/* ========== Self-hosted Inter ==========
   Inter is bundled in fonts/ instead of fetched from Google CDN.
   Reasons:
     · No FOUT — the brand text in the titlebar used to flash as
       Segoe UI rendered first, then snapped to Inter when the
       CDN download completed. font-display: block holds rendering
       up to ~3 s for the local woff2, which loads in <50 ms from
       disk, so the user never sees the wrong font.
     · Works offline — Qt WebEngine apps must not depend on
       external CDNs for shell chrome.
   ======================================= */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  /* WEB (P5 perf): swap, KHÔNG block — block ẩn chữ tới ~3s khi tải font 344KB qua mạng,
     giết LCP. Đã có 'Inter Fallback' khớp metrics nên FOUT không gây nhảy layout.
     Desktop nạp font từ đĩa <50ms nên swap vẫn không thấy FOUT. */
  font-display: swap;
  src: url('fonts/Inter-roman.var.woff2') format('woff2-variations'),
       url('fonts/Inter-roman.var.woff2') format('woff2');
}
/* Belt-and-suspenders: a metrics-matched fallback so even on the
   very first frame before Inter binds, the system Segoe UI glyphs
   line up with Inter's width. Numbers from capsize / font-style-
   matcher for Inter vs Segoe UI. */
@font-face {
  font-family: 'Inter Fallback';
  src: local('Segoe UI'), local('Helvetica Neue'), local('Arial');
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

/* ========== Tokens ========== */
:root {
  /* Light (default) */
  --bg: #F7F7F7;
  --bg-elev: #FFFFFF;
  --dot: #D1D1D1;
  --panel: rgba(255,255,255,0.82);
  --panel-solid: #FFFFFF;
  --panel-hover: rgba(255,255,255,0.95);
  --border: #E5E5E5;
  --border-strong: #D2D2D7;
  --text: var(--mc-label);
  --text-2: var(--mc-label-2);
  --text-3: var(--mc-label-3);
  --accent: var(--mc-accent);
  --accent-hover: var(--mc-accent-press);
  --accent-soft: var(--mc-accent-soft);
  --green: var(--mc-success);
  --red: var(--mc-danger);
  --orange: var(--mc-warn);
  --yellow: #FFCC00;
  --purple: #AF52DE;
  --pink: #FF2D55;
  --rail: rgba(245,245,247,0.72);
  --selected: rgba(0,0,0,0.06);
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.04), 0 1px 1px rgba(0,0,0,0.03);
  --shadow-md: 0 8px 24px rgba(0,0,0,0.06), 0 2px 6px rgba(0,0,0,0.04);
  --shadow-lg: 0 24px 60px rgba(0,0,0,0.10), 0 4px 12px rgba(0,0,0,0.04);
  --log-bg: rgba(248,248,250,0.85);
  --log-text: var(--mc-label);
  --ring: 0 0 0 3px rgba(0,122,255,0.18);
}

[data-theme="dark"] {
  --bg: #1C1C1E;
  --bg-elev: #2C2C2E;
  --dot: #2E2E32;
  --panel: rgba(44,44,46,0.72);
  --panel-solid: #2C2C2E;
  --panel-hover: rgba(58,58,60,0.85);
  --border: #3A3A3C;
  --border-strong: #48484A;
  --text: #F5F5F7;
  --text-2: #AEAEB2;
  --text-3: #98989D;
  --accent: #f76f19;
  --accent-hover: #409CFF;
  --accent-soft: rgba(10,132,255,0.18);
  --green: #32D74B;
  --red: #FF453A;
  --orange: #FF9F0A;
  --yellow: #FFD60A;
  --purple: #BF5AF2;
  --pink: #FF375F;
  --rail: rgba(30,30,32,0.72);
  --selected: rgba(255,255,255,0.08);
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.35);
  --shadow-md: 0 8px 24px rgba(0,0,0,0.4), 0 2px 6px rgba(0,0,0,0.3);
  --shadow-lg: 0 24px 60px rgba(0,0,0,0.55), 0 4px 12px rgba(0,0,0,0.3);
  --log-bg: rgba(20,20,22,0.75);
  --log-text: #E5E5EA;
  --ring: 0 0 0 3px rgba(10,132,255,0.30);
}

* { box-sizing: border-box; }
html, body, #root { height: 100%; }
body {
  margin: 0;
  color: var(--text);
  background: var(--bg);
  /* Inter first (self-hosted, see top of file). Inter Fallback is
     a metrics-matched system stand-in for the ~50 ms before the
     woff2 binds — same glyph widths as Inter so there is no
     visible reflow on swap. */
  font-family: 'Inter', 'Inter Fallback', -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 13px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow: hidden;
}

/* Dot-grid canvas */
.canvas {
  position: absolute; inset: 0;
  background-color: var(--bg);
  background-image: radial-gradient(circle, var(--dot) 1px, transparent 1px);
  background-size: 22px 22px;
  background-position: 0 0;
}
[data-theme="dark"] .canvas {
  background-image: radial-gradient(circle, var(--dot) 1.2px, transparent 1.2px);
}

/* ========== App shell ========== */
.app {
  position: relative;
  height: 100vh; width: 100vw;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Title bar — macOS Big Sur "toolbar material".
   Slightly tinted relative to content + a thin hairline divider
   at the bottom so the chrome reads as a distinct surface. Apple's
   Finder/Mail use this exact layering: workspace is the bright
   surface, the toolbar sits a half-step darker. The frosted blur
   only matters when something scrolls under it (translucent
   modals, the rail), but we leave it on for consistency. */
.titlebar {
  height: 38px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  background: rgba(238, 238, 240, 0.92);
  backdrop-filter: saturate(180%) blur(22px);
  -webkit-backdrop-filter: saturate(180%) blur(22px);
  border-bottom: 1px solid rgba(0, 0, 0, 0.10);
  /* A 1 px highlight at the very top edge gives the surface a
     "lifted" feel — same trick Apple uses on NSToolbar. */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55);
  position: relative;
  z-index: 20;
  -webkit-user-select: none;
  user-select: none;
}
[data-theme="dark"] .titlebar {
  background: rgba(34, 34, 36, 0.92);
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.traffic { display: flex; gap: 8px; align-items: center; }
.traffic .dot {
  width: 12px; height: 12px; border-radius: 50%;
  border: 0.5px solid rgba(0,0,0,0.12);
  position: relative; cursor: default;
}
.traffic .close    { background: #FF605C; }
.traffic .minimize { background: #FFBD44; }
.traffic .max      { background: #00CA4E; }
[data-theme="dark"] .traffic .dot { border-color: rgba(0,0,0,0.3); }

/* Windows-style title-bar controls — flat square buttons with icon
   glyphs, sitting on the right of the titlebar. Overrides the macOS
   dot styling above when the titlebar is rendered with ``.win``. */
.traffic.win { gap: 0; margin-left: 4px; }
.traffic.win .dot {
  width: 48px; height: 38px;
  border-radius: 0;
  border: none;
  background: transparent;
  color: var(--text-2);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
  padding: 0;
}
.traffic.win .dot:hover    { background: var(--selected); color: var(--text); }
.traffic.win .close:hover  { background: #E81123; color: #FFFFFF; }
.traffic.win .close:hover svg line { stroke: #FFFFFF; }

/* Flex-centered title (2026-05-17): cũ dùng ``position:absolute``
   + ``transform:translateX(-50%)``. Cold-start trước khi CSS load
   xong, title flash ở góc upper-left → đè lên logo "CAD Translation
   Pro v20" trong vài ms. Mới: dùng ``flex:1`` + ``text-align:center``
   để title chiếm khoảng giữa, tự center bằng flex layout. CSS
   không-applied vẫn render inline-block → không flash overlap. */
.title {
  flex: 1;
  text-align: center;
  font-size: 13px; font-weight: 600; color: var(--text-2);
  letter-spacing: -0.01em;
  /* Prevent extremely long screen labels từ pushing title-right
     out of view. ``min-width:0`` cho phép flex item shrink dưới
     content size, ellipsis nếu cần. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.title-right {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--text-3);
  flex: 0 0 auto;
}

/* Workspace: rail + main */
.workspace {
  flex: 1; min-height: 0;
  display: flex;
  position: relative;
}

/* Left app rail — macOS "sidebar material".
   Tinted DEEPER than the toolbar (Apple's sidebar is the most
   tinted chrome surface) so the hierarchy reads workspace →
   toolbar → sidebar. A thin right-edge hairline separates it
   from the content; vibrancy via backdrop-filter keeps it from
   feeling like a flat slab. */
.rail {
  width: 56px;
  padding: 12px 0 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: rgba(229, 229, 232, 0.85);
  backdrop-filter: blur(30px) saturate(180%);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  border-right: 1px solid rgba(0, 0, 0, 0.08);
  /* Inner left-edge highlight + a thin right-edge inset shadow
     give the rail dimensionality without crowding it with a
     heavier border. */
  box-shadow:
    inset 1px 0 0 rgba(255, 255, 255, 0.55),
    inset -1px 0 0 rgba(0, 0, 0, 0.03);
  position: relative;
  z-index: 10;
}
/* MOBILE: ẩn rail app-shell → tool chạy FULL-WIDTH như app trên iPhone (mỗi tool tự có nav riêng). */
@media (max-width: 760px) { .rail { display: none; } }

/* ═══════════ BOTTOM TAB BAR (platform-wide, mobile-only) — dùng CHUNG cho trang chủ (Chợ) + mọi tool ═══════════ */
.botbar { display: none; }
.botbar-tab { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; background: none; border: none; color: var(--text-3); font: inherit; font-size: 10px; font-weight: 600; letter-spacing: .01em; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: color .15s; position: relative; padding: 0; }
.botbar-ic { width: 26px; height: 26px; display: grid; place-items: center; }
.botbar-lbl { line-height: 1; }
.botbar-tab.on { color: var(--accent); }
.botbar-tab:active { opacity: .55; }
.botbar-add { flex: 0 0 64px; }
.botbar-add .botbar-ic { width: 46px; height: 46px; border-radius: 16px; color: #fff; margin-top: -14px; background: linear-gradient(135deg, var(--accent), #7a5bff); box-shadow: 0 7px 18px color-mix(in oklab, var(--accent) 45%, transparent); transition: transform .14s; }
.botbar-add:active .botbar-ic { transform: scale(.92); }
/* bottom sheet (thông báo) */
.botsheet-ov { position: fixed; inset: 0; z-index: 210; background: rgba(16,18,28,.42); animation: bs-fade .18s ease; }
@keyframes bs-fade { from { opacity: 0; } to { opacity: 1; } }
.botsheet { position: absolute; left: 0; right: 0; bottom: 0; background: var(--panel-solid); border-radius: 22px 22px 0 0; box-shadow: 0 -10px 40px rgba(16,24,40,.24); padding: 8px 0 calc(16px + env(safe-area-inset-bottom)); max-height: 74vh; display: flex; flex-direction: column; animation: bs-up .3s cubic-bezier(.16,1,.3,1); }
@keyframes bs-up { from { transform: translateY(100%); } to { transform: translateY(0); } }
.botsheet-grip { width: 38px; height: 5px; border-radius: 3px; background: var(--border); margin: 6px auto 4px; }
.botsheet-hd { display: flex; align-items: center; justify-content: space-between; padding: 6px 18px 10px; border-bottom: 1px solid var(--border); }
.botsheet-hd b { font-size: 17px; font-weight: 700; }
.botsheet-x { width: 30px; height: 30px; border-radius: 9px; border: none; background: var(--selected); color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
.botsheet-body { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 14px 18px; }
.botsheet-empty { display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; padding: 34px 18px 30px; color: var(--text-3); }
.botsheet-empty .bse-ic { width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: color-mix(in oklab, var(--accent) 12%, transparent); color: var(--accent); }
.botsheet-empty b { color: var(--text); font-size: 15px; font-weight: 650; }
.botsheet-empty span { font-size: 13px; line-height: 1.5; max-width: 260px; }

@media (max-width: 760px) {
  .botbar { display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 200; align-items: stretch; height: calc(54px + env(safe-area-inset-bottom)); padding-bottom: env(safe-area-inset-bottom); background: color-mix(in oklab, var(--panel-solid) 86%, transparent); -webkit-backdrop-filter: saturate(180%) blur(22px); backdrop-filter: saturate(180%) blur(22px); border-top: 1px solid var(--border); box-shadow: 0 -1px 14px rgba(16,24,40,.06); }
  /* chừa chỗ cho tab bar ở MỌI màn (trang chủ + tool) — 1 đòn bẩy chung */
  .workspace { padding-bottom: calc(54px + env(safe-area-inset-bottom)); }
}
[data-theme="dark"] .rail {
  background: rgba(22, 22, 24, 0.92);
  border-right: 1px solid rgba(255, 255, 255, 0.06);
  box-shadow:
    inset 1px 0 0 rgba(255, 255, 255, 0.03),
    inset -1px 0 0 rgba(0, 0, 0, 0.30);
}
.rail-btn {
  width: 36px; height: 36px;
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-2);
  cursor: pointer;
  transition: all 120ms ease;
  border: none; background: transparent;
  position: relative;
}
.rail-btn:hover { background: var(--selected); color: var(--text); }
.rail-btn.active {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 2px 8px color-mix(in oklab, var(--accent) 40%, transparent);
}
.rail-btn .badge {
  position: absolute; top: 4px; right: 4px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--red);
  border: 2px solid var(--rail);
}
.rail-spacer { flex: 1; }

/* ── Claude-style account chip (bottom of rail) ───────────── */
.rail-divider {
  width: 28px; height: 1px; background: var(--border);
  margin: 6px 0 8px;
}
.rail-avatar {
  width: 36px; height: 36px;
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--mc-warn), #FF6A00);
  color: #fff;
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
  border: none;
  position: relative;
  transition: transform 120ms ease, box-shadow 120ms ease;
}
.rail-avatar:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(0,0,0,0.12); }
.rail-avatar .avatar-dot {
  position: absolute; bottom: -2px; right: -2px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--rail);
}
.rail-avatar.active { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Google profile picture variant — replaces the orange gradient
   background with a tightly-cropped img. ``object-fit: cover``
   keeps any non-square Google CDN image from squishing. */
.rail-avatar:has(.rail-avatar-img) { background: transparent; padding: 0; overflow: hidden; }
.rail-avatar-img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.rail-avatar-text {
  font-weight: 600; font-size: 13px;
}
/* Anonymous (Antigravity-style) — neutral grey gradient + person
   silhouette icon. Reads as "no identity yet" without screaming. */
.rail-avatar.is-anon {
  background: linear-gradient(135deg, #4b5563, #6b7280);
  color: #e5e7eb;
}
[data-theme="dark"] .rail-avatar.is-anon {
  background: linear-gradient(135deg, #374151, #4b5563);
  color: #d1d5db;
}
.rail-avatar-anon {
  width: 22px; height: 22px;
  opacity: 0.95;
}
.account-menu-avatar.is-anon {
  background: linear-gradient(135deg, #4b5563, #6b7280);
  box-shadow: 0 2px 8px rgba(75, 85, 99, 0.3);
}
[data-theme="dark"] .account-menu-avatar.is-anon {
  background: linear-gradient(135deg, #374151, #4b5563);
}

/* Popup menu */
.account-menu-backdrop {
  position: fixed; inset: 0; z-index: 99;
}
.account-menu {
  position: fixed;
  left: 64px; bottom: 14px;
  width: 260px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.14), 0 2px 8px rgba(0,0,0,0.08);
  padding: 6px;
  z-index: 100;
  animation: menu-in 140ms ease;
  display: flex; flex-direction: column;
}
[data-theme="dark"] .account-menu {
  box-shadow: 0 12px 40px rgba(0,0,0,0.5), 0 2px 8px rgba(0,0,0,0.3);
}
/* MOBILE: "Hồ sơ" mở dạng bottom sheet (rail bottom-left bị ẩn) — nổi TRÊN tab bar.
   Phải đặt SAU rule .account-menu gốc để thắng theo thứ tự nguồn (media query không tăng specificity). */
@media (max-width: 760px) {
  .account-menu-backdrop { z-index: 209; }
  .account-menu { left: 0; right: 0; bottom: 0; width: auto; border-radius: 22px 22px 0 0; padding: 8px 8px calc(12px + env(safe-area-inset-bottom)); max-height: 80vh; overflow-y: auto; z-index: 210; animation: bs-up .3s cubic-bezier(.16,1,.3,1); }
}
@keyframes menu-in {
  from { opacity: 0; transform: translateY(4px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}
.account-menu-email {
  padding: 10px 12px 6px;
  font-size: 12.5px;
  color: var(--text-2);
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.account-menu-header {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 12px 12px;
}
.account-menu-avatar {
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #6366f1, #8b5cf6);
  color: #fff;
  font-size: 14px; font-weight: 600; letter-spacing: 0.5px;
  flex-shrink: 0;
  box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);
  overflow: hidden;
}
.account-menu-avatar img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.account-menu-identity { flex: 1; min-width: 0; }
.account-menu-name {
  font-size: 13.5px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.account-menu-sub {
  font-size: 11.5px; color: var(--text-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-top: 2px;
}
.account-menu-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  border: none; background: transparent;
  text-align: left; width: 100%;
  transition: background 100ms ease;
}
.account-menu-item:hover { background: var(--selected); }
.account-menu-item .mi-icon {
  width: 18px; display: flex; align-items: center; justify-content: center;
  color: var(--text-2);
  flex-shrink: 0;
}
.account-menu-item .mi-label { flex: 1; }
.account-menu-item .mi-shortcut,
.account-menu-item .mi-caret {
  color: var(--text-3);
  font-size: 11px;
}
.account-menu-sep {
  height: 1px; background: var(--border);
  margin: 4px 0;
}
.account-menu-footer {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 8px 8px 10px;
  margin: 4px -6px -6px;
  border-top: 1px solid var(--border);
  background: color-mix(in oklab, var(--text) 3%, transparent);
  border-radius: 0 0 14px 14px;
}
.account-menu-footer .avatar {
  width: 34px; height: 34px; border-radius: 10px;
  background: linear-gradient(135deg, var(--mc-warn), #FF6A00);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: 13px;
}
.account-menu-footer .meta { flex: 1; min-width: 0; }
.account-menu-footer .name { font-size: 13px; font-weight: 600; }
.account-menu-footer .plan { font-size: 11px; color: var(--text-3); }
.account-menu-footer .pill-btn {
  display: flex; align-items: center; gap: 4px;
  padding: 6px 8px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text-2);
  cursor: pointer;
  position: relative;
}
.account-menu-footer .pill-btn .dot-notif {
  position: absolute; top: 3px; right: 3px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
}

/* Language flyout — side panel that opens from the "Language" row in
   the account menu. Positioned to the left so it doesn't cover the
   parent menu. Explicit Unicode-wide font stack so CJK / Devanagari /
   Vietnamese labels render correctly instead of falling back to
   tofu boxes. */
.lang-flyout {
  position: absolute;
  /* Open above and to the right so the rail-anchored account menu
     never pushes the flyout off-screen. ``bottom: 0`` aligns it
     with the row's bottom edge, growing upward. */
  bottom: 0; left: calc(100% + 4px);
  min-width: 240px;
  padding: 6px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow-lg);
  z-index: 10;
  /* Tall enough to fit all 10 supported languages in one view (no
     scroll). Capped at 80vh so it never exceeds the window. */
  max-height: min(560px, 80vh);
  overflow-y: auto;
  font-family: "Segoe UI", "Inter", "Noto Sans", "Noto Sans CJK SC",
    "Noto Sans CJK JP", "Noto Sans CJK KR", "Microsoft YaHei",
    "Malgun Gothic", "Meiryo", "Nirmala UI", "Arial Unicode MS",
    "Noto Naskh Arabic", "Tahoma", sans-serif;
}
.lang-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  padding: 6px 10px;
  border: none; background: transparent;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12.5px;
  color: var(--text);
  text-align: left;
}
.lang-item:hover { background: var(--selected); }
.lang-item .lang-label {
  flex: 1;
  font-family: inherit;
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.rail-section-label {
  font-size: 9px; font-weight: 700; letter-spacing: 0.08em;
  color: var(--text-3); text-transform: uppercase;
  margin: 8px 0 2px;
}

/* Main area */
.main {
  flex: 1; min-width: 0; min-height: 0;
  display: flex;
  position: relative;
}

/* Trang nội dung dạng form/card trong tool (Thanh toán, Mức dùng…) — căn GIỮA +
   giới hạn bề rộng để hợp MỌI thiết bị desktop: laptop hẹp thì full, màn rộng/
   ultrawide thì không kéo dãn vô tận mà canh giữa cân đối (Apple-grade). Bảng dịch
   (.workarea) thì vẫn full-bleed vì là dữ liệu — không áp .ocsb-page cho nó. */
.ocsb-page { width: 100%; max-width: 1180px; margin: 0 auto; }

/* ========== Glass panel / card ========== */
.panel {
  background: var(--panel);
  backdrop-filter: blur(30px) saturate(180%);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: var(--shadow-md);
}
.panel.flat {
  background: var(--panel-solid);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}

/* ========== Controls ========== */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px;
  height: 30px; padding: 0 14px;
  border-radius: 8px;
  border: 1px solid var(--border-strong);
  background: var(--panel-solid);
  color: var(--text);
  font-size: 13px; font-weight: 500;
  cursor: pointer;
  transition: all 120ms ease;
  white-space: nowrap;
  font-family: inherit;
}
.btn:hover { background: var(--panel-hover); }
.btn:active { transform: translateY(0.5px); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
/* Override: nút disabled NHƯNG đang chạy (data-running) phải hiện
   full opacity để red-dot pulse rõ — không bị mờ 50%. */
.btn[data-running="true"]:disabled,
.btn:disabled[data-running="true"] {
  opacity: 1;
  cursor: progress;
}
.btn.primary {
  background: var(--accent);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 1px 2px rgba(0,122,255,0.25);
}
.btn.primary:hover { background: var(--accent-hover); }
.btn.ghost { background: transparent; border-color: transparent; color: var(--text-2); }
.btn.ghost:hover { background: var(--selected); color: var(--text); }
.btn.danger { color: var(--red); border-color: color-mix(in oklab, var(--red) 40%, var(--border)); }
.btn.lg { height: 36px; padding: 0 18px; font-size: 13px; }
.btn.xl { height: 44px; padding: 0 24px; font-size: 14px; font-weight: 600; border-radius: 10px; }
.btn.sm { height: 24px; padding: 0 10px; font-size: 12px; border-radius: 6px; }
.btn.block { width: 100%; }

.input {
  height: 30px; padding: 0 10px;
  border-radius: 8px;
  border: 1px solid var(--border-strong);
  background: var(--panel-solid);
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
  outline: none;
  transition: box-shadow 120ms, border-color 120ms;
}
.input:focus { box-shadow: var(--ring); border-color: var(--accent); }

.input.search {
  padding-left: 28px;
  background-repeat: no-repeat;
  background-position: 9px center;
  background-size: 13px 13px;
}

/* Segment control */
.segment {
  display: inline-flex;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 2px;
  gap: 2px;
}
.segment button {
  border: none; background: transparent;
  padding: 4px 12px;
  font-size: 12px; font-weight: 500;
  color: var(--text-2);
  border-radius: 6px;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  font-family: inherit;
}
.segment button.on {
  background: var(--panel-solid);
  color: var(--text);
  box-shadow: var(--shadow-sm);
}

/* Pill / chip */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 22px; padding: 0 10px;
  border-radius: 999px;
  background: var(--selected);
  color: var(--text-2);
  font-size: 11px; font-weight: 500;
}
.chip.accent { background: var(--accent-soft); color: var(--accent); }
.chip.green { background: color-mix(in oklab, var(--green) 15%, transparent); color: var(--green); }
.chip.red   { background: color-mix(in oklab, var(--red) 15%, transparent); color: var(--red); }
.chip.orange{ background: color-mix(in oklab, var(--orange) 15%, transparent); color: var(--orange); }
.chip.purple{ background: color-mix(in oklab, var(--purple) 15%, transparent); color: var(--purple); }

/* ========== Text utilities ========== */
.muted { color: var(--text-2); }
.muted-2 { color: var(--text-3); }
.mono { font-family: "JetBrains Mono", "SF Mono", ui-monospace, Menlo, monospace; }
.overline {
  font-size: 10px; font-weight: 700; letter-spacing: 0.12em;
  color: var(--text-3); text-transform: uppercase;
}
h1,h2,h3,h4 { margin: 0; font-weight: 600; letter-spacing: -0.015em; }
h1 { font-size: 28px; letter-spacing: -0.02em; }
h2 { font-size: 20px; }
h3 { font-size: 16px; }

/* ========== Scroll ========== */
.scroll { overflow: auto; }
.scroll::-webkit-scrollbar { width: 10px; height: 10px; }
.scroll::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 10px; border: 2px solid transparent; background-clip: padding-box; }
.scroll::-webkit-scrollbar-thumb:hover { background-color: var(--text-3); background-clip: padding-box; }
.scroll::-webkit-scrollbar-track { background: transparent; }

/* ── Fat scrollbar for the translation table ──
   Main list can have 500+ rows so users drag the scroll thumb
   a lot — double-width grip (20 px track, visible pill = 12 px
   after the 4-px transparent ring) makes it much easier to
   target than the default 10-px thumb. Scoped to ``.table-wrap``
   so the sidebar / log panel keep their slim default. */
/* macOS-smooth scrolling for the table body (2026-05-27): smooth
   programmatic scrolls + contained overscroll so a wheel flick at the
   top edge doesn't bounce the whole window. Thinner 12px thumb reads
   more like a native macOS overlay scrollbar than the old fat 20px. */
.table-wrap .scroll {
  scroll-behavior: smooth;
  overscroll-behavior: contain;
}
.table-wrap .scroll::-webkit-scrollbar { width: 12px; }
.table-wrap .scroll::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 12px;
  border: 4px solid transparent;
  background-clip: padding-box;
  min-height: 40px;
}
.table-wrap .scroll::-webkit-scrollbar-thumb:hover {
  background-color: var(--text-3);
  background-clip: padding-box;
}
.table-wrap .scroll::-webkit-scrollbar-thumb:active {
  background-color: var(--accent);
  background-clip: padding-box;
}

/* ========== Status bar ========== */
.statusbar {
  height: 26px;
  display: flex; align-items: center; gap: 12px;
  padding: 0 14px;
  border-top: 1px solid var(--border);
  background: var(--rail);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  font-size: 11px; color: var(--text-3);
  font-family: "JetBrains Mono", "SF Mono", ui-monospace, monospace;
}

/* ========== Translation screen ========== */
.ws {
  flex: 1; min-width: 0; min-height: 0;
  height: 100%;   /* lấp đầy .main kể cả khi screen-host không phải flex-parent */
  display: grid;
  /* Responsive sidebar: 240-300px tuỳ viewport. Đảm bảo gap rõ
     ràng giữa sidebar và workarea + buttons không bị clip mép
     phải khi viewport hẹp. */
  grid-template-columns: clamp(240px, 22vw, 300px) 1fr;
  /* 1 hàng lấp đầy chiều cao — nếu để mặc định (auto) hàng chỉ cao
     bằng nội dung, để hở dải dot-grid ở đáy màn Translate. */
  grid-template-rows: minmax(0, 1fr);
  gap: 16px;
  padding: 14px;
  position: relative;
}

.sidebar-panel {
  padding: 14px;
  display: flex; flex-direction: column;
  gap: 14px;
  overflow: auto;
}

.sidebar-title {
  font-size: 13px; font-weight: 700;
  color: var(--text);
  letter-spacing: -0.01em;
}
.sidebar-sub {
  font-size: 11px;
  color: var(--text-3);
  margin-top: 2px;
}

.step {
  display: flex; flex-direction: column; gap: 6px;
}
.step-label {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.1em;
  color: var(--text-3); text-transform: uppercase;
}
.step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 4px;
  background: var(--selected);
  color: var(--text-2);
  font-size: 9px; font-weight: 700;
}

/* Work-mode segmented control (Auto / Manual). Matches macOS-style
   pill segment used elsewhere in the chrome — single rounded
   container, active tab raised with bg-elev. */
.work-mode-step { margin-top: -2px; }
.work-mode-segment {
  display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
  padding: 2px;
  background: var(--selected);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.work-mode-tab {
  appearance: none; border: 0; background: transparent;
  padding: 6px 10px; border-radius: 6px;
  font-size: 12px; font-weight: 600;
  color: var(--text-2); cursor: pointer;
  transition: background 120ms ease, color 120ms ease, box-shadow 120ms ease;
}
.work-mode-tab:hover:not(:disabled) {
  color: var(--text);
  background: color-mix(in oklab, var(--text) 5%, transparent);
}
.work-mode-tab.is-active {
  background: var(--bg-elev);
  color: var(--accent);
  box-shadow: var(--shadow-sm);
}
.work-mode-tab:disabled { opacity: 0.5; cursor: not-allowed; }
.work-mode-hint {
  font-size: 11px; color: var(--text-3);
  line-height: 1.35;
  padding: 4px 2px 0;
}

/* Manual-mode tile variant — subtle dashed accent ring on the
   write-style tiles to signal "click opens the picker" instead of
   "click runs the auto-pipeline". */
.pick-mode-btn.is-manual {
  border-style: dashed !important;
  border-color: color-mix(in oklab, var(--accent) 45%, var(--border)) !important;
}
.pick-mode-btn.is-manual:hover:not(:disabled) {
  border-color: var(--accent) !important;
}

/* Right side main */
.workarea {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 14px;
  min-height: 0; min-width: 0;
}

/* Keep-alive screen hosts: ``contents`` participates in the
   parent grid layout when active so the screen renders normally;
   ``none`` removes it from layout when hidden (cheap toggle).
   ``content-visibility: hidden`` tells the browser to skip
   rendering work entirely for offscreen subtrees — Chromium uses
   this as a hint to not lay out / paint hidden screens, so the
   active screen's switch latency drops independently of how big
   the hidden ones are. */
.screen-host.is-hidden {
  content-visibility: hidden;
  contain: layout style paint;
}
/* Halt every CSS animation/transition inside the hidden screen
   subtree — pulse dots, halos, progress bars and other looping
   keyframes keep paying GPU cost otherwise, and they're invisible
   anyway. Active screen runs normally. */
.screen-host.is-hidden,
.screen-host.is-hidden * {
  animation-play-state: paused !important;
  transition: none !important;
}
.screen-host.is-active {
  content-visibility: visible;
  contain: layout style;
}

/* Unified Library workarea — toolbar + table + log panel stacked
   vertically. Toolbar is auto height, table fills remaining
   space, log panel docks at bottom (collapsible). */
.workarea--lib-unified {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 12px;
  min-height: 0;
}
.workarea--lib-unified .table-wrap { min-height: 0; }
.workarea--lib-unified .lib-build-log {
  /* Chiều cao body do user kéo qua drag handle (.log-resize-handle)
     ở mép trên — không cần max-height fixed. */
  margin-top: 10px;
  height: auto;
  flex-shrink: 0;
}
.workarea--lib-unified .lib-build-log-body {
  overflow-y: auto;
}

/* ── macOS-style System log panel ─────────────────────────────
   Áp dụng cho cả Library + Translation tab. Đặc trưng:
   - Bo góc 10 px, viền hairline 1 px, drop-shadow nhẹ
   - Header có 3 traffic-light tròn (đỏ / vàng / xanh) bên trái —
     đỏ=Clear, vàng=Collapse, xanh=Maximize 70vh
   - Title centered, font weight 600
   - Body dùng SF Mono / Menlo monospace, tint subtle
   - Drag handle bar 6 px ở mép trên (resize chiều cao body) */
.macos-log {
  border: 1px solid color-mix(in oklab, var(--border) 80%, transparent);
  border-radius: 10px;
  background: color-mix(in oklab, var(--panel-solid) 94%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.07),
              0 1px 2px rgba(0, 0, 0, 0.05);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  margin-top: 10px;
  /* Override .lib-build-log max-height: 220px cũ — chiều cao
     do body's inline style (logH) quyết định, panel co dãn theo. */
  max-height: none !important;
  flex-shrink: 0;
}
/* Body height = inline ``style.height`` từ JS state (logH px). Bỏ
   max-height và flex grow để inline style là single source of truth.
   Khi user drag handle, body grow + panel grow theo. */
.macos-log .macos-log-body {
  flex: 0 0 auto;
  max-height: none !important;
  /* Smooth ramp khi BuildLibraryView phát ``lib:logHeightHint``
     (B1 picked → max, B2 bắt đầu → default). User drag handle
     vẫn responsive vì transition trên height là property browser
     interpolate, mỗi setLogH tick chỉ là 1 frame nên không cảm
     thấy lag khi drag. */
  transition: height 600ms cubic-bezier(0.22, 0.95, 0.26, 1);
}
[data-theme="dark"] .macos-log {
  background: color-mix(in oklab, var(--panel-solid) 88%, black);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35),
              0 1px 2px rgba(0, 0, 0, 0.25);
}
.macos-log-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--panel-solid) 96%, transparent),
    color-mix(in oklab, var(--panel-solid) 92%, transparent));
  border-bottom: 1px solid
    color-mix(in oklab, var(--border) 55%, transparent);
  flex-shrink: 0;
}

/* Traffic lights — Red / Yellow / Green dots, classic macOS.
   Glyph (×, −, +) ẩn mặc định, fade in khi hover trên 1 dot
   bất kỳ trong group (tâm lý macOS). */
.macos-traffic-lights {
  display: flex;
  gap: 8px;
  align-items: center;
}
.tl-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 0.5px solid rgba(0, 0, 0, 0.18);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 9px;
  font-weight: 700;
  line-height: 1;
  padding: 0;
  color: rgba(0, 0, 0, 0.55);
  transition: filter 120ms;
}
.tl-dot::before {
  content: attr(data-glyph);
  opacity: 0;
  transition: opacity 100ms;
}
.macos-traffic-lights:hover .tl-dot::before { opacity: 1; }
.tl-dot.tl-close { background: #ff5f57; }
.tl-dot.tl-min   { background: #ffbd2e; }
.tl-dot.tl-max   { background: #28c93f; }
.tl-dot:hover    { filter: brightness(1.06); }
.tl-dot:disabled {
  background: color-mix(in oklab, var(--text-3) 35%, transparent);
  cursor: not-allowed;
}
.tl-dot:disabled::before { opacity: 0 !important; }

.macos-log-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-2);
  letter-spacing: 0.2px;
}
.macos-log-meta {
  font-size: 11px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.macos-log-spacer { flex: 1; }

/* AI translate progress bar — slim bar dưới toolbar Library
   workarea, hiện khi auto-AI sau scan đang chạy. */
.ai-progress {
  padding: 6px 12px;
  background: color-mix(in oklab, var(--panel-solid) 96%, transparent);
  border-bottom: 1px solid var(--border);
}
.ai-progress-bar {
  position: relative;
  height: 22px;
  background: color-mix(in oklab, var(--text-3) 12%, transparent);
  border-radius: 11px;
  overflow: hidden;
}
.ai-progress-fill {
  position: absolute;
  inset: 0;
  width: 0%;
  background: linear-gradient(90deg, var(--accent),
                                     color-mix(in oklab, var(--accent) 60%, white));
  transition: width 240ms cubic-bezier(0.22, 0.95, 0.26, 1);
  border-radius: 11px;
}
.ai-progress-label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text);
  text-shadow: 0 0 4px rgba(255, 255, 255, 0.6);
}
[data-theme="dark"] .ai-progress-label {
  color: white;
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.7);
}

/* Log action buttons — compact text-icon button kế tiêu đề log.
   Thay 3 traffic-light dot trừu tượng bằng 3 nút có nhãn rõ
   ("Xoá / Thu / Phóng") để user nhìn-là-biết-bấm-cái-gì. */
.log-actions { display: flex; gap: 4px; align-items: center; }
.log-act.btn.sm {
  height: 22px;
  padding: 0 8px;
  font-size: 11px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
.macos-log-body {
  font-family: "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  font-size: 11.5px;
  line-height: 1.55;
  padding: 8px 12px;
  background: color-mix(in oklab, var(--panel-solid) 98%, black);
  overflow-y: auto;
  flex: 1 1 auto;
}
[data-theme="dark"] .macos-log-body {
  background: color-mix(in oklab, var(--panel-solid) 92%, black);
}
.macos-log-body > div { padding: 1px 0; }
.macos-log-body .ts {
  color: var(--text-3);
  font-size: 10.5px;
  margin-right: 4px;
}

/* Drag-resize handle — thanh bar 6 px ở mép TRÊN của log panel.
   Trong macOS-log nó nằm trên hairline border, hover sáng lên
   accent. */
.log-resize-handle {
  height: 6px;
  cursor: ns-resize;
  background: var(--border);
  position: relative;
  transition: background 120ms;
  flex-shrink: 0;
}
.log-resize-handle:hover,
.log-resize-handle:active {
  background: var(--accent);
}
.log-resize-handle::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 32px;
  height: 2px;
  background: color-mix(in oklab, var(--text-3) 60%, transparent);
  border-radius: 2px;
  pointer-events: none;
}
.macos-log .log-resize-handle {
  background: transparent;
  border-bottom: 1px solid
    color-mix(in oklab, var(--border) 50%, transparent);
}
.macos-log .log-resize-handle:hover,
.macos-log .log-resize-handle:active {
  background: color-mix(in oklab, var(--accent) 30%, transparent);
}
/* Active row — row đang là target của event log mới nhất.
   Pulse background subtle theo phase color, left-border highlight,
   text bold. Anh nhìn 1 cái biết row nào đang xử lý. */
/* Excel-style multi-select highlight for Library bulk delete. */
.table-row.is-row-selected {
  background: color-mix(in oklab, var(--accent) 14%, transparent) !important;
  box-shadow: inset 3px 0 0 0 var(--accent);
}
.table-row.is-row-selected:hover {
  background: color-mix(in oklab, var(--accent) 20%, transparent) !important;
}

.table-row.is-active-row {
  position: relative;
  background: color-mix(in oklab, var(--accent) 8%, transparent) !important;
  box-shadow: inset 3px 0 0 0 var(--accent);
  animation: active-row-pulse 1.6s ease-in-out infinite;
  z-index: 1;
}
.table-row.is-active-extract {
  background: color-mix(in oklab, var(--mc-accent) 10%, transparent) !important;
  box-shadow: inset 3px 0 0 0 var(--mc-accent);
}
.table-row.is-active-translate {
  background: color-mix(in oklab, #a855f7 10%, transparent) !important;
  box-shadow: inset 3px 0 0 0 #a855f7;
}
.table-row.is-active-sync {
  background: color-mix(in oklab, var(--mc-success) 10%, transparent) !important;
  box-shadow: inset 3px 0 0 0 var(--mc-success);
}
@keyframes active-row-pulse {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.08); }
}
/* ActiveRowSpotlight — pinned full-row clone trên table.
   Grid layout match .table-row, height 48px, border-left 4px
   theo phase color, animation cross-fade khi đổi row. */
.spotlight-row {
  height: 48px;
  padding: 0 12px;
  margin: 0 12px 6px;
  font-size: 13px;
  font-family: Arial, "Helvetica Neue", "Segoe UI", system-ui,
               -apple-system, sans-serif !important;
  border-radius: 8px;
  border-left: 4px solid var(--accent);
  background: color-mix(in oklab, var(--accent) 10%, transparent);
  box-shadow: 0 4px 12px -6px color-mix(in oklab,
    var(--accent) 35%, transparent);
  animation: spotlight-row-in 320ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.spotlight-row[data-phase="extract"] {
  border-left-color: var(--mc-accent);
  background: color-mix(in oklab, var(--mc-accent) 10%, transparent);
  box-shadow: 0 4px 12px -6px color-mix(in oklab,
    var(--mc-accent) 35%, transparent);
}
.spotlight-row[data-phase="translate"] {
  border-left-color: #a855f7;
  background: color-mix(in oklab, #a855f7 10%, transparent);
  box-shadow: 0 4px 12px -6px color-mix(in oklab,
    #a855f7 35%, transparent);
}
.spotlight-row[data-phase="sync"] {
  border-left-color: var(--mc-success);
  background: color-mix(in oklab, var(--mc-success) 10%, transparent);
  box-shadow: 0 4px 12px -6px color-mix(in oklab,
    var(--mc-success) 35%, transparent);
}
.spotlight-row .cell {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.spotlight-icon {
  display: inline-block;
  font-size: 14px;
  margin-right: 4px;
  animation: spotlight-icon 2s ease-in-out infinite;
  vertical-align: middle;
}
@keyframes spotlight-icon {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(1.18); opacity: 0.75; }
}
@keyframes spotlight-row-in {
  from { opacity: 0; transform: translateY(-4px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* AI paused banner — WOW entrance + breathing icon. */
@keyframes ai-banner-in {
  from { opacity: 0; transform: translateY(-6px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0)   scale(1); }
}
@keyframes ai-banner-icon {
  0%, 100% { transform: rotate(-8deg) scale(1); }
  50%      { transform: rotate(8deg) scale(1.12); }
}
/* Phase chip dot pulse — small ●  in log header indicates each
   pipeline phase running state at a glance. */
@keyframes phase-dot-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.85); }
}
/* Terminal cursor blink at end of last entry while pipeline is
   running — Apple-Terminal feel. */
@keyframes terminal-cursor-blink {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}
.terminal-cursor {
  display: inline-block;
  font-weight: 700;
  animation: terminal-cursor-blink 1s step-end infinite;
}
.live-log-body {
  /* Fine-tune system log scrollbar look — match macOS Terminal. */
  scrollbar-width: thin;
}
.live-log-body::-webkit-scrollbar { width: 8px; }
.live-log-body::-webkit-scrollbar-thumb {
  background: color-mix(in oklab, var(--text-3) 35%, transparent);
  border-radius: 4px;
}
.live-log-body::-webkit-scrollbar-track { background: transparent; }
/* Total progress bar — luôn hiển thị, gradient fill chạy ngang
   khi pipeline đang xử lý. Cao 4px (gấp đôi resize handle gốc)
   để đủ chỗ cho fill mà vẫn drag được. */
.log-total-progress {
  height: 4px !important;
  background: rgba(120,120,120,0.15) !important;
  border-bottom: none !important;
}
.log-total-progress::after { display: none; }
.log-total-progress:hover { background: rgba(120,120,120,0.25) !important; }

/* Build-mode workarea: table fills the height; the log sits underneath
   with a controllable height. ``--log-h`` is set in JS — clamped at
   28px when collapsed, free-resize via the splitter handle otherwise. */
.workarea--build {
  display: grid;
  grid-template-rows: 1fr 6px var(--log-h, 180px);
  gap: 0;
  min-height: 0; min-width: 0;
}
.workarea--build .scan-rows-wrap { min-height: 0; }
.workarea--build .lib-build-log { min-height: 0; height: 100%; }
.lib-build-splitter {
  background: var(--border);
  cursor: ns-resize;
  transition: background-color .15s ease;
  user-select: none;
}
.lib-build-splitter:hover,
.lib-build-splitter.is-dragging { background: var(--accent); }
.lib-build-log-head .log-collapse {
  padding: 2px 8px; font-size: 11px; line-height: 1.4;
  border-radius: 4px;
}

.toolbar-row {
  padding: 8px 10px;
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
}

/* Unified find-replace control: search input + replace input + action
   button inside a single rounded shell, matching Google-style inline
   toolbars. The left input doubles as the table filter. */
/* ───── Worker-thread chip (macOS-style dropdown) ─────
   The chip itself is the default .chip; adding ``.thread-chip`` nudges
   padding so the caret fits cleanly. An ``.on`` state subtly elevates
   it while the menu is open — matches Control Center / Menu Bar
   behaviour on macOS. */
.thread-chip-wrap { position: relative; display: inline-block; }

/* Apple-style borderless pill. ``.chip`` doesn't clear the user-agent
   <button> border, so we do it here explicitly — that's the dark
   outline users were seeing. A 1-px inset highlight (via box-shadow)
   gives the subtle bezel Apple uses on control-bar chips without a
   hard border. */
.thread-chip {
  padding: 0 8px 0 10px;
  gap: 4px;
  border: none;
  outline: none;
  cursor: pointer;
  /* Never clip the label — the chip grows with its content. Without
     these, flex parents and the default chip height can hide the
     tail of longer strings like "Auto · 16 threads". */
  white-space: nowrap;
  flex: 0 0 auto;
  width: auto;
  max-width: none;
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--text) 6%, transparent);
  transition:
    background 140ms ease,
    color 140ms ease,
    box-shadow 140ms ease,
    transform 120ms ease;
}
.thread-chip:hover {
  background: color-mix(in oklab, var(--text) 10%, transparent);
  color: var(--text);
}
.thread-chip:active { transform: scale(0.97); }
.thread-chip.on {
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--accent) 18%, transparent);
}
[data-theme="dark"] .thread-chip {
  box-shadow: inset 0 0 0 1px color-mix(in oklab, #fff 8%, transparent);
}
[data-theme="dark"] .thread-chip.on {
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--accent) 40%, transparent);
}
.thread-chip.on .thread-caret { transform: rotate(180deg); }
.thread-caret { transition: transform 160ms ease; }

/* Dropdown menu — white (or dark) pill with a 10-px radius, subtle
   shadow, translucent blur fallback. Item rows share a 28-px height
   for visual rhythm. */
.thread-menu {
  position: absolute;
  top: calc(100% + 6px); right: 0;
  width: 272px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.14), 0 2px 8px rgba(0,0,0,0.06);
  padding: 4px;
  z-index: 140;
  animation: menu-in 140ms ease;
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
}
[data-theme="dark"] .thread-menu {
  box-shadow: 0 12px 40px rgba(0,0,0,0.55), 0 2px 8px rgba(0,0,0,0.3);
}
.thread-menu-header {
  padding: 8px 10px 6px;
}
.thread-menu-title {
  font-size: 12px; font-weight: 600; color: var(--text);
  letter-spacing: -0.01em;
}
.thread-menu-sub {
  font-size: 10.5px; color: var(--text-3);
  margin-top: 2px;
}
.thread-menu-list {
  display: flex; flex-direction: column;
  max-height: 260px; overflow-y: auto;
}
.thread-menu-sep {
  height: 1px; background: var(--border);
  margin: 4px 2px;
}
.thread-menu-item {
  display: flex; align-items: center; gap: 8px;
  height: 28px;
  padding: 0 10px;
  border: none; background: transparent;
  border-radius: 6px;
  color: var(--text);
  font-size: 12.5px;
  cursor: pointer;
  text-align: left;
  transition: background 80ms ease;
}
.thread-menu-item:hover { background: var(--selected); }
.thread-menu-item.on   { color: var(--accent); font-weight: 500; }
.thread-menu-item.on:hover { background: var(--accent-soft); }
.thread-menu-item.danger { color: var(--red); }
.thread-menu-item.danger:hover { background: color-mix(in oklab, var(--red) 12%, transparent); }
.tm-bullet {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--text-3);
  flex: 0 0 auto;
}
.thread-menu-item.on .tm-bullet     { background: var(--accent); }
.thread-menu-item.danger .tm-bullet { background: var(--red); }
.tm-label { flex: 1 1 0; min-width: 0; }
.tm-meta  {
  font-size: 11px; color: var(--text-3);
  font-family: "JetBrains Mono", monospace;
}
.tm-check { color: var(--accent); flex: 0 0 auto; }
/* ════════════════════════════════════════════════════════════════
   Zone Configuration dialog — Apple-style sheet.
   Backdrop uses a heavy saturate + blur (what macOS calls a 'light
   material') so the app behind dims without going pitch-black. The
   sheet itself fades + slides in from slightly below for that soft
   modal feel.
   ════════════════════════════════════════════════════════════════ */
.zc-backdrop {
  position: fixed; inset: 0; z-index: 900;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.28);
  backdrop-filter: saturate(180%) blur(8px);
  -webkit-backdrop-filter: saturate(180%) blur(8px);
  animation: zc-fade 160ms ease;
}
[data-theme="dark"] .zc-backdrop { background: rgba(0,0,0,0.52); }
@keyframes zc-fade   { from { opacity: 0; } to { opacity: 1; } }
@keyframes zc-slide  {
  from { opacity: 0; transform: translateY(10px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}

.zc-dialog {
  width: min(920px, 92vw);
  height: min(640px, 88vh);
  background: var(--panel-solid);
  border-radius: 14px;
  box-shadow: 0 40px 120px rgba(0,0,0,0.30), 0 8px 20px rgba(0,0,0,0.10);
  border: 1px solid var(--border);
  display: flex; flex-direction: column; overflow: hidden;
  animation: zc-slide 200ms cubic-bezier(0.2, 0.9, 0.3, 1);
}
[data-theme="dark"] .zc-dialog {
  box-shadow: 0 40px 120px rgba(0,0,0,0.65), 0 8px 20px rgba(0,0,0,0.40);
}

.zc-head {
  display: flex; align-items: center;
  padding: 10px 14px 10px 16px;
  border-bottom: 1px solid var(--border);
  background: linear-gradient(to bottom,
      color-mix(in oklab, var(--bg) 60%, var(--panel-solid)),
      var(--panel-solid));
}
.zc-head-title {
  flex: 1; display: flex; align-items: center; gap: 10px;
  font-size: 13px; font-weight: 600; letter-spacing: -0.01em;
  color: var(--text);
}
.zc-head-dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: linear-gradient(135deg, #FF3D7F, #A855F7, var(--mc-accent));
}
.zc-close {
  width: 24px; height: 24px; border-radius: 6px;
  border: none; background: transparent;
  color: var(--text-3); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 120ms ease, color 120ms ease;
}
.zc-close:hover { background: var(--selected); color: var(--text); }

.zc-body {
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: 300px 1fr;
}

/* ── Left column: toolbar (search + tag filter) + list + actions ── */
.zc-list {
  border-right: 1px solid var(--border);
  background: color-mix(in oklab, var(--bg) 40%, var(--panel-solid));
  display: flex; flex-direction: column; min-height: 0;
}

.zc-list-toolbar {
  padding: 10px 10px 8px;
  border-bottom: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 8px;
}

/* Search pill */
.zc-search-wrap {
  display: flex; align-items: center; gap: 6px;
  height: 30px;
  padding: 0 8px 0 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel-solid);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.zc-search-wrap:focus-within {
  border-color: color-mix(in oklab, var(--accent) 50%, var(--border));
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 18%, transparent);
}
.zc-search-input {
  flex: 1; border: none; outline: none; background: transparent;
  font-size: 12.5px; color: var(--text); font-family: inherit;
}
.zc-search-clear {
  width: 18px; height: 18px; border-radius: 50%;
  border: none; background: var(--selected); color: var(--text-2);
  cursor: pointer; font-size: 14px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.zc-search-clear:hover { background: var(--border-strong); color: var(--text); }

/* Tag filter row */
.zc-tag-filter {
  display: flex; flex-wrap: wrap; gap: 4px;
}
.zc-tag-filter-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 8px 3px 7px;
  border: 1px solid var(--border);
  background: var(--panel-solid);
  color: var(--text-2);
  border-radius: 999px;
  font-size: 10.5px; font-weight: 500;
  cursor: pointer;
  transition: all 120ms ease;
}
.zc-tag-filter-chip:hover { background: var(--selected); color: var(--text); }
.zc-tag-filter-chip.on { color: #fff; border-color: var(--accent); background: var(--accent); }
.zc-tag-dot {
  width: 7px; height: 7px; border-radius: 50%;
  flex: 0 0 auto;
}
.zc-tag-filter-chip.on .zc-tag-dot { background: rgba(255,255,255,0.8) !important; }
.zc-tag-count {
  font-variant-numeric: tabular-nums;
  opacity: 0.6; font-size: 10px;
}

/* Scrollable zone list (no header — toolbar handles intent) */
.zc-list-scroll { flex: 1; min-height: 0; overflow: auto; padding: 6px; }
.zc-list-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  padding: 7px 10px 7px 6px;
  border: 1px solid transparent;
  background: transparent;
  border-radius: 8px;
  color: var(--text); font-size: 12.5px;
  cursor: pointer;
  transition: background 80ms ease, border-color 80ms ease,
              transform 120ms ease, opacity 120ms ease;
  text-align: left;
  user-select: none;
}
.zc-list-item:hover { background: var(--selected); }
.zc-list-item.on {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: color-mix(in oklab, var(--accent) 30%, var(--border));
  font-weight: 500;
}
.zc-list-item.drag-over {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--accent) 18%, transparent);
}
.zc-grip {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
  color: var(--text-3);
  opacity: 0;
  cursor: grab;
  transition: opacity 120ms ease;
}
.zc-list-item:hover .zc-grip,
.zc-list-item.on    .zc-grip { opacity: 1; }
.zc-list-item:active .zc-grip { cursor: grabbing; }
.zc-list-name {
  flex: 1 1 0; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.zc-list-tags { display: inline-flex; gap: 3px; flex: 0 0 auto; }
.zc-list-tag {
  font-size: 9.5px; font-weight: 600;
  padding: 1px 6px; border-radius: 999px;
}
.zc-empty {
  padding: 22px 12px;
  text-align: center;
  color: var(--text-3); font-size: 12px;
}

/* Footer action buttons — icon + label, grouped with a thin divider */
.zc-list-foot {
  display: flex; gap: 6px;
  padding: 8px 10px;
  border-top: 1px solid var(--border);
  background: color-mix(in oklab, var(--bg) 20%, var(--panel-solid));
}
.zc-action {
  flex: 1;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  height: 28px;
  padding: 0 10px;
  border-radius: 7px;
  border: 1px solid var(--border);
  background: var(--panel-solid);
  color: var(--text-2);
  font-size: 11.5px; font-weight: 500;
  cursor: pointer;
  transition: all 120ms ease;
}
.zc-action:hover:not(:disabled) {
  background: var(--selected); color: var(--text);
  border-color: var(--border-strong);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}
.zc-action:active:not(:disabled) { transform: translateY(0); }
.zc-action:disabled { opacity: 0.4; cursor: not-allowed; }
.zc-action.danger { color: var(--red); }
.zc-action.danger:hover:not(:disabled) {
  background: color-mix(in oklab, var(--red) 12%, transparent);
  color: var(--red);
  border-color: color-mix(in oklab, var(--red) 30%, var(--border));
}

/* ── Right detail ── */
.zc-detail {
  padding: 16px 20px; overflow: auto; min-height: 0;
  display: flex; flex-direction: column; gap: 10px;
}
.zc-no-sel {
  margin: auto; color: var(--text-3); font-size: 13px;
}
.zc-field {
  display: flex; flex-direction: column; gap: 4px;
}
.zc-field-label {
  font-size: 11px; font-weight: 600;
  color: var(--text-2); letter-spacing: -0.005em;
}
.zc-field-hint {
  font-size: 10.5px; color: var(--text-3); line-height: 1.35;
}
.zc-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

.zc-input, .zc-select {
  width: 100%;
  height: 30px;
  padding: 0 10px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 12.5px;
  font-family: inherit;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.zc-input:focus, .zc-select:focus {
  outline: none;
  border-color: color-mix(in oklab, var(--accent) 50%, var(--border));
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 18%, transparent);
}

.zc-edit-text {
  display: inline-block;
  padding: 4px 8px;
  border-radius: 6px;
  cursor: text;
  transition: background 120ms ease;
  min-width: 80px;
  font-weight: 500;
}
.zc-edit-text:hover {
  background: var(--selected);
}

/* Tag chips */
.zc-tag-grid {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.zc-tag-chip {
  border: 1px solid var(--border);
  background: var(--panel-solid);
  color: var(--text-2);
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11.5px; font-weight: 500;
  cursor: pointer;
  transition: all 120ms ease;
}
.zc-tag-chip { display: inline-flex; align-items: center; gap: 6px; }
.zc-tag-chip:hover { background: var(--selected); color: var(--text); }
.zc-tag-chip.on { color: #fff; }
.zc-tag-chip.add { color: var(--accent); border-style: dashed; }
.zc-tag-label { pointer-events: none; }
/* The `×` sits inside the chip <button>; a <span> (not a nested
   button) keeps the HTML valid. We surface it only on hover / when
   the chip is active so the default state stays visually clean. */
.zc-tag-x {
  display: none;
  font-size: 13px; line-height: 1;
  opacity: 0.7;
  padding: 0 2px;
  border-radius: 50%;
  transition: opacity 120ms ease, background 120ms ease;
}
.zc-tag-chip:hover .zc-tag-x,
.zc-tag-chip.on   .zc-tag-x { display: inline-block; }
.zc-tag-x:hover { opacity: 1; background: rgba(0,0,0,0.18); }

/* Save bar inside the zone detail pane — right-aligned, muted border
   above to separate from the form fields. */
.zc-save-bar {
  display: flex; justify-content: flex-end;
  margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--border);
}
.zc-save-btn {
  padding: 7px 18px;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 7px;
  font-size: 12px; font-weight: 500;
  cursor: pointer;
  transition: filter 120ms ease;
}
.zc-save-btn:hover { filter: brightness(1.08); }

/* ════════════════════════════════════════════════════════════════
   Output Mode Card — Settings › Output. Each of the three modes
   (2-lines, horizontal, overwrite) lives in its own stacked card so
   all three can be configured at once. Layout:
     [ diagram | title + description ]
     [ text 1 | text 2  (+ separator picker if horizontal) ]
     [ CAD preview ]
   ════════════════════════════════════════════════════════════════ */
/* 3-column grid — middle card is wider because the horizontal
   bilingual preview ("ENG TEXT / VIE TEXT" on one row) needs more
   room than the other two modes to avoid wrapping to 2 lines.
   Below ~1100px the explicit ratio is dropped and cards stack via
   the responsive override. */
.output-modes-grid {
  display: grid;
  grid-template-columns: 1fr 1.55fr 1fr;
  gap: 12px;
  margin-top: 14px;
}
@media (max-width: 1100px) {
  .output-modes-grid {
    grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  }
}
.output-mode-card {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--panel-solid);
  padding: 10px 12px;
  display: flex; flex-direction: column;
  gap: 10px;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.output-mode-card:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-sm);
}
/* Header: small diagram on the left, label + 1-line desc next to it.
   Compact heights so 3 cards in a row fit a single viewport. */
.omc-head {
  display: flex; align-items: center; gap: 10px;
}
.omc-diag {
  flex: 0 0 64px;
  height: 40px;
  border-radius: 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
}
.omc-meta { flex: 1; min-width: 0; }
.omc-title {
  font-size: 12.5px; font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.omc-desc {
  font-size: 11px;
  color: var(--text-3);
  margin-top: 1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.omc-config {
  border-top: 1px solid var(--border);
  padding-top: 8px;
}
.omc-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
/* Variant — Text 1 / swap / Text 2 with a center button column. The
   swap button column is narrow (28 px) so the dropdowns stay roughly
   the same width as the no-swap layout. Vertical alignment is to the
   bottom of the dropdown so the chevron sits next to the inputs, not
   over the labels above them. */
.omc-grid--with-swap {
  grid-template-columns: 1fr 28px 1fr;
  align-items: end;
  gap: 6px;
}
.omc-swap-btn {
  width: 28px; height: 28px;
  border-radius: 999px;
  background: var(--bg-elev, #1d2127);
  border: 1px solid var(--border, rgba(255,255,255,0.10));
  color: var(--text-2, var(--mc-label-2));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  /* Slight downward nudge so the icon vertical-centers on the
     dropdown row, not on the label above. */
  margin-bottom: 2px;
  transition: transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1),
              background 160ms ease,
              color 160ms ease,
              box-shadow 160ms ease;
}
.omc-swap-btn:hover {
  background: var(--accent, var(--mc-accent));
  border-color: var(--accent, var(--mc-accent));
  color: #fff;
  box-shadow: 0 2px 10px rgba(59, 130, 246, 0.35);
}
.omc-swap-btn:active {
  transform: rotate(180deg) scale(0.92);
  transition-duration: 320ms;
}
/* Force the dropdown wrapper INSIDE the swap variant to fill the
   column so the button doesn't drift left/right on narrow widths. */
.omc-grid--with-swap > div { min-width: 0; }
.omc-preview {
  border-top: 1px solid var(--border);
  padding-top: 8px;
  background: var(--bg);
  margin: 0 -12px -10px;
  padding: 8px 12px 10px;
  border-radius: 0 0 12px 12px;
}

/* Separator chips — tiny segmented picker for horizontal mode. */
.sep-chip {
  min-width: 42px; height: 26px;
  padding: 0 10px;
  border: 1px solid var(--border);
  background: var(--panel-solid);
  color: var(--text-2);
  border-radius: 6px;
  font-family: "JetBrains Mono", monospace;
  font-size: 12px;
  cursor: pointer;
  transition: all 120ms ease;
}
.sep-chip:hover { background: var(--selected); color: var(--text); }
.sep-chip.on {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
  box-shadow: 0 1px 4px color-mix(in oklab, var(--accent) 40%, transparent);
}

/* Advanced section (offset, rotate, line spacing, case, paper, scale).
   Collapses behind a disclosure toggle so the primary pane stays
   calm for first-time users but power users still get every knob. */
.zc-advanced {
  margin-top: 6px;
  border-top: 1px dashed var(--border);
  padding-top: 10px;
}
.zc-advanced-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  background: transparent; border: none; cursor: pointer;
  color: var(--text-2);
  font-size: 11.5px; font-weight: 600;
  padding: 4px 6px; border-radius: 6px;
}
.zc-advanced-toggle:hover { background: var(--selected); color: var(--text); }
.zc-chevron { transition: transform 160ms ease; }
.zc-advanced-badge {
  margin-left: 4px;
  padding: 1px 6px; border-radius: 999px;
  font-size: 9.5px; font-weight: 500;
  background: var(--accent-soft); color: var(--accent);
}
.zc-advanced-body {
  display: flex; flex-direction: column; gap: 10px;
  margin-top: 8px;
  animation: zc-fade 160ms ease;
}

/* macOS-style switch (for italic) */
.zc-switch { position: relative; display: inline-block; cursor: pointer; }
.zc-switch input { position: absolute; opacity: 0; pointer-events: none; }
.zc-switch-track {
  display: inline-block;
  width: 38px; height: 22px;
  border-radius: 999px;
  background: var(--selected);
  position: relative;
  transition: background 180ms ease;
}
.zc-switch-dot {
  position: absolute; left: 2px; top: 2px;
  width: 18px; height: 18px; border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2), 0 0 0 0.5px rgba(0,0,0,0.06);
  transition: left 180ms cubic-bezier(0.3, 0.9, 0.3, 1);
}
.zc-switch input:checked + .zc-switch-track { background: var(--green); }
.zc-switch input:checked + .zc-switch-track .zc-switch-dot { left: 18px; }

.tm-rec-pill {
  flex: 0 0 auto;
  font-size: 9.5px; font-weight: 600;
  letter-spacing: 0.02em;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  text-transform: uppercase;
}

/* Zone tag filter chips — horizontal row above the zone buttons. */
.zone-tag-bar {
  display: flex; flex-wrap: wrap; gap: 4px;
  padding: 4px 0 6px;
  border-bottom: 1px dashed var(--border);
  margin-bottom: 4px;
}
.tag-chip {
  border: 1px solid var(--border);
  background: var(--panel-solid);
  color: var(--text-2);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 10.5px;
  cursor: pointer;
  transition: all 120ms ease;
}
.tag-chip:hover { background: var(--selected); color: var(--text); }
.tag-chip.on {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* Zone row: main zone button + trailing edit pencil on the right. */
.zone-row {
  display: flex; gap: 4px; align-items: stretch;
}
.zone-row .zone-btn {
  flex: 1; min-width: 0;
  display: inline-flex; align-items: center; gap: 6px;
  white-space: normal; text-align: left;
  height: auto; min-height: 30px;
  padding: 6px 12px; font-size: 12px;
}
.zone-row .zone-pin {
  color: var(--orange);
  flex: 0 0 auto;
  font-size: 11px;
}
.zone-row .zone-label { flex: 1 1 0; min-width: 0; }
.zone-row .zone-edit {
  flex: 0 0 28px;
  width: 28px; height: 28px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--panel-solid);
  color: var(--text-3);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: all 120ms ease;
  align-self: center;
}
.zone-row .zone-edit:hover {
  background: var(--selected); color: var(--text);
  border-color: var(--border-strong);
}

/* ── Busy indicator — pulsing red dot on an in-flight action ───
   Any action button tagged with ``.is-busy`` gets a small red dot
   that pulses while the Python side is working. bridge.js sets the
   class on click and clears it on the corresponding completion
   signal (rowsChanged / connectionChanged / translationProgress),
   so the user never has to wonder whether the click registered. */
.is-busy {
  position: relative;
}
.is-busy::after {
  content: "";
  position: absolute;
  top: 6px;
  right: 6px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--mc-danger);
  /* Halo blends with whatever the button's own background is — a
     2px ring in the panel colour gives the dot breathing room on
     both light panels and the accent-filled scan-all CTA. */
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--panel-solid) 55%, transparent),
              0 0 8px rgba(255,59,48,0.55);
  animation: busy-pulse 1.1s ease-in-out infinite;
  pointer-events: none;
  z-index: 2;
}
@keyframes busy-pulse {
  0%, 100% { opacity: 0.55; transform: scale(0.85); }
  50%      { opacity: 1;    transform: scale(1.05); }
}
/* Dot moves off the sub-text on the scan-all CTA — otherwise the
   red circle overlaps "Tự đề xuất phương án". Park it just left of
   the sub block and dim the sub so the dot stays the focal point. */
.scan-all-btn.is-busy::after {
  /* Vertical-centre via ``top: calc(50% - half-dot-height)`` rather
     than ``transform: translateY(-50%)`` — the busy-pulse animation
     already owns ``transform: scale(...)`` and would overwrite any
     translate we set here, dropping the dot below centre. Since the
     dot is 7 px tall, offsetting top by -3.5 px lands its centre on
     the button's midline without competing with the animation. */
  top: calc(50% - 3.5px);
  right: 14px;
}
.scan-all-btn.is-busy:not(:disabled),
.btn.is-busy,
.mode-btn.is-busy,
.align-btn.is-busy {
  animation: scan-all-busy-glow 1.6s ease-in-out infinite;
}
@keyframes scan-all-busy-glow {
  0%, 100% { box-shadow: 0 1px 2px rgba(0,122,255,0.20),
                         0 4px 14px rgba(0,122,255,0.18),
                         inset 0 1px 0 rgba(255,255,255,0.18); }
  50%      { box-shadow: 0 1px 2px rgba(0,122,255,0.28),
                         0 6px 22px rgba(0,122,255,0.32),
                         inset 0 1px 0 rgba(255,255,255,0.22); }
}
/* On tiny mode-tile buttons the 7px dot feels big — trim to 6px and
   pull it closer to the corner so it doesn't crowd the icon. */
.mode-btn.is-busy::after {
  width: 6px; height: 6px;
  top: 4px; right: 4px;
}
/* Align-icon buttons are square and 32-ish px — same tiny-dot rule. */
.align-btn.is-busy::after {
  width: 6px; height: 6px;
  top: 3px; right: 3px;
}

/* ── Scan-All primary CTA ───────────────────────────────────────
   The one-click "Quét tất cả" button that dominates the Scan step.
   Apple HIG styling: filled accent background, subtle inner glow on
   hover, two-line label (verb + short subtitle) so the intent is
   readable without a tooltip. Disabled state drops to a flat neutral
   so it doesn't compete with the enabled flow. */
.scan-all-btn {
  display: flex; align-items: center; justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 10px 14px;
  background: var(--panel-solid);
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  color: var(--text);
  cursor: pointer;
  font-size: 13px;
  text-align: center;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04);
  transition: background 120ms ease, box-shadow 120ms ease,
              transform 80ms ease, filter 120ms ease, border-color 120ms ease;
  margin-bottom: 10px;
}
.scan-all-btn:hover:not(:disabled) {
  background: var(--panel-hover);
  border-color: color-mix(in oklab, var(--accent) 50%, var(--border-strong));
  box-shadow: 0 2px 6px rgba(0,0,0,0.06);
}
.scan-all-btn:active:not(:disabled) { transform: translateY(1px); }
.scan-all-btn:disabled {
  background: var(--panel-solid);
  border-color: var(--border);
  color: var(--text-3);
  box-shadow: none;
  cursor: not-allowed;
}
.scan-all-icon {
  flex-shrink: 0;
  opacity: 0.92;
}
.scan-all-btn:disabled .scan-all-icon { opacity: 0.5; }
.scan-all-label {
  font-weight: 600; font-size: 13.5px; line-height: 1.15;
  color: inherit;
}

/* Secondary "Quét tất cả" — placed below the 3 manual tiles. Smaller,
   regular-weight label so the manual tiles read as the primary path. */
.scan-all-btn--secondary {
  padding: 6px 10px;
  margin-top: 8px;
  margin-bottom: 4px;
}
.scan-all-btn--secondary .scan-all-label {
  font-weight: 400;
  font-size: 12.5px;
}

/* ── Section divider above the manual mode tiles ───────────────
   Thin rule with centered label — "Hoặc quét thủ công từng vùng".
   Keeps the rail glanceable: primary on top, divider, secondary
   options below — classic Apple settings-panel hierarchy. */
.scan-section-divider {
  display: flex; align-items: center;
  gap: 8px;
  margin: 4px 0 8px;
  color: var(--text-3);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 500;
}
.scan-section-divider::before,
.scan-section-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}
.scan-section-divider span { flex-shrink: 0; }

/* Secondary tint — the 3 manual mode tiles read as a subordinate
   group under the primary Scan-All CTA. Slightly smaller padding +
   dimmed label so the eye lands on the primary button first. */
.mode-grid--secondary .mode-btn {
  padding: 8px 6px 6px;
}
.mode-grid--secondary .mode-label {
  font-size: 10.5px;
  color: var(--text-2);
}
.mode-grid--secondary .mode-btn--active .mode-label {
  color: var(--accent);
}

/* ── Scan-mode tile grid ────────────────────────────────────────
   Three side-by-side buttons that replace the old zone preset list.
   Each tile stacks an SVG layout icon over a short label. The active
   tile gets the accent ring; disabled (not connected) tiles still
   render at full opacity minus pointer interaction, so the icons
   stay legible as reference even before AutoCAD is connected. */
.mode-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-bottom: 8px;
}
.mode-btn {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 6px;
  padding: 10px 6px 8px;
  border: 1px solid var(--border);
  background: var(--panel-solid);
  color: var(--text);
  border-radius: 10px;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, transform 80ms ease;
}
.mode-btn:hover:not(:disabled) {
  background: var(--panel-hover);
  border-color: var(--border-strong);
}
.mode-btn:active:not(:disabled) { transform: translateY(1px); }
.mode-btn:disabled { opacity: 0.55; cursor: not-allowed; }
.mode-btn--active {
  border-color: var(--accent);
  background: color-mix(in oklab, var(--accent) 10%, var(--panel-solid));
  box-shadow: 0 0 0 1px var(--accent) inset;
  color: var(--accent);
}
.mode-btn--active .mode-label { color: var(--accent); }
.mode-icon { color: var(--text-2); }
.mode-btn--active .mode-icon { color: var(--accent); }
.mode-label {
  font-size: 11.5px; font-weight: 500; line-height: 1.2;
  text-align: center; color: var(--text);
  max-width: 100%;
}

/* Inline numeric editor below the 3 tiles. Mirrors the zone-config
   dialog field layout (label left, input right) but denser to fit in
   the sidebar. */
.mode-params {
  display: flex; flex-direction: column;
  gap: 6px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-solid);
}
.mode-param-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 11.5px;
}
.mode-param-row label {
  flex: 1 1 auto; min-width: 0;
  color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mode-param-row input {
  flex: 0 0 72px;
  height: 24px;
  padding: 0 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-elev);
  color: var(--text);
  font: inherit; font-size: 11.5px; text-align: right;
  font-variant-numeric: tabular-nums;
}
.mode-param-row input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--ring);
}

/* Row-level right-click menu for the translator table. Fixed
   positioning so it overlays the table and floats above surrounding
   content without shifting layout. Scroll region caps the zone list
   for tables with many zones. */
.ctx-menu {
  position: fixed;
  z-index: 200;
  min-width: 220px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow-lg);
  padding: 4px;
  font-size: 12.5px;
  animation: menu-in 120ms ease;
}
.ctx-header {
  padding: 6px 10px 4px;
  color: var(--text-3);
  font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase;
}
.ctx-scroll { max-height: 260px; overflow-y: auto; }
.ctx-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  padding: 6px 10px;
  border: none; background: transparent;
  border-radius: 6px;
  cursor: pointer; color: var(--text);
  text-align: left;
}
.ctx-item:hover { background: var(--selected); }
.ctx-item.danger { color: var(--red); }
.ctx-item.danger:hover { background: color-mix(in oklab, var(--red) 12%, transparent); }
.ctx-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
}
.ctx-sep { height: 1px; background: var(--border); margin: 4px 0; }
.ctx-empty { padding: 6px 10px; color: var(--text-3); font-size: 11px; }

.find-replace {
  display: flex; align-items: center;
  flex: 2 1 520px; min-width: 320px; max-width: 720px;
  height: 30px;
  padding: 0 4px 0 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel-solid);
  overflow: hidden;
}
.find-replace .fr-icon { color: var(--text-3); flex: 0 0 auto; margin-right: 6px; }
.find-replace input.input {
  flex: 1 1 0; min-width: 0;
  border: none; background: transparent; height: 28px; border-radius: 0;
  padding: 0 8px;
}
.find-replace input.input:focus { outline: none; }
.find-replace .fr-sep { width: 1px; height: 18px; background: var(--border); flex: 0 0 auto; }
.find-replace .fr-btn {
  border: none; border-left: 1px solid var(--border);
  border-radius: 0; height: 30px; padding: 0 12px;
  background: transparent;
}
.find-replace .fr-btn:not(:disabled):hover { background: var(--selected); }
.find-replace .fr-btn:disabled { color: var(--text-3); cursor: not-allowed; }

/* Google-Docs-style align button group — square icon buttons in a
   segmented pill, 1-px divider between them. */
.align-group {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel-solid);
  overflow: hidden;
}
.align-group .align-btn {
  width: 34px; height: 30px;
  border: none; background: transparent; color: var(--text-2);
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  border-radius: 0;
  border-right: 1px solid var(--border);
  transition: background 120ms ease, color 120ms ease;
}
.align-group .align-btn:last-child { border-right: none; }
.align-group .align-btn:not(:disabled):hover { background: var(--selected); color: var(--text); }
.align-group .align-btn:disabled { color: var(--text-3); cursor: not-allowed; }

.table-wrap {
  min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.table-head {
  display: grid;
  gap: 0;
  padding: 0 12px;
  height: 38px;
  align-items: center;
  /* Solid, faintly-elevated header bar — macOS list-view chrome. No
     backdrop blur: it washed out the 1px column separators below. */
  background: color-mix(in oklab, var(--panel-solid) 50%, var(--bg));
  border-bottom: 1px solid var(--border);
  font-size: 11px; font-weight: 600;
  color: var(--text-3);
  text-transform: uppercase;
  letter-spacing: 0.045em;
  position: sticky; top: 0; z-index: 2;
}
.table-head > div {
  display: flex;
  align-items: center;
  height: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* ── Column dividers (2026-05-26) ──────────────────────────────────
   User report: bảng "bị lỗi cột, không tách biệt từng cột". The grid
   used gap:0 with no borders, so adjacent columns blended together —
   especially where a cell was empty (e.g. a Library row with only a
   Vietnamese value left the English column blank, making the source
   text look like it spilled into the next field). Add a subtle 1px
   vertical separator between every column on BOTH the header and the
   rows so each field reads as its own column. Head and rows share the
   same grid track widths (gridStyle), so the dividers line up exactly.
   The last column carries no trailing divider. */
/* Column separators — clearly VISIBLE vertical rules between every
   column (user kept marking the header gaps with red boxes: the prior
   hairlines were too faint, and the header's backdrop-filter washed the
   1px border out entirely). Use macOS's separator grey (#C6C6C8-ish)
   at full strength on the header and a slightly lighter rule on rows.
   Header + rows share the same grid tracks (gridStyle) so the rules
   line up into continuous vertical lines down the whole table. */
.table-head > div {
  border-right: 1px solid color-mix(in oklab, var(--text-3) 42%, transparent);
}
.table-row > .cell,
.table-row > .cell-with-picker {
  border-right: 1px solid color-mix(in oklab, var(--text-3) 22%, transparent);
}
.table-head > div:last-child,
.table-row > .cell:last-child,
.table-row > .cell-with-picker:last-child {
  border-right: none;
}
/* Generous breathing room either side of each divider so text never
   kisses the separator line — the crowded look was the main "not like
   a macOS product" complaint. 14px ≈ NSTableView default cell inset. */
.table-head > div:not(:first-child),
.table-row > .cell:not(:first-child),
.table-row > .cell-with-picker:not(:first-child) {
  padding-left: 14px;
}
/* ── Empty state — clean centred placeholder (2026-05-29) ──────────
   No faux column dividers (1–5) and no dot-grid bleed-through (6): the
   wrap paints a SOLID panel that fully covers the global dot canvas, and
   a single softly-elevated icon card sits centred — macOS Finder/Numbers
   "no items" calm. */
/* Make the table's scroll area a flex column so the empty placeholder can
   flex:1 and fill the leftover height below the sticky header — letting the
   card sit in the TRUE vertical centre of the table. Scoped to .table-wrap
   so other .scroll users are untouched. */
.table-wrap .scroll { display: flex; flex-direction: column; }
.tr-empty-wrap {
  position: relative;
  flex: 1 1 auto;
  min-height: 280px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--panel-solid);
  animation: tr-empty-fade 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes tr-empty-fade { from { opacity: 0; } to { opacity: 1; } }
.tr-empty-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 8px 20px;
  max-width: 320px;
  animation: tr-empty-rise 460ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes tr-empty-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.tr-empty-icon {
  width: 60px; height: 60px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 18px;
  margin-bottom: 16px;
  color: var(--accent);
  background: color-mix(in oklab, var(--accent) 9%, var(--panel-solid));
  border: 1px solid color-mix(in oklab, var(--accent) 18%, transparent);
  box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 8px 22px color-mix(in oklab, var(--accent) 12%, transparent);
}
.tr-empty-title { font-weight: 600; font-size: 15px; letter-spacing: -0.01em; color: var(--text); margin-bottom: 5px; }
.tr-empty-hint { font-size: 12.5px; line-height: 1.5; color: var(--text-3); }
@media (prefers-reduced-motion: reduce) {
  .tr-empty-wrap, .tr-empty-card { animation: none; }
}

/* ════════════════════════════════════════════════════════════════════
   Tab 7 — Chợ Tool · "Atelier"  ★ v3.0
   Port nguyên bản thiết kế toolmarket-prototype. Paper theme ấm độc lập
   theme app — mọi thứ scope dưới .atelier. Fonts: Fraunces / Hanken Grotesk
   / IBM Plex Mono (inject qua <link>, fallback hệ thống). Spring + glass.
   ════════════════════════════════════════════════════════════════════ */
/* ★ macOS-2026: theme Chợ KHÔNG còn bảng màu riêng — mọi biến trỏ về /mac26.css.
   Giữ đúng tinh thần "giấy ấm" của Atelier (vốn đã cùng hướng với mac26 warm-paper),
   nhưng nay 1 nguồn-sự-thật: đổi hệ thống → Chợ đổi theo. --a-session/-week/-month là
   3 màu SERIES của bảng xếp hạng (ngữ nghĩa phân biệt) → giữ. */
.atelier{
  --bg:var(--mc-canvas);--bg-2:var(--mc-canvas-2);--surface:var(--mc-mat-thin);--surface-solid:var(--mc-surface);
  --ink:var(--mc-label);--ink-2:var(--mc-label-2);--ink-3:var(--mc-label-3);
  --line:var(--mc-separator);--line-2:var(--mc-separator-strong);
  --shadow:var(--mc-e2);
  --shadow-lg:var(--mc-e4);
  --r:var(--mc-r-sheet);--r-lg:var(--mc-r-window);--ease:var(--mc-ease-out);--spring:var(--mc-ease-spring);
  --a-session:#FF6A2B;--a-week:#2E7DFF;--a-month:#13C28E;--brand:var(--mc-accent);
  /* Bề rộng khung nội dung: LẤP GẦN FULL mọi màn — chỉ chừa lề mỏng 2 bên,
     cap rất cao để màn 34"/4K vẫn dùng hết chiều ngang (không gutter lớn). */
  --shell-w:min(3320px,calc(100vw - 56px));
  position:relative;flex:1;min-width:0;min-height:0;overflow-y:auto;overflow-x:hidden;
  background:var(--bg);color:var(--ink);letter-spacing:-.01em;
  font-family:'Hanken Grotesk',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  -webkit-font-smoothing:antialiased;
}
/* nền: 1 vầng accent RẤT nhạt (bỏ 3 vầng xanh/cam/lục chỏi nhau) — kính phía trên
   hút màu nền này, đúng cách Liquid Glass lấy chiều sâu. */
.atelier .at-bg{position:absolute;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(46% 50% at 12% 18%, var(--mc-accent-soft), transparent 62%),
    radial-gradient(40% 50% at 82% 6%, rgba(17,15,10,.04), transparent 60%);}
.atelier ::selection{background:var(--ink);color:var(--bg)}

.atelier .nav-scrim{position:sticky;top:0;left:0;right:0;height:0;z-index:40;margin:0;pointer-events:none}
.atelier .nav-scrim::after{content:"";position:absolute;left:0;right:0;top:0;height:96px;
  /* solid paper for the band the pill sits in, then a soft fade so content
     dissolves into the background as it scrolls up — no hard cut line. */
  background:linear-gradient(var(--bg) 0%,var(--bg) 64%,rgba(242,241,236,0) 100%)}
.atelier .nav{position:sticky;top:14px;z-index:50;width:var(--shell-w);max-width:calc(100% - 36px);margin:14px auto 0;isolation:isolate;
  display:flex;align-items:center;gap:14px;padding:9px 9px 9px 22px;
  /* Opaque paper surface so content scrolling underneath is fully masked
     (backdrop-filter is unreliable in QtWebEngine → was bleeding text
     through the bar). Blur kept as an enhancement on top of the solid. */
  background:rgba(251,250,247,.94);
  backdrop-filter:blur(30px) saturate(1.6);-webkit-backdrop-filter:blur(30px) saturate(1.6);
  border:1px solid rgba(255,255,255,.7);border-radius:999px;
  box-shadow:0 1px 2px rgba(20,19,15,.05),0 10px 30px rgba(20,19,15,.10);
  transition:opacity .35s var(--ease),transform .45s var(--ease)}
/* Nav lớn mờ + trượt lên khi cuộn trong trang chi tiết */
.atelier .nav.is-hidden{opacity:0;transform:translateY(-16px) scale(.98);pointer-events:none}

/* ── Condensed header (trang chi tiết) ──────────────────────────────
   Dính trên cùng, hiện khi cuộn: back + icon + tên tool + hàng tab. */
/* top:38px = chiều cao .titlebar của app (frameless) → thanh gọn nằm ngay
   dưới titlebar, không bị che. position:fixed bám viewport. */
/* Thanh gọn khi cuộn = capsule NỔI bo tròn, GIỐNG HỆT .nav (không full-width vuông). */
.atelier .dtl-cond{position:fixed;top:14px;left:56px;right:0;z-index:52;
  width:var(--shell-w);max-width:calc(100vw - 92px);margin:0 auto;
  background:rgba(251,250,247,.94);backdrop-filter:blur(30px) saturate(1.6);-webkit-backdrop-filter:blur(30px) saturate(1.6);
  border:1px solid rgba(255,255,255,.7);border-radius:999px;
  box-shadow:0 1px 2px rgba(20,19,15,.05),0 10px 30px rgba(20,19,15,.10);
  opacity:0;transform:translateY(-12px);transition:opacity .35s var(--ease),transform .45s var(--ease);pointer-events:none}
.atelier .dtl-cond.show{opacity:1;transform:none;pointer-events:auto}
/* 1 dòng duy nhất bên trong capsule: Back · tabs · Tải về */
.atelier .dtl-cond-tabs{display:flex;align-items:center;gap:4px;width:100%;padding:8px 12px 8px 11px}
.atelier .dtl-cond-back{width:34px;height:34px;border-radius:50%;flex-shrink:0;border:1px solid var(--line);background:var(--surface-solid);color:var(--ink);cursor:pointer;display:grid;place-items:center;margin-right:6px;transition:background .25s var(--ease),transform .3s var(--spring)}
.atelier .dtl-cond-back:hover{background:rgba(20,19,15,.05);transform:translateX(-2px)}
.atelier .dtl-cond-back svg{width:18px;height:18px}
.atelier .dtl-cond-tab{font:inherit;font-size:13.5px;font-weight:600;color:var(--ink-3);background:none;border:none;cursor:pointer;padding:10px 14px;position:relative;transition:color .3s var(--ease)}
.atelier .dtl-cond-tab:hover{color:var(--ink-2)}
.atelier .dtl-cond-tab.on{color:var(--ink)}
.atelier .dtl-cond-tab.on::after{content:"";position:absolute;left:14px;right:14px;bottom:-3px;height:2px;background:var(--ink);border-radius:2px}
.atelier .dtl-cond-dl{margin-left:auto;flex-shrink:0;height:34px;padding:0 16px;font-size:13px;border-radius:999px}
@media(max-width:680px){.atelier .dtl-cond-dl{display:none}}
@media(prefers-reduced-motion:reduce){.atelier .nav,.atelier .dtl-cond{transition:none}}
.atelier .brand{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:21px;letter-spacing:-.02em;margin-right:6px;display:inline-flex;align-items:center;gap:7px}
.atelier .brand b{font-weight:600}
.atelier .dot{width:7px;height:7px;border-radius:50%;background:var(--a-session);display:inline-block;margin:0 7px 1px 0;animation:at-pulse 2.6s var(--ease) infinite}
@keyframes at-pulse{0%{box-shadow:0 0 0 0 rgba(255,106,43,.45)}70%{box-shadow:0 0 0 7px rgba(255,106,43,0)}100%{box-shadow:0 0 0 0 rgba(255,106,43,0)}}
.atelier .tabs{display:flex;gap:2px;margin-left:auto}
.atelier .tab{font:inherit;font-size:14.5px;font-weight:500;color:var(--ink-2);background:none;border:none;cursor:pointer;padding:9px 16px;border-radius:999px;transition:color .3s var(--ease),background .3s var(--ease)}
.atelier .tab:hover{color:var(--ink)}
.atelier .tab.on{color:var(--ink);background:rgba(20,19,15,.06)}
/* Nav gộp 1 hàng: dải phân cách giữa chợ (market) ↔ Sử dụng/Gói cước */
.atelier .tab-sep{flex:0 0 auto;width:1px;height:18px;background:var(--line-2);margin:0 9px;align-self:center}
.atelier .tab-sec{color:var(--ink-3)}
.atelier .tab-sec:hover{color:var(--ink-2)}
.atelier .tab-sec.on{color:var(--ink)}
.atelier .island{display:flex;align-items:center;gap:9px;cursor:pointer;background:var(--ink);color:var(--bg);border-radius:999px;
  padding:9px 16px 9px 13px;font-size:13.5px;font-weight:500;transition:transform .5s var(--spring),box-shadow .5s var(--ease);
  box-shadow:0 4px 16px rgba(20,19,15,.22);position:relative;overflow:hidden}
.atelier .island:hover{transform:translateY(-1px) scale(1.02)}
.atelier .island .mini{display:flex;gap:4px}
.atelier .island .mini i{width:5px;height:18px;border-radius:3px;background:rgba(255,255,255,.28);position:relative;overflow:hidden}
.atelier .island .mini i::after{content:"";position:absolute;left:0;right:0;bottom:0;border-radius:3px;background:var(--c);height:var(--h);transition:height 1.4s var(--ease)}
.atelier .island .t b{font-family:'IBM Plex Mono',ui-monospace,monospace;font-weight:500;font-variant-numeric:tabular-nums}

.atelier .stage{position:relative;z-index:1;width:var(--shell-w);max-width:calc(100% - 36px);margin:0 auto;padding:30px 24px 60px}
.atelier .view{animation:at-enter .7s var(--ease) both}
@keyframes at-enter{from{opacity:0;transform:translateY(14px) scale(.992);filter:blur(6px)}to{opacity:1;transform:none;filter:none}}
.atelier .eyebrow{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3);display:block;margin-bottom:16px}
.atelier .stg{text-align:center}
.atelier h1.hero{font-family:'Fraunces',Georgia,serif;font-weight:400;font-size:clamp(40px,6.4vw,76px);line-height:.98;letter-spacing:-.03em;max-width:18ch;margin-inline:auto}
.atelier h1.hero em{font-style:italic;color:var(--ink-2)}
.atelier .lead{font-size:clamp(16px,1.7vw,19px);color:var(--ink-2);max-width:46ch;margin:22px auto 0;line-height:1.55}
.atelier .stg>*{opacity:0;transform:translateY(16px);animation:at-rise .8s var(--ease) forwards}
@keyframes at-rise{to{opacity:1;transform:none}}

/* ── Market tab bar (Trending / Tool AI / Agent AI / Workflow) ── */
.atelier .mkt-tabs{display:flex;gap:4px;background:rgba(20,19,15,.05);border-radius:999px;padding:5px;margin:4px 0 10px;width:fit-content}
.atelier .mkt-tab{font:inherit;font-size:14.5px;font-weight:600;color:var(--ink-2);background:none;border:none;cursor:pointer;padding:9px 20px;border-radius:999px;transition:color .3s var(--ease),background .3s var(--ease)}
.atelier .mkt-tab:hover{color:var(--ink)}
.atelier .mkt-tab.on{color:var(--ink);background:var(--surface-solid);box-shadow:0 2px 8px rgba(20,19,15,.1)}

/* ── Trending: Top earners (theo lượt dùng đã xác minh) ── */
.atelier .te-list{display:flex;flex-direction:column;gap:10px}
.atelier .te-row{display:grid;grid-template-columns:30px 44px 1fr auto 200px auto;gap:18px;align-items:center;
  background:var(--surface-solid);border:1px solid var(--line);border-radius:18px;padding:16px 22px;cursor:pointer;
  transition:transform .4s var(--spring),box-shadow .4s var(--ease),border-color .3s var(--ease)}
.atelier .te-row:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);border-color:var(--line-2)}
.atelier .te-rank{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:14px;color:var(--ink-3);text-align:center}
.atelier .te-ico{width:44px;height:44px;border-radius:13px;display:grid;place-items:center;color:#fff;font-family:'Fraunces',Georgia,serif;font-size:18px;box-shadow:inset 0 1px 0 rgba(255,255,255,.3)}
.atelier .te-meta{min-width:0}
.atelier .te-name{font-size:15px;font-weight:700;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .te-by{font-size:12.5px;color:var(--ink-3);display:flex;align-items:center;gap:4px;margin-top:2px}
.atelier .te-by .te-v{width:13px;height:13px;color:var(--a-week);flex-shrink:0}
.atelier .te-runs{text-align:right;font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .te-runs .n{font-size:12.5px;color:var(--ink-2)}
.atelier .te-runs .p{font-size:11.5px;color:var(--ink-3);margin-top:2px}
.atelier .te-bar{height:7px;border-radius:4px;background:rgba(20,19,15,.08);overflow:hidden}
.atelier .te-bar i{display:block;height:100%;border-radius:4px;background:linear-gradient(90deg,#5AA0FF,var(--a-week));width:0;transition:width 1s var(--ease)}
.atelier .te-earn{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:15px;font-weight:600;color:var(--a-month);text-align:right;white-space:nowrap}
@media(max-width:860px){
  .atelier .te-row{grid-template-columns:26px 40px 1fr auto;gap:12px;row-gap:10px}
  .atelier .te-bar{grid-column:1 / -1;order:5}
  .atelier .te-earn{grid-column:4;order:4}
}
/* Publish & earn banner */
.atelier .te-cta{display:flex;align-items:center;justify-content:space-between;gap:24px;flex-wrap:wrap;
  margin-top:22px;padding:22px 26px;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface-solid)}
.atelier .te-cta-h{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:19px;letter-spacing:-.01em}
.atelier .te-cta-p{font-size:13.5px;color:var(--ink-2);line-height:1.5;margin-top:5px;max-width:52ch}
.atelier .te-cta-btn{flex-shrink:0}

/* Trending segmented control — Top earners · Đang bùng nổ · Đường đua */
.atelier .te-seg{display:inline-flex;gap:4px;padding:4px;margin:2px 0 10px;
  background:var(--surface);border:1px solid var(--line);border-radius:14px;animation:at-rise .6s var(--ease) both}
.atelier .te-seg-btn{appearance:none;border:0;background:transparent;cursor:pointer;
  font-family:'Hanken Grotesk',sans-serif;font-size:14px;font-weight:600;color:var(--ink-2);
  padding:9px 18px;border-radius:10px;transition:background .2s var(--ease),color .2s var(--ease),box-shadow .2s var(--ease)}
.atelier .te-seg-btn:hover{color:var(--ink)}
.atelier .te-seg-btn.on{background:var(--surface-solid);color:var(--brand);box-shadow:var(--shadow-sm)}
/* Thanh công cụ trên cùng: chế độ (trái) · khoảng thời gian (phải) */
.atelier .te-toolbar{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin:2px 0 18px}
.atelier .te-toolbar .te-seg{margin:0}
/* Bộ lọc khoảng thời gian — segmented control kiểu macOS (track lõm + thumb nổi) */
.atelier .te-range{display:inline-flex;gap:3px;padding:3px;border-radius:11px;
  background:var(--surface);border:1px solid var(--line);animation:at-rise .6s var(--ease) .1s both}
.atelier .te-range-b{appearance:none;border:0;background:transparent;cursor:pointer;
  font-family:'Hanken Grotesk',sans-serif;font-size:12.5px;font-weight:600;color:var(--ink-2);
  padding:6px 13px;border-radius:8px;white-space:nowrap;
  transition:background .2s var(--ease),color .2s var(--ease),box-shadow .2s var(--ease)}
.atelier .te-range-b:hover{color:var(--ink)}
.atelier .te-range-b.on{background:var(--surface-solid);color:var(--ink);font-weight:700;box-shadow:var(--shadow-sm)}
/* Nút chọn tỷ lệ macOS: icon khung + nhãn, segmented */
.atelier .rst-ar .te-range-b{display:inline-flex;align-items:center;gap:6px}
.atelier .rst-ar svg{display:block;flex:0 0 auto;opacity:.85}
.atelier .rst-ar .te-range-b.on svg{opacity:1;color:var(--brand)}
/* Vòng focus bàn phím (WCAG 2.4.7) cho cả 2 segmented control */
.atelier .te-seg-btn:focus-visible,.atelier .te-range-b:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
/* Màn hẹp: xếp dọc thanh công cụ để không tràn / lệch hàng */
@media (max-width:680px){.atelier .te-toolbar{flex-direction:column;align-items:stretch;justify-content:flex-start;gap:9px}}
.atelier .te-score{font-size:18px;text-align:right}
/* Trend badges */
.atelier .tb-new,.atelier .tb-fire,.atelier .tb-mv{display:inline-flex;align-items:center;gap:3px;
  font-family:'Hanken Grotesk',sans-serif;font-size:10.5px;font-weight:800;letter-spacing:.02em;
  padding:2px 8px;border-radius:999px;margin-left:7px;vertical-align:middle;line-height:1.5}
.atelier .tb-new{background:var(--mc-accent);color:var(--mc-on-accent)}
.atelier .tb-fire{background:color-mix(in oklab,var(--brand) 14%,transparent);color:var(--brand)}
.atelier .tb-mv.up{background:color-mix(in oklab,var(--a-month) 16%,transparent);color:var(--a-month)}
.atelier .tb-mv.down{background:rgba(20,19,15,.07);color:var(--ink-3)}
.atelier .race-soon{padding:60px 0;text-align:center;color:var(--ink-3);font-size:15px}

/* ── Lan toả (cascade viral) ──────────────────────────────────────────── */
.atelier .casc{display:flex;flex-direction:column;gap:18px}
.atelier .casc-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}
.atelier .casc-eyebrow{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3)}
.atelier .casc-reach{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:38px;letter-spacing:-.02em;line-height:1.05;margin-top:6px;
  background:linear-gradient(90deg,var(--brand),#E84D7A);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.atelier .casc-reach span{-webkit-text-fill-color:initial;color:var(--ink-3);font-family:'Hanken Grotesk',sans-serif;font-size:14px;font-weight:500}
.atelier .casc-replay{appearance:none;border:1px solid var(--line);background:var(--surface-solid);cursor:pointer;
  font-family:'Hanken Grotesk',sans-serif;font-size:13px;font-weight:600;color:var(--ink-2);padding:8px 16px;border-radius:11px;
  transition:border-color .2s var(--ease),color .2s var(--ease)}
.atelier .casc-replay:hover{border-color:var(--brand);color:var(--brand)}
/* Lưới chấm quốc gia */
.atelier .casc-map{display:flex;gap:10px;flex-wrap:wrap}
.atelier .casc-dot{display:flex;flex-direction:column;align-items:center;gap:3px;min-width:64px;padding:12px 10px;
  border:1px solid var(--line);border-radius:14px;background:var(--surface);opacity:.45;
  transition:opacity .5s var(--ease),border-color .5s var(--ease),background .5s var(--ease),transform .5s var(--spring)}
.atelier .casc-dot.lit{opacity:1;border-color:color-mix(in oklab,var(--brand) 45%,var(--line));
  background:color-mix(in oklab,var(--brand) 8%,var(--surface-solid));transform:translateY(-2px);animation:casc-pulse .6s var(--ease)}
.atelier .casc-dot-c{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:14px;font-weight:700;color:var(--ink)}
.atelier .casc-dot-n{font-size:10.5px;color:var(--ink-3)}
@keyframes casc-pulse{0%{box-shadow:0 0 0 0 color-mix(in oklab,var(--brand) 40%,transparent)}100%{box-shadow:0 0 0 12px transparent}}
/* Rail giai đoạn */
.atelier .casc-rail{display:flex;flex-direction:column;gap:0;position:relative}
.atelier .casc-stage{display:grid;grid-template-columns:40px 1fr;gap:14px;padding:14px 4px;position:relative;
  opacity:.4;transform:translateX(-4px);transition:opacity .45s var(--ease),transform .45s var(--ease)}
.atelier .casc-stage.on{opacity:1;transform:none}
.atelier .casc-stage:not(:last-child)::before{content:"";position:absolute;left:19px;top:44px;bottom:-2px;width:2px;background:var(--line)}
.atelier .casc-stage.on:not(:last-child)::before{background:color-mix(in oklab,var(--brand) 40%,var(--line))}
.atelier .casc-kind{width:40px;height:40px;border-radius:50%;display:grid;place-items:center;font-size:18px;
  background:var(--surface);border:1px solid var(--line);z-index:1}
.atelier .casc-stage.on .casc-kind{background:color-mix(in oklab,var(--brand) 12%,var(--surface-solid));border-color:color-mix(in oklab,var(--brand) 40%,var(--line))}
.atelier .casc-stage-top{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.atelier .casc-stage-label{font-size:15px;font-weight:700;letter-spacing:-.01em}
.atelier .casc-stage-reach{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:13px;font-weight:600;color:var(--brand)}
.atelier .casc-stage-note{font-size:12.5px;color:var(--ink-3);margin-top:3px;line-height:1.45}
.atelier .casc-foot{font-size:12px;color:var(--ink-3);border-top:1px solid var(--line);padding-top:12px}
/* Pulse engine — năng lượng + giai đoạn khoá (lan truyền THẬT) */
.atelier .casc-energy{display:flex;flex-direction:column;align-items:flex-end;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:21px;font-weight:700;color:var(--brand);line-height:1}
.atelier .casc-energy span{font-family:'Hanken Grotesk',sans-serif;font-size:11px;font-weight:600;color:var(--ink-3);margin-top:3px}
.atelier .casc-stage.locked{opacity:.55}
.atelier .casc-stage.locked .casc-kind{background:var(--surface);border-style:dashed}
.atelier .casc-stage.locked .casc-stage-reach{color:var(--ink-3);font-weight:600}
.atelier .casc-stage.locked .casc-stage-note{color:var(--brand);opacity:.85}
/* Tương tác THẬT trên trang chi tiết (like/save/share → engine) */
.atelier .dtl-react{display:flex;gap:9px;margin-top:6px;flex-wrap:wrap;justify-content:center}
.atelier .dtl-react-b{display:inline-flex;align-items:center;gap:7px;appearance:none;cursor:pointer;
  background:var(--surface-solid);border:1px solid var(--line);border-radius:12px;padding:9px 14px;
  font-family:'Hanken Grotesk',sans-serif;font-size:13.5px;font-weight:600;color:rgb(100,97,92);
  transition:border-color .18s var(--ease),color .18s var(--ease),background .18s var(--ease),transform .18s var(--spring)}
.atelier .dtl-react-b:hover{border-color:var(--line-2);color:var(--ink);transform:translateY(-1px)}
/* Trạng thái đã thích/đã lưu: GIỮ TRUNG TÍNH như nút chia sẻ (không màu hồng/cam),
   chỉ icon được tô đặc (fill) để báo trạng thái — đồng nhất, tinh tế kiểu iOS. */
.atelier .dtl-react-b.on.like,.atelier .dtl-react-b.on.save{color:rgb(100,97,92);border-color:var(--line);background:var(--surface-solid)}
/* Chuông thông báo lan truyền */
.atelier .as-bell-wrap{position:relative;margin-left:auto}
.atelier .as-bell{position:relative;appearance:none;cursor:pointer;width:38px;height:38px;border-radius:11px;display:grid;place-items:center;
  background:var(--surface-solid);border:1px solid var(--line);color:var(--ink-2);transition:border-color .18s var(--ease),color .18s var(--ease)}
.atelier .as-bell:hover,.atelier .as-bell.on{border-color:var(--brand);color:var(--brand)}
.atelier .as-bell-dot{position:absolute;top:-5px;right:-5px;min-width:18px;height:18px;padding:0 4px;border-radius:9px;
  background:#E84D7A;color:#fff;font-size:10.5px;font-weight:700;display:grid;place-items:center;font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .as-bell-scrim{position:fixed;inset:0;z-index:40}
.atelier .as-bell-pop{position:absolute;top:46px;right:0;z-index:41;width:330px;max-height:60vh;overflow-y:auto;
  background:var(--surface-solid);border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow-lg);padding:8px;animation:at-rise .2s var(--ease) both}
.atelier .as-bell-h{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3);padding:8px 10px 6px}
.atelier .as-bell-empty{padding:14px 12px;font-size:13px;color:var(--ink-3);line-height:1.5}
.atelier .as-bell-it{display:flex;align-items:center;gap:11px;width:100%;appearance:none;cursor:pointer;text-align:left;
  background:transparent;border:0;border-radius:11px;padding:10px;transition:background .15s var(--ease)}
.atelier .as-bell-it:hover{background:var(--surface)}
.atelier .as-bell-ic{width:34px;height:34px;flex-shrink:0;border-radius:10px;display:grid;place-items:center;color:#fff;font-family:'Fraunces',Georgia,serif;font-size:14px;font-weight:600}
.atelier .as-bell-m{flex:1;font-size:13px;color:var(--ink-2);line-height:1.35}
.atelier .as-bell-m b{color:var(--ink);font-weight:700}
.atelier .as-bell-m i{color:var(--brand);font-style:normal;font-weight:700}
.atelier .as-bell-rk{font-size:15px}
/* ── Bộ chọn NGÔN NGỮ ở header Chợ — chip + flyout, khớp style chuông ── */
.atelier .as-bell-wrap{margin-left:0}                 /* Phát hành đã giữ marginLeft:auto → gom nhóm phải sát nhau */
.atelier .as-lang-wrap{position:relative}
.atelier .as-lang{position:relative;appearance:none;cursor:pointer;height:38px;padding:0 12px;border-radius:11px;display:flex;align-items:center;gap:7px;
  background:var(--surface-solid);border:1px solid var(--line);color:var(--ink-2);transition:border-color .18s var(--ease),color .18s var(--ease)}
.atelier .as-lang:hover,.atelier .as-lang.on{border-color:var(--brand);color:var(--brand)}
.atelier .as-lang-code{font-size:12.5px;font-weight:700;letter-spacing:.03em;font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .as-lang-scrim{position:fixed;inset:0;z-index:40}
.atelier .as-lang-pop{position:absolute;top:46px;right:0;z-index:41;width:248px;max-height:60vh;overflow-y:auto;
  background:var(--surface-solid);border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow-lg);padding:6px;animation:at-rise .2s var(--ease) both}
.atelier .as-lang-it{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;appearance:none;cursor:pointer;text-align:left;
  background:transparent;border:0;border-radius:10px;padding:9px 11px;font-size:13px;color:var(--ink-2);transition:background .15s var(--ease),color .15s var(--ease)}
.atelier .as-lang-it:hover{background:var(--surface)}
.atelier .as-lang-it.on{color:var(--brand);font-weight:700}
.atelier .as-lang-lbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.atelier .as-lang-ck{color:var(--brand);font-weight:700;flex:none}
/* ✨ Gợi ý cho bạn — cá nhân hoá minh bạch */
.atelier .as-foryou{margin:6px 0 18px;animation:at-rise .7s var(--ease) both}
.atelier .as-foryou-h{display:flex;align-items:baseline;gap:10px;margin-bottom:11px;flex-wrap:wrap}
.atelier .as-foryou-t{font-family:'Fraunces',Georgia,serif;font-size:18px;font-weight:500;letter-spacing:-.01em}
.atelier .as-foryou-s{font-size:12.5px;color:var(--ink-3)}
.atelier .as-foryou-row{display:flex;gap:11px;overflow-x:auto;padding-bottom:4px}
.atelier .as-fy-card{display:flex;align-items:center;gap:11px;flex:0 0 auto;width:238px;appearance:none;cursor:pointer;text-align:left;
  background:var(--surface-solid);border:1px solid var(--line);border-radius:15px;padding:12px;
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease),transform .18s var(--spring)}
.atelier .as-fy-card:hover{border-color:var(--line-2);box-shadow:var(--shadow-sm);transform:translateY(-2px)}
.atelier .as-fy-ic{width:40px;height:40px;flex-shrink:0;border-radius:12px;display:grid;place-items:center;color:#fff;font-family:'Fraunces',Georgia,serif;font-size:16px;font-weight:600}
.atelier .as-fy-m{display:flex;flex-direction:column;gap:3px;min-width:0}
.atelier .as-fy-n{font-size:13.5px;font-weight:700;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .as-fy-why{font-size:11.5px;color:var(--brand);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .te-mine{color:var(--brand);font-weight:700}

/* ── Đăng app theo quota (SubmitFlow modal) ───────────────────────────── */
.atelier .sub-ov{position:fixed;inset:0;z-index:120;display:grid;place-items:center;padding:24px;
  background:rgba(20,19,15,.42);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);animation:at-fade .25s var(--ease)}
@keyframes at-fade{from{opacity:0}to{opacity:1}}
.atelier .sub-card{position:relative;width:min(620px,100%);max-height:88vh;overflow:auto;
  background:var(--surface-solid);border:1px solid var(--line);border-radius:var(--r-lg);padding:30px 32px 24px;
  box-shadow:var(--shadow-lg);animation:at-rise .4s var(--spring) both}
.atelier .sub-x{position:absolute;top:16px;right:18px;appearance:none;border:0;background:transparent;cursor:pointer;
  font-size:26px;line-height:1;color:var(--ink-3)}
.atelier .sub-x:hover{color:var(--ink)}
.atelier .sub-steps{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:22px}
.atelier .sub-step{display:flex;align-items:center;gap:7px;font-size:12.5px;font-weight:600;color:var(--ink-3);
  padding:6px 12px;border-radius:999px;background:var(--surface);border:1px solid var(--line)}
.atelier .sub-step.on{color:var(--brand);border-color:color-mix(in oklab,var(--brand) 40%,var(--line));background:color-mix(in oklab,var(--brand) 8%,var(--surface-solid))}
.atelier .sub-step.done{color:var(--a-month)}
.atelier .sub-step-n{display:grid;place-items:center;width:18px;height:18px;border-radius:50%;font-size:10.5px;font-weight:800;
  background:var(--line);color:var(--ink-2)}
.atelier .sub-step.on .sub-step-n{background:var(--brand);color:#fff}
.atelier .sub-step.done .sub-step-n{background:var(--a-month);color:#fff}
.atelier .sub-h{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:23px;letter-spacing:-.01em;margin-bottom:6px}
.atelier .sub-p{font-size:13.5px;color:var(--ink-2);line-height:1.55;margin-bottom:18px}
.atelier .sub-field{display:flex;flex-direction:column;gap:6px;margin-bottom:14px}
.atelier .sub-field>span{font-size:12px;font-weight:700;letter-spacing:.02em;color:var(--ink-2)}
.atelier .sub-field input,.atelier .sub-field select,.atelier .sub-field textarea{
  font-family:'Hanken Grotesk',sans-serif;font-size:14px;color:var(--ink);
  background:var(--surface);border:1px solid var(--line);border-radius:11px;padding:10px 13px;outline:none;resize:vertical}
.atelier .sub-field input:focus,.atelier .sub-field select:focus,.atelier .sub-field textarea:focus{border-color:var(--brand)}
.atelier .sub-icon-row{display:flex;align-items:center;gap:12px}
.atelier .sub-icon-prev{width:46px;height:46px;border-radius:13px;display:grid;place-items:center;color:#fff;flex-shrink:0}
.atelier .sub-ini{width:74px;text-align:center;text-transform:uppercase;
  font-family:'IBM Plex Mono',ui-monospace,monospace !important;font-size:14px;
  background:var(--surface);border:1px solid var(--line);border-radius:11px;padding:10px;outline:none}
.atelier .sub-ini:focus{border-color:var(--brand)}
.atelier .sub-colors{display:flex;gap:7px}
.atelier .sub-color{width:26px;height:26px;border-radius:8px;border:2px solid transparent;cursor:pointer;transition:transform .15s var(--ease)}
.atelier .sub-color:hover{transform:scale(1.12)}
.atelier .sub-color.on{border-color:var(--ink);box-shadow:0 0 0 2px var(--surface-solid) inset}
/* logo: tabs Tự đặt / Tải lên (chuẩn App Store) */
.atelier .sub-logo-tabs{display:flex;gap:6px;margin-bottom:10px}
.atelier .sub-logo-tab{appearance:none;cursor:pointer;font-size:12px;font-weight:700;padding:6px 12px;
  border-radius:999px;border:1px solid var(--line);background:var(--surface);color:var(--ink-2);transition:all .15s var(--ease)}
.atelier .sub-logo-tab:hover{border-color:var(--ink-3)}
.atelier .sub-logo-tab.on{background:var(--ink);color:var(--surface-solid);border-color:var(--ink)}
.atelier .sub-upload{margin-top:10px}
.atelier .sub-upload-drop{display:block;cursor:pointer;text-align:center;padding:16px;border:1.5px dashed var(--line);
  border-radius:13px;font-size:13px;color:var(--ink-2);transition:border-color .15s var(--ease)}
.atelier .sub-upload-drop:hover{border-color:var(--brand);color:var(--brand)}
.atelier .sub-upload-req{font-size:11.5px;color:var(--ink-3);line-height:1.55;margin-top:8px}
/* tier picker */
.atelier .sub-tiers{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin-bottom:16px}
.atelier .sub-tier{appearance:none;cursor:pointer;text-align:center;padding:12px 6px;border-radius:13px;
  background:var(--surface);border:1px solid var(--line);transition:border-color .2s var(--ease),background .2s var(--ease)}
.atelier .sub-tier:hover{border-color:var(--line-2)}
.atelier .sub-tier.on{border-color:var(--brand);background:color-mix(in oklab,var(--brand) 9%,var(--surface-solid))}
.atelier .sub-tier-n{font-size:13px;font-weight:700;color:var(--ink)}
.atelier .sub-tier-pr{font-size:10.5px;color:var(--ink-3);margin-top:3px}
.atelier .sub-tier-pr span{opacity:.7}
.atelier .sub-quota{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:16px}
.atelier .sub-quota-cell{background:var(--surface);border:1px solid var(--line);border-radius:13px;padding:13px 14px;text-align:center}
.atelier .sub-quota-w{font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3)}
.atelier .sub-quota-v{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:18px;font-weight:600;color:var(--ink);margin-top:5px}
.atelier .sub-quota-v span{font-size:11px;color:var(--ink-3);font-weight:400}
.atelier .sub-quota-d{font-size:11px;color:var(--ink-3);margin-top:3px}
.atelier .sub-earn{background:color-mix(in oklab,var(--a-month) 7%,var(--surface));border:1px solid color-mix(in oklab,var(--a-month) 22%,var(--line));border-radius:15px;padding:16px}
.atelier .sub-earn-h{font-size:12.5px;font-weight:700;color:var(--ink-2);margin-bottom:12px}
.atelier .sub-earn-row{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.atelier .sub-earn-cell{text-align:center}
.atelier .sub-earn-v{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:20px;font-weight:700;color:var(--a-month)}
.atelier .sub-earn-l{font-size:11px;color:var(--ink-3);margin-top:3px}
.atelier .sub-earn-note{font-size:11.5px;color:var(--ink-3);line-height:1.5;margin-top:14px;border-top:1px solid color-mix(in oklab,var(--a-month) 18%,var(--line));padding-top:10px}
.atelier .sub-preview{display:grid;place-items:center;padding:10px 0 6px}
.atelier .sub-preview .card{width:min(320px,100%);cursor:default}
.atelier .sub-preview .card:hover{transform:none}
.atelier .sub-confirm{display:flex;gap:24px;flex-wrap:wrap;font-size:13px;color:var(--ink-2);margin-top:14px;
  border-top:1px solid var(--line);padding-top:14px}
.atelier .sub-done{text-align:center;padding-top:8px}
.atelier .sub-done-ic{width:58px;height:58px;border-radius:50%;display:grid;place-items:center;margin:0 auto 14px;
  font-size:30px;color:#fff;background:linear-gradient(150deg,var(--a-month),#0E9E74)}
.atelier .sub-mylist{text-align:left;margin-top:18px;border-top:1px solid var(--line);padding-top:14px}
.atelier .sub-mylist-h{font-size:12px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--ink-3);margin-bottom:10px}
.atelier .sub-myrow{display:grid;grid-template-columns:38px 1fr auto;gap:12px;align-items:center;padding:8px 0}
.atelier .sub-myrow-ic{width:38px;height:38px;border-radius:11px;display:grid;place-items:center;color:#fff;font-size:13px}
.atelier .sub-myrow-n{font-size:14px;font-weight:600}
.atelier .sub-myrow-d{font-size:11.5px;color:var(--ink-3);margin-top:2px}
.atelier .sub-status{font-size:11px;font-weight:700;padding:4px 10px;border-radius:999px;white-space:nowrap}
.atelier .sub-status.pending{background:color-mix(in oklab,var(--a-session) 16%,transparent);color:#C2410C}
.atelier .sub-status.review{background:color-mix(in oklab,var(--a-week) 16%,transparent);color:var(--a-week)}
.atelier .sub-status.live{background:color-mix(in oklab,var(--a-month) 16%,transparent);color:var(--a-month)}
.atelier .sub-nav{display:flex;align-items:center;gap:10px;margin-top:22px;padding-top:18px;border-top:1px solid var(--line)}
@media(max-width:560px){
  .atelier .sub-tiers{grid-template-columns:repeat(3,1fr)}
  .atelier .sub-quota,.atelier .sub-earn-row{grid-template-columns:1fr 1fr}
}

/* ── Đường đua (Bar chart race / Horserace) + xuất video ──────────────── */
.atelier .race{display:flex;flex-direction:column;gap:18px;animation:at-rise .5s var(--ease) both}
.atelier .race-ctrl{display:flex;flex-wrap:wrap;gap:18px 26px}
.atelier .race-grp{display:flex;flex-direction:column;gap:7px}
.atelier .race-lbl{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3)}
.atelier .race-seg{display:inline-flex;gap:3px;padding:3px;background:var(--surface);border:1px solid var(--line);border-radius:11px}
.atelier .race-seg-b{appearance:none;border:0;background:transparent;cursor:pointer;
  font-family:'Hanken Grotesk',sans-serif;font-size:13px;font-weight:600;color:var(--ink-2);
  padding:7px 13px;border-radius:8px;transition:background .18s var(--ease),color .18s var(--ease)}
.atelier .race-seg-b:hover:not(:disabled){color:var(--ink)}
.atelier .race-seg-b.on{background:var(--surface-solid);color:var(--brand);box-shadow:var(--shadow-sm)}
.atelier .race-seg-b:disabled{opacity:.5;cursor:not-allowed}
.atelier .race-span{display:inline-flex;align-items:center;height:34px;padding:0 14px;border-radius:11px;
  font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:12.5px;font-weight:600;color:var(--ink-2);
  background:var(--surface);border:1px solid var(--line)}
.atelier .race-sel{height:40px;padding:0 32px 0 14px;border-radius:11px;cursor:pointer;
  font-family:'Hanken Grotesk',sans-serif;font-size:13.5px;font-weight:600;color:var(--ink);
  background:var(--surface-solid) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238A8A8A' stroke-width='3'><path d='M6 9l6 6 6-6'/></svg>") no-repeat right 12px center;
  border:1px solid var(--line);outline:none;appearance:none;-webkit-appearance:none;min-width:170px}
.atelier .race-sel:focus{border-color:var(--brand);box-shadow:0 0 0 3px color-mix(in oklab,var(--brand) 14%,transparent)}
.atelier .race-sel:disabled{opacity:.5;cursor:not-allowed}
/* khung canvas — giữ tỷ lệ; canvas backing-store là 1920×1080/1080×1920 */
/* Khung đồ thị = thẻ macOS: bo mềm, viền hairline, đổ bóng nhẹ ĐỒNG BỘ app */
.atelier .race-stage{position:relative;margin:0 auto;width:100%;background:#0E0D0B;border-radius:18px;overflow:hidden;cursor:ew-resize;
  border:1px solid var(--line);box-shadow:0 14px 40px rgba(20,19,15,.13),0 2px 8px rgba(20,19,15,.07)}
.atelier .race-stage.is-light{background:#F4F3EE;border-color:var(--line-2)}
.atelier .race-stage:active{cursor:grabbing}
.atelier .race-stage.ar-16x9{max-width:1040px;aspect-ratio:16/9}
.atelier .race-stage.ar-9x16{max-width:430px;aspect-ratio:9/16}
.atelier .race-cv{display:block;width:100%;height:100%}
.atelier .race-rec{position:absolute;top:12px;right:14px;display:flex;align-items:center;gap:7px;
  background:rgba(0,0,0,.55);color:#fff;font-size:12px;font-weight:600;padding:6px 12px;border-radius:999px}
.atelier .race-rec-dot{width:9px;height:9px;border-radius:50%;background:var(--mc-danger);animation:race-blink 1s steps(2,start) infinite}
@keyframes race-blink{50%{opacity:.25}}
/* Lineup builder — tìm & thêm đối thủ nhanh */
.atelier .race-build{display:flex;flex-direction:column;gap:12px}
.atelier .race-build-head{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap}
.atelier .race-build-head .race-lbl b{color:var(--brand)}
.atelier .race-search{position:relative;min-width:300px;flex:1;max-width:440px}
.atelier .race-search-ic{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--ink-3);pointer-events:none}
.atelier .race-search-in{width:100%;height:42px;padding:0 38px 0 38px;border-radius:13px;
  font-family:'Hanken Grotesk',sans-serif;font-size:14px;color:var(--ink);
  background:var(--surface-solid);border:1px solid var(--line);outline:none;
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease)}
.atelier .race-search-in:focus{border-color:var(--brand);box-shadow:0 0 0 3px color-mix(in oklab,var(--brand) 14%,transparent)}
.atelier .race-search-in:disabled{opacity:.5}
.atelier .race-search-x{position:absolute;right:10px;top:50%;transform:translateY(-50%);appearance:none;border:0;background:transparent;
  cursor:pointer;color:var(--ink-3);font-size:14px;width:22px;height:22px;border-radius:50%}
.atelier .race-search-x:hover{background:var(--surface);color:var(--ink)}
/* dropdown kết quả */
.atelier .race-drop{position:absolute;z-index:30;top:calc(100% + 6px);left:0;right:0;
  background:var(--surface-solid);border:1px solid var(--line);border-radius:14px;padding:6px;
  box-shadow:var(--shadow-lg);max-height:320px;overflow:auto;animation:at-rise .2s var(--ease) both}
.atelier .race-drop-empty{padding:14px;text-align:center;font-size:13px;color:var(--ink-3)}
.atelier .race-drop-it{display:flex;align-items:center;gap:11px;width:100%;appearance:none;border:0;cursor:pointer;
  background:transparent;border-radius:10px;padding:8px 10px;text-align:left;transition:background .14s var(--ease)}
.atelier .race-drop-it:hover{background:color-mix(in oklab,var(--brand) 9%,var(--surface))}
.atelier .race-drop-av{width:34px;height:34px;flex-shrink:0;border-radius:10px;display:grid;place-items:center;
  color:#fff;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:12px;font-weight:700}
.atelier .race-drop-m{display:flex;flex-direction:column;min-width:0;flex:1}
.atelier .race-drop-n{font-size:13.5px;font-weight:600;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .race-drop-t{font-size:11.5px;color:var(--ink-3)}
.atelier .race-drop-add{flex-shrink:0;font-size:12px;font-weight:700;color:var(--brand);opacity:0;transition:opacity .14s var(--ease)}
.atelier .race-drop-it:hover .race-drop-add{opacity:1}
/* roster đã chọn */
.atelier .race-roster{display:flex;flex-wrap:wrap;gap:9px;align-items:center}
.atelier .race-chip{display:inline-flex;align-items:center;gap:8px;padding:5px 8px 5px 5px;border-radius:999px;
  background:var(--surface-solid);border:1px solid var(--line);transition:border-color .18s var(--ease),box-shadow .18s var(--ease);
  animation:at-rise .3s var(--spring) both}
.atelier .race-chip:hover{border-color:var(--line-2)}
.atelier .race-chip.is-hero{border-color:color-mix(in oklab,var(--brand) 50%,var(--line));
  background:color-mix(in oklab,var(--brand) 9%,var(--surface-solid));box-shadow:0 0 0 1px color-mix(in oklab,var(--brand) 26%,transparent)}
.atelier .race-chip-av{width:28px;height:28px;flex-shrink:0;border-radius:50%;display:grid;place-items:center;
  color:#fff;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11px;font-weight:700}
.atelier .race-chip-n{font-family:'Hanken Grotesk',sans-serif;font-size:13px;font-weight:600;color:var(--ink);max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .race-chip-x{appearance:none;border:0;cursor:pointer;background:transparent;color:var(--ink-3);font-size:12px;
  width:20px;height:20px;border-radius:50%;flex-shrink:0;transition:background .14s var(--ease),color .14s var(--ease)}
.atelier .race-chip-x:hover:not(:disabled){background:color-mix(in oklab,#E84D7A 16%,transparent);color:#E84D7A}
.atelier .race-chip-x:disabled{opacity:.35;cursor:not-allowed}
.atelier .race-chip-add{appearance:none;cursor:pointer;font-family:'Hanken Grotesk',sans-serif;font-size:13px;font-weight:600;
  color:var(--brand);background:transparent;border:1.5px dashed color-mix(in oklab,var(--brand) 40%,var(--line));
  border-radius:999px;padding:7px 15px;transition:background .16s var(--ease),border-color .16s var(--ease)}
.atelier .race-chip-add:hover{background:color-mix(in oklab,var(--brand) 8%,transparent);border-color:var(--brand)}
/* gợi ý thêm nhanh */
.atelier .race-quick{display:flex;flex-wrap:wrap;align-items:center;gap:7px}
.atelier .race-quick-lbl{font-size:12px;color:var(--ink-3);font-weight:600}
.atelier .race-quick-b{display:inline-flex;align-items:center;gap:6px;appearance:none;cursor:pointer;
  font-family:'Hanken Grotesk',sans-serif;font-size:12px;font-weight:600;color:var(--ink-2);
  background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:5px 11px;
  transition:border-color .16s var(--ease),color .16s var(--ease),background .16s var(--ease)}
.atelier .race-quick-b:hover{border-color:var(--brand);color:var(--brand);background:color-mix(in oklab,var(--brand) 7%,transparent)}
.atelier .race-quick-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.atelier .race-actions{display:flex;align-items:center;gap:10px;border-top:1px solid var(--line);padding-top:16px}
.atelier .race-export{min-width:150px}
.atelier .race-note{font-size:12px;color:var(--ink-3);line-height:1.5}
/* Toolbar gọn (macOS) */
.atelier .race-bar{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap}
.atelier .race-bar-l{display:flex;flex-direction:column;gap:2px;min-width:0}
.atelier .race-bar-title{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:20px;letter-spacing:-.01em}
.atelier .race-bar-sum{font-size:12.5px;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .race-bar-r{display:flex;align-items:center;gap:9px;flex-shrink:0}
.atelier .race-gear{display:inline-flex;align-items:center;gap:7px;appearance:none;cursor:pointer;
  font-family:'Hanken Grotesk',sans-serif;font-size:13.5px;font-weight:600;color:var(--ink-2);
  background:var(--surface-solid);border:1px solid var(--line);border-radius:11px;padding:9px 15px;
  transition:border-color .18s var(--ease),color .18s var(--ease),background .18s var(--ease)}
.atelier .race-gear:hover:not(:disabled){border-color:var(--line-2);color:var(--ink)}
.atelier .race-gear.on{border-color:var(--brand);color:var(--brand);background:color-mix(in oklab,var(--brand) 8%,var(--surface-solid))}
.atelier .race-gear svg{transition:transform .4s var(--spring)}
.atelier .race-gear.on svg{transform:rotate(60deg)}
/* ── Studio đường đua: TẤT CẢ trên một màn hình (rail trái + canvas phải) ── */
/* Khi stage chứa đường đua: cắt padding thừa để studio có tối đa chiều cao
   (padding-bottom 60px của stage rất phí cho 1 màn không cuộn) */
.atelier .stage:has(.race-studio){padding-top:14px;padding-bottom:14px}
/* race-studio: chiều cao do JS đặt = lấp vừa viewport (không cuộn trang) */
.atelier .race-studio{display:flex;flex-direction:column;gap:11px;min-height:0;overflow:hidden;animation:at-rise .5s var(--ease) both}
.atelier .rst-bar{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;flex-shrink:0}
.atelier .rst-bar-l{display:flex;flex-direction:column;gap:1px;min-width:0}
.atelier .rst-title{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:19px;letter-spacing:-.01em}
.atelier .rst-sum{font-size:12px;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .rst-bar-r{display:flex;align-items:center;gap:9px;flex-shrink:0}
/* rst-main lấp toàn bộ chiều cao còn lại của studio → rail + canvas cùng 1 màn */
.atelier .rst-main{flex:1;min-height:0;display:flex;gap:14px;align-items:stretch}
/* Bảng cài đặt accordion kiểu Flourish — dock phải, mỗi mục gập/mở */
.atelier .rst-panel{order:2;flex:0 0 300px;width:300px;display:flex;flex-direction:column;overflow-y:auto;
  background:var(--surface);border:1px solid var(--line);border-radius:16px;min-height:0}
.atelier .rst-panel-head{display:flex;align-items:center;justify-content:center;gap:10px;padding:12px 13px;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:2;
  background:var(--surface-solid)}
.atelier .rst-panel-head .rst-ar{width:100%;justify-content:center}
.atelier .rst-panel-head .rst-ar .te-range-b{flex:1;justify-content:center;padding:8px 10px;font-size:13px}
/* Nút Xuất MP4 — neo ở đáy panel cấu hình (sticky footer) */
.atelier .rst-panel-foot{position:sticky;bottom:0;z-index:3;margin-top:auto;padding:12px 13px;
  border-top:1px solid var(--line);background:var(--surface-solid)}
.atelier .rst-export{width:100%;display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:11px 14px;font-size:13.5px;font-weight:700;white-space:nowrap}
.atelier .rst-sec{border-bottom:1px solid var(--line)}
.atelier .rst-sec-h{display:flex;align-items:center;gap:8px;width:100%;appearance:none;cursor:pointer;background:transparent;border:0;
  padding:14px 16px;font-family:'Hanken Grotesk',sans-serif;font-size:15px;font-weight:700;color:var(--ink);text-align:left;
  transition:background .16s var(--ease)}
.atelier .rst-sec-h:hover{background:var(--surface-solid)}
.atelier .rst-sec-t{flex:1}
.atelier .rst-sec-sub{font-size:10.5px;font-weight:700;color:var(--ink-3);background:var(--surface-solid);
  border:1px solid var(--line);border-radius:999px;padding:1px 8px;font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .rst-sec-chev{color:var(--ink-3);transition:transform .22s var(--ease);flex:0 0 auto}
.atelier .rst-sec.open .rst-sec-chev{transform:rotate(180deg)}
.atelier .rst-sec-b{display:flex;flex-direction:column;gap:15px;padding:4px 16px 18px;animation:at-rise .22s var(--ease) both}
.atelier .rst-ctrls{display:flex;flex-direction:column;gap:9px}
.atelier .rst-ctrls .btn{width:100%;justify-content:center}
/* ✨ Preset phong cách 1-chạm (no-code) */
.atelier .rst-preset{display:flex;flex-direction:column;gap:7px}
.atelier .rst-preset-b{display:flex;align-items:center;gap:11px;width:100%;appearance:none;cursor:pointer;text-align:left;
  background:var(--surface-solid);border:1.5px solid var(--line);border-radius:13px;padding:9px 11px;
  transition:border-color .16s var(--ease),background .16s var(--ease),transform .16s var(--spring),box-shadow .16s var(--ease)}
.atelier .rst-preset-b:hover:not(:disabled){border-color:var(--line-2);transform:translateY(-1px);box-shadow:var(--shadow-sm)}
.atelier .rst-preset-b.on{border-color:var(--brand);background:color-mix(in oklab,var(--brand) 8%,var(--surface-solid));box-shadow:0 0 0 3px color-mix(in oklab,var(--brand) 13%,transparent)}
.atelier .rst-preset-b:disabled{opacity:.55;cursor:not-allowed}
.atelier .rst-preset-ic{font-size:22px;line-height:1;flex:0 0 auto;width:30px;text-align:center}
.atelier .rst-preset-m{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.atelier .rst-preset-n{font-family:'Hanken Grotesk',sans-serif;font-size:13.5px;font-weight:700;color:var(--ink)}
.atelier .rst-preset-b.on .rst-preset-n{color:var(--brand)}
.atelier .rst-preset-d{font-size:11px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .rst-preset-ck{flex:0 0 auto;color:var(--brand);font-weight:800;font-size:15px}
.atelier .rst-preset-note{font-size:11px;color:var(--ink-3);margin-top:9px;line-height:1.45}
/* Màu nền — swatch trực quan */
.atelier .rst-bg{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.atelier .rst-bg-b{display:flex;align-items:center;gap:9px;appearance:none;cursor:pointer;text-align:left;
  background:var(--surface-solid);border:1.5px solid var(--line);border-radius:12px;padding:8px 9px;
  transition:border-color .16s var(--ease),box-shadow .16s var(--ease),transform .16s var(--spring)}
.atelier .rst-bg-b:hover:not(:disabled){border-color:var(--line-2);transform:translateY(-1px)}
.atelier .rst-bg-b.on{border-color:var(--brand);box-shadow:0 0 0 3px color-mix(in oklab,var(--brand) 14%,transparent)}
.atelier .rst-bg-b:disabled{opacity:.55;cursor:not-allowed}
.atelier .rst-bg-sw{width:26px;height:26px;border-radius:8px;flex:0 0 auto;border:1px solid rgba(20,19,15,.14)}
.atelier .rst-bg-b.bg-light .rst-bg-sw{background:linear-gradient(135deg,#fff,#eceae3)}
.atelier .rst-bg-b.bg-dark .rst-bg-sw{background:linear-gradient(135deg,#2a2722,#0e0d0b)}
.atelier .rst-bg-m{display:flex;flex-direction:column;min-width:0;flex:1}
.atelier .rst-bg-n{font-size:12.5px;font-weight:700;color:var(--ink)}
.atelier .rst-bg-b.on .rst-bg-n{color:var(--brand)}
.atelier .rst-bg-d{font-size:10px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .rst-bg-ck{color:var(--brand);font-weight:800;font-size:13px;flex:0 0 auto}
.atelier .rst-grp{display:flex;flex-direction:column;gap:7px;min-width:0}
.atelier .rst-row{display:grid;grid-template-columns:1fr 1fr;gap:10px;align-items:start}
.atelier .rst-lbl{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .rst-lbl b{color:var(--brand);font-weight:700}
.atelier .rst-lbl-v{color:var(--brand);font-weight:800;font-variant-numeric:tabular-nums}
/* Thanh trượt giãn cách (kéo ngang) — track bo + thumb tròn kiểu macOS */
.atelier .rst-slider{-webkit-appearance:none;appearance:none;width:100%;height:6px;border-radius:99px;
  background:var(--line);outline:none;cursor:pointer;margin:7px 0 3px;transition:opacity .15s var(--ease)}
.atelier .rst-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;
  background:var(--brand);border:2.5px solid var(--surface-solid);box-shadow:0 1px 5px rgba(20,19,15,.32),0 0 0 .5px rgba(20,19,15,.06);
  cursor:pointer;transition:transform .12s var(--spring)}
.atelier .rst-slider::-webkit-slider-thumb:hover{transform:scale(1.14)}
.atelier .rst-slider::-webkit-slider-thumb:active{transform:scale(.96)}
.atelier .rst-slider:focus-visible{outline:2px solid var(--brand);outline-offset:3px}
.atelier .rst-slider:disabled{opacity:.5;cursor:not-allowed}
.atelier .rst-slider-ends{display:flex;justify-content:space-between;font-size:10px;font-weight:600;color:var(--ink-3);letter-spacing:.02em}
/* chủ đề — pill dọc 3 ô */
.atelier .rst-subj{display:flex;gap:6px}
.atelier .rst-subj-b{flex:1;min-width:0;display:inline-flex;flex-direction:column;align-items:center;gap:2px;cursor:pointer;
  appearance:none;background:var(--surface-solid);border:1.5px solid var(--line);border-radius:12px;padding:5px 3px;
  font-family:'Hanken Grotesk',sans-serif;font-size:11px;font-weight:600;color:var(--ink-2);
  transition:border-color .16s var(--ease),background .16s var(--ease),color .16s var(--ease)}
.atelier .rst-subj-b:hover:not(:disabled){border-color:var(--line-2)}
.atelier .rst-subj-b.on{border-color:var(--brand);color:var(--brand);background:color-mix(in oklab,var(--brand) 8%,var(--surface-solid))}
.atelier .rst-subj-ic{font-size:17px;line-height:1}
/* Kiểu đồ thị: hàng ngang 4 ô preview gọn (tiết kiệm chiều cao rail) */
.atelier .rst-types{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
.atelier .rst-roster{display:flex;flex-wrap:wrap;align-content:flex-start;gap:6px;flex:1;min-height:40px;overflow-y:auto;overflow-x:hidden}
/* Đối thủ = nhóm CUỐI rail → giãn lấp phần còn lại; chỉ danh sách chip cuộn,
   mọi BỘ LỌC phía trên LUÔN hiện đủ (không cuộn) */
.atelier .rst-panel > .rst-grp:last-child{flex:1 1 auto;min-height:0}
/* Rail compact: thu nhỏ control dùng chung cho vừa 1 màn */
.atelier .rst-panel .race-type{gap:6px;padding:8px 5px;border-radius:11px;align-items:center}
.atelier .rst-panel .race-type-thumb{padding:5px;border-radius:7px;width:100%}
.atelier .rst-panel .race-type-thumb svg{height:24px;width:100%}
.atelier .rst-panel .race-type-lb{font-size:11.5px;line-height:1.15}
.atelier .rst-panel .race-sel{height:40px;min-width:0;width:100%;font-size:13.5px;padding:0 28px 0 12px}
.atelier .rst-panel .race-seg{padding:3px;width:100%}
.atelier .rst-panel .race-seg-b{padding:8px 6px;font-size:13.5px}
.atelier .rst-panel .race-search{min-width:0;max-width:none;width:100%;flex:none}
.atelier .rst-panel .race-search-in{height:38px;font-size:14px}
.atelier .rst-panel .race-chip{padding:3px 7px 3px 3px;gap:6px}
.atelier .rst-panel .race-chip-av{width:22px;height:22px;font-size:10px}
.atelier .rst-panel .race-chip-n{font-size:12px;max-width:104px}
/* sân khấu canvas — FULL-BLEED cinematic: bỏ khung/nền/padding để đồ thị tối làm chủ */
.atelier .rst-stage-wrap{flex:1;min-width:0;display:flex;align-items:center;justify-content:center;
  background:transparent;border:none;border-radius:0;padding:0;overflow:visible;position:relative}
.atelier .rst-stage-wrap .race-stage{margin:0;max-height:100%;max-width:100%}
/* Điều khiển nổi kiểu Apple — kính mờ trên góc phải đồ thị */
/* Thanh điều khiển trên (ngoài canvas) — Phát lại / Xuất MP4 căn phải */
.atelier .rst-topbar{display:flex;justify-content:flex-end;align-items:center;gap:9px;flex-shrink:0;margin-bottom:2px}
.atelier .rst-top-b{display:inline-flex;align-items:center;gap:7px}
/* Thanh điều khiển video kiểu macOS QuickTime — frosted, span đáy canvas, có track tua */
.atelier .rst-vbar{position:absolute;left:14px;right:14px;bottom:13px;z-index:7;
  display:flex;align-items:center;gap:11px;height:46px;padding:0 13px 0 7px;border-radius:15px;
  background:rgba(252,251,248,.74);-webkit-backdrop-filter:blur(22px) saturate(1.7);backdrop-filter:blur(22px) saturate(1.7);
  border:1px solid rgba(20,19,15,.08);
  box-shadow:0 10px 30px rgba(20,19,15,.18),0 1px 2px rgba(20,19,15,.1),inset 0 1px 0 rgba(255,255,255,.6)}
.atelier .rst-vbar-play{flex:0 0 auto;width:34px;height:34px;border-radius:50%;border:none;cursor:pointer;
  display:grid;place-items:center;color:#fff;background:linear-gradient(180deg,#FF9A3D,#F26B1A);
  box-shadow:0 3px 9px rgba(242,107,26,.42),inset 0 1px 0 rgba(255,255,255,.42);
  transition:transform .14s var(--spring),filter .14s var(--ease)}
.atelier .rst-vbar-play:hover:not(:disabled){filter:brightness(1.05);transform:scale(1.06)}
.atelier .rst-vbar-play:active:not(:disabled){transform:scale(.93)}
.atelier .rst-vbar-rep{flex:0 0 auto;width:30px;height:30px;border-radius:50%;cursor:pointer;display:grid;place-items:center;
  color:var(--ink-2);background:rgba(20,19,15,.05);border:1px solid rgba(20,19,15,.07);
  transition:background .14s var(--ease),color .14s var(--ease),transform .14s var(--spring)}
.atelier .rst-vbar-rep:hover:not(:disabled){background:rgba(20,19,15,.1);color:var(--ink);transform:scale(1.06)}
.atelier .rst-vbar-track{position:relative;flex:1 1 auto;height:6px;align-self:center;border-radius:99px;cursor:pointer;
  background:rgba(20,19,15,.13)}
.atelier .rst-vbar-track::before{content:"";position:absolute;left:0;right:0;top:-10px;bottom:-10px}
.atelier .rst-vbar-fill{position:absolute;left:0;top:0;bottom:0;width:0;border-radius:99px;
  background:linear-gradient(90deg,#FF9A3D,#F26B1A);pointer-events:none}
.atelier .rst-vbar-knob{position:absolute;top:50%;left:0;width:14px;height:14px;transform:translate(-50%,-50%);
  border-radius:50%;background:#fff;box-shadow:0 1px 4px rgba(20,19,15,.35),0 0 0 1px rgba(20,19,15,.06);
  pointer-events:none;transition:transform .12s var(--ease)}
.atelier .rst-vbar-track:hover .rst-vbar-knob{transform:translate(-50%,-50%) scale(1.18)}
.atelier .rst-vbar-play:disabled,.atelier .rst-vbar-rep:disabled{opacity:.5;cursor:not-allowed}
/* Biến thể nền tối: bar kính mờ tối để nổi trên canvas tối */
.atelier .race-stage:not(.is-light) .rst-vbar{background:rgba(30,28,24,.56);border-color:rgba(255,255,255,.12);
  box-shadow:0 10px 30px rgba(0,0,0,.42),inset 0 1px 0 rgba(255,255,255,.12)}
.atelier .race-stage:not(.is-light) .rst-vbar-track{background:rgba(255,255,255,.18)}
.atelier .race-stage:not(.is-light) .rst-vbar-rep{background:rgba(255,255,255,.1);color:rgba(255,255,255,.82);border-color:rgba(255,255,255,.13)}
.atelier .race-stage:not(.is-light) .rst-vbar-rep:hover:not(:disabled){background:rgba(255,255,255,.2);color:#fff}
.atelier .rst-float{position:absolute;top:14px;right:14px;z-index:6;display:flex;gap:9px}
.atelier .rst-float-b{display:inline-flex;align-items:center;gap:7px;appearance:none;cursor:pointer;
  border:1px solid rgba(255,255,255,.18);background:rgba(18,17,14,.46);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  color:#fff;font-family:'Hanken Grotesk',sans-serif;font-size:13px;font-weight:600;padding:9px 15px;border-radius:12px;
  transition:background .18s var(--ease),transform .18s var(--spring),border-color .18s var(--ease),box-shadow .18s var(--ease)}
.atelier .rst-float-b:hover:not(:disabled){background:rgba(18,17,14,.66);transform:translateY(-1px);border-color:rgba(255,255,255,.34)}
.atelier .rst-float-b.primary{background:var(--brand);border-color:transparent;box-shadow:0 8px 22px rgba(247,111,25,.42)}
.atelier .rst-float-b.primary:hover:not(:disabled){background:#ff7d2e;box-shadow:0 10px 26px rgba(247,111,25,.5)}
.atelier .rst-float-b:disabled{opacity:.6;cursor:not-allowed}
.atelier .rst-rec-dot{width:9px;height:9px;border-radius:50%;background:#fff;animation:race-blink 1s steps(2,start) infinite}
/* ── Đường đua: GIỮ chợ (nav + market tabs + segment), chỉ dọn rác trong view
   trending — ẩn footnote thừa; tiêu đề lặp đã bỏ ở JSX, nút đã thành nổi. ── */
.atelier.race-immersive .footnote{display:none}
.atelier .rst-stage-wrap .race-stage.ar-16x9{width:auto;height:100%;max-width:100%;aspect-ratio:16/9}
.atelier .rst-stage-wrap .race-stage.ar-9x16{width:auto;height:100%;max-width:100%;aspect-ratio:9/16}
/* WEB NHÚNG (tab Khám phá, .ocs-race-embed): trang cuộn dài — height:100% bị flex-stretch
   theo panel Thiết lập → MÉO tỷ lệ. Đảo chiều: 16:9 WIDTH dẫn (aspect-ratio giữ chuẩn);
   9:16 height dẫn (≤78vh) + căn giữa. Studio không bị ép cao. */
.ocs-race-embed .rst-stage-wrap{align-items:flex-start}
.ocs-race-embed .rst-stage-wrap .race-stage.ar-16x9{width:100%;height:auto;aspect-ratio:16/9}
.ocs-race-embed .rst-stage-wrap .race-stage.ar-9x16{width:auto;height:min(78vh,820px);max-width:100%;aspect-ratio:9/16;margin-inline:auto}
.ocs-race-embed .race-studio{height:auto !important;overflow:visible}
/* ── 3 CHẾ ĐỘ (CEO 2026-07-05): MIN mặc định = CHỈ đồ thị (thiết lập ẩn); ⚙ mở STUDIO
   full màn hình với CỘT THIẾT LẬP BÊN PHẢI; ⛶ = fullscreen chart nền đen. ── */
.ocs-race-embed.ocs-race-min .rst-panel{display:none}
.ocs-race-embed .rst-stage-wrap{width:100%}
/* Nút Xuất video — pill ĐEN (hành động; cam chỉ dành cho logo) */
.ocs-race-embed .rst-panel-foot .rst-export{border-radius:999px;
  background:var(--mc-accent);box-shadow:var(--mc-e2);
  transition:transform .16s ease,box-shadow .16s ease}
.ocs-race-embed .rst-panel-foot .rst-export:hover{transform:translateY(-1px)}
.ocs-race-embed .rst-panel-foot .rst-export:active{transform:translateY(0) scale(.97)}
/* STUDIO: khung full màn hình nền paper, chart TRÁI co giữa + panel THIẾT LẬP cột PHẢI cuộn được */
.ocs-race-embed.ocs-race-studio .race-studio{position:fixed;inset:0;z-index:9700;background:rgba(244,243,238,.99);
  display:flex;flex-direction:column;
  padding:max(12px,env(safe-area-inset-top)) max(12px,env(safe-area-inset-right)) max(12px,env(safe-area-inset-bottom)) max(12px,env(safe-area-inset-left))}
.ocs-race-embed.ocs-race-studio .rst-main{flex:1;min-height:0;flex-direction:row;gap:14px;align-items:stretch}
.ocs-race-embed.ocs-race-studio .rst-panel{display:flex;order:2;flex:0 0 330px;width:330px;flex-direction:column;
  overflow-y:auto;min-height:0;background:#fff;border:1px solid rgba(120,120,110,.16);border-radius:16px;
  box-shadow:0 14px 40px rgba(20,19,15,.10)}
.ocs-race-embed.ocs-race-studio .rst-stage-wrap{flex:1;min-width:0;width:auto;display:flex;align-items:center;justify-content:center}
.ocs-race-embed.ocs-race-studio .rst-stage-wrap .race-stage.ar-16x9{width:auto;height:auto;max-width:100%;max-height:100%;aspect-ratio:16/9;
  width:min(100%,calc((100dvh - 28px)*1.7778))}
.ocs-race-embed.ocs-race-studio .rst-stage-wrap .race-stage.ar-9x16{width:auto;height:min(calc(100dvh - 28px),100%);max-width:100%;aspect-ratio:9/16;margin:0 auto}
@media(max-width:760px){
  /* mobile studio: chart TRÊN, thiết lập cuộn DƯỚI (cột phải không vừa màn dọc) */
  .ocs-race-embed.ocs-race-studio .rst-main{flex-direction:column}
  .ocs-race-embed.ocs-race-studio .rst-panel{order:2;flex:1;width:100%;min-height:0}
  .ocs-race-embed.ocs-race-studio .rst-stage-wrap{flex:none}
  .ocs-race-embed.ocs-race-studio .rst-stage-wrap .race-stage.ar-16x9{width:100%;height:auto}
}
/* Nút TOÀN MÀN HÌNH ⛶ trên góc stage — glass tối, hover đậm, không dính scrub kéo-tua */
.ocs-race-fsbtn{position:absolute;right:12px;top:12px;z-index:6;width:40px;height:40px;border-radius:12px;border:none;
  background:rgba(20,19,15,.45);color:#fff;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .16s ease,transform .12s ease}
.ocs-race-fsbtn:hover{background:rgba(20,19,15,.68)}
.ocs-race-fsbtn:active{transform:scale(.9)}
/* Chế độ FULL MÀN HÌNH (pseudo-FS — chạy mượt MỌI thiết bị, kể cả iOS): stage fixed inset 0,
   nền đen điện ảnh, chart căn giữa GIỮ TỶ LỆ theo 100dvh, ribbon ẩn, ESC/✕ thoát. */
body.ocs-race-fs-open{overflow:hidden!important}
.ocs-race-embed.ocs-race-fs:not(.ocs-race-studio) .rst-panel{display:none}
/* animation at-rise biến .race-studio thành CONTAINING BLOCK → fixed bị neo nội bộ; FS/studio phải tắt */
.ocs-race-embed.ocs-race-fs .race-studio,.ocs-race-embed.ocs-race-fs .rst-main{animation:none!important;transform:none!important;filter:none!important;backdrop-filter:none!important;will-change:auto!important}
.ocs-race-embed.ocs-race-fs:not(.ocs-race-studio) .rst-stage-wrap{position:fixed;inset:0;z-index:9700;background:#0B0A09;
  display:flex;align-items:center;justify-content:center;
  padding:max(12px,env(safe-area-inset-top)) max(12px,env(safe-area-inset-right)) max(12px,env(safe-area-inset-bottom)) max(12px,env(safe-area-inset-left))}
.ocs-race-embed.ocs-race-fs:not(.ocs-race-studio) .rst-stage-wrap .race-stage.ar-16x9{width:min(100%,calc((100dvh - 24px)*1.7778));height:auto;max-height:100%}
.ocs-race-embed.ocs-race-fs:not(.ocs-race-studio) .rst-stage-wrap .race-stage.ar-9x16{width:auto;height:min(calc(100dvh - 24px),100%);max-width:100%;aspect-ratio:9/16}
/* cụm nút góc phải stage (⚙ + ⛶ ở min; ✕ ở fs/studio) */
.ocs-race-btns{position:absolute;right:12px;top:12px;z-index:6;display:flex;gap:8px}
.ocs-race-btns .ocs-race-fsbtn{position:static}
@media(max-width:760px){
  .ocs-race-fsbtn{width:38px;height:38px}
  .ocs-race-btns{right:10px;top:10px}
  .ocs-race-embed.ocs-race-studio .rst-panel-foot .rst-export{width:100%;justify-content:center}
}
@media(max-width:980px){
  .atelier .race-studio{overflow:visible;height:auto !important}
  .atelier .rst-main{flex-direction:column}
  .atelier .rst-panel{flex:none;width:100%}
  .atelier .rst-types{grid-template-columns:repeat(4,1fr)}
  .atelier .rst-stage-wrap .race-stage{width:100%;height:auto;max-height:62vh}
}

/* Khu làm việc: sidebar settings + canvas cạnh nhau (canvas LUÔN thấy) */
.atelier .race-work{display:flex;gap:16px;align-items:flex-start}
.atelier .race-canvas-col{flex:1;min-width:0}
.atelier .race-side{flex:0 0 300px;width:300px;align-self:stretch;display:flex;flex-direction:column;
  background:var(--surface-solid);border:1px solid var(--line);border-radius:18px;overflow:hidden;
  box-shadow:var(--shadow-md);animation:race-side-in .3s var(--ease) both;max-height:72vh}
@keyframes race-side-in{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:none}}
.atelier .race-side-head{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;
  padding:13px 16px;border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,color-mix(in oklab,var(--brand) 6%,var(--surface)),var(--surface))}
.atelier .race-side-title{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:16px;letter-spacing:-.01em;color:var(--ink)}
.atelier .race-side-body{display:flex;flex-direction:column;gap:18px;padding:16px;overflow-y:auto;min-height:0}
/* trong sidebar: thẻ chủ đề & preview xếp DỌC cho gọn */
.atelier .race-side .race-cards{grid-template-columns:1fr}
.atelier .race-side .race-types{grid-template-columns:1fr 1fr}
.atelier .race-side .race-seg-fill{flex-wrap:wrap}
@media(max-width:980px){
  .atelier .race-work{flex-direction:column}
  .atelier .race-side{flex:none;width:100%;max-height:none}
  .atelier .race-side .race-cards{grid-template-columns:repeat(3,1fr)}
}
/* Sheet tùy chỉnh (cũ, giữ class dùng chung) — panel kiểu macOS */
.atelier .race-sheet{background:var(--surface-solid);border:1px solid var(--line);border-radius:20px;
  box-shadow:var(--shadow-lg);overflow:hidden;animation:race-sheet-in .32s var(--ease) both}
@keyframes race-sheet-in{from{opacity:0;transform:translateY(-12px) scale(.985)}to{opacity:1;transform:none}}
.atelier .race-sheet-head{display:flex;align-items:center;justify-content:space-between;
  padding:15px 20px;border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,color-mix(in oklab,var(--brand) 5%,var(--surface)),var(--surface))}
.atelier .race-sheet-htxt{display:flex;flex-direction:column;gap:2px}
.atelier .race-sheet-title{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:17px;letter-spacing:-.01em;color:var(--ink)}
.atelier .race-sheet-sub{font-size:12px;color:var(--ink-3)}
.atelier .race-sheet-x{display:grid;place-items:center;appearance:none;border:1px solid var(--line);cursor:pointer;
  background:var(--surface-solid);color:var(--ink-3);width:30px;height:30px;border-radius:50%;
  transition:background .15s var(--ease),color .15s var(--ease),border-color .15s var(--ease)}
.atelier .race-sheet-x:hover{background:var(--surface);color:var(--ink);border-color:var(--line-2)}
.atelier .race-sheet-body{display:flex;flex-direction:column;gap:20px;padding:20px}
.atelier .race-sec{display:flex;flex-direction:column;gap:9px;min-width:0}
.atelier .race-sheet-row{display:grid;grid-template-columns:1fr 1.1fr .8fr;gap:22px}
@media(max-width:820px){.atelier .race-sheet-row{grid-template-columns:1fr}}
.atelier .race-seg-fill{display:flex}
.atelier .race-seg-fill .race-seg-b{flex:1;text-align:center;white-space:nowrap}
/* Nút Tỷ lệ: icon khung + nhãn, dùng style segmented rõ nét như các nút khác */
.atelier .rst-ar-b{display:inline-flex;align-items:center;justify-content:center;gap:6px}
.atelier .rst-ar-b svg{display:block;flex:0 0 auto;opacity:.8}
.atelier .race-seg-b.rst-ar-b.on svg{opacity:1}
/* Thẻ chủ đề giàu thông tin */
.atelier .race-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
@media(max-width:560px){.atelier .race-cards{grid-template-columns:1fr}}
.atelier .race-card{position:relative;display:flex;align-items:center;gap:12px;cursor:pointer;text-align:left;
  appearance:none;background:var(--surface);border:1.5px solid var(--line);border-radius:15px;padding:13px 15px;
  transition:border-color .18s var(--ease),background .18s var(--ease),box-shadow .18s var(--ease),transform .18s var(--spring)}
.atelier .race-card:hover:not(:disabled){border-color:var(--line-2);transform:translateY(-1px)}
.atelier .race-card.on{border-color:var(--brand);background:color-mix(in oklab,var(--brand) 7%,var(--surface-solid));box-shadow:0 0 0 3px color-mix(in oklab,var(--brand) 13%,transparent)}
.atelier .race-card-ic{font-size:24px;line-height:1;flex-shrink:0}
.atelier .race-card-tx{display:flex;flex-direction:column;min-width:0}
.atelier .race-card-tx b{font-size:14px;font-weight:700;color:var(--ink)}
.atelier .race-card-tx i{font-style:normal;font-size:11.5px;color:var(--ink-3);margin-top:1px}
.atelier .race-card-tick{position:absolute;top:9px;right:9px;display:grid;place-items:center;width:18px;height:18px;
  border-radius:50%;background:var(--brand);color:#fff}
.atelier .race-card:disabled{opacity:.5;cursor:not-allowed}
/* Preview kiểu đồ thị */
.atelier .race-types{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
@media(max-width:680px){.atelier .race-types{grid-template-columns:repeat(2,1fr)}}
.atelier .race-type{display:flex;flex-direction:column;gap:8px;cursor:pointer;appearance:none;
  background:var(--surface);border:1.5px solid var(--line);border-radius:15px;padding:10px;
  transition:border-color .18s var(--ease),background .18s var(--ease),box-shadow .18s var(--ease),transform .18s var(--spring)}
.atelier .race-type:hover:not(:disabled){border-color:var(--line-2);transform:translateY(-1px)}
.atelier .race-type.on{border-color:var(--brand);background:color-mix(in oklab,var(--brand) 7%,var(--surface-solid));box-shadow:0 0 0 3px color-mix(in oklab,var(--brand) 13%,transparent)}
.atelier .race-type-thumb{display:block;background:linear-gradient(180deg,#FBFAF7,#F0EFE9);border:1px solid var(--line);border-radius:9px;padding:9px;line-height:0}
.atelier .race-type-thumb svg{width:100%;height:auto;display:block}
.atelier .race-type-lb{font-size:12.5px;font-weight:600;color:var(--ink-2);text-align:center}
.atelier .race-type.on .race-type-lb{color:var(--brand)}
.atelier .race-type:disabled{opacity:.5;cursor:not-allowed}
.atelier .race-sheet-foot{display:flex;align-items:center;gap:9px;padding:13px 20px;border-top:1px solid var(--line);
  background:var(--surface);font-size:11.5px;color:var(--ink-3);line-height:1.5}
.atelier .race-foot-dot{width:7px;height:7px;border-radius:50%;background:var(--green,#13C28E);flex-shrink:0}

/* ── (cũ) Leaderboard lb-* — giữ cho an toàn nếu còn tham chiếu ── */
.atelier .lb{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;background:var(--surface-solid)}
.atelier .lb-row{display:flex;align-items:center;gap:16px;padding:14px 20px;border-top:1px solid var(--line);cursor:pointer;transition:background .25s var(--ease)}
.atelier .lb-row:first-child{border-top:none}
.atelier .lb-row:hover{background:rgba(20,19,15,.03)}
.atelier .lb-rank{width:30px;flex-shrink:0;font-family:'Fraunces',Georgia,serif;font-size:20px;color:var(--ink-3);text-align:center}
.atelier .lb-rank.top{color:var(--a-session)}
.atelier .lb-ico{width:44px;height:44px;border-radius:12px;flex-shrink:0;display:grid;place-items:center;color:#fff;font-family:'Fraunces',Georgia,serif;font-size:18px}
.atelier .lb-meta{flex:1;min-width:0}
.atelier .lb-name{display:flex;align-items:center;gap:7px;font-size:15px;font-weight:600}
.atelier .lb-name .verify{width:15px;height:15px;color:var(--a-week);flex-shrink:0}
.atelier .lb-kind{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10px;font-weight:600;padding:2px 8px;border-radius:999px;letter-spacing:.02em}
.atelier .lb-kind.k-tool{background:color-mix(in oklab,var(--a-week) 14%,transparent);color:var(--a-week)}
.atelier .lb-kind.k-agent{background:color-mix(in oklab,#E84D7A 14%,transparent);color:#E84D7A}
.atelier .lb-kind.k-workflow{background:color-mix(in oklab,var(--violet,#7A5BFF) 16%,transparent);color:#7A5BFF}
.atelier .lb-by{font-size:12px;color:var(--ink-3);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .lb-uses{text-align:right;flex-shrink:0}
.atelier .lb-uses b{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:15px}
.atelier .lb-uses span{display:block;font-size:10.5px;color:var(--ink-3)}

/* ── Card flag variants + agent/workflow card extras ── */
.atelier .card-flag.flag-agent{background:linear-gradient(135deg,#E84D7A,#b3275a)}
.atelier .card-flag.flag-wf{background:linear-gradient(135deg,#7A5BFF,#5a3be0)}
.atelier .card-expert{margin-top:auto;font-size:12px;color:var(--ink-2);background:color-mix(in oklab,#E84D7A 8%,transparent);border-radius:9px;padding:7px 10px}
.atelier .card-steps{display:flex;gap:6px;flex-wrap:wrap;margin-top:auto}
.atelier .wf-pill{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10.5px;font-weight:600;color:#fff;background:var(--c);padding:3px 9px;border-radius:999px}

/* ── Agent: ask box + samples (detail) ── */
.atelier .ag-ask{border:1px solid color-mix(in oklab,#E84D7A 28%,var(--line));border-radius:18px;padding:18px;margin:6px 0 18px;background:color-mix(in oklab,#E84D7A 5%,transparent)}
.atelier .ag-ask-h{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.atelier .ag-badge{font-size:12.5px;font-weight:600;color:#b3275a}
.atelier .ag-cases{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11.5px;color:var(--ink-3)}
.atelier .ag-q-row{display:flex;gap:8px;align-items:center}
.atelier .ag-q-row input{flex:1;border:1px solid var(--line-2);border-radius:999px;padding:11px 16px;font:inherit;font-size:14px;background:var(--surface-solid);color:var(--ink);outline:none}
.atelier .ag-q-row input:focus{border-color:#E84D7A}
.atelier .ag-q-send{width:42px;height:42px;border-radius:50%;flex-shrink:0;border:none;background:#E84D7A;color:#fff;cursor:pointer;display:grid;place-items:center;transition:transform .3s var(--spring)}
.atelier .ag-q-send:hover{transform:scale(1.06)}
.atelier .ag-q-send svg{width:18px;height:18px}
.atelier .ag-samples{display:flex;flex-direction:column;gap:8px;margin-top:14px}
.atelier .ag-samples-lbl{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3)}
.atelier .ag-sample{text-align:left;font:inherit;font-size:13.5px;color:var(--ink);background:var(--surface-solid);border:1px solid var(--line);border-radius:12px;padding:10px 14px;cursor:pointer;transition:.25s var(--ease)}
.atelier .ag-sample:hover{border-color:#E84D7A;transform:translateX(3px)}

/* ── Workflow: steps + revenue split (detail) ── */
.atelier .wf-flow{margin:6px 0 4px}
.atelier .wf-steps{display:flex;flex-direction:column;align-items:stretch;margin:6px 0 18px}
.atelier .wf-step{display:flex;align-items:center;gap:14px;border:1px solid var(--line);border-radius:16px;padding:14px 16px;background:var(--surface-solid)}
.atelier .wf-step-ico{width:32px;height:32px;border-radius:50%;flex-shrink:0;display:grid;place-items:center;color:#fff;font-family:'Fraunces',Georgia,serif;font-size:15px}
.atelier .wf-step-body{flex:1;min-width:0}
.atelier .wf-step-name{font-size:14.5px;font-weight:600}
.atelier .wf-step-desc{font-size:12.5px;color:var(--ink-3);margin-top:2px}
.atelier .wf-step-pct{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:13px;font-weight:500;color:var(--ink-2)}
.atelier .wf-arrow{text-align:center;color:var(--ink-3);font-size:16px;line-height:1;padding:5px 0}
.atelier .wf-split{display:flex;flex-direction:column;gap:11px}
.atelier .wf-split-row{display:flex;align-items:center;gap:12px;font-size:13px}
.atelier .wf-split-row .nm{width:160px;flex-shrink:0;color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atelier .wf-split-row .track{flex:1;height:8px;border-radius:4px;background:rgba(20,19,15,.07);overflow:hidden}
.atelier .wf-split-row .track i{display:block;height:100%;border-radius:4px;width:0;transition:width 1s var(--ease)}
.atelier .wf-split-row .pct{width:36px;text-align:right;font-weight:600;font-family:'IBM Plex Mono',ui-monospace,monospace}

.atelier .catbar{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;margin:36px auto 22px;max-width:960px}
.atelier .chip{display:inline-flex;align-items:center;min-height:52px;font:inherit;font-size:15.5px;font-weight:500;letter-spacing:-.01em;color:var(--ink-2);background:var(--surface-solid);border:1px solid var(--line);border-radius:16px;padding:0 26px;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.035);transition:.3s var(--ease)}
.atelier .chip:hover{border-color:var(--ink-3);color:var(--ink);transform:translateY(-1px);box-shadow:0 5px 14px rgba(0,0,0,.08)}
.atelier .chip.on{background:var(--ink);color:var(--bg);border-color:var(--ink);font-weight:600;box-shadow:0 5px 16px rgba(0,0,0,.18)}
.atelier .gridmeta{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:12.5px;color:var(--ink-3);margin:0 0 18px;letter-spacing:.02em}
.atelier .grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
@media(min-width:1500px){.atelier .grid{grid-template-columns:repeat(4,1fr)}}
@media(min-width:2100px){.atelier .grid{grid-template-columns:repeat(5,1fr)}}
@media(min-width:2900px){.atelier .grid{grid-template-columns:repeat(6,1fr)}}
@media(max-width:980px){.atelier .grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:620px){.atelier .grid{grid-template-columns:1fr}}
.atelier .card{position:relative;background:var(--surface-solid);border:1px solid var(--line);border-radius:var(--r-lg);padding:24px;cursor:pointer;overflow:hidden;
  transition:transform .55s var(--spring),box-shadow .55s var(--ease),border-color .4s var(--ease);transform-style:preserve-3d;will-change:transform}
.atelier .card:hover{box-shadow:var(--shadow-lg);border-color:transparent}
/* Thẻ sản phẩm chính hãng (flagship) — viền accent + nhãn góc */
.atelier .card.is-featured{border-color:color-mix(in oklab,var(--a-week) 45%,var(--line));box-shadow:0 2px 6px rgba(46,125,255,.08),0 18px 50px rgba(46,125,255,.10)}
.atelier .card.is-featured:hover{box-shadow:0 4px 12px rgba(46,125,255,.14),0 28px 70px rgba(46,125,255,.18)}
.atelier .card-flag{position:absolute;top:16px;right:16px;z-index:1;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10.5px;font-weight:600;letter-spacing:.02em;color:#fff;background:linear-gradient(135deg,var(--a-week),#1850c8);padding:4px 10px;border-radius:999px;box-shadow:0 4px 12px rgba(46,125,255,.3)}
.atelier .card .glow{position:absolute;width:280px;height:280px;border-radius:50%;filter:blur(50px);opacity:0;transition:opacity .5s var(--ease);pointer-events:none;top:-90px;right:-60px}
.atelier .card:hover .glow{opacity:.55}
.atelier .icon{width:52px;height:52px;border-radius:15px;display:grid;place-items:center;margin-bottom:54px;color:#fff;font-family:'Fraunces',Georgia,serif;font-size:24px;font-weight:500;box-shadow:inset 0 1px 0 rgba(255,255,255,.4),0 8px 20px rgba(20,19,15,.14)}
.atelier .card h3{font-size:19px;font-weight:600;letter-spacing:-.02em;display:flex;align-items:center;gap:8px;line-height:1.2}
.atelier .card h3 .verify{width:16px;height:16px;color:var(--a-week);flex-shrink:0}
.atelier .card .by{font-size:13px;color:var(--ink-3);margin:5px 0 12px}
.atelier .card p{font-size:14px;color:var(--ink-2);line-height:1.5;min-height:42px}
.atelier .card .foot{display:flex;align-items:center;justify-content:space-between;margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}
.atelier .card .stat{font-size:12.5px;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .card .stat b{color:var(--ink);font-weight:500}
.atelier .card .arrow{width:30px;height:30px;border-radius:50%;border:1px solid var(--line-2);display:grid;place-items:center;transition:.4s var(--spring);flex-shrink:0}
.atelier .card:hover .arrow{background:var(--ink);border-color:var(--ink);color:#fff;transform:rotate(-45deg)}

.atelier .usewrap{display:grid;grid-template-columns:1.05fr .95fr;gap:24px;align-items:start;margin-top:40px}
@media(max-width:980px){.atelier .usewrap{grid-template-columns:1fr}}
.atelier .panel{background:var(--surface-solid);border:1px solid var(--line);border-radius:var(--r-lg);padding:28px;box-shadow:var(--shadow)}
.atelier .panel.dark{background:linear-gradient(160deg,#1A1916,#14130F);color:#fff;border:none}
.atelier .rings-card{display:flex;gap:28px;align-items:center}
@media(max-width:560px){.atelier .rings-card{flex-direction:column;text-align:center}}
.atelier .rings{position:relative;width:230px;height:230px;flex-shrink:0}
.atelier .rings svg{transform:rotate(-90deg);overflow:visible}
.atelier .ring-bg{fill:none;stroke:rgba(20,19,15,.07);stroke-width:13}
.atelier .ring-fg{fill:none;stroke-width:13;stroke-linecap:round;transition:stroke-dashoffset 1.3s var(--spring)}
.atelier .rings .ctr{position:absolute;inset:0;display:grid;place-content:center;text-align:center}
.atelier .rings .ctr .big{font-family:'Fraunces',Georgia,serif;font-size:40px;font-weight:400;line-height:1;font-variant-numeric:tabular-nums}
.atelier .rings .ctr .sub{font-size:11px;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace;letter-spacing:.1em;margin-top:4px;text-transform:uppercase}
.atelier .legend{display:flex;flex-direction:column;gap:18px;flex:1}
.atelier .leg{display:flex;align-items:center;gap:13px}
.atelier .leg .swatch{width:11px;height:11px;border-radius:50%;flex-shrink:0;box-shadow:0 0 0 4px rgba(0,0,0,.03)}
.atelier .leg .meta{flex:1}
.atelier .leg .meta .nm{font-size:14.5px;font-weight:600}
.atelier .leg .meta .vl{font-size:12.5px;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .leg .pct{font-family:'Fraunces',Georgia,serif;font-size:21px;font-variant-numeric:tabular-nums}
.atelier .feedrow{display:flex;align-items:center;gap:13px;padding:13px 0;border-bottom:1px solid var(--line)}
.atelier .feedrow:last-child{border-bottom:none}
.atelier .feedrow .fi{width:34px;height:34px;border-radius:10px;display:grid;place-items:center;color:#fff;font-family:'Fraunces',Georgia,serif;font-size:15px;flex-shrink:0}
.atelier .feedrow .fmeta{flex:1}
.atelier .feedrow .fmeta .a{font-size:14px;font-weight:500}
.atelier .feedrow .fmeta .b{font-size:12px;color:var(--ink-3)}
.atelier .feedrow .amt{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:13px;color:var(--ink-2)}
.atelier .section-h{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:6px}
.atelier .section-h h2{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:22px;letter-spacing:-.02em}
.atelier .section-h .lk{font-size:13px;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace}

.atelier .seg{display:inline-flex;background:rgba(20,19,15,.06);border-radius:999px;padding:4px;margin:34px 0 10px;position:relative}
.atelier .seg button{font:inherit;font-size:14.5px;font-weight:600;color:var(--ink-2);background:none;border:none;cursor:pointer;padding:11px 26px;border-radius:999px;position:relative;z-index:2;transition:color .4s var(--ease)}
.atelier .seg button.on{color:var(--ink)}
.atelier .seg .pill{position:absolute;top:4px;bottom:4px;background:var(--surface-solid);border-radius:999px;box-shadow:0 2px 8px rgba(20,19,15,.1);transition:left .5s var(--spring),width .5s var(--spring);z-index:1}
.atelier .plannote{font-size:13.5px;color:var(--ink-2);max-width:50ch;line-height:1.5;margin-bottom:8px}
.atelier .plannote b{color:var(--ink);font-weight:600}
.atelier .planwrap{display:grid;grid-template-columns:1.15fr .85fr;gap:24px;align-items:start;margin-top:26px}
@media(max-width:980px){.atelier .planwrap{grid-template-columns:1fr}}
.atelier .bigprice{display:flex;align-items:flex-end;gap:6px;margin:6px 0 2px}
.atelier .bigprice .cur{font-family:'Fraunces',Georgia,serif;font-size:26px;margin-bottom:8px}
.atelier .bigprice .num{font-family:'Fraunces',Georgia,serif;font-size:64px;font-weight:400;line-height:.9;letter-spacing:-.03em;font-variant-numeric:tabular-nums;transition:.4s var(--spring)}
.atelier .bigprice .per{font-size:14px;color:var(--ink-3);margin-bottom:10px}
.atelier .featlist{list-style:none;margin-top:22px;display:flex;flex-direction:column;gap:13px}
.atelier .featlist li{display:flex;align-items:flex-start;gap:11px;font-size:14.5px;color:var(--ink-2)}
.atelier .featlist li svg{flex-shrink:0;margin-top:2px;color:var(--a-month)}
.atelier .featlist li b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.atelier .btn{font:inherit;font-weight:600;font-size:15px;cursor:pointer;border:none;border-radius:999px;padding:15px 28px;transition:transform .4s var(--spring),box-shadow .4s var(--ease);display:inline-flex;align-items:center;gap:8px}
.atelier .btn-primary{background:var(--brand);color:#fff;box-shadow:0 6px 20px color-mix(in oklab,var(--brand) 34%,transparent)}
/* Nút "Đã thêm vào workspace" — trạng thái đã cài (macOS-style):
   pill xanh tinh tế, viền hairline, dấu ✓ trong vòng tròn, không phải nút bấm. */
.atelier .btn-installed{
  background:color-mix(in oklab, var(--green,#13a35a) 9%, var(--paper,#fff));
  color:color-mix(in oklab, var(--green,#13a35a) 78%, var(--ink,#14130f));
  border:1px solid color-mix(in oklab, var(--green,#13a35a) 26%, transparent);
  box-shadow:0 1px 2px rgba(20,19,15,.04), inset 0 1px 0 rgba(255,255,255,.5);
  cursor:default;font-weight:600;gap:8px}
.atelier .btn-installed:hover{filter:none;transform:none}
.atelier .btn-installed svg{
  background:var(--green,#13a35a);color:#fff;border-radius:50%;padding:3px;
  width:18px;height:18px;box-sizing:border-box;flex-shrink:0;stroke-width:3}
.atelier .btn-primary:hover{transform:translateY(-2px);box-shadow:0 10px 30px color-mix(in oklab,var(--brand) 42%,transparent)}
.atelier .btn-ghost{background:transparent;color:var(--ink);border:1px solid var(--line-2)}
.atelier .btn-ghost:hover{transform:translateY(-2px);border-color:var(--ink)}
.atelier .scale-badge{display:inline-block;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:12px;background:var(--ink);color:var(--bg);padding:4px 10px;border-radius:999px;margin-bottom:14px;letter-spacing:.05em}

.atelier .footnote{text-align:center;color:var(--ink-3);font-size:12.5px;margin-top:70px;font-family:'IBM Plex Mono',ui-monospace,monospace;letter-spacing:.04em}

/* ---- DETAIL ---- */
.atelier .dtl-wrap{animation:at-enter .55s var(--ease) both}
.atelier .dtl-wrap{position:relative}
/* Màn rộng (≥2700px, vd 34"): không chừa lề phải → nội dung CĂN GIỮA, thẳng với nav.
   Màn hẹp hơn (rail icon nổi sát mép) → chừa lề phải để rail không đè nội dung. */
@media(max-width:2700px){.atelier .dtl-wrap{padding-right:80px}}
@media(max-width:760px){.atelier .dtl-wrap{padding-right:0}}
.atelier .back{font:inherit;font-size:13.5px;font-weight:500;color:var(--ink-2);background:var(--surface-solid);border:1px solid var(--line);border-radius:999px;padding:8px 16px 8px 12px;cursor:pointer;display:inline-flex;align-items:center;gap:6px;transition:.3s var(--ease);margin-bottom:24px}
.atelier .back:hover{border-color:var(--line-2);transform:translateX(-2px)}
.atelier .dtl-head{display:flex;gap:20px;align-items:flex-start;flex-wrap:wrap}
.atelier .dtl-head .icon{margin-bottom:0;width:66px;height:66px;border-radius:18px;font-size:30px}
.atelier .dtl-h-meta{flex:1;min-width:200px}
.atelier .dtl-h-meta h1{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:clamp(30px,4vw,42px);letter-spacing:-.02em;display:flex;align-items:center;gap:10px;line-height:1.05}
.atelier .dtl-h-meta h1 .verify{width:22px;height:22px;color:var(--a-week);flex-shrink:0}
.atelier .dtl-h-meta .by{font-size:14px;color:var(--ink-3);margin:6px 0 12px}
.atelier .metachips{display:flex;gap:8px;flex-wrap:wrap;margin:4px 0 2px}
.atelier .metachips span{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11.5px;color:var(--ink-2);background:rgba(20,19,15,.05);border:1px solid var(--line);padding:5px 11px;border-radius:999px}
.atelier .dtl-cta{display:flex;flex-direction:column;gap:10px;align-items:stretch}
.atelier .dtl-cta .btn{padding:13px 22px;font-size:14.5px;justify-content:center}
.atelier .dtl-cta-note{font-size:11px;color:var(--ink-3,#8a8782);text-align:center;display:flex;align-items:center;justify-content:center;gap:5px;margin-top:-3px}
.atelier .dtl-cta-note::before{content:"⬇";font-size:10px}
@media(max-width:680px){.atelier .dtl-cta{flex-direction:row;width:100%;flex-wrap:wrap}.atelier .dtl-cta .btn{flex:1}}

/* ── Metachip stat (area 1 gộp vào area 2) — chip có icon trong dải metachips */
.atelier .metachips .mc-stat{display:inline-flex;align-items:center;gap:5px;color:var(--ink-2);font-weight:500}
.atelier .metachips .mc-stat svg{width:13px;height:13px;color:var(--ink-3)}

/* ── Area 3 — TikTok-style vertical action rail ──────────────────────
   Nổi cố định ở MÉP PHẢI màn hình (ngoài nội dung), mỗi nút là 1 vòng
   tròn + đếm phía dưới — như rail của YouTube Shorts / TikTok. Nội dung
   chi tiết được chừa 88px lề phải (.dtl-wrap) để không bao giờ chồng. */
.atelier .tt-rail{position:fixed;right:18px;top:50%;transform:translateY(-50%);z-index:55;
  display:flex;flex-direction:column;align-items:center;gap:18px;
  animation:tt-rail-in .5s var(--spring) both}
@keyframes tt-rail-in{from{opacity:0;transform:translate(12px,-50%)}to{opacity:1;transform:translateY(-50%)}}
@media(prefers-reduced-motion:reduce){.atelier .tt-rail{animation:none}}
.atelier .tt-btn{display:flex;flex-direction:column;align-items:center;gap:6px;background:none;border:none;cursor:pointer;font:inherit}
.atelier .tt-ic{width:52px;height:52px;border-radius:50%;display:grid;place-items:center;
  background:var(--surface-solid);border:1px solid var(--line);color:var(--ink);
  box-shadow:0 4px 16px rgba(20,19,15,.10);
  transition:transform .45s var(--spring),box-shadow .4s var(--ease),background .3s var(--ease),color .3s var(--ease),border-color .3s var(--ease)}
.atelier .tt-ic svg{width:24px;height:24px}
.atelier .tt-btn:hover .tt-ic{transform:translateY(-2px) scale(1.06);box-shadow:0 8px 22px rgba(20,19,15,.16)}
.atelier .tt-btn:active .tt-ic{transform:scale(.92)}
.atelier .tt-n{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:12px;font-weight:600;color:var(--ink-2)}
/* Like bật — đỏ hồng đầy + pop */
.atelier .tt-btn.on.like .tt-ic{background:#E84D7A;border-color:#E84D7A;color:#fff;box-shadow:0 8px 22px rgba(232,77,122,.4);animation:tt-pop .5s var(--spring)}
.atelier .tt-btn.on.like .tt-n{color:#E84D7A}
/* Save bật — xanh dương đầy */
.atelier .tt-btn.on.save .tt-ic{background:var(--a-week);border-color:var(--a-week);color:#fff;box-shadow:0 8px 22px rgba(46,125,255,.4);animation:tt-pop .5s var(--spring)}
.atelier .tt-btn.on.save .tt-n{color:var(--a-week)}
@keyframes tt-pop{0%{transform:scale(1)}35%{transform:scale(1.28)}60%{transform:scale(.92)}100%{transform:scale(1)}}
@media(max-width:1180px){.atelier .tt-rail{right:10px;gap:14px}.atelier .tt-ic{width:46px;height:46px}.atelier .tt-ic svg{width:21px;height:21px}}
/* Rail bị ẩn (unmount) khi mở ngăn bình luận — xử lý ở JSX (!cmtOpen). */

/* ── Comment drawer — phong cách YouTube ─────────────────────────────
   Trượt từ phải; mỗi bình luận có @handle · thời gian, nội dung, hàng
   thao tác 👍 đếm / 👎 / Phản hồi, menu 3 chấm; ô "Thêm bình luận…". */
.atelier .yt-cmt-scrim{position:fixed;inset:0;z-index:64;background:rgba(20,19,15,.28);backdrop-filter:blur(3px);animation:at-fadein .3s var(--ease) both}
@keyframes at-fadein{from{opacity:0}to{opacity:1}}
.atelier .yt-cmt{position:fixed;top:0;right:0;bottom:0;z-index:65;width:min(420px,94vw);
  background:var(--surface-solid);border-left:1px solid var(--line);box-shadow:var(--shadow-lg);
  display:flex;flex-direction:column;
  /* Drawer chỉ mount khi mở → slide-in bằng animation (không transition). */
  animation:yt-cmt-in .5s var(--spring) both}
@keyframes yt-cmt-in{from{transform:translateX(102%)}to{transform:none}}
@media(prefers-reduced-motion:reduce){.atelier .yt-cmt{animation:none}}
.atelier .yt-cmt-h{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;border-bottom:1px solid var(--line)}
.atelier .yt-cmt-h .ttl{font-size:17px;font-weight:600;letter-spacing:-.01em}
.atelier .yt-cmt-h .ttl .cnt{color:var(--ink-3);font-weight:500;margin-left:6px}
.atelier .yt-cmt-h-act{display:flex;align-items:center;gap:4px}
.atelier .yt-icbtn{width:36px;height:36px;border-radius:50%;border:none;background:none;color:var(--ink-2);cursor:pointer;display:grid;place-items:center;transition:background .25s var(--ease)}
.atelier .yt-icbtn:hover{background:rgba(20,19,15,.06);color:var(--ink)}
.atelier .yt-icbtn svg{width:20px;height:20px}
.atelier .yt-cmt-list{flex:1;overflow-y:auto;padding:8px 18px 18px}
.atelier .yt-cmt-row{display:flex;gap:12px;padding:14px 0}
.atelier .yt-cmt-row .av{width:36px;height:36px;border-radius:50%;flex-shrink:0;display:grid;place-items:center;color:#fff;font-weight:600;font-size:14px}
.atelier .yt-cmt-body{flex:1;min-width:0}
.atelier .yt-cmt-body .meta{font-size:13px;font-weight:600;color:var(--ink)}
.atelier .yt-cmt-body .meta .when{color:var(--ink-3);font-weight:400;font-size:12px;margin-left:5px}
.atelier .yt-cmt-body .txt{font-size:14px;color:var(--ink);line-height:1.5;margin:3px 0 6px;white-space:pre-wrap;word-break:break-word}
.atelier .yt-cmt-body .acts{display:flex;align-items:center;gap:6px}
.atelier .yt-cmt-body .acts .like,.atelier .yt-cmt-body .acts .dislike{display:inline-flex;align-items:center;gap:6px;background:none;border:none;cursor:pointer;color:var(--ink-2);padding:6px 6px;border-radius:999px;font:inherit;font-size:12px;transition:background .25s var(--ease),color .25s var(--ease)}
.atelier .yt-cmt-body .acts .like:hover,.atelier .yt-cmt-body .acts .dislike:hover{background:rgba(20,19,15,.06);color:var(--ink)}
.atelier .yt-cmt-body .acts svg{width:18px;height:18px}
.atelier .yt-cmt-body .acts .reply{margin-left:4px;background:none;border:none;cursor:pointer;color:var(--ink);font:inherit;font-size:12.5px;font-weight:600;padding:7px 12px;border-radius:999px;transition:background .25s var(--ease)}
.atelier .yt-cmt-body .acts .reply:hover{background:rgba(20,19,15,.06)}
.atelier .yt-cmt-more{display:inline-flex;align-items:center;gap:6px;margin-top:8px;background:none;border:none;cursor:pointer;color:var(--a-week);font:inherit;font-size:13px;font-weight:600;padding:6px 12px;border-radius:999px;transition:background .25s var(--ease)}
.atelier .yt-cmt-more:hover{background:color-mix(in oklab,var(--a-week) 10%,transparent)}
.atelier .yt-cmt-more svg{width:16px;height:16px}
.atelier .yt-cmt-kebab{width:30px;height:30px;flex-shrink:0;border-radius:50%;border:none;background:none;color:var(--ink-3);cursor:pointer;display:grid;place-items:center;transition:background .25s var(--ease)}
.atelier .yt-cmt-kebab:hover{background:rgba(20,19,15,.06);color:var(--ink)}
.atelier .yt-cmt-kebab svg{width:18px;height:18px}
.atelier .yt-cmt-in{display:flex;align-items:center;gap:12px;padding:14px 18px;border-top:1px solid var(--line);background:var(--surface-solid)}
.atelier .yt-cmt-in .me{width:34px;height:34px;border-radius:50%;flex-shrink:0;display:grid;place-items:center;color:#fff;font-weight:600;font-size:13px;background:linear-gradient(150deg,#7A5BFF,#5a3be0)}
.atelier .yt-cmt-in input{flex:1;border:none;border-bottom:1px solid var(--line-2);background:none;padding:8px 2px;font:inherit;font-size:14px;color:var(--ink);outline:none;transition:border-color .25s var(--ease)}
.atelier .yt-cmt-in input:focus{border-bottom-color:var(--ink)}
.atelier .yt-cmt-send{width:38px;height:38px;border-radius:50%;flex-shrink:0;border:none;background:var(--ink);color:var(--bg);cursor:pointer;display:grid;place-items:center;transition:opacity .3s var(--ease),transform .3s var(--spring)}
.atelier .yt-cmt-send svg{width:17px;height:17px}
.atelier .yt-cmt-send:disabled{opacity:.35;cursor:default}
.atelier .yt-cmt-send:not(:disabled):hover{transform:scale(1.06)}
@media(max-width:680px){.atelier .act-stat{padding:6px 8px}.atelier .act-sep{display:none}}

/* Toast */
.atelier .at-toast{position:fixed;left:50%;bottom:36px;transform:translateX(-50%);z-index:70;
  background:var(--ink);color:var(--bg);font-size:13.5px;font-weight:500;padding:12px 20px;border-radius:999px;
  box-shadow:0 10px 30px rgba(20,19,15,.3);animation:at-toast-in .4s var(--spring) both}
@keyframes at-toast-in{from{opacity:0;transform:translate(-50%,12px) scale(.96)}to{opacity:1;transform:translate(-50%,0) scale(1)}}
.atelier .dtl-tabs{display:flex;gap:4px;margin:30px 0 0;border-bottom:1px solid var(--line);flex-wrap:wrap}
.atelier .dtl-tab{font:inherit;font-size:14.5px;font-weight:600;color:var(--ink-3);background:none;border:none;cursor:pointer;padding:12px 16px;position:relative;transition:color .3s var(--ease)}
.atelier .dtl-tab:hover{color:var(--ink-2)}
.atelier .dtl-tab.on{color:var(--ink)}
.atelier .dtl-tab.on::after{content:"";position:absolute;left:12px;right:12px;bottom:-1px;height:2px;background:var(--ink);border-radius:2px}
.atelier .dtl-grid{display:grid;grid-template-columns:1fr 300px;gap:28px;margin-top:28px;align-items:start}
@media(max-width:980px){.atelier .dtl-grid{grid-template-columns:1fr}}
.atelier .dtl-panel{animation:at-enter .5s var(--ease) both}
.atelier .readme h3{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:20px;margin:24px 0 12px;letter-spacing:-.01em}
.atelier .readme h3:first-child{margin-top:0}
.atelier .readme p{font-size:15px;color:var(--ink-2);line-height:1.65;margin-bottom:14px}
.atelier .readme ul{list-style:none;display:flex;flex-direction:column;gap:10px;margin:4px 0 8px}
.atelier .readme li{display:flex;gap:10px;font-size:14.5px;color:var(--ink-2);align-items:flex-start}
.atelier .readme li svg{flex-shrink:0;margin-top:3px;color:var(--a-month)}
.atelier .codeblk{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:13px;background:#1A1916;color:#E9E6DD;border-radius:14px;padding:16px 18px;line-height:1.8;overflow-x:auto;margin:6px 0 16px;white-space:pre-wrap}
.atelier .codeblk .c{color:rgba(233,230,221,.42)}
.atelier .codeblk .k{color:#FF9A6B;font-weight:500}
.atelier .shot{border-radius:18px;border:1px solid var(--line);background:repeating-linear-gradient(135deg,var(--bg-2),var(--bg-2) 14px,#fff 14px,#fff 28px);height:190px;display:grid;place-items:center;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:12.5px;margin:6px 0 16px;letter-spacing:.05em}
.atelier .rel{position:relative;padding-left:26px;margin-bottom:22px}
.atelier .rel::before{content:"";position:absolute;left:5px;top:6px;width:11px;height:11px;border-radius:50%;background:var(--ink);box-shadow:0 0 0 4px var(--bg)}
.atelier .rel::after{content:"";position:absolute;left:10px;top:18px;bottom:-22px;width:1px;background:var(--line-2)}
.atelier .rel:last-child::after{display:none}
.atelier .rel .rh{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.atelier .rel .rv{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:15px;font-weight:500}
.atelier .rel .rdate{font-size:12.5px;color:var(--ink-3)}
.atelier .rel .latest{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10.5px;color:#fff;background:linear-gradient(135deg,#3BE8A6,#0FA877);padding:3px 9px;border-radius:999px;letter-spacing:.04em;font-weight:600}
.atelier .rel .upg{font:inherit;font-size:12px;font-weight:600;margin-left:auto;background:rgba(20,19,15,.05);border:1px solid var(--line);color:var(--ink);border-radius:999px;padding:5px 13px;cursor:pointer;transition:.3s var(--ease)}
.atelier .rel .upg:hover{background:var(--ink);color:#fff;border-color:var(--ink)}
.atelier .rel ul{list-style:none;display:flex;flex-direction:column;gap:6px}
.atelier .rel li{font-size:13.5px;color:var(--ink-2);display:flex;gap:9px;align-items:flex-start}
.atelier .rel li::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--line-2);margin-top:7px;flex-shrink:0}
.atelier .gig{display:flex;align-items:center;gap:14px;padding:14px;border:1px solid var(--line);border-radius:18px;margin-bottom:10px;transition:.4s var(--ease);cursor:pointer}
.atelier .gig:hover{border-color:var(--line-2);transform:translateX(3px);box-shadow:var(--shadow)}
.atelier .gig .av{width:42px;height:42px;border-radius:50%;flex-shrink:0;display:grid;place-items:center;color:#fff;font-weight:600;font-size:15px}
.atelier .gig .gm{flex:1}
.atelier .gig .gm .gt{font-size:14.5px;font-weight:600}
.atelier .gig .gm .gs{font-size:12.5px;color:var(--ink-3)}
.atelier .gig .star{font-size:12.5px;font-family:'IBM Plex Mono',ui-monospace,monospace;color:var(--ink-2)}
.atelier .gig .gp{font-family:'Fraunces',Georgia,serif;font-size:18px}
.atelier .rvw{border:1px solid var(--line);border-radius:18px;padding:18px;margin-bottom:12px}
.atelier .rvw .rt{display:flex;align-items:center;gap:11px;margin-bottom:9px}
.atelier .rvw .av{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;color:#fff;font-weight:600;font-size:13px;flex-shrink:0}
.atelier .rvw .nm{font-size:14px;font-weight:600}
.atelier .rvw .rl{font-size:12px;color:var(--ink-3)}
.atelier .rvw .st{margin-left:auto;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:12.5px;color:#E0A020}
.atelier .rvw p{font-size:13.5px;color:var(--ink-2);line-height:1.55}
/* Card sidebar kiểu macOS: bo 16px, viền mảnh, đổ bóng dịu GỌN (không bị clip vỡ góc). */
.atelier .dtl-side .panel{padding:22px 20px;border-radius:16px;box-shadow:0 1px 2px rgba(20,19,15,.05), 0 8px 22px rgba(20,19,15,.05)}
/* Sidebar dính theo khi cuộn nội dung khu Tổng quan — top 64px chừa thanh
   header gọn (fixed). Vì sticky chỉ dính trong phạm vi cha .dtl-grid (phần
   review nằm NGOÀI grid), nên khi cuộn tới Đánh giá sidebar tự nhả & cuộn
   tự nhiên — đúng yêu cầu. */
.atelier .dtl-side{
  position:sticky;
  top:64px;
  align-self:start;
  /* KHÔNG overflow/clip — nếu clip thì box-shadow của .panel bị cắt → vỡ bóng ở 4 góc.
     Sidebar ngắn nên không cần scroll trong; sticky là đủ. */
}
@media(max-width:980px){.atelier .dtl-side{position:static;max-height:none;overflow:visible}}
.atelier .statline{display:flex;justify-content:space-between;align-items:baseline;gap:20px;padding:11px 0;border-bottom:1px solid var(--line);font-size:13.5px}
.atelier .statline:last-child{border-bottom:none}
.atelier .statline .k{color:var(--ink-3);flex:0 0 auto;white-space:nowrap}
.atelier .statline .v{font-weight:600;font-family:'IBM Plex Mono',ui-monospace,monospace;color:rgb(100,97,92);flex:1 1 auto;min-width:0;text-align:right;line-height:1.55;overflow-wrap:break-word}
.atelier .sidecard{margin-top:18px}
.atelier .sidecard .lbl{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);margin-bottom:12px}
.atelier .revrow{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:10px}
.atelier .revrow .big{font-family:'Fraunces',Georgia,serif;font-size:30px;line-height:1}
.atelier .revrow .sm{font-size:12px;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .revbar{height:7px;border-radius:4px;background:rgba(20,19,15,.07);overflow:hidden}
.atelier .revbar i{display:block;height:100%;border-radius:4px;width:0;transition:width 1.1s var(--ease)}
.atelier .sidenote{font-size:11.5px;color:var(--ink-3);line-height:1.5;margin-top:11px}

/* ── Hướng dẫn (guide) ── */
.atelier .guide-list{display:flex;flex-direction:column;gap:14px;margin:8px 0 18px}
.atelier .guide-step{display:flex;gap:16px;align-items:flex-start;padding:16px 18px;border:1px solid var(--line);border-radius:18px;background:var(--surface-solid);transition:.4s var(--ease)}
.atelier .guide-step:hover{border-color:var(--line-2);transform:translateX(3px);box-shadow:var(--shadow)}
.atelier .guide-num{width:30px;height:30px;border-radius:50%;flex-shrink:0;display:grid;place-items:center;font-family:'Fraunces',Georgia,serif;font-size:15px;background:var(--ink);color:var(--bg)}
.atelier .guide-step .gtt{font-size:14.5px;font-weight:600;margin-bottom:3px}
.atelier .guide-step .gtb{font-size:13.5px;color:var(--ink-2);line-height:1.55}

/* ── Insights ── */
.atelier .ins-kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:18px}
@media(max-width:780px){.atelier .ins-kpis{grid-template-columns:repeat(2,1fr)}}
.atelier .ins-kpi{border:1px solid var(--line);border-radius:18px;padding:18px;background:var(--surface-solid)}
.atelier .ins-kpi .k{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-bottom:8px}
.atelier .ins-kpi .v{font-family:'Fraunces',Georgia,serif;font-size:30px;line-height:1;font-variant-numeric:tabular-nums}
.atelier .ins-kpi .d{font-size:11.5px;color:var(--a-month);margin-top:7px;font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .ins-card{margin-bottom:16px}
/* Area + line chart (star-history style) */
.atelier .at-chart{position:relative;margin-top:8px}
.atelier .at-chart svg{width:100%;height:240px;display:block;overflow:visible}
.atelier .at-ytick{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10px;fill:var(--ink-3)}
.atelier .at-xtick{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10px;fill:var(--ink-3)}
.atelier .at-area{opacity:0;transition:opacity .9s var(--ease) .35s}
.atelier .at-area.on{opacity:1}
.atelier .at-line{stroke-dasharray:2400;stroke-dashoffset:2400}
.atelier .at-line.on{animation:at-draw 1.4s var(--ease) forwards}
@keyframes at-draw{to{stroke-dashoffset:0}}
.atelier .at-tip{position:absolute;top:-2px;transform:translateX(-50%);pointer-events:none;
  background:var(--ink);color:var(--bg);border-radius:10px;padding:6px 10px;white-space:nowrap;
  box-shadow:0 6px 18px rgba(20,19,15,.25);display:flex;flex-direction:column;line-height:1.25}
.atelier .at-tip b{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:13px}
.atelier .at-tip span{font-size:10.5px;opacity:.7}

/* ── Reviews · section ở cuối tab Tổng quan ── */
.atelier .dtl-rv-section{margin-top:40px;padding-top:30px;border-top:1px solid var(--line)}
.atelier .rv-eyebrow{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3);margin-bottom:10px}
.atelier .rv-h2{font-family:'Fraunces',Georgia,serif;font-weight:500;font-size:26px;letter-spacing:-.02em;margin-bottom:18px}
.atelier .dtl-rv-section .dtl-panel{animation:none}
/* ── Reviews · summary ── */
.atelier .rv-summary{display:grid;grid-template-columns:220px 1fr 1fr;gap:44px;align-items:center;padding:32px 40px;max-width:1120px;margin:0 auto 8px}
.atelier .rv-summary>.rv-bars,.atelier .rv-summary>.rv-cats{position:relative}
.atelier .rv-summary>.rv-bars::before,.atelier .rv-summary>.rv-cats::before{content:"";position:absolute;left:-20px;top:2px;bottom:2px;width:1px;background:var(--line)}
@media(max-width:900px){.atelier .rv-summary{grid-template-columns:1fr;gap:24px;padding:24px}.atelier .rv-summary>.rv-bars::before,.atelier .rv-summary>.rv-cats::before{display:none}}
.atelier .rv-score{display:flex;flex-direction:column;align-items:center;text-align:center}
.atelier .rv-score .big{font-family:'Fraunces',Georgia,serif;font-size:66px;line-height:.9;letter-spacing:-.03em}
.atelier .rv-score .stars{color:var(--a-session);font-size:16px;letter-spacing:2px;margin:8px 0 6px;white-space:nowrap}
.atelier .rv-score .cnt{font-size:12.5px;color:var(--ink-3)}
.atelier .rv-verified{display:inline-block;margin-top:13px;font-size:12px;font-weight:600;color:#0FA877;background:color-mix(in oklab,var(--a-month) 13%,transparent);padding:7px 12px;border-radius:12px;line-height:1.35}
.atelier .rv-bars{display:flex;flex-direction:column;gap:9px}
.atelier .rv-brow{display:flex;align-items:center;gap:10px;font-size:12px}
.atelier .rv-brow .lab{width:26px;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .rv-brow .track{flex:1;height:7px;border-radius:4px;background:rgba(20,19,15,.07);overflow:hidden}
.atelier .rv-brow .track i{display:block;height:100%;border-radius:4px;background:var(--a-session);width:0;transition:width 1s var(--ease)}
.atelier .rv-brow .num{width:46px;text-align:right;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .rv-cats{display:flex;flex-direction:column;gap:11px}
.atelier .rv-cat{display:flex;align-items:center;gap:12px;font-size:12.5px}
.atelier .rv-cat .nm{width:130px;color:var(--ink-2)}
.atelier .rv-cat .track{flex:1;height:7px;border-radius:4px;background:rgba(20,19,15,.07);overflow:hidden}
.atelier .rv-cat .track i{display:block;height:100%;border-radius:4px;background:var(--a-week);width:0;transition:width 1s var(--ease)}
.atelier .rv-cat .val{width:30px;text-align:right;font-weight:600;font-family:'IBM Plex Mono',ui-monospace,monospace}
/* ── Reviews · filters + grid ── */
.atelier .rv-filters{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:22px 0 16px}
.atelier .rv-fchip{font:inherit;font-size:13px;font-weight:500;color:var(--ink-2);background:var(--surface-solid);border:1px solid var(--line);border-radius:999px;padding:7px 14px;cursor:pointer;transition:.3s var(--ease)}
.atelier .rv-fchip .n{color:var(--ink-3);margin-left:5px;font-size:11.5px}
.atelier .rv-fchip:hover{border-color:var(--line-2)}
.atelier .rv-fchip.on{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.atelier .rv-fchip.on .n{color:rgba(255,255,255,.6)}
.atelier .rv-sort{margin-left:auto;font-size:12.5px;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .rv-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(400px,1fr));gap:16px;align-items:start}
@media(max-width:900px){.atelier .rv-grid{grid-template-columns:1fr}}
.atelier .rvw{border-radius:22px;padding:22px}
.atelier .rvw .rtop{display:flex;align-items:flex-start;gap:12px}
.atelier .rvw .who{display:flex;align-items:center;gap:7px;font-size:14px;font-weight:600;flex-wrap:wrap}
.atelier .rvw .flag{font-size:13px}
.atelier .rvw .ver{font-size:10.5px;font-weight:600;color:#0FA877;background:color-mix(in oklab,var(--a-month) 14%,transparent);padding:2px 8px;border-radius:999px}
.atelier .rvw .sub2{font-size:12px;color:var(--ink-3);margin-top:3px}
.atelier .rvw .stars{margin-left:auto;color:var(--a-session);font-size:13px;letter-spacing:1px;flex-shrink:0}
.atelier .rvw .title{font-size:15px;font-weight:600;margin:14px 0 6px;letter-spacing:-.01em}
.atelier .rvw .body{font-size:13.5px;color:var(--ink-2);line-height:1.6}
.atelier .rvw .photos{display:flex;gap:8px;margin-top:14px}
.atelier .rvw-photo{width:66px;height:50px;border-radius:9px;border:1px solid rgba(255,255,255,.3);display:grid;place-items:center;font-size:11px;color:#fff;font-weight:600;box-shadow:inset 0 1px 0 rgba(255,255,255,.25)}
.atelier .rvw-reply{margin-top:16px;padding:14px;border-radius:14px;background:color-mix(in oklab,var(--a-week) 7%,transparent);border:1px solid color-mix(in oklab,var(--a-week) 18%,transparent)}
.atelier .rvw-reply .rh2{display:flex;align-items:center;gap:9px;margin-bottom:7px}
.atelier .rvw-reply .ct{width:26px;height:26px;border-radius:7px;background:linear-gradient(150deg,#2E7DFF,#1850c8);color:#fff;display:grid;place-items:center;font-size:10.5px;font-weight:700;flex-shrink:0}
.atelier .rvw-reply .nm2{font-size:12.5px;font-weight:600}
.atelier .rvw-reply .wh{font-size:11px;color:var(--ink-3)}
.atelier .rvw-reply p{font-size:12.5px;color:var(--ink-2);line-height:1.55}
.atelier .rvw-foot{display:flex;align-items:center;gap:18px;margin-top:16px;padding-top:14px;border-top:1px solid var(--line);font-size:12.5px;color:var(--ink-3)}
.atelier .rvw-foot button{font:inherit;background:none;border:none;color:var(--ink-3);cursor:pointer;font-size:12.5px;padding:0}
.atelier .rvw-foot button:hover{color:var(--ink)}
.atelier .rvw-foot .note{margin-left:auto;font-style:italic;font-size:11px;text-align:right}

/* ── Hỏi kỹ sư · floating widget ── */
.atelier .at-help{position:fixed;right:24px;bottom:40px;z-index:60;display:inline-flex;align-items:center;gap:9px;background:var(--ink);color:var(--bg);border:none;border-radius:999px;padding:13px 20px;font:inherit;font-size:14px;font-weight:600;cursor:pointer;box-shadow:0 8px 24px rgba(20,19,15,.28);transition:transform .4s var(--spring),box-shadow .4s var(--ease)}
.atelier .at-help:hover{transform:translateY(-2px);box-shadow:0 12px 32px rgba(20,19,15,.34)}
.atelier .at-help .hdot{width:8px;height:8px;border-radius:50%;background:var(--a-month);animation:at-pulse 2.6s var(--ease) infinite}
.atelier .at-help-scrim{position:fixed;inset:0;z-index:59}
.atelier .at-help-panel{position:fixed;right:24px;bottom:92px;z-index:61;width:min(366px,calc(100vw - 48px));max-height:min(560px,calc(100vh - 140px));overflow-y:auto;background:var(--surface-solid);border:1px solid var(--line);border-radius:24px;box-shadow:var(--shadow-lg);padding:20px;animation:at-help-in .5s var(--spring) both}
@keyframes at-help-in{from{opacity:0;transform:translateY(14px) scale(.97)}to{opacity:1;transform:none}}
.atelier .at-help-h{display:flex;align-items:center;gap:11px}
.atelier .at-help-h .ai{width:38px;height:38px;border-radius:12px;background:linear-gradient(150deg,#7A5BFF,#5a3be0);color:#fff;display:grid;place-items:center;font-family:'Fraunces',Georgia,serif;font-size:18px;flex-shrink:0}
.atelier .at-help-h .nm{font-size:15px;font-weight:600}
.atelier .at-help-h .st{font-size:11px;color:var(--a-month);font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .at-help-x{margin-left:auto;background:none;border:none;font-size:22px;color:var(--ink-3);cursor:pointer;line-height:1}
.atelier .at-help-sub{font-size:13px;color:var(--ink-2);line-height:1.55;margin:12px 0 14px}
.atelier .at-help-qs{display:flex;flex-direction:column;gap:8px;margin-bottom:14px}
.atelier .at-q{text-align:left;font:inherit;font-size:13px;color:var(--ink);background:rgba(20,19,15,.04);border:1px solid var(--line);border-radius:12px;padding:10px 13px;cursor:pointer;transition:.3s var(--ease)}
.atelier .at-q:hover{background:rgba(20,19,15,.07);transform:translateX(2px)}
.atelier .at-help-in-row{display:flex;gap:8px;align-items:center;background:rgba(20,19,15,.04);border:1px solid var(--line);border-radius:14px;padding:7px 7px 7px 14px}
.atelier .at-help-in-row input{flex:1;border:none;background:none;outline:none;font:inherit;font-size:13.5px;color:var(--ink)}
.atelier .at-help-send{width:34px;height:34px;border-radius:10px;border:none;background:var(--ink);color:var(--bg);cursor:pointer;flex-shrink:0;display:grid;place-items:center}
.atelier .at-help-div{display:flex;align-items:center;gap:10px;margin:16px 0 12px;font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .at-help-div::before,.atelier .at-help-div::after{content:"";flex:1;height:1px;background:var(--line)}
.atelier .at-help-human{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.atelier .at-hbtn{display:flex;flex-direction:column;gap:3px;text-align:left;font:inherit;background:var(--surface-solid);border:1px solid var(--line);border-radius:14px;padding:11px 13px;cursor:pointer;transition:.3s var(--ease)}
.atelier .at-hbtn:hover{border-color:var(--line-2);transform:translateY(-1px);box-shadow:var(--shadow)}
.atelier .at-hbtn b{font-size:13px;font-weight:600}
.atelier .at-hbtn span{font-size:11px;color:var(--ink-3)}

@media(prefers-reduced-motion:reduce){
  .atelier *{animation:none!important;transition:none!important}
  .atelier .card:hover{transform:none}
}
.resizer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 14px;
  cursor: col-resize;
  z-index: 10;
  background: transparent;
}
.resizer:hover {
  background: color-mix(in oklab, var(--accent) 30%, transparent);
}
[data-theme="dark"] .table-head {
  background: color-mix(in oklab, var(--panel-solid) 70%, #000);
}
.table-row {
  display: grid;
  padding: 0 12px;
  /* Fixed row height (not min-height) so every row renders at the
     EXACT same pixel height regardless of content or variant
     (library / pending / skipped / ticked / ai). Padding moves
     outside the height budget so the cell vertically centres via
     align-items. Long source text clips with the ellipsis rule on
     ``.cell`` — user hovers to see the full text via CellPopover. */
  /* Row height tăng 42→48px: Vietnamese diacritics 2-tầng (Ế, Ấ,
     Ổ, …) cần thêm ~6px để glyph không bị clip mép trên. Mọi row
     đồng nhất 48px (fixed, không min/max) để bảng không giật. */
  height: 48px;
  font-size: 13px;
  /* macOS list hairline — lighter than the structural --border so rows
     feel like a continuous list, not boxed-in spreadsheet cells. */
  border-bottom: 1px solid color-mix(in oklab, var(--border) 65%, transparent);
  align-items: center;
  cursor: pointer;
  transition: background 120ms ease;
  /* Force Arial cho table cells — CAD drawings author bằng nhiều
     font khác nhau (VnTime, VnArial, Tahoma, system…), khi extract
     ra Unicode đôi khi render lệch baseline / glyph khác nhau.
     Pin xuống Arial → mọi row glyph đồng nhất, không bị "lỗi font"
     visual. Fallback đến system sans nếu Arial absent. */
  font-family: Arial, "Helvetica Neue", "Segoe UI", system-ui,
               -apple-system, sans-serif !important;
}
/* Cascade Arial xuống mọi phần tử text trong cell — ngăn font
   inherit từ system khi cell wrap có font-family riêng. */
.table-row .cell, .table-row textarea.cell-edit-textarea,
.table-row .cell-hover-wrap, .table-row .cell-hover-wrap > div,
.table-row .cell-hover-wrap > span,
.table-row .cell-hover-wrap textarea,
.table-row .cell *, .table-row .cell-hover-wrap * {
  font-family: Arial, "Helvetica Neue", "Segoe UI", system-ui,
               -apple-system, sans-serif !important;
}
/* Zebra striping — the macOS Numbers signature. Alternate rows carry a
   whisper-faint tint so the eye tracks a row straight across all six
   columns without needing heavy gridlines. Declared BEFORE :hover /
   .selected so those states always win on the same specificity. */
.table-row:nth-child(even) {
  background: color-mix(in oklab, var(--text-3) 6%, transparent);
}
.table-row:hover { background: var(--selected); }
.table-row.selected { background: var(--accent-soft); }
/* Rows flagged by the duplicate detector stay highlighted in amber
   until the user explicitly acknowledges the toast banner or a fresh
   scan with no dupes clears them. Entry uses a brief pulse to draw
   the eye, then settles into a steady tint + left rail so older
   users who look away for a few seconds don't miss the signal. */
.table-row.dup-flash {
  background: rgba(245, 158, 11, 0.18) !important;
  position: relative;
  z-index: 1;
  animation: dup-flash-enter 900ms ease-out 1;
}
.table-row.dup-flash::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--mc-warn);
  border-radius: 2px;
}
.table-row.dup-flash:hover {
  background: rgba(245, 158, 11, 0.28) !important;
}
@keyframes dup-flash-enter {
  0%   { background: rgba(245, 158, 11, 0.45); }
  40%  { background: rgba(245, 158, 11, 0.25); }
  100% { background: rgba(245, 158, 11, 0.18); }
}

/* Streaming row-enter — fresh rows fade up from 10px below with a
   subtle left-edge accent sweep. React stamps animation-delay inline
   on each new row so they arrive in cascade (even when the backend
   ships them in a single batch), which is the "chữ được đẩy lên
   liên tục" feel — customers watch the list pour in instead of
   staring at a frozen UI.

   fill-mode ``both`` keeps the row invisible until its delay slot
   elapses — prevents the flash-of-unstaggered-content that
   otherwise shows a full pile of rows for one frame before the
   cascade begins.

   ``prefers-reduced-motion`` honours the OS accessibility toggle —
   users who opted out of fancy motion see rows land instantly. */
/* macOS-style row INSERT-PUSH (2026-05-27, user spec "mới ở trên,
   animation đẩy mượt"): new scan rows land at the TOP. Instead of the
   old translateY (which let the row take full height instantly → the
   rows below SNAPPED down = "chữ nhảy"), the new row now expands its
   HEIGHT from 0 → 48px on Apple's decel curve. As it grows, every row
   below glides down continuously with it — a smooth accordion push,
   no jump. Content is clipped (overflow:hidden) while the row is
   shorter than its content so cells don't spill mid-animation. */
.table-row.row-enter {
  animation: row-insert 420ms cubic-bezier(0.32, 0.72, 0, 1) both;
  overflow: hidden;
  will-change: height;
}
.table-row.row-enter::after {
  content: "";
  position: absolute;
  left: 0; top: 12%;
  width: 2.5px; height: 76%;
  border-radius: 2px;
  background: linear-gradient(180deg,
    transparent,
    color-mix(in oklab, var(--accent) 70%, transparent),
    transparent);
  opacity: 0;
  animation: row-accent 640ms ease-out both;
  pointer-events: none;
}
@keyframes row-insert {
  0%   { height: 0; opacity: 0; }
  50%  { opacity: 1; }
  100% { height: 48px; opacity: 1; }
}
@keyframes row-accent {
  0%   { opacity: 0; }
  35%  { opacity: 0.9; }
  100% { opacity: 0; }
}
.table-row.row-enter { position: relative; }
@media (prefers-reduced-motion: reduce) {
  .table-row.row-enter,
  .table-row.row-enter::after { animation: none !important; }
}

/* Scan-All skipped rows — "không cần dịch" entries the heuristic
   parked at the bottom of the table. Rendered in AutoCAD's color-8
   gray so the user visually groups them as "not part of the active
   translation set" while still being able to review and promote
   via the right-click menu. Hover still applies so the row doesn't
   feel frozen, and the pencil / Chip icons stay legible even after
   the dim. */
.table-row.row-skipped {
  opacity: 0.58;
  background: color-mix(in oklab, var(--panel-solid) 90%, transparent);
}
/* Thin top divider above the FIRST skipped row groups them as a
   visual section — rendered only when the previous row is NOT
   skipped via the adjacent-sibling trick. NO margin-top: the
   divider replaces the existing border-bottom of the previous
   row, keeping every row at the uniform ``.table-row`` height. */
.table-row:not(.row-skipped) + .table-row.row-skipped {
  border-top: 1px dashed color-mix(in oklab, var(--text-3) 45%, transparent);
}
.table-row.row-skipped .cell,
.table-row.row-skipped .cell .cell-text,
.table-row.row-skipped .cell-popover-trigger {
  color: #8a8a8a;
  font-style: italic;
}
[data-theme="dark"] .table-row.row-skipped .cell,
[data-theme="dark"] .table-row.row-skipped .cell .cell-text,
[data-theme="dark"] .table-row.row-skipped .cell-popover-trigger {
  color: #7a7a7a;
}
.table-row.row-skipped:hover {
  opacity: 0.85;
  background: var(--selected);
}
.table-row.row-skipped .skip-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  /* Match the pencil button's 26 px height so the zone column
     stays uniform across normal + skipped rows. Padding shifts
     a touch to keep the SVG + label vertically centred inside
     the fixed box. */
  height: 26px;
  padding: 0 8px;
  font-size: 10.5px;
  font-weight: 500;
  line-height: 1;
  color: #8a8a8a;
  border: 1px dashed color-mix(in oklab, var(--text-3) 55%, transparent);
  border-radius: 6px;
  background: transparent;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.table-row.row-skipped .skip-badge svg {
  opacity: 0.8;
  flex-shrink: 0;
}

/* ── Style chip ─────────────────────────────────────────────────
   Clickable pill in the STYLE column — shows the short style name
   (Trên dưới / Ngang / Đè) with a tiny pencil on the right. Click
   opens the Auto-fit modal for that row's style. Height matches
   ``.skip-badge`` so library / skipped rows stay on the same
   vertical grid. */
.style-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 8px;
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  color: var(--text-2);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
  max-width: 100%;
  transition: background 120ms ease, color 120ms ease,
              border-color 120ms ease;
}
.style-chip:hover {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: color-mix(in oklab, var(--accent) 40%, var(--border));
}
.style-chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.style-chip svg {
  opacity: 0.55;
  flex-shrink: 0;
  transition: opacity 120ms ease;
}
.style-chip:hover svg { opacity: 1; }
/* Custom (tuned by user) — accent-filled so the user can spot which
   rows they've hand-tweaked at a glance. */
.style-chip.is-custom {
  background: rgba(0, 122, 255, 0.12);
  color: var(--accent);
  border-color: transparent;
}
.style-chip.is-custom svg { opacity: 0.8; }
/* Pending — zone still being analyzed by the Phase 2 classifier.
   Dim + italic so it reads as transient, not a final assignment. */
.style-chip.is-pending {
  color: var(--text-3);
  font-style: italic;
  border-style: dashed;
  border-color: color-mix(in oklab, var(--text-3) 35%, transparent);
}
.style-chip.is-pending svg { opacity: 0.35; }

.cell.idx {
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
}
.cell {
  padding-right: 14px;
  display: flex;
  align-items: center;
  min-width: 0;
  overflow: hidden;
  /* Keep cell content on a single line so a long SOURCE / translation
     truncates at its own column edge instead of wrapping or visually
     bleeding into the neighbouring column (part of the 2026-05-26
     column-separation fix). The inner .cell-text already ellipsises;
     this guards cells that render text directly (e.g. .cell.src). */
  white-space: nowrap;
  line-height: 1.2;
  /* Stretch every cell to the full 42 px row track so flex
     ``align-items: center`` pivots around the row midpoint
     regardless of the cell's intrinsic content height. Without
     this the grid's ``align-items: center`` collapsed each cell
     to its own content box (~15 px for text, 26 px for chips)
     and centred the boxes independently — chip centres and text
     baselines landed on DIFFERENT Y-coords because their boxes
     had different heights. Stretching guarantees every cell's
     centre is 21 px from the row top, locking text + chips onto
     the same horizontal line. */
  align-self: stretch;
}
/* CellPopover wraps the text cell in a ``.cell-hover-wrap`` that
   ALSO carries the ``.cell`` class — the align-self stretch above
   already applies. This rule just enforces the shared line-height
   for the inner text div (which has inline ``flex: 1`` + no
   line-height of its own, otherwise it inherits 1.55 from body
   and the ink drifts above the chip centre). */
/* Line-height 1.5 (thay vì 1.2) — Vietnamese diacritics stacked
   (Ế = E + circumflex + acute, Ấ, Ể, …) cần ~1.4× font-size để
   glyph trên cùng không bị clip bởi line box. Pin 1.5 cho mọi
   cell để mọi row đồng nhất chiều cao + dấu hiển thị đầy đủ. */
.cell-hover-wrap { line-height: 1.5; position: relative; }
.cell-hover-wrap > div { line-height: 1.5; }
/* Inline copy button — hiện khi hover cell, đậu sát mép phải.
   Smart: click → sao chép ngay, không cần đợi popover. */
.cell-inline-copy {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--panel-solid);
  color: var(--text-2);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  white-space: nowrap;
  overflow: hidden;
  transition: opacity 120ms ease,
              width 280ms cubic-bezier(0.34, 1.4, 0.64, 1),
              padding 280ms cubic-bezier(0.34, 1.4, 0.64, 1),
              background 200ms ease,
              border-color 200ms ease,
              color 200ms ease;
  z-index: 2;
}
.cell-hover-wrap:hover .cell-inline-copy {
  opacity: 1;
  pointer-events: auto;
}
.cell-inline-copy:hover {
  background: var(--panel-hover);
  color: var(--text);
  border-color: var(--accent);
}
/* Morph copy → "Đã sao chép" pill xanh khi click — feedback rõ ràng
   ngay tại button, user không cần nhìn xuống global toast. Spring
   physics expand chiều ngang. */
.cell-inline-copy.is-copied {
  width: auto;
  padding: 0 9px 0 6px;
  opacity: 1 !important;
  pointer-events: auto;
  background: color-mix(in oklab, var(--green) 18%, var(--panel-solid));
  border-color: var(--green);
  color: var(--green);
}
.cell-inline-copy-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  animation: cell-copy-label-in 280ms cubic-bezier(0.34, 1.4, 0.64, 1);
}
@keyframes cell-copy-label-in {
  from { opacity: 0; transform: translateX(-4px); }
  to   { opacity: 1; transform: translateX(0); }
}
/* ── Empty-cell placeholder override ──────────────────────────────
   CellPopover renders ``<div class="cell-hover-wrap empty cell
   tr"/>`` when a cell has no text, so every row keeps the same
   grid-track count (returning ``null`` would collapse the track
   and pop the remaining columns one slot to the left).
   Problem: the global ``.empty`` utility down in this stylesheet
   (``padding: 40 px 20 px; flex-direction: column; gap: 10 px``)
   was leaking onto the placeholder. With ``box-sizing: border-
   box`` the 80 px of vertical padding ballooned the empty cell
   past the 42 px row track, which dragged the populated cells
   in the SAME row up from the track midline — the visible "text
   bumped above the chip centre" symptom on rows with blank
   EN / VI. Restoring row-flex + zero padding keeps empty cells
   pixel-identical to populated ones so the row stays at 42 px
   and every baseline lands on the shared midline. */
.cell-hover-wrap.empty {
  flex-direction: row;
  padding: 0;
  gap: 0;
  text-align: left;
}
/* Interactive children inside a .cell need their own line-height
   (otherwise they inherit 42 px and their inner label glyphs go
   askew). ``vertical-align: middle`` aligns their box with the
   parent line's midline so the chip centre sits on the row centre,
   matching plain text rows pixel-for-pixel. */
.cell .skip-badge,
.cell .style-chip,
.cell .chip,
.cell > button {
  vertical-align: middle;
  line-height: 1;
}
/* CellPopover wrap picks up .cell — no flex override needed; its
   children (plain text node or ``input.cell-edit-input``) inherit
   the line-height: 42 centering. */
.cell.idx { color: var(--text-3); font-family: "JetBrains Mono", monospace; font-size: 11px; }
.cell.src { color: var(--text); }
.cell.tr  { color: var(--text); }

.checkbox {
  width: 16px; height: 16px;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  background: var(--panel-solid);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.checkbox.on { background: var(--accent); border-color: var(--accent); }

/* Log pane */
.log {
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px 16px;
  font-family: "JetBrains Mono", "SF Mono", ui-monospace, monospace;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--text);
  max-height: 200px;
  overflow: auto;
}
.log > div { padding: 2px 0; }
.log .ts { color: var(--text-3); font-size: 11px; }
.log .tag-conn { color: var(--accent); font-weight: 600; }
.log .tag-read { color: var(--purple); font-weight: 600; }
.log .tag-proc { color: var(--orange); font-weight: 600; }
.log .tag-trans { color: var(--green); font-weight: 600; }
.log .tag-push { color: var(--pink); font-weight: 600; }
.log .tag-sys { color: var(--text-2); font-weight: 600; }
.log .tag-ok  { color: var(--green); font-weight: 600; }
.log .tag-evt { color: #8b5cf6; font-weight: 600; }
.log .tag-perf { color: #eab308; font-weight: 700; }
.log .arrow { color: var(--text-3); }

/* ========== Sub-sidebar (settings etc) ========== */
.subnav {
  width: 220px;
  padding: 14px 10px;
  display: flex; flex-direction: column; gap: 2px;
  overflow: auto;
}
.subnav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px;
  border-radius: 8px;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  transition: background 80ms;
}
.subnav-item:hover { background: var(--selected); }
.subnav-item.active { background: var(--accent); color: #fff; }
.subnav-item.active svg { color: #fff; }
.subnav-section {
  font-size: 10px; font-weight: 700; letter-spacing: 0.1em;
  color: var(--text-3); text-transform: uppercase;
  padding: 10px 10px 4px;
}

/* ========== Generic screen layout ========== */
.screen {
  flex: 1; min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
  overflow: auto;
  padding: 24px 32px;
}
.screen.padded-lg { padding: 32px 48px 48px; }
.screen-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px;
  margin-bottom: 22px;
}
.screen-head h1 { line-height: 1.1; }
.screen-head .sub { color: var(--text-2); margin-top: 6px; font-size: 14px; }

/* Settings row */
.row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px;
  gap: 16px;
}
.row + .row { border-top: 1px solid var(--border); }
.row .label { font-weight: 500; font-size: 14px; }
.row .hint { color: var(--text-3); font-size: 12px; margin-top: 3px; }

/* Guide steps */
.guide-step {
  display: flex; align-items: center; gap: 18px;
  padding: 18px 22px;
  border-radius: 14px;
  border: 1px solid var(--border);
  background: var(--panel-solid);
  transition: all 140ms;
  cursor: pointer;
}
.guide-step:hover {
  border-color: var(--accent);
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}
.guide-step .num {
  width: 36px; height: 36px; border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 15px;
  flex-shrink: 0;
}
.guide-step .icon-wrap {
  width: 36px; height: 36px; border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}

/* Pricing */
.price-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}
.price {
  display: flex; flex-direction: column;
  padding: 24px;
  border-radius: 18px;
  border: 1px solid var(--border);
  background: var(--panel-solid);
  gap: 18px;
  position: relative;
  min-height: 440px;
}
.price.featured {
  border-color: var(--accent);
  box-shadow: 0 12px 40px color-mix(in oklab, var(--accent) 18%, transparent);
}
.price .badge {
  position: absolute; top: -10px; right: 18px;
  background: var(--accent); color: #fff;
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em;
  padding: 4px 10px; border-radius: 999px;
  text-transform: uppercase;
}
.price h3 { font-size: 17px; }
.price .sub { color: var(--text-3); font-size: 12px; }
.price .amount {
  display: flex; align-items: baseline; gap: 4px;
  margin-top: 8px;
}
.price .amount .num {
  font-size: 32px; font-weight: 700; letter-spacing: -0.02em; color: var(--text);
}
.price .amount .per { color: var(--text-3); font-size: 13px; }
.price ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.price li { display: flex; gap: 10px; font-size: 13px; color: var(--text); }
.price li .check {
  width: 16px; height: 16px; border-radius: 50%;
  background: color-mix(in oklab, var(--green) 18%, transparent);
  color: var(--green);
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; margin-top: 1px;
}

/* Account */
.avatar {
  width: 56px; height: 56px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #5EC8FF, var(--mc-accent));
  color: #fff; font-size: 22px; font-weight: 600;
  flex-shrink: 0;
}

.stat-card {
  padding: 18px 20px;
  border-radius: 14px;
  border: 1px solid var(--border);
  background: var(--panel-solid);
  display: flex; flex-direction: column; gap: 6px;
}
.stat-card .value { font-size: 28px; font-weight: 700; letter-spacing: -0.02em; }
.stat-card .label { color: var(--text-3); font-size: 12px; }

/* Toggle switch */
.switch {
  position: relative;
  width: 40px; height: 24px;
  background: var(--border-strong);
  border-radius: 999px;
  cursor: pointer;
  transition: background 140ms;
  flex-shrink: 0;
}
.switch.on { background: var(--green); }
.switch::after {
  content: "";
  position: absolute; top: 2px; left: 2px;
  width: 20px; height: 20px; border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
  transition: transform 140ms;
}
.switch.on::after { transform: translateX(16px); }

/* About */
.about-row {
  display: grid;
  grid-template-columns: 120px 1fr;
  align-items: center;
  padding: 14px 0;
  border-top: 1px solid var(--border);
}
.about-row:first-child { border-top: none; }
.about-row .k { color: var(--text-3); font-size: 12px; }
.about-row .v { font-size: 13px; }

/* Empty / hint states */
.empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  color: var(--text-3);
  padding: 40px 20px;
  gap: 10px;
  text-align: center;
}

/* Focus banner */
.banner {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  border-radius: 10px;
  background: color-mix(in oklab, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in oklab, var(--accent) 30%, transparent);
  color: var(--text);
  font-size: 12.5px;
}
.banner .dot-pulse {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 color-mix(in oklab, var(--accent) 60%, transparent);
  animation: pulse 1.6s infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--accent) 55%, transparent); }
  70% { box-shadow: 0 0 0 8px rgba(0,0,0,0); }
  100% { box-shadow: 0 0 0 0 rgba(0,0,0,0); }
}

/* Tweaks panel */
.tweaks {
  position: fixed;
  right: 16px; bottom: 40px;
  width: 280px;
  z-index: 100;
  background: var(--panel);
  backdrop-filter: blur(30px) saturate(180%);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow-lg);
  padding: 14px;
  display: none;
}
.tweaks.open { display: block; }
.tweaks h4 {
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em;
  color: var(--text-3); text-transform: uppercase;
  margin-bottom: 10px;
}

/* ========== Editable cells ========== */
.cell.editable {
  cursor: text;
  border-radius: 4px;
  padding: 2px 6px;
  margin: -2px -6px;
  transition: background 100ms;
}
.cell.editable:hover {
  background: color-mix(in oklab, var(--accent) 8%, transparent);
}
/* ══════════════════════════════════════════════════════════════
   Inline cell editor — macOS-native pattern.
   · Double-click an editable cell → an auto-grow <textarea> mounts
     on top of the cell, anchored to its top-left, with the cell's
     full width as a starting size and a min-height matching the
     row.  Vertical growth lets the editor span past the row line
     so long strings stay fully visible while typing.
   · Truncated text in non-editing cells uses the OS-native title
     tooltip (no custom popover) — calmer, faster, more standard.
   ══════════════════════════════════════════════════════════════ */
.cell-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.5;
}
/* macOS-style hover tooltip (replaces the native black `title` box).
   Light card, rounded, soft shadow — shows the full text of a truncated
   cell on hover. Rendered via portal to <body> so cell overflow:hidden
   never clips it. */
.cell-tip {
  z-index: 99999;
  max-width: 460px;
  padding: 7px 11px;
  border-radius: 9px;
  background: var(--panel-solid);
  color: var(--text);
  border: 1px solid var(--border);
  box-shadow: 0 10px 28px -8px rgba(0,0,0,0.30),
              0 2px 6px -2px rgba(0,0,0,0.14);
  font-size: 12.5px;
  line-height: 1.45;
  white-space: normal;
  word-break: break-word;
  pointer-events: none;
  animation: cell-tip-in 90ms ease-out;
}
@keyframes cell-tip-in {
  from { opacity: 0; transform: translateY(-3px); }
  to   { opacity: 1; transform: none; }
}
[data-theme="dark"] .cell-tip {
  background: #2C2C2E;
  border-color: #48484A;
}

/* Global app tooltip — replaces QtWebEngine's black native `title` box
   on every [title] element (buttons, pills, workflow steps…). Same
   macOS card language as .cell-tip; positioned via JS (bridge.js),
   fixed to the viewport, never clipped. */
.app-tip {
  position: fixed;
  z-index: 100000;
  max-width: 420px;
  padding: 7px 11px;
  border-radius: 9px;
  background: var(--panel-solid, #fff);
  color: var(--text, var(--mc-label));
  border: 1px solid var(--border, #E5E5E5);
  box-shadow: 0 10px 28px -8px rgba(0,0,0,0.30),
              0 2px 6px -2px rgba(0,0,0,0.14);
  font-size: 12.5px;
  line-height: 1.45;
  white-space: normal;
  word-break: break-word;
  pointer-events: none;
  display: none;
  opacity: 0;
  transition: opacity 110ms ease;
}
[data-theme="dark"] .app-tip {
  background: #2C2C2E;
  color: #F5F5F7;
  border-color: #48484A;
}
.cell-edit-textarea {
  position: absolute;
  top: 4px;
  left: 4px;
  right: 4px;
  min-height: 36px;
  max-height: 320px;
  z-index: 6;
  border: none;
  outline: none;
  border-radius: 8px;
  background: var(--panel-solid);
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.5;
  padding: 8px 12px;
  margin: 0;
  resize: none;
  overflow: auto;
  box-sizing: border-box;
  white-space: pre-wrap;
  word-break: break-word;
  caret-color: var(--accent);
  /* Subtle 2px accent ring + soft drop shadow — Apple "in-edit"
     halo. No bouncy spring; the editor should feel calm and
     immediate, not theatrical. */
  box-shadow:
    0 0 0 2px var(--accent),
    0 6px 18px -6px color-mix(in oklab, var(--accent) 22%, rgba(0,0,0,0.16)),
    0 2px 4px -2px rgba(0,0,0,0.08);
  transition: box-shadow 120ms ease;
  animation: cell-edit-fade-in 140ms ease-out;
}
[data-theme="dark"] .cell-edit-textarea {
  box-shadow:
    0 0 0 2px var(--accent),
    0 8px 22px -6px color-mix(in oklab, var(--accent) 30%, rgba(0,0,0,0.55)),
    0 2px 6px -2px rgba(0,0,0,0.30);
}
@keyframes cell-edit-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* While editing, hide the row's hover background so the textarea
   reads as the focus surface instead of two stacked tints. */
.table-row:has(.cell-hover-wrap.is-editing):hover {
  background: transparent;
}

/* Global "Copied" pill — Apple-style dark floating confirmation.
   Sits near the bottom of the viewport (above the status bar). Larger
   + higher-contrast than the in-popover badge so it's impossible to
   miss even when the user's eyes are on the cell they just clicked.
   ``pointer-events: none`` keeps it transparent to clicks. */
.copy-toast-global {
  position: fixed;
  left: 50%;
  bottom: 72px;
  z-index: 999999;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 20px;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: #fff;
  background: rgba(28,28,30,0.92);
  border: 1px solid rgba(255,255,255,0.08);
  backdrop-filter: saturate(180%) blur(22px);
  -webkit-backdrop-filter: saturate(180%) blur(22px);
  box-shadow:
    0 24px 56px rgba(0,0,0,0.30),
    0 4px 12px rgba(0,0,0,0.14);
  transform: translateX(-50%);
  animation: copy-toast-pop 1800ms cubic-bezier(0.22, 0.9, 0.3, 1) forwards;
  pointer-events: none;
}
.copy-toast-global svg {
  color: var(--green);
  flex: 0 0 auto;
  width: 15px; height: 15px;
}
@keyframes copy-toast-pop {
  0%   { opacity: 0; transform: translateX(-50%) translateY(16px) scale(0.9); }
  8%   { opacity: 1; transform: translateX(-50%) translateY(0)    scale(1);   }
  88%  { opacity: 1; transform: translateX(-50%) translateY(0)    scale(1);   }
  100% { opacity: 0; transform: translateX(-50%) translateY(-8px) scale(0.96); }
}

/* Cursor affordance. Editable cells show a text caret to hint that
   double-clicking opens the inline editor (Numbers / Notes pattern).
   Read-only cells inherit the row's pointer cursor — single-click
   selects the row; the small Copy button on hover handles copy. */
.cell-hover-wrap.is-editable { cursor: text; }
.cell-hover-wrap.is-editing  { cursor: default; }

/* In-button spinner for the "Connecting…" state on the Connect
   button. Kept tiny + accent-tinted so it reads as "busy" without
   dominating the label. */
.spinner-dot {
  width: 10px; height: 10px; border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  animation: spin 0.7s linear infinite;
  display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }
.connect-autocad-btn.is-connecting { cursor: progress; }

/* Primary "connect" CTA — brand accent fill. Inline styles set the
   resting colour; these rules add the interaction states (hover lift,
   active press, focus ring). !important is required only because the
   resting fill is an inline style and inline beats a plain selector. */
.connect-autocad-btn.is-primary {
  font-weight: 600;
  transition: background .15s ease, box-shadow .15s ease, transform .06s ease;
}
.connect-autocad-btn.is-primary:hover {
  background: var(--accent-hover) !important;
  border-color: var(--accent-hover) !important;
  box-shadow: 0 4px 14px color-mix(in oklab, var(--accent) 38%, transparent);
}
.connect-autocad-btn.is-primary:active {
  transform: translateY(0.5px) scale(0.995);
  box-shadow: 0 1px 4px color-mix(in oklab, var(--accent) 30%, transparent);
}
.connect-autocad-btn.is-primary:focus-visible {
  outline: none;
  box-shadow: var(--ring), 0 4px 14px color-mix(in oklab, var(--accent) 30%, transparent);
}

/* ── Blacklist / Whitelist screen ──────────────────────────────
   Dedicated rail tab (below Library) where users audit and curate
   the two persisted skip-lists. Styled to match the Library
   screen's information-dense layout — a header bar with search +
   reload, a two-column panel grid for the lists themselves. */
.bl-screen {
  display: flex; flex-direction: column;
  height: 100%;
  padding: 18px 22px;
  gap: 14px;
  overflow: hidden;
}
.bl-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 18px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.bl-title {
  font-size: 17px; font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
}
.bl-subtitle {
  font-size: 12px;
  color: var(--text-3);
  margin-top: 2px;
}
.bl-actions {
  display: flex; align-items: center; gap: 8px;
}
.bl-search-wrap {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0 10px;
  height: 30px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--text-3);
  min-width: 260px;
  transition: border-color 120ms ease;
}
.bl-search-wrap:focus-within {
  border-color: var(--accent);
  box-shadow: var(--ring);
}
.bl-search {
  flex: 1; min-width: 0;
  height: 100%;
  background: transparent;
  border: none;
  outline: none;
  color: var(--text);
  font-size: 12.5px;
}

.bl-flash {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  border-radius: 10px;
  background: color-mix(in oklab, var(--green) 12%, transparent);
  color: color-mix(in oklab, var(--green) 70%, var(--text));
  border: 1px solid color-mix(in oklab, var(--green) 35%, transparent);
  font-size: 12.5px; font-weight: 500;
  animation: bl-flash-in 200ms cubic-bezier(0.22, 0.9, 0.3, 1);
}
@keyframes bl-flash-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.bl-panels {
  display: flex;
  flex-direction: column;
  gap: 14px;
  flex: 1; min-height: 0;
}
.bl-panel {
  display: flex; flex-direction: column;
  min-height: 0;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.bl-panel-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  background: color-mix(in oklab, var(--text-3) 3%, transparent);
}
.bl-panel-title {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600;
  color: var(--text);
}
.bl-panel-hint {
  font-size: 11.5px;
  color: var(--text-3);
  margin-top: 3px;
  line-height: 1.4;
}
.bl-dot {
  display: inline-block;
  width: 8px; height: 8px; border-radius: 50%;
  box-shadow: 0 0 0 3px color-mix(in oklab, currentColor 16%, transparent);
}
.bl-dot--black { background: var(--red); color: var(--red); }
.bl-dot--white { background: var(--green); color: var(--green); }
.bl-dot--auto  { background: var(--orange); color: var(--orange); }
/* Auto-filtered entries are wider pills so the reason column can
   breathe. The same pill shape still reads as "an audit entry"
   but with the regex reason visible and a rescue CTA at the end. */
.bl-item--auto {
  display: flex;
  width: 100%;
  background: color-mix(in oklab, var(--orange) 8%, transparent);
  border-color: color-mix(in oklab, var(--orange) 28%, var(--border));
  border-radius: 8px;
  padding: 6px 8px 6px 12px;
  gap: 10px;
  align-items: center;
}
.bl-item--auto .bl-item-main {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.bl-item--auto .bl-item-text {
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bl-item--auto .bl-item-reason {
  font-size: 10.5px;
  color: var(--text-3);
  font-style: italic;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bl-rescue {
  flex-shrink: 0;
  background: var(--green);
  color: white;
  border: none;
  font-size: 11px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 120ms ease;
}
.bl-rescue:hover {
  background: color-mix(in oklab, var(--green) 85%, white);
}

/* ═══════════════════════════════════════════════════════════════
   Library-Build view — folder-walk staging workspace
   ═══════════════════════════════════════════════════════════════ */
.lib-mode-toggle {
  display: flex;
  gap: 4px;
  padding: 3px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin: 8px 0;
}
.lib-mode-btn {
  flex: 1;
  border: none;
  background: transparent;
  color: var(--text-2);
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 600;
  border-radius: 6px;
  cursor: pointer;
  transition: background 100ms ease, color 100ms ease;
}
.lib-mode-btn:hover { color: var(--text); }
.lib-mode-btn.is-active {
  background: var(--accent);
  color: white;
}

.lib-build-only {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--bg);
}
.lib-build-modebar {
  display: flex;
  gap: 4px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  background: var(--panel-solid);
}
.lib-build-modebar .lib-mode-btn {
  font-size: 12px;
  padding: 5px 14px;
}
.lib-build-only > .lib-build-root {
  flex: 1;
  min-height: 0;
}

/* Overall progress banner — replaces the speed + quality trend
   cards. Dense, skimmable: progress bar on top, 4-stat row below. */
.overall-banner {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 16px;
  background: color-mix(in oklab, var(--accent) 6%, var(--panel-solid));
  border: 1px solid color-mix(in oklab, var(--accent) 24%, var(--border));
  border-radius: 10px;
}
.overall-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.overall-title {
  font-size: 13px;
  font-weight: 700;
}
.overall-counter {
  font-variant-numeric: tabular-nums;
}
.overall-done {
  font-size: 22px;
  font-weight: 800;
  color: var(--accent);
}
.overall-slash { color: var(--text-3); margin: 0 3px; }
.overall-total {
  font-size: 18px;
  font-weight: 600;
  color: var(--text-2);
}
.overall-pct {
  margin-left: 10px;
  font-size: 14px;
  color: var(--text-2);
  font-weight: 600;
}
.overall-progress-bar {
  height: 6px;
  background: color-mix(in oklab, var(--border) 60%, transparent);
  border-radius: 3px;
  overflow: hidden;
}
.overall-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), color-mix(in oklab, var(--accent) 70%, var(--green)));
  transition: width 420ms ease;
}
.overall-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}
.overall-stats > div {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.overall-stat-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-3);
  font-weight: 600;
}
.overall-stat-value {
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.overall-stat-eta { color: var(--orange); }

/* Per-dir progress line — thin bar under folder header showing
   how many .dwg leaves under this subtree have finished. */
.lib-build-dir-stats {
  display: flex;
  gap: 6px;
  align-items: center;
  flex-shrink: 0;
}
.lib-build-dir-eta {
  font-size: 10.5px;
  color: var(--orange);
  font-weight: 600;
  background: color-mix(in oklab, var(--orange) 14%, transparent);
  padding: 1px 6px;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}
.lib-build-dir-progress {
  height: 2px;
  background: color-mix(in oklab, var(--border) 50%, transparent);
  margin-right: 8px;
  margin-bottom: 3px;
  border-radius: 1px;
  overflow: hidden;
}
.lib-build-dir-progress-fill {
  height: 100%;
  transition: width 220ms ease, background 220ms ease;
}

/* Compact sidebar-friendly BuildLibraryView. Lives INSIDE the
   existing 280 px sidebar, so everything stacks vertically. */
.lib-build-sidebar {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
  min-height: 0;
}
/* Toggle expand/collapse — bấm vào section sẽ đẩy nó lên full height
   và ẩn các section khác. Click lại nút thu để khôi phục layout
   3-section mặc định. Animation: max-height + opacity transition giữ
   cảm giác đẩy mượt mà thay vì biến mất đột ngột. */
.sb-section {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  transition: flex 240ms cubic-bezier(0.22, 0.95, 0.26, 1),
              max-height 240ms cubic-bezier(0.22, 0.95, 0.26, 1),
              opacity 200ms ease;
}
.sb-toggle {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  background: var(--panel-solid);
  color: var(--text-2);
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  z-index: 5;
  transition: background 120ms, color 120ms, border-color 120ms;
}
.sb-toggle:hover {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent);
}
/* Khi 1 section đang mở rộng — section đó chiếm hết, các section
   khác (kể cả header banner + autopilot button) co lại 0px.   */
.lib-build-sidebar.sb-exp-workflow > :not(.sb-section-workflow):not(.sb-keep-visible),
.lib-build-sidebar.sb-exp-files    > :not(.sb-section-files):not(.sb-keep-visible) {
  max-height: 0;
  opacity: 0;
  margin: 0;
  padding-top: 0;
  padding-bottom: 0;
  pointer-events: none;
}
.lib-build-sidebar.sb-exp-workflow .sb-section-workflow,
.lib-build-sidebar.sb-exp-files    .sb-section-files {
  flex: 1 1 auto;
  max-height: none;
}
.lib-build-sb-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.lib-build-sb-folder {
  font-size: 11px;
  color: var(--text-3);
  line-height: 1.4;
  word-break: break-all;
  font-family: "JetBrains Mono", "SF Mono", ui-monospace, monospace;
  padding: 6px 8px;
  background: color-mix(in oklab, var(--panel-solid) 96%, black);
  border-radius: 4px;
}
.lib-build-sb-folder--bottom {
  margin-top: auto;
  border-top: 1px solid var(--border);
  padding-top: 8px;
  max-height: 120px;
  overflow-y: auto;
}
.lib-build-sb-session {
  font-size: 11px;
  color: var(--text-3);
}
.overall-stats-compact {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 4px 10px;
  font-size: 11px;
  color: var(--text-2);
}
.overall-stats-compact b {
  color: var(--text);
  font-size: 12px;
}
.overall-stats-compact .overall-stat-eta b { color: var(--orange); }
.lib-build-files--sidebar {
  flex: 1;
  min-height: 150px;
  max-height: 40vh;
}
.lib-build-files--sidebar .lib-build-files-head {
  padding: 8px 10px;
  font-size: 11.5px;
}
.lib-build-files--sidebar .lib-build-file,
.lib-build-files--sidebar .lib-build-dir {
  font-size: 11.5px;
}

.lib-build-root {
  display: flex;
  flex-direction: column;
  height: 100%;
  gap: 10px;
  padding: 14px 16px;
  box-sizing: border-box;
}
.lib-build-top {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.lib-build-prog {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  padding: 3px 10px;
  background: var(--accent-soft);
  border-radius: 999px;
}
.lib-build-log {
  display: flex;
  flex-direction: column;
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-solid);
  overflow: hidden;
  max-height: 220px;
  flex-shrink: 0;
}
/* Build-mode workarea variant — log lives in a fixed-size row of
   the parent grid, so the inherited max-height/flex-shrink would
   prevent the splitter from working. Reset both. */
.workarea--build .lib-build-log {
  max-height: none;
  margin-top: 0;
  flex-shrink: 1;
  height: 100%;
}

/* Translation-quality chips on the build-rows table. L1 (exact) is
   the strongest signal → green; L2 (base+context) → blue; L3 (fuzzy)
   → amber; miss → grey. Compact 28px pill so it never steals row
   width from the source/translation columns. */
.ap-match {
  display: inline-block;
  min-width: 28px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  text-align: center;
  letter-spacing: 0.4px;
  font-family: "JetBrains Mono", monospace;
}
.ap-match-l1   { background: #d1fae5; color: #047857; }
.ap-match-l2   { background: #dbeafe; color: #1d4ed8; }
.ap-match-l3   { background: #fef3c7; color: #b45309; }
.ap-match-miss { background: #f3f4f6; color: #6b7280; }
[data-theme="dark"] .ap-match-l1   { background: #064e3b; color: #6ee7b7; }
[data-theme="dark"] .ap-match-l2   { background: #1e3a8a; color: #93c5fd; }
[data-theme="dark"] .ap-match-l3   { background: #78350f; color: #fcd34d; }
[data-theme="dark"] .ap-match-miss { background: #374151; color: #9ca3af; }

/* Subtle background tint on rows still needing translation. */
.lib-build-table tr.ap-row-miss {
  background: color-mix(in oklab, var(--orange) 6%, transparent);
}
.lib-build-table tr.ap-row-miss:hover {
  background: color-mix(in oklab, var(--orange) 12%, transparent);
}

/* New scan-result rows prepended to the library table — subtle
   tint + left accent stripe so the user sees what just landed
   without having the whole table flash. */
.table-row.is-scan-new {
  background: color-mix(in oklab, var(--orange) 5%, transparent);
  border-left: 2px solid var(--orange);
}
.table-row.is-scan-new:hover {
  background: color-mix(in oklab, var(--orange) 10%, transparent);
}

/* QA-flagged rows — Judge Agent đánh dấu severity != none. Background
   vàng nhạt + viền trái vàng đậm để user scan thấy ngay những dòng
   cần check. Tooltip note (set qua data-qa-note) hiện khi hover. */
.table-row.qa-flagged {
  background: color-mix(in oklab, var(--mc-warn) 10%, transparent);
  border-left: 3px solid var(--mc-warn);
}
.table-row.qa-flagged:hover {
  background: color-mix(in oklab, var(--mc-warn) 18%, transparent);
}
.table-row.qa-flagged.qa-critical {
  background: color-mix(in oklab, var(--mc-danger) 12%, transparent);
  border-left-color: var(--mc-danger);
}
.table-row.qa-flagged.qa-critical:hover {
  background: color-mix(in oklab, var(--mc-danger) 22%, transparent);
}

/* Step state for "skipped" — when QA is toggled OFF, B3 renders
   muted to show the user it won't fire automatically. */
.wf-step.wf-step-skipped { opacity: 0.55; }
.wf-step.wf-step-skipped .wf-step-dot {
  background: var(--text-3) !important;
}
.wf-step.wf-step-skipped .wf-step-dot::before { content: "—"; }

/* ── Library/Translate sidebar: running red-dot pulse ──────────
   Bỏ connector line dọc giữa các step theo yêu cầu — chỉ giữ
   chấm đỏ pulse trên nút đang chạy (giống Antigravity command
   indicator). */
.sidebar-panel .step { position: relative; }
/* Red-dot pulse — gắn ::after vào nút khi data-running="true".
   Position absolute trong nút (nút đã position:relative qua btn). */
.btn[data-running="true"] {
  position: relative;
  padding-right: 32px;          /* chỗ cho dot không đè text */
}
.btn[data-running="true"]::after {
  content: "";
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--mc-danger);
  box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.85);
  animation: btn-running-pulse 1.4s infinite cubic-bezier(0.66, 0, 0, 1);
}
/* Phase progress bar — Apple-style slim bar (3 px tall) với
   gradient fill, dùng trong sidebar level indicator. */
.phase-progress-bar {
  height: 3px;
  width: 100%;
  background: rgba(120,120,120,0.18);
  border-radius: 2px;
  overflow: hidden;
  margin: 3px 0 2px 0;
}
.phase-progress-fill {
  height: 100%;
  border-radius: 2px;
  transition: width 280ms cubic-bezier(0.4, 0, 0.2, 1);
}
.phase-progress-indeterminate .phase-progress-fill {
  width: 35% !important;
  animation: phase-progress-slide 1.4s infinite ease-in-out;
}
@keyframes phase-progress-slide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(285%); }
}
/* Real <span> dot — luôn render trong button, hiển thị/ẩn qua
   ``data-running`` attribute trên button cha. Bridge.js bulletproof
   interval cập nhật attribute mỗi 200ms từ window.__libStepRunning,
   nên dot luôn đồng bộ với phase Python emit ngay cả khi React
   state stale. */
.step-running-dot {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--mc-danger);
  box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.85);
  animation: btn-running-pulse 1.4s infinite cubic-bezier(0.66, 0, 0, 1);
  pointer-events: none;
  z-index: 2;
  display: none;          /* default: ẩn */
}
.btn[data-running="true"] .step-running-dot {
  display: inline-block;  /* hiện khi data-running */
}
@keyframes btn-running-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); }
  70%  { box-shadow: 0 0 0 12px rgba(239, 68, 68, 0); }
  100% { box-shadow: 0 0 0 0   rgba(239, 68, 68, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .btn[data-running="true"]::after { animation: none; }
}

/* Scan-rows header stats pills + filter button states. */
.ap-stats {
  display: inline-flex;
  gap: 8px;
  margin-left: 12px;
  font-size: 11.5px;
  font-weight: 600;
}
.ap-stats-hit  { color: var(--green); }
.ap-stats-miss { color: var(--orange); }
.btn.is-active {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent);
}

/* File-tree summary header — rich done/total + status pills + a
   thin progress bar. Designed to read at a glance during 6 000-file
   overnight runs ("file-processing pro" view). */
.lib-build-files-head { display: block; padding: 8px 10px; }
.lib-build-files-head-row {
  display: flex; align-items: baseline; gap: 8px;
  margin-bottom: 6px;
}
.lib-build-files-title {
  font-size: 12px; font-weight: 700; letter-spacing: 0.3px;
  color: var(--text-2); text-transform: uppercase;
}
.lib-build-files-count {
  margin-left: auto; font-size: 13px; font-weight: 700;
}
.lib-build-files-count b { color: var(--accent); }
.lib-build-files-bar {
  height: 4px; border-radius: 2px;
  background: var(--border); overflow: hidden; margin-bottom: 6px;
}
.lib-build-files-bar-fill {
  height: 100%; background: var(--green);
  transition: width 0.25s ease-out;
}
.lib-build-files-pills {
  display: flex; flex-wrap: wrap; gap: 4px;
}
.lib-build-files-pills .pill {
  font-size: 10.5px; font-weight: 600;
  padding: 1px 7px; border-radius: 999px;
  font-family: "JetBrains Mono", monospace;
  letter-spacing: 0.3px;
}
.pill-done { background: color-mix(in oklab, var(--green) 18%, transparent);  color: var(--green);  }
.pill-proc { background: color-mix(in oklab, var(--accent) 18%, transparent); color: var(--accent); }
.pill-pend { background: color-mix(in oklab, var(--text-3) 14%, transparent); color: var(--text-2); }
.pill-err  { background: color-mix(in oklab, var(--red) 18%, transparent);    color: var(--red);    }

/* ── Library workflow (sidebar 4-step) ────────────────────────
   B1 Pick folder · B2 Scan + Translate · B3 QA review ·
   B4 Cloud sync. Each step shows: number badge, dot (red pulse
   when active, green check when done), title + sub line, and an
   optional action button. */
.wf-pipeline {
  display: flex; flex-direction: column;
  padding: 10px 8px 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--panel-solid);
  margin-top: 10px;
}
.wf-title {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.4px;
  color: var(--text-2);
  text-transform: uppercase;
  padding: 4px 6px 8px;
}
.wf-step {
  display: flex; gap: 10px;
  position: relative;
  padding: 4px 6px;
}
/* Vertical spine running through the dots — gives the user the
   visual chain "1 → 2 → 3 → 4". */
.wf-step-spine {
  position: relative;
  width: 16px;
  flex: 0 0 auto;
}
.wf-step-spine::before {
  content: "";
  position: absolute;
  left: 7px; top: 18px; bottom: -8px;
  width: 1.5px;
  background: var(--border);
  z-index: 0;
}
.wf-step:last-child .wf-step-spine::before { display: none; }
.wf-step-dot {
  position: absolute;
  left: 1px; top: 4px;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--border);
  display: flex; align-items: center; justify-content: center;
  color: white; font-size: 9px; font-weight: 900;
  z-index: 1;
  transition: background 0.2s;
}
.wf-step-pending .wf-step-dot { background: var(--border); }
.wf-step-ready   .wf-step-dot { background: var(--text-3); }
.wf-step-done    .wf-step-dot { background: var(--green); }
.wf-step-error   .wf-step-dot { background: var(--red); font-size: 12px; }
.wf-step-active  .wf-step-dot {
  background: var(--mc-danger);
  animation: wf-step-pulse 1.4s ease-in-out infinite;
}
.wf-step-active  .wf-step-dot::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 2px solid var(--mc-danger);
  opacity: 0.6;
  animation: wf-step-halo 1.4s ease-out infinite;
}
@keyframes wf-step-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.18); }
}
@keyframes wf-step-halo {
  0%   { transform: scale(0.8); opacity: 0.7; }
  100% { transform: scale(2.2); opacity: 0;   }
}
.wf-step-body {
  flex: 1; min-width: 0;
  padding-bottom: 6px;
}
.wf-step-head {
  display: flex; align-items: center; gap: 6px;
  margin-bottom: 2px;
}
.wf-step-no {
  font-size: 10px; font-weight: 800;
  color: var(--accent);
  background: color-mix(in oklab, var(--accent) 14%, transparent);
  padding: 1px 6px;
  border-radius: 999px;
  letter-spacing: 0.5px;
}
.wf-step-title {
  font-size: 12.5px; font-weight: 600;
  color: var(--text);
}
.wf-step-pending .wf-step-title { color: var(--text-3); font-weight: 500; }
.wf-step-running {
  margin-left: auto;
  font-size: 10px;
  color: var(--red);
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  font-family: "JetBrains Mono", monospace;
  animation: wf-step-blink 1.2s ease-in-out infinite;
}
@keyframes wf-step-blink { 50% { opacity: 0.4; } }
.wf-step-sub {
  font-size: 11px; color: var(--text-2);
  margin-top: 1px;
  font-family: "JetBrains Mono", monospace;
  line-height: 1.45;
}
.wf-step-actions {
  margin-top: 6px;
  display: flex; gap: 4px;
}
.wf-step-actions .btn.sm { padding: 3px 10px; }

/* ── Phase pipeline (sidebar) ───────────────────────────────────
   Vertical 3-step indicator with a pulsing red dot on the active
   stage. Reads at a glance: Setup → Process → Done.            */
.pipe-pipeline {
  display: flex; flex-direction: column;
  gap: 2px;
  padding: 8px 10px 10px;
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-solid);
}
.pipe-title {
  font-size: 11px; font-weight: 700; letter-spacing: 0.4px;
  color: var(--text-2); text-transform: uppercase;
  margin-bottom: 4px;
}
.pipe-step {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 4px 0; min-height: 24px;
  position: relative;
}
.pipe-step::before {
  /* Connector line that runs through the dots on the left. */
  content: ""; position: absolute;
  left: 6px; top: 22px; bottom: -4px;
  width: 1.5px; background: var(--border);
  z-index: 0;
}
.pipe-step:last-child::before { display: none; }
.pipe-dot {
  width: 13px; height: 13px;
  border-radius: 50%;
  background: var(--border);
  flex-shrink: 0;
  margin-top: 3px;
  display: flex; align-items: center; justify-content: center;
  color: white; font-size: 9px; font-weight: 900;
  position: relative;
  z-index: 1;
}
.pipe-step-pending .pipe-dot { background: var(--border); }
.pipe-step-done    .pipe-dot { background: var(--green); }
.pipe-step-error   .pipe-dot { background: var(--red); font-size: 12px; }
.pipe-step-active  .pipe-dot {
  background: var(--mc-danger);
  animation: pipe-pulse 1.4s ease-in-out infinite;
}
.pipe-step-active  .pipe-dot::after {
  /* Pulsing halo ring around the active dot. */
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 2px solid var(--mc-danger);
  opacity: 0.6;
  animation: pipe-halo 1.4s ease-out infinite;
}
@keyframes pipe-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.18); }
}
@keyframes pipe-halo {
  0%   { transform: scale(0.8); opacity: 0.7; }
  100% { transform: scale(2.0); opacity: 0;   }
}
.pipe-text { flex: 1; min-width: 0; line-height: 1.3; }
.pipe-label {
  font-size: 12px; font-weight: 600;
  color: var(--text);
}
.pipe-step-pending .pipe-label { color: var(--text-3); font-weight: 500; }
.pipe-no { color: var(--text-3); font-weight: 700; margin-right: 2px; }
.pipe-sub {
  font-size: 11px; color: var(--text-2); margin-top: 1px;
  font-family: "JetBrains Mono", monospace;
}

/* ── AI provider rotation pool (Settings → AI) ─────────────────
   Shared between the Translation and QA/Evaluation pools. Two
   instances rendered side-by-side; each one is an ordered list of
   provider+key entries with ↑↓✕ controls and a status chip. */
.ai-pool {
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--panel-solid);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column;
}
.ai-pool-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  user-select: none;
}
.ai-pool.is-collapsed .ai-pool-head {
  border-bottom-color: transparent;
}
.ai-pool-caret {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 4px 8px;
  font-size: 14px;
  cursor: pointer;
  color: var(--text-2);
  border-radius: 6px;
  transition: background 0.12s;
}
.ai-pool-caret:hover {
  background: color-mix(in oklab, var(--text-3) 10%, transparent);
  color: var(--text);
}
.ai-pool-chip {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 10px;
  border-radius: 999px;
  white-space: nowrap;
}
.ai-pool-icon {
  width: 22px; height: 22px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
}
.ai-pool-title { font-size: 13px; font-weight: 600; }
.ai-pool-subtitle {
  font-size: 11px; color: var(--text-3); margin-top: 1px;
}
.ai-pool-status {
  font-size: 11px; font-weight: 600;
  padding: 8px 16px;
  border-bottom: 1px solid var(--border);
  font-family: "JetBrains Mono", monospace;
  letter-spacing: 0.2px;
}
.ai-pool-list {
  display: flex; flex-direction: column;
  padding: 8px;
  gap: 6px;
}
.ai-pool-empty {
  padding: 18px 12px;
  font-size: 11.5px;
  color: var(--text-3);
  text-align: center;
  font-style: italic;
  line-height: 1.5;
}
/* Single-line row: # · status-dot · provider · model · API key · ↑↓✕ */
.ai-pool-row {
  display: grid;
  grid-template-columns: 28px 14px 130px 170px 1fr auto;
  gap: 8px; align-items: center;
  padding: 5px 4px;
  border-radius: 8px;
  transition: background 0.12s;
}
.ai-pool-row:hover { background: color-mix(in oklab, var(--accent) 4%, transparent); }
.ai-pool-row-active {
  background: color-mix(in oklab, var(--accent) 10%, transparent);
  outline: 1px solid color-mix(in oklab, var(--accent) 35%, transparent);
}
.ai-pool-row-exhausted { opacity: 0.55; }
.ai-pool-row-error {
  background: color-mix(in oklab, var(--red) 8%, transparent);
}
.ai-pool-no {
  font-size: 11px; font-weight: 700;
  color: var(--text-3); text-align: center;
  font-family: "JetBrains Mono", monospace;
}
.ai-pool-prov, .ai-pool-model {
  height: 28px;
  font-size: 12px;
  padding-left: 8px;
}
.ai-pool-model {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  color: var(--text-2);
}
.ai-pool-key {
  height: 28px;
  font-family: "JetBrains Mono", monospace;
  font-size: 11.5px;
  letter-spacing: 0.04em;
}
/* Connection status dot per row — position: just before the provider
   select. Tooltip on hover gives the human-readable state. */
.ai-dot {
  display: inline-block;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--text-3);
  box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--text-3) 30%, transparent);
  transition: background 0.18s, box-shadow 0.18s;
}
.ai-dot-idle {
  background: var(--text-3);
  box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--text-3) 30%, transparent);
}
.ai-dot-ok {
  background: var(--green);
  box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--green) 35%, transparent),
              0 0 6px color-mix(in oklab, var(--green) 50%, transparent);
}
.ai-dot-exh {
  background: var(--orange);
  box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--orange) 35%, transparent);
}
.ai-dot-err {
  background: var(--red);
  box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--red) 40%, transparent),
              0 0 6px color-mix(in oklab, var(--red) 60%, transparent);
}
.ai-dot-checking {
  background: var(--accent);
  animation: ai-dot-pulse 1.0s ease-in-out infinite;
}
@keyframes ai-dot-pulse {
  0%, 100% { box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--accent) 40%, transparent),
                          0 0 0 0 color-mix(in oklab, var(--accent) 50%, transparent); }
  50%      { box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--accent) 40%, transparent),
                          0 0 0 6px color-mix(in oklab, var(--accent) 0%,  transparent); }
}

/* Status message row that wraps under the entry after a check.
   Spans the full grid width; colour is set inline in the JSX. */
.ai-pool-row-msg {
  font-size: 11px;
  font-family: "JetBrains Mono", monospace;
  padding: 2px 4px 0 36px; /* indent past # + dot column */
  letter-spacing: 0.2px;
}

/* ── Pricing comparison table ─────────────────────────────────
   Sortable read-only reference of model price + quality. Loaded
   from core/ai_pricing.json on the Python side so maintainers can
   bump prices without a code change. */
.ai-cmp {
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--panel-solid);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.ai-cmp-head {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.ai-cmp-title { font-size: 13px; font-weight: 600; }
.ai-cmp-sub {
  font-size: 11px; color: var(--text-3); margin-top: 2px;
}
/* No max-height: show every row of the sorted list top-to-bottom
   so the user can compare the entire catalog at once. The outer
   Settings panel already scrolls if content exceeds viewport. */
.ai-cmp-body { overflow: visible; }
.ai-cmp-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  /* Fixed layout = predictable column widths · prevents the
     provider/model/speed cells from collapsing when the window
     narrows. Best_for column gets ellipsis instead of wrap. */
  table-layout: fixed;
}
.ai-cmp-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--panel-solid);
  text-align: left;
  padding: 8px 12px;
  font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--text-2);
  text-transform: uppercase;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.ai-cmp-table tbody td {
  padding: 8px 12px;
  border-bottom: 1px solid color-mix(in oklab, var(--border) 60%, transparent);
  /* Default behaviour for content cells: never wrap, ellipsis if
     the cell is narrower than the content. The cells that need
     more breathing room override this in their own selector. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ai-cmp-table tbody tr:hover {
  background: color-mix(in oklab, var(--accent) 4%, transparent);
}
.ai-cmp-prov-chip {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 2px;
  margin-right: 6px;
  vertical-align: middle;
  flex-shrink: 0;
}
.ai-cmp-model {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.2px;
  white-space: nowrap;
}
.ai-cmp-speed-dot {
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
  flex-shrink: 0;
}
.ai-cmp-best {
  font-size: 11px;
  color: var(--text-2);
  /* Phù hợp column ellipses on overflow — full text on hover via
     the title attribute already set in JSX. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Full-URL "Link API Key" cell. Stripped-protocol display so the
   short part (``platform.openai.com/api-keys``) fits the column;
   full URL on the title attribute for hover. Click opens the
   provider portal via the ``open_external`` Python slot. */
.ai-cmp-key-cell {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
}
.ai-cmp-key-link {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dashed color-mix(in oklab, var(--accent) 50%, transparent);
  cursor: pointer;
  transition: color 0.12s, border-color 0.12s;
}
.ai-cmp-key-link:hover {
  color: color-mix(in oklab, var(--accent) 80%, var(--text));
  border-bottom-color: var(--accent);
  border-bottom-style: solid;
}
.ai-cmp-qbar {
  position: relative;
  height: 14px;
  background: color-mix(in oklab, var(--border) 70%, transparent);
  border-radius: 7px;
  overflow: hidden;
  display: flex; align-items: center;
}
.ai-cmp-qbar-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  border-radius: 7px;
  transition: width 0.3s ease-out, background 0.3s;
}
.ai-cmp-qbar-num {
  position: relative;
  z-index: 1;
  width: 100%;
  text-align: center;
  font-family: "JetBrains Mono", monospace;
  font-size: 10.5px; font-weight: 700;
  color: var(--text);
  text-shadow: 0 0 2px var(--panel-solid);
}
.ai-cmp-foot {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 16px;
  font-size: 11px;
  color: var(--text-2);
  background: color-mix(in oklab, var(--text-3) 4%, transparent);
  border-top: 1px solid var(--border);
}

/* ── Active-account namespace badge ───────────────────────────
   Top-right of the AI Settings header. Shows whether the user is
   editing the anonymous "@default" config or their per-account
   settings; offers a sign-in CTA when anonymous so the user knows
   their setup will follow them across machines. */
.ai-ns-badge {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--panel-solid);
  min-width: 230px;
}
.ai-ns-badge.is-default {
  border-color: color-mix(in oklab, var(--orange) 40%, var(--border));
  background: color-mix(in oklab, var(--orange) 5%, var(--panel-solid));
}
.ai-ns-badge.is-user {
  border-color: color-mix(in oklab, var(--green) 40%, var(--border));
  background: color-mix(in oklab, var(--green) 5%, var(--panel-solid));
}
.ai-ns-icon {
  font-size: 16px;
  width: 24px; height: 24px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.ai-ns-badge.is-default .ai-ns-icon {
  background: color-mix(in oklab, var(--orange) 14%, transparent);
  color: var(--orange);
}
.ai-ns-badge.is-user .ai-ns-icon {
  background: color-mix(in oklab, var(--green) 14%, transparent);
  color: var(--green);
  font-weight: 900;
  font-size: 12px;
}
.ai-ns-text { flex: 1; min-width: 0; }
.ai-ns-label {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
}
.ai-ns-badge.is-default .ai-ns-label { color: var(--orange); }
.ai-ns-badge.is-user    .ai-ns-label { color: var(--green); }
.ai-ns-email {
  font-size: 11.5px;
  color: var(--text-2);
  margin-top: 1px;
  font-family: "JetBrains Mono", monospace;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 180px;
}

/* ── User-habit insights (smart defaults) ─────────────────────
   Google-Dev-style "we noticed you've been using X — set as
   default?" banner. Sits at the top of the AI Settings panel. */
.ai-insights {
  border: 1px solid var(--border);
  border-radius: 14px;
  background: linear-gradient(
    135deg,
    color-mix(in oklab, var(--accent) 4%, var(--panel-solid)),
    var(--panel-solid));
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.ai-insights-head {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.ai-insights-title {
  font-size: 13px; font-weight: 600;
  display: flex; align-items: center; gap: 6px;
}
.ai-insights-sub {
  font-size: 11px; color: var(--text-3); margin-top: 2px;
}

.ai-insights-recs {
  padding: 10px 16px;
  display: flex; flex-direction: column; gap: 8px;
  border-bottom: 1px solid var(--border);
}
.ai-insights-rec {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 10px;
  background: color-mix(in oklab, var(--accent) 8%, transparent);
  border-radius: 8px;
  border-left: 3px solid var(--accent);
}
.ai-insights-rec-icon { font-size: 14px; }
.ai-insights-rec-text { flex: 1; font-size: 12px; }
.btn.xs {
  padding: 2px 8px; font-size: 11px; height: 22px;
}

.ai-insights-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
  padding: 10px 12px;
}
.ai-insights-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px;
  background: var(--panel-solid);
}
.ai-insights-card-title {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.4px;
  color: var(--text-2);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.ai-insights-empty {
  font-size: 11px; color: var(--text-3);
  font-style: italic;
  padding: 10px 6px;
}
.ai-insights-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 5px;
}
.ai-insights-list li {
  display: grid;
  grid-template-columns: 22px 12px 1fr 70px 30px;
  gap: 6px; align-items: center;
  font-size: 12px;
}
.ai-insights-rank {
  color: var(--text-3); font-weight: 700;
  font-size: 10.5px;
  font-family: "JetBrains Mono", monospace;
}
.ai-insights-prov-chip {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 2px;
}
.ai-insights-name {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 11.5px;
}
.ai-insights-name .muted-2 {
  font-family: "JetBrains Mono", monospace;
  font-size: 10.5px;
}
.ai-insights-bar {
  position: relative;
  height: 5px;
  background: color-mix(in oklab, var(--border) 60%, transparent);
  border-radius: 3px;
  overflow: hidden;
}
.ai-insights-bar-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  border-radius: 3px;
  transition: width 0.3s;
}
.ai-insights-count {
  text-align: right;
  font-family: "JetBrains Mono", monospace;
  font-size: 10.5px; color: var(--text-2);
  font-weight: 700;
}

/* 24-hour activity heatmap (hour-of-day, last 7 d). */
.ai-insights-heat {
  display: grid;
  grid-template-columns: repeat(24, 1fr);
  gap: 2px;
  height: 56px;
  align-items: end;
  margin-bottom: 4px;
}
.ai-insights-heat-bar {
  border-radius: 2px;
  min-height: 2px;
  transition: background 0.2s;
}
.ai-insights-heat-axis {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: var(--text-3);
  font-family: "JetBrains Mono", monospace;
  padding: 0 2px;
}

/* ── Per-model usage history ──────────────────────────────────
   Google-Cloud-Console-style dashboard for AI calls. Auto-refreshes
   every 5 s from the Python ai_usage_get slot. */
.ai-usage {
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--panel-solid);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.ai-usage-head {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.ai-usage-title { font-size: 13px; font-weight: 600; }
.ai-usage-sub {
  font-size: 11px; color: var(--text-3); margin-top: 2px;
}
.ai-usage-body { max-height: 320px; overflow: auto; }
.ai-usage-empty {
  padding: 24px 16px;
  font-size: 12px;
  color: var(--text-3);
  text-align: center;
  font-style: italic;
}
.ai-usage-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  table-layout: fixed;
}
.ai-usage-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--panel-solid);
  text-align: left;
  padding: 8px 12px;
  font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--text-2);
  text-transform: uppercase;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.ai-usage-table tbody td {
  padding: 8px 12px;
  border-bottom: 1px solid color-mix(in oklab, var(--border) 60%, transparent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ai-usage-table tbody tr:hover {
  background: color-mix(in oklab, var(--accent) 4%, transparent);
}
.ai-usage-model {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  color: var(--text-3);
}
.ai-usage-err {
  font-size: 10.5px;
  color: var(--red);
  font-weight: 700;
}
.ai-usage-spark {
  display: inline-block;
  vertical-align: middle;
}
.ai-usage-foot {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 16px;
  font-size: 11px;
  color: var(--text-2);
  background: color-mix(in oklab, var(--text-3) 4%, transparent);
  border-top: 1px solid var(--border);
}

/* Sticky Save bar — pinned to the bottom of the Settings scroll
   panel so the user can hit Save no matter how far they've
   scrolled into the pricing / usage tables. Glassy backdrop +
   top border keep the underlying content readable through it. */
.ai-save-bar {
  position: sticky;
  bottom: 0;
  z-index: 5;
  padding: 12px 16px;
  margin-left: -22px;
  margin-right: -22px;
  margin-bottom: -22px;
  background: color-mix(in oklab, var(--panel-solid) 92%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-top: 1px solid var(--border);
  box-shadow: 0 -4px 16px color-mix(in oklab, var(--text) 4%, transparent);
}

/* "Đã cập nhật • HH:MM:SS DD/MM/YYYY" pill. Flashes green for
   ~2.4s after the user clicks Save, then settles to a muted
   neutral so the timestamp stays readable but isn't shouty. */
.ai-saved-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px;
  font-family: "JetBrains Mono", monospace;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--panel-solid);
  color: var(--text-2);
  transition: background 0.2s, color 0.2s, border-color 0.2s,
              box-shadow 0.2s;
}
.ai-saved-icon {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--text-3);
  color: white;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 900; font-size: 9px;
}
.ai-saved-chip.is-flash {
  background: color-mix(in oklab, var(--green) 15%, transparent);
  color: var(--green);
  border-color: color-mix(in oklab, var(--green) 40%, var(--border));
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--green) 12%, transparent);
  animation: ai-saved-pulse 0.8s ease-out;
}
.ai-saved-chip.is-flash .ai-saved-icon { background: var(--green); }
@keyframes ai-saved-pulse {
  0%   { transform: scale(0.94); opacity: 0; }
  40%  { transform: scale(1.06); opacity: 1; }
  100% { transform: scale(1.00); opacity: 1; }
}
.ai-pool-actions { display: flex; gap: 2px; }
.ai-pool-actions .btn.xs {
  padding: 1px 7px; font-size: 11px; min-width: 24px;
}
.ai-pool-add {
  margin-top: 4px;
  border: 1px dashed var(--border);
  background: transparent;
  color: var(--accent);
  font-weight: 600;
}
.ai-pool-add:hover {
  background: color-mix(in oklab, var(--accent) 8%, transparent);
  border-color: var(--accent);
}
.lib-build-log-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  background: color-mix(in oklab, var(--panel-solid) 96%, black);
}
.lib-build-log-body {
  flex: 1;
  overflow-y: auto;
  padding: 8px 12px;
  font-family: "JetBrains Mono", "SF Mono", ui-monospace, monospace;
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--text);
  min-height: 0;
}
.lib-build-log-body > div { padding: 1px 0; }
.lib-build-log-body .ts { color: var(--text-3); font-size: 10.5px; }

.perf-trend {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px 12px;
  background: color-mix(in oklab, var(--accent) 5%, var(--panel-solid));
  border: 1px solid color-mix(in oklab, var(--accent) 22%, var(--border));
  border-radius: 10px;
}
.perf-trend-head {
  font-size: 12px;
  font-weight: 700;
  color: var(--text);
}
.perf-trend-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}
.perf-trend-stats > div {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.perf-trend-spark {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 36px;
  padding: 2px 0;
  background: color-mix(in oklab, var(--panel-solid) 96%, black);
  border-radius: 4px;
}
.perf-spark-bar {
  flex: 1;
  min-width: 3px;
  border-radius: 2px 2px 0 0;
  transition: background 120ms ease, height 220ms ease;
}

.opt-trend {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px 12px;
  background: color-mix(in oklab, var(--green) 6%, var(--panel-solid));
  border: 1px solid color-mix(in oklab, var(--green) 25%, var(--border));
  border-radius: 10px;
}
.opt-trend-head {
  font-size: 12px;
  font-weight: 700;
  color: var(--text);
}
.opt-trend-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}
.opt-trend-stats > div {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.opt-stat-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-3);
  font-weight: 600;
}
.opt-stat-value {
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.opt-stat-value--small { font-size: 12px; font-weight: 600; }
.opt-trend-spark {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 40px;
  padding: 2px 0;
  background: color-mix(in oklab, var(--panel-solid) 96%, black);
  border-radius: 4px;
}
.opt-spark-bar {
  flex: 1;
  min-width: 3px;
  border-radius: 2px 2px 0 0;
  transition: background 120ms ease;
}

.oai-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.45);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.oai-modal {
  width: 480px;
  max-width: 92vw;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 18px 60px rgba(0,0,0,0.25);
}
.oai-modal-head {
  padding: 14px 18px;
  font-size: 13px;
  font-weight: 700;
  border-bottom: 1px solid var(--border);
}
.oai-modal-body { padding: 16px 18px 18px; }
.lib-build-autopilot {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  background: color-mix(in oklab, var(--accent) 6%, var(--panel-solid));
  border: 1px solid color-mix(in oklab, var(--accent) 25%, var(--border));
  border-radius: 10px;
}
.ap-status {
  display: flex;
  gap: 10px;
  align-items: center;
  font-size: 12px;
}
.ap-phase {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
  color: var(--accent);
  font-size: 10.5px;
  padding: 2px 8px;
  background: var(--accent-soft);
  border-radius: 4px;
}
.ap-counter {
  font-weight: 600;
  color: var(--text);
  font-family: "JetBrains Mono", monospace;
}
.ap-current {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-2);
}
.ap-stats {
  font-size: 11.5px;
  color: var(--text-3);
}
.lib-build-main {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 10px;
}
.lib-build-files {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-solid);
  overflow: hidden;
}
.lib-build-files-head {
  padding: 10px 12px;
  font-size: 12.5px;
  font-weight: 600;
  border-bottom: 1px solid var(--border);
  background: color-mix(in oklab, var(--panel-solid) 96%, black);
}
.lib-build-files-list {
  flex: 1;
  overflow-y: auto;
  padding: 6px;
}
.lib-build-dir {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-2);
  border-radius: 4px;
  margin-bottom: 1px;
  user-select: none;
}
.lib-build-dir:hover { background: var(--selected); color: var(--text); }
.lib-build-caret {
  width: 10px;
  font-size: 9px;
  color: var(--text-3);
  flex-shrink: 0;
}
.lib-build-dir-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lib-build-dir-count {
  font-size: 10.5px;
  color: var(--text-3);
  background: color-mix(in oklab, var(--text-3) 12%, transparent);
  padding: 1px 6px;
  border-radius: 999px;
  font-weight: 500;
}
.lib-build-file {
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
  margin-bottom: 3px;
  transition: background 80ms;
}
.lib-build-file:hover { background: var(--selected); }
.lib-build-file.is-active {
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  padding-left: 7px;
}
.lib-build-file.is-processing {
  background: color-mix(in oklab, var(--orange) 14%, transparent);
  border-left: 3px solid var(--orange);
  animation: lib-build-pulse 1.6s ease-in-out infinite;
}
@keyframes lib-build-pulse {
  0%, 100% { background: color-mix(in oklab, var(--orange) 14%, transparent); }
  50%      { background: color-mix(in oklab, var(--orange) 28%, transparent); }
}
.lib-build-file-row {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
}
.lib-build-file-name {
  font-size: 12px;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}
.lib-build-file-meta {
  font-size: 10.5px;
  color: var(--text-3);
  margin-top: 2px;
}
.lib-build-badge {
  font-size: 10px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 4px;
  flex-shrink: 0;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.bl-status-pending    { background: color-mix(in oklab, var(--text-3) 18%, transparent); color: var(--text-3); }
.bl-status-processing { background: color-mix(in oklab, var(--orange) 18%, transparent); color: var(--orange); }
.bl-status-done       { background: color-mix(in oklab, var(--green) 18%, transparent);  color: var(--green); }
.bl-status-error      { background: color-mix(in oklab, var(--red) 18%, transparent);    color: var(--red); }

.lib-build-table-wrap {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-solid);
  overflow: hidden;
  min-height: 0;
}
.scan-rows-wrap {
  display: flex;
  flex-direction: column;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  min-height: 0;
}
.scan-rows-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  background: color-mix(in oklab, var(--panel-solid) 96%, black);
  position: sticky;
  top: 0;
  z-index: 2;
}
.scan-rows-body {
  overflow: auto;
  height: 100%;
  min-height: 0;
}
.scan-rows-body .lib-build-table {
  width: 100%;
}
.scan-rows-body .lib-build-table thead th {
  position: sticky;
  top: 0;
  background: var(--panel-solid);
  z-index: 1;
}

.lib-build-automerge-badge {
  background: color-mix(in oklab, var(--green) 18%, transparent);
  color: var(--green);
  border: 1px solid color-mix(in oklab, var(--green) 35%, transparent);
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.lib-build-table-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  background: color-mix(in oklab, var(--panel-solid) 96%, black);
  gap: 8px;
}
.lib-build-table-body {
  flex: 1;
  overflow: auto;
  min-height: 0;
}
.lib-build-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.lib-build-table thead th {
  position: sticky;
  top: 0;
  background: var(--panel-solid);
  z-index: 1;
  text-align: left;
  padding: 8px 10px;
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-3);
  border-bottom: 1px solid var(--border);
}
.lib-build-table tbody td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.lib-build-table tbody tr:hover { background: var(--selected); }
.lib-build-table tbody tr.is-selected {
  background: color-mix(in oklab, var(--accent) 12%, transparent);
}
.bl-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 22px;
  padding: 0 8px;
  background: var(--selected);
  color: var(--text-2);
  font-size: 11.5px; font-weight: 600;
  border-radius: 999px;
  flex-shrink: 0;
}
.bl-empty {
  padding: 28px 14px;
  text-align: center;
  color: var(--text-3);
  font-size: 12px;
  font-style: italic;
}
.bl-list {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding: 10px;
  display: flex; flex-wrap: wrap; align-content: flex-start;
  gap: 6px;
}
.bl-item {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 5px 4px 5px 10px;
  background: color-mix(in oklab, var(--red) 8%, transparent);
  border: 1px solid color-mix(in oklab, var(--red) 25%, var(--border));
  border-radius: 999px;
  font-size: 11.5px;
  color: var(--text);
  max-width: 100%;
  transition: background 120ms ease, border-color 120ms ease;
}
.bl-item:hover {
  background: color-mix(in oklab, var(--red) 14%, transparent);
  border-color: color-mix(in oklab, var(--red) 45%, var(--border));
}
.bl-item--whitelist {
  background: color-mix(in oklab, var(--green) 8%, transparent);
  border-color: color-mix(in oklab, var(--green) 25%, var(--border));
}
.bl-item--whitelist:hover {
  background: color-mix(in oklab, var(--green) 14%, transparent);
  border-color: color-mix(in oklab, var(--green) 45%, var(--border));
}
.bl-item-text {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 360px;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
}
.bl-remove {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-3);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 120ms ease, color 120ms ease;
}
.bl-remove:hover {
  background: var(--red);
  color: #fff;
}
.bl-item--whitelist .bl-remove:hover {
  background: var(--text-3);
}

/* ── Skip-list manager button (sidebar step) ───────────────────
   Full-width button inside its own "Từ đã lưu" workflow step,
   styled as a secondary action (neutral fill, dashed border) so
   it reads as management/audit rather than a primary translate
   step. Click opens the Blacklist/Whitelist manager modal. */
.skiplist-open-btn {
  display: flex; align-items: center; justify-content: center;
  width: 100%;
  padding: 8px 12px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-2);
  background: color-mix(in oklab, var(--text-3) 6%, transparent);
  border: 1px dashed color-mix(in oklab, var(--text-3) 35%, var(--border));
  border-radius: 8px;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease,
              border-color 120ms ease;
}
.skiplist-open-btn:hover {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: color-mix(in oklab, var(--accent) 40%, transparent);
  border-style: solid;
}
.skiplist-open-btn svg { opacity: 0.8; }
.skiplist-open-btn:hover svg { opacity: 1; }

/* ── Skip-list manager modal ───────────────────────────────────
   Full-screen backdrop + centered sheet, sharing the translucent-
   blur aesthetic of ``.confirm-backdrop``. Two sections stacked
   vertically (blacklist + whitelist) with independent scroll so a
   long blacklist never pushes the whitelist off the sheet. Each
   row is a compact pill with the word on the left and an X button
   on the right that calls ``user_skip_remove``. */
.skiplist-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.32);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 999998;
  display: flex; align-items: center; justify-content: center;
  animation: confirm-fade-in 160ms ease both;
}
.skiplist-panel {
  width: min(560px, calc(100vw - 48px));
  max-height: min(680px, calc(100vh - 96px));
  background: var(--panel-solid);
  color: var(--text);
  border-radius: 14px;
  box-shadow:
    0 30px 80px rgba(0,0,0,0.35),
    0 6px 18px rgba(0,0,0,0.18),
    0 0 0 1px rgba(0,0,0,0.06);
  display: flex; flex-direction: column;
  animation: confirm-pop-in 180ms cubic-bezier(0.22, 0.9, 0.3, 1) both;
  overflow: hidden;
}
[data-theme="dark"] .skiplist-panel {
  background: #2C2C2E;
  box-shadow:
    0 30px 80px rgba(0,0,0,0.55),
    0 6px 18px rgba(0,0,0,0.40),
    0 0 0 1px rgba(255,255,255,0.06);
}
.skiplist-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px 12px;
  border-bottom: 1px solid var(--border);
}
.skiplist-title {
  font-size: 14px; font-weight: 600;
  letter-spacing: -0.01em;
}
.skiplist-close {
  width: 26px; height: 26px;
  border-radius: 6px;
  border: none;
  background: transparent;
  color: var(--text-2);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.skiplist-close:hover { background: var(--selected); color: var(--text); }

.skiplist-section {
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
  overflow: hidden;
  display: flex; flex-direction: column;
  min-height: 0;
}
.skiplist-section:last-of-type { border-bottom: none; }
.skiplist-section-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 4px;
}
.skiplist-section-title {
  font-size: 12px; font-weight: 600;
  color: var(--text);
  letter-spacing: -0.005em;
}
.skiplist-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 18px;
  padding: 0 6px;
  background: var(--selected);
  color: var(--text-2);
  font-size: 11px; font-weight: 600;
  border-radius: 999px;
}
.skiplist-hint {
  font-size: 11px;
  color: var(--text-3);
  margin-bottom: 8px;
}
.skiplist-empty {
  font-size: 11.5px;
  color: var(--text-3);
  font-style: italic;
  padding: 10px 0;
}
.skiplist-items {
  display: flex; flex-wrap: wrap; gap: 6px;
  overflow-y: auto;
  max-height: 200px;
  padding: 2px;
}
.skiplist-item {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 4px 4px 10px;
  background: color-mix(in oklab, var(--text-3) 8%, transparent);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 11.5px;
  color: var(--text);
  max-width: 100%;
  transition: background 120ms ease, border-color 120ms ease;
}
.skiplist-item:hover {
  background: color-mix(in oklab, var(--accent) 10%, transparent);
  border-color: color-mix(in oklab, var(--accent) 30%, var(--border));
}
.skiplist-item-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 320px;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
}
.skiplist-remove {
  width: 20px; height: 20px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-3);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 120ms ease, color 120ms ease;
}
.skiplist-remove:hover {
  background: var(--red);
  color: #fff;
}

.skiplist-footer {
  display: flex; justify-content: flex-end;
  padding: 12px 20px;
  background: color-mix(in oklab, var(--text-3) 4%, transparent);
}

/* ── Blacklist Library modal ──────────────────────────────────────
   macOS Sequoia-style sheet, opened from the Library tab toolbar.
   Three vertically stacked sections (AI seed + manual add + current
   entries). Frosted backdrop, rounded 14px corners, soft layered
   shadow, NSColorWell-style accent on the icon chip. Tested at
   560-640px width — the chip grid wraps gracefully.

   Reuses ``confirm-fade-in`` / ``confirm-pop-in`` keyframes so all
   sheets in the app open with the same motion language. */
.bl-modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.34);
  backdrop-filter: blur(6px) saturate(140%);
  -webkit-backdrop-filter: blur(6px) saturate(140%);
  z-index: 999998;
  display: flex; align-items: center; justify-content: center;
  animation: confirm-fade-in 160ms ease both;
}
.bl-modal {
  width: min(640px, calc(100vw - 48px));
  max-height: min(82vh, 760px);
  background: var(--panel-solid);
  color: var(--text);
  border-radius: 14px;
  box-shadow:
    0 30px 80px rgba(0,0,0,0.35),
    0 6px 18px rgba(0,0,0,0.18),
    0 0 0 1px rgba(0,0,0,0.06);
  display: flex; flex-direction: column;
  overflow: hidden;
  animation: confirm-pop-in 180ms cubic-bezier(0.22, 0.9, 0.3, 1) both;
}
[data-theme="dark"] .bl-modal {
  background: #2C2C2E;
  box-shadow:
    0 30px 80px rgba(0,0,0,0.55),
    0 6px 18px rgba(0,0,0,0.40),
    0 0 0 1px rgba(255,255,255,0.06);
}

/* Header — icon chip + title/subtitle + close. The icon chip uses
   the system accent at 14% alpha as background with the accent itself
   as glyph — same treatment as macOS Settings.app section headers. */
.bl-modal-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
}
.bl-modal-head-l {
  display: flex; align-items: flex-start; gap: 12px;
  min-width: 0;
}
.bl-modal-head-icon {
  flex: 0 0 28px;
  width: 28px; height: 28px;
  border-radius: 8px;
  background: color-mix(in oklab, var(--accent) 14%, transparent);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  margin-top: 1px;
}
.bl-modal-title {
  font-size: 14px; font-weight: 600;
  letter-spacing: -0.012em;
  line-height: 1.25;
}
.bl-modal-sub {
  font-size: 11.5px;
  color: var(--text-2);
  margin-top: 3px;
  line-height: 1.4;
}
.bl-close {
  flex: 0 0 auto;
  width: 26px; height: 26px;
  border-radius: 6px;
  border: none;
  background: transparent;
  color: var(--text-2);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.bl-close:hover { background: var(--selected); color: var(--text); }

/* Body scrolls internally so the foot bar always pins to the
   sheet's bottom. Padding is on the section, not the body, so the
   scrollbar tracks tight to the edge. */
.bl-modal-body {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex; flex-direction: column;
}

.bl-section {
  padding: 16px 20px 18px;
  border-bottom: 1px solid var(--border);
}
.bl-section:last-child { border-bottom: none; }
.bl-section-head { margin-bottom: 10px; }
.bl-section-eyebrow {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 4px;
}
.bl-section-eyebrow svg { opacity: 0.9; }
.bl-section-title {
  font-size: 13px; font-weight: 600;
  letter-spacing: -0.008em;
}
.bl-section-hint {
  font-size: 11.5px;
  color: var(--text-2);
  margin-top: 4px;
  line-height: 1.45;
}
.bl-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 16px;
  padding: 0 5px;
  margin-left: 6px;
  background: color-mix(in oklab, var(--text-3) 14%, transparent);
  color: var(--text-2);
  font-size: 10px; font-weight: 700;
  border-radius: 999px;
  letter-spacing: 0;
  text-transform: none;
}

/* Input row — sets the input to flex-grow so the button sits flush
   on the right at a fixed width. Matches the visual weight of the
   sheet's title baseline. */
.bl-ai-row {
  display: flex; gap: 8px;
  align-items: center;
}
.bl-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 8px 12px;
  font-size: 13px;
  color: var(--text);
  background: var(--input-bg, var(--panel));
  border: 1px solid var(--border);
  border-radius: 8px;
  outline: none;
  transition: border-color 120ms ease, box-shadow 120ms ease;
  font-family: inherit;
}
.bl-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 22%, transparent);
}
.bl-input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
.bl-ai-btn { flex: 0 0 auto; white-space: nowrap; }

.bl-error {
  margin-top: 10px;
  padding: 8px 10px;
  font-size: 11.5px;
  color: var(--red, var(--mc-danger));
  background: color-mix(in oklab, var(--red, var(--mc-danger)) 8%, transparent);
  border: 1px solid color-mix(in oklab, var(--red, var(--mc-danger)) 24%, transparent);
  border-radius: 8px;
}

/* Spinner — pure CSS, 12px so it lines up with the button label.
   Borrowed from the existing translation-tab spinner to stay
   visually consistent. */
.bl-spinner {
  width: 12px; height: 12px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  display: inline-block;
  animation: bl-spin 700ms linear infinite;
}
@keyframes bl-spin { to { transform: rotate(360deg); } }

/* Suggestion sub-section — sits inside the AI section once results
   arrive. Small header + chip grid + confirm bar. */
.bl-suggest-head {
  display: flex; align-items: center; justify-content: space-between;
  margin: 14px 0 8px;
  font-size: 11px;
  color: var(--text-2);
}
.bl-suggest-count { font-weight: 600; color: var(--text); }
.bl-suggest-actions { display: flex; align-items: center; gap: 6px; }
.bl-link {
  background: none; border: none; padding: 0;
  color: var(--accent);
  font: inherit; font-size: 11px; font-weight: 500;
  cursor: pointer;
}
.bl-link:hover { text-decoration: underline; }
.bl-dot { color: var(--text-3); }

.bl-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  max-height: 200px;
  overflow-y: auto;
  padding: 2px;
}
.bl-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 11px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 11.5px;
  color: var(--text);
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease,
              color 120ms ease, transform 80ms ease;
  font-family: inherit;
  max-width: 100%;
}
.bl-chip:hover {
  background: color-mix(in oklab, var(--accent) 8%, var(--panel));
  border-color: color-mix(in oklab, var(--accent) 24%, var(--border));
}
.bl-chip:active { transform: scale(0.97); }
.bl-chip.on {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.bl-chip.on:hover {
  background: color-mix(in oklab, var(--accent) 88%, black);
}
.bl-chip-check { flex: 0 0 auto; }
.bl-chip-text {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 220px;
}

.bl-suggest-footer {
  display: flex; justify-content: flex-end;
  margin-top: 12px;
}

/* Current entries — pill tags with an X button on the right. Slightly
   smaller than chips so users can tell "what's already saved" apart
   from "what AI is proposing right now". */
.bl-section-list { background: color-mix(in oklab, var(--text-3) 3%, transparent); }
.bl-empty {
  font-size: 11.5px;
  color: var(--text-3);
  font-style: italic;
  padding: 8px 0 4px;
  line-height: 1.5;
}
.bl-tags {
  display: flex; flex-wrap: wrap; gap: 6px;
  max-height: 220px;
  overflow-y: auto;
  padding: 2px;
}
.bl-tag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 4px 3px 10px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 11.5px;
  color: var(--text);
  max-width: 100%;
  transition: background 120ms ease, border-color 120ms ease;
}
.bl-tag:hover {
  background: color-mix(in oklab, var(--red, var(--mc-danger)) 8%, var(--panel));
  border-color: color-mix(in oklab, var(--red, var(--mc-danger)) 24%, var(--border));
}
.bl-tag-text {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 260px;
}
.bl-tag-x {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--text-2);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
  padding: 0;
}
.bl-tag-x:hover {
  background: var(--red, var(--mc-danger));
  color: #fff;
}

.bl-modal-foot {
  display: flex; justify-content: flex-end;
  padding: 12px 20px;
  background: color-mix(in oklab, var(--text-3) 4%, transparent);
  border-top: 1px solid var(--border);
}

/* ── macOS-style confirmation dialog ───────────────────────────────
   Replaces the browser's ``confirm()`` chrome, which on QtWebEngine
   shows "Javascript Confirm — file:///…/app.html" in the titlebar.
   Centered sheet, translucent backdrop, NSAlert-ish icon + button
   layout (Cancel on the left, destructive default on the right). */
.confirm-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.32);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 999998;
  display: flex; align-items: center; justify-content: center;
  animation: confirm-fade-in 160ms ease both;
}
@keyframes confirm-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.confirm-panel {
  width: min(420px, calc(100vw - 48px));
  background: var(--panel-solid);
  color: var(--text);
  border-radius: 14px;
  box-shadow:
    0 30px 80px rgba(0,0,0,0.35),
    0 6px 18px rgba(0,0,0,0.18),
    0 0 0 1px rgba(0,0,0,0.06);
  padding: 22px 22px 16px 22px;
  display: grid;
  grid-template-columns: 52px 1fr;
  grid-template-rows: auto auto;
  column-gap: 18px;
  row-gap: 16px;
  animation: confirm-pop-in 180ms cubic-bezier(0.22, 0.9, 0.3, 1) both;
}
[data-theme="dark"] .confirm-panel {
  background: #2C2C2E;
  box-shadow:
    0 30px 80px rgba(0,0,0,0.55),
    0 6px 18px rgba(0,0,0,0.40),
    0 0 0 1px rgba(255,255,255,0.06);
}
@keyframes confirm-pop-in {
  from { opacity: 0; transform: translateY(8px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0)   scale(1);    }
}
.confirm-icon {
  grid-column: 1; grid-row: 1;
  width: 52px; height: 52px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in oklab, var(--accent) 16%, transparent);
  color: var(--accent);
}
.confirm-icon.destructive {
  background: color-mix(in oklab, var(--red) 16%, transparent);
  color: var(--red);
}
.confirm-body {
  grid-column: 2; grid-row: 1;
  min-width: 0;
  display: flex; flex-direction: column; gap: 6px;
  padding-top: 2px;
}
.confirm-title {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
  line-height: 1.3;
}
.confirm-message {
  font-size: 12.5px;
  color: var(--text-2);
  line-height: 1.45;
}
.confirm-actions {
  grid-column: 1 / span 2;
  grid-row: 2;
  display: flex; justify-content: flex-end; gap: 8px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
  margin-top: 4px;
}
.confirm-btn {
  min-width: 96px;
  height: 32px;
  padding: 0 16px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  border: 1px solid var(--border-strong);
  background: var(--bg-elev);
  color: var(--text);
  transition: background 120ms ease, border-color 120ms ease, transform 100ms ease;
}
.confirm-btn:hover   { background: color-mix(in oklab, var(--text) 6%, var(--bg-elev)); }
.confirm-btn:active  { transform: scale(0.98); }
.confirm-btn:focus-visible {
  outline: none;
  box-shadow: var(--ring);
}
.confirm-btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.confirm-btn.primary:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}
.confirm-btn.primary.destructive {
  background: var(--red);
  border-color: var(--red);
}
.confirm-btn.primary.destructive:hover {
  background: color-mix(in oklab, var(--red) 85%, black);
  border-color: color-mix(in oklab, var(--red) 85%, black);
}

/* ========== Progress bar ========== */
.progress-bar-wrap {
  position: relative;
  height: 22px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
.progress-bar-fill {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--accent), var(--green));
  border-radius: 8px;
  transition: width 300ms ease;
}
.progress-bar-label {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
  font-family: "JetBrains Mono", monospace;
}


/* Google/Apple style custom scroll for AutoFit */
.custom-scroll-style::-webkit-scrollbar { width: 8px; height: 8px; }
.custom-scroll-style::-webkit-scrollbar-track { background: transparent; }
.custom-scroll-style::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.2); border-radius: 10px; border: 2px solid var(--bg-elev); }
.custom-scroll-style::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.35); }

/* ─────────────────────────────────────────────────────
   Global backdrop-filter override — kill GPU-heavy blur
   trên 34" 2K fullscreen gây flicker liên tục. Mọi
   element có blur trước đây đều fall-back về solid bg.
   ───────────────────────────────────────────────────── */
*, *::before, *::after {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}


/* ─────────────────────────────────────────────────────
   Customer Support Chat — Apple/Intercom-style floating
   widget góc phải-dưới. Slide-in panel + chat bubbles.
   ───────────────────────────────────────────────────── */
.support-fab {
  position: fixed;
  right: 20px;
  bottom: 32px;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), #6366f1);
  color: #fff;
  border: none;
  cursor: pointer;
  z-index: 9000;
  box-shadow: 0 8px 24px -6px rgba(99, 102, 241, 0.45),
              0 4px 12px -4px rgba(0, 0, 0, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 200ms cubic-bezier(0.22, 0.61, 0.36, 1),
              box-shadow 200ms ease;
}
.support-fab:hover {
  transform: scale(1.06);
  box-shadow: 0 12px 32px -6px rgba(99, 102, 241, 0.6),
              0 6px 16px -4px rgba(0, 0, 0, 0.2);
}
.support-fab:active { transform: scale(0.96); }
.support-fab-dot {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--mc-danger);
  border: 2px solid #fff;
  box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
  animation: support-fab-pulse 1.4s infinite cubic-bezier(0.66, 0, 0, 1);
}
@keyframes support-fab-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); }
  70%  { box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); }
  100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
}
.support-chat-panel {
  position: fixed;
  right: 20px;
  bottom: 96px;
  width: 380px;
  max-width: calc(100vw - 40px);
  height: 540px;
  max-height: calc(100vh - 130px);
  background: var(--panel-solid, #fff);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: 0 20px 48px -12px rgba(0, 0, 0, 0.22),
              0 8px 16px -8px rgba(0, 0, 0, 0.12);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 9001;
  animation: support-panel-in 280ms cubic-bezier(0.22, 0.61, 0.36, 1);
  /* Composer Mode wow effect: panel breathes upward when user
     focuses the input — spring physics, soft glow accent. */
  transition: height 460ms cubic-bezier(0.34, 1.4, 0.64, 1),
              width  460ms cubic-bezier(0.34, 1.4, 0.64, 1),
              box-shadow 320ms ease,
              border-color 320ms ease,
              transform 460ms cubic-bezier(0.34, 1.4, 0.64, 1);
}
.support-chat-panel.is-composing {
  height: min(82vh, 760px);
  width: 440px;
  border-color: color-mix(in oklab, var(--accent) 40%, var(--border));
  box-shadow:
    0 28px 64px -14px color-mix(in oklab, var(--accent) 22%, rgba(0,0,0,0.25)),
    0 12px 24px -10px rgba(0, 0, 0, 0.18),
    0 0 0 4px color-mix(in oklab, var(--accent) 10%, transparent);
  transform: translateY(-2px);
}
@keyframes support-panel-in {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.support-chat-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  background: linear-gradient(180deg, var(--bg) 0%, var(--panel-solid) 100%);
}
.support-chat-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
}
.support-chat-close {
  width: 28px; height: 28px;
  border: none;
  background: transparent;
  color: var(--text-3);
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms ease, color 120ms ease;
}
.support-chat-close:hover {
  background: color-mix(in oklab, var(--text-3) 15%, transparent);
  color: var(--text);
}
.support-chat-list {
  flex: 1;
  overflow-y: auto;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--bg);
}
.support-chat-empty {
  padding: 24px;
  text-align: center;
  color: var(--text-3);
  font-size: 12.5px;
  font-style: italic;
}
.support-msg-row {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  max-width: 88%;
  animation: support-msg-in 220ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
@keyframes support-msg-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.support-msg-user {
  margin-left: auto;
  flex-direction: row-reverse;
}
.support-msg-agent { margin-right: auto; }
.support-msg-avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), #6366f1);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.support-msg-bubble {
  padding: 8px 12px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.45;
  max-width: 100%;
  word-break: break-word;
}
.support-msg-user .support-msg-bubble {
  background: var(--accent);
  color: #fff;
  border-bottom-right-radius: 4px;
}
.support-msg-agent .support-msg-bubble {
  background: var(--panel-solid, #fff);
  border: 1px solid var(--border);
  color: var(--text);
  border-bottom-left-radius: 4px;
}
.support-msg-author {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-3);
  margin-bottom: 2px;
}
.support-msg-text {
  white-space: pre-wrap;
}
.support-msg-time {
  font-size: 10px;
  opacity: 0.6;
  margin-top: 4px;
  text-align: right;
}
.support-msg-typing {
  display: flex;
  gap: 4px;
  padding: 10px 14px;
  background: var(--panel-solid, #fff);
  border: 1px solid var(--border);
  border-radius: 14px;
  border-bottom-left-radius: 4px;
}
.support-msg-typing span {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--text-3);
  animation: support-typing 1.2s infinite ease-in-out;
}
.support-msg-typing span:nth-child(2) { animation-delay: 0.15s; }
.support-msg-typing span:nth-child(3) { animation-delay: 0.3s; }
@keyframes support-typing {
  0%, 60%, 100% { opacity: 0.3; transform: translateY(0); }
  30%           { opacity: 1; transform: translateY(-4px); }
}
.support-chat-input-wrap {
  padding: 12px 14px 14px;
  border-top: 1px solid var(--border);
  background: var(--panel-solid, #fff);
}
.support-chat-input-shell {
  position: relative;
  display: flex;
  align-items: flex-end;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 6px 6px 6px 14px;
  transition: border 120ms ease, box-shadow 120ms ease;
}
.support-chat-input-shell {
  transition: border-color 320ms ease, box-shadow 320ms ease,
              padding 360ms cubic-bezier(0.34, 1.4, 0.64, 1);
}
.support-chat-input-shell:focus-within {
  border-color: var(--accent);
  box-shadow: var(--ring);
}
.is-composing .support-chat-input-shell {
  padding: 10px 8px 10px 16px;
}
.is-composing .support-chat-input {
  min-height: 88px;
  max-height: 240px;
  font-size: 14px;
  transition: min-height 460ms cubic-bezier(0.34, 1.4, 0.64, 1),
              max-height 460ms cubic-bezier(0.34, 1.4, 0.64, 1),
              font-size 320ms ease;
}
.is-composing .support-chat-send {
  width: 34px;
  height: 34px;
  transition: width 320ms cubic-bezier(0.34, 1.4, 0.64, 1),
              height 320ms cubic-bezier(0.34, 1.4, 0.64, 1);
}
.support-chat-input {
  flex: 1;
  border: none;
  background: transparent;
  padding: 6px 0;
  font-size: 13px;
  font-family: inherit;
  color: var(--text);
  resize: none;
  outline: none;
  min-height: 22px;
  max-height: 120px;
  line-height: 1.5;
  /* Hide native scrollbar arrows (▲▼) on overflow — auto-grow handles
     visual height, scrollbar only kicks in past max-height. */
  scrollbar-width: thin;
}
.support-chat-input::placeholder { color: var(--text-3); }
.support-chat-input::-webkit-scrollbar { width: 6px; }
.support-chat-input::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 3px;
}
.support-chat-send {
  width: 30px;
  height: 30px;
  border: none;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-left: 4px;
  transition: background 120ms ease, transform 120ms ease,
              opacity 120ms ease;
}
.support-chat-send:hover:not(:disabled) {
  background: var(--accent-hover);
  transform: scale(1.06);
}
.support-chat-send:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  background: var(--text-3);
}

/* ─────────────────────────────────────────────────────
   3-click help center: Home → Topic → Article
   ───────────────────────────────────────────────────── */
.support-view-stage {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: support-view-in 240ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
@keyframes support-view-in {
  from { opacity: 0; transform: translateX(8px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* Home view */
.support-home {
  flex: 1;
  overflow-y: auto;
  padding: 18px 18px 22px;
  background: var(--bg);
}
.support-hero {
  margin-bottom: 14px;
}
.support-hero-greeting {
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.01em;
  margin-bottom: 4px;
}
.support-hero-sub {
  font-size: 13px;
  color: var(--text-2);
}
.support-search-wrap {
  position: relative;
  margin-bottom: 18px;
}
.support-search-icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-3);
  pointer-events: none;
}
.support-search-input {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px 10px 34px;
  font-size: 13px;
  font-family: inherit;
  background: var(--panel-solid, #fff);
  color: var(--text);
  outline: none;
  transition: border 120ms ease, box-shadow 120ms ease;
}
.support-search-input:focus {
  border-color: var(--accent);
  box-shadow: var(--ring);
}
.support-search-input::placeholder { color: var(--text-3); }

.support-section-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-3);
  margin: 4px 0 10px;
}

/* Topic cards */
.support-topics {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
}
.support-topic-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--panel-solid, #fff);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  color: var(--text);
  transition: border 120ms ease, transform 120ms ease,
              box-shadow 120ms ease, background 120ms ease;
}
.support-topic-card:hover {
  border-color: var(--accent);
  background: var(--panel-hover, #fff);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}
.support-topic-icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  flex-shrink: 0;
}
.support-topic-text { flex: 1; min-width: 0; }
.support-topic-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 2px;
}
.support-topic-blurb {
  font-size: 11.5px;
  color: var(--text-2);
  line-height: 1.4;
}
.support-topic-arrow {
  color: var(--text-3);
  flex-shrink: 0;
  transition: transform 120ms ease, color 120ms ease;
}
.support-topic-card:hover .support-topic-arrow {
  color: var(--accent);
  transform: translateX(2px);
}

/* Search results / empty */
.support-results {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.support-empty {
  padding: 28px 14px;
  text-align: center;
  color: var(--text-3);
  font-size: 12.5px;
  line-height: 1.5;
}
.support-empty a {
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
}

/* Article cards (used in search results + topic view) */
.support-article-card {
  position: relative;
  display: block;
  width: 100%;
  text-align: left;
  padding: 12px 36px 12px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-solid, #fff);
  cursor: pointer;
  font-family: inherit;
  color: var(--text);
  transition: border 120ms ease, background 120ms ease,
              transform 120ms ease, box-shadow 120ms ease;
}
.support-article-card:hover {
  border-color: var(--accent);
  background: var(--panel-hover, #fff);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}
.support-article-meta {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: var(--text-3);
  margin-bottom: 4px;
}
.support-article-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 3px;
}
.support-article-preview {
  font-size: 11.5px;
  color: var(--text-2);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.support-article-arrow {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-3);
  transition: color 120ms ease, transform 120ms ease;
}
.support-article-card:hover .support-article-arrow {
  color: var(--accent);
  transform: translateY(-50%) translateX(2px);
}

/* Chat CTA on home */
.support-chat-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  margin-top: 16px;
  padding: 11px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-solid, #fff);
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: background 120ms ease, border 120ms ease, color 120ms ease;
}
.support-chat-cta:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* Topic & article view shell */
.support-view {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg);
}
.support-view-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--panel-solid, #fff);
}
.support-back {
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: var(--text-2);
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms ease, color 120ms ease;
  flex-shrink: 0;
}
.support-back:hover {
  background: color-mix(in oklab, var(--text-3) 15%, transparent);
  color: var(--text);
}
.support-view-title {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.support-view-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 18px 22px;
}
.support-view-blurb {
  font-size: 12.5px;
  color: var(--text-2);
  margin-bottom: 14px;
  line-height: 1.5;
}
.support-articles-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Article body */
.support-art-title {
  font-size: 17px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.01em;
  margin: 0 0 12px;
}
.support-art-content {
  font-size: 13px;
  line-height: 1.6;
  color: var(--text);
}
.support-art-p {
  margin: 0 0 8px;
}
.support-art-p b {
  font-weight: 600;
  color: var(--text);
}
.support-art-br {
  height: 8px;
}
.support-art-feedback {
  margin-top: 22px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-solid, #fff);
}
.support-art-fb-q {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-2);
  margin-bottom: 8px;
}
.support-art-fb-btns {
  display: flex;
  gap: 8px;
}
.support-art-fb-btn {
  padding: 6px 12px;
  font-size: 12px;
  font-family: inherit;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
  transition: border 120ms ease, background 120ms ease;
}
.support-art-fb-btn:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.support-art-fb-thanks {
  font-size: 12px;
  color: var(--text-2);
  font-style: italic;
}
.support-still-help {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  margin-top: 16px;
  padding: 11px 14px;
  border: none;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background 120ms ease, transform 120ms ease;
}
.support-still-help:hover {
  background: var(--accent-hover);
  transform: translateY(-1px);
}

/* ─────────────────────────────────────────────────────
   Subscription StatusBanner — 6 states machine (Tab 1 MVP6)
   Priority: payment_failed > downgrade_pending > quota_5h_exhausted
   > quota_month_exhausted > approaching_limit (70-95%) > none.
   ───────────────────────────────────────────────────── */
.sub-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-radius: 12px;
  margin-bottom: 16px;
  font-size: 13px;
  line-height: 1.45;
  font-weight: 500;
  animation: support-msg-in 320ms cubic-bezier(0.34, 1.4, 0.64, 1);
  border: 1px solid transparent;
}
.sub-banner-icon {
  font-size: 18px;
  flex-shrink: 0;
  line-height: 1;
}
.sub-banner-text { flex: 1; }
.sub-banner-action {
  flex-shrink: 0;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
  font-family: inherit;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: background 160ms ease, transform 100ms ease;
}
.sub-banner-action:active { transform: scale(0.96); }

.sub-banner-error {
  background: color-mix(in oklab, var(--red) 9%, var(--panel-solid, #fff));
  border-color: color-mix(in oklab, var(--red) 30%, transparent);
  color: var(--text);
}
.sub-banner-error .sub-banner-icon { color: var(--red); }
.sub-banner-error .sub-banner-action {
  background: var(--red);
  color: #fff;
}
.sub-banner-error .sub-banner-action:hover {
  background: color-mix(in oklab, var(--red) 88%, black);
}

.sub-banner-warn {
  background: color-mix(in oklab, var(--orange) 9%, var(--panel-solid, #fff));
  border-color: color-mix(in oklab, var(--orange) 30%, transparent);
  color: var(--text);
}
.sub-banner-warn .sub-banner-icon { color: var(--orange); }
.sub-banner-warn .sub-banner-action {
  background: var(--orange);
  color: #fff;
}
.sub-banner-warn .sub-banner-action:hover {
  background: color-mix(in oklab, var(--orange) 88%, black);
}

.sub-banner-info {
  background: color-mix(in oklab, var(--text-3) 6%, var(--panel-solid, #fff));
  border-color: var(--border);
  color: var(--text-2);
}
.sub-banner-info .sub-banner-icon { color: var(--text-3); }
.sub-banner-info .sub-banner-action {
  background: var(--panel-solid, #fff);
  color: var(--text);
  border: 1px solid var(--border);
}
.sub-banner-info .sub-banner-action:hover {
  background: var(--selected);
}

/* ─────────────────────────────────────────────────────
   Upgrade plan screen — Claude-style + Apple macOS
   Triggered từ avatar menu → Upgrade plan, hoặc Settings →
   Subscription → “So sánh chi tiết các gói”.
   ───────────────────────────────────────────────────── */
.upgrade-screen {
  /* Fill the full workspace width so the content can centre inside.
     Without ``width: 100%; box-sizing: border-box`` the screen shrinks
     to its intrinsic content (just the container max-width) and ends
     up hugging the workspace’s left edge. */
  width: 100%;
  min-height: 100%;
  padding: 48px 32px 64px;
  background: var(--bg);
  overflow-y: auto;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.upgrade-container {
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
}
.upgrade-header {
  text-align: center;
  margin-bottom: 36px;
}
.upgrade-title {
  font-size: 38px;
  font-weight: 700;
  letter-spacing: -0.025em;
  margin: 0 0 10px;
  color: var(--text);
  line-height: 1.1;
}
.upgrade-subtitle {
  font-size: 17px;
  color: var(--text-2);
  margin: 0 0 24px;
  line-height: 1.45;
}
.upgrade-toggle {
  display: inline-flex;
  background: var(--panel-solid, #fff);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px;
  gap: 0;
}
.upgrade-toggle-pill {
  padding: 7px 22px;
  font-size: 13px;
  font-weight: 500;
  font-family: inherit;
  border: none;
  background: transparent;
  color: var(--text-2);
  border-radius: 999px;
  cursor: pointer;
  transition: background 200ms ease, color 200ms ease,
              box-shadow 200ms ease;
}
.upgrade-toggle-pill:hover { color: var(--text); }
.upgrade-toggle-pill.is-on {
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  box-shadow: 0 4px 12px -2px color-mix(in oklab, var(--accent) 35%, transparent);
}

/* Plan grid */
.plan-grid {
  display: grid;
  gap: 16px;
  margin-bottom: 36px;
}
.plan-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr));
                max-width: 720px; margin-left: auto; margin-right: auto;
                margin-bottom: 36px; }
.plan-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.plan-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.plan-grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr));
                gap: 12px; }
.plan-grid-5 .plan-card { padding: 22px 18px 18px; }
.plan-grid-5 .plan-name { font-size: 18px; }
.plan-grid-5 .plan-price-num { font-size: 26px; }
@media (max-width: 1320px) {
  .plan-grid-5 { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 1100px) {
  .plan-grid-4 { grid-template-columns: repeat(2, 1fr); }
  .plan-grid-3 { grid-template-columns: repeat(2, 1fr); }
  .plan-grid-5 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 720px) {
  .plan-grid { grid-template-columns: 1fr !important; }
  .upgrade-title { font-size: 28px; }
}

.plan-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 28px 24px 22px;
  background: var(--panel-solid, #fff);
  border: 1px solid var(--border);
  border-radius: 18px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.03);
  transition: transform 200ms cubic-bezier(0.34, 1.4, 0.64, 1),
              box-shadow 200ms ease,
              border-color 200ms ease;
}
.plan-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 32px -8px rgba(0,0,0,0.12),
              0 4px 12px -4px rgba(0,0,0,0.06);
}
.plan-card.is-featured {
  border-color: color-mix(in oklab, var(--accent) 50%, var(--border));
  box-shadow:
    0 16px 40px -10px color-mix(in oklab, var(--accent) 20%, rgba(0,0,0,0.12)),
    0 4px 12px -4px rgba(0,0,0,0.06),
    0 0 0 1px color-mix(in oklab, var(--accent) 30%, transparent);
}
.plan-card.is-featured:hover {
  transform: translateY(-3px);
}
.plan-card.is-current {
  background: color-mix(in oklab, var(--text-3) 5%, var(--panel-solid, #fff));
  opacity: 0.92;
}

.plan-popular {
  position: absolute;
  top: -11px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--accent);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 4px 12px;
  border-radius: 999px;
  white-space: nowrap;
  box-shadow: 0 4px 10px -2px color-mix(in oklab, var(--accent) 40%, transparent);
}
.plan-head { margin-bottom: 18px; }
.plan-name {
  margin: 0 0 4px;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--text);
}
.plan-tag {
  font-size: 12.5px;
  color: var(--text-3);
  line-height: 1.4;
}
.plan-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  margin-bottom: 6px;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display",
                "Inter", sans-serif;
}
.plan-price-num {
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--text);
  line-height: 1;
}
.plan-price-unit {
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
  margin-left: 2px;
  letter-spacing: -0.01em;
}
.plan-price-per {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-3);
  margin-left: 4px;
}
.plan-price-custom {
  font-size: 24px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.015em;
}
.plan-min {
  font-size: 11.5px;
  color: var(--text-3);
  margin-bottom: 16px;
}
.plan-cta {
  width: 100%;
  height: 46px;
  border: 1px solid var(--red);
  background: var(--red);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  border-radius: 10px;
  cursor: pointer;
  margin-top: 8px;
  margin-bottom: 22px;
  letter-spacing: 0.2px;
  box-shadow: 0 2px 8px color-mix(in oklab, var(--red) 22%, transparent);
  transition: background 160ms ease, border-color 160ms ease,
              color 160ms ease, transform 100ms ease,
              box-shadow 160ms ease;
}
.plan-cta:hover:not(.is-disabled) {
  background: color-mix(in oklab, var(--red) 88%, black);
  border-color: color-mix(in oklab, var(--red) 88%, black);
  box-shadow: 0 4px 14px color-mix(in oklab, var(--red) 38%, transparent);
  transform: translateY(-1px);
}
.plan-cta:active:not(.is-disabled) { transform: scale(0.98); }
.plan-cta.is-primary {
  background: var(--red);
  color: #fff;
  border-color: var(--red);
}
.plan-cta.is-primary:hover {
  background: color-mix(in oklab, var(--red) 88%, black);
  border-color: color-mix(in oklab, var(--red) 88%, black);
}
.plan-cta.is-disabled {
  background: transparent;
  color: var(--text-3);
  border: 1px dashed var(--border-strong);
  cursor: default;
  box-shadow: none;
}
.plan-cta.is-disabled:hover {
  background: transparent;
  color: var(--text-3);
  border-color: var(--border-strong);
  transform: none;
  box-shadow: none;
}

/* Hide app titlebar text while checkout is open — keeps focus on
   the inline checkout flow without the redundant "Tab 1 — Subscription"
   label competing with the back arrow + plan title. */
body.checkout-active .title { visibility: hidden; }

/* ── Inline checkout (pricing screen) ───────────────────────────
   Back arrow top-left, plan title, 2 cycle radio-cards, order
   details card, info banner, payment form with method selector,
   big Subscribe button. */
.checkout-view {
  position: relative; min-height: 100%; width: 100%;
  padding: 0 0 60px;
  background: var(--bg);
  overflow-y: auto;
}
/* Back button — sticky to top of the scroll container so it stays
   reachable while the user scrolls down the form. Sits in its own
   sticky bar so background covers content scrolling beneath. */
.checkout-back {
  position: sticky; top: 0; z-index: 10;
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  margin: 14px 0 0 22px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 50%;
  cursor: pointer;
  color: var(--text);
  box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  transition: background 0.15s, border-color 0.15s, transform 0.05s;
}
.checkout-back:hover {
  background: var(--selected);
  border-color: var(--text-2);
}
.checkout-back:active { transform: scale(0.95); }
.checkout-wrap {
  max-width: 540px; margin: 0 auto;
  padding-top: 28px;
}
.checkout-title {
  font-size: 26px; font-weight: 700; letter-spacing: -0.5px;
  margin: 0 0 22px;
  color: var(--text);
}
.checkout-cycle-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  margin-bottom: 26px;
}
.checkout-cycle-card {
  position: relative;
  display: flex; gap: 12px; align-items: flex-start;
  padding: 14px 16px;
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 12px;
  cursor: pointer; text-align: left;
  font-family: inherit;
  transition: border-color 0.15s, background 0.15s;
}
.checkout-cycle-card:hover { border-color: var(--border-strong); }
.checkout-cycle-card.is-selected {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: 0 0 0 1px var(--accent) inset;
}
.checkout-cycle-dot {
  flex-shrink: 0; width: 18px; height: 18px;
  border-radius: 50%;
  border: 2px solid var(--border-strong);
  background: var(--bg-elev);
  margin-top: 1px;
  position: relative;
}
.checkout-cycle-card.is-selected .checkout-cycle-dot {
  border-color: var(--accent);
}
.checkout-cycle-card.is-selected .checkout-cycle-dot::after {
  content: ""; position: absolute; inset: 2px;
  background: var(--accent); border-radius: 50%;
}
.checkout-cycle-body { flex: 1; min-width: 0; }
.checkout-cycle-label {
  font-size: 13.5px; font-weight: 600; color: var(--text);
  margin-bottom: 4px;
}
.checkout-cycle-price {
  font-size: 13px; color: var(--text-2); line-height: 1.4;
}
.checkout-cycle-vat { color: var(--text-3); font-size: 12.5px; }
.checkout-cycle-badge {
  position: absolute; top: 12px; right: 12px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.02em;
  background: var(--accent-soft); color: var(--accent);
  padding: 3px 8px; border-radius: 999px;
}

/* Order details + Payment form cards */
.checkout-card {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 14px; padding: 18px 20px;
  margin-bottom: 18px;
}
.checkout-card-title {
  font-size: 15px; font-weight: 600; color: var(--text);
  margin-bottom: 14px;
}
.checkout-line {
  display: flex; justify-content: space-between; align-items: flex-start;
  padding: 8px 0; font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.checkout-line-title { color: var(--text); }
.checkout-line-sub { color: var(--text-3); font-size: 12px; margin-top: 2px; }
.checkout-line-price { color: var(--text); white-space: nowrap; margin-left: 16px; }
.checkout-bold { font-weight: 700; }
.checkout-divider {
  height: 1px; background: var(--border);
  margin: 6px 0;
}

/* Auto-renew info banner */
.checkout-banner {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 14px 16px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  margin-bottom: 18px;
  font-size: 12.5px; color: var(--text-2); line-height: 1.5;
}
.checkout-banner svg { flex-shrink: 0; margin-top: 1px; color: var(--text-3); }

/* Form fields — taller, more breathing room */
.checkout-field {
  display: flex; flex-direction: column; gap: 8px;
  margin-bottom: 16px;
}
.checkout-field > label {
  font-size: 13.5px; font-weight: 500; color: var(--text);
}
.checkout-field input[type="text"],
.checkout-field input[type="email"],
.checkout-field select {
  width: 100%;
  padding: 13px 14px;
  height: 46px;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: var(--bg-elev);
  color: var(--text);
  font-size: 14.5px;
  font-family: inherit;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.checkout-field input:focus,
.checkout-field select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.checkout-field select {
  appearance: none; -webkit-appearance: none;
  padding-right: 36px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2386868B' stroke-width='2'><path d='m6 9 6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  cursor: pointer;
}
.checkout-field-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
}
.checkout-hint {
  font-size: 12px; color: var(--text-3); line-height: 1.5;
  margin-bottom: 4px;
}

/* Payment method selector (Card / Wallet) */
.checkout-method-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  margin-bottom: 16px;
}
.checkout-method-card {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px;
  height: 60px;
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  cursor: pointer; font-family: inherit;
  font-size: 14px; font-weight: 500; color: var(--text);
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}
.checkout-method-card:hover { border-color: var(--text-2); }
.checkout-method-card.is-selected {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent) inset;
}
.checkout-method-card svg { flex-shrink: 0; }
.checkout-wallet-hint {
  font-size: 13px; color: var(--text-2);
  padding: 12px 14px;
  background: var(--bg);
  border: 1px dashed var(--border-strong); border-radius: 10px;
  margin-bottom: 16px; line-height: 1.5;
}

/* Card number with brand strip */
.checkout-card-input {
  position: relative;
  display: flex; align-items: center;
  border: 1px solid var(--border-strong); border-radius: 10px;
  background: var(--bg-elev);
  padding-right: 12px;
  height: 46px;
}
.checkout-card-input:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.checkout-card-input input {
  flex: 1; min-width: 0;
  border: none !important; background: transparent !important;
  padding: 0 14px !important;
  height: 100% !important;
  font-size: 14.5px !important;
}
.checkout-card-input input:focus { box-shadow: none !important; }
.checkout-brands { display: flex; gap: 4px; flex-shrink: 0; }
.cb {
  font-size: 8.5px; font-weight: 800;
  padding: 3px 6px; border-radius: 4px;
  border: 1px solid var(--border-strong);
  background: #fff; color: #1a1a1a;
  letter-spacing: 0.04em;
  min-width: 28px; text-align: center;
}
.cb-visa { color: #1A1F71; }
.cb-mc { color: #EB001B; }
.cb-amex { color: #006FCF; }
.cb-jcb { color: #0E4C96; }

/* Checkbox-as-radio row */
.checkout-radio {
  display: flex; gap: 10px; align-items: flex-start;
  font-size: 13px; color: var(--text-2);
  padding: 6px 0;
  cursor: pointer;
  line-height: 1.5;
}
.checkout-radio input[type="checkbox"] {
  margin-top: 2px;
  width: 16px; height: 16px;
  accent-color: var(--accent);
  flex-shrink: 0;
  cursor: pointer;
}
.checkout-radio a { color: var(--accent); text-decoration: underline; }

.checkout-error {
  color: var(--red); font-size: 13px;
  padding: 10px 12px;
  background: color-mix(in oklab, var(--red) 8%, transparent);
  border: 1px solid color-mix(in oklab, var(--red) 30%, var(--border));
  border-radius: 10px;
  margin: 8px 0;
}

.checkout-subscribe {
  width: 100%;
  padding: 16px 20px;
  height: 54px;
  background: #8E8E93;
  color: #fff;
  border: none; border-radius: 12px;
  font-size: 16px; font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  margin-top: 18px;
  letter-spacing: 0.2px;
  transition: background 0.15s, transform 0.05s;
}
.checkout-subscribe:not(:disabled) {
  background: var(--text);
}
.checkout-subscribe:not(:disabled):hover {
  background: color-mix(in oklab, var(--text) 88%, #fff);
}
.checkout-subscribe:active:not(:disabled) { transform: scale(0.99); }
.checkout-subscribe:disabled {
  cursor: not-allowed;
}

/* Custom-users input on the Business "contact" plan card.
   Fills in between plan-head and plan-price; entering ≥5 swaps the
   card from contact mode to a fully priced layout. */
.biz-custom-input {
  display: flex; flex-direction: column; gap: 6px;
  margin: 4px 0 14px;
}
.biz-custom-input > label {
  font-size: 12px; font-weight: 600;
  color: var(--text-2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.biz-custom-input-field {
  width: 100%;
  padding: 11px 14px;
  height: 44px;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: var(--bg-elev);
  color: var(--text);
  font-size: 15px; font-weight: 600;
  font-family: inherit;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
  -moz-appearance: textfield;
}
.biz-custom-input-field::-webkit-outer-spin-button,
.biz-custom-input-field::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
.biz-custom-input-field:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.biz-custom-warn {
  font-size: 11.5px; color: var(--orange);
  line-height: 1.4;
}

/* ═══════════════════════════════════════════════════════════════════
   Role info — macOS-style portal popover
   ═══════════════════════════════════════════════════════════════════
   The (i) trigger lives inside the plan card; the popup is portal-
   rendered to <body> and positioned via inline top/left (computed by
   JS against the trigger). This means NO parent can ever clip it —
   not the card, not the screen container, not the page wrapper.

   Visual language: native macOS popover.
     - Translucent panel with backdrop-filter
     - Layered shadow (close + ambient) for depth
     - Subtle 1px border at the panel edge
     - Color-coded role chips (cyan/violet/pink) for fast scan
     - Spring-like scale-in animation (180ms)
     - Inverted in dark mode without losing the glassy feel
   ─────────────────────────────────────────────────────────────────── */

.biz-feat-roles {
  display: flex;
  align-items: center;
  gap: 8px;
  position: relative;
}

/* Trigger pill — sized to feel clickable but visually quiet until hover. */
.role-info-btn {
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: var(--bg-elev);
  color: var(--text-2);
  font-size: 11px;
  font-weight: 700;
  font-style: italic;
  font-family: "New York", Georgia, "Times New Roman", serif;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  line-height: 1;
  transition:
    background 0.18s cubic-bezier(.2,.8,.2,1),
    color      0.18s cubic-bezier(.2,.8,.2,1),
    border-color 0.18s cubic-bezier(.2,.8,.2,1),
    transform  0.12s cubic-bezier(.2,.8,.2,1),
    box-shadow 0.18s cubic-bezier(.2,.8,.2,1);
}
.role-info-btn:hover {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent);
  transform: translateY(-1px);
  box-shadow: 0 4px 10px -4px color-mix(in oklab, var(--accent) 40%, transparent);
}
.role-info-btn:active { transform: translateY(0); }
.role-info-btn.is-on {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
  box-shadow: 0 6px 14px -4px color-mix(in oklab, var(--accent) 50%, transparent);
}

/* ── Popup panel ───────────────────────────────────────────────────── */
.role-pop {
  position: fixed;
  z-index: 9999;
  /* Translucent vibrancy — falls back gracefully if backdrop-filter
     isn't supported (older Qt WebEngine builds). */
  background: color-mix(in oklab, var(--panel-solid) 92%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(24px);
  backdrop-filter: saturate(180%) blur(24px);
  border: 1px solid color-mix(in oklab, var(--border) 80%, transparent);
  border-radius: 14px;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.5) inset,
    0 24px 60px -16px rgba(0,0,0,0.30),
    0 8px 24px -8px rgba(0,0,0,0.18),
    0 0 0 0.5px rgba(0,0,0,0.06);
  color: var(--text);
  font-size: 13px;
  line-height: 1.5;
  overflow: hidden;
  /* Spring fade-in */
  animation: rolePopIn 180ms cubic-bezier(.2,.9,.25,1.05);
  transform-origin: var(--origin, left center);
}
.role-pop-right  { --origin: left center; }
.role-pop-left   { --origin: right center; }
.role-pop-below  { --origin: top center; }

[data-theme="dark"] .role-pop {
  background: color-mix(in oklab, var(--panel-solid) 88%, transparent);
  box-shadow:
    0 1px 0 rgba(255,255,255,0.04) inset,
    0 24px 60px -16px rgba(0,0,0,0.65),
    0 8px 24px -8px rgba(0,0,0,0.45),
    0 0 0 0.5px rgba(255,255,255,0.04);
}

@keyframes rolePopIn {
  0%   { opacity: 0; transform: scale(0.94); }
  60%  { opacity: 1; }
  100% { opacity: 1; transform: scale(1); }
}

/* ── Arrow ───────────────────────────────────────────────────────────
   Inline-styled top/left from JS to align with the trigger center,
   regardless of how the popup got clamped vertically. */
.role-pop-arrow {
  position: absolute;
  width: 12px; height: 12px;
  background: inherit;
  border: 1px solid color-mix(in oklab, var(--border) 80%, transparent);
  transform: rotate(45deg);
  pointer-events: none;
}
.role-pop-right  .role-pop-arrow {
  left: -7px;
  border-right: none; border-top: none;
  margin-top: -6px;
}
.role-pop-left   .role-pop-arrow {
  right: -7px;
  border-left: none; border-bottom: none;
  margin-top: -6px;
}
.role-pop-below  .role-pop-arrow {
  top: -7px;
  border-right: none; border-bottom: none;
  margin-left: -6px;
}

/* ── Header bar ───────────────────────────────────────────────────── */
.role-pop-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px 8px;
  border-bottom: 1px solid color-mix(in oklab, var(--border) 60%, transparent);
}
.role-pop-title {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--text-2);
}
.role-pop-close {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-3);
  font-size: 16px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.role-pop-close:hover {
  background: var(--selected);
  color: var(--text);
}

/* ── Body ────────────────────────────────────────────────────────── */
.role-pop-body {
  padding: 12px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.role-pop-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.role-pop-row-head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.role-chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.3px;
  line-height: 1.3;
  border: 1px solid transparent;
}
.chip-owner {
  background: color-mix(in oklab, var(--purple) 18%, transparent);
  color: var(--purple);
  border-color: color-mix(in oklab, var(--purple) 35%, transparent);
}
.chip-admin {
  background: color-mix(in oklab, var(--accent) 14%, transparent);
  color: var(--accent);
  border-color: color-mix(in oklab, var(--accent) 30%, transparent);
}
.chip-member {
  background: color-mix(in oklab, var(--green) 14%, transparent);
  color: var(--green);
  border-color: color-mix(in oklab, var(--green) 30%, transparent);
}
.role-pop-desc {
  font-size: 12.5px;
  color: var(--text-2);
  line-height: 1.55;
  /* Indent slightly so the description visually attaches to the chip
     above without needing a separator line. */
  padding-left: 2px;
}
.role-info-row {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.role-info-row b {
  font-size: 12px;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 0.2px;
}
.role-info-row span {
  color: var(--text-2);
  font-size: 12px;
  font-weight: 400;
}

/* Cycle toggle pill — larger, more prominent (in-card) */
.pc-cycle-pill {
  display: inline-flex;
  background: var(--selected, rgba(0,0,0,0.06));
  border-radius: 999px;
  padding: 4px;
  gap: 0;
}
.pc-cycle-pill-btn {
  border: none;
  background: transparent;
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 12.5px;
  font-family: inherit;
  font-weight: 500;
  color: var(--text-2);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  transition: background 160ms ease, color 160ms ease, box-shadow 160ms ease;
  white-space: nowrap;
}
.pc-cycle-pill-btn.is-on {
  background: var(--bg-elev, #fff);
  color: var(--text);
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(0,0,0,0.10), 0 0 0 0.5px rgba(0,0,0,0.04);
}
.pc-cycle-pill-save {
  font-size: 10.5px;
  font-weight: 700;
  background: var(--green);
  color: #fff;
  padding: 2px 7px;
  border-radius: 999px;
  letter-spacing: 0.02em;
}
.plan-features {
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 13px;
  color: var(--text-2);
  line-height: 1.55;
}
.plan-features li {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 8px;
}
.plan-feat-check {
  color: var(--accent);
  flex-shrink: 0;
  margin-top: 2px;
}
.is-current .plan-feat-check { color: var(--text-3); }

/* Footer / disclaimers */
.upgrade-footer {
  text-align: center;
  margin-top: 8px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.upgrade-compare {
  display: inline-block;
  font-size: 13.5px;
  color: var(--accent);
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  margin-bottom: 18px;
}
.upgrade-compare:hover { text-decoration: underline; }
.upgrade-disclaimers {
  display: flex;
  justify-content: center;
  gap: 28px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--text-3);
  margin-bottom: 18px;
}
.upgrade-disclaimers span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.upgrade-fineprint {
  font-size: 11px;
  color: var(--text-3);
  line-height: 1.5;
  max-width: 720px;
  margin: 0 auto;
  text-align: center;
  font-style: italic;
  opacity: 0.85;
}

/* Confirm upgrade modal — Apple-style sheet */
.upgrade-modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.42);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center;
  z-index: 100200;
  animation: support-panel-in 240ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.upgrade-modal {
  background: var(--panel-solid, #fff);
  border-radius: 18px;
  width: 480px;
  max-width: calc(100vw - 40px);
  padding: 26px 28px 22px;
  border: 1px solid var(--border);
  box-shadow: 0 32px 64px -16px rgba(0,0,0,0.32);
  color: var(--text);
}
.upgrade-modal-title {
  margin: 0 0 14px;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.015em;
}
.upgrade-modal-error {
  margin-top: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  background: color-mix(in oklab, var(--red) 12%, transparent);
  color: var(--red);
  font-size: 12.5px;
}
.upgrade-modal-loading {
  padding: 24px;
  text-align: center;
  color: var(--text-3);
  font-size: 13px;
}
.upgrade-modal-row-light {
  font-size: 12.5px;
  color: var(--text-2);
  margin-bottom: 14px;
}
.upgrade-modal-prorate,
.upgrade-modal-firsttime {
  padding: 14px 16px;
  background: var(--bg);
  border-radius: 12px;
  font-size: 13px;
}
.upgrade-modal-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 0;
  font-size: 13px;
  color: var(--text-2);
}
.upgrade-modal-row.total {
  color: var(--text);
}
.upgrade-modal-row.total b {
  font-size: 14px;
}
.upgrade-modal-divider {
  height: 1px;
  background: var(--border);
  margin: 8px 0;
}
.upgrade-modal-micro {
  font-size: 10.5px;
  font-weight: 500;
  color: var(--text-3);
  margin-left: 6px;
}
.upgrade-modal-next {
  margin-top: 12px;
  font-size: 12px;
  color: var(--text-3);
}
.upgrade-modal-method {
  margin-top: 12px;
  font-size: 12.5px;
  color: var(--text-2);
}
.upgrade-modal-change-card {
  color: var(--accent);
  font-size: 11.5px;
  margin-left: 6px;
  cursor: pointer;
  text-decoration: none;
}
.upgrade-modal-downgrade-warn ul {
  margin: 0;
  padding-left: 22px;
  font-size: 12.5px;
  color: var(--text-2);
  line-height: 1.6;
}
.upgrade-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 22px;
}
.upgrade-modal-btn-cancel,
.upgrade-modal-btn-confirm {
  padding: 9px 18px;
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  border-radius: 10px;
  cursor: pointer;
  transition: background 160ms ease, border-color 160ms ease,
              opacity 160ms ease;
}
.upgrade-modal-btn-cancel {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-2);
}
.upgrade-modal-btn-cancel:hover {
  background: var(--selected);
  color: var(--text);
}
.upgrade-modal-btn-confirm {
  background: var(--accent);
  border: none;
  color: #fff;
}
.upgrade-modal-btn-confirm:hover:not(:disabled) {
  background: var(--accent-hover);
}
.upgrade-modal-btn-confirm:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* History CTA on home (secondary, below primary chat CTA) */
.support-history-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  margin-top: 8px;
  padding: 9px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: transparent;
  color: var(--text-2);
  font-size: 12.5px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: background 120ms ease, border 120ms ease, color 120ms ease;
}
.support-history-cta:hover {
  background: var(--panel-solid, #fff);
  border-color: var(--border-strong);
  color: var(--text);
}

.support-info-banner {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 12px;
  padding: 10px 12px;
  background: var(--accent-soft);
  border: 1px solid color-mix(in oklab, var(--accent) 25%, transparent);
  border-radius: 10px;
  font-size: 11.5px;
  color: var(--text-2);
  line-height: 1.45;
}
.support-info-banner b { color: var(--text); }
.support-info-icon {
  font-size: 14px;
  line-height: 1;
  flex-shrink: 0;
  margin-top: 1px;
}

/* Tickets list */
.support-tickets-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
}
.support-ticket-card {
  display: block;
  width: 100%;
  text-align: left;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-solid, #fff);
  cursor: pointer;
  font-family: inherit;
  color: var(--text);
  transition: border 120ms ease, background 120ms ease,
              transform 120ms ease, box-shadow 120ms ease;
}
.support-ticket-card:hover {
  border-color: var(--accent);
  background: var(--panel-hover, #fff);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}
.support-ticket-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}
.support-ticket-id {
  font-family: "JetBrains Mono", "SF Mono", Consolas, monospace;
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0.02em;
}
.support-ticket-status {
  font-size: 10.5px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.support-ticket-status.status-open {
  background: var(--accent-soft);
  color: var(--accent);
}
.support-ticket-status.status-awaiting_reply {
  background: color-mix(in oklab, var(--orange) 18%, transparent);
  color: var(--orange);
}
.support-ticket-status.status-resolved {
  background: color-mix(in oklab, var(--green) 18%, transparent);
  color: var(--green);
}
.support-ticket-preview {
  font-size: 12.5px;
  color: var(--text-2);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-bottom: 8px;
}
.support-ticket-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 11px;
  color: var(--text-3);
}
.support-ticket-date { white-space: nowrap; }
.support-ticket-rating { display: inline-flex; gap: 1px; }
.support-ticket-rating .star-on  { color: #FFB400; }
.support-ticket-rating .star-off { color: var(--border-strong); }
.support-ticket-norating {
  font-style: italic;
  font-size: 10.5px;
  color: var(--text-3);
}

/* Topic-interest tag — what user was reading before chat */
.support-ticket-interest {
  margin-top: 6px;
  font-size: 11px;
  color: var(--accent);
  font-weight: 500;
  padding: 3px 8px;
  background: var(--accent-soft);
  border-radius: 6px;
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Legacy interest banner — replaced by .support-interest-quote.
   Kept rules removed; selectors no longer referenced in JSX. */

/* Chat header — Apple-style: back + mono ticket chip + dot status
   + Đánh giá. Tighter spacing, single-row, no uppercase pills. */
.support-chat-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--panel-solid, #fff);
}
.support-chat-meta {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
  min-width: 0;
}
.support-tk-chip {
  font-family: "JetBrains Mono", "SF Mono", Consolas, monospace;
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0.02em;
  background: color-mix(in oklab, var(--text-3) 10%, transparent);
  border: none;
  border-radius: 6px;
  padding: 3px 8px;
  cursor: pointer;
  align-self: flex-start;
  font-family: "JetBrains Mono", "SF Mono", Consolas, monospace;
  transition: background 120ms ease;
}
.support-tk-chip:hover {
  background: color-mix(in oklab, var(--text-3) 20%, transparent);
}
.support-tk-status {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--text-3);
}
.support-status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
}
.support-status-dot.status-open {
  background: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 18%, transparent);
}
.support-status-dot.status-awaiting_reply {
  background: var(--orange);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--orange) 18%, transparent);
  animation: support-status-pulse 1.6s infinite;
}
.support-status-dot.status-resolved {
  background: var(--green);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--green) 18%, transparent);
}
@keyframes support-status-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in oklab, var(--orange) 50%, transparent); }
  70%  { box-shadow: 0 0 0 6px color-mix(in oklab, var(--orange) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--orange) 0%, transparent); }
}
.support-status-label {
  font-weight: 500;
  letter-spacing: 0.01em;
}
.support-chat-resolve {
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-2);
  font-size: 11px;
  font-weight: 600;
  font-family: inherit;
  padding: 6px 12px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition: border 120ms ease, background 120ms ease, color 120ms ease,
              transform 120ms ease;
  flex-shrink: 0;
}
.support-chat-resolve:hover {
  border-color: var(--green);
  background: color-mix(in oklab, var(--green) 12%, transparent);
  color: var(--green);
  transform: translateY(-1px);
}

/* Quote card — compact 1-line interest reference at thread top */
.support-interest-quote {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  margin: 0 6px 6px;
  background: color-mix(in oklab, var(--purple) 8%, var(--panel-solid, #fff));
  border-radius: 10px;
  border-left: 3px solid var(--purple);
  font-size: 12px;
  color: var(--text-2);
  line-height: 1.4;
}
.support-interest-quote-arrow {
  color: var(--purple);
  font-weight: 700;
  flex-shrink: 0;
}
.support-interest-quote-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.support-interest-quote-text b { color: var(--text); font-weight: 600; }
.support-interest-quote-topic { color: var(--text-3); }

/* Rating widget */
.support-stars {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.support-star {
  border: none;
  background: transparent;
  color: var(--border-strong);
  cursor: pointer;
  padding: 2px;
  font-family: inherit;
  transition: color 100ms ease, transform 100ms ease;
}
.support-star.is-on   { color: #FFB400; }
.support-star:not(.is-readonly):hover { transform: scale(1.15); }
.support-star.is-readonly { cursor: default; }
.support-star:disabled { cursor: default; }

.support-rating-card {
  background: var(--panel-solid, #fff);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  margin: 4px auto 4px;
  width: 100%;
  max-width: 96%;
  box-shadow: var(--shadow-sm);
  animation: support-msg-in 240ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.support-rating-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 10px;
  text-align: center;
}
.support-rating-comment {
  width: 100%;
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12px;
  font-family: inherit;
  background: var(--bg);
  color: var(--text);
  resize: vertical;
  min-height: 60px;
  outline: none;
  transition: border 120ms ease, box-shadow 120ms ease;
}
.support-rating-comment:focus {
  border-color: var(--accent);
  box-shadow: var(--ring);
}
.support-rating-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 10px;
}
.support-rating-skip,
.support-rating-submit {
  padding: 7px 14px;
  font-size: 12px;
  font-weight: 600;
  font-family: inherit;
  border-radius: 8px;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease,
              border 120ms ease, opacity 120ms ease;
}
.support-rating-skip {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-2);
}
.support-rating-skip:hover {
  background: var(--panel-hover, #fff);
  color: var(--text);
}
.support-rating-submit {
  background: var(--accent);
  border: 1px solid var(--accent);
  color: #fff;
}
.support-rating-submit:hover:not(:disabled) {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}
.support-rating-submit:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.support-rating-done {
  background: color-mix(in oklab, var(--green) 8%, var(--panel-solid, #fff));
  border-color: color-mix(in oklab, var(--green) 30%, var(--border));
  text-align: center;
}
.support-rating-comment-readonly {
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-2);
  font-style: italic;
}
.support-rating-time {
  margin-top: 6px;
  font-size: 10.5px;
  color: var(--text-3);
}

/* ─────────────────────────────────────────────────────────────────
   Tab 5 Marketplace v2.2 — MVP1 (post job wizard)
   ───────────────────────────────────────────────────────────────── */

/* Marketplace screens phải claim full flex height + cho phép
   nội dung scroll dọc — nếu không content > viewport sẽ bị cắt
   ở cuối (parent .main là flex, không có overflow auto). */
.mkt-home,
.mkt-browse,
.mkt-placeholder {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
.mkt-home {
  max-width: 1100px;
  margin: 0 auto;
  padding: 32px 24px 80px;
}

.mkt-hero { text-align: center; padding: 48px 24px 32px; }
.mkt-hero-eyebrow {
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--accent); margin-bottom: 12px;
}
.mkt-hero-title {
  font-size: 36px; font-weight: 700; line-height: 1.15;
  margin: 0 0 14px; letter-spacing: -0.02em;
}
.mkt-hero-sub {
  font-size: 15px; color: var(--text-2);
  max-width: 720px; margin: 0 auto 28px; line-height: 1.55;
}
.mkt-role-switch {
  display: inline-flex; background: var(--rail);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 4px; gap: 4px; margin-bottom: 24px;
}
.mkt-role-pill {
  padding: 8px 18px; border: none; background: transparent;
  border-radius: 999px; font-size: 13px; font-weight: 500;
  color: var(--text-2); cursor: pointer;
  transition: all 180ms ease;
}
.mkt-role-pill.is-on {
  background: var(--panel-solid); color: var(--text);
  box-shadow: var(--shadow-sm);
}
.mkt-cta-row {
  display: flex; justify-content: center; gap: 12px;
  flex-wrap: wrap;
}
.mkt-cta-primary {
  padding: 14px 28px; background: var(--accent);
  color: #fff; border: none; border-radius: 12px;
  font-size: 15px; font-weight: 600; cursor: pointer;
  transition: background 180ms ease;
}
.mkt-cta-primary:hover { background: var(--accent-hover); }
.mkt-cta-secondary {
  padding: 14px 24px; background: var(--panel-solid);
  color: var(--text); border: 1px solid var(--border-strong);
  border-radius: 12px; font-size: 14px; font-weight: 500;
  cursor: pointer;
}
.mkt-pillars {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 16px; margin-top: 56px;
}
.mkt-pillar {
  background: var(--panel-solid); border: 1px solid var(--border);
  border-radius: 14px; padding: 22px;
}
.mkt-pillar-icon { font-size: 28px; margin-bottom: 10px; }
.mkt-pillar-title { font-size: 14px; font-weight: 700; margin-bottom: 6px; }
.mkt-pillar-desc { font-size: 12.5px; color: var(--text-2); line-height: 1.5; }

.mkt-tier-strip {
  margin-top: 48px; padding: 24px;
  background: var(--panel-solid); border: 1px solid var(--border);
  border-radius: 16px;
}
.mkt-tier-strip-title { font-size: 14px; font-weight: 700; margin-bottom: 14px; }
.mkt-tier-strip-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
}
.mkt-tier-mini-card {
  padding: 14px; border-radius: 10px;
  background: var(--bg); border: 1px solid var(--border);
}
.mkt-tier-mini-icon { font-size: 20px; margin-bottom: 6px; }
.mkt-tier-mini-name { font-size: 13px; font-weight: 600; }
.mkt-tier-mini-price {
  font-size: 12px; color: var(--accent);
  font-weight: 600; margin: 4px 0;
}
.mkt-tier-mini-fit { font-size: 11.5px; color: var(--text-2); }

/* Wizard */
.mkt-wiz {
  flex: 1;
  min-height: 0;
  display: flex; flex-direction: column;
  background: var(--bg);
}
.mkt-wiz-header {
  position: relative; padding: 24px 32px 0;
  background: var(--panel-solid); border-bottom: 1px solid var(--border);
}
.mkt-wiz-close {
  position: absolute; top: 16px; right: 16px;
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--panel-solid);
  font-size: 18px; cursor: pointer; color: var(--text-2);
}
.mkt-wiz-title { font-size: 18px; font-weight: 700; margin-bottom: 18px; }
.mkt-wiz-stepper { display: flex; gap: 0; padding-bottom: 0; }
.mkt-wiz-step {
  flex: 1; display: flex; align-items: center; gap: 8px;
  padding: 12px 0; border-bottom: 2px solid var(--border);
  position: relative; color: var(--text-3); font-size: 12.5px;
  transition: all 180ms ease;
}
.mkt-wiz-step.is-current {
  color: var(--accent); border-bottom-color: var(--accent);
  font-weight: 600;
}
.mkt-wiz-step.is-done {
  color: var(--green); border-bottom-color: var(--green);
}
.mkt-wiz-step-num {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--rail); color: var(--text-2);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
}
.mkt-wiz-step.is-current .mkt-wiz-step-num { background: var(--accent); color: #fff; }
.mkt-wiz-step.is-done .mkt-wiz-step-num { background: var(--green); color: #fff; }

.mkt-wiz-body { flex: 1; overflow-y: auto; padding: 32px; }
.mkt-step { max-width: 920px; margin: 0 auto; }
.mkt-step-title {
  font-size: 22px; font-weight: 700; margin: 0 0 8px;
  letter-spacing: -0.01em;
}
.mkt-step-sub { font-size: 13px; color: var(--text-2); margin: 0 0 24px; }

.mkt-tier-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
}
.mkt-tier-card {
  position: relative; padding: 20px; border-radius: 14px;
  background: var(--panel-solid); border: 2px solid var(--border);
  text-align: left; cursor: pointer; transition: all 180ms ease;
  font-family: inherit;
}
.mkt-tier-card:hover {
  border-color: color-mix(in oklab, var(--tier-color, var(--accent)) 50%, var(--border));
  transform: translateY(-2px); box-shadow: var(--shadow-md);
}
.mkt-tier-card.is-selected {
  border-color: var(--tier-color, var(--accent));
  background: color-mix(in oklab,
    var(--tier-color, var(--accent)) 7%, var(--panel-solid));
}
.mkt-tier-card-icon { font-size: 28px; margin-bottom: 10px; }
.mkt-tier-card-name { font-size: 16px; font-weight: 700; margin-bottom: 4px; }
.mkt-tier-card-tagline { font-size: 12px; color: var(--text-2); margin-bottom: 12px; }
.mkt-tier-card-price {
  font-size: 18px; font-weight: 700;
  color: var(--tier-color, var(--accent)); margin-bottom: 4px;
}
.mkt-tier-card-est {
  font-size: 13px; font-weight: 500;
  color: var(--text-2); margin-bottom: 14px;
}
.mkt-tier-card-fit {
  font-size: 11.5px; color: var(--text-2); line-height: 1.5;
  padding: 10px; border-radius: 8px; background: var(--bg);
  margin-bottom: 8px;
}
.mkt-tier-card-commission { font-size: 11px; color: var(--text-3); font-weight: 500; }
.mkt-tier-card-check {
  position: absolute; top: 12px; right: 12px;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--tier-color, var(--accent)); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 700;
}

.mkt-form-row { margin-bottom: 18px; }
.mkt-form-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.mkt-form-label {
  display: block; font-size: 12px; font-weight: 600;
  color: var(--text-2); margin-bottom: 6px;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.mkt-form-input {
  width: 100%; padding: 10px 12px; border-radius: 8px;
  border: 1px solid var(--border-strong); background: var(--panel-solid);
  color: var(--text); font-size: 13px; font-family: inherit;
}
.mkt-form-input:focus {
  outline: none; border-color: var(--accent); box-shadow: var(--ring);
}
textarea.mkt-form-input { resize: vertical; min-height: 80px; }
.mkt-form-hint { font-size: 11.5px; color: var(--text-3); margin-top: 4px; }

.mkt-pill-row { display: flex; gap: 6px; flex-wrap: wrap; }
.mkt-pill {
  padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--border-strong); background: var(--panel-solid);
  color: var(--text-2); font-size: 12px; cursor: pointer;
  font-family: inherit;
}
.mkt-pill.is-on { background: var(--accent); color: #fff; border-color: var(--accent); }

.mkt-radio-group { display: flex; flex-direction: column; gap: 8px; }
.mkt-radio-card {
  display: flex; gap: 12px; padding: 14px; border-radius: 10px;
  border: 1.5px solid var(--border); background: var(--panel-solid);
  cursor: pointer;
}
.mkt-radio-card.is-selected {
  border-color: var(--accent); background: var(--accent-soft);
}
.mkt-radio-card-compact { padding: 10px 14px; align-items: center; }
.mkt-radio-card input[type="radio"] { margin-top: 2px; accent-color: var(--accent); }
.mkt-radio-card-compact input[type="radio"] { margin-top: 0; }
.mkt-radio-title { font-size: 13.5px; font-weight: 600; }
.mkt-radio-rec { font-size: 11.5px; color: var(--text-3); font-weight: 400; }
.mkt-radio-desc { font-size: 12px; color: var(--text-2); margin-top: 4px; line-height: 1.45; }

.mkt-checkbox-list { display: flex; flex-direction: column; gap: 6px; }
.mkt-checkbox-row {
  display: flex; gap: 8px; align-items: center;
  padding: 8px 12px; border-radius: 8px;
  background: var(--panel-solid); border: 1px solid var(--border);
  font-size: 12.5px; cursor: pointer;
}
.mkt-checkbox-row input[type="checkbox"] { accent-color: var(--accent); }

.mkt-summary-card {
  background: var(--panel-solid); border: 1px solid var(--border);
  border-radius: 12px; padding: 18px 20px; margin-bottom: 14px;
}
.mkt-summary-section-title {
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-3); margin-bottom: 12px;
}
.mkt-summary-row { display: flex; justify-content: space-between; padding: 6px 0; font-size: 13px; }
.mkt-summary-label { color: var(--text-2); }
.mkt-summary-value { color: var(--text); text-align: right; }
.mkt-summary-extra { color: var(--orange); font-size: 11.5px; }
.mkt-summary-divider { height: 1px; background: var(--border); margin: 8px 0; }
.mkt-privacy-note {
  margin-top: 10px; padding: 10px 12px;
  background: var(--accent-soft); border-radius: 8px;
  font-size: 11.5px; color: var(--text-2); line-height: 1.5;
}
.mkt-payment-row { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.mkt-card-icon { font-size: 18px; }
.mkt-payment-change {
  margin-left: auto; padding: 4px 10px; font-size: 11.5px;
  border-radius: 6px; border: 1px solid var(--border);
  background: transparent; cursor: pointer; font-family: inherit;
}

.mkt-wiz-footer {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 32px; background: var(--panel-solid);
  border-top: 1px solid var(--border);
}
.mkt-wiz-prev, .mkt-wiz-next, .mkt-wiz-publish {
  padding: 10px 22px; border-radius: 10px;
  font-size: 13px; font-weight: 600; cursor: pointer;
  font-family: inherit; border: none;
}
.mkt-wiz-prev {
  background: transparent; color: var(--text-2);
  border: 1px solid var(--border-strong);
}
.mkt-wiz-prev:disabled { opacity: 0.4; cursor: not-allowed; }
.mkt-wiz-next, .mkt-wiz-publish { background: var(--accent); color: #fff; }
.mkt-wiz-next:disabled { opacity: 0.5; cursor: not-allowed; }
.mkt-wiz-publish { background: var(--green); }
.mkt-wiz-progress { flex: 1; text-align: center; font-size: 12px; color: var(--text-3); }

.mkt-placeholder {
  position: relative;
  max-width: 600px; margin: 80px auto;
  text-align: center; padding: 48px 32px;
  background: var(--panel-solid); border-radius: 16px;
  border: 1px dashed var(--border-strong);
}
.mkt-placeholder-icon { font-size: 48px; margin-bottom: 16px; }
.mkt-placeholder-title { font-size: 18px; font-weight: 700; margin-bottom: 8px; }
.mkt-placeholder-desc { font-size: 13px; color: var(--text-2); line-height: 1.55; }
.mkt-back {
  position: absolute; top: 24px; left: 24px;
  padding: 8px 14px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--panel-solid);
  color: var(--text-2); font-size: 12.5px; cursor: pointer;
}

/* ── MVP2 Browse jobs ─────────────────────────────────────────── */
.mkt-browse {
  max-width: 1200px;
  margin: 0 auto;
  padding: 32px 24px 80px;
  position: relative;
}
.mkt-browse-header {
  margin-bottom: 24px;
  padding-top: 24px;
}
.mkt-browse-title-row {
  display: flex; align-items: baseline; gap: 16px;
  flex-wrap: wrap;
}
.mkt-browse-title {
  font-size: 28px; font-weight: 700;
  margin: 0; letter-spacing: -0.02em;
}
.mkt-browse-count {
  font-size: 13px; color: var(--text-2);
}

.mkt-filter-bar {
  display: grid;
  grid-template-columns: 2fr 1.4fr 1fr 1fr 1fr;
  gap: 12px;
  padding: 14px 16px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 12px;
  margin-bottom: 20px;
}
@media (max-width: 1100px) {
  .mkt-filter-bar { grid-template-columns: 1fr 1fr; }
}
.mkt-filter-group { min-width: 0; }
.mkt-filter-label {
  font-size: 10.5px; font-weight: 600;
  color: var(--text-3); text-transform: uppercase;
  letter-spacing: 0.05em; margin-bottom: 6px;
}
.mkt-filter-select { padding: 6px 10px; font-size: 12.5px; }

.mkt-browse-empty {
  text-align: center; padding: 80px 24px;
  background: var(--panel-solid);
  border: 1px dashed var(--border-strong);
  border-radius: 14px; margin: 24px 0;
  color: var(--text-2);
}
.mkt-browse-empty-title {
  font-size: 16px; font-weight: 700;
  margin: 12px 0 6px; color: var(--text);
}
.mkt-browse-empty-desc { font-size: 13px; line-height: 1.5; }
.mkt-spinner {
  width: 32px; height: 32px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  margin: 0 auto 12px;
  animation: mkt-spin 720ms linear infinite;
}
@keyframes mkt-spin {
  from { transform: rotate(0deg); } to { transform: rotate(360deg); }
}

.mkt-job-list {
  display: flex; flex-direction: column; gap: 14px;
}
.mkt-job-card {
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 18px 22px;
  transition: all 200ms ease;
}
.mkt-job-card:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}
.mkt-job-card-head {
  display: flex; justify-content: space-between;
  align-items: flex-start; gap: 14px;
  margin-bottom: 10px;
}
.mkt-job-card-id {
  font-size: 11px; font-weight: 600;
  color: var(--text-3); font-family: monospace;
  margin-bottom: 4px;
}
.mkt-job-card-title {
  font-size: 15.5px; font-weight: 700;
  margin-bottom: 4px;
}
.mkt-job-card-client {
  font-size: 12px; color: var(--text-2);
  display: flex; gap: 8px; align-items: center;
}
.mkt-job-verified {
  font-size: 10.5px; padding: 2px 8px;
  background: var(--accent-soft); color: var(--accent);
  border-radius: 999px; font-weight: 600;
}

.mkt-tier-badge {
  padding: 5px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600;
  white-space: nowrap;
}
.mkt-tier-badge-remote {
  background: color-mix(in oklab, var(--accent) 12%, transparent);
  color: var(--accent);
}
.mkt-tier-badge-onsite_standard {
  background: color-mix(in oklab, var(--orange) 14%, transparent);
  color: var(--orange);
}
.mkt-tier-badge-onsite_premium {
  background: color-mix(in oklab, var(--purple) 14%, transparent);
  color: var(--purple);
}

.mkt-job-card-meta {
  display: flex; gap: 16px; flex-wrap: wrap;
  font-size: 12px; color: var(--text-2);
  margin-bottom: 12px;
}

.mkt-job-card-pay {
  background: var(--bg);
  border-radius: 10px;
  padding: 10px 14px;
  margin-bottom: 12px;
}
.mkt-job-pay-main {
  font-size: 14px;
  margin-bottom: 4px;
}
.mkt-job-pay-main b {
  font-size: 16px;
  color: var(--green);
}
.mkt-job-pay-bonus {
  font-size: 11.5px; color: var(--text-2);
}

.mkt-match-score {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 14px;
  border-radius: 10px;
  margin-bottom: 14px;
  border: 1px solid var(--border);
}
.mkt-match-score.is-high {
  background: color-mix(in oklab, var(--green) 8%, var(--panel-solid));
  border-color: color-mix(in oklab, var(--green) 30%, var(--border));
}
.mkt-match-score.is-mid {
  background: color-mix(in oklab, var(--accent) 7%, var(--panel-solid));
  border-color: color-mix(in oklab, var(--accent) 25%, var(--border));
}
.mkt-match-score.is-low {
  background: color-mix(in oklab, var(--text-3) 5%, var(--panel-solid));
}
.mkt-match-score-num {
  font-size: 22px; font-weight: 700;
  font-family: -apple-system, BlinkMacSystemFont, "Inter", sans-serif;
}
.mkt-match-score.is-high .mkt-match-score-num { color: var(--green); }
.mkt-match-score.is-mid  .mkt-match-score-num { color: var(--accent); }
.mkt-match-score.is-low  .mkt-match-score-num { color: var(--text-2); }

.mkt-match-score-label {
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-3); margin-bottom: 2px;
}
.mkt-match-score-reason {
  font-size: 12px; color: var(--text-2);
  line-height: 1.4;
}

.mkt-job-card-actions {
  display: flex; gap: 8px;
}
.mkt-job-apply, .mkt-job-save, .mkt-job-skip {
  padding: 8px 16px; border-radius: 8px;
  font-size: 12.5px; font-weight: 600;
  cursor: pointer; font-family: inherit;
  border: none;
}
.mkt-job-apply { background: var(--accent); color: #fff; }
.mkt-job-save {
  background: var(--panel-solid); color: var(--text-2);
  border: 1px solid var(--border-strong);
}
.mkt-job-skip {
  background: transparent; color: var(--text-3);
  border: 1px solid var(--border);
}

/* ── Apply modal ───────────────────────────────────────────────── */
.mkt-modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  z-index: 100;
  animation: mkt-modal-bg-in 200ms ease;
}
@keyframes mkt-modal-bg-in {
  from { opacity: 0; } to { opacity: 1; }
}
.mkt-modal {
  position: relative;
  width: min(560px, 90vw);
  max-height: 90vh;
  overflow-y: auto;
  background: var(--panel-solid);
  border-radius: 16px;
  box-shadow: var(--shadow-lg);
  padding: 28px 32px;
  animation: mkt-modal-in 240ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
@keyframes mkt-modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.mkt-modal-title {
  font-size: 20px; font-weight: 700;
  margin: 0 0 18px;
}
.mkt-apply-job-summary {
  background: var(--bg);
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 18px;
}
.mkt-apply-job-id {
  font-size: 11px; color: var(--text-3);
  font-family: monospace;
}
.mkt-apply-job-title {
  font-size: 14px; font-weight: 600; margin: 4px 0;
}
.mkt-apply-pay {
  font-size: 13px;
}
.mkt-apply-pay b { color: var(--green); }
.mkt-portfolio-btn {
  padding: 10px 14px; border-radius: 8px;
  border: 1px dashed var(--border-strong);
  background: transparent;
  font-size: 13px; cursor: pointer;
  font-family: inherit;
  width: 100%; text-align: center;
}
.mkt-modal-actions {
  display: flex; gap: 10px; justify-content: flex-end;
  margin-top: 20px;
}

/* ── Convert-fonts button progress fill ─────────────────────────
   Khi font conversion chạy, ``::before`` pseudo paint 1 dải xanh
   nhạt rộng theo ``--font-pct`` (controlled từ React state).
   Khi 100% (class ``is-done``) → background đầy giống nút "Đã
   kết nối — AutoCAD" để user thấy "xong".

   Layout: button position:relative + overflow:hidden để ::before
   không tràn ngoài corner radius. Text label dùng z-index:1 để
   nằm trên gradient. */
.convert-fonts-btn {
  position: relative;
  overflow: hidden;
  transition: background 200ms ease, border-color 200ms ease,
              color 200ms ease;
}
.convert-fonts-btn::before {
  content: "";
  position: absolute;
  inset: 0;
  width: var(--font-pct, 0%);
  background: color-mix(in oklab, var(--green) 14%, transparent);
  transition: width 220ms cubic-bezier(0.22, 0.9, 0.3, 1);
  pointer-events: none;
  z-index: 0;
}
.convert-fonts-btn.is-running {
  border-color: color-mix(in oklab, var(--green) 30%, var(--border));
  color: var(--green);
}
.convert-fonts-btn.is-done {
  /* 100% — đồng nhất với .disconnect-autocad-btn để hai trạng
     thái "xong" trong sidebar có ngôn ngữ thị giác giống nhau. */
  background: color-mix(in oklab, var(--green) 14%, transparent);
  border-color: color-mix(in oklab, var(--green) 30%, var(--border));
  color: var(--green);
}

/* Bước 3 "Quét & Dịch tự động" — done state khớp ngôn ngữ thị giác
   với Bước 2 (.convert-fonts-btn.is-done) + .disconnect-autocad-btn
   để 3 trạng thái "xong" trong sidebar đồng nhất. */
.auto-translate-btn.is-done {
  background: color-mix(in oklab, var(--green) 14%, transparent);
  border-color: color-mix(in oklab, var(--green) 30%, var(--border));
  color: var(--green);
  /* Không cần is-done::before fill vì button không có pseudo
     progress layer (chỉ button Bước 2 mới có). */
}
/* Specificity boost: ``.scan-all-btn`` base rule + ``:disabled`` /
   inherited ``.btn`` color override the green when the button
   stacks all three classes (.scan-all-btn .auto-translate-btn
   .write-style-btn) — the user reported "Đã dịch · N dòng" text
   stays dark while "Đã ghi · N text" reads green. Re-assert green
   at higher specificity so the done-state matches the other Bước 2
   / Bước 4 buttons in the sidebar. ``!important`` is overkill;
   chaining 4 classes wins over any :disabled rule via specificity. */
.scan-all-btn.auto-translate-btn.write-style-btn.is-done,
.scan-all-btn.auto-translate-btn.write-style-btn.is-done .mode-label {
  color: var(--green);
}

/* Bước 4 — 3 nút "thực thi ghi" theo phong cách. Reuse layout của
   .mode-btn (scan mode tiles cũ) nhưng đổi accent màu sang accent
   chính (xanh primary) khi hover/active để báo hiệu "action button"
   chứ không phải "selector". Disabled state mờ hơn để rõ ràng không
   thể click khi rows trống.

   Progress fill: ``.write-tile-fill`` là 1 ::-like span absolute
   bên trong button, width = ``--write-pct`` (controlled từ React
   state). Khi tile đang chạy, fill xanh nhạt lan từ trái sang phải
   matching % tiến độ write-back. Icon + label nằm trên fill nhờ
   ``position: relative; z-index: 1``. Apple-style: fill grow mượt
   bằng cubic-bezier easing 220ms. */
.write-style-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}
.write-style-btn {
  position: relative;
  overflow: hidden;
  /* Inherit base mode-btn styling */
  transition: background 140ms ease, border-color 140ms ease,
              transform 80ms ease, color 140ms ease;
}
.write-tile-fill {
  position: absolute;
  inset: 0;
  width: var(--write-pct, 0%);
  /* 2026-05-24 v34 · rgba thay color-mix (compat Qt WebEngine
     Chromium cũ). Transition 600ms + cubic-bezier mượt — user feedback:
     'thấy dừng một lúc đầu rồi load full rất nhanh' do progress jump
     trong từng step. Transition dài hơn = animation liên tục mượt
     giữa các progress events. */
  background: rgba(48, 209, 88, 0.18);
  transition: width 600ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
  pointer-events: none;
  z-index: 0;
}
.write-style-btn .mode-icon,
.write-style-btn .mode-label {
  position: relative;
  z-index: 1;
}
.write-style-btn.is-running {
  border-color: color-mix(in oklab, var(--green) 32%, var(--border));
  color: var(--green);
}
.write-style-btn.is-done {
  background: color-mix(in oklab, var(--green) 14%, transparent);
  border-color: color-mix(in oklab, var(--green) 30%, var(--border));
  color: var(--green);
}
.write-style-btn.is-done .write-tile-fill {
  width: 100%;
}
.write-style-btn:not(:disabled):hover {
  background: color-mix(in oklab, var(--accent, var(--mc-accent)) 10%, transparent);
  border-color: color-mix(in oklab, var(--accent, var(--mc-accent)) 35%, var(--border));
  color: var(--accent, var(--mc-accent));
}
.write-style-btn.is-running:not(:disabled):hover,
.write-style-btn.is-done:not(:disabled):hover {
  /* Khi đang chạy / xong, giữ tone xanh-green thay vì flip sang
     accent blue — tránh "nhảy màu" gây sao lãng. */
  background: color-mix(in oklab, var(--green) 18%, transparent);
  border-color: color-mix(in oklab, var(--green) 35%, var(--border));
  color: var(--green);
}
.write-style-btn:not(:disabled):active {
  transform: scale(0.97);
  background: color-mix(in oklab, var(--accent, var(--mc-accent)) 18%, transparent);
}
.write-style-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Bước 6 (per user 9-step UX spec) — tile chọn chế độ ghi.
   User spec 2026-05-25: "khi chọn xong thì nền phải chuyển màu
   xanh" — confirms a successful selection action distinctly from
   the accent-blue used elsewhere as a "this is interactive" hint.
   Green = "you picked this, pipeline is anchored to it".
   Previous version used accent-blue which felt like a hover hint
   rather than a committed selection. */
.pick-mode-btn.is-selected {
  background: rgba(48, 209, 88, 0.16);
  border-color: rgba(48, 209, 88, 0.55);
  color: var(--mc-success);
  box-shadow: 0 0 0 1px rgba(48, 209, 88, 0.30) inset;
  transition: background 220ms ease, border-color 220ms ease,
              color 220ms ease, box-shadow 220ms ease;
}
.pick-mode-btn.is-selected:not(:disabled):hover {
  background: rgba(48, 209, 88, 0.22);
  border-color: rgba(48, 209, 88, 0.65);
  color: var(--mc-success);
}
/* Icon + label inherit the green color in selected state. */
.pick-mode-btn.is-selected .mode-icon,
.pick-mode-btn.is-selected .mode-label {
  color: var(--mc-success);
}

/* 2026-05-23 v17 · Khi chế độ Bước 1 chuyển sang đang chạy / xong,
   nền nút phải xanh giống "Đã kết nối / Đã xử lý / Đã dịch / Đã ghi".
   Dùng rgba() thay color-mix() — Qt WebEngine có thể là phiên Chromium
   cũ không support color-mix(), khiến rule fail silently → background
   default trắng. rgba explicit guaranteed compatible.
   Green tint = var(--mc-success) with various alphas. */
.pick-mode-btn.is-running,
.pick-mode-btn.is-selected.is-running,
.pick-mode-btn.write-style-btn.is-running,
.mode-btn.pick-mode-btn.is-running,
.mode-btn.pick-mode-btn.is-selected.is-running {
  background: rgba(48, 209, 88, 0.16) !important;
  border-color: rgba(48, 209, 88, 0.55) !important;
  color: var(--mc-success) !important;
  box-shadow: 0 0 0 1px rgba(48, 209, 88, 0.30) inset !important;
}
.pick-mode-btn.is-done,
.pick-mode-btn.is-selected.is-done,
.pick-mode-btn.write-style-btn.is-done,
.mode-btn.pick-mode-btn.is-done,
.mode-btn.pick-mode-btn.is-selected.is-done {
  background: rgba(48, 209, 88, 0.22) !important;
  border-color: rgba(48, 209, 88, 0.62) !important;
  color: var(--mc-success) !important;
  box-shadow: 0 0 0 1px rgba(48, 209, 88, 0.38) inset !important;
}
.pick-mode-btn.is-running:not(:disabled):hover,
.pick-mode-btn.is-done:not(:disabled):hover {
  background: rgba(48, 209, 88, 0.28) !important;
  border-color: rgba(48, 209, 88, 0.70) !important;
  color: var(--mc-success) !important;
}
.convert-fonts-btn.is-done::before {
  /* Full fill — duplicate paint với chính cùng tint là OK
     (color-mix idempotent), nhưng giữ width=100% để animation
     từ is-running → is-done không "nhảy ngược" khi pct=100. */
  width: 100%;
}
.convert-fonts-label {
  position: relative;
  z-index: 1;
}

/* ── Settings modal (sm-*) — macOS-style overlay ───────────────
   No top header bar — close button floats. "Settings" title lives
   inside the sidebar. System font stack for native feel. */
.sm-overlay {
  position: fixed; inset: 0; z-index: 2000;
  background: rgba(0, 0, 0, 0.35);
  display: flex; align-items: center; justify-content: center;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: smFadeIn 0.18s ease-out;
}
@keyframes smFadeIn { from { opacity: 0 } to { opacity: 1 } }
.sm-modal {
  position: relative;
  width: 980px; max-width: 92vw;
  height: 680px; max-height: 88vh;
  background: var(--bg-elev);
  border: 1px solid rgba(0,0,0,0.08);
  border-radius: 12px;
  box-shadow: 0 30px 80px rgba(0,0,0,0.20), 0 6px 20px rgba(0,0,0,0.10);
  display: flex; overflow: hidden;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter",
               "Segoe UI", system-ui, sans-serif;
  animation: smPop 0.22s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes smPop {
  from { transform: scale(0.97); opacity: 0 }
  to   { transform: scale(1);    opacity: 1 }
}
.sm-close-float {
  position: absolute; top: 14px; right: 14px; z-index: 10;
  width: 26px; height: 26px;
  background: transparent; border: none; cursor: pointer;
  color: var(--text-2); border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
}
.sm-close-float:hover { background: var(--selected); color: var(--text); }

.sm-sidebar {
  width: 240px; min-width: 240px;
  padding: 22px 14px 16px;
  background: var(--rail);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 14px;
  overflow-y: auto;
}
.sm-sidebar-title {
  padding: 0 6px 4px;
  font-size: 17px; font-weight: 600;
  color: var(--text); letter-spacing: -0.2px;
}
.sm-search-wrap {
  position: relative; padding: 0 4px;
}
.sm-search-icon {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  color: var(--text-3); pointer-events: none;
}
.sm-search {
  width: 100%; padding: 7px 10px 7px 30px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-elev); color: var(--text);
  font-size: 13px; outline: none;
  transition: border-color 0.15s;
}
.sm-search:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

.sm-nav { display: flex; flex-direction: column; gap: 1px; padding: 0 4px; }
.sm-nav-item {
  display: flex; align-items: center; gap: 11px;
  padding: 8px 10px; border-radius: 7px;
  background: transparent; border: none; cursor: pointer;
  color: var(--text); font-size: 13.5px; text-align: left;
  width: 100%; transition: background 0.12s;
}
.sm-nav-item:hover { background: rgba(0,0,0,0.04); }
[data-theme="dark"] .sm-nav-item:hover { background: rgba(255,255,255,0.05); }
.sm-nav-item.is-active {
  background: rgba(0,0,0,0.07);
  font-weight: 600;
}
[data-theme="dark"] .sm-nav-item.is-active { background: rgba(255,255,255,0.08); }
.sm-nav-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; color: var(--text-2);
  flex-shrink: 0;
}
.sm-nav-item.is-active .sm-nav-icon { color: var(--text); }
.sm-nav-label { flex: 1; }
.sm-nav-badge {
  padding: 1px 7px; border-radius: 9px;
  background: var(--selected); color: var(--text-2);
  font-size: 10px; font-weight: 600; text-transform: lowercase;
}
.sm-nav-group-title {
  padding: 14px 10px 4px;
  font-size: 11px; color: var(--text-3);
  font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.5px;
}

.sm-content {
  flex: 1; overflow-y: auto;
  padding: 36px 40px;
  background: var(--bg-elev);
}
.sm-panel { display: flex; flex-direction: column; gap: 0; max-width: 680px; }
/* Plan picker uses the FULL content width so 3 cards fit horizontally
   in one screen without scrolling. The 680px cap is the right call for
   forms (overview, payment) but cramps the 3-up plan grid. */
.sm-panel.sm-panel-plans { max-width: none; }

/* ═══════════════════════════════════════════════════════════════════
   Embedded PricingScreen inside Settings → Billing
   ───────────────────────────────────────────────────────────────────
   The profile-menu PricingScreen is the canonical upgrade UI. We
   render the same component here so both surfaces look identical.
   This block (1) lets the pricing screen fill the panel edge-to-edge
   (2) floats a "← Quay lại" pill above so user can pop back to the
   billing overview without navigating through the screen itself. */
.sm-panel.sm-panel-pricing {
  max-width: none;
  /* Negate parent Panel padding (20px 28px) so PricingScreen claims
     the full content area exactly like it does in the profile flow. */
  margin: -20px -28px;
  padding: 0;
  background: transparent;
  position: relative;
}
.sm-back-floating {
  position: sticky;
  top: 12px;
  left: 16px;
  z-index: 50;
  /* Sits in its own row above PricingScreen — float it inline with
     a small inset so the pricing title still appears centered below. */
  display: inline-block;
  margin: 12px 0 -36px 16px;
  padding: 6px 14px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--accent);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  transition: background 0.15s, transform 0.05s;
  width: fit-content;
}
.sm-back-floating:hover { background: var(--accent-soft); }
.sm-back-floating:active { transform: translateY(1px); }
/* Embedded checkout — when CheckoutView lives inside Settings → Billing
   it must (1) fill the panel area edge-to-edge with one uniform bg
   (no white gap to the left of the centered content) and (2) delegate
   scrolling to the outer settings Panel so the back arrow stays sticky
   to the TRUE top of the visible area while the user scrolls the form. */
.sm-panel.sm-panel-checkout {
  /* Negate the parent's 20px 28px inset so the checkout bg actually
     touches the sidebar divider and the right edge — no halo of
     uncovered area inside the red box. */
  max-width: none;
  margin: -20px -28px;
  padding: 0;
  /* Inherit from the parent Panel — same bg as the rest of the
     settings content area so there's no visible seam. */
  background: transparent;
}
.sm-panel.sm-panel-checkout .checkout-view {
  /* Kill the inner scroll context. With overflow:auto here, the sticky
     back arrow would stick to THIS element's top — which never moves
     because there's no inner scroll — and disappears from view when
     the outer settings Panel scrolls. Letting the outer Panel own the
     scroll makes sticky work the way the user expects. */
  overflow: visible;
  min-height: 100%;
  padding-bottom: 40px;
  /* Transparent so the panel bg fills uniformly behind back button
     and the empty left/right gutters next to the centered wrap. */
  background: transparent;
}
/* Back button sits sticky at the TOP of the outer scroll container
   (.panel.scroll). We re-declare position:sticky here mainly to bump
   z-index above the wrap content and tune the offset so it tucks
   under the title bar without floating awkwardly. */
.sm-panel.sm-panel-checkout .checkout-back {
  position: sticky;
  top: 8px;
  z-index: 20;
  margin: 16px 0 0 16px;
  /* Solid opaque bg so scrolling content doesn't bleed through the
     small gap between button and the circle's border. */
  background: var(--bg-elev);
}
.sm-panel.sm-panel-checkout .checkout-wrap {
  padding-top: 8px;
}
.sm-section-title {
  font-size: 17px; font-weight: 600;
  color: var(--text); letter-spacing: -0.2px;
  padding: 0 0 14px 0;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.sm-row {
  display: flex; gap: 20px; align-items: center;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}
.sm-row:last-child { border-bottom: none; }
.sm-row-header {
  border-bottom: 1px solid var(--border);
  padding: 6px 0 12px;
  margin-bottom: 4px;
}
.sm-row-header h2 { margin: 0; font-size: 17px; font-weight: 600; letter-spacing: -0.2px; }
.sm-row-l { flex: 1; min-width: 0; }
.sm-row-r { flex: 0 0 auto; display: flex; align-items: center; gap: 10px; min-width: 0; }
.sm-row-title { font-size: 14px; color: var(--text); font-weight: 500; line-height: 1.4; }
.sm-row-sub { font-size: 12.5px; color: var(--text-2); margin-top: 4px; line-height: 1.5; max-width: 480px; }
.sm-row-actions { justify-content: flex-end; padding-top: 8px; border-bottom: none; }
.sm-section-gap { height: 22px; }

.sm-plan-pill {
  margin-left: 10px; padding: 2px 12px;
  border-radius: 12px; color: var(--text-2);
  background: rgba(0,0,0,0.05);
  font-size: 12.5px; font-weight: 500;
}
[data-theme="dark"] .sm-plan-pill { background: rgba(255,255,255,0.08); }
.sm-link {
  color: var(--accent); text-decoration: underline;
  font-size: 13px; margin-left: auto;
  text-decoration-color: rgba(0,122,255,0.4);
  text-underline-offset: 2px;
}
.sm-link:hover { text-decoration-color: var(--accent); }

/* Inputs / selects / textarea — macOS aesthetic */
.sm-input, .sm-select, .sm-textarea {
  padding: 7px 11px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-elev); color: var(--text);
  font-size: 13.5px;
  font-family: inherit;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.sm-input:focus, .sm-select:focus, .sm-textarea:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.sm-input { min-width: 240px; text-align: right; }
.sm-select { min-width: 200px; padding-right: 28px; cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2386868B' stroke-width='2'><path d='m6 9 6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  appearance: none; -webkit-appearance: none;
}
.sm-textarea {
  width: 100%; min-height: 90px; text-align: left;
  resize: vertical; line-height: 1.5;
}

/* Buttons inherit project .btn class but with refined sizing */
.sm-row .btn { font-size: 13px; padding: 6px 14px; border-radius: 8px; }

/* Segmented control (theme switcher) */
.sm-seg {
  display: inline-flex; gap: 0;
  background: var(--selected); border-radius: 8px; padding: 2px;
}
.sm-seg-btn {
  border: none; background: transparent;
  width: 32px; height: 26px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-2); cursor: pointer;
  transition: background 0.12s;
}
.sm-seg-btn:hover { color: var(--text); }
.sm-seg-btn.is-active {
  background: var(--bg-elev);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(0,0,0,0.06), 0 0 0 0.5px rgba(0,0,0,0.04);
}

/* Progress bars (legacy single-row UsageItem — kept for compat) */
.sm-bar { display: flex; align-items: center; gap: 14px; min-width: 280px; }
.sm-bar-track { flex: 1; height: 4px; background: var(--selected); border-radius: 999px; overflow: hidden; }
.sm-bar-fill { height: 100%; border-radius: 999px; transition: width 0.35s ease; }
.sm-bar-text { font-size: 12.5px; color: var(--text-2); font-variant-numeric: tabular-nums; min-width: 64px; text-align: right; }
.sm-count { font-size: 13.5px; color: var(--text-2); font-variant-numeric: tabular-nums; font-weight: 500; }

/* ── v2.3 Usage panel — three-window quota cards ────────────────── */

/* Block banner — color-keyed by which window is blocking */
.sm-block-banner {
  margin: 12px 0 4px;
  padding: 12px 16px; border-radius: 10px;
  background: rgba(220, 38, 38, 0.08);
  border: 1px solid rgba(220, 38, 38, 0.35);
}
.sm-block-banner[data-window="5h"]    { background: rgba(245, 158, 11, 0.10);
                                         border-color: rgba(245, 158, 11, 0.40); }
.sm-block-banner[data-window="week"]  { background: rgba(220, 38, 38, 0.10);
                                         border-color: rgba(220, 38, 38, 0.45); }
.sm-block-banner[data-window="month"] { background: rgba(168, 85, 247, 0.10);
                                         border-color: rgba(168, 85, 247, 0.40); }
.sm-block-title { font-weight: 700; font-size: 13.5px; margin-bottom: 3px; color: var(--text-1); }
.sm-block-body  { font-size: 12.5px; color: var(--text-2); line-height: 1.5; }

/* Quy ước box — explains the words ≈ drawings convention AND the
   translation scope (TEXT/MTEXT only). Two paragraphs share one box
   so users see both rules at the same glance. */
.sm-quota-convention {
  font-size: 11.5px; color: var(--text-2); line-height: 1.55;
  padding: 10px 14px; margin: 4px 0 10px;
  background: rgba(0, 122, 255, 0.06);
  border-left: 3px solid rgba(0, 122, 255, 0.45);
  border-radius: 0 6px 6px 0;
}
.sm-quota-convention b { color: var(--text-1); font-weight: 600; }
.sm-quota-convention-p { margin: 0; }
.sm-quota-convention-p + .sm-quota-convention-p {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed rgba(0, 122, 255, 0.20);
}
.sm-quota-convention-scope { color: var(--text-3); }
[data-theme="dark"] .sm-quota-convention {
  background: rgba(64, 156, 255, 0.08);
  border-left-color: rgba(64, 156, 255, 0.5);
}
[data-theme="dark"] .sm-quota-convention-p + .sm-quota-convention-p {
  border-top-color: rgba(64, 156, 255, 0.25);
}

/* Last-updated inline (next to plan pill in header) */
.sm-updated-inline {
  margin-left: auto; display: inline-flex; align-items: center; gap: 4px;
  font-size: 11.5px; color: var(--text-3); font-variant-numeric: tabular-nums;
}

/* Window card — one per cap (5h/week/month) */
.sm-window-card {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 12px 14px; margin: 6px 0;
  background: var(--bg-elev);
}
.sm-window-head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 10px;
}
.sm-window-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--text-3);
  flex-shrink: 0;
}
.sm-window-dot[data-window="5h"]    { background: rgb(245, 158, 11); }
.sm-window-dot[data-window="week"]  { background: rgb(220, 38, 38); }
.sm-window-dot[data-window="month"] { background: rgb(168, 85, 247); }
.sm-window-title {
  font-size: 13.5px; font-weight: 600; color: var(--text-1);
}
.sm-window-sub {
  margin-left: auto; font-size: 11.5px; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

/* Two metric bars per card (Từ + Bản vẽ) */
.sm-window-metrics {
  display: flex; flex-direction: column; gap: 6px;
}
.sm-metric {
  display: grid;
  grid-template-columns: 130px 1fr auto;
  align-items: center; gap: 12px;
}
.sm-metric-label {
  font-size: 12px; color: var(--text-3);
}
.sm-metric-track {
  height: 4px; background: var(--selected);
  border-radius: 999px; overflow: hidden;
  opacity: 0.7;
}
.sm-metric-fill {
  height: 100%; border-radius: 999px;
  transition: width 0.35s ease;
}
.sm-metric-num {
  font-size: 12px; font-variant-numeric: tabular-nums;
  display: inline-flex; gap: 10px; align-items: baseline;
  min-width: 200px; justify-content: flex-end;
}
.sm-metric-pct { font-weight: 600; color: var(--text-2); min-width: 36px; text-align: right; }
.sm-metric-raw { color: var(--text-3); }

/* Primary metric (Số từ = the real billable unit) is visually stronger
   than the secondary derived metric (Bản vẽ ước tính). */
.sm-metric.is-primary .sm-metric-label { color: var(--text-1); font-weight: 600; }
.sm-metric.is-primary .sm-metric-track { height: 6px; opacity: 1; }
.sm-metric.is-primary .sm-metric-pct   { color: var(--text-1); font-size: 13px; }
.sm-metric.is-primary .sm-metric-raw   { color: var(--text-2); }

/* Credit balance pill in section header */
.sm-credit-balance {
  margin-left: auto; padding: 2px 10px; border-radius: 10px;
  background: rgba(34, 197, 94, 0.12); color: rgb(22, 163, 74);
  font-size: 11.5px; font-weight: 600; font-variant-numeric: tabular-nums;
}
[data-theme="dark"] .sm-credit-balance {
  background: rgba(34, 197, 94, 0.18); color: rgb(74, 222, 128);
}

/* ── v2.3 Credit bổ sung block — Anthropic Console pattern ──────── */

.sm-credits-intro {
  font-size: 12.5px; color: var(--text-2); line-height: 1.55;
  padding: 4px 0 12px;
}

.sm-credits-rows {
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg-elev);
}
.sm-credits-rows.is-disabled { opacity: 0.55; pointer-events: none; }

.sm-credit-row {
  display: flex; align-items: center; gap: 12px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--border);
}
.sm-credit-row:last-child { border-bottom: none; }
.sm-credit-row-l { flex: 1; min-width: 0; }
.sm-credit-row-r {
  display: inline-flex; align-items: center; gap: 12px;
}
.sm-credit-row-main {
  font-size: 17px; font-weight: 500; color: var(--text-1);
  font-variant-numeric: tabular-nums; line-height: 1.3;
}
.sm-credit-row-aux { color: var(--text-3); font-weight: 400; }
.sm-credit-row-sub {
  font-size: 12.5px; color: var(--text-3); margin-top: 4px;
}
.sm-credit-limit-value {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--accent);
}
.sm-credit-info-icon {
  color: var(--text-3); font-size: 12px; cursor: help;
}
.sm-auto-pill {
  display: inline-block; padding: 1px 8px; border-radius: 10px;
  background: var(--selected); color: var(--text-3);
  font-size: 11px; font-weight: 500; margin-left: 4px;
}
.sm-auto-pill[data-on="true"] {
  background: rgba(34, 197, 94, 0.15); color: rgb(22, 163, 74);
}
[data-theme="dark"] .sm-auto-pill[data-on="true"] {
  background: rgba(34, 197, 94, 0.20); color: rgb(74, 222, 128);
}
.sm-discount-pill {
  background: rgba(0, 122, 255, 0.10); color: var(--accent);
  font-size: 11px; font-weight: 500;
  padding: 2px 8px; border-radius: 10px;
}

/* ── Modal shell (used by 3 credit modals) ─────────────────────── */
.sm-modal-backdrop {
  position: fixed; inset: 0; z-index: 9000;
  background: rgba(0, 0, 0, 0.45);
  display: flex; align-items: center; justify-content: center;
  padding: 24px; animation: smModalFade 0.15s ease;
}
@keyframes smModalFade { from { opacity: 0; } to { opacity: 1; } }
.sm-modal-dialog {
  background: var(--bg); color: var(--text-1);
  border: 1px solid var(--border); border-radius: 14px;
  width: 100%; max-width: 460px; max-height: 92vh;
  overflow: auto; padding: 28px 28px 22px;
  position: relative; box-shadow: 0 16px 50px rgba(0,0,0,0.28);
}
.sm-modal-dialog.is-wide { max-width: 560px; }
.sm-modal-close {
  position: absolute; top: 16px; right: 16px;
  background: none; border: none; cursor: pointer;
  width: 30px; height: 30px; border-radius: 6px;
  font-size: 22px; color: var(--text-2);
  display: inline-flex; align-items: center; justify-content: center;
}
.sm-modal-close:hover { background: var(--selected); color: var(--text); }
.sm-modal-title { margin: 0 0 10px; font-size: 22px; font-weight: 700; line-height: 1.25; }
.sm-modal-lead  { margin: 0 0 20px; font-size: 14px; color: var(--text-2); line-height: 1.55; }
.sm-modal-hint  { margin: 8px 0 0;  font-size: 12px;  color: var(--text-3); }
.sm-modal-aux   { color: var(--text-3); font-size: 11px; }

.sm-modal-field { display: block; margin-bottom: 14px; }
.sm-modal-field-label {
  display: block; font-size: 13px; color: var(--text-2);
  margin-bottom: 8px; font-weight: 500;
}

/* Input with currency prefix — bigger, money-input pattern */
.sm-modal-input-wrap {
  position: relative; display: block;
}
.sm-modal-input-prefix {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  font-size: 16px; color: var(--text-2); pointer-events: none;
  font-variant-numeric: tabular-nums;
}
.sm-modal-input {
  width: 100%; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg-elev); color: var(--text-1);
  font-size: 16px; font-variant-numeric: tabular-nums;
}
.sm-modal-input-money { padding-left: 30px; font-size: 17px; font-weight: 500; }
.sm-modal-input:focus {
  outline: none; border-color: var(--text-1);
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.08);
}
.sm-modal-input:disabled { opacity: 0.5; cursor: not-allowed; }

.sm-modal-actions {
  display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px;
}
.sm-modal-actions .btn { padding: 10px 18px; font-size: 14px; font-weight: 500; }
.sm-modal-cta {
  width: 100%; margin-top: 20px; padding: 14px;
  font-size: 15px; font-weight: 600;
}
/* Dark CTA (Anthropic-style) */
.btn-dark, .btn.btn-dark, .btn.primary.btn-dark {
  background: #1a1a1a; color: #fff; border: 1px solid #1a1a1a;
}
.btn-dark:hover:not(:disabled) { background: #000; }
.btn-dark:disabled { background: #d1d5db; border-color: #d1d5db; color: #fff; opacity: 0.7; }
[data-theme="dark"] .btn-dark {
  background: #fff; color: #000; border-color: #fff;
}
[data-theme="dark"] .btn-dark:hover:not(:disabled) { background: #e5e7eb; }

.sm-modal-fineprint {
  margin: 12px 0 0; font-size: 11.5px; color: var(--text-3);
  line-height: 1.55; text-align: center;
}
.sm-modal-fineprint-left { text-align: left; }

/* ── Buy modal — pack grid + breakdown ──────────────────────────── */
.sm-pack-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 10px; margin-bottom: 16px;
}
.sm-pack-card {
  border: 1.5px solid var(--border); border-radius: 12px;
  background: var(--bg); cursor: pointer;
  padding: 20px 8px 14px; text-align: center;
  display: flex; flex-direction: column; gap: 6px;
  align-items: center; justify-content: center;
  min-height: 96px;
  transition: border-color 0.15s, background 0.15s;
}
.sm-pack-card:hover { border-color: var(--text-3); }
.sm-pack-card.is-picked {
  border-color: var(--text-1); border-width: 2px;
  padding: 19px 7px 13px;     /* compensate for 2px border to keep size */
}
.sm-pack-price-big {
  font-size: 22px; font-weight: 600; color: var(--text-1);
  font-variant-numeric: tabular-nums; letter-spacing: -0.3px;
}
.sm-pack-save  {
  display: inline-block;
  padding: 3px 10px; border-radius: 10px;
  background: rgba(0, 122, 255, 0.10); color: var(--accent);
  font-size: 11.5px; font-weight: 500;
}
.sm-pack-other .sm-pack-price-big { color: var(--text-2); font-weight: 500; font-size: 17px; }

.sm-breakdown {
  margin-top: 16px; padding: 18px 20px;
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 12px;
}
.sm-breakdown-row {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 14px; padding: 6px 0;
  color: var(--text-1); font-variant-numeric: tabular-nums;
}
.sm-breakdown-row.sm-breakdown-discount { color: var(--text-2); }
.sm-breakdown-row.sm-breakdown-total {
  margin-top: 8px; padding-top: 14px;
  border-top: 1px solid var(--border);
  font-size: 18px; font-weight: 700; color: var(--text-1);
}
.sm-breakdown-aux {
  margin-top: 10px; padding-top: 10px;
  border-top: 1px dashed var(--border);
  font-size: 12px; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

.sm-payment-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 16px; padding: 14px 18px;
  border: 1px solid var(--border); border-radius: 12px;
  font-size: 14px; color: var(--text-2);
}
.sm-payment-card {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--text-1); font-weight: 500;
}

/* Empty states */
.sm-empty, .sm-empty-soft {
  padding: 40px 0; text-align: center; color: var(--text-3); font-size: 13px;
}
.sm-empty-soft { padding: 24px 0; }

/* Callout banner (Privacy) */
.sm-callout {
  background: var(--bg);
  border: 1px solid var(--border); border-radius: 10px;
  padding: 14px 16px;
  font-size: 13px; color: var(--text-2); line-height: 1.55;
  margin-bottom: 8px;
}

/* Mono text */
.sm-mono { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 12.5px; color: var(--text-2); }

/* Last-updated row */
.sm-updated {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text-3);
  padding: 10px 0;
}
.sm-refresh {
  background: transparent; border: none; cursor: pointer;
  color: var(--text-2); padding: 2px 6px; border-radius: 4px;
  display: inline-flex; align-items: center;
}
.sm-refresh:hover { background: var(--selected); color: var(--text); }

/* Avatar (Profile section) */
.sm-avatar-lg {
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--selected); color: var(--text-2);
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 500; overflow: hidden;
}
.sm-avatar-lg img { width: 100%; height: 100%; object-fit: cover; }

/* Toggle switch (macOS-style) */
.sm-toggle { position: relative; display: inline-block; width: 38px; height: 22px; }
.sm-toggle input { opacity: 0; width: 0; height: 0; }
.sm-toggle-slider {
  position: absolute; cursor: pointer; inset: 0;
  background: rgba(120,120,128,0.32);
  border-radius: 999px; transition: background 0.2s;
}
.sm-toggle-slider::before {
  content: ""; position: absolute; height: 18px; width: 18px;
  left: 2px; top: 2px; background: white; border-radius: 50%;
  transition: transform 0.2s;
  box-shadow: 0 2px 4px rgba(0,0,0,0.15), 0 0.5px 1px rgba(0,0,0,0.1);
}
.sm-toggle input:checked + .sm-toggle-slider { background: var(--mc-success); }
.sm-toggle input:checked + .sm-toggle-slider::before { transform: translateX(16px); }

/* Tables (sessions, invoices) */
.sm-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.sm-table th {
  text-align: left; padding: 8px 10px;
  color: var(--text-3); font-weight: 500; font-size: 11.5px;
  text-transform: uppercase; letter-spacing: 0.4px;
  border-bottom: 1px solid var(--border);
}
.sm-table td {
  padding: 10px; color: var(--text);
  border-bottom: 1px solid var(--border);
}
.sm-icon-btn {
  background: transparent; border: none; cursor: pointer;
  color: var(--text-2); padding: 2px 6px; border-radius: 4px;
}
.sm-icon-btn:hover { background: var(--selected); color: var(--text); }

/* Pills */
.sm-pill {
  margin-left: 8px; padding: 2px 8px; border-radius: 8px;
  font-size: 10.5px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.3px;
}
.sm-pill-current { background: var(--accent-soft); color: var(--accent); }
.sm-pill-paid { background: rgba(48,209,88,0.15); color: var(--green); }
.sm-pill-soft {
  background: rgba(0,122,255,0.12); color: var(--accent);
  padding: 1px 8px; border-radius: 8px; font-size: 10.5px; font-weight: 600;
  margin-left: 6px;
}

/* Back button (inline navigation within a panel) */
.sm-back {
  background: transparent; border: none; cursor: pointer;
  color: var(--accent); font-size: 13px; padding: 6px 0;
  margin-bottom: 14px; display: inline-flex; align-items: center; gap: 4px;
}
.sm-back:hover { text-decoration: underline; }

/* Plan picker — Claude-style: spacious cards, big price, black CTA */
.sm-cycle-toggle {
  display: inline-flex; gap: 0;
  background: var(--selected); border-radius: 10px; padding: 3px;
  margin-bottom: 20px;
}
.sm-cycle-toggle-lg {
  padding: 4px;
  border-radius: 999px;
  margin: 0 auto 24px;
  display: flex;
  width: fit-content;
}
.sm-cycle-btn {
  border: none; background: transparent;
  padding: 8px 20px; border-radius: 999px;
  color: var(--text-2); cursor: pointer; font-size: 13.5px;
  display: flex; align-items: center; gap: 8px;
  transition: background 0.15s;
}
.sm-cycle-btn.is-active {
  background: var(--bg-elev); color: var(--text); font-weight: 600;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08), 0 0 0 0.5px rgba(0,0,0,0.04);
}
.sm-pill-save {
  background: rgba(48,209,88,0.18); color: var(--green);
  padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 700;
}
.sm-plans-hero {
  text-align: center;
  padding: 8px 0 18px;
}
.sm-plans-hero h1 {
  margin: 0 0 10px;
  font-size: 28px; font-weight: 700;
  letter-spacing: -0.5px;
  color: var(--text);
}
/* Compact variant — shrinks the hero so the 3-up plan grid fits
   above the fold without scrolling on a typical 800-900px window. */
.sm-plans-hero.is-compact {
  padding: 2px 0 12px;
}
.sm-plans-hero.is-compact h1 {
  font-size: 22px;
  margin: 0 0 6px;
}
.sm-plans-hero.is-compact .sm-plans-sub {
  font-size: 12.5px;
}
.sm-plans-sub {
  font-size: 14px; color: var(--text-2);
  max-width: 560px; margin: 0 auto;
  line-height: 1.5;
}

/* Plan grid — exactly 3 columns on desktop so all paid tiers are
   visible side-by-side without scrolling. Collapses to 1 column on
   very narrow viewports (< 720px) for readability. */
.sm-plan-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
@media (max-width: 720px) {
  .sm-plan-grid { grid-template-columns: 1fr; }
}

/* Claude-style card v2 — compact one-screen variant. The 28px padding
   was generous for a 2-card layout; with 3 cards we drop to 18px to
   keep everything above the fold. */
.sm-plan-card.v2 {
  position: relative;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 18px 18px 16px;
  display: flex; flex-direction: column; gap: 0;
  transition: transform 0.18s, box-shadow 0.18s, border-color 0.18s;
}
.sm-plan-card.v2:hover {
  transform: translateY(-3px);
  box-shadow: 0 16px 32px rgba(0,0,0,0.06), 0 4px 8px rgba(0,0,0,0.04);
  border-color: rgba(0,0,0,0.18);
}
.sm-plan-card.v2.is-current {
  background: rgba(0,0,0,0.03);
  border-color: rgba(0,0,0,0.20);
}
[data-theme="dark"] .sm-plan-card.v2.is-current {
  background: rgba(255,255,255,0.05);
  border-color: rgba(255,255,255,0.15);
}
.sm-plan-card.v2.is-popular { border-color: var(--accent); }
.sm-plan-card.v2.is-popular:hover { border-color: var(--accent); }
.sm-plan-card.v2 .sm-plan-badge {
  position: absolute; top: -9px; left: 50%; transform: translateX(-50%);
  background: var(--accent); color: white;
  padding: 2px 11px; border-radius: 9px;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.3px; white-space: nowrap;
}
.sm-plan-icon {
  color: var(--text);
  opacity: 0.9;
}
/* Compact card layout: cycle pill on its own row at the top, plan
   name + tagline below. Keeps the 3-up grid tight without crowding. */
.sm-plan-card.v2 { padding-top: 18px; }
.sm-plan-card.v2 .sm-plan-cycle {
  position: static;
  margin-bottom: 14px;
  align-self: flex-start;
}
.sm-plan-name-wrap {
  display: flex; flex-direction: column;
  min-width: 0;
  margin-bottom: 12px;
}
.sm-plan-name.v2 { white-space: nowrap; }

/* Per-card cycle toggle (Monthly / Yearly Save 17%) */
.sm-plan-cycle {
  display: inline-flex;
  background: var(--selected);
  border-radius: 999px;
  padding: 2px;
  align-items: center;
}
.sm-plan-cycle-btn {
  border: none; background: transparent;
  padding: 4px 10px; border-radius: 999px;
  color: var(--text-2); cursor: pointer;
  font-size: 11px; font-weight: 500;
  display: inline-flex; align-items: center; gap: 4px;
  transition: background 0.12s;
  font-family: inherit;
  white-space: nowrap;
}
.sm-plan-cycle-btn.is-active {
  background: var(--bg-elev); color: var(--text); font-weight: 600;
  box-shadow: 0 1px 2px rgba(0,0,0,0.08), 0 0 0 0.5px rgba(0,0,0,0.05);
}
.sm-plan-cycle-btn .sm-pill-save {
  padding: 1px 6px; font-size: 9.5px; margin-left: 1px;
}
.sm-plan-name.v2 {
  font-size: 19px; font-weight: 700;
  color: var(--text); letter-spacing: -0.4px;
  line-height: 1.1;
}
.sm-plan-role.v2 {
  font-size: 12px; color: var(--text-2);
  margin-top: 2px; margin-bottom: 0;
}
.sm-plan-price.v2 {
  display: flex; align-items: baseline; gap: 2px;
  margin-bottom: 2px;
}
/* macOS-style currency placement — $ prefix sits in front of the
   number at small-cap size, not floating awkwardly to the right. */
.sm-plan-curr-pre {
  font-size: 18px; font-weight: 600; color: var(--text);
  margin-right: 1px; align-self: flex-start;
  margin-top: 6px;
  letter-spacing: -0.4px;
}
.sm-plan-amt.v2 {
  font-size: 34px; font-weight: 700;
  color: var(--text); letter-spacing: -1.2px;
  line-height: 1; font-variant-numeric: tabular-nums;
}
.sm-plan-per-suffix {
  font-size: 12.5px; color: var(--text-2);
  margin-left: 4px; align-self: flex-end;
  padding-bottom: 4px;
}
.sm-plan-billed-line {
  font-size: 11px; color: var(--text-3);
  line-height: 1.3; margin-bottom: 10px;
}

/* Annual savings line — green, sits just under the price block to
   reinforce the discount choice without screaming. Margins on the
   CTA are owned by the CTA itself for consistent spacing whether
   the savings line is shown or not. */
.sm-plan-savings {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--green);
  margin-top: -4px;
  margin-bottom: 4px;
  letter-spacing: 0.1px;
}
.sm-plan-card.v2 .sm-plan-cta-btn { margin-top: 10px; }

/* ── Pending-downgrade banner (current-tier card) ──────────────────
   Warm yellow + ↺ undo button. Sits between CTA and feature list. */
.sm-plan-pending {
  margin-top: 8px;
  padding: 8px 10px;
  background: color-mix(in oklab, var(--orange) 12%, transparent);
  border: 1px solid color-mix(in oklab, var(--orange) 35%, transparent);
  border-radius: 9px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.sm-plan-pending-msg {
  font-size: 10.5px;
  color: var(--text);
  line-height: 1.4;
}
.sm-plan-pending-undo {
  align-self: flex-start;
  border: none;
  background: var(--bg-elev);
  color: var(--orange);
  border: 1px solid color-mix(in oklab, var(--orange) 40%, transparent);
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, transform 0.05s;
  font-family: inherit;
}
.sm-plan-pending-undo:hover {
  background: color-mix(in oklab, var(--orange) 14%, transparent);
}
.sm-plan-pending-undo:active { transform: scale(0.98); }

/* ── Resume link (pending-target card) ─────────────────────────────
   Sits under the CTA on the tier the user has scheduled to drop to.
   "Trở lại gói Max 20x" pulls them back to where they were. */
.sm-plan-resume {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: center;
}
.sm-plan-resume-btn {
  background: transparent;
  border: 1px dashed var(--border-strong);
  color: var(--accent);
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s, border-color 0.15s, transform 0.05s;
}
.sm-plan-resume-btn:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  border-style: solid;
}
.sm-plan-resume-btn:active { transform: scale(0.98); }
.sm-plan-resume-sub {
  font-size: 10.5px;
  color: var(--text-3);
  letter-spacing: 0.1px;
}

/* Highlight the pending-target card subtly — dashed accent ring so
   user can spot at a glance which tier they're scheduled to land on. */
.sm-plan-card.v2.is-pending-target {
  border-style: dashed;
  border-color: var(--orange);
  background: color-mix(in oklab, var(--orange) 4%, var(--bg-elev));
}

.sm-plan-cta-btn {
  width: 100%;
  padding: 9px 14px;
  border-radius: 9px;
  background: var(--text);
  color: var(--bg-elev);
  border: none; cursor: pointer;
  font-size: 12.5px; font-weight: 600;
  white-space: nowrap;
  transition: opacity 0.15s, transform 0.05s;
  font-family: inherit;
}
.sm-plan-cta-btn:hover { opacity: 0.85; }
.sm-plan-cta-btn:active { transform: scale(0.99); }
.sm-plan-cta-btn.is-disabled,
.sm-plan-cta-btn:disabled {
  background: var(--selected);
  color: var(--text-3);
  cursor: not-allowed;
  opacity: 1;
}
.sm-plan-card.v2.is-popular .sm-plan-cta-btn {
  background: var(--accent);
  color: white;
}
.sm-plan-card.v2.is-popular .sm-plan-cta-btn:hover { background: var(--accent-hover); opacity: 1; }

.sm-plan-subtext {
  text-align: center; font-size: 10.5px;
  color: var(--text-3); margin-top: 6px;
  letter-spacing: 0.1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.sm-plan-feats-header {
  font-size: 11.5px; font-weight: 600;
  color: var(--text); margin-top: 14px;
  margin-bottom: 7px;
}
.sm-plan-feats.v2 {
  list-style: none; padding: 0; margin: 0;
}
.sm-plan-feats.v2 li {
  font-size: 12px; color: var(--text-2);
  padding: 3px 0 3px 20px; position: relative;
  line-height: 1.4;
}
.sm-plan-feats.v2 li::before {
  content: "✓"; position: absolute; left: 0; top: 3px;
  color: var(--text); font-weight: 600;
  font-size: 11px;
}

/* Checkout form (inline payment) */
.sm-checkout {
  display: grid; grid-template-columns: 1.4fr 1fr; gap: 24px;
  margin-top: 8px;
}
.sm-checkout-form { display: flex; flex-direction: column; gap: 14px; }
.sm-form-row { display: flex; flex-direction: column; gap: 5px; }
.sm-form-row > label {
  font-size: 11px; color: var(--text-2);
  text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600;
}
.sm-form-input {
  width: 100%; min-width: 0; text-align: left !important;
}
.sm-form-grid-2 {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
}
.sm-form-actions {
  display: flex; gap: 10px; justify-content: flex-end;
  margin-top: 6px; padding-top: 14px;
  border-top: 1px solid var(--border);
}
.sm-error {
  color: var(--red); font-size: 12.5px;
  padding: 8px 12px; background: rgba(255,59,48,0.08);
  border-radius: 6px;
}
.sm-checkout-summary {
  background: var(--rail); border: 1px solid var(--border);
  border-radius: 12px; padding: 16px; height: fit-content;
}
.sm-summary-title {
  font-size: 11px; color: var(--text-3);
  text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600;
  margin-bottom: 12px;
}
.sm-summary-row {
  display: flex; justify-content: space-between;
  font-size: 13px; padding: 6px 0;
  font-variant-numeric: tabular-nums;
}
.sm-summary-discount { color: var(--green); }
.sm-summary-total {
  border-top: 1px solid var(--border); margin-top: 8px;
  padding-top: 12px; font-weight: 700; font-size: 15px;
}
.sm-summary-note {
  font-size: 11px; color: var(--text-3); line-height: 1.5;
  margin-top: 14px; padding-top: 14px;
  border-top: 1px solid var(--border);
}

/* Success state */
.sm-success {
  text-align: center; padding: 40px 20px;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}
.sm-success-icon {
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--green); color: white;
  display: flex; align-items: center; justify-content: center;
  font-size: 28px; font-weight: 700;
  margin-bottom: 8px;
  animation: smPop 0.3s ease-out;
}
.sm-success h2 { margin: 0; font-size: 19px; font-weight: 600; }
.sm-success p { margin: 0; color: var(--text-2); font-size: 14px; max-width: 380px; line-height: 1.5; }

/* Billing hero */
.sm-billing-hero {
  display: flex; gap: 14px; align-items: center;
  padding: 18px 20px; background: var(--bg);
  border: 1px solid var(--border); border-radius: 12px;
}
.sm-billing-icon {
  width: 44px; height: 44px; border-radius: 12px;
  background: var(--accent-soft); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; flex-shrink: 0;
}
.sm-billing-info { flex: 1; min-width: 0; }
.sm-billing-tier { font-size: 16px; font-weight: 600; color: var(--text); }
.sm-billing-role { font-size: 12px; color: var(--text-3); margin-top: 2px; }
.sm-billing-renew { font-size: 12px; color: var(--text-2); margin-top: 6px; }

/* ── Avatar dropdown redesign (Claude-style) ──────────────────── */
.account-menu-email {
  padding: 10px 14px;
  font-size: 13px; color: var(--text-2);
  border-bottom: 1px solid var(--border);
}
.account-menu-danger {
  color: var(--red) !important;
}
.account-menu-danger .mi-icon { color: var(--red); }
.account-menu-card {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px;
}
.account-menu-card-avatar {
  width: 32px; height: 32px; border-radius: 8px;
  background: var(--orange); color: white;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; overflow: hidden;
  flex-shrink: 0;
}
.account-menu-card-avatar img { width: 100%; height: 100%; object-fit: cover; }
.account-menu-card-avatar.is-anon { background: var(--dot); color: var(--text-3); }
.account-menu-card-id { flex: 1; min-width: 0; }
.account-menu-card-name {
  font-size: 13px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.account-menu-card-plan {
  font-size: 11.5px; color: var(--text-3); margin-top: 1px;
}
.account-menu-card-btn {
  background: transparent; border: none; cursor: pointer;
  color: var(--text-2); padding: 6px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
}
.account-menu-card-btn:hover { background: var(--selected); color: var(--text); }

/* ── Usage screen (Plan limits, 5h window, monthly tracking) ──
   Tier quotas from docs/specs/01_Tab_Nang_Cap_Tai_Khoan.md.
   5h rolling window + monthly subscription period. */
.usage-screen {
  height: 100%; width: 100%; padding: 28px 36px; overflow-y: auto;
  background: var(--bg); max-width: 980px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 22px;
}

/* v2.3: block banner — surfaces when any of the 3 quota windows is over cap.
   Color shifts by which window is blocking so users learn at a glance whether
   they hit the 5h burst cap (amber), the weekly fair-use cap (red), or the
   monthly billing cap (purple, since they can buy credits). */
.usage-block-banner {
  padding: 14px 18px; border-radius: 12px; margin-bottom: 4px;
  background: rgba(220, 38, 38, 0.08);
  border: 1px solid rgba(220, 38, 38, 0.35);
  color: var(--text-1);
}
.usage-block-banner[data-window="5h"]    { background: rgba(245, 158, 11, 0.10);
                                            border-color: rgba(245, 158, 11, 0.40); }
.usage-block-banner[data-window="week"]  { background: rgba(220, 38, 38, 0.10);
                                            border-color: rgba(220, 38, 38, 0.45); }
.usage-block-banner[data-window="month"] { background: rgba(168, 85, 247, 0.10);
                                            border-color: rgba(168, 85, 247, 0.40); }
.usage-block-title { font-weight: 700; font-size: 14px; margin-bottom: 4px; }
.usage-block-body  { font-size: 12.5px; color: var(--text-2); line-height: 1.5; }

/* Convention note — explains why words is primary unit, drawings is derived */
.usage-convention {
  font-size: 12px; color: var(--text-2); line-height: 1.55;
  padding: 10px 14px;
  background: rgba(0, 122, 255, 0.06);
  border-left: 3px solid rgba(0, 122, 255, 0.45);
  border-radius: 0 8px 8px 0;
}
.usage-convention b { color: var(--text-1); font-weight: 600; }
[data-theme="dark"] .usage-convention {
  background: rgba(64, 156, 255, 0.08);
  border-left-color: rgba(64, 156, 255, 0.5);
}

/* Plan card — top hero showing current tier + upgrade CTA */
.usage-plan-card {
  display: flex; justify-content: space-between; align-items: center;
  gap: 16px; padding: 18px 22px;
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 14px; box-shadow: var(--shadow-sm);
}
.usage-plan-eyebrow {
  font-size: 11px; color: var(--text-3); text-transform: uppercase;
  letter-spacing: 0.5px; margin-bottom: 6px;
}
.usage-plan-name { display: flex; align-items: center; gap: 12px; margin-bottom: 4px; }
.usage-plan-price { font-size: 15px; color: var(--text-2); font-weight: 500; }
.usage-plan-role { font-size: 12.5px; color: var(--text-3); font-style: italic; }
.usage-plan-top { color: var(--text-2); font-size: 13px; padding: 6px 12px; background: var(--selected); border-radius: 8px; }

/* Section headers */
.usage-section { display: flex; flex-direction: column; gap: 12px; }
.usage-section-head {
  display: flex; align-items: center; gap: 10px;
  border-bottom: 1px solid var(--border); padding-bottom: 10px;
}
.usage-section-head h2 { margin: 0; font-size: 15px; font-weight: 600; }
.usage-resets {
  margin-left: auto; font-size: 11.5px; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

/* Plan pill (small colored chip with tier label) */
.usage-plan-pill {
  padding: 3px 10px; border-radius: 10px; color: white;
  font-size: 11px; font-weight: 700; letter-spacing: 0.3px;
  text-transform: uppercase;
}

/* Two-column quota row (words + drawings side by side) */
.usage-quota-row {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 12px; padding: 14px 16px;
  display: flex; flex-direction: column; gap: 12px;
}
.usage-quota-head .usage-row-title { font-size: 14px; font-weight: 500; }
.usage-quota-head .usage-row-sub { font-size: 11.5px; color: var(--text-3); margin-top: 3px; max-width: 600px; }
.usage-quota-twins {
  display: grid; grid-template-columns: 1fr 1fr; gap: 18px;
  margin-top: 4px;
}
.usage-quota-side {
  display: flex; flex-direction: column; gap: 6px;
}
.usage-quota-side-head {
  display: flex; justify-content: space-between; align-items: baseline;
}
.usage-quota-side-label {
  font-size: 11px; color: var(--text-2); text-transform: uppercase;
  letter-spacing: 0.5px; font-weight: 500;
}
.usage-quota-side-num {
  font-size: 13px; color: var(--text); font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.usage-quota-side-num .dim { color: var(--text-3); font-weight: 400; }

/* Generic row (single quota or feature) */
.usage-row {
  display: flex; gap: 16px; align-items: center;
  padding: 10px 4px;
}
.usage-row-l { flex: 1; min-width: 0; }
.usage-row-r { flex: 0 0 220px; display: flex; justify-content: flex-end; align-items: center; }
.usage-row-title { font-size: 13.5px; color: var(--text); font-weight: 500; }
.usage-row-sub { font-size: 11.5px; color: var(--text-3); margin-top: 2px; max-width: 540px; }

/* Progress bar */
.usage-bar { display: flex; align-items: center; gap: 10px; width: 100%; }
.usage-bar-track { flex: 1; background: var(--selected); border-radius: 999px; overflow: hidden; }
.usage-bar-fill { height: 100%; border-radius: 999px; transition: width 0.35s ease; }
.usage-bar-text {
  flex: 0 0 46px; text-align: right; font-size: 12px;
  color: var(--text-2); font-variant-numeric: tabular-nums;
}

/* Session stats grid */
.usage-session-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px;
}
.usage-stat {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 10px; padding: 14px; text-align: center;
}
.usage-stat-num {
  font-size: 24px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums; line-height: 1.1;
}
.usage-stat-label {
  font-size: 11px; color: var(--text-3); text-transform: uppercase;
  letter-spacing: 0.4px; margin-top: 4px;
}

/* Extra credits row */
.usage-extras {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; background: var(--bg);
  border-radius: 8px;
}
.usage-extra-num {
  font-size: 14px; font-weight: 600; color: var(--orange);
  font-variant-numeric: tabular-nums;
}

/* Footer "updated at" */
.usage-updated {
  display: flex; align-items: center; gap: 6px; justify-content: flex-end;
  font-size: 11px; color: var(--text-3);
  padding-top: 8px;
}
.usage-refresh {
  background: transparent; border: none; cursor: pointer;
  color: var(--text-2); font-size: 14px; padding: 2px 6px;
  border-radius: 4px;
}
.usage-refresh:hover { background: var(--selected); color: var(--text); }

/* Loading / error */
.usage-loading, .usage-error { padding: 40px 20px; text-align: center; color: var(--text-2); }
.usage-error { color: var(--red); }

/* Toggle switch (auto top-up) */
.usage-toggle { position: relative; display: inline-block; width: 40px; height: 22px; }
.usage-toggle input { opacity: 0; width: 0; height: 0; }
.usage-toggle-slider {
  position: absolute; cursor: pointer; inset: 0;
  background: var(--dot); border-radius: 999px; transition: 0.2s;
}
.usage-toggle-slider::before {
  content: ""; position: absolute; height: 16px; width: 16px;
  left: 3px; top: 3px; background: white; border-radius: 50%;
  transition: 0.2s; box-shadow: var(--shadow-sm);
}
.usage-toggle input:checked + .usage-toggle-slider { background: var(--accent); }
.usage-toggle input:checked + .usage-toggle-slider::before { transform: translateX(18px); }

/* Upgrade CTA */
.usage-cta {
  display: flex; align-items: center; gap: 16px; justify-content: space-between;
  padding: 16px 20px; background: var(--accent-soft);
  border: 1px solid var(--accent); border-radius: 12px;
}
.usage-cta h3 { margin: 0 0 4px 0; font-size: 15px; }
.usage-cta p { margin: 0; font-size: 13px; color: var(--text-2); line-height: 1.5; }
/* ── Spec tab summary screens ──────────────────────────────────
   Top-level summary for each of 6 business model tabs (subscription,
   affiliate, team, partner, marketplace, pioneer). Card + tier grid
   pattern reused across all 6. */
.spec-tab {
  height: 100%; width: 100%; padding: 24px 32px; overflow-y: auto;
  background: var(--bg); display: flex; flex-direction: column; gap: 24px;
  max-width: 1100px; margin: 0 auto;
}
.spec-tab-hero { border-bottom: 1px solid var(--border); padding-bottom: 20px; }
.spec-tab-eyebrow {
  font-size: 11px; color: var(--accent); font-weight: 600;
  text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px;
}
.spec-tab h1 {
  margin: 0 0 12px 0; font-size: 28px; font-weight: 700;
  letter-spacing: -0.5px;
}
.spec-tab h2 {
  margin: 0 0 14px 0; font-size: 18px; font-weight: 600;
}
.spec-tab-lede { color: var(--text-2); font-size: 14px; line-height: 1.5; margin: 0; max-width: 720px; }
.spec-tab-foot { padding-top: 16px; border-top: 1px solid var(--border); }
.spec-link {
  color: var(--accent); text-decoration: none; font-size: 13px;
  font-weight: 500;
}
.spec-link:hover { text-decoration: underline; }
.spec-section { display: flex; flex-direction: column; gap: 12px; }

/* Card row — used for high-level metric/feature cards */
.spec-cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
.spec-card {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 12px; padding: 16px; box-shadow: var(--shadow-sm);
}
.spec-card-num {
  font-size: 36px; font-weight: 700; color: var(--accent);
  line-height: 1; margin-bottom: 8px;
}
.spec-card h3 { margin: 0 0 6px 0; font-size: 15px; }
.spec-card p { color: var(--text-2); font-size: 13px; margin: 0; line-height: 1.45; }

/* Tier grid — used by all 6 tabs for the 3-tier display */
.spec-tier-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.spec-tier {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 12px; padding: 16px; display: flex; flex-direction: column;
  gap: 10px;
}
.spec-tier h4 { margin: 0; font-size: 17px; font-weight: 600; }
.spec-tier-req {
  font-size: 11px; color: var(--text-2); text-transform: uppercase;
  letter-spacing: 0.5px;
}
.spec-tier ul { margin: 0; padding-left: 18px; }
.spec-tier li {
  font-size: 13px; color: var(--text); line-height: 1.45;
  margin-bottom: 4px;
}
.spec-tier.bronze { border-left: 3px solid #cd7f32; }
.spec-tier.silver { border-left: 3px solid #aaa; }
.spec-tier.gold   { border-left: 3px solid var(--accent); background: var(--accent-soft); }

/* 2-col feature grid */
.spec-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.spec-feat {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 10px; padding: 14px;
}
.spec-feat h4 { margin: 0 0 6px 0; font-size: 14px; font-weight: 600; }
.spec-feat p { margin: 0; font-size: 13px; color: var(--text-2); line-height: 1.45; }

/* Bullet lists */
.spec-bullets { margin: 0; padding-left: 18px; }
.spec-bullets li { font-size: 13px; color: var(--text); line-height: 1.55; margin-bottom: 4px; }

/* Flow numbered list */
.spec-flow { padding-left: 22px; margin: 0; }
.spec-flow li { font-size: 13px; line-height: 1.65; margin-bottom: 6px; color: var(--text); }
.spec-flow b { color: var(--accent); }

/* Privacy callout */
.spec-privacy {
  display: flex; flex-direction: column; gap: 8px;
}
.spec-privacy-row {
  display: flex; align-items: center; gap: 12px; padding: 10px 12px;
  border-radius: 8px; font-size: 13px;
}
.spec-privacy-row.pass { background: rgba(48,209,88,0.10); border: 1px solid rgba(48,209,88,0.3); }
.spec-privacy-row.fail { background: rgba(255,59,48,0.10); border: 1px solid rgba(255,59,48,0.3); }
.spec-badge {
  font-size: 10px; font-weight: 700; padding: 3px 8px; border-radius: 6px;
  text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap;
}
.spec-badge.ok { background: var(--green); color: white; }
.spec-badge.no { background: var(--red);   color: white; }
.spec-note {
  font-size: 12px; color: var(--text-2); font-style: italic;
  margin: 8px 0 0 0;
}

/* ── Teams management screen ────────────────────────────────────
   List of teams + roster + invite form. Card-per-team layout. */
.teams-screen {
  height: 100%; min-height: 0; width: 100%; padding: 20px 24px;
  display: flex; flex-direction: column; gap: 16px; overflow-y: auto;
  background: var(--bg);
}
.teams-toolbar {
  display: flex; justify-content: space-between; align-items: center;
  padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.teams-toolbar-l { display: flex; align-items: baseline; gap: 8px; }
.teams-title { font-size: 22px; font-weight: 600; margin: 0; }
.teams-email { color: var(--text-2); font-size: 13px; }
.teams-empty { text-align: center; padding: 60px 20px; color: var(--text-2); }
.teams-empty h3 { color: var(--text); margin-bottom: 8px; }
.teams-signin-prompt {
  padding: 20px; background: var(--panel-solid);
  border: 1px solid var(--border); border-radius: 10px;
  text-align: center; color: var(--text-2);
}
.teams-loading { padding: 30px; text-align: center; color: var(--text-2); }
.teams-list { display: flex; flex-direction: column; gap: 16px; }
.teams-card {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 12px; padding: 16px; box-shadow: var(--shadow-sm);
}
.teams-card-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  margin-bottom: 12px;
}
.teams-card-name { margin: 0 0 4px 0; font-size: 17px; font-weight: 600; }
.teams-card-meta { display: flex; gap: 10px; align-items: center; font-size: 12px; }
.teams-badge {
  background: var(--accent-soft); color: var(--accent);
  padding: 2px 8px; border-radius: 8px; font-weight: 600;
}
.teams-seats { color: var(--text-2); }
.teams-role-self {
  background: var(--selected); padding: 1px 6px; border-radius: 6px;
  text-transform: capitalize; color: var(--text-2);
}
.teams-roster {
  width: 100%; border-collapse: collapse; font-size: 13px;
  margin-bottom: 12px;
}
.teams-roster th, .teams-roster td {
  text-align: left; padding: 6px 8px;
  border-bottom: 1px solid var(--border);
}
.teams-roster th { color: var(--text-2); font-weight: 500; font-size: 11px; text-transform: uppercase; }
.teams-actions { display: flex; gap: 4px; justify-content: flex-end; }
/* Pending-approval section — members who accepted invitation but
   admin/owner hasn't approved yet. Distinct visual treatment (warm
   yellow tone) to draw admin's eye. */
.teams-approvals {
  background: rgba(255, 204, 0, 0.08);
  border: 1px solid rgba(255, 204, 0, 0.35);
  padding: 12px 14px; border-radius: 10px;
  margin-bottom: 12px; font-size: 13px;
}
.teams-approvals h5 {
  margin: 0 0 8px 0; font-size: 12px; font-weight: 600;
  color: var(--text); display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
}
.teams-approvals-hint {
  font-size: 11.5px; font-weight: 400; color: var(--text-2);
  text-transform: none; letter-spacing: 0;
}
.teams-approvals-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.teams-approvals-list li {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  padding: 6px 0; border-bottom: 1px dashed rgba(255, 204, 0, 0.25);
}
.teams-approvals-list li:last-child { border-bottom: none; }
.teams-appr-email { font-weight: 500; }
.teams-appr-role { color: var(--accent); font-weight: 500; font-size: 12px; }
.teams-appr-joined { color: var(--text-3); font-size: 12px; }
.teams-appr-actions { display: flex; gap: 6px; margin-left: auto; }

.teams-pending {
  background: var(--bg); padding: 8px 12px; border-radius: 8px;
  margin-bottom: 12px; font-size: 12px;
}
.teams-pending h5 { margin: 0 0 6px 0; color: var(--text-2); font-size: 11px; text-transform: uppercase; }
.teams-pending ul { list-style: none; padding: 0; margin: 0; }
.teams-pending li {
  display: flex; gap: 10px; align-items: center;
  padding: 4px 0; border-bottom: 1px dashed var(--border);
}
.teams-pending li:last-child { border-bottom: none; }
.teams-pending-role { color: var(--accent); font-weight: 500; }
.teams-pending-exp { color: var(--text-3); margin-left: auto; }
.teams-invite-form {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  padding-top: 8px; border-top: 1px dashed var(--border);
}
.teams-invite-form input[type=email] {
  flex: 1; min-width: 200px; padding: 6px 10px;
  border: 1px solid var(--border-strong); border-radius: 6px;
  background: var(--bg-elev); color: var(--text);
}
.teams-invite-form select {
  padding: 6px 10px; border: 1px solid var(--border-strong);
  border-radius: 6px; background: var(--bg-elev); color: var(--text);
}
.teams-msg { width: 100%; color: var(--accent); font-size: 12px; padding-top: 4px; }
.teams-err { color: var(--red); font-size: 13px; padding: 8px 0; }
.teams-token {
  width: 100%; display: flex; gap: 8px; align-items: center;
  background: var(--panel-solid); padding: 6px 10px; border-radius: 6px;
}
.teams-token code {
  flex: 1; font-family: ui-monospace, "SF Mono", monospace; font-size: 11px;
  word-break: break-all; color: var(--text);
}
.teams-full {
  color: var(--orange); font-size: 12px; padding: 6px 0;
  border-top: 1px dashed var(--border);
}
.teams-my-invites {
  background: var(--accent-soft); border: 1px solid var(--accent);
  border-radius: 12px; padding: 16px;
}
.teams-my-invites h3 { margin: 0 0 10px 0; font-size: 14px; color: var(--accent); }
.teams-my-invites-hint {
  font-size: 12px; color: var(--text-2); margin-bottom: 10px;
  line-height: 1.5;
}
.teams-invite-row {
  display: flex; align-items: center; gap: 12px; padding: 6px 0;
}
.teams-invite-exp { color: var(--text-3); margin-left: auto; font-size: 12px; }
/* Create-team modal */
.teams-modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,0.45);
  z-index: 1000; display: flex; align-items: center; justify-content: center;
}
.teams-modal {
  background: var(--bg-elev); border-radius: 14px; padding: 22px;
  width: 380px; max-width: 90vw; box-shadow: var(--shadow-lg);
}
.teams-modal-title { margin: 0 0 16px 0; font-size: 17px; font-weight: 600; }
.teams-field {
  display: flex; flex-direction: column; gap: 4px; margin-bottom: 14px;
}
.teams-field span {
  font-size: 12px; color: var(--text-2); text-transform: uppercase;
  letter-spacing: 0.5px;
}
.teams-field input, .teams-field select {
  padding: 8px 10px; border: 1px solid var(--border-strong);
  border-radius: 8px; background: var(--bg); color: var(--text);
  font-size: 14px;
}
.teams-modal-actions {
  display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px;
}

/* ── Shared TM dashboard ────────────────────────────────────────
   Admin view của shared_translations. Sticky toolbar trên, sortable
   grid dưới. Provenance badges dùng accent tints theo từng nguồn
   để eye-scan trong table dense. */
.stm-screen {
  height: 100%; min-height: 0;
  width: 100%;
  display: flex; flex-direction: column;
  /* Full-width frame — was ``padding: 18px 24px`` which subtracted
     48 px of horizontal space and left a generous gutter to the
     right of the table. User wants the library to fill the entire
     screen width. Side padding is dropped; top padding preserved so
     the toolbar doesn't kiss the tab strip. */
  padding: 18px 0 0;
  gap: 14px;
}
.stm-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  position: sticky; top: 0; z-index: 5;
}
.stm-toolbar-l, .stm-toolbar-r {
  display: flex; align-items: center; gap: 10px;
}

/* Segmented language filter — macOS NSSegmentedControl-ish.
   ``flex-wrap`` lets the 16-language strip break onto a second row on
   narrower windows instead of clipping the right-side options. */
.stm-seg {
  display: inline-flex;
  flex-wrap: wrap;
  row-gap: 4px;
  background: color-mix(in oklab, var(--text-3) 10%, transparent);
  border-radius: 8px;
  padding: 2px;
}
.stm-seg-btn {
  padding: 4px 12px;
  background: transparent;
  border: none;
  font-size: 12px; font-weight: 600;
  color: var(--text-2);
  border-radius: 6px;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.stm-seg-btn:hover { color: var(--text); }
.stm-seg-btn.on {
  background: var(--panel-solid, #fff);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(0,0,0,0.08);
}
[data-theme="dark"] .stm-seg-btn.on {
  background: #3A3A3C;
  box-shadow: 0 1px 2px rgba(0,0,0,0.4);
}

.stm-select {
  padding: 5px 10px;
  font-size: 12px; font-weight: 500;
  color: var(--text);
  background: var(--panel-solid, #fff);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  outline: none;
  font-family: inherit;
}
.stm-select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 22%, transparent);
}

.stm-pager-info {
  font-size: 12px; color: var(--text-2);
}
.stm-pager-btn {
  width: 28px; height: 26px;
  font-size: 16px; line-height: 1;
  background: var(--panel-solid, #fff);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.stm-pager-btn:hover:not(:disabled) {
  background: color-mix(in oklab, var(--accent) 8%, var(--panel-solid, #fff));
  border-color: color-mix(in oklab, var(--accent) 28%, var(--border));
}
.stm-pager-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.stm-spinner-sm {
  width: 12px; height: 12px;
  border: 2px solid var(--text-3);
  border-top-color: transparent;
  border-radius: 50%;
  animation: bl-spin 700ms linear infinite;
}

.stm-error {
  padding: 8px 12px;
  font-size: 12px;
  color: var(--red, var(--mc-danger));
  background: color-mix(in oklab, var(--red, var(--mc-danger)) 8%, transparent);
  border: 1px solid color-mix(in oklab, var(--red, var(--mc-danger)) 24%, transparent);
  border-radius: 8px;
}

.stm-grid-wrap {
  flex: 1 1 auto;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-solid, #fff);
}
.stm-grid {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.stm-grid thead th {
  position: sticky; top: 0;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  padding: 10px 12px;
  text-align: left;
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-2);
  white-space: nowrap;
}
.stm-grid tbody td {
  padding: 9px 12px;
  border-bottom: 1px solid color-mix(in oklab, var(--border) 60%, transparent);
  vertical-align: middle;
}
.stm-grid tbody tr:hover td {
  background: color-mix(in oklab, var(--accent) 5%, transparent);
}

.stm-num   { color: var(--text-3); font-variant-numeric: tabular-nums; }
.stm-num-r { text-align: right; font-variant-numeric: tabular-nums; }
.stm-src   { font-weight: 500; max-width: 280px;
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stm-tr    { color: var(--text); max-width: 320px;
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stm-empty {
  text-align: center; padding: 36px 12px;
  color: var(--text-3); font-style: italic; font-size: 12px;
}

/* Infinite-scroll sentinel — thin row reserved for the "loading more…"
   hint. Stays invisible until IntersectionObserver fires the next
   fetch and ``busy`` flips, keeping the table from jumping. */
.stm-sentinel td {
  text-align: center; padding: 14px 12px;
  color: var(--text-3); font-size: 11.5px;
  border-bottom: none;
}

/* ── Country picker (chip + searchable popover) ─────────────────────
   Replaces the previous 25-button wrap strip. The chip shows the
   selected country; clicking it opens a popover with a search input
   and the full country list filtered as the user types. Compact +
   single-source-of-truth for the selected lang. */
.stm-cp { position: relative; display: inline-flex; }
.stm-cp-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px;
  font-size: 12.5px; line-height: 1;
  background: var(--panel-solid, #fff);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
  min-width: 200px;
}
.stm-cp-chip:hover {
  background: color-mix(in oklab, var(--accent) 6%, var(--panel-solid, #fff));
  border-color: color-mix(in oklab, var(--accent) 28%, var(--border));
}
.stm-cp-chip.on {
  border-color: color-mix(in oklab, var(--accent) 50%, var(--border));
  background: color-mix(in oklab, var(--accent) 8%, var(--panel-solid, #fff));
}
.stm-cp-chip-code {
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 4px;
  background: color-mix(in oklab, var(--text-3) 14%, transparent);
  color: var(--text-2);
  letter-spacing: 0.04em;
  font-size: 10.5px;
}
.stm-cp-chip-label { flex: 1; text-align: left; }
.stm-cp-chip-caret { font-size: 10px; color: var(--text-3); }

.stm-cp-pop {
  position: absolute; top: calc(100% + 6px); left: 0;
  z-index: 30;
  width: 280px;
  max-height: 360px;
  background: var(--panel-solid, #fff);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  display: flex; flex-direction: column;
  overflow: hidden;
}
[data-theme="dark"] .stm-cp-pop {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
}
.stm-cp-search-wrap {
  padding: 8px;
  border-bottom: 1px solid var(--border);
}
.stm-cp-search {
  width: 100%;
  padding: 6px 10px;
  font-size: 13px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel);
  color: var(--text);
  outline: none;
}
.stm-cp-search:focus {
  border-color: color-mix(in oklab, var(--accent) 50%, var(--border));
}
.stm-cp-list {
  flex: 1; overflow: auto;
  padding: 4px;
}
.stm-cp-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  padding: 6px 8px;
  background: transparent; border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12.5px;
  color: var(--text);
  text-align: left;
}
.stm-cp-item:hover {
  background: color-mix(in oklab, var(--accent) 10%, transparent);
}
.stm-cp-item.on {
  background: color-mix(in oklab, var(--accent) 14%, transparent);
  color: var(--text);
  font-weight: 600;
}
.stm-cp-item-code {
  font-size: 10.5px; font-weight: 600;
  padding: 1px 6px;
  border-radius: 4px;
  background: color-mix(in oklab, var(--text-3) 14%, transparent);
  color: var(--text-2);
  letter-spacing: 0.04em;
}
.stm-cp-item-label { flex: 1; }
.stm-cp-empty {
  padding: 16px 12px;
  text-align: center;
  font-style: italic;
  color: var(--text-3);
  font-size: 12px;
}

/* Provenance badges — tint theo nguồn, đủ contrast trong cả light
   và dark theme. */
.stm-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px;
  font-size: 10.5px; font-weight: 600;
  border-radius: 999px;
  letter-spacing: 0.02em;
}
.stm-badge-ai {
  background: color-mix(in oklab, var(--mc-accent) 14%, transparent);
  color: color-mix(in oklab, var(--mc-accent) 90%, var(--text));
}
.stm-badge-seed {
  background: color-mix(in oklab, var(--text-3) 18%, transparent);
  color: var(--text-2);
}
.stm-badge-verified {
  background: color-mix(in oklab, #34C759 16%, transparent);
  color: color-mix(in oklab, #34C759 80%, var(--text));
}
.stm-badge-community {
  background: color-mix(in oklab, var(--mc-warn) 16%, transparent);
  color: color-mix(in oklab, var(--mc-warn) 80%, var(--text));
}
.stm-badge-manual {
  background: color-mix(in oklab, var(--mc-warn) 16%, transparent);
  color: color-mix(in oklab, var(--mc-warn) 80%, var(--text));
}
.stm-badge-other {
  background: color-mix(in oklab, var(--text-3) 12%, transparent);
  color: var(--text-3);
}

.stm-vote-btn {
  padding: 4px 10px;
  font-size: 11.5px; font-weight: 600;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: background 120ms ease, transform 80ms ease;
}
.stm-vote-btn:hover:not(:disabled) {
  background: color-mix(in oklab, var(--accent) 88%, black);
}
.stm-vote-btn:active:not(:disabled) { transform: scale(0.96); }
.stm-vote-btn:disabled {
  background: color-mix(in oklab, var(--text-3) 16%, transparent);
  color: var(--text-2);
  cursor: not-allowed;
}

/* ── Phase bars (Xử lý text — 2 pha) ────────────────────────────
   Vùng giữa table và log panel, dành cho user theo dõi tiến độ
   Pha 1 (Gộp text) + Pha 2 (Chuyển font). Mỗi bar có:
     * Số pha (chip tròn nhỏ)
     * Label (Gộp text / Chuyển font Arial)
     * Meta text (X/Y · Z%, "đang quét…", "xong")
     * Track + fill (gradient xanh, indeterm dùng slide animation)
*/
.phase-bars {
  display: flex; flex-direction: column;
  gap: 6px;
  padding: 8px 12px;
  background: color-mix(in oklab, var(--accent, var(--mc-accent)) 6%, transparent);
  border: 1px solid color-mix(in oklab, var(--accent, var(--mc-accent)) 18%, var(--border));
  border-radius: 8px;
  margin: 8px 0;
}
.phase-bar {
  display: flex; flex-direction: column;
  gap: 4px;
}
.phase-bar.is-idle  { opacity: 0.55; }
.phase-bar.is-done  { opacity: 1; }
.phase-bar-head {
  display: flex; align-items: center;
  gap: 8px;
  font-size: 11.5px;
}
.phase-bar-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px;
  border-radius: 50%;
  font-size: 10.5px; font-weight: 700;
  background: var(--accent, var(--mc-accent));
  color: #fff;
  flex: 0 0 auto;
}
.phase-bar.is-done .phase-bar-num {
  background: var(--green, #34c759);
}
.phase-bar.is-idle .phase-bar-num {
  background: color-mix(in oklab, var(--text-3) 30%, transparent);
}
.phase-bar-label {
  font-weight: 600;
  color: var(--text);
  flex: 1 1 auto;
}
.phase-bar-meta {
  font-size: 11px;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}
.phase-bar-track {
  position: relative;
  height: 6px;
  background: color-mix(in oklab, var(--text-3) 15%, transparent);
  border-radius: 3px;
  overflow: hidden;
}
.phase-bar-fill {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  background: linear-gradient(90deg,
    var(--accent, var(--mc-accent)),
    color-mix(in oklab, var(--accent, var(--mc-accent)) 80%, white));
  border-radius: 3px;
  transition: width 220ms cubic-bezier(0.22, 0.9, 0.3, 1);
}
.phase-bar.is-done .phase-bar-fill {
  background: linear-gradient(90deg,
    var(--green, #34c759),
    color-mix(in oklab, var(--green, #34c759) 80%, white));
}
/* Indeterminate slide — width=30% fixed + translate left/right */
.phase-bar-fill.is-indeterm {
  animation: phase-indeterm 1.4s linear infinite;
}
@keyframes phase-indeterm {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(366%); }   /* 30% width × ~3.3 sweeps */
}

/* ── Blacklist full-screen wrapper ──────────────────────────────
   Reuse các class .bl-* hiện có từ Library modal (.bl-section,
   .bl-input, .bl-chips, .bl-tag, .bl-empty, .bl-spinner...). Bổ
   sung wrapper layout cho full-screen mode. */
.bl-screen {
  height: 100%; min-height: 0;
  display: flex; flex-direction: column;
  padding: 18px 24px 0;
  gap: 14px;
  overflow: hidden;
}
.bl-screen-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  position: sticky; top: 0; z-index: 5;
}
.bl-screen-toolbar-l {
  display: flex; align-items: center; gap: 10px;
  min-width: 0;
}
.bl-screen-icon {
  width: 32px; height: 32px;
  border-radius: 8px;
  background: color-mix(in oklab, var(--accent) 14%, transparent);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
}
.bl-screen-title {
  font-size: 13px; font-weight: 600;
  color: var(--text);
  letter-spacing: -0.01em;
}
.bl-screen-sub {
  font-size: 11.5px; color: var(--text-2);
  margin-top: 2px;
  max-width: 540px;
  line-height: 1.45;
}
.bl-screen-toolbar-r {
  display: flex; align-items: center; gap: 10px;
  flex: 0 0 auto;
}
.bl-screen-count {
  font-size: 11.5px; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.bl-screen-status {
  padding: 8px 14px;
  font-size: 12px;
  color: color-mix(in oklab, var(--mc-success) 80%, var(--text));
  background: color-mix(in oklab, var(--mc-success) 8%, transparent);
  border: 1px solid color-mix(in oklab, var(--mc-success) 22%, transparent);
  border-radius: 8px;
}
.bl-screen-body {
  flex: 1 1 auto;
  overflow: auto;
  display: flex; flex-direction: column;
  gap: 14px;
  padding-bottom: 24px;
}
/* DEV pill — small accent badge next to AI eyebrow khi dev_no_api */
.bl-dev-pill {
  display: inline-flex;
  padding: 1px 6px;
  margin-left: 6px;
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.06em;
  background: color-mix(in oklab, var(--mc-warn) 18%, transparent);
  color: color-mix(in oklab, var(--mc-warn) 85%, var(--text));
  border-radius: 4px;
}

/* ════════════════════════════════════════════════════════════════
   RTL — Arabic + future Hebrew/Persian. Most layout mirrors
   automatically via dir="rtl" (browser flips inline boxes); these
   rules patch the few places where direction is hardcoded.
   ════════════════════════════════════════════════════════════════ */

/* Flip side-bar from left → right edge */
[dir="rtl"] .app-sidebar      { left: auto; right: 0; border-right: none; border-left: 1px solid var(--border); }
[dir="rtl"] .app-main         { margin-left: 0; margin-right: var(--sidebar-width, 56px); }

/* Margin-left auto for "push to end" — swap to margin-right */
[dir="rtl"] .sm-link,
[dir="rtl"] .usage-resets,
[dir="rtl"] .sm-window-sub,
[dir="rtl"] .sm-updated-inline,
[dir="rtl"] .sm-credit-balance     { margin-left: 0; margin-right: auto; }

/* Block-banner border accent + convention box accent */
[dir="rtl"] .sm-quota-convention,
[dir="rtl"] .usage-convention      {
  border-left: none;
  border-right: 3px solid rgba(0, 122, 255, 0.45);
  border-radius: 6px 0 0 6px;
}

/* Modal close button → left side */
[dir="rtl"] .sm-modal-close        { right: auto; left: 14px; }

/* Input prefix ($) → right side */
[dir="rtl"] .sm-modal-input-prefix { left: auto; right: 14px; }
[dir="rtl"] .sm-modal-input-money  { padding-left: 14px; padding-right: 30px; }

/* Step number arrows in titles ("01 — TÊN") work naturally
   because text inside is rendered RTL — em dash flips visually. */

/* Force progress bar fills to grow from leading edge regardless of dir */
[dir="rtl"] .usage-bar-fill,
[dir="rtl"] .sm-bar-fill,
[dir="rtl"] .sm-metric-fill        { transform: scaleX(-1); transform-origin: center; }

/* Library footer · background-sync pulse indicator. The dot inflates
   from 60% → 100% opacity every 1.2s while a sync is in flight. Kept
   intentionally subtle — this is ambient feedback, not a CTA. */
@keyframes lib-sync-pulse {
  0%   { opacity: 0.55; transform: scale(0.9); }
  50%  { opacity: 1;    transform: scale(1.15); }
  100% { opacity: 0.55; transform: scale(0.9); }
}

/* Apple-style Save button (Settings → Output settings).
   Three keyframes:
     · apple-save-spin    — continuous 360° rotation while saving
     · apple-save-ring    — expanding ring once per click, mimics
                            the soft halo seen on macOS confirmation
                            buttons when pressed
   The button's color morph (blue → green) is handled inline on the
   component via React state; this CSS only owns the motion. */
@keyframes apple-save-spin {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
@keyframes apple-save-ring {
  0%   { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.45); }
  100% { box-shadow: 0 0 0 12px rgba(59, 130, 246, 0); }
}
.apple-save                  { will-change: transform, background; }
.apple-save:active           { transform: scale(0.95) !important; transition-duration: 90ms; }
.apple-save--saved           { box-shadow: 0 1px 12px rgba(34, 197, 94, 0.30); }
.apple-save:disabled         { opacity: 1; }   /* never grey out — anim conveys state */

/* ADR-008 Upgrade #3 — Candidate picker UI.
   Each editable translation cell carries a subtle "⋯" button that
   reveals ranked alternative translations from the SQL candidate
   scorer. Picking an alternative records it as a user correction
   so the library learns from the choice over time. */
.cell-with-picker {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  height: 100%;
}
.cell-with-picker > .cell.tr {
  flex: 1;
  min-width: 0;
}
.cand-picker {
  position: relative;
  display: inline-flex;
  align-items: center;
  margin-left: 2px;
  opacity: 0;
  transition: opacity 140ms ease;
  flex-shrink: 0;
}
.cell-with-picker:hover .cand-picker,
.cand-picker:focus-within { opacity: 1; }
.cand-picker-btn {
  width: 18px; height: 18px;
  border-radius: 4px;
  background: transparent;
  border: 1px solid var(--border, rgba(255,255,255,0.10));
  color: var(--text-2, var(--mc-label-2));
  font-size: 13px;
  line-height: 1;
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.cand-picker-btn:hover {
  background: rgba(59, 130, 246, 0.12);
  border-color: rgba(59, 130, 246, 0.45);
  color: var(--accent, var(--mc-accent));
}
.cand-picker-pop {
  position: absolute;
  right: 0;
  top: 100%;
  z-index: 50;
  margin-top: 4px;
  min-width: 240px;
  max-width: 360px;
  max-height: 280px;
  overflow-y: auto;
  background: var(--bg-elev, #1d2127);
  border: 1px solid var(--border, rgba(255,255,255,0.12));
  border-radius: 8px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.40);
  padding: 4px;
}
.cand-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12px;
  color: var(--text, var(--mc-label));
  transition: background 100ms ease;
}
.cand-row:hover { background: rgba(255,255,255,0.06); }
.cand-row.is-active {
  background: rgba(48, 209, 88, 0.14);
  color: var(--mc-success);
  font-weight: 600;
  cursor: default;
}
.cand-row.muted {
  color: var(--text-2, var(--mc-label-2));
  cursor: default;
  font-style: italic;
}
.cand-value {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cand-meta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  flex-shrink: 0;
}
.cand-score {
  font-variant-numeric: tabular-nums;
  color: var(--text-2, var(--mc-label-2));
  font-weight: 500;
}
.cand-tag {
  padding: 1px 5px;
  border-radius: 3px;
  font-weight: 500;
  font-size: 10px;
}
.cand-tag.good {
  background: rgba(48, 209, 88, 0.18);
  color: var(--mc-success);
}
.cand-tag.bad {
  background: rgba(239, 68, 68, 0.18);
  color: #dc2626;
}

/* ADR-008 follow-up — Library Health widget (Output Settings).
   Shows live coverage so users can tell which language pairs are
   pre-translated vs need API calls. Auto-refreshes every 8s.
   The widget is intentionally compact — it sits between the 3 mode
   cards and the Save button, so it must not eat vertical real
   estate. */
.lib-health {
  border: 1px solid var(--border, rgba(255,255,255,0.10));
  background: linear-gradient(180deg,
              rgba(255,255,255,0.035), rgba(255,255,255,0.015));
  border-radius: 10px;
  padding: 14px 14px 13px;
  /* A subtle left accent rail tinted by overall health. */
  border-left: 3px solid var(--border, rgba(255,255,255,0.10));
  transition: border-left-color 240ms ease;
}
.lib-health--good { border-left-color: var(--green, var(--mc-success)); }
.lib-health--ok   { border-left-color: var(--accent, var(--mc-accent)); }
.lib-health--low  { border-left-color: var(--warn, var(--mc-warn)); }

.lib-health-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}
.lib-health-titlewrap {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}
.lib-health-icon {
  font-size: 18px;
  line-height: 1;
  opacity: 0.9;
  flex-shrink: 0;
}
.lib-health-titles { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.lib-health-title {
  font-weight: 650;
  font-size: 13px;
  letter-spacing: -0.01em;
  color: var(--text, var(--mc-label));
}
.lib-health-sub {
  font-size: 11px;
  color: var(--text-2, var(--mc-label-2));
  font-variant-numeric: tabular-nums;
}
.lib-health-backend { opacity: 0.6; font-weight: 600; }

/* Big round score chip on the right — the at-a-glance "how ready". */
.lib-health-score {
  margin-left: auto;
  flex-shrink: 0;
  display: flex;
  align-items: baseline;
  gap: 1px;
  padding: 4px 11px;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.08);
}
.lib-health-score-num { font-size: 17px; font-weight: 700; line-height: 1; }
.lib-health-score-pct { font-size: 11px; font-weight: 600; opacity: 0.8; }
.lib-health-score--good { color: var(--green, var(--mc-success));
  background: rgba(48,209,88,0.12); border-color: rgba(48,209,88,0.28); }
.lib-health-score--ok { color: var(--accent, var(--mc-accent));
  background: rgba(59,130,246,0.12); border-color: rgba(59,130,246,0.28); }
.lib-health-score--low { color: var(--warn, var(--mc-warn));
  background: rgba(245,158,11,0.12); border-color: rgba(245,158,11,0.28); }

.lib-health-bars {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.lib-health-hint {
  margin-top: 11px;
  display: flex;
  align-items: flex-start;
  gap: 6px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-2, var(--mc-label-2));
}
.lib-health-hint-icon { color: var(--warn, var(--mc-warn)); flex-shrink: 0; }

.cov-row { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.cov-row-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px;
}
.cov-label {
  font-size: 11.5px;
  font-weight: 550;
  color: var(--text, var(--mc-label));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cov-pct {
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.cov-track {
  position: relative;
  height: 7px;
  border-radius: 999px;
  background: rgba(255,255,255,0.07);
  overflow: hidden;
}
.cov-fill {
  position: absolute;
  inset: 0;
  width: 0%;
  border-radius: 999px;
  transition: width 320ms cubic-bezier(0.4, 0, 0.2, 1),
              background 200ms ease;
}
.cov-sub {
  font-size: 10px;
  color: var(--text-2, var(--mc-label-2));
  font-variant-numeric: tabular-nums;
}

/* ADR-011 — auto-filler controls inside the LibraryHealth widget. */
.lib-health-autofill {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border, rgba(255,255,255,0.08));
}
.autofill-start-btn {
  width: 100%;
  padding: 7px 12px;
  border-radius: 6px;
  background: rgba(59, 130, 246, 0.12);
  border: 1px solid rgba(59, 130, 246, 0.35);
  color: var(--accent, var(--mc-accent));
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  transition: background 140ms ease, border-color 140ms ease;
}
.autofill-start-btn:hover {
  background: rgba(59, 130, 246, 0.22);
  border-color: rgba(59, 130, 246, 0.55);
}
.autofill-status {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  margin-bottom: 6px;
  color: var(--text, var(--mc-label));
}
.autofill-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--green, var(--mc-success));
  animation: autofill-pulse 1.4s ease-in-out infinite;
  flex-shrink: 0;
}
@keyframes autofill-pulse {
  0%, 100% { opacity: 1.0; transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.85); }
}
.autofill-text { font-weight: 500; }
.autofill-current {
  color: var(--text-2, var(--mc-label-2));
  font-size: 11px;
  margin-left: auto;
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.autofill-bar {
  height: 4px;
  border-radius: 2px;
  background: rgba(255,255,255,0.06);
  overflow: hidden;
  margin-bottom: 8px;
}
.autofill-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent, var(--mc-accent)), var(--green, var(--mc-success)));
  transition: width 320ms cubic-bezier(0.4, 0, 0.2, 1);
}
.autofill-actions {
  display: flex;
  gap: 6px;
}
.autofill-btn {
  flex: 1;
  padding: 5px 10px;
  border-radius: 5px;
  font-size: 11px;
  font-weight: 600;
  border: 1px solid var(--border, rgba(255,255,255,0.10));
  background: transparent;
  color: var(--text, var(--mc-label));
  cursor: pointer;
  transition: background 120ms ease;
}
.autofill-btn:hover { background: rgba(255,255,255,0.06); }
.autofill-btn-stop {
  color: var(--warn, var(--mc-warn));
  border-color: rgba(245, 158, 11, 0.35);
}
.autofill-btn-stop:hover {
  background: rgba(245, 158, 11, 0.12);
  border-color: rgba(245, 158, 11, 0.55);
}

/* ADR-012 — community sync button row inside LibraryHealth. */
.lib-health-sync {
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.lib-sync-btn {
  padding: 5px 12px;
  border-radius: 5px;
  font-size: 11.5px;
  font-weight: 600;
  border: 1px solid rgba(59, 130, 246, 0.35);
  background: rgba(59, 130, 246, 0.10);
  color: var(--accent, var(--mc-accent));
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.lib-sync-btn:hover:not(:disabled) {
  background: rgba(59, 130, 246, 0.20);
  border-color: rgba(59, 130, 246, 0.55);
}
.lib-sync-btn:disabled { opacity: 0.6; cursor: default; }
.lib-sync-msg {
  font-size: 11px;
  color: var(--text-2, var(--mc-label-2));
}
.lib-sync-msg.is-ok { color: var(--green, var(--mc-success)); }
.lib-sync-rel { opacity: 0.7; }

/* ════════ Dev-reliability KPI · Issues · Wall (tab chi tiết tool) ════════ */
.atelier .dev-rel{display:grid;grid-template-columns:200px 1fr;gap:16px;margin-bottom:8px}
.atelier .dev-rel.is-compact{grid-template-columns:170px 1fr;gap:12px;margin:14px 0 4px}
.atelier .dr-score{border:1px solid var(--line);border-radius:var(--r,18px);background:var(--surface-solid);
  padding:20px;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center}
.atelier .dr-gauge{font-family:'Fraunces',Georgia,serif;line-height:1;display:flex;align-items:baseline;gap:2px}
.atelier .dr-num{font-size:48px;font-weight:600}
.atelier .dev-rel.is-compact .dr-num{font-size:38px}
.atelier .dr-max{font-size:15px;color:var(--ink-3)}
.atelier .dr-tier{margin-top:8px;font-weight:600;font-size:14px}
.atelier .dr-sub{margin-top:2px;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11px;color:var(--ink-3);letter-spacing:.04em}
.atelier .dr-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--r,18px);overflow:hidden}
.atelier .dev-rel.is-compact .dr-grid{grid-template-columns:repeat(3,1fr)}
.atelier .dr-kpi{background:var(--surface-solid);padding:14px 16px}
.atelier .dr-kpi.is-dim{opacity:.55}
.atelier .dr-k{font-size:12px;color:var(--ink-2);margin-bottom:6px}
.atelier .dr-v{font-family:'Fraunces',Georgia,serif;font-size:22px;color:var(--ink);display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.atelier .dr-dot{width:8px;height:8px;border-radius:50%;flex:none}
.atelier .dr-dot[data-s="g"]{background:#13C28E}
.atelier .dr-dot[data-s="a"]{background:#E0A020}
.atelier .dr-dot[data-s="r"]{background:#E84D7A}
.atelier .dr-dot[data-s="n"]{background:var(--ink-3)}
.atelier .dr-trend{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11px;font-style:normal}
.atelier .dr-trend.up{color:#13C28E}
.atelier .dr-trend.down{color:#E0A020}
.atelier .dr-n{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10.5px;color:var(--ink-3);margin-top:3px}
.atelier .dr-warn{grid-column:1/-1;margin-top:2px;font-size:12.5px;color:var(--ink-2);
  border:1px dashed var(--line-2);border-radius:14px;padding:10px 14px}
.atelier .dr-more{grid-column:1/-1;justify-self:start;margin-top:2px;border:none;background:none;cursor:pointer;
  font-family:inherit;font-size:12.5px;font-weight:600;color:var(--brand);padding:4px 0}
@media (max-width:760px){.atelier .dev-rel{grid-template-columns:1fr}.atelier .dr-grid{grid-template-columns:repeat(2,1fr)}}

/* Issues */
.atelier .iss-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin:14px 0 12px}
.atelier .iss-chips{display:flex;flex-wrap:wrap;gap:6px}
.atelier .iss-chip{border:1px solid var(--line);background:var(--surface-solid);color:var(--ink-2);cursor:pointer;
  font-family:inherit;font-size:12px;font-weight:600;padding:5px 12px;border-radius:99px;transition:all .15s var(--ease,ease)}
.atelier .iss-chip:hover{color:var(--ink);border-color:var(--ink-3)}
.atelier .iss-chip.on{background:var(--ink);color:var(--surface-solid);border-color:var(--ink)}
.atelier .iss-sort{border:1px solid var(--line);background:var(--surface-solid);color:var(--ink);cursor:pointer;
  font-family:inherit;font-size:12.5px;padding:6px 10px;border-radius:10px}
.atelier .iss-new-btn{border:1px dashed var(--line-2);background:none;color:var(--ink-2);cursor:pointer;
  font-family:inherit;font-size:12.5px;font-weight:600;padding:8px 14px;border-radius:10px;margin-bottom:12px;transition:all .15s}
.atelier .iss-new-btn:hover{color:var(--brand);border-color:var(--brand)}
.atelier .iss-composer{border:1px solid var(--line);border-radius:var(--r,18px);background:var(--surface-solid);padding:16px;margin-bottom:16px;display:flex;flex-direction:column;gap:10px}
.atelier .iss-in,.atelier .iss-ta{width:100%;box-sizing:border-box;border:1px solid var(--line);border-radius:10px;
  padding:10px 12px;font-family:inherit;font-size:13.5px;color:var(--ink);background:transparent;outline:none}
.atelier .iss-ta{min-height:70px;resize:vertical;line-height:1.55}
.atelier .iss-in:focus,.atelier .iss-ta:focus{border-color:var(--brand)}
.atelier .iss-pick{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.atelier .iss-pick-l{font-size:12px;color:var(--ink-3);margin-right:4px;min-width:54px}
.atelier .iss-pill{border:1px solid var(--line);background:transparent;color:var(--ink-2);cursor:pointer;
  font-family:inherit;font-size:11.5px;font-weight:600;padding:4px 11px;border-radius:99px;transition:all .15s}
.atelier .iss-pill.on{font-weight:700}
.atelier .iss-composer-act{display:flex;justify-content:flex-end;gap:8px;margin-top:2px}
.atelier .iss-cancel{border:1px solid var(--line);background:transparent;color:var(--ink);cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:600;padding:7px 14px;border-radius:9px}
.atelier .iss-submit{border:none;background:var(--ink);color:var(--surface-solid);cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:650;padding:7px 16px;border-radius:9px}
.atelier .iss-submit:disabled{opacity:.45;cursor:default}
.atelier .iss-list{display:flex;flex-direction:column}
.atelier .iss-row{display:flex;gap:12px;padding:16px 0;border-top:1px solid var(--line)}
.atelier .iss-row.closed{opacity:.72}
.atelier .iss-av{width:38px;height:38px;flex:none;border-radius:50%;display:flex;align-items:center;justify-content:center;
  color:#fff;font-weight:700;font-size:15px;font-family:'Fraunces',Georgia,serif}
.atelier .iss-main{flex:1;min-width:0}
.atelier .iss-row-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:4px}
.atelier .iss-badge{font-size:11px;font-weight:700;padding:2px 9px;border-radius:99px}
.atelier .iss-badge.open{color:#E0A020;background:color-mix(in oklab,#E0A020 14%,transparent)}
.atelier .iss-badge.closed{color:#13C28E;background:color-mix(in oklab,#13C28E 14%,transparent)}
.atelier .iss-tag{font-size:11.5px;font-weight:600}
.atelier .iss-id{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11px;color:var(--ink-3);margin-left:auto}
.atelier .iss-title{font-size:14.5px;font-weight:650;color:var(--ink);line-height:1.4}
.atelier .iss-body{font-size:13px;color:var(--ink-2);line-height:1.55;margin-top:3px}
.atelier .iss-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:12px;color:var(--ink-3);margin-top:7px}
.atelier .iss-time{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11px;font-weight:600;padding:2px 9px;border-radius:99px}
.atelier .iss-time.good{color:#13C28E;background:color-mix(in oklab,#13C28E 12%,transparent)}
.atelier .iss-time.ok{color:var(--ink-2);background:color-mix(in oklab,var(--ink) 7%,transparent)}
.atelier .iss-time.amber{color:#E0A020;background:color-mix(in oklab,#E0A020 13%,transparent)}
.atelier .iss-time.red{color:#E84D7A;background:color-mix(in oklab,#E84D7A 13%,transparent)}
.atelier .iss-resolution{margin-top:9px;font-size:13px;color:var(--ink-2);line-height:1.55;
  border-left:2px solid #13C28E;background:color-mix(in oklab,#13C28E 6%,transparent);padding:9px 12px;border-radius:0 10px 10px 0}
.atelier .iss-resolution b{color:var(--ink)}
.atelier .iss-close-btn{margin-top:9px;border:1px solid #13C28E;background:transparent;color:#13C28E;cursor:pointer;
  font-family:inherit;font-size:12px;font-weight:650;padding:6px 13px;border-radius:9px;transition:all .15s}
.atelier .iss-close-btn:hover{background:color-mix(in oklab,#13C28E 12%,transparent)}
.atelier .iss-close-box{margin-top:9px;display:flex;flex-direction:column;gap:8px}
.atelier .iss-empty{text-align:center;padding:40px 20px}
.atelier .iss-empty-t{font-family:'Fraunces',Georgia,serif;font-size:18px;color:var(--ink);margin-bottom:6px}
.atelier .iss-empty-s{font-size:13px;color:var(--ink-2);max-width:420px;margin:0 auto;line-height:1.6}
.atelier .iss-link{border:none;background:none;color:var(--brand);cursor:pointer;font-family:inherit;font-size:13px;font-weight:600;padding:0}
.atelier .iss-allclear{margin-top:14px;text-align:center;font-size:13px;font-weight:600;color:#13C28E;
  background:color-mix(in oklab,#13C28E 8%,transparent);border:1px solid color-mix(in oklab,#13C28E 22%,transparent);border-radius:14px;padding:12px 16px}
.atelier .iss-hire{margin-top:18px;width:100%;border:1px solid var(--line);background:var(--surface-solid);color:var(--ink);
  cursor:pointer;font-family:inherit;font-size:13.5px;font-weight:650;padding:12px;border-radius:12px;transition:all .15s}
.atelier .iss-hire:hover{border-color:var(--brand);color:var(--brand)}

/* Wall */
.atelier .at-wall{display:flex;flex-direction:column;gap:14px}
.atelier .wall-composer{display:flex;gap:11px;align-items:flex-start;border:1px solid var(--line);border-radius:var(--r,18px);background:var(--surface-solid);padding:14px}
.atelier .wall-av{width:40px;height:40px;flex:none;border-radius:50%;display:flex;align-items:center;justify-content:center;
  color:#fff;font-weight:700;font-size:14px;font-family:'Fraunces',Georgia,serif}
.atelier .wall-ta{flex:1;border:none;background:transparent;outline:none;resize:vertical;min-height:42px;
  font-family:inherit;font-size:14px;color:var(--ink);line-height:1.55}
.atelier .wall-post-btn{align-self:center;border:none;background:var(--ink);color:var(--surface-solid);cursor:pointer;
  font-family:inherit;font-size:13px;font-weight:650;padding:9px 18px;border-radius:10px}
.atelier .wall-post-btn:disabled{opacity:.4;cursor:default}
.atelier .wall-post{border:1px solid var(--line);border-radius:var(--r,18px);background:var(--surface-solid);padding:16px 18px}
.atelier .wall-head{display:flex;align-items:center;gap:11px;margin-bottom:10px}
.atelier .wall-id{flex:1;min-width:0}
.atelier .wall-name{font-size:14px;font-weight:700;color:var(--ink);display:flex;align-items:center;gap:7px}
.atelier .wall-devb{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10px;font-weight:600;color:var(--mc-label-2);
  background:var(--mc-fill);padding:1px 7px;border-radius:99px}
.atelier .wall-when{font-size:11.5px;color:var(--ink-3);margin-top:1px}
.atelier .wall-admin{display:flex;gap:4px}
.atelier .wall-admin button{border:none;background:none;cursor:pointer;font-family:inherit;font-size:11.5px;color:var(--ink-3);padding:4px 7px;border-radius:7px}
.atelier .wall-admin button:hover{color:var(--ink);background:color-mix(in oklab,var(--ink) 7%,transparent)}
.atelier .wall-body{font-size:14px;color:var(--ink);line-height:1.6;white-space:pre-wrap}
.atelier .wall-actions{display:flex;align-items:center;gap:4px;margin-top:14px;padding-top:10px;border-top:1px solid var(--line);flex-wrap:wrap}
.atelier .wall-react{position:relative}
.atelier .wall-abtn,.atelier .wall-rbtn{display:inline-flex;align-items:center;gap:7px;border:none;background:none;cursor:pointer;
  font-family:inherit;font-size:13px;font-weight:600;color:var(--ink-2);padding:8px 13px;border-radius:12px;
  transition:background .18s var(--ease),color .18s var(--ease),transform .1s var(--ease)}
.atelier .wall-abtn:hover,.atelier .wall-rbtn:hover{background:color-mix(in oklab,var(--ink) 6%,transparent);color:var(--ink)}
.atelier .wall-abtn:active,.atelier .wall-rbtn:active{transform:scale(.93)}
.atelier .wall-abtn svg,.atelier .wall-rbtn svg{width:17px;height:17px;flex:none}
.atelier .wall-rbtn.on,.atelier .wall-abtn.on{color:var(--brand)}
.atelier .wall-remoji{font-size:17px;line-height:1;animation:wall-pop .35s var(--spring)}
@keyframes wall-pop{from{transform:scale(.4)}60%{transform:scale(1.25)}to{transform:scale(1)}}
.atelier .wall-acount{font-style:normal;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:12px;font-weight:600;
  color:var(--ink-3);background:color-mix(in oklab,var(--ink) 6%,transparent);padding:1px 7px;border-radius:99px;min-width:20px;text-align:center}
.atelier .wall-rbtn.on .wall-acount,.atelier .wall-abtn.on .wall-acount{color:var(--brand);background:color-mix(in oklab,var(--brand) 13%,transparent)}
.atelier .wall-react-pop{position:absolute;left:0;bottom:calc(100% + 8px);display:flex;gap:3px;padding:6px;border-radius:18px;
  background:var(--surface-solid);border:1px solid var(--line);box-shadow:0 12px 34px rgba(20,19,15,.20),inset 0 1px 0 rgba(255,255,255,.6);
  opacity:0;transform:translateY(10px) scale(.9);transform-origin:bottom left;pointer-events:none;
  transition:opacity .18s var(--ease),transform .26s var(--spring);z-index:6}
/* Cầu nối trong suốt phủ khoảng trống button↔palette để di chuột lên không bị mất hover */
.atelier .wall-react-pop::after{content:"";position:absolute;left:-6px;right:-6px;top:100%;height:14px}
.atelier .wall-react:hover .wall-react-pop,.atelier .wall-react:focus-within .wall-react-pop{opacity:1;transform:none;pointer-events:auto}
.atelier .wall-rpop-b{display:flex;flex-direction:column;align-items:center;gap:2px;border:none;background:none;cursor:pointer;line-height:1;padding:5px 7px 4px;border-radius:12px;
  transition:transform .2s var(--spring),background .15s}
.atelier .wall-rpop-b:hover{transform:scale(1.22) translateY(-3px);background:color-mix(in oklab,var(--ink) 5%,transparent)}
.atelier .wall-rpop-b.on{background:color-mix(in oklab,var(--brand) 15%,transparent)}
.atelier .wall-rpop-e{font-size:23px;line-height:1}
.atelier .wall-rpop-n{font-style:normal;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10px;font-weight:600;color:var(--ink-3)}
.atelier .wall-rpop-b.on .wall-rpop-n{color:var(--brand)}
/* ── Bình luận kiểu RedNote (avatar + bong bóng) — tách hẳn khỏi thanh tương tác ── */
.atelier .wall-cmts{margin-top:6px;padding-top:16px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:4px}
.atelier .wall-cmts-h{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:700;color:var(--ink-2);margin-bottom:8px}
.atelier .wall-cmts-h span{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11px;font-weight:600;color:var(--ink-3);background:color-mix(in oklab,var(--ink) 6%,transparent);padding:1px 8px;border-radius:99px}
/* Mỗi bình luận: avatar · nội dung (không bong bóng, kiểu IG) · tim bên phải */
.atelier .wall-cmt{display:flex;gap:11px;align-items:flex-start;padding:9px 0}
.atelier .wall-cmt.is-reply{margin-left:45px;padding:6px 0;border-left:2px solid var(--line);padding-left:14px}
.atelier .wall-cmt-av{flex:none;width:34px;height:34px;border-radius:50%;display:grid;place-items:center;color:#fff;font-weight:700;font-size:13.5px;font-family:'Fraunces',Georgia,serif}
.atelier .wall-cmt.is-reply .wall-cmt-av{width:28px;height:28px;font-size:12px}
.atelier .wall-cmt-main{flex:1;min-width:0}
.atelier .wall-cmt-top{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:2px}
.atelier .wall-cmt-au{font-weight:700;font-size:13px;color:var(--ink);letter-spacing:-.01em}
.atelier .wall-cmt-badge{display:inline-flex;align-items:center;gap:3px;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:9px;font-weight:700;letter-spacing:.06em;color:#fff;background:var(--brand);padding:2px 7px 2px 5px;border-radius:99px}
.atelier .wall-cmt-badge svg{width:10px;height:10px}
.atelier .wall-cmt-when{font-size:11px;color:var(--ink-3);font-family:'IBM Plex Mono',ui-monospace,monospace}
.atelier .wall-cmt-tx{font-size:13.5px;color:var(--ink);line-height:1.55;white-space:pre-wrap}
.atelier .wall-cmt-mention{font-weight:600;color:var(--brand)}
.atelier .wall-cmt-meta{display:flex;align-items:center;gap:16px;margin-top:6px}
.atelier .wall-cmt-likes{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11.5px;font-weight:600;color:var(--ink-3)}
.atelier .wall-cmt-reply{border:none;background:none;cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;color:var(--ink-3);padding:0;transition:color .15s}
.atelier .wall-cmt-reply:hover{color:var(--ink)}
.atelier .wall-cmt-heart{flex:none;border:none;background:none;cursor:pointer;color:var(--ink-3);padding:5px;margin-top:8px;border-radius:50%;transition:transform .1s var(--spring),color .15s}
.atelier .wall-cmt-heart svg{width:15px;height:15px;display:block}
.atelier .wall-cmt-heart:hover{color:var(--ink)}
.atelier .wall-cmt-heart:active{transform:scale(.8)}
.atelier .wall-cmt-heart.on{color:#E84D7A;animation:wall-pop .35s var(--spring)}
.atelier .wall-cmt-in{display:flex;gap:8px;margin-top:14px;align-items:center}
.atelier .wall-cmt-in input{flex:1;border:1px solid var(--line);border-radius:999px;padding:10px 16px;font-family:inherit;font-size:13px;color:var(--ink);background:var(--bg);outline:none;transition:border-color .15s,box-shadow .15s}
.atelier .wall-cmt-in input:focus{border-color:var(--brand);box-shadow:0 0 0 3px color-mix(in oklab,var(--brand) 16%,transparent);background:var(--surface-solid)}
.atelier .wall-cmt-in button{border:none;background:var(--brand);color:#fff;cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:650;padding:10px 18px;border-radius:999px;transition:filter .15s,transform .1s}
.atelier .wall-cmt-in button:hover{filter:brightness(1.06)}
.atelier .wall-cmt-in button:active{transform:scale(.96)}
.atelier .wall-empty{text-align:center;padding:40px;color:var(--ink-3);font-size:13.5px}

/* Releases — changelog timeline */
.atelier .rel-tl{margin-top:18px;display:flex;flex-direction:column}
.atelier .rel-tl-item{display:flex;gap:14px}
.atelier .rel-tl-line{position:relative;width:14px;flex:none;display:flex;justify-content:center}
.atelier .rel-tl-line:before{content:"";position:absolute;top:4px;bottom:-4px;width:2px;background:var(--line)}
.atelier .rel-tl-item:last-child .rel-tl-line:before{display:none}
.atelier .rel-tl-dot{position:relative;z-index:1;width:11px;height:11px;border-radius:50%;background:var(--line-2);margin-top:4px;border:2px solid var(--surface-solid)}
.atelier .rel-tl-dot.latest{background:#13C28E;box-shadow:0 0 0 3px color-mix(in oklab,#13C28E 20%,transparent)}
.atelier .rel-tl-body{flex:1;padding-bottom:22px;min-width:0}
.atelier .rel-tl-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.atelier .rel-tl-v{font-family:'Fraunces',Georgia,serif;font-size:19px;font-weight:600;color:var(--ink)}
.atelier .rel-tl-badge{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10px;font-weight:600;color:#13C28E;
  background:color-mix(in oklab,#13C28E 13%,transparent);padding:2px 8px;border-radius:99px;letter-spacing:.04em}
.atelier .rel-tl-date{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:11.5px;color:var(--ink-3)}
.atelier .rel-tl-sep{color:var(--ink-3);font-size:13px;opacity:.6;margin:0 -3px}
.atelier .rel-tl-head .rel-tl-badge{margin-left:auto}
.atelier .rel-tl-notes{margin:9px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:6px}
.atelier .rel-tl-notes li{position:relative;padding-left:18px;font-size:13.5px;color:var(--ink-2);line-height:1.55}
.atelier .rel-tl-notes li:before{content:"";position:absolute;left:2px;top:8px;width:5px;height:5px;border-radius:50%;background:var(--ink-3)}
/* Danh sách 19 ngôn ngữ (endonym) trong changelog — dòng riêng, dịu, dễ đọc. */
.atelier .rel-langs{display:block;margin-top:5px;color:var(--ink-3);font-size:12.5px;line-height:1.85;letter-spacing:.01em}
.atelier .rel-foot{margin-top:6px;font-size:12.5px;color:var(--ink-3);border-top:1px solid var(--line);padding-top:14px}

/* Marketplace search + stats (hero) */
.atelier .as-find{max-width:760px;margin:30px auto 4px;opacity:0;transform:translateY(16px);animation:at-rise .8s var(--ease) forwards;animation-delay:.26s}
.atelier .as-search{display:flex;align-items:center;gap:10px;background:var(--surface-solid);border:1px solid var(--line);border-radius:16px;padding:7px 7px 7px 18px;box-shadow:0 2px 12px rgba(0,0,0,.045);transition:border-color .18s,box-shadow .18s}
.atelier .as-search:focus-within{border-color:var(--ink-3);box-shadow:0 6px 22px rgba(0,0,0,.08)}
.atelier .as-search-ic{color:var(--ink-3);flex:none}
.atelier .as-search-in{flex:1;min-width:0;border:none;background:none;outline:none;font-family:inherit;font-size:15.5px;color:var(--ink)}
.atelier .as-search-in::placeholder{color:var(--ink-3)}
.atelier .as-search-x{flex:none;border:none;background:none;cursor:pointer;color:var(--ink-3);font-size:13px;padding:6px 8px;border-radius:8px;line-height:1}
.atelier .as-search-x:hover{color:var(--ink);background:color-mix(in oklab,var(--ink) 7%,transparent)}
.atelier .as-search-btn{flex:none;border:none;cursor:pointer;font-family:inherit;font-size:14px;font-weight:600;color:#fff;background:var(--brand);padding:11px 24px;border-radius:11px;transition:filter .15s,transform .12s}
.atelier .as-search-btn:hover{filter:brightness(1.06)}
.atelier .as-search-btn:active{transform:translateY(1px)}
.atelier .as-stats{display:flex;gap:38px;justify-content:center;flex-wrap:wrap;margin-top:22px}
.atelier .as-stat{text-align:center;min-width:74px}
.atelier .as-stat-n{font-family:'Fraunces',Georgia,serif;font-size:27px;font-weight:600;color:var(--ink);line-height:1}
.atelier .as-stat-l{font-size:12px;color:var(--ink-3);margin-top:6px;letter-spacing:.01em}
@media (max-width:560px){.atelier .as-stats{gap:24px}.atelier .as-stat-n{font-size:22px}.atelier .chip{min-height:44px;padding:0 18px;font-size:14px}}

/* Insights dashboard (ins2) — phân tích theo tuần/tháng/năm/tất cả */
.atelier .ins2-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:20px}
.atelier .ins2-range{display:inline-flex;gap:2px;background:var(--surface-solid);border:1px solid var(--line);border-radius:13px;padding:4px;box-shadow:0 1px 2px rgba(0,0,0,.04)}
.atelier .ins2-rbtn{border:none;background:none;cursor:pointer;font-family:inherit;font-size:13.5px;font-weight:500;color:var(--ink-2);padding:8px 18px;border-radius:9px;transition:.2s var(--ease)}
.atelier .ins2-rbtn:hover{color:var(--ink)}
.atelier .ins2-rbtn.on{background:var(--ink);color:var(--bg,#fff);font-weight:600;box-shadow:0 2px 8px rgba(0,0,0,.16)}
.atelier .ins2-kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:18px}
.atelier .ins2-kpi{border:1px solid var(--line);border-radius:16px;padding:16px 18px;background:var(--surface-solid);box-shadow:0 1px 2px rgba(0,0,0,.03)}
.atelier .ins2-k{font-size:12.5px;color:var(--ink-2);margin-bottom:8px}
.atelier .ins2-v{font-family:'Fraunces',Georgia,serif;font-size:30px;color:var(--ink);line-height:1}
.atelier .ins2-d{font-size:11.5px;color:var(--ink-3);margin-top:7px}
.atelier .ins2-d.up{color:#13C28E}
.atelier .ins2-d.down{color:#E84D7A}
.atelier .ins2-duo{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:18px}
.atelier .ins2-duo .ins-card+.ins-card{margin-top:0}
.atelier .ins2-bars{display:flex;flex-direction:column;gap:14px;padding:4px 0 2px}
.atelier .ins2-bar-top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:7px;font-size:13px;color:var(--ink-2)}
.atelier .ins2-bar-top b{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:13px;color:var(--ink);font-weight:600}
.atelier .ins2-track{display:block;height:8px;border-radius:99px;background:color-mix(in oklab,var(--ink) 7%,transparent);overflow:hidden}
.atelier .ins2-track i{display:block;height:100%;border-radius:99px;transition:width 1.1s var(--ease)}
.atelier .ins2-note{margin-top:18px;font-size:12px;color:var(--ink-3);text-align:center}
@media (max-width:760px){.atelier .ins2-kpis{grid-template-columns:repeat(2,1fr)}.atelier .ins2-duo{grid-template-columns:1fr}}

/* ≥34" (ultra-wide ~3440px+): LẤP GẦN FULL màn, chỉ chừa lề mỏng (không gutter lớn) + thêm cột */
@media (min-width:3440px){
  .atelier{--shell-w:calc(100vw - 64px)}
  .atelier .grid{grid-template-columns:repeat(6,1fr)}
}

/* Chart axis labels (HTML overlay) — không bị SVG preserveAspectRatio kéo giãn */
.atelier .ac-yax{position:absolute;left:0;top:0;width:100%;height:240px;pointer-events:none}
.atelier .ac-yl{position:absolute;left:2px;transform:translateY(-100%);font:11px/1 "IBM Plex Mono",ui-monospace,monospace;color:var(--ink-3);background:linear-gradient(90deg,var(--surface-solid) 70%,transparent);padding-right:6px}
.atelier .ac-xax{display:flex;justify-content:space-between;align-items:center;padding:8px 4px 0;margin-top:-22px}
.atelier .ac-xl{font:11px/1 "IBM Plex Mono",ui-monospace,monospace;color:var(--ink-3);white-space:nowrap}

/* ═══════════════════════════════════════════════════════════════════════
   LIQUID GLASS (iOS 26 style) — opt-in layer. Add `lg` to the .atelier root.
   `.atelier.lg .x` (specificity 0,2,1) overrides the warm Atelier defaults, so
   it works regardless of source order. Desktop-safe: panels keep light,
   semi-opaque fills over a LIGHT backdrop so they stay readable even where
   QtWebEngine drops backdrop-filter; on web the blur+saturate turns them into
   real frosted glass. Fully reversible: remove `lg` from the root className.
   ═══════════════════════════════════════════════════════════════════════ */
.atelier.lg{
  --bg:#E9ECF3; --bg-2:#E1E5EE; --surface:rgba(255,255,255,.55); --surface-solid:#FBFCFF;
  --line:rgba(17,24,39,.08); --line-2:rgba(17,24,39,.13);
  --glass:rgba(255,255,255,.60); --glass-2:rgba(255,255,255,.46); --glass-brd:rgba(255,255,255,.72);
  --glass-blur:saturate(190%) blur(26px); --glass-blur-sm:saturate(180%) blur(14px);
  --glass-sh:0 1px 1px rgba(16,24,40,.05), 0 12px 34px rgba(16,24,40,.12);
  --glass-hi:inset 0 1px 0 rgba(255,255,255,.85), inset 0 -1px 0 rgba(16,24,40,.04);
}
/* Ambient backdrop — soft brand-tinted light so the glass has colour to refract */
.atelier.lg .at-bg{
  background:
    radial-gradient(38% 42% at 82% 2%, rgba(10,132,255,.18), transparent 60%),
    radial-gradient(40% 44% at 6% 10%, rgba(255,61,127,.15), transparent 60%),
    radial-gradient(46% 50% at 94% 64%, rgba(168,85,247,.16), transparent 62%),
    radial-gradient(52% 56% at 26% 102%, rgba(19,194,142,.11), transparent 64%),
    linear-gradient(180deg,#EFF2F8,#E6EAF3);
}
.atelier.lg ::selection{background:rgba(10,132,255,.22); color:var(--ink)}

/* Nav + condensed header */
.atelier.lg .nav, .atelier.lg .dtl-cond{
  background:var(--glass); -webkit-backdrop-filter:var(--glass-blur); backdrop-filter:var(--glass-blur);
  border:1px solid var(--glass-brd); box-shadow:var(--glass-sh), var(--glass-hi);
}
.atelier.lg .nav-scrim::after{background:linear-gradient(var(--bg) 0%,var(--bg) 56%,rgba(233,236,243,0) 100%)}
.atelier.lg .tab.on{background:var(--glass); -webkit-backdrop-filter:var(--glass-blur-sm); backdrop-filter:var(--glass-blur-sm); box-shadow:var(--glass-hi), 0 2px 8px rgba(16,24,40,.08)}
.atelier.lg .island{background:rgba(17,24,39,.84); -webkit-backdrop-filter:blur(14px) saturate(180%); backdrop-filter:blur(14px) saturate(180%); box-shadow:inset 0 1px 0 rgba(255,255,255,.18), 0 8px 22px rgba(16,24,40,.30)}
.atelier.lg .as-bell, .atelier.lg .as-lang{background:var(--glass); -webkit-backdrop-filter:var(--glass-blur-sm); backdrop-filter:var(--glass-blur-sm); border:1px solid var(--glass-brd)}

/* Search */
.atelier.lg .as-search{
  background:var(--glass); -webkit-backdrop-filter:var(--glass-blur); backdrop-filter:var(--glass-blur);
  border:1px solid var(--glass-brd); border-radius:18px; box-shadow:var(--glass-sh), var(--glass-hi);
}
.atelier.lg .as-search:focus-within{border-color:rgba(255,255,255,.92); box-shadow:0 12px 32px rgba(16,24,40,.14), 0 0 0 4px rgba(10,132,255,.16), var(--glass-hi)}
.atelier.lg .as-search-btn{background:linear-gradient(180deg,#FF9A4D,var(--brand)); box-shadow:inset 0 1px 0 rgba(255,255,255,.55), 0 5px 16px rgba(247,111,25,.40)}
.atelier.lg .as-search-btn:hover{filter:brightness(1.05); transform:translateY(-1px)}

/* Category chips */
.atelier.lg .chip{
  background:var(--glass-2); -webkit-backdrop-filter:var(--glass-blur-sm); backdrop-filter:var(--glass-blur-sm);
  border:1px solid var(--glass-brd); box-shadow:0 1px 2px rgba(16,24,40,.05), inset 0 1px 0 rgba(255,255,255,.7);
}
.atelier.lg .chip:hover{background:rgba(255,255,255,.74); transform:translateY(-1px); box-shadow:0 7px 18px rgba(16,24,40,.10), inset 0 1px 0 rgba(255,255,255,.8)}
.atelier.lg .chip.on{background:rgba(17,24,39,.88); color:#fff; border-color:rgba(255,255,255,.16); box-shadow:inset 0 1px 0 rgba(255,255,255,.20), 0 8px 20px rgba(16,24,40,.28)}

/* Tool cards */
.atelier.lg .card{
  background:var(--glass); -webkit-backdrop-filter:var(--glass-blur); backdrop-filter:var(--glass-blur);
  border:1px solid var(--glass-brd); box-shadow:var(--glass-sh), var(--glass-hi);
}
.atelier.lg .card:hover{transform:translateY(-3px); border-color:rgba(255,255,255,.92); box-shadow:0 2px 8px rgba(16,24,40,.08), 0 26px 56px rgba(16,24,40,.18), var(--glass-hi)}
.atelier.lg .card.is-featured{border-color:rgba(255,255,255,.85); box-shadow:0 2px 10px rgba(10,132,255,.12), 0 20px 54px rgba(10,132,255,.16), var(--glass-hi)}
.atelier.lg .card .foot{border-top-color:rgba(17,24,39,.08)}
.atelier.lg .card .arrow{background:var(--glass); border-color:var(--glass-brd); -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px)}

/* Recommended (for-you) mini-cards */
.atelier.lg .as-fy-card{background:var(--glass); -webkit-backdrop-filter:var(--glass-blur-sm); backdrop-filter:var(--glass-blur-sm); border:1px solid var(--glass-brd); box-shadow:0 1px 2px rgba(16,24,40,.05), inset 0 1px 0 rgba(255,255,255,.7)}
.atelier.lg .as-fy-card:hover{background:rgba(255,255,255,.80); transform:translateY(-2px); box-shadow:0 9px 22px rgba(16,24,40,.10), inset 0 1px 0 rgba(255,255,255,.8)}

/* Install / get-started card (inline-styled -> !important to win) */
.atelier.lg .as-getapp{
  background:var(--glass)!important; -webkit-backdrop-filter:var(--glass-blur); backdrop-filter:var(--glass-blur);
  border:1px solid var(--glass-brd)!important; box-shadow:var(--glass-sh), var(--glass-hi)!important;
}

/* Glossy sheen on tool icon squircles (gradient bg stays inline) */
.atelier.lg .icon, .atelier.lg .as-fy-ic, .atelier.lg .as-bell-ic, .atelier.lg .te-ico{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45), 0 5px 14px rgba(16,24,40,.18);
}

/* Segmented control */
.atelier.lg .seg{background:rgba(17,24,39,.05); -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px)}
.atelier.lg .seg .pill{background:var(--glass); box-shadow:var(--glass-hi), 0 2px 8px rgba(16,24,40,.12)}

/* Primary / ghost buttons */
.atelier.lg .btn-primary{background:linear-gradient(180deg,#FF9A4D,var(--brand)); box-shadow:inset 0 1px 0 rgba(255,255,255,.5), 0 5px 16px rgba(247,111,25,.36)}
.atelier.lg .btn-ghost{background:var(--glass); -webkit-backdrop-filter:var(--glass-blur-sm); backdrop-filter:var(--glass-blur-sm); border:1px solid var(--glass-brd); box-shadow:inset 0 1px 0 rgba(255,255,255,.6)}

/* ═══════════════════════════════════════════════════════════════════════
   MOBILE — Apple-app layout (<=760px). The floating pill becomes a SLIM top
   bar (brand + lang + bell); the cramped market tabs move to an iOS segmented
   control under the bar, and Publish is hidden (a desktop / App-Store-Connect
   action). Primary navigation lives in the bottom tab bar.
   ═══════════════════════════════════════════════════════════════════════ */
.atelier .as-mseg{display:none}
@media (max-width:760px){
  .atelier .nav{padding:8px 8px 8px 16px; gap:8px}
  .atelier .nav .tabs{display:none}
  .atelier .nav .tab-sec{display:none}        /* Publish -> desktop only */
  .atelier .as-lang-wrap{margin-left:auto}
  .atelier .as-bell{width:36px; height:36px}
  .atelier .as-lang{height:36px}

  /* iOS segmented control: Trending / App Store */
  .atelier .as-mseg{
    display:flex; gap:3px; width:var(--shell-w); max-width:calc(100% - 32px);
    margin:14px auto 2px; padding:3px; border-radius:13px;
    background:rgba(120,120,128,.14);
    -webkit-backdrop-filter:saturate(180%) blur(16px); backdrop-filter:saturate(180%) blur(16px);
    box-shadow:inset 0 1px 1px rgba(16,24,40,.04);
  }
  .atelier .as-mseg-b{
    flex:1; font:inherit; font-size:14px; font-weight:600; letter-spacing:-.01em;
    color:var(--ink-2); background:none; border:none; cursor:pointer; padding:9px 0; border-radius:10px;
    -webkit-tap-highlight-color:transparent;
    transition:color .25s var(--ease), background .25s var(--ease), box-shadow .25s var(--ease);
  }
  .atelier .as-mseg-b.on{
    color:var(--ink); background:rgba(255,255,255,.92);
    box-shadow:0 1px 3px rgba(16,24,40,.14), inset 0 1px 0 rgba(255,255,255,.9);
  }
  .atelier .as-mseg-b:active{transform:scale(.97)}

  /* Tighten the hero to an iOS large-title scale on phones */
  .atelier .stage{padding:18px 16px 80px}
  .atelier h1.hero{font-size:34px; line-height:1.05; letter-spacing:-.02em}
  .atelier .eyebrow{margin-bottom:10px}
  .atelier .lead{font-size:15.5px; margin-top:14px}
}

/* ═══════════════════════════════════════════════════════════════════════
   APP CLASSIFICATION (App Store / Play style) — run-in-browser vs install.
   Two axes: PRIMARY = how you run it (Dùng ngay / Máy tính) as a segmented
   filter; per-card TYPE badge shows it at a glance. Categories stay secondary.
   ═══════════════════════════════════════════════════════════════════════ */
.atelier .as-typefilter{
  display:inline-flex; gap:3px; margin:22px auto 4px; padding:4px; border-radius:14px;
  background:rgba(120,120,128,.12);
  -webkit-backdrop-filter:saturate(180%) blur(16px); backdrop-filter:saturate(180%) blur(16px);
  box-shadow:inset 0 1px 1px rgba(16,24,40,.04);
}
.atelier .as-typf{
  font:inherit; font-size:14px; font-weight:600; letter-spacing:-.01em; color:var(--ink-2);
  background:none; border:none; cursor:pointer; padding:9px 20px; border-radius:10px;
  transition:color .25s var(--ease), background .25s var(--ease), box-shadow .25s var(--ease);
}
.atelier .as-typf:hover{color:var(--ink)}
.atelier .as-typf.on{
  color:var(--ink); background:rgba(255,255,255,.92);
  box-shadow:0 1px 3px rgba(16,24,40,.14), inset 0 1px 0 rgba(255,255,255,.9);
}

/* Per-card type badge: green "instant/web" vs blue "desktop/install" */
.atelier .card .foot .card-mode{
  font-family:'IBM Plex Mono',ui-monospace,monospace; font-size:11px; font-weight:600; letter-spacing:.01em;
  padding:5px 11px; border-radius:999px; white-space:nowrap; flex:none;
}
.atelier .card-mode.mode-web{color:#0a7d50; background:color-mix(in oklab,#13C28E 16%,transparent)}
.atelier .card-mode.mode-desk{color:#1850c8; background:color-mix(in oklab,#2E7DFF 14%,transparent)}

@media (max-width:760px){
  .atelier .as-typefilter{display:flex; width:var(--shell-w); max-width:calc(100% - 32px); margin:14px auto 2px}
  .atelier .as-typf{flex:1; padding:9px 0; text-align:center}
}
