/* ==========================================================================
   Bladevel — Slide Studio (Tạo slide bài giảng) — VIẾT LẠI HOÀN TOÀN
   --------------------------------------------------------------------------
   Trình soạn slide kiểu Canva/PowerPoint: sidebar thumbnail cuộn được,
   canvas thiết kế tự do (kéo/thả/resize/xoay), toolbar chèn nội dung,
   khung thuộc tính theo ngữ cảnh bên phải.

   Toàn bộ token màu / bo góc / đổ bóng / font đều TÁI SỬ DỤNG biến
   --tw-* đã có sẵn trong teacher.css (khai báo trên .tw-shell) để giao
   diện mới hoà hợp 100% với phần còn lại của bộ công cụ giáo viên —
   không định nghĩa lại bảng màu riêng. Toàn bộ class mới dùng tiền tố
   "tws-" (Teacher Workspace Slide) để không bao giờ trùng với các class
   "tw-" dùng chung của 4 công cụ còn lại.
   ========================================================================== */

/* ---------- Ép trang này chiếm trọn chiều cao khả dụng, bỏ padding mặc
   định của .tw-main (chỉ áp dụng khi layout gắn thêm class này — xem
   app/Views/layouts/teacher.bview.php) ---------- */
.tw-main-slide-editor { padding: 0; display: flex; flex-direction: column; overflow: hidden; }

.tws-app {
  --tws-sidebar-w: 178px;
  --tws-panel-w: 272px;
  --tws-topbar-h: 56px;
  --tws-canvas-w: 960;
  --tws-canvas-h: 540;

  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--tw-bg);
  min-height: 560px;
}

/* ==========================================================================
   Thanh công cụ trên cùng (Topbar)
   ========================================================================== */
.tws-topbar {
  flex-shrink: 0;
  min-height: var(--tws-topbar-h);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 16px;
  background: var(--tw-surface);
  border-bottom: 1px solid var(--tw-border);
  position: relative;
  z-index: 30;
}
.tws-topbar-left { display: flex; align-items: center; gap: 10px; min-width: 0; flex-shrink: 1; }
.tws-topbar-center { display: flex; align-items: center; gap: 6px; flex: 1; justify-content: center; flex-wrap: wrap; }
.tws-topbar-right { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.tws-vsep { width: 1px; align-self: stretch; margin: 10px 2px; background: var(--tw-border); flex-shrink: 0; }

.tws-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: var(--tw-radius-sm);
  background: transparent; border: 1px solid transparent; color: var(--tw-text-muted);
  cursor: pointer; flex-shrink: 0; transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.tws-icon-btn:hover { background: var(--tw-surface-alt); color: var(--tw-text); border-color: var(--tw-border); }
.tws-icon-btn[disabled] { opacity: .4; cursor: not-allowed; }
.tws-icon-btn[disabled]:hover { background: transparent; border-color: transparent; }
.tws-icon-btn svg { width: 16px; height: 16px; }

.tws-deck-title-input {
  border: 1px solid transparent; background: transparent; font-size: 13.5px; font-weight: 800;
  color: var(--tw-gray-1100); border-radius: var(--tw-radius-sm); padding: 6px 9px; max-width: 240px;
  transition: background .12s ease, border-color .12s ease;
}
.tws-deck-title-input:hover { background: var(--tw-surface-alt); }
.tws-deck-title-input:focus { outline: none; background: var(--tw-surface); border-color: var(--tw-primary); box-shadow: var(--tw-focus-ring); }

.tws-save-status { font-size: 10px; font-weight: 700; color: var(--tw-text-soft); white-space: nowrap; display: flex; align-items: center; gap: 5px; }
.tws-save-status svg { width: 11px; height: 11px; }
.tws-save-status-saving { color: var(--tw-info-dark); }
.tws-save-status-error { color: var(--tw-danger); }
.tws-save-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--tw-success); flex-shrink: 0; }
.tws-save-status-saving .tws-save-dot { background: var(--tw-info); animation: tws-pulse 1s ease-in-out infinite; }
.tws-save-status-error .tws-save-dot { background: var(--tw-danger); }
@keyframes tws-pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

.tws-tool-btn {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  padding: 7px 12px; border-radius: var(--tw-radius-sm); border: 1px solid transparent;
  background: transparent; color: var(--tw-gray-900); font-size: 11.5px; font-weight: 700;
  cursor: pointer; transition: background .12s ease, color .12s ease, transform .08s ease;
}
.tws-tool-btn:hover { background: var(--tw-primary-soft); color: var(--tw-primary-dark); }
.tws-tool-btn:active { transform: translateY(1px); }
.tws-tool-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.tws-tool-btn-active { background: var(--tw-primary-soft); color: var(--tw-primary-dark); }
.tws-tool-btn-chevron { width: 10px !important; height: 10px !important; margin-left: -2px; opacity: .7; }
.tws-tool-group { position: relative; }

/* ---------- Popover (bảng chọn Khối hình / Màu sắc) ---------- */
.tws-popover {
  position: absolute; top: calc(100% + 8px); left: 50%; transform: translateX(-50%) translateY(-4px) scale(.97);
  background: var(--tw-surface); border: 1px solid var(--tw-border); border-radius: var(--tw-radius-lg);
  box-shadow: var(--tw-shadow); padding: 14px; z-index: 60; width: max-content;
  opacity: 0; pointer-events: none; transition: opacity .12s ease, transform .12s ease;
}
.tws-popover-open { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0) scale(1); }
.tws-popover-label { font-size: 9.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; color: var(--tw-text-soft); margin-bottom: 8px; }
.tws-popover-label:not(:first-child) { margin-top: 12px; }

.tws-shape-grid { display: grid; grid-template-columns: repeat(6, 44px); gap: 6px; }
.tws-shape-opt {
  width: 44px; height: 40px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--tw-radius-sm); border: 1px solid var(--tw-border); background: var(--tw-surface-alt);
  cursor: pointer; color: var(--tw-gray-800); transition: border-color .12s ease, background .12s ease;
}
.tws-shape-opt:hover { border-color: var(--tw-primary); background: var(--tw-primary-soft); color: var(--tw-primary-dark); }
.tws-shape-opt svg { width: 20px; height: 20px; }
/* Popover "Khối hình" có nhiều nhóm hơn (Cơ bản / Mũi tên / Ngôi sao & Chú
   thích / Đường kẻ) — rộng vừa đủ ôm trọn lưới 6 cột, không giới hạn chiều
   cao nên KHÔNG cần cuộn dọc/ngang, hiện đủ toàn bộ 1 lần. */
.tws-popover-wide { width: max-content; max-width: 92vw; }

.tws-swatch-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
.tws-swatch {
  width: 26px; height: 26px; border-radius: 50%; cursor: pointer; border: 2px solid var(--tw-surface);
  box-shadow: 0 0 0 1px var(--tw-border); position: relative; flex-shrink: 0;
}
.tws-swatch:hover { transform: scale(1.1); }
.tws-swatch-active::after {
  content: ""; position: absolute; inset: -4px; border-radius: 50%; border: 2px solid var(--tw-primary);
}
.tws-custom-color-row { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.tws-custom-color-row input[type="color"] {
  width: 30px; height: 30px; border-radius: var(--tw-radius-sm); border: 1px solid var(--tw-border);
  padding: 0; cursor: pointer; background: none;
}
.tws-custom-color-row span { font-size: 10.5px; font-weight: 700; color: var(--tw-text-muted); }
.tws-popover-none-btn { font-size: 10.5px; font-weight: 700; color: var(--tw-text-muted); background: var(--tw-surface-alt); border: 1px solid var(--tw-border); border-radius: var(--tw-radius-sm); padding: 5px 9px; cursor: pointer; margin-top: 10px; width: 100%; }
.tws-popover-none-btn:hover { border-color: var(--tw-primary); color: var(--tw-primary); }

/* ==========================================================================
   Khu vực chính: sidebar + canvas + panel thuộc tính
   ========================================================================== */
.tws-body { flex: 1; min-height: 0; display: flex; }

/* ---------- Sidebar trái: danh sách slide thu nhỏ ---------- */
.tws-sidebar {
  width: var(--tws-sidebar-w); flex-shrink: 0; background: var(--tw-surface-alt);
  border-right: 1px solid var(--tw-border); display: flex; flex-direction: column; min-height: 0;
}
.tws-sidebar-list {
  flex: 1; min-height: 0; overflow-y: auto; padding: 12px 15px; display: flex; flex-direction: column; gap: 10px;
  scrollbar-width: thin; scrollbar-color: var(--tw-gray-300) transparent;
}
.tws-sidebar-list::-webkit-scrollbar { width: 6px; }
.tws-sidebar-list::-webkit-scrollbar-thumb { background: var(--tw-gray-300); border-radius: 10px; }

.tws-slide-thumb {
  position: relative; border-radius: 7px; cursor: grab; border: 2px solid transparent;
  transition: border-color .12s ease, transform .1s ease; flex-shrink: 0;
}
.tws-slide-thumb:active { cursor: grabbing; }
.tws-slide-thumb-stage-wrap {
  width: 100%; aspect-ratio: 16 / 9; border-radius: 5px; overflow: hidden; background: #fff;
  box-shadow: var(--tw-shadow-sm); position: relative; pointer-events: none;
}
.tws-slide-thumb-active { border-color: var(--tw-primary); }
.tws-slide-thumb-active .tws-slide-thumb-stage-wrap { box-shadow: 0 0 0 3px var(--tw-primary-soft); }
.tws-slide-thumb:hover:not(.tws-slide-thumb-active) .tws-slide-thumb-stage-wrap { box-shadow: 0 0 0 2px var(--tw-border); }
/* Số trang: huy hiệu nhỏ đè lên góc trên-trái của chính slide (không còn nằm
   ở dòng riêng bên dưới thumbnail). */
.tws-slide-thumb-num {
  position: absolute; top: 4px; left: 4px; z-index: 2;
  min-width: 16px; height: 16px; padding: 0 4px; border-radius: 999px;
  background: rgba(15, 23, 42, .62); color: #fff; font-size: 9px; font-weight: 800;
  line-height: 16px; text-align: center; pointer-events: none;
}
.tws-slide-thumb-del {
  position: absolute; top: 4px; right: 4px; z-index: 2;
  width: 19px; height: 19px; border-radius: var(--tw-radius-sm); border: none; background: rgba(15, 23, 42, .62);
  color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer;
  opacity: 0; transition: opacity .12s ease, background .12s ease, color .12s ease; pointer-events: auto;
}
.tws-slide-thumb:hover .tws-slide-thumb-del { opacity: 1; }
.tws-slide-thumb-del:hover { background: var(--tw-danger); color: #fff; }
.tws-slide-thumb-del svg { width: 12px; height: 12px; }
.tws-slide-thumb-fx {
  position: absolute; bottom: 4px; right: 4px; z-index: 2;
  width: 16px; height: 16px; border-radius: 999px; background: rgba(56, 116, 255, .92);
  color: #fff; display: flex; align-items: center; justify-content: center; pointer-events: none;
}
.tws-slide-thumb-fx svg { width: 10px; height: 10px; stroke-width: 2; }
.tws-slide-thumb-dragover { border-color: var(--tw-primary-light); }
.tws-slide-thumb-dragging { opacity: .4; }

/* Trang được BỔ SUNG chọn bằng Ctrl/Shift+click (áp dụng chung 1 hiệu ứng
   chuyển slide) — phủ 1 lớp màu nhẹ + số trang đổi màu, phân biệt với trang
   "đang active" (chỉ có viền, không phủ màu). Cả 2 class có thể cùng có. */
.tws-slide-thumb-multi { border-color: var(--tw-primary); }
.tws-slide-thumb-multi .tws-slide-thumb-stage-wrap { box-shadow: 0 0 0 2px var(--tw-primary-soft); }
.tws-slide-thumb-multi .tws-slide-thumb-stage-wrap::after {
  content: ''; position: absolute; inset: 0; z-index: 1; border-radius: 5px;
  background: rgba(56, 116, 255, .14); pointer-events: none;
}
.tws-slide-thumb-multi .tws-slide-thumb-num { background: var(--tw-primary); }

.tws-add-slide-btn {
  flex-shrink: 0; margin: 12px 15px 15px; padding: 9px; border-radius: var(--tw-radius);
  border: 1.5px dashed var(--tw-border); background: transparent; color: var(--tw-text-muted);
  font-size: 11px; font-weight: 800; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 6px;
  transition: border-color .12s ease, color .12s ease, background .12s ease;
}
.tws-add-slide-btn:hover { border-color: var(--tw-primary); color: var(--tw-primary); background: var(--tw-primary-soft); }
.tws-add-slide-btn svg { width: 14px; height: 14px; }

/* ---------- Canvas ở giữa ---------- */
.tws-canvas-area {
  flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center;
  padding: 28px; overflow: auto; position: relative;
  background-image: radial-gradient(var(--tw-gray-200) 1px, transparent 1px);
  background-size: 22px 22px; background-position: -11px -11px;
}
.tws-canvas-scale-wrap { position: relative; flex-shrink: 0; }
.tws-canvas {
  position: relative; background: #ffffff; border-radius: 4px;
  /* Không cắt (overflow: hidden) khi đang soạn thảo, để giáo viên có thể kéo
     chữ/hình ra ngoài viền trắng thoải mái như PowerPoint/Canva — phần nằm
     ngoài khung chỉ là "nháp", không hiện khi Trình chiếu (xem .tws-present-stage). */
  overflow: visible;
  box-shadow: 0 1.5px 4px rgba(20,24,36,.08), 0 18px 40px -16px rgba(20,24,36,.35);
  transform-origin: top left;
}
.tws-canvas-deselect-hint { position: absolute; inset: 0; }

/* ---------- Phần tử trên slide ---------- */
.tws-el {
  position: absolute; box-sizing: border-box; cursor: grab; user-select: none;
}
.tws-el:active { cursor: grabbing; }
.tws-el-selected { z-index: 500 !important; }
.tws-el-selected > .tws-el-inner { outline: 1.5px solid var(--tw-primary); }
.tws-el-dragging, .tws-el-resizing, .tws-el-rotating { transition: none !important; }

/* Khung ngoài (.tws-el) KHÔNG BAO GIỜ cắt (overflow) nội dung, để tay cầm
   resize/xoay (nằm ngoài biên, offset âm) luôn hiển thị đủ. Việc cắt hình
   ảnh/bảng theo đúng khung được xử lý bởi lớp bọc trong .tws-el-inner. */
.tws-el-inner { width: 100%; height: 100%; overflow: hidden; box-sizing: border-box; }
.tws-el-inner-visible { overflow: visible; }

.tws-el-text > .tws-el-inner {
  display: flex; padding: 2px 4px; white-space: pre-wrap; word-break: break-word; line-height: 1.28;
}
.tws-el-text[data-editing="1"] > .tws-el-inner { cursor: text; outline: 1.5px dashed var(--tw-primary); user-select: text; }
.tws-el-text .tws-el-text-content { width: 100%; outline: none; }
.tws-el-text[data-align="left"] .tws-el-inner { justify-content: flex-start; text-align: left; }
.tws-el-text[data-align="center"] .tws-el-inner { justify-content: center; text-align: center; }
.tws-el-text[data-align="right"] .tws-el-inner { justify-content: flex-end; text-align: right; }
.tws-el-text[data-valign="top"] .tws-el-inner { align-items: flex-start; }
.tws-el-text[data-valign="middle"] .tws-el-inner { align-items: center; }
.tws-el-text[data-valign="bottom"] .tws-el-inner { align-items: flex-end; }
.tws-el-text-placeholder { opacity: .38; }

.tws-el-image img { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; -webkit-user-drag: none; }
.tws-el-image-empty {
  width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 6px;
  background: var(--tw-surface-alt); color: var(--tw-text-soft); border: 1.5px dashed var(--tw-border); border-radius: 6px;
  box-sizing: border-box;
}
.tws-el-image-empty svg { width: 26px; height: 26px; }
.tws-el-image-empty span { font-size: 10.5px; font-weight: 700; }

.tws-el-shape-ellipse > .tws-el-inner { border-radius: 50%; }
/* Các hình khối khác (tam giác, mũi tên, ngôi sao, trái tim, đám mây...) được
   vẽ bằng 1 <path> SVG bên trong .tws-el-inner (xem SHAPE_DEFS trong
   slide-studio.js) — không cần clip-path CSS riêng cho từng hình nữa. */

.tws-el-table table { width: 100%; height: 100%; border-collapse: collapse; table-layout: fixed; }
.tws-el-table td {
  border: 1px solid var(--tw-border); padding: 6px 9px; font-size: 13px; vertical-align: middle;
  overflow: hidden; word-break: break-word; outline: none;
}
.tws-el-table td[data-editing="1"] { cursor: text; background: var(--tw-primary-soft); user-select: text; }
.tws-el-table tr:first-child td { font-weight: 800; }

/* ---------- Tay cầm resize / xoay ---------- */
.tws-handle {
  position: absolute; width: 11px; height: 11px; background: #fff; border: 1.5px solid var(--tw-primary);
  border-radius: 50%; z-index: 600; box-shadow: 0 1px 3px rgba(20,24,36,.25);
}
.tws-handle-nw { top: -6px; left: -6px; cursor: nwse-resize; }
.tws-handle-ne { top: -6px; right: -6px; cursor: nesw-resize; }
.tws-handle-sw { bottom: -6px; left: -6px; cursor: nesw-resize; }
.tws-handle-se { bottom: -6px; right: -6px; cursor: nwse-resize; }
/* 4 tay cầm CẠNH — dạng vạch (thanh dài), kéo riêng 1 chiều ngang HOẶC dọc,
   khác hình chấm tròn của tay cầm góc (kéo chéo cả 2 chiều) để dễ phân biệt. */
.tws-handle-bar { border-radius: 3px; }
.tws-handle-n, .tws-handle-s { left: 50%; width: 22px; height: 8px; margin-left: -11px; cursor: ns-resize; }
.tws-handle-n { top: -4px; }
.tws-handle-s { bottom: -4px; }
.tws-handle-e, .tws-handle-w { top: 50%; width: 8px; height: 22px; margin-top: -11px; cursor: ew-resize; }
.tws-handle-e { right: -4px; }
.tws-handle-w { left: -4px; }
.tws-handle-rotate {
  top: -30px; left: 50%; transform: translateX(-50%); cursor: grab; background: var(--tw-primary);
  border-color: #fff;
}
.tws-handle-rotate:active { cursor: grabbing; }
.tws-handle-rotate-stick { position: absolute; top: -24px; left: 50%; width: 1.5px; height: 24px; background: var(--tw-primary); transform: translateX(-50%); z-index: 599; }

.tws-guide { position: absolute; background: var(--tw-danger); z-index: 700; pointer-events: none; }
.tws-guide-v { width: 1px; top: 0; bottom: 0; }
.tws-guide-h { height: 1px; left: 0; right: 0; }

.tws-el-mini-toolbar {
  position: absolute; top: -38px; left: 50%; transform: translateX(-50%); display: flex; gap: 2px;
  background: var(--tw-gray-1100); border-radius: var(--tw-radius-sm); padding: 3px; z-index: 601;
  box-shadow: var(--tw-shadow); white-space: nowrap;
}
.tws-el-mini-btn {
  width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; border: none;
  background: transparent; color: #cdd3e0; border-radius: 4px; cursor: pointer;
}
.tws-el-mini-btn:hover { background: rgba(255,255,255,.12); color: #fff; }
.tws-el-mini-btn svg { width: 14px; height: 14px; }

/* ==========================================================================
   Panel thuộc tính bên phải (ngữ cảnh theo phần tử đang chọn)
   ========================================================================== */
.tws-panel {
  width: var(--tws-panel-w); flex-shrink: 0; background: var(--tw-surface); border-left: 1px solid var(--tw-border);
  display: flex; flex-direction: column; min-height: 0;
}
.tws-panel-head { padding: 13px 16px; border-bottom: 1px solid var(--tw-border); display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; }
.tws-panel-head-title { font-size: 11.5px; font-weight: 800; color: var(--tw-gray-1100); display: flex; align-items: center; gap: 7px; }
.tws-panel-head-title svg { width: 15px; height: 15px; color: var(--tw-primary); }
.tws-panel-body { flex: 1; min-height: 0; overflow-y: auto; padding: 15px 16px; background: var(--tw-surface-alt); scrollbar-width: thin; scrollbar-color: var(--tw-gray-300) transparent; }
.tws-panel-body::-webkit-scrollbar { width: 6px; }
.tws-panel-body::-webkit-scrollbar-thumb { background: var(--tw-gray-300); border-radius: 10px; }
.tws-panel-empty { padding: 40px 20px; text-align: center; color: var(--tw-text-soft); }
.tws-panel-empty svg { width: 40px; height: 40px; margin: 0 auto 12px; color: var(--tw-border); }
.tws-panel-empty p { font-size: 11px; font-weight: 600; max-width: 190px; margin: 0 auto; }

.tws-prop-group { margin-bottom: 16px; display: flex; flex-direction: column; gap: 8px; }
.tws-prop-group:last-child { margin-bottom: 0; }
.tws-prop-label { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--tw-text-soft); display: block; }
.tws-prop-row { display: flex; gap: 10px; align-items: center; }
.tws-prop-row > * { min-width: 0; }

.tws-seg { display: flex; background: var(--tw-surface-alt); border: 1px solid var(--tw-border); border-radius: var(--tw-radius-sm); padding: 2px; gap: 1px; }
.tws-seg-btn { flex: 1; display: flex; align-items: center; justify-content: center; padding: 6px 0; border: none; background: transparent; color: var(--tw-text-muted); border-radius: 4px; cursor: pointer; }
.tws-seg-btn svg { width: 14px; height: 14px; }
.tws-seg-btn:hover { color: var(--tw-text); }
.tws-seg-btn-active { background: var(--tw-surface); color: var(--tw-primary); box-shadow: var(--tw-shadow-sm); }

/* Ô chọn font (Phông chữ) — 2 nút nhanh + ô tìm kiếm xổ xuống toàn bộ Google
   Fonts, mỗi dòng hiển thị mẫu bằng chính font đó. Xem buildFontPicker() và
   styleTextContent() trong slide-studio.js, danh sách font lấy qua
   /giao-vien/api/fonts (app/Controllers/FontsController.php). */
.tws-font-picker { position: relative; display: flex; flex-direction: column; gap: 6px; }
.tws-font-quick { display: flex; gap: 6px; }

/* 2 nút "Vừa chiều ngang" / "Vừa chiều dọc" — thu hẹp khung chữ vừa khít nội
   dung. Xem shrinkTextBoxToFit() trong slide-studio.js. */
.tws-fit-btn {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 5px;
  font: 600 11.5px/1.3 Arial, sans-serif; padding: 8px 6px; border-radius: var(--tw-radius-sm);
  border: 1px solid var(--tw-border); background: var(--tw-surface-alt); color: var(--tw-text-muted); cursor: pointer;
}
.tws-fit-btn:hover { border-color: var(--tw-primary); color: var(--tw-primary-dark); }
.tws-fit-btn span { font-size: 14px; line-height: 1; }
.tws-font-quick-btn {
  flex: 1; font: 600 11.5px/1.3 Arial, sans-serif; padding: 6px 8px; border-radius: var(--tw-radius-sm);
  border: 1px solid var(--tw-border); background: var(--tw-surface-alt); color: var(--tw-text-muted); cursor: pointer;
}
.tws-font-quick-btn:hover { border-color: var(--tw-primary); color: var(--tw-primary-dark); }
.tws-font-quick-btn-active { background: var(--tw-primary-soft); border-color: var(--tw-primary); color: var(--tw-primary-dark); }
.tws-font-current {
  display: flex; align-items: center; justify-content: space-between; gap: 6px; width: 100%;
  font: 500 13px/1.4 Arial, sans-serif; padding: 8px 10px; border-radius: var(--tw-radius-sm);
  border: 1px solid var(--tw-border); background: var(--tw-surface); color: var(--tw-text); cursor: pointer; text-align: left;
}
.tws-font-current:hover { border-color: var(--tw-primary); }
.tws-font-current span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tws-font-current svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--tw-text-muted); }
.tws-font-dropdown {
  position: absolute; z-index: 40; top: calc(100% + 4px); left: 0; right: 0;
  background: var(--tw-surface); border: 1px solid var(--tw-border); border-radius: var(--tw-radius-lg);
  box-shadow: var(--tw-shadow-lg); padding: 8px; display: flex; flex-direction: column; gap: 6px;
}
.tws-font-search { width: 100%; }
.tws-font-status { font: 500 11.5px/1.4 Arial, sans-serif; color: var(--tw-text-muted); padding: 10px 4px; text-align: center; }
/* QUAN TRỌNG: KHÔNG dùng display:flex ở đây. Lý do gây lỗi "chữ bị cắt mất
   nửa dưới, chỉ thấy phần trên": .tws-font-option (flex item) có
   overflow:hidden (để text-overflow:ellipsis hoạt động) — theo đúng chuẩn
   CSS Flexbox, hễ 1 flex item có overflow khác "visible" thì kích thước tối
   thiểu tự động của nó đổi từ "theo nội dung" thành 0, khiến flex-shrink có
   thể bóp chiều cao từng dòng xuống gần 0 khi danh sách dài (60 dòng) vượt
   quá max-height — cắt mất phần dưới chữ dù container vẫn cuộn được bình
   thường. Dùng block layout thường (mỗi <div> vốn đã tự xuống dòng, chiếm
   trọn chiều ngang) thì không dính lỗi flex-shrink này. */
.tws-font-list { max-height: 220px; overflow-y: auto; display: block; }
.tws-font-option {
  padding: 8px 8px; border-radius: var(--tw-radius-sm); cursor: pointer; color: var(--tw-text, #141824); font-size: 15px;
  line-height: 1.5; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tws-font-option:hover { background: var(--tw-surface-alt); }
.tws-font-option-active { background: var(--tw-primary-soft); color: var(--tw-primary-dark); }

.tws-color-field { display: flex; align-items: center; gap: 8px; padding: 6px 9px; border: 1px solid var(--tw-border); border-radius: var(--tw-radius-sm); background: var(--tw-surface-alt); cursor: pointer; }
.tws-color-field:hover { border-color: var(--tw-primary); }
.tws-color-swatch-preview { width: 18px; height: 18px; border-radius: 50%; box-shadow: 0 0 0 1px var(--tw-border) inset, 0 0 0 1px rgba(0,0,0,.03); flex-shrink: 0; }
.tws-color-field span { font-size: 11px; font-weight: 700; color: var(--tw-text-muted); text-transform: uppercase; }

.tws-stepper { display: flex; align-items: center; border: 1px solid var(--tw-border); border-radius: var(--tw-radius-sm); background: var(--tw-surface-alt); overflow: hidden; }
.tws-stepper button { width: 26px; height: 30px; border: none; background: transparent; color: var(--tw-text-muted); cursor: pointer; font-size: 14px; }
.tws-stepper button:hover { background: var(--tw-primary-soft); color: var(--tw-primary); }
.tws-stepper input { width: 40px; border: none; background: transparent; text-align: center; font-size: 12px; font-weight: 700; color: var(--tw-text); padding: 0; }
.tws-stepper input:focus { outline: none; }

.tws-mini-btn-row { display: flex; gap: 10px; }
.tws-mini-btn-row .tw-btn { flex: 1; }

.tws-table-grid-btns { display: flex; gap: 10px; }
.tws-table-grid-btns .tw-btn { flex: 1; }

/* ==========================================================================
   Modal (Tạo bài giảng mới / Bài giảng đã lưu)
   ========================================================================== */
.tws-modal-backdrop {
  position: fixed; inset: 0; background: rgba(20, 24, 36, .5); z-index: 300;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  opacity: 0; pointer-events: none; transition: opacity .15s ease;
}
.tws-modal-backdrop-open { opacity: 1; pointer-events: auto; }
.tws-modal {
  background: var(--tw-surface); border-radius: var(--tw-radius-lg); box-shadow: var(--tw-shadow);
  width: 100%; max-width: 420px; max-height: 82vh; display: flex; flex-direction: column;
  transform: translateY(10px) scale(.98); transition: transform .15s ease;
}
.tws-modal-backdrop-open .tws-modal { transform: translateY(0) scale(1); }
.tws-modal-wide { max-width: 460px; }
.tws-modal-head { padding: 16px 19px; border-bottom: 1px solid var(--tw-border); display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; }
.tws-modal-head h3 { font-size: 14px; font-weight: 800; color: var(--tw-gray-1100); margin: 0; }
.tws-modal-body { padding: 19px; overflow-y: auto; }
.tws-modal-foot { padding: 14px 19px; border-top: 1px solid var(--tw-border); display: flex; justify-content: flex-end; gap: 8px; flex-shrink: 0; background: var(--tw-surface-alt); border-radius: 0 0 var(--tw-radius-lg) var(--tw-radius-lg); }

/* Danh sách bài giảng đã lưu — tái dùng .tw-history-* của teacher.css */
.tws-deck-list { display: flex; flex-direction: column; }
.tws-deck-list .tw-history-item { padding: 10.5px 8px; border-radius: var(--tw-radius-sm); cursor: pointer; }
.tws-deck-list .tw-history-item:hover { background: var(--tw-surface-alt); }
.tw-history-item-active { background: var(--tw-primary-soft) !important; }
.tws-deck-list-empty { padding: 30px 10px; text-align: center; color: var(--tw-text-soft); font-size: 11.5px; font-weight: 600; }

/* ==========================================================================
   Chế độ trình chiếu (Present mode)
   ========================================================================== */
.tws-present {
  position: fixed; inset: 0; background: #0b0d14; z-index: 900;
  display: flex; align-items: center; justify-content: center; flex-direction: column;
}
.tws-present-stage-wrap { position: relative; cursor: pointer; }
.tws-present-stage { background: #fff; position: relative; overflow: hidden; box-shadow: 0 30px 80px rgba(0,0,0,.5); }
.tws-present-bar {
  position: absolute; bottom: 22px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 14px;
  background: rgba(255,255,255,.08); backdrop-filter: blur(6px); padding: 8px 16px; border-radius: 50rem; color: #fff;
}
.tws-present-bar button { background: none; border: none; color: #fff; cursor: pointer; display: flex; align-items: center; justify-content: center; opacity: .85; }
.tws-present-bar button:hover { opacity: 1; }
.tws-present-bar button svg { width: 18px; height: 18px; }
.tws-present-count { font-size: 11px; font-weight: 700; min-width: 42px; text-align: center; }
.tws-present-exit { position: absolute; top: 18px; right: 20px; color: #fff; background: rgba(255,255,255,.08); border: none; width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.tws-present-exit:hover { background: rgba(255,255,255,.18); }
.tws-present-exit svg { width: 16px; height: 16px; }
.tws-present-hint { position: absolute; top: 20px; left: 24px; color: rgba(255,255,255,.55); font-size: 10.5px; font-weight: 600; }

/* ==========================================================================
   Trạng thái rỗng / responsive
   ========================================================================== */
@media (max-width: 1180px) {
  .tws-app { --tws-panel-w: 248px; }
  .tws-tool-btn span { display: none; }
  .tws-tool-btn { padding: 7px 9px; }
}
@media (max-width: 900px) {
  .tws-notice-small { display: flex !important; }
}
.tws-notice-small {
  display: none; align-items: center; gap: 10px; padding: 10px 16px; background: var(--tw-warning-soft);
  color: var(--tw-warning-dark); font-size: 11px; font-weight: 700; flex-shrink: 0;
}
.tws-notice-small svg { width: 16px; height: 16px; flex-shrink: 0; }

@media print {
  .tws-app { display: none !important; }
}

/* ==========================================================================
   Hiệu ứng (Slide Studio ↔ TWSlideFX)
   --------------------------------------------------------------------------
   Phần hỗ trợ giao diện cho 61 hiệu ứng chuyển slide + 20 hiệu ứng xuất hiện
   nội dung. Bản thân các hiệu ứng do slide-fx-engine.js chạy bằng Web
   Animations API, và các style nền tảng nó cần (lưới, gạch chân, highlight,
   perspective...) nằm trong slide-fx.css — file này chỉ thêm phần UI chọn
   hiệu ứng trong panel bên phải.
   ========================================================================== */
.tws-prop-hint {
  font-size: 10px; font-weight: 600; color: var(--tw-text-soft);
  line-height: 1.45;
}

/* Phần tử đang chờ tới lượt chạy hiệu ứng trong lúc trình chiếu.
   Engine tự đặt opacity qua style inline, class này chỉ dùng để
   Slide Studio tạm loại 1 nhóm ra khỏi lượt chạy (xem playSlideAnims). */
.tws-present-stage .tw-anim-el-off { opacity: 0; }

/* Khung xem thử hiệu ứng ngay trên canvas soạn thảo */
.tws-canvas-scale-wrap { overflow: visible; }
/* ==========================================================================
   BỔ SUNG: bảng chọn khối hình 2 thẻ (2D / 3D), khối 3D & kho mô hình 3D
   ========================================================================== */

/* --- Bảng chọn khối hình: nay có hơn 70 khối 2D + 100 khối 3D nên phải
   giới hạn chiều cao và cho cuộn dọc, kèm 2 thẻ để không bị quá dài. --- */
.tws-popover-shapes { width: 330px; max-width: 92vw; max-height: 74vh; overflow-y: auto; overscroll-behavior: contain; }
.tws-popover-shapes::-webkit-scrollbar { width: 8px; }
.tws-popover-shapes::-webkit-scrollbar-thumb { background: var(--tw-border); border-radius: 4px; }

.tws-shape-tabs {
  display: flex; gap: 4px; padding: 3px; margin-bottom: 12px;
  background: var(--tw-surface-alt); border: 1px solid var(--tw-border); border-radius: var(--tw-radius-sm);
  position: sticky; top: -14px; z-index: 2;
}
.tws-shape-tab {
  flex: 1; padding: 6px 0; border: none; background: transparent; cursor: pointer;
  font-size: 11px; font-weight: 800; color: var(--tw-text-muted); border-radius: 4px;
  font-family: inherit; transition: background .12s ease, color .12s ease;
}
.tws-shape-tab:hover { color: var(--tw-text); }
.tws-shape-tab-on { background: var(--tw-surface); color: var(--tw-primary); box-shadow: var(--tw-shadow-sm); }

.tws-popover-note {
  font-size: 10.5px; line-height: 1.55; font-weight: 600; color: var(--tw-text-muted);
  background: var(--tw-surface-alt); border: 1px solid var(--tw-border);
  border-radius: var(--tw-radius-sm); padding: 8px 10px; margin-bottom: 12px;
}

/* Khối 3D cần ô rộng hơn chút để thấy rõ chiều sâu */
.tws-shape-grid-3d { grid-template-columns: repeat(5, 54px); gap: 6px; }
.tws-shape-opt-3d { width: 54px; height: 50px; padding: 4px; }
.tws-shape-opt-3d svg { width: 34px; height: 34px; }
.tws-shape-opt-3d:hover svg { transform: scale(1.06); transition: transform .12s ease; }

/* --- Panel thuộc tính: ghi chú, thanh trượt, công tắc --- */
.tws-prop-note {
  font-size: 11.5px; font-weight: 700; color: var(--tw-gray-1100);
  background: var(--tw-surface-alt); border: 1px solid var(--tw-border);
  border-radius: var(--tw-radius-sm); padding: 8px 10px; word-break: break-word;
}
.tws-range { flex: 1; accent-color: var(--tw-primary); height: 20px; cursor: pointer; }
.tws-range-value {
  min-width: 42px; text-align: right; font-size: 11px; font-weight: 800;
  color: var(--tw-text-muted); font-variant-numeric: tabular-nums;
}
.tws-switch { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 11.5px; font-weight: 600; color: var(--tw-text); }
.tws-switch input { width: 15px; height: 15px; accent-color: var(--tw-primary); cursor: pointer; flex-shrink: 0; }

/* --- Phần tử "mô hình 3D" trên canvas --- */
.tws-model3d { width: 100%; height: 100%; position: relative; display: block; border-radius: 6px; overflow: hidden; }
.tws-model3d-canvas { position: absolute; inset: 0; }
.tws-model3d-ph {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; text-align: center; padding: 10px; color: var(--tw-text-soft);
  background: var(--tw-surface-alt); border: 1px dashed var(--tw-border); border-radius: 6px;
  font-size: 11.5px; font-weight: 700;
}
.tws-model3d-ph svg { width: 30px; height: 30px; }
.tws-model3d[data-model-state="ready"] .tws-model3d-ph { display: none; }
.tws-model3d[data-model-state="error"] .tws-model3d-ph span::after { content: ' — không tải được'; }
.tws-model3d[data-model-state="error"] .tws-model3d-ph { color: var(--tw-danger, #d1495b); }

/* --- Modal kho mô hình 3D --- */
.tws-modal-xwide { max-width: 720px; }
.tws-model-searchbar { display: flex; gap: 8px; margin-bottom: 12px; }
.tws-model-searchbar .tw-input { flex: 1; min-width: 0; }
.tws-model-source { width: 138px; flex-shrink: 0; }

.tws-model-status {
  font-size: 11.5px; font-weight: 700; color: var(--tw-text-muted);
  padding: 10px 12px; background: var(--tw-surface-alt); border-radius: var(--tw-radius-sm);
  margin-bottom: 12px; line-height: 1.55;
}
.tws-model-status-danger { color: var(--tw-danger, #d1495b); }

.tws-model-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
.tws-model-card {
  display: flex; flex-direction: column; gap: 4px; padding: 8px; cursor: pointer;
  background: var(--tw-surface); border: 1px solid var(--tw-border); border-radius: var(--tw-radius-sm);
  text-align: left; font-family: inherit; transition: border-color .12s ease, box-shadow .12s ease;
}
.tws-model-card:hover { border-color: var(--tw-primary); box-shadow: var(--tw-shadow-sm); }
.tws-model-thumb {
  width: 100%; aspect-ratio: 4 / 3; border-radius: 5px; overflow: hidden;
  background: var(--tw-surface-alt); display: flex; align-items: center; justify-content: center;
  color: var(--tw-text-soft);
}
.tws-model-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tws-model-thumb-empty svg { width: 34px; height: 34px; }
.tws-model-name { font-size: 11.5px; font-weight: 800; color: var(--tw-gray-1100); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tws-model-meta { font-size: 10px; font-weight: 700; color: var(--tw-text-soft); }

.tws-model-more-wrap { display: flex; justify-content: center; margin-top: 12px; }
.tws-model-url-box { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--tw-border); }
.tws-model-url-row { display: flex; gap: 8px; margin-top: 6px; }
.tws-model-url-row .tw-input { flex: 1; min-width: 0; }

@media (max-width: 720px) {
  .tws-model-searchbar { flex-wrap: wrap; }
  .tws-model-source { width: 100%; }
  .tws-popover-shapes { width: 300px; }
  .tws-shape-grid-3d { grid-template-columns: repeat(4, 54px); }
}

/* ==========================================================================
   Chạy các bước 1, 2, 3… trong slide (slide-steps.js)
   ========================================================================== */

/* Nút chọn cách chạy (3 lựa chọn xếp ngang, chọn 1) */
.tws-seg { display: flex; border: 1px solid var(--tw-border); border-radius: var(--tw-radius-sm); background: var(--tw-surface-alt); padding: 2px; gap: 2px; }
.tws-seg-btn {
  flex: 1; min-width: 0; border: none; background: transparent; cursor: pointer;
  padding: 7px 4px; border-radius: calc(var(--tw-radius-sm) - 2px);
  font: inherit; font-size: 11.5px; font-weight: 700; line-height: 1.15;
  color: var(--tw-text-muted); transition: background .15s, color .15s, box-shadow .15s;
}
.tws-seg-btn:hover { color: var(--tw-primary); }
.tws-seg-btn-on {
  background: #fff; color: var(--tw-primary);
  box-shadow: 0 1px 3px rgba(20, 24, 36, .14), 0 0 0 1px var(--tw-primary) inset;
}

/* Chấm số bước ở góc phần tử trên canvas soạn thảo (không hiện lúc trình chiếu / ảnh thu nhỏ) */
.tws-step-badge {
  position: absolute; top: -11px; left: -11px; z-index: 550;
  min-width: 20px; height: 20px; padding: 0 5px; box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  border-radius: 999px; background: var(--tw-primary); color: #fff;
  font-size: 11px; font-weight: 800; line-height: 1;
  box-shadow: 0 1px 4px rgba(20, 24, 36, .35), 0 0 0 2px #fff;
  pointer-events: none; user-select: none;
}
.tws-step-badge-auto { background: var(--tw-text-muted, #6b7385); font-size: 8px; padding-left: 2px; }


/* ==========================================================================
   Chọn nhiều phần tử: kéo khung chọn (marquee), khung bao nhóm, nút căn lề
   ========================================================================== */

/* Khung chọn khi kéo chuột trên nền — position: fixed vì được gắn thẳng vào <body>
   (biến màu chỉ có trong .tw-shell nên dùng màu cứng dự phòng). */
.tws-marquee {
  position: fixed; z-index: 9999; pointer-events: none; box-sizing: border-box;
  background: rgba(56, 116, 255, .12);
  border: 1px solid var(--tw-primary, #3874ff);
  border-radius: 2px;
}
body.tws-marquee-active { user-select: none; -webkit-user-select: none; cursor: crosshair; }

/* Phần tử đang nằm trong khung chọn (sáng viền trước khi thả chuột) */
.tws-el-marquee-hit > .tws-el-inner { outline: 1.5px solid var(--tw-primary); }

/* Khung nét đứt bao cả nhóm đang chọn */
.tws-group-box {
  position: absolute; z-index: 600; pointer-events: none; box-sizing: border-box;
  border: 1px dashed var(--tw-primary);
}

/* Lưới nút căn lề / dàn đều ở panel "Nhiều phần tử" */
.tws-align-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.tws-align-btn {
  display: flex; align-items: center; justify-content: center; height: 34px; padding: 0;
  border: 1px solid var(--tw-border); border-radius: var(--tw-radius-sm);
  background: var(--tw-surface); color: var(--tw-text-muted); cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.tws-align-btn svg { width: 18px; height: 18px; }
.tws-align-btn:hover:not(:disabled) { color: var(--tw-primary); border-color: var(--tw-primary); background: var(--tw-primary-soft); }
.tws-align-btn:disabled { opacity: .4; cursor: not-allowed; }