/* ==========================================================================
   OK2SHIP AI — Design System (FINAL)
   Base: Ant Design v5 tokens & component conventions, colorPrimary = Mektec navy
   + AI motion layer (Magic UI technique, hand-written CSS, no external dep):
     - Border Beam   : rotating conic-gradient outline on AI-driven metrics
     - Shimmer       : light sweep on primary actions
     - Live pulse    : breathing dot marking an active AI/real-time process
   Use these 3 effects ONLY where they carry real meaning (see usage notes
   inline) — never decorative-only, to keep the product credible for a
   factory operations tool.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,500;0,600;0,700;1,400&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');

:root {
  /* ---- AntD theme.token (customized to Mektec navy) ---- */
  --ant-colorPrimary: #2B2FA0;
  --ant-colorPrimaryHover: #4247B8;
  --ant-colorPrimaryActive: #1D2088;
  --ant-colorPrimaryBg: #F0F1FA;
  --ant-colorPrimaryBgHover: #E4E5F5;
  --ant-colorPrimaryBorder: #C6C8EC;

  --ant-colorSuccess: #52C41A; --ant-colorSuccessBg: #F6FFED; --ant-colorSuccessBorder: #B7EB8F;
  --ant-colorWarning: #FAAD14; --ant-colorWarningBg: #FFFBE6; --ant-colorWarningBorder: #FFE58F;
  --ant-colorError: #FF4D4F; --ant-colorErrorBg: #FFF2F0; --ant-colorErrorBorder: #FFCCC7;
  --ant-colorInfo: #1677FF; --ant-colorInfoBg: #E6F4FF; --ant-colorInfoBorder: #91CAFF;

  --ant-colorText: rgba(0,0,0,0.88);
  --ant-colorTextSecondary: rgba(0,0,0,0.65);
  --ant-colorTextTertiary: rgba(0,0,0,0.45);
  --ant-colorTextQuaternary: rgba(0,0,0,0.25);
  --ant-colorTextDisabled: rgba(0,0,0,0.25);
  --ant-colorBorder: #D9D9D9;
  --ant-colorBorderSecondary: #F0F0F0;
  --ant-colorBgLayout: #F5F5F7;
  --ant-colorBgContainer: #FFFFFF;
  --ant-colorFillTertiary: #F5F5F5;
  --ant-colorFillQuaternary: #FAFAFA;

  /* ---- Sider (dark, Mektec navy family) ---- */
  --ant-siderBg: #12145E;
  --ant-siderBgHeader: #0D0E47;
  --ant-siderItemColor: rgba(255,255,255,0.65);
  --ant-siderItemHoverBg: rgba(255,255,255,0.08);
  --ant-siderItemSelectedBg: #2B2FA0;
  --ant-siderItemSelectedColor: #FFFFFF;

  /* ---- Radius / shadow (AntD v5 defaults) ---- */
  --ant-borderRadius: 6px;
  --ant-borderRadiusLG: 8px;
  --ant-borderRadiusSM: 4px;
  --ant-boxShadow: 0 1px 2px -2px rgba(0,0,0,0.16), 0 3px 6px 0 rgba(0,0,0,0.12), 0 5px 12px 4px rgba(0,0,0,0.09);
  --ant-boxShadowSecondary: 0 6px 16px 0 rgba(0,0,0,0.08), 0 3px 6px -4px rgba(0,0,0,0.12), 0 9px 28px 8px rgba(0,0,0,0.05);
  --ant-boxShadowTertiary: 0 1px 2px 0 rgba(0,0,0,0.03), 0 1px 6px -1px rgba(0,0,0,0.02), 0 2px 4px 0 rgba(0,0,0,0.02);

  --font-ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;
  --ease: cubic-bezier(0.645,0.045,0.355,1); /* AntD's own motion curve */

  /* ---- AI accent (used only by the 3 effects below) ---- */
  --ai-glow: #7A7FE8;
}

* { box-sizing: border-box; }
html, body { height: 100%; overflow: hidden; }
body {
  margin: 0; font-family: var(--font-ui); background: var(--ant-colorBgLayout);
  color: var(--ant-colorText); font-size: 14px; line-height: 1.5714285714285714;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3 { margin: 0; color: var(--ant-colorText); font-weight: 600; }
p { margin: 0; }
a { color: var(--ant-colorPrimary); text-decoration: none; transition: color 0.2s var(--ease); }
a:hover { color: var(--ant-colorPrimaryHover); }
.mono { font-family: var(--font-mono); }

@keyframes fadeInUp { from { opacity:0; transform: translateY(8px); } to { opacity:1; transform:none; } }
@keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@keyframes antZoomIn { from { opacity:0; transform: scale(0.92); } to { opacity:1; transform: scale(1); } }
@keyframes antZoomOut { from { opacity:1; transform: scale(1); } to { opacity:0; transform: scale(0.92); } }
@keyframes antMessageIn { from { opacity:0; transform: translate(-50%, -12px); } to { opacity:1; transform: translate(-50%, 0); } }
@keyframes shimmerSkeleton { 0% { background-position: -420px 0; } 100% { background-position: 420px 0; } }
@keyframes pulseDot { 0%,100% { opacity:1; } 50% { opacity:.4; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes shakeX { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-4px)} 75%{transform:translateX(4px)} }
@keyframes dashFlow { to { stroke-dashoffset: -32; } }

/* ==========================================================================
   AI MOTION LAYER — 3 effects, used sparingly and only with business meaning
   ========================================================================== */

/* 1) BORDER BEAM — a light trace continuously circling a card's border.
   Usage rule: ONLY on the one metric that is actively computed/refreshed by
   an AI/Rule Engine process (e.g. the hero "Tổng số user" stat, or later a
   live Yield/Cpk figure on the QC dashboard). Never on static content. */
@property --beam-angle { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
@keyframes beamRotate { to { --beam-angle: 360deg; } }
.border-beam { position: relative; isolation: isolate; }
.border-beam::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px;
  background: conic-gradient(from var(--beam-angle), transparent 0%, var(--ant-colorPrimary) 8%, var(--ai-glow) 14%, transparent 24%, transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  animation: beamRotate 4.5s linear infinite; pointer-events: none; z-index: 1;
}

/* 2) SHIMMER — a soft light sweep across a primary button.
   Usage rule: ONLY on the single main call-to-action of a screen (e.g.
   "Add user", "Đăng nhập", the confirm button of the primary flow) —
   never on every button, or it stops meaning "primary". */
@keyframes shimmerSweep { 0% { transform: translateX(-120%) skewX(-15deg); } 100% { transform: translateX(220%) skewX(-15deg); } }
.ant-btn-primary .shimmer {
  position: absolute; top:0; left:0; height:100%; width:35%;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,0.35), transparent);
  animation: shimmerSweep 2.8s ease-in-out infinite; pointer-events:none;
}

/* 3) LIVE PULSE — a small breathing dot.
   Usage rule: ONLY next to a module/process that is genuinely live right
   now (an AI engine currently running, an Active status). Do not attach to
   inert list items — a pulse implies "this is happening at this moment". */
@keyframes aiPulse { 0% { box-shadow: 0 0 0 0 rgba(94,230,168,0.55); } 70% { box-shadow: 0 0 0 6px rgba(94,230,168,0); } 100% { box-shadow: 0 0 0 0 rgba(94,230,168,0); } }
.ai-live-dot { width:6px; height:6px; border-radius:50%; background:#5EE6A8; flex-shrink:0; animation: aiPulse 2s ease-in-out infinite; }

/* AI badge pill — pairs with the effects above to label a section as AI-driven */
.ai-badge { display:inline-flex; align-items:center; gap:6px; font-size:11.5px; font-weight:600; color: var(--ant-colorPrimary); background: var(--ant-colorPrimaryBg); border:1px solid var(--ant-colorPrimaryBorder); padding:3px 10px 3px 8px; border-radius:999px; margin-left:10px; }
.ai-badge svg { width:12px; height:12px; }

/* ================= Layout ================= */
/* height (không phải min-height): ép Sider + Main giãn đúng 100vh theo
   flex stretch mặc định, để "ghim" cả sidebar lẫn header cố định — chỉ
   .ant-content bên trong cuộn riêng (xem overflow:hidden/auto bên dưới). */
.ant-layout { display:flex; height:100vh; }

.ant-sider { width: 232px; flex-shrink:0; background: var(--ant-siderBg); display:flex; flex-direction:column; }
.sider-logo { height:64px; display:flex; align-items:center; gap:10px; padding: 0 20px; border-bottom: 1px solid rgba(255,255,255,0.08); }
.sider-logo .mark { width:32px; height:32px; border-radius:6px; background:#fff; display:flex; align-items:center; justify-content:center; padding:3px; flex-shrink:0; }
.sider-logo .mark img { width:100%; height:100%; object-fit:contain; }
.sider-logo .txt { color:#fff; font-weight:600; font-size:14px; line-height:1.3; }
.sider-logo .sub { color: rgba(255,255,255,0.45); font-size:11px; font-family: var(--font-mono); }

.ant-menu { padding: 12px 8px; flex:1; overflow-y:auto; }
.menu-group-title { padding: 12px 12px 6px; font-size:11px; font-weight:600; letter-spacing:0.04em; text-transform:uppercase; color: rgba(255,255,255,0.3); }
.menu-item {
  display:flex; align-items:center; gap:10px; padding: 0 12px; height:40px; border-radius: var(--ant-borderRadius);
  color: var(--ant-siderItemColor); font-size:14px; cursor:pointer; margin-bottom:4px;
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}
.menu-item svg { width:16px; height:16px; flex-shrink:0; }
.menu-item:hover { background: var(--ant-siderItemHoverBg); color:#fff; }
.menu-item.selected { background: var(--ant-siderItemSelectedBg); color: var(--ant-siderItemSelectedColor); font-weight:500; }
.menu-item .ai-live-dot { margin-left:auto; }

.sider-foot { padding:14px 16px; border-top:1px solid rgba(255,255,255,0.08); display:flex; align-items:center; gap:10px; }
.ant-avatar { width:28px; height:28px; border-radius:50%; background: var(--ant-colorPrimary); color:#fff; display:flex; align-items:center; justify-content:center; font-size:12px; font-weight:600; flex-shrink:0; }
.sider-foot .who { color:#fff; font-size:12.5px; font-weight:500; }
.sider-foot .role { color: rgba(255,255,255,0.45); font-size:11px; }

.ant-main { flex:1; min-width:0; display:flex; flex-direction:column; overflow:hidden; }

/* ================= Header ================= */
.ant-header { height:64px; background: var(--ant-colorBgContainer); border-bottom: 1px solid var(--ant-colorBorderSecondary); display:flex; align-items:center; justify-content:space-between; padding: 0 24px; flex-shrink:0; }
.ant-breadcrumb { font-size:14px; color: var(--ant-colorTextTertiary); display:flex; align-items:center; gap:8px; }
.ant-breadcrumb b { color: var(--ant-colorText); font-weight:400; }
.header-actions { display:flex; align-items:center; gap:16px; }
.icon-btn-ant { width:36px; height:36px; display:flex; align-items:center; justify-content:center; border-radius:50%; color: var(--ant-colorTextSecondary); cursor:pointer; position:relative; transition: background 0.2s var(--ease); }
.icon-btn-ant:hover { background: var(--ant-colorFillTertiary); }
.icon-btn-ant svg { width:17px; height:17px; }
.icon-btn-ant .dot { position:absolute; top:8px; right:9px; width:6px; height:6px; border-radius:50%; background: var(--ant-colorError); border:1.5px solid #fff; }
.header-user { display:flex; align-items:center; gap:8px; cursor:pointer; }
.header-user .name { font-size:13.5px; font-weight:500; color: var(--ant-colorText); }
.header-user .email { font-size:11.5px; color: var(--ant-colorTextTertiary); }

.ant-content { padding:24px; flex:1; overflow-y:auto; }

.page-title { font-size:20px; font-weight:600; color: var(--ant-colorText); margin-bottom:4px; display:flex; align-items:center; }
.page-desc { font-size:13px; color: var(--ant-colorTextSecondary); }
.page-head { display:flex; align-items:flex-start; justify-content:space-between; margin-bottom:20px; flex-wrap:wrap; gap:12px; animation: fadeInUp 0.3s var(--ease) both; }

/* ================= Card ================= */
.ant-card { background: var(--ant-colorBgContainer); border: 1px solid var(--ant-colorBorderSecondary); border-radius: var(--ant-borderRadiusLG); animation: fadeInUp 0.3s var(--ease) both; animation-delay: 60ms; }
.ant-card-head { padding: 14px 20px; border-bottom: 1px solid var(--ant-colorBorderSecondary); display:flex; align-items:center; justify-content:space-between; }
.ant-card-head-title { font-size:15px; font-weight:600; }
.ant-card-body { padding: 20px; }

/* ================= Toolbar / filters ================= */
.toolbar-ant { display:flex; gap:10px; padding: 16px 20px; border-bottom: 1px solid var(--ant-colorBorderSecondary); flex-wrap:wrap; align-items:center; }
.ant-input-search { position:relative; flex:1; min-width:240px; }
.ant-input-search svg { position:absolute; left:11px; top:50%; transform:translateY(-50%); width:14px; height:14px; color: var(--ant-colorTextTertiary); pointer-events:none; }
.ant-input-search input { padding-left:34px !important; }

/* ================= Form controls ================= */
input[type=text], input[type=email], input[type=password], select {
  width:100%; font-family: var(--font-ui); font-size:14px; color: var(--ant-colorText);
  padding: 4px 11px; height:32px; border-radius: var(--ant-borderRadius); border: 1px solid var(--ant-colorBorder);
  background: var(--ant-colorBgContainer); outline:none;
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
input:focus, select:focus { border-color: var(--ant-colorPrimaryHover); box-shadow: 0 0 0 2px var(--ant-colorPrimaryBg); }
input::placeholder { color: var(--ant-colorTextQuaternary); }
select { min-width:150px; cursor:pointer; }

.ant-form-item { margin-bottom:20px; }
.ant-form-item-label { display:block; font-size:14px; color: var(--ant-colorText); margin-bottom:6px; }
.ant-form-item-label .req { color: var(--ant-colorError); margin-right:4px; }
.ant-form-item-explain-error { font-size:12.5px; color: var(--ant-colorError); margin-top:4px; display:flex; align-items:center; gap:4px; animation: fadeInUp 0.2s var(--ease) both; }
.ant-form-item-extra { font-size:12.5px; color: var(--ant-colorTextTertiary); margin-top:4px; }
.input-error { border-color: var(--ant-colorError) !important; animation: shakeX 300ms var(--ease); }
.input-icon-wrap { position:relative; }
.input-icon-wrap input { padding-right:36px; }
.input-icon-wrap .toggle-visibility { position:absolute; right:10px; top:50%; transform:translateY(-50%); cursor:pointer; color: var(--ant-colorTextTertiary); display:flex; }
.input-icon-wrap .toggle-visibility:hover { color: var(--ant-colorPrimary); }
.input-icon-wrap .toggle-visibility svg { width:15px; height:15px; }
.ant-input-prefix-icon { position:absolute; left:11px; top:50%; transform:translateY(-50%); color: var(--ant-colorTextQuaternary); display:flex; }
.has-prefix { padding-left: 32px !important; }

/* ================= Buttons ================= */
.ant-btn {
  height:32px; padding: 4px 15px; font-family: var(--font-ui); font-size:14px; font-weight:400;
  border-radius: var(--ant-borderRadius); border:1px solid var(--ant-colorBorder); background: var(--ant-colorBgContainer);
  color: var(--ant-colorText); cursor:pointer; display:inline-flex; align-items:center; gap:6px; position:relative; overflow:hidden;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease), background 0.2s var(--ease);
}
.ant-btn svg { width:14px; height:14px; }
.ant-btn:hover { color: var(--ant-colorPrimaryHover); border-color: var(--ant-colorPrimaryHover); }
.ant-btn-primary { background: var(--ant-colorPrimary); border-color: var(--ant-colorPrimary); color:#fff; }
.ant-btn-primary:hover { background: var(--ant-colorPrimaryHover); border-color: var(--ant-colorPrimaryHover); color:#fff; }
.ant-btn-primary:active { background: var(--ant-colorPrimaryActive); }
.ant-btn-dangerous { color: var(--ant-colorError); border-color: var(--ant-colorError); }
.ant-btn-dangerous:hover { color:#fff; background: #FF7875; border-color:#FF7875; }
.ant-btn-dangerous.ant-btn-primary { background: var(--ant-colorError); color:#fff; }
.ant-btn-dangerous.ant-btn-primary:hover { background:#FF7875; border-color:#FF7875; }
.ant-btn-text { border-color:transparent; background:transparent; }
.ant-btn-text:hover { background: var(--ant-colorFillTertiary); border-color:transparent; color: var(--ant-colorText); }
.ant-btn-lg { height:40px; padding:6.4px 15px; font-size:15px; }
.ant-btn-block { width:100%; justify-content:center; }
.ant-btn:disabled { cursor:not-allowed; color: var(--ant-colorTextDisabled); border-color: var(--ant-colorBorder); background: var(--ant-colorFillQuaternary); }

/* ================= Tag ================= */
.ant-tag { display:inline-flex; align-items:center; gap:5px; font-size:12px; line-height:20px; padding: 0 8px; border-radius: var(--ant-borderRadiusSM); border:1px solid; white-space:nowrap; }
.tag-success { color: #389E0D; background: var(--ant-colorSuccessBg); border-color: var(--ant-colorSuccessBorder); }
.tag-processing { color: #0958D9; background: var(--ant-colorInfoBg); border-color: var(--ant-colorInfoBorder); }
.tag-warning { color: #D48806; background: var(--ant-colorWarningBg); border-color: var(--ant-colorWarningBorder); }
.tag-default { color: rgba(0,0,0,0.65); background: var(--ant-colorFillQuaternary); border-color: var(--ant-colorBorderSecondary); }
.ant-tag .dot { width:6px; height:6px; border-radius:50%; background:currentColor; flex-shrink:0; }
.ant-tag .dot.pulse { animation: pulseDot 1.8s ease-in-out infinite; }
.ant-tag-primary { color: var(--ant-colorPrimary); background: var(--ant-colorPrimaryBg); border-color: var(--ant-colorPrimaryBorder); }

/* ================= Table ================= */
table.ant-table { width:100%; border-collapse:collapse; font-size:14px; }
table.ant-table thead th { text-align:left; font-weight:600; color: var(--ant-colorText); padding:12px 16px; background: var(--ant-colorFillQuaternary); border-bottom: 1px solid var(--ant-colorBorderSecondary); }
table.ant-table tbody td { padding:14px 16px; border-bottom: 1px solid var(--ant-colorBorderSecondary); }
table.ant-table tbody tr { transition: background 0.2s var(--ease); animation: fadeInUp 0.25s var(--ease) both; }
table.ant-table tbody tr:hover td { background: var(--ant-colorFillQuaternary); }
table.ant-table tbody tr:last-child td { border-bottom:none; }
.cell-user { display:flex; align-items:center; gap:10px; }
.cell-user .name { font-weight:500; color: var(--ant-colorText); }
.cell-user .sub { font-size:12px; color: var(--ant-colorTextTertiary); }
.text-secondary { color: var(--ant-colorTextSecondary); }
.actions-cell { display:flex; gap:4px; justify-content:flex-end; }
.action-icon { width:28px; height:28px; display:flex; align-items:center; justify-content:center; border-radius: var(--ant-borderRadius); color: var(--ant-colorTextSecondary); cursor:pointer; transition: background 0.2s var(--ease), color 0.2s var(--ease); }
.action-icon svg { width:15px; height:15px; }
.action-icon:hover { background: var(--ant-colorFillTertiary); color: var(--ant-colorPrimary); }
.action-icon.danger:hover { background: var(--ant-colorErrorBg); color: var(--ant-colorError); }

.skeleton { background: linear-gradient(90deg, var(--ant-colorFillQuaternary) 25%, var(--ant-colorFillTertiary) 37%, var(--ant-colorFillQuaternary) 63%); background-size:800px 100%; animation: shimmerSkeleton 1.5s linear infinite; border-radius:4px; height:14px; }

.ant-pagination { display:flex; align-items:center; justify-content:space-between; padding: 14px 20px; font-size:13px; color: var(--ant-colorTextSecondary); }
.page-btn { min-width:32px; height:32px; border-radius: var(--ant-borderRadius); border:1px solid var(--ant-colorBorder); background:#fff; display:flex; align-items:center; justify-content:center; font-size:13px; cursor:pointer; }
.page-btn:disabled { color: var(--ant-colorTextDisabled); cursor:not-allowed; }

/* ================= Modal ================= */
.ant-modal-mask { position:fixed; inset:0; background: rgba(0,0,0,0.45); display:flex; align-items:center; justify-content:center; z-index:50; padding:20px; animation: fadeIn 0.2s var(--ease) both; }
.ant-modal-mask.closing { animation: fadeIn 0.15s var(--ease) reverse both; }
.ant-modal { background:#fff; border-radius: var(--ant-borderRadiusLG); box-shadow: var(--ant-boxShadowSecondary); width:480px; max-width:100%; max-height:90vh; display:flex; flex-direction:column; overflow:hidden; animation: antZoomIn 0.2s var(--ease) both; }
.ant-modal-mask.closing .ant-modal { animation: antZoomOut 0.15s var(--ease) both; }
.ant-modal-header { padding: 16px 24px; border-bottom: 1px solid var(--ant-colorBorderSecondary); flex-shrink:0; }
.ant-modal-title { font-size:16px; font-weight:600; }
.ant-modal-close { position:absolute; top:16px; right:20px; width:22px; height:22px; display:flex; align-items:center; justify-content:center; color: var(--ant-colorTextTertiary); cursor:pointer; border-radius:4px; }
.ant-modal-close:hover { background: var(--ant-colorFillTertiary); color: var(--ant-colorText); }
.ant-modal-body { padding: 24px; position:relative; overflow-y:auto; flex:1 1 auto; min-height:0; }
.ant-modal-footer { padding: 10px 16px; border-top: 1px solid var(--ant-colorBorderSecondary); display:flex; justify-content:flex-end; gap:8px; flex-shrink:0; }
.modal-icon-danger { width:22px; height:22px; color: var(--ant-colorError); flex-shrink:0; }
.modal-confirm-body { display:flex; gap:12px; }
.modal-confirm-title { font-size:16px; font-weight:600; margin-bottom:8px; }
.modal-confirm-desc { font-size:14px; color: var(--ant-colorTextSecondary); line-height:1.6; }

.chip-tag { display:inline-flex; align-items:center; gap:5px; font-size:12px; padding: 1px 4px 1px 8px; border-radius: var(--ant-borderRadiusSM); background: var(--ant-colorPrimaryBg); color: var(--ant-colorPrimary); border: 1px solid var(--ant-colorPrimaryBorder); margin: 2px 4px 2px 0; }
.chip-tag svg { width:11px; height:11px; cursor:pointer; }
.chip-input-box { border:1px solid var(--ant-colorBorder); border-radius: var(--ant-borderRadius); padding:4px 6px; display:flex; flex-wrap:wrap; gap:2px; align-items:center; min-height:32px; transition: border-color 0.2s var(--ease); }
.chip-input-box:focus-within { border-color: var(--ant-colorPrimaryHover); box-shadow: 0 0 0 2px var(--ant-colorPrimaryBg); }
.chip-input-box input { border:none; flex:1; min-width:100px; height:24px; padding:2px 4px; box-shadow:none !important; }

/* ================= Message (top-center toast) ================= */
.ant-message { position:fixed; top:16px; left:50%; transform:translateX(-50%); z-index:100; display:flex; flex-direction:column; align-items:center; gap:8px; pointer-events:none; }
.ant-message-notice { background:#fff; border-radius: var(--ant-borderRadius); box-shadow: var(--ant-boxShadowSecondary); padding: 9px 16px; font-size:14px; color: var(--ant-colorText); display:flex; align-items:center; gap:8px; animation: antMessageIn 0.25s var(--ease) both; }
.ant-message-notice.closing { animation: fadeIn 0.2s var(--ease) reverse both; }
.ant-message-notice svg { width:16px; height:16px; color: var(--ant-colorSuccess); flex-shrink:0; }

/* ================= Auth pages ================= */
.auth-page { display:flex; min-height:100vh; }
.auth-side { width:46%; background: linear-gradient(160deg, var(--ant-siderBg) 0%, #0D0E47 100%); position:relative; overflow:hidden; display:flex; flex-direction:column; justify-content:space-between; padding:44px 52px; color:#fff; }
.auth-side .circuit-bg { position:absolute; inset:0; opacity:0.5; }
.auth-side .circuit-bg path { stroke-dasharray: 6 10; animation: dashFlow 3.6s linear infinite; }
.auth-side .circuit-bg circle { animation: pulseDot 2.6s ease-in-out infinite; }
.auth-side-top { position:relative; display:flex; align-items:center; gap:11px; }
.auth-side-top .mark { width:44px; height:44px; border-radius:8px; background:#fff; display:flex; align-items:center; justify-content:center; padding:5px; box-shadow: var(--ant-boxShadow); }
.auth-side-top .mark img { width:100%; height:100%; object-fit:contain; }
.auth-side-top .name { font-weight:600; font-size:15px; }
.auth-side-mid { position:relative; max-width:380px; }
.auth-side-mid h2 { font-size:26px; color:#fff; line-height:1.4; font-weight:600; }
.auth-side-mid p { font-size:13.5px; color: rgba(255,255,255,0.55); margin-top:12px; line-height:1.65; }
.auth-side-foot { position:relative; font-size:11.5px; color: rgba(255,255,255,0.4); }
.auth-form-wrap { flex:1; display:flex; align-items:center; justify-content:center; padding:40px; background: var(--ant-colorBgLayout); }
.auth-card-box { width:100%; max-width:380px; }
.auth-card-box h1 { font-size:24px; margin-bottom:8px; }
.auth-card-box .sub { font-size:14px; color: var(--ant-colorTextSecondary); margin-bottom:28px; }
.ant-checkbox-wrap { display:flex; align-items:center; gap:7px; font-size:13.5px; color: var(--ant-colorText); cursor:pointer; }
.ant-checkbox-box { width:16px; height:16px; border-radius:4px; border:1px solid var(--ant-colorBorder); display:flex; align-items:center; justify-content:center; }

@media (max-width: 900px) {
  .auth-side { display:none; }
  .ant-sider { display:none; }
}

  #userGrid { width:100%; }

  .gc-user { display:flex; align-items:center; gap:10px; height:100%; }
  .gc-avatar { width:29px; height:29px; border-radius:50%; background:var(--ant-colorPrimary); color:#fff; display:flex; align-items:center; justify-content:center; font-size:11px; font-weight:600; flex-shrink:0; }
  .gc-name { font-weight:500; color:var(--ant-colorText); }
  .gc-email-wrap { line-height:1.35; }
  .gc-email-sub { font-size:11.5px; color:var(--ant-colorTextTertiary); font-family:var(--font-mono); }
  .gc-actions { display:flex; gap:2px; justify-content:flex-end; height:100%; align-items:center; }
  .gc-action-icon { width:28px; height:28px; display:flex; align-items:center; justify-content:center; border-radius:var(--ant-borderRadius); color:var(--ant-colorTextSecondary); cursor:pointer; transition:background .2s var(--ease), color .2s var(--ease); }
  .gc-action-icon:hover { background:var(--ant-colorFillTertiary); color:var(--ant-colorPrimary); }
  .gc-action-icon.danger:hover { background:var(--ant-colorErrorBg); color:var(--ant-colorError); }
  .gc-action-icon svg { width:15px; height:15px; pointer-events:none; }

  /* Custom Filter Component popup (Vai trò / Trạng thái) — hiện khi bấm
     icon phễu trên header, không chiếm thêm hàng nào trên bảng */
  .cf-filter-popup { padding:10px; min-width:180px; }
  .cf-filter-label { font-size:12px; font-weight:600; color:var(--ant-colorTextSecondary); margin-bottom:6px; }
  .cf-select { width:100%; height:32px; font-size:13px; border-radius:var(--ant-borderRadius); border:1px solid var(--ant-colorBorder); background:#fff; padding:0 8px; cursor:pointer; }
  .cf-select:focus { outline:none; border-color:var(--ant-colorPrimaryHover); box-shadow:0 0 0 2px var(--ant-colorPrimaryBg); }
  /* ================= Login page additions ================= */
  .login-alert {
    display: flex; align-items: flex-start; gap: 8px; margin: -8px 0 18px; padding: 10px 12px;
    background: var(--ant-colorErrorBg); border: 1px solid var(--ant-colorErrorBorder); border-radius: var(--ant-borderRadius);
    font-size: 13px; color: var(--ant-colorError); line-height: 1.5; animation: fadeInUp 0.2s var(--ease) both;
  }
  .login-alert.success { background: var(--ant-colorSuccessBg); border-color: var(--ant-colorSuccessBorder); color: #389E0D; }
  .login-alert svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 1px; }

  .demo-hint {
    margin-top: 18px; padding: 10px 12px; border-radius: var(--ant-borderRadius);
    background: var(--ant-colorFillQuaternary); border: 1px dashed var(--ant-colorBorder);
    font-size: 12px; line-height: 1.7; color: var(--ant-colorTextSecondary);
  }
  .demo-hint b { color: var(--ant-colorText); }

  /* ================= User menu dropdown (header-user) ================= */
  .header-user { position: relative; }
  .user-dropdown {
    position: absolute; top: 46px; right: 0; background: #fff;
    border: 1px solid var(--ant-colorBorderSecondary); border-radius: var(--ant-borderRadius);
    box-shadow: var(--ant-boxShadowSecondary); min-width: 180px; padding: 6px; z-index: 60;
    animation: antZoomIn 0.15s var(--ease) both;
  }
  .user-dropdown-item { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: var(--ant-borderRadius); font-size: 13.5px; color: var(--ant-colorText); cursor: pointer; }
  .user-dropdown-item:hover { background: var(--ant-colorFillTertiary); }
  .user-dropdown-item svg { width: 15px; height: 15px; color: var(--ant-colorTextSecondary); flex-shrink: 0; }
  .user-dropdown-item.danger { color: var(--ant-colorError); }
  .user-dropdown-item.danger svg { color: var(--ant-colorError); }
  .user-dropdown-divider { height: 1px; background: var(--ant-colorBorderSecondary); margin: 4px 0; }


/* ============================================================
   TEMPLATE MANAGEMENT — bổ sung riêng cho trang này
   (kế thừa toàn bộ design token/AntD component ở trên, không
   định nghĩa lại font/màu — chỉ thêm layout mới: flow banner,
   Drawer, Tabs, checklist hạng mục cấu trúc, wizard import)
   ============================================================ */

.page-title-row { display:flex; align-items:center; gap:10px; }
.page-desc { font-size:13px; color: var(--ant-colorTextSecondary); margin-top:4px; max-width:640px; }
.page-head-actions { display:flex; gap:10px; flex-shrink:0; }

/* ================= Flow context banner ================= */
.flow-banner {
  background: var(--ant-colorPrimaryBg); border: 1px solid var(--ant-colorPrimaryBorder);
  border-radius: var(--ant-borderRadiusLG); padding: 14px 20px; margin-bottom: 20px;
  display:flex; align-items:center; gap:4px; overflow-x:auto; animation: fadeInUp 0.3s var(--ease) both;
}
.flow-banner-label { font-size:11.5px; font-weight:600; color: var(--ant-colorPrimary); text-transform:uppercase; letter-spacing:0.03em; flex-shrink:0; margin-right:14px; white-space:nowrap; }
.flow-step { display:flex; align-items:center; gap:8px; flex-shrink:0; }
.flow-step-num {
  width:22px; height:22px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:11px; font-weight:600; background:#fff; border:1.5px solid var(--ant-colorBorder); color: var(--ant-colorTextTertiary);
  flex-shrink:0; transition: all 0.2s var(--ease);
}
.flow-step.active .flow-step-num { background: var(--ant-colorPrimary); border-color: var(--ant-colorPrimary); color:#fff; }
.flow-step-label { font-size:12.5px; color: var(--ant-colorTextTertiary); white-space:nowrap; }
.flow-step.active .flow-step-label { color: var(--ant-colorPrimary); font-weight:600; }
.flow-step:not(.active) { cursor:pointer; }
.flow-step:not(.active):hover .flow-step-num { border-color: var(--ant-colorPrimary); color: var(--ant-colorPrimary); }
.flow-step:not(.active):hover .flow-step-label { color: var(--ant-colorPrimary); }
.flow-arrow { color: var(--ant-colorTextQuaternary); flex-shrink:0; display:flex; }
.flow-arrow svg { width:14px; height:14px; }

/* ================= AG Grid host cho Template ================= */
#tmGrid { width:100%; }
.gc-tpl { display:flex; align-items:center; gap:10px; height:100%; }
.gc-tpl-icon { width:32px; height:32px; border-radius: var(--ant-borderRadius); background: var(--ant-colorPrimaryBg); color: var(--ant-colorPrimary); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.gc-tpl-icon svg { width:16px; height:16px; }
.gc-tpl-name { font-weight:500; color: var(--ant-colorText); line-height:1.3; white-space:normal; }
.gc-struct-wrap { display:flex; flex-direction:column; gap:4px; width:100%; padding-right:12px; }
.gc-struct-count { font-size:12px; color: var(--ant-colorTextSecondary); font-family: var(--font-mono); }
.progress-bar-track { height:6px; border-radius:3px; background: var(--ant-colorFillTertiary); overflow:hidden; width:100%; }
.progress-bar-fill { height:100%; background: var(--ant-colorPrimary); border-radius:3px; transition: width 0.3s var(--ease); }
.progress-bar-fill.complete { background: var(--ant-colorSuccess); }

/* ================= Drawer ================= */
.ant-drawer-mask { position:fixed; inset:0; background: rgba(0,0,0,0.45); z-index:50; animation: fadeIn 0.2s var(--ease) both; display:flex; justify-content:flex-end; }
.ant-drawer-mask.closing { animation: fadeIn 0.15s var(--ease) reverse both; }
@keyframes drawerSlideIn { from { transform: translateX(100%); } to { transform: translateX(0); } }
@keyframes drawerSlideOut { from { transform: translateX(0); } to { transform: translateX(100%); } }
.ant-drawer {
  width: min(760px, 94vw); height:100vh; background:#fff; box-shadow: var(--ant-boxShadowSecondary);
  display:flex; flex-direction:column; animation: drawerSlideIn 0.25s var(--ease) both;
}
.ant-drawer-mask.closing .ant-drawer { animation: drawerSlideOut 0.2s var(--ease) both; }
.ant-drawer-header { padding: 18px 24px; border-bottom: 1px solid var(--ant-colorBorderSecondary); display:flex; align-items:flex-start; justify-content:space-between; flex-shrink:0; }
.ant-drawer-title { font-size:16px; font-weight:600; }
.ant-drawer-subtitle { font-size:12.5px; color: var(--ant-colorTextTertiary); margin-top:3px; font-family: var(--font-mono); }
.ant-drawer-close { width:26px; height:26px; display:flex; align-items:center; justify-content:center; color: var(--ant-colorTextTertiary); cursor:pointer; border-radius:4px; flex-shrink:0; }
.ant-drawer-close:hover { background: var(--ant-colorFillTertiary); color: var(--ant-colorText); }
.ant-drawer-body { flex:1; overflow-y:auto; padding: 4px 0 24px; }
.ant-drawer-footer { padding: 12px 24px; border-top: 1px solid var(--ant-colorBorderSecondary); display:flex; justify-content:space-between; align-items:center; gap:8px; flex-shrink:0; }

/* ================= Tabs ================= */
.ant-tabs-nav { display:flex; gap:28px; padding: 0 24px; border-bottom: 1px solid var(--ant-colorBorderSecondary); position:sticky; top:0; background:#fff; z-index:2; }
.ant-tabs-tab { padding: 13px 0; font-size:14px; color: var(--ant-colorTextSecondary); cursor:pointer; position:relative; white-space:nowrap; transition: color 0.2s var(--ease); }
.ant-tabs-tab:hover { color: var(--ant-colorText); }
.ant-tabs-tab.active { color: var(--ant-colorPrimary); font-weight:500; }
.ant-tabs-tab.active::after { content:''; position:absolute; bottom:-1px; left:0; right:0; height:2px; background: var(--ant-colorPrimary); border-radius:2px 2px 0 0; }
.ant-tabs-pane { display:none; padding: 20px 24px 0; animation: fadeIn 0.2s var(--ease) both; }
.ant-tabs-pane.active { display:block; }

/* ================= Detail info grid (Tab: Thông tin chung) ================= */
.info-grid { display:grid; grid-template-columns: repeat(2, 1fr); gap:16px 24px; margin-bottom:24px; }
.info-grid .full { grid-column: 1 / -1; }
.info-item-label { font-size:12px; color: var(--ant-colorTextTertiary); margin-bottom:4px; }
.info-item-value { font-size:14px; color: var(--ant-colorText); }
.info-item-value.mono { font-family: var(--font-mono); font-size:13px; }

/* ================= Cấu trúc file — checklist theo nhóm ================= */
.struct-summary { display:flex; align-items:center; gap:14px; padding:14px 16px; background: var(--ant-colorFillQuaternary); border-radius: var(--ant-borderRadiusLG); margin-bottom:20px; }
.struct-summary-count { font-family: var(--font-mono); font-size:20px; font-weight:600; color: var(--ant-colorText); flex-shrink:0; }
.struct-summary-bar { flex:1; }
.struct-summary-label { font-size:12px; color: var(--ant-colorTextSecondary); margin-bottom:6px; }

.struct-group { margin-bottom:20px; }
.struct-group-title { font-size:11.5px; font-weight:600; letter-spacing:0.03em; text-transform:uppercase; color: var(--ant-colorTextTertiary); margin-bottom:8px; padding-left:2px; }
.struct-item {
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:10px 12px; border:1px solid var(--ant-colorBorderSecondary); border-radius: var(--ant-borderRadius);
  margin-bottom:8px; transition: border-color 0.2s var(--ease), background 0.2s var(--ease);
}
.struct-item:hover { border-color: var(--ant-colorPrimaryBorder); background: var(--ant-colorPrimaryBg); }
.struct-item-left { display:flex; align-items:center; gap:11px; min-width:0; }
.struct-item-idx { width:22px; height:22px; border-radius:50%; background: var(--ant-colorFillTertiary); color: var(--ant-colorTextSecondary); font-size:11px; font-weight:600; display:flex; align-items:center; justify-content:center; flex-shrink:0; font-family: var(--font-mono); }
.struct-item-text { min-width:0; }
.struct-item-name { font-size:13.5px; font-weight:500; color: var(--ant-colorText); }
.struct-item-map { font-size:11.5px; color: var(--ant-colorTextTertiary); font-family: var(--font-mono); margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.struct-item-right { display:flex; align-items:center; gap:8px; flex-shrink:0; }
.struct-status-icon { width:16px; height:16px; flex-shrink:0; }
.struct-status-icon.done { color: var(--ant-colorSuccess); }
.struct-status-icon.pending { color: var(--ant-colorWarning); }
.struct-status-icon.na { color: var(--ant-colorTextQuaternary); }
.badge-req { font-size:11.5px; font-weight:500; color: var(--ant-colorError); white-space:nowrap; }
.badge-opt { font-size:11.5px; color: var(--ant-colorTextTertiary); white-space:nowrap; }

/* ================= Version history table (Tab 3) ================= */
.vh-table { width:100%; border-collapse:collapse; font-size:13px; }
.vh-table th { text-align:left; font-weight:600; color: var(--ant-colorTextSecondary); padding:8px 10px; border-bottom:1px solid var(--ant-colorBorderSecondary); font-size:12px; }
.vh-table td { padding:10px 10px; border-bottom:1px solid var(--ant-colorBorderSecondary); vertical-align:top; }
.vh-table tr:last-child td { border-bottom:none; }
.vh-rev-badge { display:inline-flex; align-items:center; justify-content:center; width:24px; height:24px; border-radius:50%; background: var(--ant-colorPrimaryBg); color: var(--ant-colorPrimary); font-weight:700; font-size:12px; font-family: var(--font-mono); }
.vh-rev-badge.current { background: var(--ant-colorPrimary); color:#fff; }

/* ================= Wizard (Import Template) ================= */
.wizard-steps { display:flex; align-items:center; margin-bottom:26px; }
.wizard-step { display:flex; align-items:center; gap:8px; color: var(--ant-colorTextTertiary); flex-shrink:0; }
.wizard-step-num { width:26px; height:26px; border-radius:50%; border:1.5px solid currentColor; display:flex; align-items:center; justify-content:center; font-size:12.5px; font-weight:600; flex-shrink:0; transition: all 0.2s var(--ease); }
.wizard-step-label { font-size:13px; font-weight:500; white-space:nowrap; }
.wizard-step.active { color: var(--ant-colorPrimary); }
.wizard-step.active .wizard-step-num { background: var(--ant-colorPrimary); color:#fff; border-color: var(--ant-colorPrimary); }
.wizard-step.done { color: var(--ant-colorSuccess); }
.wizard-step.done .wizard-step-num { background: var(--ant-colorSuccess); color:#fff; border-color: var(--ant-colorSuccess); }
.wizard-divider { flex:1; height:1px; background: var(--ant-colorBorderSecondary); margin:0 12px; min-width:24px; }

.wizard-pane { display:none; }
.wizard-pane.active { display:block; animation: fadeInUp 0.25s var(--ease) both; }

.dropzone {
  border:1.5px dashed var(--ant-colorBorder); border-radius: var(--ant-borderRadiusLG);
  padding:36px 20px; text-align:center; cursor:pointer; transition: border-color 0.2s var(--ease), background 0.2s var(--ease);
  margin-bottom:18px;
}
.dropzone:hover, .dropzone.dragover { border-color: var(--ant-colorPrimary); background: var(--ant-colorPrimaryBg); }
.dropzone svg { width:30px; height:30px; color: var(--ant-colorTextTertiary); margin-bottom:10px; }
.dropzone-title { font-size:14px; font-weight:500; color: var(--ant-colorText); margin-bottom:4px; }
.dropzone-sub { font-size:12px; color: var(--ant-colorTextTertiary); }
.dropzone.has-file { border-style:solid; border-color: var(--ant-colorSuccessBorder); background: var(--ant-colorSuccessBg); }
.dropzone-file-row { display:flex; align-items:center; gap:10px; justify-content:center; }
.dropzone-file-row svg { width:20px; height:20px; margin:0; color: var(--ant-colorSuccess); }

.scope-cascade { display:flex; align-items:flex-end; gap:6px; flex-wrap:nowrap; }
.scope-cascade-col { flex:1; min-width:0; }
.scope-cascade-label { font-size:11.5px; color: var(--ant-colorTextTertiary); margin-bottom:4px; }
.scope-cascade-label .scope-cascade-optional { color: var(--ant-colorTextQuaternary); }
.scope-cascade-col select { width:100%; }
.scope-cascade-col select:disabled { cursor:not-allowed; color: var(--ant-colorTextQuaternary); background: var(--ant-colorFillQuaternary); }
.scope-cascade-arrow { flex-shrink:0; width:14px; height:14px; color: var(--ant-colorTextQuaternary); margin-bottom:9px; }

.scan-progress { text-align:center; padding:34px 20px; }
.scan-spinner { width:38px; height:38px; border-radius:50%; border:3px solid var(--ant-colorPrimaryBorder); border-top-color: var(--ant-colorPrimary); margin:0 auto 16px; animation: spin 0.8s linear infinite; }
.scan-title { font-size:14px; font-weight:500; margin-bottom:4px; }
.scan-sub { font-size:12.5px; color: var(--ant-colorTextTertiary); font-family: var(--font-mono); }

.detect-summary { display:flex; align-items:center; gap:12px; padding:13px 16px; border-radius: var(--ant-borderRadiusLG); margin-bottom:18px; background: var(--ant-colorSuccessBg); border:1px solid var(--ant-colorSuccessBorder); }
.detect-summary svg { width:20px; height:20px; color: var(--ant-colorSuccess); flex-shrink:0; }
.detect-summary-title { font-size:13.5px; font-weight:600; color:#389E0D; }
.detect-summary-desc { font-size:12px; color: var(--ant-colorTextSecondary); margin-top:1px; }
.detect-scroll { max-height:340px; overflow-y:auto; padding-right:4px; margin-bottom:6px; }

/* ================= Model picker (liên kết Template ↔ Model) ================= */
.model-picker { border:1px solid var(--ant-colorBorder); border-radius: var(--ant-borderRadius); padding:10px 12px; max-height:220px; overflow-y:auto; }
.model-picker-item { display:flex; align-items:center; gap:8px; padding:6px 2px; font-size:13px; cursor:pointer; }
.model-picker-item input { cursor:pointer; flex-shrink:0; }
.model-picker-add { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; padding-top:10px; border-top:1px dashed var(--ant-colorBorderSecondary); }
.conflict-warning { background: var(--ant-colorWarningBg); border:1px solid var(--ant-colorWarningBorder); border-radius: var(--ant-borderRadius); padding:10px 12px; font-size:12.5px; color:#AD6800; margin-top:14px; line-height:1.7; }

@media (max-width: 900px) {
  .info-grid { grid-template-columns: 1fr; }
  .ant-drawer { width:100vw; }
}
