/* visual-editor.css — Giao diện chế độ "🧩 Kéo thả" trong editor.php (xem visual-editor.js).
   Dùng chung biến --ac-* và class ac- có sẵn của builder-html.css/editor-theme.css. */

.ac-pane.ac-visual-pane.active { display: flex; }
/* overflow: hidden — chặn đúng gốc rễ 1 lỗi từng gặp: panel Thuộc tính (position: absolute, kéo
   rời được, xem wirePropsPanelDrag) kéo xuống quá thấp có thể lòi ra ngoài khung .ac-visual-layout;
   không có dòng này, phần lòi ra đó KHÔNG bị cắt (không tổ tiên nào khác có overflow:hidden/auto)
   nên trôi tiếp lên tới html (chỉ overflow-x:hidden, còn overflow-y mặc định visible), khiến CẢ
   TRANG hiện thêm 1 thanh cuộn dọc thừa. Kẹp toạ độ+max-height trong JS đã giảm khả năng này xảy
   ra, nhưng vẫn giữ dòng này làm lưới an toàn cuối cùng. */
.ac-visual-layout { position: relative; width: 100%; height: 100%; min-width: 0; overflow: hidden; }

/* Chế độ Kéo thả tự nó đã là xem trước "sống" (Shadow DOM render thật) — ẩn khung xem trước
   code riêng và cho khung soạn thảo chiếm trọn chiều rộng, dễ chỉnh sửa hơn. */
.ac-editor-body.is-visual-mode .ac-preview-wrap { display: none; }
.ac-editor-body.is-visual-mode .ac-editor-panes { flex: 1 1 100%; border-right: none; }

/* ── Vùng canvas: chiếm trọn toàn bộ khung, palette/panel thuộc tính nổi đè lên trên ──────
   Đệm trái/phải đủ rộng để tránh đúng vùng 2 panel nổi — nếu không, phần nội dung canvas nằm
   ngay dưới panel sẽ bị panel chặn mất thao tác chuột/kéo-thả (không chỉ là khuất hình). */
.ac-visual-stage-wrap {
  --ac-stage-pad-left: calc(190px * var(--ac-ui-scale, 1)); --ac-stage-pad-right: calc(330px * var(--ac-ui-scale, 1));
  position: absolute; inset: 0; overflow: auto; background: #2a2d3f;
  padding: 20px var(--ac-stage-pad-right) 20px var(--ac-stage-pad-left);
}
/* Canh giữa theo đúng VÙNG LÀM VIỆC THẤY ĐƯỢC (khoảng giữa 2 panel nổi), không phải giữa cả
   .ac-visual-stage-wrap. Phần tử position:absolute lấy mốc % theo PADDING BOX của khung chứa —
   tức tính cả 2 dải đệm 190px/330px nằm dưới panel — nên "left:50%" rơi lệch sang phải đúng
   (330-190)/2 = 70px so với tâm thật của canvas. Đặt left/right bằng chính 2 biến đệm rồi
   margin-inline:auto để tự canh giữa trong khoảng còn lại, luôn khớp dù sau này đổi bề rộng panel. */
.ac-visual-stage-hint {
  position: absolute; top: 50%; left: var(--ac-stage-pad-left); right: var(--ac-stage-pad-right);
  transform: translateY(-50%); margin-inline: auto; width: max-content; max-width: 220px;
  color: #6a6f92; font-size: 13px; text-align: center; pointer-events: none; z-index: 1;
}
/* min-height: 100% (không phải số px cố định) — khớp đúng theo tỉ lệ với .stage/.page bên
   trong Shadow DOM (visual-editor.js, cũng min-height:100%), nên luôn bằng nhau tuyệt đối,
   không lệch như trước (từng có "vùng chết" do host 400px cố định > .page 240px cố định —
   phần dư ra không có gì trong Shadow DOM để nhận sự kiện). Nhờ vậy .page (nền trắng) luôn phủ
   kín màn hình làm việc thay vì chỉ cao bằng nội dung, để lộ nền tối #2a2d3f xung quanh; nội
   dung dài hơn 1 màn hình vẫn tự giãn cao hơn 100% bình thường (không bị cắt, khớp growPageToFit). */
.ac-visual-canvas-host {
  display: block; margin: 0 auto; min-height: 100%;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .35); border-radius: 6px; position: relative;
}

/* Thông báo nổi ngắn ở cạnh dưới màn hình (VD: vừa kéo 1 phần tử sang Section khác). Là con
   TRỰC TIẾP của .ac-visual-layout (không nằm trong .ac-visual-stage-wrap) — .ac-visual-layout
   không cuộn, nên vị trí "absolute" ở đây luôn bám đúng cạnh dưới khung làm việc, không bị cuốn
   theo khi cuộn canvas dài bên trong .ac-visual-stage-wrap (từng đặt nhầm bên trong đó: dù
   "position:absolute", "bottom" lại tính theo chiều cao TOÀN BỘ nội dung có thể cuộn, không phải
   khung nhìn đang thấy, nên trông như "dính" vào đúng section đang cuộn tới). Nằm trên nút
   zoom (bottom:12px) nên đặt bottom cao hơn để không đè lên nhau. Ẩn/hiện bằng opacity+visibility
   (không dùng [hidden]) để có hiệu ứng mờ dần và không phải lo rule display bị [hidden] đè. */
.ac-visual-toast {
  position: absolute; left: 50%; bottom: 56px; transform: translate(-50%, 8px);
  background: rgba(30, 32, 48, .92); color: #fff; font-size: 12.5px; font-weight: 600;
  padding: 8px 16px; border-radius: 999px; box-shadow: 0 6px 20px rgba(0, 0, 0, .35);
  pointer-events: none; opacity: 0; visibility: hidden; white-space: nowrap; z-index: 50;
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
}
.ac-visual-toast.is-visible { opacity: 1; visibility: visible; transform: translate(-50%, 0); }

/* Mô tả nút trên thanh công cụ nổi của khối (#toolbar / #multiToolbar trong canvas) — hiện NGAY khi rê chuột (tooltip
   gốc của trình duyệt trễ khoảng 1 giây), cố định ở cạnh dưới khung làm việc, ngay trên bảng điều khiển dưới cùng. Con
   trực tiếp của .ac-visual-layout như .ac-visual-toast nên không trôi theo khi cuộn canvas; nằm đè lên toast nếu trùng lúc. */
.ac-visual-tool-tip {
  position: absolute; left: 50%; bottom: 62px; transform: translate(-50%, 6px);
  width: max-content; max-width: min(620px, calc(100% - 32px)); z-index: 55;
  padding: 9px 14px; border-radius: 10px;
  background: var(--ac-code-panel); border: 1px solid var(--ac-border); box-shadow: 0 12px 32px rgba(0, 0, 0, .45);
  color: var(--ac-ink-soft); font-size: 12.5px; line-height: 1.5;
  pointer-events: none; opacity: 0; visibility: hidden;
  transition: opacity .12s ease, transform .12s ease, visibility .12s;
}
.ac-visual-tool-tip.is-visible { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
.ac-visual-tool-tip-name { display: block; color: var(--ac-ink); font-size: 13px; font-weight: 700; margin-bottom: 2px; }
.ac-visual-tool-tip-desc { display: block; }
.ac-visual-tool-tip-key {
  display: inline-block; margin-top: 6px; padding: 1px 7px; border-radius: 5px;
  border: 1px solid var(--ac-border); color: var(--ac-ink); font-size: 11.5px; font-weight: 600;
}
/* Dòng nhắc cuối: có thể tắt phần mô tả này trong Cài đặt → Giao diện. */
.ac-visual-tool-tip-off {
  display: block; margin-top: 6px; padding-top: 5px; border-top: 1px solid var(--ac-border);
  font-size: 11.5px; opacity: .8;
}
@media (prefers-reduced-motion: reduce) { .ac-visual-tool-tip { transition: none; } }

/* Thanh Desktop/Mobile + dropdown kích thước — giờ nằm trong .ac-editor-toolbar (gộp chung với
   .ac-tabs), không còn nổi trên canvas nữa nên không cần position:absolute; chỉ ẩn/hiện theo
   tab đang chọn (xem switchTab trong editor.js, toggle .hidden trực tiếp bằng JS vì toolbar
   đứng TRƯỚC #acEditorBody trong DOM — CSS không có bộ chọn "sibling đứng trước"). */
.ac-toolbar-device-toggle { display: flex; align-items: center; gap: 3px; }
/* Ẩn bằng visibility chứ KHÔNG phải display:none — cụm này chỉ vô nghĩa ở tab Console, nhưng nếu
   biến mất hẳn khỏi bố cục thì mọi nút quanh nó nhảy chỗ mỗi lần đổi tab. Giữ nguyên chỗ, chỉ tàng
   hình và không bấm được. */
.ac-toolbar-device-toggle.is-hidden { visibility: hidden; pointer-events: none; }
.ac-device-width-dropdown { position: relative; }
.ac-device-width-btn {
  border: none; background: transparent; color: var(--ac-ink-soft); font-size: 12px; font-weight: 700;
  padding: 5px 8px; border-radius: 6px; cursor: pointer; display: inline-flex; align-items: center; gap: 4px;
}
.ac-device-width-btn:hover { background: rgba(255, 255, 255, .08); color: var(--ac-ink); }
/* Bề rộng cố định cho nhãn mốc: "1200px" dài hơn "420px" kha khá, để tự co giãn thì mỗi lần đổi
   mốc là cả cụm nút rộng/hẹp theo, các nút bên cạnh lại xê dịch. */
#acDeviceWidthLabel { display: inline-block; min-width: 48px; text-align: center; }
.ac-device-width-menu {
  position: absolute; top: 100%; left: 0; margin-top: 6px; min-width: 100px; z-index: 50;
  background: var(--ac-code-panel); border: 1px solid var(--ac-border); border-radius: 8px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .4); overflow: hidden; display: flex; flex-direction: column;
}
.ac-device-width-opt {
  border: none; background: transparent; color: var(--ac-ink-soft); font-size: 12.5px; font-weight: 600;
  padding: 8px 14px; text-align: left; cursor: pointer;
}
.ac-device-width-opt:hover { background: rgba(255, 255, 255, .08); color: var(--ac-ink); }
.ac-device-width-opt.active { color: #fff; background: var(--ac-accent); }

/* Nút zoom to/nhỏ — cố định dưới đáy, canh giữa, cùng kiểu nổi như thanh kích thước trên đầu. */
/* Bảng điều khiển nổi ở cạnh dưới khu vực làm việc: gom mức thu phóng + lực hút (bên trái) và
   2 nút hoàn tác/làm lại (bên phải) vào cùng 1 chỗ, thay vì để rời rạc giữa canvas. Là con TRỰC
   TIẾP của .ac-visual-layout (không nằm trong .ac-visual-stage-wrap) nên luôn bám đúng cạnh dưới
   khung làm việc, không bị cuốn đi khi cuộn canvas dài — cùng lý do với .ac-visual-toast. */
.ac-visual-bottom-bar {
  position: absolute; bottom: 12px; left: 50%; transform: translateX(-50%);
  z-index: 6; display: flex; align-items: center; gap: 6px;
  /* Nền + viền + đổ bóng lấy đúng bộ của palette/panel thuộc tính để 3 panel nổi trông cùng 1 họ. */
  padding: 5px 8px; background: var(--ac-code-panel); border: 1px solid var(--ac-border);
  border-radius: 12px; box-shadow: 0 12px 32px rgba(0, 0, 0, .4);
}
/* Các nhóm nút BÊN TRONG bảng bỏ nền pill riêng — nếu không sẽ thành pill lồng trong pill, rối
   mắt và mất cảm giác "1 bảng liền mạch". Ngăn cách giữa các nhóm bằng 1 vạch mảnh. */
.ac-visual-bottom-bar .ac-view-toggle { background: transparent; padding: 0; }
.ac-visual-bottom-sep { width: 1px; align-self: stretch; margin: 2px 2px; background: var(--ac-border); }

/* Sơ đồ các khối trong trang — bung LÊN TRÊN từ chính bảng điều khiển (bottom:100%), canh giữa
   theo nút bấm, cùng bộ nền/viền/bóng với các panel nổi khác. */
.ac-visual-outline-panel {
  position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%);
  width: 300px; max-height: min(60vh, 460px); overflow-y: auto; padding: 6px;
  background: var(--ac-code-panel); border: 1px solid var(--ac-border);
  border-radius: 10px; box-shadow: 0 12px 32px rgba(0, 0, 0, .45);
}
.ac-visual-outline-empty { color: var(--ac-ink-soft); font-size: 12px; padding: 10px 8px; text-align: center; }
.ac-visual-outline-row {
  display: flex; align-items: center; gap: 6px; width: 100%; border: none; background: transparent;
  color: var(--ac-ink); font-size: 12px; font-weight: 600; text-align: left;
  padding: 5px 6px; border-radius: 6px; cursor: pointer;
}
.ac-visual-outline-row:hover { background: rgba(255, 255, 255, .07); }
.ac-visual-outline-row.is-selected { background: var(--ac-accent); color: #fff; }
.ac-visual-outline-row .ac-icon { width: 14px; height: 14px; flex: 0 0 auto; opacity: .85; }
.ac-visual-outline-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ac-visual-outline-row.is-hidden-block { opacity: .45; }
.ac-visual-zoom-control {
  display: flex; align-items: center; gap: 2px; width: fit-content; margin: 0;
}
.ac-visual-history-control { display: flex; align-items: center; gap: 2px; }
.ac-visual-history-control .ac-view-btn { padding: 5px 9px; }
.ac-visual-history-control .ac-view-btn:disabled { opacity: .35; cursor: not-allowed; }
.ac-visual-zoom-control .ac-view-btn { font-size: 15px; font-weight: 700; padding: 5px 12px; }
#acZoomLabel { font-size: 12px; font-weight: 700; color: var(--ac-ink-soft); padding: 0 6px; min-width: 40px; text-align: center; }

/* ── Palette bên trái + panel thuộc tính bên phải: nổi đè (floating), không chiếm chỗ ngang
   của canvas — z-index cao hơn canvas, nền + đổ bóng để đọc được rõ dù đè lên nội dung. ───── */
.ac-visual-palette, .ac-visual-props {
  position: absolute; top: 12px; bottom: 12px; z-index: 5; width: 160px; overflow-y: auto;
  padding: 10px; background: var(--ac-code-panel); border: 1px solid var(--ac-border);
  border-radius: 10px; box-shadow: 0 12px 32px rgba(0, 0, 0, .4);
}
.ac-visual-palette { left: 12px; display: flex; flex-direction: column; gap: 6px; }
/* Panel thuộc tính kéo-thả được (xem acVisualPropsHandle trong visual-editor.js) — mặc định vẫn
   cố định bên phải như trước, nhưng bấm-kéo thanh tiêu đề để dời đi bất kỳ đâu trong vùng làm
   việc; bấm đúp vào thanh đó để đưa về lại đúng vị trí cố định bên phải ban đầu. Đổi sang
   flex-column: thanh tiêu đề đứng yên, chỉ phần nội dung bên dưới cuộn riêng. */
.ac-visual-props {
  right: 12px; width: 300px; padding: 0; display: flex; flex-direction: column; overflow: hidden;
}
.ac-visual-props-handle {
  flex-shrink: 0; display: flex; align-items: center; gap: 6px; padding: 9px 8px 9px 12px;
  font-size: 11.5px; font-weight: 700; color: var(--ac-ink-soft); border-bottom: 1px solid var(--ac-border);
  cursor: grab; user-select: none;
}
.ac-visual-props-handle:active { cursor: grabbing; }
.ac-visual-props-handle .ac-icon { width: 14px; height: 14px; flex-shrink: 0; }
/* Tên khối (updatePropsHandleTitle) — chiếm hết chỗ còn lại, cắt gọn (...) nếu tên quá dài thay
   vì đẩy 2 nút bên phải ra khỏi khung panel. */
.ac-visual-props-handle-title {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Ô nhập tên khi bấm nút bút chì (beginRenamePropsHandle) — thay thế đúng vị trí span tiêu đề ở
   trên, cùng kích thước hàng, viền/nền theo đúng theme tối của panel (mặc định trình duyệt sẽ ra
   ô trắng khó đọc trên nền tối nếu không khai riêng). */
.ac-visual-props-handle-input {
  flex: 1 1 auto; min-width: 0; height: 24px; padding: 2px 6px; font-size: 11.5px; font-weight: 700;
  background: rgba(255, 255, 255, .08); color: var(--ac-ink); border: 1px solid var(--ac-accent);
  border-radius: 5px;
}
.ac-visual-props-reset-btn, .ac-visual-props-rename-btn {
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0; border-radius: 6px; border: none; background: transparent;
  color: var(--ac-ink-soft); cursor: pointer;
}
.ac-visual-props-reset-btn:hover, .ac-visual-props-rename-btn:hover { color: var(--ac-ink); background: rgba(255, 255, 255, .08); }
.ac-visual-props-reset-btn .ac-icon, .ac-visual-props-rename-btn .ac-icon { width: 14px; height: 14px; }
/* min-height: 0 — không có dòng này, 1 flex item mặc định không co dưới chiều cao NỘI DUNG của
   nó (min-height: auto ngầm định), nên khi panel cha bị giới hạn max-height (kéo xuống thấp, xem
   clampPropsPanelToViewport trong visual-editor.js) nội dung dài vẫn ép panel cao hơn mức đó thay
   vì tự cuộn bên trong — mất hẳn tác dụng của overflow-y: auto ở dòng này. */
.ac-visual-props-content { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 14px; }
/* Thanh cuộn của bảng thuộc tính, bảng phần tử, khung canvas: dùng luật thanh cuộn chung của toàn builder-html
   (builder-html.css — "Thanh cuộn mảnh, cùng tông thương hiệu"), không khai báo riêng ở đây nữa. */

.ac-vpal-item {
  display: flex; align-items: center; gap: 8px; padding: 9px 10px; border-radius: 8px;
  background: rgba(255, 255, 255, .04); border: 1px solid var(--ac-border); color: var(--ac-ink-soft);
  font-size: 12.5px; font-weight: 600; cursor: grab; user-select: none;
}
.ac-vpal-item:hover { background: rgba(255, 255, 255, .08); color: var(--ac-ink); }
.ac-vpal-item:active { cursor: grabbing; }
.ac-vpal-icon { display: inline-flex; width: 18px; flex-shrink: 0; }

.ac-visual-props-empty, .ac-visual-props-hint { font-size: 12.5px; color: var(--ac-ink-soft); line-height: 1.6; }
.ac-visual-props-title { font-size: 13px; font-weight: 700; color: var(--ac-ink); margin-bottom: 10px; }
.ac-visual-props-hint { margin-bottom: 10px; }
.ac-visual-img-preview {
  width: 100%; height: 90px; border-radius: 6px; background-size: cover; background-position: center;
  background-color: rgba(255, 255, 255, .05); margin-bottom: 8px; border: 1px solid var(--ac-border);
}
/* Input trong panel tối cần nền/màu chữ riêng — .ac-field input mặc định không set nền,
   trên nền tối sẽ ra input nền trắng mặc định của trình duyệt, khó đọc. */
.ac-visual-props .ac-field label { color: var(--ac-ink-soft); }
/* .ac-visual-transform-field (renderTransformGrid — Góc xoay/Xoay trục X/Y/Nghiêng ngang/dọc)
   dùng RIÊNG class này thay vì .ac-field (bố cục icon+input nằm ngang thay vì nhãn-trên-input-
   dưới) nên phải liệt kê thêm ở đây — nếu không, input của nhóm này rơi về nền trắng mặc định
   của trình duyệt thay vì nền tối khớp phần còn lại của panel. */
.ac-visual-props .ac-field input, .ac-visual-props .ac-field textarea, .ac-visual-props .ac-field select,
.ac-visual-props .ac-visual-transform-field input {
  /* background-color (KHÔNG dùng shorthand "background") — select bên dưới cần tự vẽ thêm 1 lớp
     background-image (mũi tên xổ xuống riêng); shorthand "background" ở ĐÂY sẽ ngầm reset lại
     background-image về "none" bất kể thứ tự/độ ưu tiên của rule kia, xoá mất mũi tên vừa vẽ. */
  background-color: rgba(255, 255, 255, .06); color: var(--ac-ink); border-color: var(--ac-border);
}
.ac-visual-props .ac-field input::placeholder, .ac-visual-props .ac-field textarea::placeholder { color: #6a6f92; }
/* Ô nhập trong panel CAO BẰNG ô select: .ac-field input gốc (builder-html.css) dùng padding 9px +
   cỡ chữ 14px → cao 39px, trong khi select ở panel là padding 8px + 12.5px → cao 34px; đứng cạnh
   nhau trên cùng 1 hàng (fieldRow) thấy lệch hẳn. Khai lại đúng 2 số đó cho input/textarea.
   Trừ thanh trượt (range) và ô tick (checkbox) — 2 loại này có kiểu dáng riêng, không phải ô nhập. */
.ac-visual-props .ac-field input:not([type="range"]):not([type="checkbox"]),
.ac-visual-props .ac-field textarea,
.ac-visual-props .ac-visual-transform-field input { padding: 8px 10px; font-size: 12.5px; }
/* Ô SỐ chỉ hiện vài chữ số nên không cần rộng bằng cả hàng như ô chữ/ô select — kẹp lại cho vừa
   giá trị (max-width, không phải width: ô nào nằm trong cột hẹp hơn vẫn tự co theo cột). */
.ac-visual-props .ac-field > .ac-visual-number-stepper { max-width: 96px; }
/* CSS trên chỉ style được Ô SELECT ĐÓNG — danh sách <option> khi MỞ ra do trình duyệt tự vẽ theo
   nền mặc định (thường trắng), không tự thừa hưởng nền tối của ô select cha; chữ (color) THÌ có
   thừa hưởng, nên nếu không khai riêng, chữ sáng lại nằm trên nền trắng mặc định đó — gần như
   không đọc được. Khai riêng "select option" (không giới hạn trong .ac-field) để áp dụng luôn cho
   mọi select khác trong panel không nằm trong .ac-field (vd .ac-visual-event-row-head select). */
.ac-visual-props select option { background: var(--ac-code-panel); color: var(--ac-ink); }
/* select KHÔNG tự thừa hưởng padding từ rule "input, textarea" gốc (builder-html.css chỉ áp cho
   input/textarea, không có select) — lại còn giữ nguyên mũi tên xổ xuống MẶC ĐỊNH của hệ điều
   hành, không theo màu/kiểu icon của app — cả 2 khiến select trông lệch hẳn so với input/nút cạnh
   nó (thiếu đồng bộ thiết kế). Bỏ hẳn appearance gốc, tự vẽ padding riêng + 1 icon chevron-down
   (cùng path data với icon "chevron-down" dùng nơi khác trong app) làm mũi tên, tô màu --ac-ink-
   soft (#a3a8c9) khớp màu icon mặc định ở mọi nơi khác trong panel. 3 selector liệt kê đủ MỌI nơi
   có <select> trong panel (Thiết kế/Hiệu ứng/Nâng cao dùng chung .ac-field; Sự kiện có 2 lớp CSS
   riêng của nó) — cố tình viết ĐỦ 3 thay vì 1 rule "select" chung chung, để độ ưu tiên chắc chắn
   thắng các rule padding/border-radius cũ hơn của riêng từng nơi (vd .ac-visual-event-row-head
   select, .ac-visual-event-row > select) mà không phải phụ thuộc thứ tự khai báo trong file. */
.ac-visual-props .ac-field select,
.ac-visual-props .ac-visual-event-row-head select,
.ac-visual-props .ac-visual-event-row > select {
  width: 100%; padding: 8px 28px 8px 10px; border-radius: 6px; font-size: 12.5px; cursor: pointer;
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a3a8c9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 7px center; background-size: 13px 13px;
}
/* Thanh trượt "Độ trong suốt" — mặc định trình duyệt tự vẽ theo màu hệ điều hành (thường xanh
   dương), lệch hẳn tông tím của giao diện. -webkit-appearance: none/appearance: none bỏ hẳn dáng
   vẽ gốc, tự vẽ lại rãnh (track) + núm kéo (thumb) bằng đúng --ac-accent. */
.ac-visual-props .ac-field input[type="range"] {
  -webkit-appearance: none; appearance: none; padding: 0; background: transparent; border: none; cursor: pointer;
}
.ac-visual-props .ac-field input[type="range"]::-webkit-slider-runnable-track {
  height: 4px; border-radius: 999px; background: rgba(255, 255, 255, .15);
}
.ac-visual-props .ac-field input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; margin-top: -5px; width: 14px; height: 14px; border-radius: 50%;
  background: var(--ac-accent); border: 2px solid #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .4);
}
.ac-visual-props .ac-field input[type="range"]::-moz-range-track {
  height: 4px; border-radius: 999px; background: rgba(255, 255, 255, .15);
}
.ac-visual-props .ac-field input[type="range"]::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%; background: var(--ac-accent);
  border: 2px solid #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .4);
}
/* Ẩn nút xổ ▲▼ GỐC của trình duyệt (luôn theo màu hệ điều hành, không đổi được để khớp giao diện
   tối) — thay bằng nút xổ tự vẽ (wrapNumberStepper trong visual-editor.js) bọc quanh input. */
.ac-visual-props input[type="number"] { -moz-appearance: textfield; }
.ac-visual-props input[type="number"]::-webkit-outer-spin-button,
.ac-visual-props input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
/* Con trỏ đổi hẳn sang mũi tên 2 chiều khi đưa vào ô số — báo trước có thể NHẤN GIỮ rồi KÉO
   ngang để chỉnh nhanh (xem wireNumberScrub), không cần đợi bấm mới biết. */
.ac-visual-number-scrub { cursor: ew-resize; }
.ac-visual-number-stepper { display: flex; align-items: stretch; }
.ac-visual-number-stepper input[type="number"] { border-top-right-radius: 0; border-bottom-right-radius: 0; border-right: none; flex: 1 1 0; min-width: 0; }
.ac-visual-number-stepper-col {
  display: flex; flex-direction: column; flex-shrink: 0; width: 18px;
  border: 1px solid var(--ac-border); border-left: none; border-radius: 0 8px 8px 0; overflow: hidden;
}
.ac-visual-number-stepper-btn {
  flex: 1 1 0; display: flex; align-items: center; justify-content: center; padding: 0;
  border: none; background: rgba(255, 255, 255, .06); color: var(--ac-ink-soft); cursor: pointer; line-height: 0;
}
.ac-visual-number-stepper-btn:not(:first-child) { border-top: 1px solid var(--ac-border); }
.ac-visual-number-stepper-btn:hover { background: rgba(255, 255, 255, .14); color: var(--ac-ink); }
.ac-visual-number-stepper-btn .ac-icon { width: 11px; height: 11px; }

/* Nhóm 5 ô Góc xoay/Xoay trục X/Y/Nghiêng ngang/dọc (renderTransformGrid) — icon thay nhãn chữ
   (đầy đủ chuyển thành title, xem khi rê chuột) nên mỗi ô chỉ cần ~1/3 hàng, độ to ô input vừa
   phải thay vì phải đủ rộng chứa cả dòng nhãn chữ dài như trước. */
.ac-visual-transform-grid { display: flex; flex-wrap: wrap; gap: 8px 6px; margin-bottom: 14px; }
.ac-visual-transform-field { display: flex; align-items: center; gap: 5px; flex: 1 1 calc(33.333% - 4px); min-width: 64px; }
.ac-visual-transform-icon { flex-shrink: 0; display: inline-flex; color: var(--ac-ink-soft); }
.ac-visual-transform-icon .ac-icon { width: 14px; height: 14px; }
.ac-visual-transform-field .ac-visual-number-stepper { flex: 1 1 0; min-width: 0; }
.ac-visual-props .ac-field-checkbox label {
  display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 400; cursor: pointer; margin-bottom: 0;
}
.ac-visual-props .ac-field-checkbox input[type="checkbox"] { width: auto; accent-color: var(--ac-accent); cursor: pointer; }

/* Tiêu đề từng nhóm trong tab Thiết kế (groupHead): Kích thước / Chữ / Nền & viền / Hiển thị ảnh /
   Hiển thị & bộ lọc / Biến đổi hình dạng — chia panel thành từng cụm thay vì 1 dãy field dài. */
.ac-visual-group-head {
  margin: 12px 0 10px; padding-top: 13px; border-top: 1px solid var(--ac-border);
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ac-ink-soft);
}
.ac-visual-style-section > .ac-visual-group-head:first-child { margin-top: 0; padding-top: 0; border-top: none; }

/* Khối "Kiểu dáng" — cấu hình màu sắc/kích thước chữ, nền, bo góc... tuỳ theo LOẠI khối đang
   chọn (xem renderStyleSection trong visual-editor.js). ac-visual-style-section-flush: bỏ viền/
   khoảng đệm trên khi là NỘI DUNG DUY NHẤT của 1 thẻ mục (ngay dưới thanh thẻ mục, xem
   .ac-visual-props-tab-content bên dưới) — chỉ giữ viền khi xếp NGAY SAU 1 khối khác trong cùng
   1 thẻ mục (vd renderAdvancedSection sau renderPinSyncSection trong thẻ "Nâng cao"). */
.ac-visual-style-section { margin-top: 4px; padding-top: 10px; border-top: 1px solid var(--ac-border); }
.ac-visual-style-section-flush { margin-top: 0; padding-top: 0; border-top: none; }
.ac-visual-props-subhead { font-size: 12.5px; font-weight: 700; color: var(--ac-ink-soft); margin-bottom: 8px; }
.ac-visual-seg-row { display: flex; gap: 4px; }
.ac-visual-seg-btn {
  flex: 1 1 0; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--ac-border); background: rgba(255, 255, 255, .06); color: var(--ac-ink-soft);
  font-size: 12.5px; font-weight: 600; padding: 7px 4px; border-radius: 6px; cursor: pointer;
}
.ac-visual-seg-btn:hover { color: var(--ac-ink); background: rgba(255, 255, 255, .12); }
.ac-visual-seg-btn.active { background: var(--ac-accent); color: #fff; border-color: var(--ac-accent); }
.ac-visual-seg-btn .ac-icon { width: 15px; height: 15px; }

/* Xếp 2 field cạnh nhau (fieldRow trong visual-editor.js) — vd Thẻ HTML + Cỡ chữ. */
.ac-visual-field-row { display: flex; gap: 8px; align-items: stretch; }
/* 2 ô trên cùng 1 hàng phải THẲNG HÀNG NHAU kể cả khi 1 nhãn dài phải xuống 2 dòng: nhãn đẩy phần
   điều khiển xuống đáy cột (margin-bottom: auto), nên ô nhập/ô màu của 2 cột luôn cùng 1 đường. */
.ac-visual-field-row > .ac-field { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; }
.ac-visual-props .ac-visual-field-row > .ac-field > label,
.ac-visual-props .ac-visual-field-row > .ac-field > .ac-visual-gradient-label-row {
  margin-bottom: auto; padding-bottom: 6px;
}

/* Màu đơn sắc/gradient/ảnh (colorOrGradientField) — nhãn + 3 icon chọn kiểu (Đơn sắc/Gradient/
   Ảnh) trên cùng 1 hàng, ô giá trị theo đúng kiểu đang chọn (1 ô màu / 2 ô màu + góc / 1 ảnh xem
   trước) ở hàng dưới. */
.ac-visual-gradient-label-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-bottom: 6px; }
.ac-visual-gradient-label-row label { margin-bottom: 0; }
.ac-visual-gradient-mode-row { display: flex; gap: 2px; }
.ac-visual-gradient-mode-btn {
  display: flex; align-items: center; justify-content: center; width: 20px; height: 20px;
  border: 1px solid var(--ac-border); background: rgba(255, 255, 255, .06); color: var(--ac-ink-soft);
  border-radius: 5px; cursor: pointer; padding: 0;
}
.ac-visual-gradient-mode-btn:hover { color: var(--ac-ink); background: rgba(255, 255, 255, .12); }
.ac-visual-gradient-mode-btn.active { background: var(--ac-accent); border-color: var(--ac-accent); color: #fff; }
.ac-visual-gradient-mode-btn .ac-icon { width: 12px; height: 12px; }
.ac-visual-gradient-inputs { display: flex; gap: 6px; }
.ac-visual-gradient-angle { flex: 0 0 58px; }
/* Ảnh xem trước (kiểu "Ảnh") — bấm vào để đổi ảnh khác, giống hệt thao tác đổi ảnh của khối
   Hình ảnh (xem .ac-visual-img-preview) nhưng thấp hơn để khớp chiều cao 1 ô màu/gradient. */
.ac-visual-gradient-image-preview {
  width: 100%; height: 30px; border-radius: 6px; background-size: cover; background-position: center;
  background-color: rgba(255, 255, 255, .06); border: 1px solid var(--ac-border); cursor: pointer;
}
/* Compact: Màu chữ/Màu nền giờ luôn dồn chung 1 hàng với Cỡ chữ/Bo góc (xem renderStyleSection)
   — ô màu không cần rộng bằng nửa hàng nữa, thu nhỏ về 1 ô vuông nhỏ cố định. */
/* Gom "Màu chữ"/"Màu nền" thành 1 KHỐI nhìn thấy rõ: nhãn + 3 nút kiểu (Đơn sắc/Gradient/Ảnh) +
   ô giá trị nằm chung 1 khung viền — trước đây 3 phần rời nhau, người dùng khó nhận ra 3 nút đó
   là của chính ô màu bên dưới chứ không phải của field bên cạnh. */
.ac-visual-props .ac-field-gradient {
  padding: 8px; border: 1px solid var(--ac-border); border-radius: 8px;
  background: rgba(255, 255, 255, .03);
}
.ac-visual-props .ac-field-gradient > .ac-visual-gradient-label-row { margin-bottom: 8px; }
.ac-visual-props .ac-visual-field-row > .ac-field-gradient > .ac-visual-gradient-label-row { padding-bottom: 0; }
/* Ô màu đứng cạnh 1 ô số (vd "Màu chữ" + "Cỡ chữ"): ô màu cần chỗ cho nhãn + 3 nút kiểu + ô giá trị,
   còn ô số chỉ hiện vài chữ số (đã kẹp 96px) — chia 2/3 cho ô màu thay vì 50/50 để nhãn khỏi xuống dòng. */
.ac-visual-props .ac-visual-field-row > .ac-field-gradient { flex: 2 1 0; }
/* Hàng có 1 ô cao hơn hẳn vì mang thêm nút/gợi ý bên dưới (vd Phông chữ + nút Tải font chữ lên):
   canh theo MÉP TRÊN, không canh đáy — nếu không ô còn lại bị kéo tụt xuống cho bằng chiều cao. */
.ac-visual-props .ac-visual-field-row.is-top { align-items: flex-start; }
/* Ô chọn phần tử đích của "Sự kiện": ô tìm nằm trên, ô chọn nằm dưới, cùng chiều rộng. */
.ac-visual-props .ac-visual-event-target { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ac-visual-props .ac-visual-event-target-search { font-size: 11.5px; }
.ac-visual-props .ac-visual-field-row.is-top > .ac-field > label,
.ac-visual-props .ac-visual-field-row.is-top > .ac-field > .ac-visual-gradient-label-row { margin-bottom: 6px; padding-bottom: 0; }
.ac-field-gradient-compact .ac-visual-gradient-inputs { gap: 4px; }
.ac-field-gradient-compact .ac-visual-gradient-angle { flex: 1 1 0; min-width: 0; font-size: 12px; padding: 5px 4px; }

/* Nút "Nâng cao" (biểu tượng, không chữ) mở/đóng lưới 4 ô chỉnh riêng từng góc/cạnh — dùng chung
   .ac-visual-gradient-label-row làm hàng nhãn (đã có sẵn layout label + nút bên phải, xem
   pxStyleFieldWithAdvanced). Lưới 2x2 hiện ngay dưới ô đồng bộ khi bấm mở. */
.ac-visual-advanced-toggle {
  /* margin-right: auto — nút đứng NGAY SAU nhãn của chính nó. Trước đây hàng nhãn dàn 2 đầu
     (space-between) nên nút bị đẩy ra tận mép phải của cột: với field nửa hàng (vd "Bo góc" nằm
     cạnh "Cách hiển thị ảnh") nó rơi vào đúng khoảng giữa 2 cột, trông như nút của ô BÊN CẠNH. */
  margin-right: auto;
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border: 1px solid var(--ac-border); border-radius: 5px;
  background: rgba(255, 255, 255, .06); color: var(--ac-ink-soft); cursor: pointer;
}
.ac-visual-advanced-toggle:hover { color: var(--ac-ink); background: rgba(255, 255, 255, .14); }
.ac-visual-advanced-toggle.active { background: var(--ac-accent); border-color: var(--ac-accent); color: #fff; }
.ac-visual-advanced-toggle .ac-icon { width: 12px; height: 12px; }
/* Ảnh của Hình ảnh (renderImageSourceField): hình thu nhỏ + nút Đổi ảnh cùng 1 hàng; Mô tả ảnh (alt) ẩn sau nút nâng cao. */
.ac-visual-advanced-toggle.has-value:not(.active) { border-color: var(--ac-accent); color: var(--ac-ink); }
.ac-visual-img-row { display: flex; align-items: center; gap: 10px; }
.ac-visual-img-thumb {
  flex: 0 0 72px; width: 72px; height: 48px; padding: 0; border-radius: 6px; cursor: pointer;
  background-size: cover; background-position: center; background-color: rgba(255, 255, 255, .05); border: 1px solid var(--ac-border);
}
.ac-visual-img-thumb:hover { border-color: var(--ac-accent); }
.ac-visual-img-row .ac-btn { flex: 1 1 auto; justify-content: center; }
/* Ô Icon (phần tử Icon) và ô Mask (Hình ảnh): cùng hàng [hình][nút] như ô Ảnh — xem renderIconSourceField/renderImageMaskField. */
.ac-visual-img-thumb.is-icon, .ac-visual-img-thumb.is-mask {
  display: flex; align-items: center; justify-content: center; padding: 6px; color: var(--ac-ink);
  background-size: contain; background-repeat: no-repeat; background-position: center;
  background-color: rgba(255, 255, 255, .06);
}
.ac-visual-img-thumb.is-icon svg { width: 100%; height: 100%; }
.ac-visual-img-thumb.is-empty { color: var(--ac-ink-soft); border-style: dashed; }
.ac-visual-img-thumb.is-empty .ac-icon { width: 20px; height: 20px; }
.ac-visual-img-row .ac-visual-mask-clear { flex: 0 0 auto; padding: 0 9px; }
.ac-visual-mask-fit { margin-top: 8px; }
.ac-visual-mask-hint { margin: 6px 0 0; font-size: 11.5px; line-height: 1.45; color: var(--ac-ink-soft); }

/* Bộ lọc màu (renderFilterSection): nhóm gập lại được, mở ra là 1 ô Hoà trộn + các cặp ô số. */
.ac-visual-filter-body[hidden] { display: none; }
.ac-visual-filter-body { margin-top: 8px; }
/* Dấu ">" là BẮT BUỘC: không có nó, rule bắt luôn ô BÊN PHẢI của mọi hàng (ô cuối trong .ac-visual-
   field-row) → ô đó mất lề dưới, hàng cao hơn 14px và ô bên phải bị đẩy tụt xuống, trông lệch hàng. */
.ac-visual-filter-body > .ac-field:last-child { margin-bottom: 0; }
.ac-visual-filter-reset {
  display: inline-flex; align-items: center; gap: 5px; margin-top: 2px; padding: 5px 9px;
  border: 1px solid var(--ac-border); border-radius: 6px; background: transparent;
  color: var(--ac-ink-soft); font-size: 11.5px; font-weight: 600; cursor: pointer;
}
.ac-visual-filter-reset:hover { color: var(--ac-ink); border-color: var(--ac-accent); }
.ac-visual-filter-reset .ac-icon { width: 12px; height: 12px; }
.ac-visual-img-fit { margin: 10px 0 0; }
.ac-visual-img-advanced { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--ac-border); }
.ac-visual-img-advanced[hidden] { display: none; }
.ac-visual-props .ac-visual-img-advanced label { font-size: 12px; font-weight: 600; margin-bottom: 4px; }
.ac-visual-advanced-positions-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px 8px; margin-top: 8px;
  padding-top: 8px; border-top: 1px dashed var(--ac-border);
}
.ac-visual-advanced-position-field { margin-bottom: 0; }
.ac-visual-advanced-position-field label { font-size: 11px; font-weight: 600; margin-bottom: 3px; }

/* Bảng Thuộc tính: 4 thẻ mục dạng biểu tượng (icon trên, chữ dưới), xếp ngang, bấm mục nào hiện
   đúng nội dung mục đó (xem renderPropsTabs trong visual-editor.js) — thay cho việc xếp chồng
   liên tiếp cả 4 khối "Kiểu dáng"/"Sự kiện"/"Hiệu ứng"/"Nâng cao". */
.ac-visual-props-tabs-wrap { margin-top: 6px; }
/* Dính (sticky) ở đầu VÙNG CUỘN #acVisualPropsContent — khi bảng Thuộc tính bị kéo ngắn lại
   (xem clampPropsPanelToViewport) và nội dung 1 thẻ mục dài hơn chỗ còn lại, cuộn xuống xem hết
   nội dung KHÔNG được cuộn mất luôn cả hàng 4 thẻ mục. top:-14px + margin/padding ngang bù trừ
   đúng phần đệm 14px của #acVisualPropsContent để hàng thẻ mục dính khít sát mép trên/2 bên khi
   cuộn tới, nền đặc (không trong suốt) để chữ/field cuộn phía dưới không lộ xuyên qua. */
.ac-visual-props-tabs {
  position: sticky; top: -14px; z-index: 2;
  display: flex; gap: 4px; margin: -14px -14px 12px; padding: 14px 14px 10px;
  background: var(--ac-code-panel); border-bottom: 1px solid var(--ac-border);
}
.ac-visual-props-tab {
  flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 4px;
  border: 1px solid transparent; background: transparent; color: var(--ac-ink-soft);
  padding: 7px 2px; border-radius: 8px; cursor: pointer; font-size: 11px; font-weight: 600;
}
.ac-visual-props-tab .ac-icon { width: 17px; height: 17px; }
.ac-visual-props-tab span { line-height: 1.2; }
.ac-visual-props-tab:hover { color: var(--ac-ink); background: rgba(255, 255, 255, .06); }
.ac-visual-props-tab.active { color: #fff; background: var(--ac-accent); }
.ac-visual-props-tab-content { min-width: 0; }
/* Từng khối con bên trong 1 thẻ mục (vd "Nâng cao" gồm 2 khối: Ghim & đồng bộ, rồi CSS/JS) —
   giống .ac-visual-style-section (viền trên phân cách), nhưng khối ĐẦU TIÊN của thẻ mục đó nên
   sát luôn lên thanh thẻ mục (không viền/đệm thừa) — dùng thêm class -flush cho khối đầu tiên. */
.ac-visual-props-tab-section { margin-top: 4px; padding-top: 10px; border-top: 1px solid var(--ac-border); }
.ac-visual-props-tab-section-flush { margin-top: 0; padding-top: 0; border-top: none; }
.ac-visual-props-tab-section .ac-field + .ac-visual-props-hint { margin-top: -2px; }
.ac-visual-code-area {
  font-family: "Cascadia Code", Consolas, "Courier New", monospace; font-size: 12px; line-height: 1.5;
  resize: vertical; min-height: 64px;
}

/* Danh sách "Sự kiện" (renderEventRow trong visual-editor.js) — mỗi sự kiện 1 thẻ: đầu thẻ "Sự kiện N" + nút xoá; lưới 2 cột
   nhãn ngắn | ô nhập, đọc thành câu "Khi … / Thì … / Phần tử …"; chân thẻ: Chờ (ms), Chỉ lần đầu. */
.ac-visual-events-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px; }
.ac-visual-event-row {
  display: flex; flex-direction: column; gap: 8px; padding: 8px 10px 10px; border-radius: 8px;
  background: rgba(255, 255, 255, .04); border: 1px solid var(--ac-border);
}
.ac-visual-event-row-head { display: flex; align-items: center; justify-content: space-between; min-height: 24px; }
.ac-visual-event-title { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ac-ink-soft); }
.ac-visual-event-del {
  flex: 0 0 auto; border: none; background: transparent; color: var(--ac-ink-soft); cursor: pointer; margin-right: -4px;
  width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border-radius: 6px;
}
.ac-visual-event-del:hover { color: #e8604a; background: rgba(232, 96, 74, .15); }
.ac-visual-event-del .ac-icon { width: 14px; height: 14px; }
.ac-visual-event-grid { display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: 6px 8px; align-items: center; }
.ac-visual-event-label { font-size: 12px; line-height: 1.3; color: var(--ac-ink-soft); }
.ac-visual-event-label.is-full, .ac-visual-event-ctl.is-full, .ac-visual-event-hint.is-full { grid-column: 1 / -1; }
.ac-visual-event-label.is-full { margin-bottom: -2px; }
.ac-visual-event-ctl { display: flex; align-items: center; gap: 6px; min-width: 0; }
.ac-visual-event-ctl > .ac-visual-event-input { flex: 1 1 auto; }
.ac-visual-event-hint { grid-column: 2; margin-top: -2px; font-size: 11.5px; line-height: 1.5; color: var(--ac-ink-soft); }
.ac-visual-props select optgroup { background: var(--ac-code-panel); color: var(--ac-ink-soft); font-style: normal; }
.ac-visual-props .ac-visual-event-input {
  width: 100%; min-width: 0; background: rgba(255, 255, 255, .06); color: var(--ac-ink); border: 1px solid var(--ac-border);
  border-radius: 6px; padding: 7px 9px; font-size: 12.5px;
}
.ac-visual-props .ac-visual-event-input::placeholder { color: #6a6f92; }
.ac-visual-props select.ac-visual-event-input {
  padding-right: 26px; cursor: pointer; appearance: none; -webkit-appearance: none; -moz-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a3a8c9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 7px center; background-size: 13px 13px;
}
.ac-visual-props textarea.ac-visual-event-input { resize: vertical; min-height: 64px; }
.ac-visual-event-checkbox { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ac-ink-soft); cursor: pointer; }
.ac-visual-event-checkbox input { width: auto; accent-color: var(--ac-accent); cursor: pointer; }
.ac-visual-event-num { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ac-ink-soft); }
.ac-visual-event-num .ac-visual-number-stepper { width: 88px; }
.ac-visual-props .ac-visual-event-num input[type="number"] {
  background: rgba(255, 255, 255, .06); color: var(--ac-ink); border: 1px solid var(--ac-border); border-right: none;
  border-radius: 6px 0 0 6px; padding: 6px 8px; font-size: 12.5px;
}
.ac-visual-event-foot {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 16px; padding-top: 8px;
  border-top: 1px dashed var(--ac-border); font-size: 12px; color: var(--ac-ink-soft);
}
.ac-visual-event-delay { display: inline-flex; align-items: center; gap: 8px; }
.ac-visual-event-empty {
  padding: 14px 12px; border-radius: 8px; border: 1px dashed var(--ac-border);
  text-align: center; font-size: 12.5px; color: var(--ac-ink-soft);
}
.ac-visual-event-add {
  width: 100%; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 10px; border-radius: 8px;
  border: 1px dashed var(--ac-border); background: transparent; color: var(--ac-ink); font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.ac-visual-event-add:hover { border-color: var(--ac-accent); background: rgba(124, 92, 255, .1); }
.ac-visual-event-add .ac-icon { width: 14px; height: 14px; }

/* Tab Hiệu ứng (renderEffectSection): hàng cuối [Lặp lại liên tục] ........ [▶ Chạy thử] */
.ac-visual-effect-actions { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ac-visual-effect-play {
  display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; border-radius: 6px; cursor: pointer;
  border: 1px solid var(--ac-accent); background: rgba(124, 92, 255, .16); color: var(--ac-ink); font-size: 12.5px; font-weight: 600;
}
.ac-visual-effect-play:hover { background: rgba(124, 92, 255, .28); }
.ac-visual-effect-play.is-playing { border-color: var(--ac-border); background: rgba(255, 255, 255, .06); }
.ac-visual-effect-play .ac-icon { width: 13px; height: 13px; }
/* Hiệu ứng chạm chuột: [Thời lượng (ms)] [▶ Chạy thử] cùng 1 hàng, nút canh theo đáy ô nhập. */
.ac-visual-hover-row { display: flex; align-items: flex-end; gap: 8px; }
.ac-visual-hover-row > .ac-field { flex: 1 1 0; min-width: 0; }
.ac-visual-hover-row > .ac-visual-effect-play { margin-bottom: 14px; padding-top: 8px; padding-bottom: 8px; }

/* Tab Nâng cao (round 56): Ghim vị trí [Toàn trang | Trong section] + 9 ô vị trí + khoảng cách 4 cạnh; đồng bộ gọn; ô code có nút phóng to. */
.ac-visual-props .ac-field.ac-field-checkbox { margin-bottom: 8px; }
.ac-visual-props .ac-field-checkbox .ac-visual-props-hint { margin: 2px 0 0 22px; font-size: 11.5px; line-height: 1.45; }
.ac-visual-adv-subhead { margin-top: 4px; }
.ac-visual-pin-body {
  display: flex; flex-direction: column; gap: 8px; padding: 8px; margin-bottom: 12px; border-radius: 8px;
  background: rgba(255, 255, 255, .04); border: 1px solid var(--ac-border);
}
.ac-visual-pin-scope .ac-visual-seg-btn { flex: 1 1 0; font-size: 12px; }
.ac-visual-pin-layout { display: flex; align-items: center; gap: 10px; }
.ac-visual-pin-grid {
  flex: 0 0 auto; display: grid; grid-template-columns: repeat(3, 22px); gap: 4px; padding: 5px;
  border-radius: 7px; border: 1px dashed var(--ac-border);
}
.ac-visual-pin-cell {
  position: relative; width: 22px; height: 22px; padding: 0; border-radius: 5px; cursor: pointer;
  border: 1px solid var(--ac-border); background: rgba(255, 255, 255, .04);
}
.ac-visual-pin-cell::after { content: ""; position: absolute; inset: 7px; border-radius: 2px; background: var(--ac-ink-soft); opacity: .45; }
.ac-visual-pin-cell:hover { border-color: var(--ac-accent); }
.ac-visual-pin-cell.active { background: var(--ac-accent); border-color: var(--ac-accent); }
.ac-visual-pin-cell.active::after { background: #fff; opacity: 1; }
.ac-visual-pin-offsets { flex: 1 1 0; min-width: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.ac-visual-pin-offset { display: flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--ac-ink-soft); transition: opacity .15s; }
.ac-visual-pin-offset span { flex: 0 0 26px; }
.ac-visual-props .ac-visual-pin-offset input {
  flex: 1 1 0; min-width: 0; width: 100%; padding: 5px 6px; font-size: 12px; border-radius: 6px;
  background: rgba(255, 255, 255, .06); color: var(--ac-ink); border: 1px solid var(--ac-border);
}
.ac-visual-pin-offset.is-off { opacity: .35; }
.ac-visual-props .ac-visual-code-field { margin-bottom: 10px; }
.ac-visual-code-head { display: flex; align-items: center; gap: 6px; margin-bottom: 5px; min-height: 24px; }
.ac-visual-props .ac-visual-code-head label { margin: 0; font-size: 12.5px; }
.ac-visual-code-note { font-size: 11.5px; color: var(--ac-ink-soft); }
.ac-visual-code-expand {
  margin-left: auto; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: 6px; background: transparent; color: var(--ac-ink-soft); cursor: pointer;
}
.ac-visual-code-expand:hover { color: var(--ac-ink); background: rgba(255, 255, 255, .1); }
.ac-visual-code-expand .ac-icon { width: 14px; height: 14px; }
/* Cửa sổ viết code lớn (openCodeModal) — gắn thẳng vào body. */
.ac-code-modal { max-width: 1000px; width: 94vw; height: min(80vh, 760px); max-height: none; }
.ac-code-modal .ac-modal-header h3 { margin: 0; font-size: 15px; }
.ac-code-modal-body { flex: 1 1 auto; min-height: 0; padding: 0; overflow: hidden; }
.ac-code-modal-body .CodeMirror { height: 100%; font-size: 13.5px; }
.ac-code-modal-fallback { width: 100%; height: 100%; border: none; padding: 12px; font: 13px/1.5 "Cascadia Code", Consolas, monospace; resize: none; }
.ac-code-modal-tip { margin-right: auto; font-size: 12px; color: var(--ac-ink-soft); }

/* Bảng màu tự vẽ (openColorPicker trong visual-editor.js) — thay <input type="color"> mặc định
   (không hỗ trợ alpha, hộp thoại chọn màu do HỆ ĐIỀU HÀNH vẽ nên không tài nào tuỳ biến giao diện
   được). Popup gắn thẳng vào document.body (position: fixed, NGOÀI panel Thuộc tính) nên phải tự
   khai đủ nền/viền/màu — không thừa hưởng được các quy tắc chỉ áp dụng trong .ac-visual-props. */
.ac-color-popup {
  position: fixed; z-index: 1000; width: 220px; padding: 12px; border-radius: 10px;
  background: var(--ac-code-panel); border: 1px solid var(--ac-border); box-shadow: 0 12px 32px rgba(0, 0, 0, .5);
  font-size: 12px;
}
.ac-color-sv-box {
  position: relative; width: 100%; height: 120px; border-radius: 6px; cursor: crosshair; margin-bottom: 10px;
  background-image: linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, transparent);
}
.ac-color-sv-thumb {
  position: absolute; width: 12px; height: 12px; border-radius: 50%; border: 2px solid #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .4), 0 1px 3px rgba(0, 0, 0, .5); transform: translate(-50%, -50%); pointer-events: none;
}
.ac-color-hue-slider, .ac-color-alpha-slider {
  position: relative; height: 10px; border-radius: 999px; cursor: pointer; margin-bottom: 10px; overflow: hidden;
}
.ac-color-hue-slider { background: linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00); }
.ac-color-alpha-slider {
  background-image: conic-gradient(#8a8f9c 90deg, #cfd3e6 90deg 180deg, #8a8f9c 180deg 270deg, #cfd3e6 270deg);
  background-size: 8px 8px;
}
.ac-color-alpha-gradient { position: absolute; inset: 0; }
.ac-color-slider-thumb {
  position: absolute; top: 50%; width: 14px; height: 14px; border-radius: 50%; background: #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .4), 0 1px 3px rgba(0, 0, 0, .5); transform: translate(-50%, -50%); pointer-events: none;
}
.ac-color-hex-row { display: flex; gap: 6px; margin-bottom: 10px; }
.ac-color-hex-input {
  flex: 1 1 0; min-width: 0; padding: 6px 8px; border-radius: 6px; border: 1px solid var(--ac-border);
  background: rgba(255, 255, 255, .06); color: var(--ac-ink); font-family: "Cascadia Code", Consolas, monospace; font-size: 12px;
}
/* Nút đổi kiểu hiển thị mã màu (Hex 6/8 số <-> rgba()) — chữ trên nút LUÔN là kiểu sẽ đổi SANG,
   giống mọi nút chuyển kiểu khác trong panel (vd Đơn sắc/Gradient/Ảnh). */
.ac-color-format-toggle {
  flex: 0 0 auto; border: 1px solid var(--ac-border); background: rgba(255, 255, 255, .06); color: var(--ac-ink-soft);
  font-size: 11px; font-weight: 700; padding: 0 8px; border-radius: 6px; cursor: pointer;
}
.ac-color-format-toggle:hover { color: var(--ac-ink); background: rgba(255, 255, 255, .14); }
.ac-color-swatch-section:not(:last-child) { margin-bottom: 10px; }
.ac-color-swatch-label { font-size: 11px; font-weight: 700; color: var(--ac-ink-soft); margin-bottom: 5px; }
.ac-color-swatch-row { display: flex; flex-wrap: wrap; gap: 5px; }
.ac-color-swatch {
  width: 20px; height: 20px; border-radius: 5px; border: 1px solid var(--ac-border); cursor: pointer; padding: 0;
  background-image: conic-gradient(#8a8f9c 90deg, #cfd3e6 90deg 180deg, #8a8f9c 180deg 270deg, #cfd3e6 270deg);
  background-size: 6px 6px;
}
.ac-color-swatch-empty { font-size: 11px; color: var(--ac-ink-soft); }

/* Nút vuông hiện màu hiện tại (thay input[type=color]) — nền caro phía sau để thấy rõ độ trong
   suốt, phủ màu thật lên trên qua biến --ac-swatch-color (JS đổi mỗi lần chọn màu mới, xem
   createColorSwatchButton). */
.ac-color-swatch-trigger {
  width: 30px; height: 30px; border-radius: 6px; border: 1px solid var(--ac-border); padding: 0; cursor: pointer;
  background-image: linear-gradient(var(--ac-swatch-color), var(--ac-swatch-color)),
    conic-gradient(#8a8f9c 90deg, #cfd3e6 90deg 180deg, #8a8f9c 180deg 270deg, #cfd3e6 270deg);
  background-size: 100% 100%, 8px 8px;
}
.ac-field-gradient-compact .ac-color-swatch-trigger { flex: 0 0 30px; }

@media (max-width: 860px) {
  .ac-visual-palette { width: 128px; }
  .ac-visual-props { width: 230px; }
  .ac-visual-stage-wrap { --ac-stage-pad-left: calc(158px * var(--ac-ui-scale, 1)); --ac-stage-pad-right: calc(260px * var(--ac-ui-scale, 1)); }
}

/* ── Cỡ giao diện + chế độ "Chỉ icon" (Cài đặt → Giao diện) cho 3 bảng nổi quanh canvas ───────
   Cỡ giao diện phóng to/thu nhỏ CẢ 3 bảng bằng zoom; khoảng chừa 2 bên canvas ở đầu file tính theo
   cùng hệ số --ac-ui-scale nên bảng phóng to không đè vào vùng làm việc. Panel thuộc tính kéo được:
   toạ độ kéo đã quy đổi theo zoom trong visual-editor.js (xem panelZoom). */
:is(html[data-ac-ui-scale="80"], html[data-ac-ui-scale="90"], html[data-ac-ui-scale="110"], html[data-ac-ui-scale="120"])
  :is(.ac-visual-palette, .ac-visual-props, .ac-visual-bottom-bar) { zoom: var(--ac-ui-scale, 1); }

/* "Chỉ icon" rút gọn BẢNG KHỐI + BẢNG ĐIỀU KHIỂN. Bảng thuộc tính KHÔNG rút gọn: chữ ở đó là tên
   các thông số đang chỉnh, bỏ đi thì không còn biết ô nào là ô nào (tên khối, cỡ chữ, màu...). */
html[data-ac-toolbar-labels="icons"] .ac-visual-palette { width: 46px; padding: 8px 6px; }
html[data-ac-toolbar-labels="icons"] .ac-vpal-item { justify-content: center; padding: 9px 6px; }
html[data-ac-toolbar-labels="icons"] .ac-vpal-label { display: none; }
html[data-ac-toolbar-labels="icons"] .ac-visual-stage-wrap { --ac-stage-pad-left: calc(76px * var(--ac-ui-scale, 1)); }
html[data-ac-toolbar-labels="icons"] .ac-visual-bottom-bar .ac-btn-label { display: none; }
html[data-ac-toolbar-labels="icons"] .ac-visual-bottom-bar .ac-view-btn { padding: 5px 8px; }

/* ── Chế độ điện thoại: chỉ sửa chữ + đổi ảnh (html[data-ac-phone="content"], xem "Chế độ điện thoại" trong visual-editor.js) ──
   Trang thiết kế dành cho máy tính; trên màn hình hẹp giấu mọi thứ để kéo thả/căn bố cục, chừa trọn màn hình cho trang và
   danh sách nội dung. "full" = người dùng tự chọn giao diện đầy đủ trên điện thoại — chỉ hiện thêm nút quay lại. */
.ac-phone-bar, .ac-phone-list, .ac-phone-hint, .ac-phone-back { display: none; }
html[data-ac-phone="content"] { --ac-phone-bar-h: 52px; --ac-phone-bottom-h: 62px; }

html[data-ac-phone="content"] :is(.ac-visual-palette, .ac-visual-props, .ac-visual-tool-tip, .ac-visual-stage-hint),
html[data-ac-phone="content"] .ac-visual-bottom-bar :is(.ac-visual-zoom-control, .ac-visual-outline-control, .ac-visual-bottom-sep, .ac-visual-outline-panel),
html[data-ac-phone="content"] :is(#acPromptBuilderBtn, #acDeviceToggle, .ac-tab[data-tab="console"]) { display: none !important; }
html[data-ac-phone="content"] .ac-editor-toolbar .ac-btn-label { display: none; }
/* Thanh công cụ trên cùng: logo + tên project chung 1 hàng, cụm trạng thái/chế độ/nút gọn lại vừa 1 hàng — không để lẻ 1 nút rớt
   xuống hàng riêng, chừa tối đa chiều cao cho trang đang sửa. */
html[data-ac-phone="content"] .ac-editor-toolbar { gap: 6px; padding: 8px 10px; }
/* Tên project chiếm hết phần còn lại của hàng đầu (cạnh logo) — mọi thứ sau nó xuống hàng 2, tên không bị ép còn vài chữ. */
html[data-ac-phone="content"] .ac-editor-title-input { flex: 1 1 calc(100% - 120px); min-width: 0; }
/* Nút "Chạy lại" chỉ dùng lúc Xem thử — ở máy tính giữ sẵn chỗ (visibility) cho các nút khỏi xê dịch, trên điện thoại chỗ trống
   đó chỉ làm hàng nút rộng thừa. */
html[data-ac-phone="content"] #acPreviewReloadBtn.is-hidden { display: none; }
html[data-ac-phone="content"] .ac-editor-toolbar .ac-btn-sm { padding: 6px 7px; }
html[data-ac-phone="content"] .ac-editor-toolbar .ac-tab { padding: 6px 8px; }

html[data-ac-phone="content"] .ac-phone-bar {
  display: flex; align-items: center; gap: 8px; position: absolute; top: 0; left: 0; right: 0; z-index: 7;
  height: var(--ac-phone-bar-h); box-sizing: border-box; padding: 0 10px;
  background: var(--ac-code-panel); border-bottom: 1px solid var(--ac-border);
}
.ac-phone-seg { display: flex; gap: 3px; padding: 3px; background: var(--ac-border); border-radius: 9px; }
.ac-phone-seg-btn {
  display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 0 12px; border: none; border-radius: 7px;
  background: transparent; color: var(--ac-ink-soft); font-size: 13px; font-weight: 700; cursor: pointer;
}
.ac-phone-seg-btn .ac-icon { width: 15px; height: 15px; }
.ac-phone-seg-btn.active { background: var(--ac-accent); color: #fff; }
.ac-phone-full-btn {
  margin-left: auto; display: inline-flex; align-items: center; gap: 5px; min-height: 36px; padding: 0 4px;
  border: none; background: transparent; color: var(--ac-ink-soft); font-size: 12px; font-weight: 600; cursor: pointer;
}
.ac-phone-full-btn .ac-icon { width: 14px; height: 14px; }

html[data-ac-phone="content"] .ac-visual-stage-wrap {
  top: var(--ac-phone-bar-h); bottom: var(--ac-phone-bottom-h); padding: 10px 8px;
  --ac-stage-pad-left: 8px; --ac-stage-pad-right: 8px; overflow-x: hidden;
}
html[data-ac-phone="content"] .ac-visual-layout.is-phone-list .ac-visual-stage-wrap { visibility: hidden; }

html[data-ac-phone="content"] .ac-phone-list:not([hidden]) {
  display: block; position: absolute; top: var(--ac-phone-bar-h); bottom: var(--ac-phone-bottom-h); left: 0; right: 0; z-index: 6;
  overflow-y: auto; padding: 12px 12px 24px; background: var(--ac-code-bg);
}
.ac-phone-list-section {
  margin: 16px 2px 8px; color: var(--ac-ink-soft); font-size: 11.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
}
.ac-phone-list-section:first-child { margin-top: 2px; }
.ac-phone-item {
  margin-bottom: 8px; padding: 10px 12px; border: 1px solid var(--ac-border); border-radius: 10px; background: var(--ac-code-panel);
}
.ac-phone-item-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; color: var(--ac-ink); font-size: 13px; font-weight: 700; }
.ac-phone-item-head .ac-icon { width: 15px; height: 15px; flex: 0 0 auto; color: var(--ac-ink-soft); }
.ac-phone-item-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ac-phone-item-find {
  flex: 0 0 auto; min-height: 32px; padding: 0 6px; border: none; background: transparent;
  color: var(--ac-ink-soft); font-size: 12px; font-weight: 600; text-decoration: underline; cursor: pointer;
}
/* 16px: nhỏ hơn thì Safari iOS tự phóng to cả trang mỗi lần chạm vào ô nhập. */
.ac-phone-textarea {
  display: block; width: 100%; box-sizing: border-box; min-height: 44px; padding: 8px 10px; resize: vertical;
  border: 1px solid var(--ac-border); border-radius: 8px; font: inherit; font-size: 16px; line-height: 1.5;
}
.ac-phone-list .ac-phone-textarea { background: var(--ac-code-bg); color: var(--ac-ink); overflow: hidden; }
.ac-phone-list .ac-phone-textarea:focus { outline: 2px solid var(--ac-accent); outline-offset: 1px; }
.ac-phone-item-image { display: flex; align-items: center; gap: 12px; }
.ac-phone-thumb {
  width: 72px; height: 72px; flex: 0 0 72px; object-fit: cover; border-radius: 8px;
  border: 1px solid var(--ac-border); background: #fff;
}
.ac-phone-empty { padding: 40px 16px; color: var(--ac-ink-soft); font-size: 13px; line-height: 1.6; text-align: center; }

html[data-ac-phone="content"] .ac-visual-bottom-bar { left: 8px; right: 8px; bottom: 8px; transform: none; justify-content: space-between; }
html[data-ac-phone="content"] .ac-phone-hint {
  display: block; min-width: 0; padding: 0 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--ac-ink-soft); font-size: 12px;
}
html[data-ac-phone="content"] .ac-visual-bottom-bar .ac-view-btn { min-width: 40px; min-height: 36px; justify-content: center; }

html[data-ac-phone="full"] .ac-phone-back {
  display: inline-flex; align-items: center; gap: 6px; position: absolute; left: 8px; bottom: 64px; z-index: 60;
  padding: 9px 13px; border: 1px solid var(--ac-border); border-radius: 999px; background: var(--ac-code-panel);
  color: var(--ac-ink); font-size: 12.5px; font-weight: 700; box-shadow: 0 8px 24px rgba(0, 0, 0, .4); cursor: pointer;
}
.ac-phone-back .ac-icon { width: 15px; height: 15px; }

.ac-phone-text-overlay { align-items: flex-start; padding-top: max(10px, 8vh); }
.ac-phone-notice { max-width: 420px; }
.ac-phone-notice .ac-modal-body { padding: 26px 22px 6px; text-align: center; }
.ac-phone-notice-icon {
  display: grid; place-items: center; width: 52px; height: 52px; margin: 0 auto 12px; border-radius: 14px;
  background: rgba(124, 92, 255, .12); color: var(--ac-accent);
}
.ac-phone-notice-icon .ac-icon { width: 26px; height: 26px; }
.ac-phone-notice h3 { margin: 0 0 10px; font-size: 18px; text-wrap: balance; }
.ac-phone-notice p { margin: 0 0 10px; color: var(--ac-ink-soft); font-size: 14px; line-height: 1.6; }
.ac-phone-notice .ac-modal-footer { justify-content: center; border-top: none; padding-bottom: 20px; }
