/* ========== HaloTab 网址导航主样式 ========== */

:root{
  --ht-bg: #f4f6fa;
  --ht-card-bg: rgba(255,255,255,.18);          /* 偏透明，配白字 */
  --ht-card-border: rgba(255,255,255,.22);
  --ht-card-shadow: 0 1px 2px rgba(0,0,0,.05), 0 8px 24px rgba(0,0,0,.12);
  --ht-card-shadow-hover: 0 4px 12px rgba(0,0,0,.18), 0 16px 40px rgba(0,0,0,.28);
  --ht-text: #ffffff;                            /* 主体文字偏白 */
  --ht-text-soft: rgba(255,255,255,.7);
  /* —— 主色（科技感冷调）：电蓝 → 电光紫 ——
   * 旧：#5b8def → #8b5cf6（蓝紫，偏柔）
   * 新：#3ba5ff → #7c5cff（更冷、更亮，对比更强，贴近 Cyber/Sci-Fi UI）
   * --ht-accent-rgb 给后续 rgba(...) 渐进替换用 */
  --ht-accent:    #3ba5ff;
  --ht-accent-2:  #7c5cff;
  --ht-accent-rgb: 59,165,255;
  /* 主品牌色 —— 默认/图片背景使用科技蓝；选择渐变背景时 JS 会临时联动为该渐变最后一个色值 */
  --ht-grad: #3ba5ff;
  --ht-radius: 14px;
  --ht-radius-sm: 10px;
  --ht-header-h: 0px;
  --ht-footer-h: 50px;
}
html[data-theme="dark"]{
  --ht-bg:#0f1115;
  --ht-card-bg: rgba(28,30,38,.5);
  --ht-card-border: rgba(255,255,255,.14);
  --ht-card-shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.6);
  --ht-card-shadow-hover: 0 4px 12px rgba(0,0,0,.55), 0 16px 40px rgba(0,0,0,.7);
  --ht-text:#ffffff;
  --ht-text-soft: rgba(255,255,255,.7);
}
@media (prefers-color-scheme: dark){
  html[data-theme="auto"]{
    --ht-bg:#0f1115;
    --ht-card-bg: rgba(28,30,38,.5);
    --ht-card-border: rgba(255,255,255,.14);
    --ht-card-shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.6);
    --ht-card-shadow-hover: 0 4px 12px rgba(0,0,0,.55), 0 16px 40px rgba(0,0,0,.7);
    --ht-text:#ffffff;
    --ht-text-soft: rgba(255,255,255,.7);
  }
}

*{box-sizing:border-box}
html,body{
  margin:0; padding:0;
  height:100%;
  /* 让 body 填满整屏，footer 贴底 */
}
body.halotab-body{
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", Roboto, sans-serif;
  color: var(--ht-text);
  background: var(--ht-bg);
  -webkit-font-smoothing:antialiased;
  display:flex; flex-direction:column; min-height:100vh;
  position:relative;
}

/* ----- 背景层（壁纸 / 纯色，不再做高斯模糊） ----- */
.halotab-bg, .halotab-bg-mask{
  position:fixed; inset:0; z-index:-1; pointer-events:none;
}
.halotab-bg{
  background-size:cover;
  background-position:center;
  background-repeat:no-repeat;
}
body.halotab-body .halotab-bg:not([style*="background-image"]):not([style*="background-color"]){
  background: linear-gradient(135deg, #c2e9fb 0%, #a1c4fd 50%, #fbc2eb 100%);
}
html[data-theme="dark"] body.halotab-body .halotab-bg:not([style*="background-image"]):not([style*="background-color"]),
html[data-theme="auto"] body.halotab-body .halotab-bg:not([style*="background-image"]):not([style*="background-color"]){
  background: linear-gradient(135deg, #1e293b 0%, #0f172a 50%, #312e81 100%);
}
/* 遮罩层：由外观设置控制透明度与毛玻璃强度 */
.halotab-bg-mask{
  --ht-mask-opacity: 0;
  --ht-glass-blur: 0px;
  background: rgba(0,0,0,var(--ht-mask-opacity));
  -webkit-backdrop-filter: blur(var(--ht-glass-blur));
  backdrop-filter: blur(var(--ht-glass-blur));
  transition: background .2s ease;
}

/* ----- 顶部导航（已移除，保留兼容声明） ----- */
.halotab-header{ display: none; }

/* ----- 右下角浮动操作 ----- */
.halotab-fab{
  position: fixed; right: 16px; bottom: calc(var(--ht-footer-h) + 12px);
  z-index: 28;
  display:flex; gap:6px; align-items:center;
  background: rgba(255,255,255,.16);
  border: 1px solid rgba(255,255,255,.22);
  padding: 5px;
  border-radius: 999px;
  box-shadow: 0 4px 14px rgba(0,0,0,.18);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: gap .2s ease;
}
/* 收起模式：隐藏所有按钮，只保留 toggle 按钮 */
.halotab-fab.collapsed .halotab-icon-btn:not(.halotab-fab-toggle){ display:none; }
.halotab-fab.collapsed{ gap:0; }
/* toggle 按钮：展开/收起切换 */
.halotab-fab-toggle{
  background:transparent; border: none;
  color:var(--ht-text); padding:6px 10px; border-radius: 999px; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center;
  text-decoration:none; font-size:13px;
}
.halotab-fab-toggle:hover{ background: rgba(255,255,255,.2); }
.halotab-icon-btn{
  background:transparent; border: none;
  color:var(--ht-text); padding:6px 12px; border-radius: 999px; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  text-decoration:none; font-size:13px;
}
.halotab-icon-btn:hover{ background: rgba(255,255,255,.2); }

/* ----- 顶部固定区：时钟 + 日期 + 搜索框 ----- */
.halotab-top{
  flex-shrink: 0;
  width: 80%;
  max-width: 1600px;
  margin: 0 auto;
  padding: 40px 0 20px;
  text-align: center;
}

/* ----- 主体（自动撑开） ----- */
.halotab-main{
  flex: 1 1 0;        /* 自动填充顶部和底部之间的剩余空间 */
  min-height: 0;       /* flex 子元素 overflow 必备 */
  width: 100%;
  margin: 0 auto;
  padding: 0;
  display: flex; flex-direction: column;
  position: relative;
}

/* loading */
.halotab-loading{
  text-align:center; padding: 80px 20px;
  color: var(--ht-text-soft);
  font-size:14px;
}

/* ============================================================
 *  分页（pager）：mTab 风格的整页 transform 切换
 *  - 高度由 main flex 撑出（主体填充剩余空间）
 *  - 每页 = 标签卡片网格区，超出则内部竖向滚动
 * ============================================================ */
.halotab-pager{
  flex: 1 1 0;
  min-height: 0;
  width: 100%;
  position: relative;
  overflow: hidden;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}
.halotab-pager-track{
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  transition: transform .55s cubic-bezier(.22, 1, .36, 1);
}
.halotab-pager.dragging .halotab-pager-track{ transition: none !important; }

.halotab-page{
  width: 100%;
  height: 100%;          /* 与 pager 等高 */
  flex-shrink: 0;
  display: flex; align-items: stretch; justify-content: center;
  padding: 16px 0 24px;  /* 左右留给 .halotab-page-inner 的 80% 居中布局 */
  position: relative;
  overflow-y: auto;
  scrollbar-width: thin;
}
.halotab-page::-webkit-scrollbar{ width: 6px; }
.halotab-page::-webkit-scrollbar-thumb{ background: rgba(255,255,255,.25); border-radius: 3px; }

.halotab-page-inner{
  width: 100%;
  max-width: 1160px;
  padding: 0 12px;
  box-sizing: border-box;
  margin: 0 auto;
  align-self: stretch;        /* 与 page 等高，给 group 一个可撑满的高度上下文 */
  display: flex;
  flex-direction: column;
  /* 入场动画：默认隐藏，当前页 .on 时浮现 */
  opacity: 0;
  transform: translateY(28px) scale(.985);
  transition: opacity .55s cubic-bezier(.22, 1, .36, 1) .08s,
              transform .55s cubic-bezier(.22, 1, .36, 1) .08s;
}
/* 2K+ 屏幕（≥2560px）加宽容器，让 12 列 80px 卡片有充裕空间 */
@media (min-width: 2560px){
  .halotab-page-inner{ max-width: 1440px; }
}
/* 1080p ~ 2K 屏幕（≥1920px）适度加宽 */
@media (min-width: 1920px) and (max-width: 2559px){
  .halotab-page-inner{ max-width: 1320px; }
}
.halotab-page.on > .halotab-page-inner{
  opacity: 1;
  transform: none;
}

/* 第一页：封面（Hero）整页居中 */
.halotab-page-hero{ align-items: center; }
.halotab-page-hero .halotab-hero{ margin: 0; }

/* 普通分组页：让分组容器与网格垂直撑满整页（卡片少时也均匀占据空间） */
.halotab-page-group .halotab-group{
  margin-top: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.halotab-page-group .halotab-grid{
  flex: 1 1 auto;
  align-content: start;       /* 行从顶部开始排列，避免被强行拉伸成超大格 */
}

/* ============================================================
 * 右侧分组指示器（图标 + 名称 上下排列；末尾固定"添加分组"按钮）
 *
 * 设计要点：
 *   - 外壳：轻玻璃（低饱和白底 + 高斯模糊 + 细描边），避免在亮/暗背景上"糊"
 *   - 项目：默认完全透明，仅 hover/active 出现底色；用左侧 3px 圆点指示当前项
 *   - 动效：transform + 颜色过渡，不再依赖 box-shadow 抢戏
 *   - 文字：与图标拉开间距，使用细字重 + 字距，提升节奏感
 * ============================================================ */
.halotab-dots{
  position: fixed;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 30;
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 6px;
  background: rgba(255,255,255,.10);
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 20px;
  box-shadow:
    0 8px 24px -8px rgba(0,0,0,.28),
    inset 0 1px 0 rgba(255,255,255,.16);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,.28) transparent;
}
.halotab-dots::-webkit-scrollbar{ width: 4px; }
.halotab-dots::-webkit-scrollbar-track{ background: transparent; }
.halotab-dots::-webkit-scrollbar-thumb{
  background: rgba(255,255,255,.28);
  border-radius: 4px;
}
.halotab-dots::-webkit-scrollbar-thumb:hover{ background: rgba(255,255,255,.45); }

.halotab-dot{
  /* 上下排列：图标在上、文字在下 */
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 5px;
  width: 60px;
  padding: 9px 4px 8px;
  border: none; cursor: pointer;
  background: transparent;
  border-radius: 14px;
  color: rgba(255,255,255,.78);
  transition:
    background-color .18s ease,
    color .18s ease,
    transform .25s cubic-bezier(.34,1.56,.64,1);
  position: relative;
  -webkit-tap-highlight-color: transparent;
}
.halotab-dot::before{
  /* 左侧 active 指示圆点（默认隐藏） */
  content: '';
  position: absolute;
  left: 2px;
  top: 50%;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: #fff;
  opacity: 0;
  transform: translateY(-50%) scale(.4);
  transition: opacity .2s ease, transform .25s cubic-bezier(.34,1.56,.64,1), height .25s ease;
}
.halotab-dot:hover{
  background: rgba(255,255,255,.12);
  color: #fff;
}
.halotab-dot:active{ transform: scale(.96); }
.halotab-dot.on{
  background: rgba(255,255,255,.18);
  color: #fff;
}
.halotab-dot.on::before{
  opacity: 1;
  height: 18px;
  border-radius: 2px;
  transform: translateY(-50%) scale(1);
}
.halotab-dot-icon{
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  font-size: 20px;             /* emoji / 文字图标字号 */
  line-height: 1;
  transition: transform .25s cubic-bezier(.34,1.56,.64,1);
}
.halotab-dot:hover .halotab-dot-icon{ transform: translateY(-1px); }
.halotab-dot.on .halotab-dot-icon{ transform: scale(1.06); }
.halotab-dot-icon img{
  width: 24px; height: 24px;
  object-fit: contain;
  display: block;
}
.halotab-dot-icon > .ht-i{
  /* 容器是 28x28 flex 居中，把图标做到 22px 视觉重量更接近 emoji */
  width: 22px; height: 22px;
  font-size: 22px;
  vertical-align: 0;
}
.halotab-dot-text{
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .2px;
  line-height: 1.2;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
  opacity: .92;
}
.halotab-dot.on .halotab-dot-text{ font-weight: 500; opacity: 1; }

/* 切换分组时：当前项短暂强调（轻量化，仅 scale，不再额外加阴影） */
.halotab-dot.flash{
  animation: ht-dot-pop .55s cubic-bezier(.34,1.56,.64,1);
}
@keyframes ht-dot-pop{
  0%   { transform: scale(1); }
  40%  { transform: scale(1.10); }
  100% { transform: scale(1); }
}

/* "添加分组"按钮：与分组项视觉区分（虚线边 + 顶部细分隔线） */
.halotab-dot-add{
  margin-top: 4px;
  padding-top: 10px;
  border: 1px dashed rgba(255,255,255,.35);
  color: var(--ht-text-soft);
  position: relative;
}
.halotab-dot-add::after{
  /* 与上方分组之间一条若隐若现的分隔线 */
  content: '';
  position: absolute;
  left: 10px; right: 10px; top: -3px;
  height: 1px;
  background: linear-gradient(90deg,
    transparent,
    rgba(255,255,255,.22),
    transparent);
}
.halotab-dot-add:hover{
  border-color: rgba(255,255,255,.7);
  background: rgba(255,255,255,.12);
  color: #fff;
}
.halotab-dot-add .halotab-dot-icon{ font-size: 22px; font-weight: 300; }

/* ---------- 分组拖动排序（编辑模式） ---------- */
.halotab-dot[draggable="true"]{ cursor: grab; }
.halotab-dot[draggable="true"]:active{ cursor: grabbing; }
.halotab-dot.ht-dragging{
  opacity: .35;
  transform: scale(.95);
  /* drop 后此 class 被移除，opacity / scale 回到默认值 ——
   * 这就是 dot"副本回归本体"的过渡，时长与 FLIP 一致更协调 */
  transition: opacity .35s ease, transform .35s cubic-bezier(.22,.61,.36,1);
}
/* FLIP：拖动过程中实时交换位置，从旧位置平滑滑到新位置 */
.halotab-dot.ht-flip{
  transition: transform .45s cubic-bezier(.22,.61,.36,1) !important;
  will-change: transform;
}


/* ----- Hero（顶部固定区内的视觉元素） ----- */
.halotab-hero{ text-align:center; }
/* 时钟（HH:MM:SS）大字，等宽数字，白色 + 淡阴影 */
.halotab-hero-clock{
  font-size: 64px; font-weight: 500; margin: 0 0 6px;
  letter-spacing: 2px;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  color: #ffffff;
  text-shadow: 0 2px 12px rgba(0,0,0,.25);
  line-height: 1.05;
}
.halotab-hero-date{
  color: #ffffff;
  margin: 0 0 22px;
  font-size: 15px;
  letter-spacing: .5px;
  opacity: .9;
  text-shadow: 0 1px 6px rgba(0,0,0,.25);
}
.halotab-hero-date .sep{
  display: inline-block; width: 1px; height: 12px;
  background: currentColor; opacity: .35;
  margin: 0 10px; vertical-align: middle;
}
.halotab-hero-title{
  font-size: 30px; font-weight:700; margin: 0 0 6px;
  color: var(--ht-text);
  text-shadow: 0 2px 12px rgba(0,0,0,.25);
  letter-spacing:.5px;
}
.halotab-hero-slogan{ color: rgba(255,255,255,.8); margin:0 0 22px; font-size:15px; }

.halotab-search-wrap{ display: flex; justify-content: center; }

.halotab-search{
  display:flex; align-items:center;
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  background: rgba(255,255,255,.18);
  border:1px solid rgba(255,255,255,.28);
  border-radius: 999px; padding: 4px 4px 4px 6px;
  box-shadow: 0 4px 16px rgba(0,0,0,.18);
  transition:box-shadow .2s, transform .2s, background .2s;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.halotab-search:focus-within{
  background: rgba(255,255,255,.24);
  box-shadow: 0 6px 20px rgba(0,0,0,.25);
  transform: translateY(-1px);
}
/* 引擎下拉 */
.halotab-search-engine{
  border:none; background:transparent; color:#ffffff;
  font-size:13px; padding:8px 22px 8px 14px;
  outline:none; cursor:pointer;
  appearance:none; -webkit-appearance:none;
  border-right: 1px solid rgba(255,255,255,.25);
  border-radius: 999px 0 0 999px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff'><path d='M7 10l5 5 5-5z'/></svg>");
  background-repeat: no-repeat;
  background-position: right 6px center;
  background-size: 14px 14px;
  margin-right: 4px;
}
.halotab-search-engine option{ color:#1f2937; background:#ffffff; }
.halotab-search-engine:hover{ color:#fff; opacity:.85; }
.halotab-search-input{
  flex:1; border:none; outline:none; background:transparent;
  padding: 14px 14px; font-size: 15px; color: var(--ht-text);
}
.halotab-search-input::placeholder{ color: var(--ht-text-soft); }
.halotab-search-btn{
  width:42px;height:42px; border:none; border-radius:50%;
  background: var(--ht-grad);
  color:#fff; cursor:pointer; display:flex; align-items:center; justify-content:center;
  flex-shrink: 0;
  transition: transform .12s ease;
}
.halotab-search-btn:active{ transform: scale(.92); }

/* ----- 锚点条 ----- */
.halotab-anchors{
  display:flex; gap:8px; flex-wrap:wrap; justify-content:center;
  margin-top: 22px;
}
.halotab-anchor{
  padding: 5px 12px; border-radius: 999px;
  background: var(--ht-card-bg); border:1px solid var(--ht-card-border);
  color: var(--ht-text-soft); text-decoration:none; font-size:13px;
  transition: color .15s, border-color .15s, background .15s;
}
.halotab-anchor:hover{ color:var(--ht-text); border-color: var(--ht-accent); }

/* ----- 分组 ----- */
.halotab-group{ margin-top: 36px; scroll-margin-top: calc(var(--ht-header-h) + 12px); }
.halotab-group:first-child{ margin-top: 10px; }
.halotab-page .halotab-group{ margin-top: 0 !important; }
.halotab-group-head{
  display:flex; align-items:baseline; justify-content:space-between;
  margin: 0 4px 14px;
}
.halotab-group-title{
  font-size: 18px; margin:0; display:flex; align-items:center; gap:10px;
  font-weight:600;
}
.halotab-group-title small{ color: var(--ht-text-soft); font-weight:400; font-size:12px; }
.halotab-group-bar{
  width:4px; height:18px; border-radius:2px;
  background: linear-gradient(180deg, #3ba5ff 0%, #5d7bff 50%, #7c5cff 100%);
}
.halotab-group-emoji{ font-size:18px; line-height:1; }

/* ----- 卡片网格 -----
 *  设计原则：
 *  - 1×1 卡片：理想 80×110，实际由 JS 根据容器宽度动态计算
 *  - 列宽 / 行高由 JS 写入 --ht-cell-w / --ht-cell-h；W×H 通过跨格表达
 *  - 每行最多 12 列；实际列数 + cell 尺寸由 JS 根据容器宽度动态计算
 *  - 间距固定：column-gap = 24px、row-gap = 2px
 *  - 容器多余水平空间通过 justify-content:center 左右均分留白
 */
.halotab-grid{
  --ht-cols: 12;
  --ht-cell-w: 80px;
  --ht-cell-h: 110px;          /* 单元格高 = 图标 + 标题；1×1/2×1 直接吃这个 */
  --ht-cell-gap: 24px;         /* 水平间距（固定） */
  --ht-row-gap: 2px;           /* 垂直间距（固定） */
  display: grid;
  grid-template-columns: repeat(var(--ht-cols), var(--ht-cell-w));
  grid-auto-rows: var(--ht-cell-h);
  column-gap: var(--ht-cell-gap);
  row-gap: var(--ht-row-gap);
  justify-content: start;             /* 居中由 JS 设 margin-left（整数像素，避免亚像素偏移致字体模糊） */
  grid-auto-flow: dense;              /* 小卡填补大卡空洞 */
  contain: layout style;
}

/* 跨格规则：W x H（仅保留 1x1 / 2x1 / 1x2 / 2x2 / 4x2）。
 * 1x1 / 2x1：直接由 grid 行轨道（cell-h=110）撑高，图标块 = 卡宽（1x1 正方，2x1 横长）✅
 * 1x2：「我要更高的图标」语义 → grid 默认拉成 cell-h*2+row-gap，图标竖长 ✅
 * 2x2：希望「图标方区是正方形」，需特殊修正（见下）
 * 4x2：保持 grid 默认（横向 banner，图标横长，比如 calendar）✅ */
.halotab-card[data-size="1x1"]{ grid-column: span 1; grid-row: span 1; }
.halotab-card[data-size="2x1"]{ grid-column: span 2; grid-row: span 1; }
.halotab-card[data-size="1x2"]{ grid-column: span 1; grid-row: span 2; }
.halotab-card[data-size="2x2"]{ grid-column: span 2; grid-row: span 2; }
.halotab-card[data-size="4x2"]{ grid-column: span 4; grid-row: span 2; }

/* 「图标方区正方形」修正 —— 仅作用于 2×2：
 *   卡总宽 = 2*cell-w + cell-gap
 *   卡总高 = 卡总宽 + 30   ← 让 (高-30) = 宽，图标块为正方形
 * 用 align-self:start：保留 grid-row:span 2 的占位（防别的卡来抢下方格子），
 * 但卡片自身只渲染到 height 指定的高度，多出的空白仍属于这张卡的 grid 槽位。
 * 占位符同步处理，拖拽时高度一致不抖。
 *
 * 用 calc + grid 变量，gap 改变时自动跟随，不再写死 206px 这种\"假设 gap=16\"的魔法数。
 * 4x2 不做此修正，保持 grid 默认（横向 banner）。 */
.halotab-card[data-size="2x2"],
.halotab-card-placeholder[data-size="2x2"]{
  align-self: start;
  height: calc(var(--ht-cell-w) * 2 + var(--ht-cell-gap) + 30px);
}

/* 拖拽排序 —— 占位符跟着卡片大小一致，避免 grid 抖动 */
.halotab-card-placeholder[data-size="1x1"]{ grid-column: span 1; grid-row: span 1; }
.halotab-card-placeholder[data-size="2x1"]{ grid-column: span 2; grid-row: span 1; }
.halotab-card-placeholder[data-size="1x2"]{ grid-column: span 1; grid-row: span 2; }
.halotab-card-placeholder[data-size="2x2"]{ grid-column: span 2; grid-row: span 2; }
.halotab-card-placeholder[data-size="4x2"]{ grid-column: span 4; grid-row: span 2; }
.halotab-card-placeholder{
  border: 2px dashed rgba(255,255,255,.6);
  border-radius: var(--ht-radius);
  background: rgba(255,255,255,.08);
  box-sizing: border-box;
}
/* 拖拽中的卡片：保持原位占位，只做"虚化"提示，且不参与命中检测 —— 避免抖动 */
.halotab-card.dragging{
  opacity: .25;
  cursor: grabbing;
  pointer-events: none;
  /* 关键：不要再加 transform / filter / scale，避免触发额外重排造成闪烁 */
  /* drop 后此 class 被移除，opacity 从 .25 回到 1 —— 这就是"副本回归本体"的过渡，
   * 时长稍长让归位更柔和（与 FLIP .45s 同节奏） */
  transition: opacity .35s ease;
}
/* 注意：拖拽过程中其它卡片的位置过渡由 JS 用 FLIP 在 transform 上动态设置，
 * 这里不要给 .halotab-card 加 transition: transform，否则会与 FLIP 的瞬时 transform
 * 冲突，造成回弹/闪烁。 */
/* 管理员鼠标悬停时显示"可拖拽"光标 */
.halotab-card[draggable="true"]{ cursor: grab; }
.halotab-card[draggable="true"]:active{ cursor: grabbing; }

/* 卡片本体：上下结构 —— 图标占据「卡片高度 - 20」、标题占固定 20，宽度均 = 卡片宽 */
.halotab-card{
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: var(--ht-radius);
  text-decoration: none; color: var(--ht-text);
  overflow: hidden;
  text-align: center;
  container-type: inline-size;
  contain: layout style paint;
  transition: transform .12s ease;
}
/* 点击时给一个轻微缩小的反馈（非 widget 的网址卡片才整体缩；widget 卡片内部交互多，避免误触发） */
.halotab-card:not(.is-widget):active{ transform: scale(.96); }

/* 图标块：宽 = 卡片宽，高 = 卡片高 - 30（标题高度），跟着卡片尺寸自然变化
 * 背景：使用卡片自定义背景色 var(--card-bg)，由 JS 在外层 <a.halotab-card> 上注入；
 *      默认 #fff —— 与历史视觉保持一致。
 * 注意：外层 <a.halotab-card> 整体透明（见上），cardBg 仅作用于此 IconParent，
 *      标题区 .halotab-card-body 保持透明，跟卡片整体的"上图标 + 下标题"骨架契合。 */
.halotab-card-icon{
  flex: 1 1 auto;               /* 高度 = 卡片高 - 标题高(30) */
  width: 100%;
  min-height: 0;
  border-radius: var(--ht-radius);
  background: var(--card-bg, #fff);
  display:flex; align-items:center; justify-content:center;
  overflow:hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,.12);
}
/* 图片图标：在图标槽内固定 48×48 显示，与卡片 data-size 无关。
 * - object-fit: contain 保证不裁剪、不变形（小图标会被等比放大、大图标会被等比缩小到 48）。
 * - 圆角/白底/阴影由父 .halotab-card-icon 提供，图片自身保持透明，避免双层白底视觉重影。 */
.halotab-card-icon img{
  width: 48px;
  height: 48px;
  object-fit: contain;
  display: block;
  margin: auto;
  border-radius: 0;
  background: transparent;
}
/* 2x2 / 4x2 大尺寸卡片：图片图标放大到 64×64，与卡片视觉比例匹配 */
.halotab-card[data-size="2x2"] > .halotab-card-icon > img,
.halotab-card[data-size="4x2"] > .halotab-card-icon > img{
  width: 64px;
  height: 64px;
}

/* ---------- 图标充满（icon-fill）：用户在表单里勾选「图标充满」时启用 ----------
 * 视觉目标：让图片图标 cover 铺满整个 IconParent，做"全图卡"/海报式卡片。
 * 实现要点：
 *   - 父块去掉白底 / 阴影 / 内边距，避免出现"图片+白色边框"的双层观感；
 *   - <img> 改成 100% 撑满 + object-fit:cover，不论 1×1 / 2×1 / 1×2 / 2×2 都能正确铺满；
 *   - 圆角继承父块的 var(--ht-radius)，与卡片整体一致；
 *   - 优先级用属性选择器 + 类名叠加保证比上面的「48×48 / 64×64」规则更具体。
 * 注意：本类只对图片图标 (.halotab-card-icon.icon-fill) 生效；
 *       渲染时 has-img-bg 与 icon-fill 互斥（renderCard 已处理），所以不会与
 *       「沉浸式高斯模糊背景」(::before/::after) 冲突。
 */
.halotab-card-icon.icon-fill{
  background: transparent;
  box-shadow: none;
  padding: 0;
}
.halotab-card-icon.icon-fill > img,
.halotab-card[data-size="2x2"] > .halotab-card-icon.icon-fill > img,
.halotab-card[data-size="4x2"] > .halotab-card-icon.icon-fill > img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* 圆角统一交给父级 .halotab-card-icon（已 overflow:hidden）裁切，
     这里 <img> 不再自己写 border-radius，避免双层圆角叠加导致的锯齿 / 不圆润；
     同时给父级开启 GPU 合成，让裁切边缘的抗锯齿更平滑。 */
  border-radius: 0;
  margin: 0;
  display: block;
}
/* 图标充满时父级裁切优化：开启硬件合成 + 强制重排子层，
   消除某些浏览器（Chrome / WebKit）下 overflow:hidden + 圆角 在子元素是图片时
   会出现的灰色锯齿边。 */
.halotab-card-icon.icon-fill{
  /* 强制创建独立层，让 border-radius 的抗锯齿走 GPU 合成路径 */
  transform: translateZ(0);
  -webkit-mask-image: -webkit-radial-gradient(white, black); /* Safari 圆角裁切抗锯齿兜底 */
  isolation: isolate;
}

/* ---------- 图片图标的沉浸式背景（纯 CSS 滤镜近似法） ----------
 * 思路：用图标本身重复模糊后作为父图标块的背景，
 *      ::before 取图标"左上角"附近做高斯模糊形成主色区，
 *      ::after  取图标"右下角"附近做高斯模糊形成副色区，
 *      二者通过 background-blend-mode/位置错位融合成"主色→副色"渐变观感。
 * 由 JS 在 .halotab-card-icon 上注入 CSS 变量 --icon-img:url(...)，
 * 所以本规则只对带 .has-img-bg 的图标块生效；文字/widget 图标完全不受影响。
 */
.halotab-card-icon.has-img-bg{
  position: relative;
  background: var(--card-bg, #fff);  /* 兜底：变量未生效或 ::before/::after 加载前先用 cardBg，避免闪黑 */
  isolation: isolate;           /* 让 ::before/::after 的 mix-blend-mode 仅作用在本块内 */
}
.halotab-card-icon.has-img-bg::before,
.halotab-card-icon.has-img-bg::after{
  content: "";
  position: absolute;
  inset: -20%;                  /* 外扩 20%，让模糊溢出被父 overflow:hidden 裁掉，避免出现暗边 */
  background-image: var(--icon-img);
  background-repeat: no-repeat;
  background-size: 220% 220%;   /* 拉大 → 单色面积变大，模糊后只剩颜色，看不出原图形 */
  filter: blur(28px) saturate(1.6);
  pointer-events: none;
  z-index: 0;
}
/* 主色层：取图标左上角附近的颜色，铺满整块。
 * 缓慢漂移 + 极轻微缩放，让卡片颜色像水波一样持续流动；
 * 14s/18s 两个不同的周期让上下两层颜色错位变化，避免规律感。 */
.halotab-card-icon.has-img-bg::before{
  background-position: 0% 0%;
  opacity: .85;
  animation: halotab-card-bg-drift-a 14s ease-in-out infinite;
}
/* 副色层：取图标右下角附近的颜色，与主色层错位融合，形成渐变。
 * mix-blend-mode: screen 让两层亮色相加叠加，整体更"沉浸"鲜活、不发灰。 */
.halotab-card-icon.has-img-bg::after{
  background-position: 100% 100%;
  opacity: .75;
  mix-blend-mode: screen;
  animation: halotab-card-bg-drift-b 18s ease-in-out infinite;
}

/* 卡片背景缓慢"流动"动画：
 * 仅平移 + 极轻微缩放（≤4%），位移在 ±6% 内，幅度小到不会打扰阅读，
 * 但能让原本静止的纯色块看起来"活"起来。 */
@keyframes halotab-card-bg-drift-a{
  0%   { background-position:   0%   0%; transform: translate(0,    0)    scale(1);    }
  50%  { background-position:   6%   4%; transform: translate(-2%, -1.5%) scale(1.04); }
  100% { background-position:   0%   0%; transform: translate(0,    0)    scale(1);    }
}
@keyframes halotab-card-bg-drift-b{
  0%   { background-position: 100% 100%; transform: translate(0,    0)    scale(1);    }
  50%  { background-position:  94%  96%; transform: translate(2%,   1.5%) scale(1.03); }
  100% { background-position: 100% 100%; transform: translate(0,    0)    scale(1);    }
}

/* 用户开启"减少动画"系统偏好时，关闭背景流动动画，遵守可访问性。 */
@media (prefers-reduced-motion: reduce){
  .halotab-card-icon.has-img-bg::before,
  .halotab-card-icon.has-img-bg::after{
    animation: none;
  }
  .halotab-dot.flash{ animation: none; }
  .ht-ctxmenu.show{ animation: none; }
  .halotab-dot,
  .halotab-dot.ht-flip{ transition: none !important; }
}
/* 真正的图标 <img> 浮在两层模糊背景之上 */
.halotab-card-icon.has-img-bg > img{
  position: relative;
  z-index: 1;
}
/* 文字图标：背景色 + 大字。
 * 字号按 data-size 分三档：
 *   1×1 / 2×1 / 1×2  → 22px
 *   2×2              → 36px
 *   4×2              → 48px
 * 默认值给 22px（覆盖大多数小卡场景），下方再为大尺寸卡覆盖。 */
.halotab-card-icon.text-icon{
  background: var(--icon-bg, #5b8def);
  color: #ffffff;
  font-size: 22px;
  font-weight: 700;
  line-height: 1;
  user-select: none;
  -webkit-user-select: none;
}
.halotab-card[data-size="2x2"] > .halotab-card-icon.text-icon{
  font-size: 36px;
}
.halotab-card[data-size="4x2"] > .halotab-card-icon.text-icon{
  font-size: 48px;
}

/* 标题区：固定高度 30px、宽度 = 卡片宽，不重叠图标 */
.halotab-card-body{
  flex: 0 0 30px;
  height: 30px;
  width: 100%;
  display: flex; flex-direction: row; gap: 0;
  align-items: center; justify-content: center;
  padding: 0 4px;
  box-sizing: border-box;
  overflow: hidden;
}
.halotab-card-title{
  font-size: 12px; font-weight: 600;
  color: var(--ht-text);
  width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  line-height: 30px;            /* 与 body 等高，垂直居中 */
  text-align: center;
}
/* 描述：标题区只有 30px，描述默认隐藏（如需显示请改 data-size 大尺寸样式或扩高） */
.halotab-card-desc{
  display: none;
}

/* 大尺寸：标题字号略大；图标已按 「卡片高 - 20」 自然变大，无需额外尺寸规则 */
.halotab-card[data-size="2x2"] .halotab-card-title,
.halotab-card[data-size="4x2"] .halotab-card-title{
  font-size: 13px;
}

/* ----- 空状态 ----- */
.halotab-empty-wrap{
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.halotab-empty{
  text-align:center; padding: 60px 20px;
  background: var(--ht-card-bg); border:1px solid var(--ht-card-border);
  border-radius: var(--ht-radius); margin-top: 0;
  max-width: 520px;
}
.halotab-empty h3{margin:0 0 10px;}
.halotab-empty p{ color: var(--ht-text-soft); margin:6px 0; }
.halotab-btn-primary{
  display:inline-block; margin-top:14px; padding:10px 20px;
  background: var(--ht-grad);
  color:#fff; border-radius: 999px; text-decoration:none; font-weight:500;
  border:none; cursor:pointer; font-size:14px;
}

/* ----- 页脚（贴底，无独立背景） ----- */
.halotab-footer{
  flex-shrink:0;
  height: var(--ht-footer-h);
  display:flex; align-items:center; justify-content:center; gap: 12px;
  padding: 0 20px;
  color: rgba(255,255,255,.7);
  font-size:13px;
  background: transparent;
  border-top: none;
  text-shadow: 0 1px 4px rgba(0,0,0,.2);
}
.halotab-footer-anon-tip{
  color: #ef4444;
  font-size: 12px;
  white-space: nowrap;
}

/* ----- 响应式 ----- */
@media (max-width: 640px){
  .halotab-top{ width: 92%; padding: 20px 0 12px; }
  .halotab-hero-clock{ font-size:46px; }
  .halotab-hero-date{ font-size: 13px; margin-bottom: 12px; }
  .halotab-hero-title{ font-size:24px; }
  /* 移动端：列数 / 间距交给 JS 计算（基于容器宽度），这里仅微调字号 */
  .halotab-card{ padding: 0; }
  .halotab-card-title{ font-size: 11px; }
  .halotab-card-desc{ font-size: 10px; }

  .halotab-page{ padding: 8px 0 16px; }
  .halotab-page-inner{ width: 92%; }
  .halotab-dots{ display: none; }

  .halotab-fab{ right: 10px; bottom: calc(var(--ht-footer-h) + 8px); }
}

/* ============================================================
 *  右键菜单 / 弹窗 / Toast
 * ============================================================ */

.ht-ctxmenu{
  position: fixed; z-index: 9999; width: 150px;
  background-color: transparent;
  border: 0;
  border-radius: 10px;
  box-shadow: none;
  padding: 5px;
  display: none;
  font-size: 13px; color: #1f2937;
  /* 锚点固定到左上角；默认 transform 为 none，避免 .show 之后立即测 offsetWidth/Height
   * 时读到 0（边界回弹会失效）。动画 from 为 scale 0、to 为 scale 1，由 keyframes 接管。 */
  transform-origin: left top;
  pointer-events: none;
}
/* 磨砂卡片底（伪元素方式，避免改动 DOM）：铺满整个菜单容器，承担"看得见的卡片"职责
 *   - 背景使用 .72 半透明，搭配 backdrop-filter:blur(8px) 才能透出背后的磨砂质感；
 *     若取 .96 几乎不透，毛玻璃就形同虚设。 */
.ht-ctxmenu::before{
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  background: rgba(255,255,255,.72);
  border: 1px solid rgba(0,0,0,.08);
  box-shadow: 0 10px 30px rgba(0,0,0,.18);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  z-index: -1;
}
html[data-theme="dark"] .ht-ctxmenu,
html[data-theme="auto"] .ht-ctxmenu{
  color: #e5e7eb;
}
html[data-theme="dark"] .ht-ctxmenu::before,
html[data-theme="auto"] .ht-ctxmenu::before{
  background: rgba(28,30,38,.72);
  border-color: rgba(255,255,255,.08);
}
@keyframes ht-ctxmenu-fade-in{
  from { transform: scale3d(0, 0, 1); }
  to   { transform: scale3d(1, 1, 1); }
}
.ht-ctxmenu.show{
  display: block;
  animation: ht-ctxmenu-fade-in .18s forwards;
  pointer-events: auto;
}
.ht-ctxmenu-item{
  padding: 7px 12px; border-radius: 6px; cursor: pointer;
  white-space: nowrap;
  /* 与 ::before 同一 stacking context，显式置于伪元素之上，避免 z-index:-1 在某些浏览器下穿透 */
  position: relative; z-index: 1;
}
.ht-ctxmenu-item:hover{
  background: var(--ht-grad);
  color: #fff;
}
.ht-ctxmenu-item.danger{ color: #ef4444; }
.ht-ctxmenu-item.danger:hover{
  background: #ef4444; color: #fff;
}

/* 子菜单 —— 与主菜单视觉对齐：半透明背景 + backdrop-filter 磨砂 */
.ht-ctxmenu-has-sub{ position: relative; }
.ht-ctxmenu-sub{
  display: none;
  position: absolute; left: 100%; top: -6px;
  min-width: 140px;
  /* 半透明卡片底色，叠加 backdrop-filter 后才能看到背后内容的磨砂 */
  background: rgba(255,255,255,.72);
  border: 1px solid rgba(0,0,0,.08);
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,.18);
  padding: 6px;
  font-size: 13px; color: #1f2937;
  /* 与主菜单 ::before 同一档（8px）；-webkit- 前缀兼容 Safari */
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
html[data-theme="dark"] .ht-ctxmenu-sub,
html[data-theme="auto"] .ht-ctxmenu-sub{
  background: rgba(28,30,38,.72);
  border-color: rgba(255,255,255,.08);
  color: #e5e7eb;
}
.ht-ctxmenu-sub.show{ display: block; }
.ht-ctxmenu-sub .ht-ctxmenu-item{ padding: 7px 12px; border-radius: 6px; cursor: pointer; white-space: nowrap; }
.ht-ctxmenu-sub .ht-ctxmenu-item:hover{
  background: var(--ht-grad);
  color: #fff;
}

/* ---------- Element UI 风格图标系统 ----------
 * 用法：<i class="ht-i ht-i-{name}"></i>
 * 着色跟随 currentColor，因此放进 .danger / hover 反白都能自适应。
 * SVG 内联为 mask 数据，零外部依赖。
 */
.ht-i{
  display: inline-block;
  width: 1em; height: 1em;
  vertical-align: -0.15em;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  flex-shrink: 0;
}
/* 编辑（铅笔，类 el-icon-edit-outline） */
.ht-i-edit{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M5 19h1.4l8.625-8.625-1.4-1.4L5 17.6V19zM3 21v-4.25L16.2 3.575c.2-.183.42-.325.663-.425.241-.1.495-.15.762-.15s.525.05.775.15c.25.1.467.25.65.45L20.425 4.8c.2.183.345.4.438.65a2.16 2.16 0 0 1 0 1.512 1.755 1.755 0 0 1-.438.663L7.25 21H3zm14.575-13.6 1.4-1.4-1.4-1.4-1.4 1.4 1.4 1.4z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M5 19h1.4l8.625-8.625-1.4-1.4L5 17.6V19zM3 21v-4.25L16.2 3.575c.2-.183.42-.325.663-.425.241-.1.495-.15.762-.15s.525.05.775.15c.25.1.467.25.65.45L20.425 4.8c.2.183.345.4.438.65a2.16 2.16 0 0 1 0 1.512 1.755 1.755 0 0 1-.438.663L7.25 21H3zm14.575-13.6 1.4-1.4-1.4-1.4-1.4 1.4 1.4 1.4z'/></svg>");
}
/* 删除（垃圾桶，类 el-icon-delete） */
.ht-i-delete{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M7 21q-.825 0-1.412-.587Q5 19.825 5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413Q17.825 21 17 21H7zM17 6H7v13h10V6zM9 17h2V8H9v9zm4 0h2V8h-2v9z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M7 21q-.825 0-1.412-.587Q5 19.825 5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413Q17.825 21 17 21H7zM17 6H7v13h10V6zM9 17h2V8H9v9zm4 0h2V8h-2v9z'/></svg>");
}
/* 加号（el-icon-plus） */
.ht-i-plus{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M11 13H5v-2h6V5h2v6h6v2h-6v6h-2v-6z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M11 13H5v-2h6V5h2v6h6v2h-6v6h-2v-6z'/></svg>");
}
/* 调色板 / 主题（el-icon-magic-stick 近似） */
.ht-i-brush{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M5 21q-.825 0-1.412-.587Q3 19.825 3 19V6.85q0-.4.15-.762.15-.363.45-.638l3.6-3.3q.275-.275.65-.413A2.4 2.4 0 0 1 8.7 1.6q.45 0 .85.15.4.15.7.4l3.6 3.3q.3.275.45.638.15.362.15.762V19q0 .825-.587 1.413Q12.275 21 11.45 21H5zm12.5-1q-1.875 0-3.187-1.312Q13 17.375 13 15.5q0-1.65 1.025-3.275Q15.05 10.6 17.5 9q2.45 1.6 3.475 3.225Q22 13.85 22 15.5q0 1.875-1.312 3.188Q19.375 20 17.5 20zM5 19h6.45V8h-6.4v11h-.05zm3.225-2q.5 0 .862-.363.363-.362.363-.862t-.363-.863a1.18 1.18 0 0 0-.862-.362q-.5 0-.863.362-.362.363-.362.863t.362.862q.363.363.863.363zM5.05 8h6.4l-3.2-3-3.2 3z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M5 21q-.825 0-1.412-.587Q3 19.825 3 19V6.85q0-.4.15-.762.15-.363.45-.638l3.6-3.3q.275-.275.65-.413A2.4 2.4 0 0 1 8.7 1.6q.45 0 .85.15.4.15.7.4l3.6 3.3q.3.275.45.638.15.362.15.762V19q0 .825-.587 1.413Q12.275 21 11.45 21H5zm12.5-1q-1.875 0-3.187-1.312Q13 17.375 13 15.5q0-1.65 1.025-3.275Q15.05 10.6 17.5 9q2.45 1.6 3.475 3.225Q22 13.85 22 15.5q0 1.875-1.312 3.188Q19.375 20 17.5 20zM5 19h6.45V8h-6.4v11h-.05zm3.225-2q.5 0 .862-.363.363-.362.363-.862t-.363-.863a1.18 1.18 0 0 0-.862-.362q-.5 0-.863.362-.362.363-.362.863t.362.862q.363.363.863.363zM5.05 8h6.4l-3.2-3-3.2 3z'/></svg>");
}
/* 设置（齿轮，el-icon-setting） */
.ht-i-setting{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m9.25 22-.4-3.2a5.39 5.39 0 0 1-.862-.412 9.43 9.43 0 0 1-.788-.538L4.2 19.1l-2.75-4.8 2.575-1.95a3.97 3.97 0 0 1-.063-.575v-1.55q0-.275.063-.575L1.45 7.7 4.2 2.9l3 1.25q.375-.275.787-.512.413-.238.863-.413l.4-3.225h5.5l.4 3.2q.45.175.875.413.425.237.775.512l3-1.25 2.75 4.8-2.575 1.95q.05.3.063.587v1.55q0 .275-.075.575l2.575 1.95-2.75 4.8-3-1.25q-.375.275-.788.525a5.397 5.397 0 0 1-.862.4L14.75 22h-5.5zM12 15q1.25 0 2.125-.875T15 12q0-1.25-.875-2.125T12 9q-1.25 0-2.125.875T9 12q0 1.25.875 2.125T12 15z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m9.25 22-.4-3.2a5.39 5.39 0 0 1-.862-.412 9.43 9.43 0 0 1-.788-.538L4.2 19.1l-2.75-4.8 2.575-1.95a3.97 3.97 0 0 1-.063-.575v-1.55q0-.275.063-.575L1.45 7.7 4.2 2.9l3 1.25q.375-.275.787-.512.413-.238.863-.413l.4-3.225h5.5l.4 3.2q.45.175.875.413.425.237.775.512l3-1.25 2.75 4.8-2.575 1.95q.05.3.063.587v1.55q0 .275-.075.575l2.575 1.95-2.75 4.8-3-1.25q-.375.275-.788.525a5.397 5.397 0 0 1-.862.4L14.75 22h-5.5zM12 15q1.25 0 2.125-.875T15 12q0-1.25-.875-2.125T12 9q-1.25 0-2.125.875T9 12q0 1.25.875 2.125T12 15z'/></svg>");
}
/* 复制（el-icon-document-copy） */
.ht-i-copy{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M9 18q-.825 0-1.412-.587Q7 16.825 7 16V4q0-.825.588-1.413A1.93 1.93 0 0 1 9 2h9q.825 0 1.413.587Q20 3.175 20 4v12q0 .825-.587 1.413A1.93 1.93 0 0 1 18 18H9zm0-2h9V4H9v12zm-4 6q-.825 0-1.412-.587A1.93 1.93 0 0 1 3 20V7h2v13h10v2H5z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M9 18q-.825 0-1.412-.587Q7 16.825 7 16V4q0-.825.588-1.413A1.93 1.93 0 0 1 9 2h9q.825 0 1.413.587Q20 3.175 20 4v12q0 .825-.825 1.413A1.93 1.93 0 0 1 18 18H9zm0-2h9V4H9v12zm-4 6q-.825 0-1.412-.587A1.93 1.93 0 0 1 3 20V7h2v13h10v2H5z'/></svg>");
}
/* 在新标签打开（el-icon-top-right） */
.ht-i-newtab{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M5 21q-.825 0-1.412-.587Q3 19.825 3 19V5q0-.825.588-1.413A1.93 1.93 0 0 1 5 3h7v2H5v14h14v-7h2v7q0 .825-.587 1.413Q19.825 21 19 21H5zm4.7-5.3-1.4-1.4L17.6 5H14V3h7v7h-2V6.4l-9.3 9.3z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M5 21q-.825 0-1.412-.587Q3 19.825 3 19V5q0-.825.588-1.413A1.93 1.93 0 0 1 5 3h7v2H5v14h14v-7h2v7q0 .825-.587 1.413Q19.825 21 19 21H5zm4.7-5.3-1.4-1.4L17.6 5H14V3h7v7h-2V6.4l-9.3 9.3z'/></svg>");
}
/* 内置弹窗（el-icon-monitor 近似 → 浏览器窗口） */
.ht-i-window{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 20q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V6q0-.825.588-1.413A1.93 1.93 0 0 1 4 4h16q.825 0 1.413.587Q22 5.175 22 6v12q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20H4zm0-12h16V6H4v2zm0 2v8h16v-8H4z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 20q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V6q0-.825.588-1.413A1.93 1.93 0 0 1 4 4h16q.825 0 1.413.587Q22 5.175 22 6v12q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20H4zm0-12h16V6H4v2zm0 2v8h16v-8H4z'/></svg>");
}
/* 布局（4 格） */
.ht-i-layout{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M3 11V3h8v8H3zm0 10v-8h8v8H3zm10-10V3h8v8h-8zm0 10v-8h8v8h-8zM5 9h4V5H5v4zm10 0h4V5h-4v4zm0 10h4v-4h-4v4zm-10 0h4v-4H5v4z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M3 11V3h8v8H3zm0 10v-8h8v8H3zm10-10V3h8v8h-8zm0 10v-8h8v8h-8zM5 9h4V5H5v4zm10 0h4V5h-4v4zm0 10h4v-4h-4v4zm-10 0h4v-4H5v4z'/></svg>");
}
/* 移动至分组（drive_file_move：文件夹 + 右箭头） */
.ht-i-move{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 20q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V6q0-.825.588-1.413A1.93 1.93 0 0 1 4 4h6l2 2h8q.825 0 1.413.588Q22 7.175 22 8v10q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20H4zm0-2h16V8h-8.825l-2-2H4v12zm9-2 4-4-4-4v3H8v2h5v3z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 20q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V6q0-.825.588-1.413A1.93 1.93 0 0 1 4 4h6l2 2h8q.825 0 1.413.588Q22 7.175 22 8v10q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20H4zm0-2h16V8h-8.825l-2-2H4v12zm9-2 4-4-4-4v3H8v2h5v3z'/></svg>");
}
/* 右箭头（子菜单展开符，替代 ▸） */
.ht-i-arrow-right{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M9.7 18.3 8.3 16.9l4.9-4.9-4.9-4.9 1.4-1.4 6.3 6.3-6.3 6.3z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M9.7 18.3 8.3 16.9l4.9-4.9-4.9-4.9 1.4-1.4 6.3 6.3-6.3 6.3z'/></svg>");
}
/* 选中标记（实心对勾） */
.ht-i-check{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m9.55 17.575-4.7-4.7 1.425-1.425 3.275 3.275 7.85-7.85 1.425 1.425-9.275 9.275z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m9.55 17.575-4.7-4.7 1.425-1.425 3.275 3.275 7.85-7.85 1.425 1.425-9.275 9.275z'/></svg>");
}
/* 警告（弹窗 / iframe 加载失败提示） */
.ht-i-warning{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M1 21 12 2l11 19H1zm3.45-2h15.1L12 6l-7.55 13zm7.55-1q.425 0 .713-.288A.97.97 0 0 0 12.7 17q0-.425-.287-.712A.97.97 0 0 0 12 16q-.425 0-.713.288A.97.97 0 0 0 11 17q0 .425.287.712.288.288.713.288zm-1-3h2v-5h-2v5z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M1 21 12 2l11 19H1zm3.45-2h15.1L12 6l-7.55 13zm7.55-1q.425 0 .713-.288A.97.97 0 0 0 12.7 17q0-.425-.287-.712A.97.97 0 0 0 12 16q-.425 0-.713.288A.97.97 0 0 0 11 17q0 .425.287.712.288.288.713.288zm-1-3h2v-5h-2v5z'/></svg>");
}

/* ============================================================
 *  分组语义图标库 .ht-i-g-*
 *  - 用于右侧分组指示器（halotab-dot）+ 分组弹窗预设网格
 *  - 全部 24x24，currentColor 自适应（白底/暗底/选中态自动反白）
 *  - 风格：Material Symbols Outlined 同源，线条简洁、无彩色
 *  - 命名沿用业务语义，新增图标直接追加即可
 * ============================================================ */
.ht-i-g-home{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M6 19h3v-6h6v6h3v-9l-6-4.5L6 10v9zm-2 2V9l8-6 8 6v12h-7v-6h-2v6H4z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M6 19h3v-6h6v6h3v-9l-6-4.5L6 10v9zm-2 2V9l8-6 8 6v12h-7v-6h-2v6H4z'/></svg>");
}
.ht-i-g-game{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M7.5 18q-2.275 0-3.887-1.612Q2 14.775 2 12.5q0-2.275 1.613-3.887Q5.225 7 7.5 7h9q2.275 0 3.888 1.613Q22 10.225 22 12.5q0 2.275-1.612 3.888Q18.775 18 16.5 18q-1.075 0-2.05-.4t-1.7-1.15L12 15.7l-.75.75q-.725.75-1.7 1.15-.975.4-2.05.4zm0-2q.7 0 1.288-.262.587-.263 1.062-.738L11.6 13.25q.075-.075.288-.175Q12.1 13 12 13t-.288.075q-.212.1-.287.175l-1.75 1.75q-.475.475-1.062.738Q8.2 16 7.5 16q-1.45 0-2.475-1.025Q4 13.95 4 12.5q0-1.45 1.025-2.475Q6.05 9 7.5 9h9q1.45 0 2.475 1.025Q20 11.05 20 12.5q0 1.45-1.025 2.475Q17.95 16 16.5 16q-.7 0-1.288-.262-.587-.263-1.062-.738L12.4 13.25q-.075-.075-.288-.175Q11.9 13 12 13t.288.075q.212.1.287.175l1.75 1.75q.475.475 1.062.738.588.262 1.288.262zM8 13H6v-2h2V9h2v2h2v2h-2v2H8v-2zm8 1q.425 0 .713-.288.287-.287.287-.712 0-.425-.287-.713A.97.97 0 0 0 16 12q-.425 0-.712.287A.97.97 0 0 0 15 13q0 .425.288.712.287.288.712.288zm2-3q.425 0 .713-.288A.97.97 0 0 0 19 10q0-.425-.287-.713A.97.97 0 0 0 18 9q-.425 0-.712.287A.97.97 0 0 0 17 10q0 .425.288.712.287.288.712.288z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M7.5 18q-2.275 0-3.887-1.612Q2 14.775 2 12.5q0-2.275 1.613-3.887Q5.225 7 7.5 7h9q2.275 0 3.888 1.613Q22 10.225 22 12.5q0 2.275-1.612 3.888Q18.775 18 16.5 18q-1.075 0-2.05-.4t-1.7-1.15L12 15.7l-.75.75q-.725.75-1.7 1.15-.975.4-2.05.4zm0-2q.7 0 1.288-.262.587-.263 1.062-.738L11.6 13.25q.075-.075.288-.175Q12.1 13 12 13t-.288.075q-.212.1-.287.175l-1.75 1.75q-.475.475-1.062.738Q8.2 16 7.5 16q-1.45 0-2.475-1.025Q4 13.95 4 12.5q0-1.45 1.025-2.475Q6.05 9 7.5 9h9q1.45 0 2.475 1.025Q20 11.05 20 12.5q0 1.45-1.025 2.475Q17.95 16 16.5 16q-.7 0-1.288-.262-.587-.263-1.062-.738L12.4 13.25q-.075-.075-.288-.175Q11.9 13 12 13t.288.075q.212.1.287.175l1.75 1.75q.475.475 1.062.738.588.262 1.288.262zM8 13H6v-2h2V9h2v2h2v2h-2v2H8v-2zm8 1q.425 0 .713-.288.287-.287.287-.712 0-.425-.287-.713A.97.97 0 0 0 16 12q-.425 0-.712.287A.97.97 0 0 0 15 13q0 .425.288.712.287.288.712.288zm2-3q.425 0 .713-.288A.97.97 0 0 0 19 10q0-.425-.287-.713A.97.97 0 0 0 18 9q-.425 0-.712.287A.97.97 0 0 0 17 10q0 .425.288.712.287.288.712.288z'/></svg>");
}
.ht-i-g-music{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M9 21q-1.65 0-2.825-1.175Q5 18.65 5 17q0-1.65 1.175-2.825Q7.35 13 9 13q.575 0 1.063.137.487.138.937.413V3h8v4h-6v10q0 1.65-1.175 2.825Q10.65 21 9 21z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M9 21q-1.65 0-2.825-1.175Q5 18.65 5 17q0-1.65 1.175-2.825Q7.35 13 9 13q.575 0 1.063.137.487.138.937.413V3h8v4h-6v10q0 1.65-1.175 2.825Q10.65 21 9 21z'/></svg>");
}
.ht-i-g-work{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 20q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V8q0-.825.588-1.412A1.93 1.93 0 0 1 4 6h4V4q0-.825.588-1.413A1.93 1.93 0 0 1 10 2h4q.825 0 1.413.587Q16 3.175 16 4v2h4q.825 0 1.413.588Q22 7.175 22 8v10q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20H4zm0-2h16V8H4v10zm6-12h4V4h-4v2zM4 18V8v10z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 20q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V8q0-.825.588-1.412A1.93 1.93 0 0 1 4 6h4V4q0-.825.588-1.413A1.93 1.93 0 0 1 10 2h4q.825 0 1.413.587Q16 3.175 16 4v2h4q.825 0 1.413.588Q22 7.175 22 8v10q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20H4zm0-2h16V8H4v10zm6-12h4V4h-4v2zM4 18V8v10z'/></svg>");
}
.ht-i-g-chat{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M6 14h8v-2H6v2zm0-3h12V9H6v2zm0-3h12V6H6v2zM2 22V4q0-.825.588-1.413A1.93 1.93 0 0 1 4 2h16q.825 0 1.413.587Q22 3.175 22 4v12q0 .825-.587 1.413A1.93 1.93 0 0 1 20 18H6l-4 4zm3.15-6H20V4H4v13.125L5.15 16zM4 16V4v12z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M6 14h8v-2H6v2zm0-3h12V9H6v2zm0-3h12V6H6v2zM2 22V4q0-.825.588-1.413A1.93 1.93 0 0 1 4 2h16q.825 0 1.413.587Q22 3.175 22 4v12q0 .825-.587 1.413A1.93 1.93 0 0 1 20 18H6l-4 4zm3.15-6H20V4H4v13.125L5.15 16zM4 16V4v12z'/></svg>");
}
.ht-i-g-shop{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M7 22q-.825 0-1.412-.587A1.93 1.93 0 0 1 5 20q0-.825.588-1.413A1.93 1.93 0 0 1 7 18q.825 0 1.413.587Q9 19.175 9 20q0 .825-.587 1.413A1.93 1.93 0 0 1 7 22zm10 0q-.825 0-1.412-.587A1.93 1.93 0 0 1 15 20q0-.825.588-1.413A1.93 1.93 0 0 1 17 18q.825 0 1.413.587Q19 19.175 19 20q0 .825-.587 1.413A1.93 1.93 0 0 1 17 22zM5.2 6l2.4 5h8.85l2.75-5H5.2zM4.15 4H21.5q.575 0 .875.5t.025 1.025l-3.55 6.4q-.275.5-.737.788Q17.65 13 17.1 13H7.1l-1.1 2h13v2H6q-1.125 0-1.7-.987-.575-.988-.05-1.963L5.6 11.6 2 4h2.15z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M7 22q-.825 0-1.412-.587A1.93 1.93 0 0 1 5 20q0-.825.588-1.413A1.93 1.93 0 0 1 7 18q.825 0 1.413.587Q9 19.175 9 20q0 .825-.587 1.413A1.93 1.93 0 0 1 7 22zm10 0q-.825 0-1.412-.587A1.93 1.93 0 0 1 15 20q0-.825.588-1.413A1.93 1.93 0 0 1 17 18q.825 0 1.413.587Q19 19.175 19 20q0 .825-.587 1.413A1.93 1.93 0 0 1 17 22zM5.2 6l2.4 5h8.85l2.75-5H5.2zM4.15 4H21.5q.575 0 .875.5t.025 1.025l-3.55 6.4q-.275.5-.737.788Q17.65 13 17.1 13H7.1l-1.1 2h13v2H6q-1.125 0-1.7-.987-.575-.988-.05-1.963L5.6 11.6 2 4h2.15z'/></svg>");
}
.ht-i-g-travel{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m21 16-7-4.5V6.5q0-.625-.437-1.062A1.45 1.45 0 0 0 12.5 5q-.625 0-1.062.438A1.45 1.45 0 0 0 11 6.5v5L4 16v2l7-2.5V20l-2 1v1l3.5-1 3.5 1v-1l-2-1v-4.5L21 18v-2z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m21 16-7-4.5V6.5q0-.625-.437-1.062A1.45 1.45 0 0 0 12.5 5q-.625 0-1.062.438A1.45 1.45 0 0 0 11 6.5v5L4 16v2l7-2.5V20l-2 1v1l3.5-1 3.5 1v-1l-2-1v-4.5L21 18v-2z'/></svg>");
}
.ht-i-g-web{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 22q-2.05 0-3.875-.788-1.825-.787-3.187-2.15-1.363-1.362-2.15-3.187Q2 14.05 2 12t.788-3.875q.787-1.825 2.15-3.188 1.362-1.362 3.187-2.15Q9.95 2 12 2t3.875.787q1.825.788 3.188 2.15 1.362 1.363 2.15 3.188Q22 9.95 22 12t-.787 3.875q-.788 1.825-2.15 3.187-1.363 1.363-3.188 2.15Q14.05 22 12 22zm0-2.05q.65-.9 1.125-1.875T13.9 16h-3.8q.3 1.1.775 2.075.475.975 1.125 1.875zm-2.6-.4q-.45-.825-.788-1.713A12.4 12.4 0 0 1 8.05 16H5.1q.725 1.25 1.813 2.175Q8 19.1 9.4 19.55zm5.2 0q1.4-.45 2.488-1.375Q18.175 17.25 18.9 16h-2.95q-.225.975-.562 1.863-.338.887-.788 1.712zM4.25 14h3.4q-.075-.5-.112-.987Q7.5 12.525 7.5 12t.038-1.013q.037-.487.112-.987h-3.4q-.125.5-.187.987Q4 11.475 4 12t.063 1.013q.062.487.187.987zm5.4 0h4.7q.075-.5.113-.987Q14.5 12.525 14.5 12t-.037-1.013a9.5 9.5 0 0 0-.113-.987h-4.7a9.5 9.5 0 0 0-.113.987Q9.5 11.475 9.5 12t.038 1.013q.037.487.112.987zm6.7 0h3.4q.125-.5.188-.987Q20 12.525 20 12t-.062-1.013a8.9 8.9 0 0 0-.188-.987h-3.4q.075.5.113.987.037.488.037 1.013t-.037 1.013a9.5 9.5 0 0 1-.113.987zm-.4-6h2.95q-.725-1.25-1.812-2.175Q16 4.9 14.6 4.45q.45.825.788 1.713.337.887.562 1.837zm-5.85 0h3.8q-.3-1.1-.775-2.075A8.6 8.6 0 0 0 12 4.05a8.55 8.55 0 0 0-1.125 1.875Q10.4 6.9 10.1 8zm-5 0h2.95q.225-.95.562-1.837.338-.888.788-1.713-1.4.45-2.488 1.375Q5.825 6.75 5.1 8z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 22q-2.05 0-3.875-.788-1.825-.787-3.187-2.15-1.363-1.362-2.15-3.187Q2 14.05 2 12t.788-3.875q.787-1.825 2.15-3.188 1.362-1.362 3.187-2.15Q9.95 2 12 2t3.875.787q1.825.788 3.188 2.15 1.362 1.363 2.15 3.188Q22 9.95 22 12t-.787 3.875q-.788 1.825-2.15 3.187-1.363 1.363-3.188 2.15Q14.05 22 12 22zm0-2.05q.65-.9 1.125-1.875T13.9 16h-3.8q.3 1.1.775 2.075.475.975 1.125 1.875zm-2.6-.4q-.45-.825-.788-1.713A12.4 12.4 0 0 1 8.05 16H5.1q.725 1.25 1.813 2.175Q8 19.1 9.4 19.55zm5.2 0q1.4-.45 2.488-1.375Q18.175 17.25 18.9 16h-2.95q-.225.975-.562 1.863-.338.887-.788 1.712zM4.25 14h3.4q-.075-.5-.112-.987Q7.5 12.525 7.5 12t.038-1.013q.037-.487.112-.987h-3.4q-.125.5-.187.987Q4 11.475 4 12t.063 1.013q.062.487.187.987zm5.4 0h4.7q.075-.5.113-.987Q14.5 12.525 14.5 12t-.037-1.013a9.5 9.5 0 0 0-.113-.987h-4.7a9.5 9.5 0 0 0-.113.987Q9.5 11.475 9.5 12t.038 1.013q.037.487.112.987zm6.7 0h3.4q.125-.5.188-.987Q20 12.525 20 12t-.062-1.013a8.9 8.9 0 0 0-.188-.987h-3.4q.075.5.113.987.037.488.037 1.013t-.037 1.013a9.5 9.5 0 0 1-.113.987zm-.4-6h2.95q-.725-1.25-1.812-2.175Q16 4.9 14.6 4.45q.45.825.788 1.713.337.887.562 1.837zm-5.85 0h3.8q-.3-1.1-.775-2.075A8.6 8.6 0 0 0 12 4.05a8.55 8.55 0 0 0-1.125 1.875Q10.4 6.9 10.1 8zm-5 0h2.95q.225-.95.562-1.837.338-.888.788-1.713-1.4.45-2.488 1.375Q5.825 6.75 5.1 8z'/></svg>");
}
.ht-i-g-book{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 21q-1.5-1.05-3.35-1.525Q6.8 19 5 19q-.75 0-1.375.05a8.7 8.7 0 0 0-1.225.2q-.475.075-.937-.225Q1 18.725 1 18.175V5.85q0-.35.187-.625.188-.275.513-.4Q3.05 4.4 4.5 4.2 5.95 4 7.5 4q1.95 0 3.825.512Q13.2 5.025 15 6v13.5q1.55-1 3.408-1.5Q20.225 17.5 22 17.5q.6 0 1.013.05.412.05.987.15.325.075.513.35Q24.5 18.275 24.5 18.625v.55q0 .55-.45.85-.45.3-.95.225-.55-.075-1.05-.125Q21.55 20 21 20q-1.8 0-3.65.475T14 22V21zM15 18V8q-1.5-.95-3.225-1.475Q10.05 6 8.25 6 6.45 6 5.225 6.225 4 6.45 3 6.85v11.625q1.275-.35 2.5-.475T8 18q1.55 0 3.025.262Q12.5 18.525 15 19V18zM7 12.5q.55 0 1.05.05.5.05 1 .175v-2.05q-.5-.1-1-.137A12.5 12.5 0 0 0 7 10.5q-1 0-1.95.1A14 14 0 0 0 3 11v2q.575-.225 1.475-.363Q5.375 12.5 7 12.5zm0 4.5q.55 0 1.05.05.5.05 1 .15v-2.1Q8.55 15 8.05 15a13 13 0 0 0-2 .05A14 14 0 0 0 3 15.5v2.1q.575-.275 1.475-.413Q5.375 17 7 17z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 21q-1.5-1.05-3.35-1.525Q6.8 19 5 19q-.75 0-1.375.05a8.7 8.7 0 0 0-1.225.2q-.475.075-.937-.225Q1 18.725 1 18.175V5.85q0-.35.187-.625.188-.275.513-.4Q3.05 4.4 4.5 4.2 5.95 4 7.5 4q1.95 0 3.825.512Q13.2 5.025 15 6v13.5q1.55-1 3.408-1.5Q20.225 17.5 22 17.5q.6 0 1.013.05.412.05.987.15.325.075.513.35Q24.5 18.275 24.5 18.625v.55q0 .55-.45.85-.45.3-.95.225-.55-.075-1.05-.125Q21.55 20 21 20q-1.8 0-3.65.475T14 22V21zM15 18V8q-1.5-.95-3.225-1.475Q10.05 6 8.25 6 6.45 6 5.225 6.225 4 6.45 3 6.85v11.625q1.275-.35 2.5-.475T8 18q1.55 0 3.025.262Q12.5 18.525 15 19V18zM7 12.5q.55 0 1.05.05.5.05 1 .175v-2.05q-.5-.1-1-.137A12.5 12.5 0 0 0 7 10.5q-1 0-1.95.1A14 14 0 0 0 3 11v2q.575-.225 1.475-.363Q5.375 12.5 7 12.5zm0 4.5q.55 0 1.05.05.5.05 1 .15v-2.1Q8.55 15 8.05 15a13 13 0 0 0-2 .05A14 14 0 0 0 3 15.5v2.1q.575-.275 1.475-.413Q5.375 17 7 17z'/></svg>");
}
.ht-i-g-star{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m8.85 17.825 3.15-1.9 3.15 1.925-.825-3.6 2.775-2.4-3.65-.325L12 8.2l-1.425 3.3-3.65.325 2.775 2.425-.85 3.575zM5.825 22l1.625-7.025L2 10.25l7.2-.625L12 3l2.8 6.625 7.2.625-5.45 4.725L18.175 22 12 18.275 5.825 22z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m8.85 17.825 3.15-1.9 3.15 1.925-.825-3.6 2.775-2.4-3.65-.325L12 8.2l-1.425 3.3-3.65.325 2.775 2.425-.85 3.575zM5.825 22l1.625-7.025L2 10.25l7.2-.625L12 3l2.8 6.625 7.2.625-5.45 4.725L18.175 22 12 18.275 5.825 22z'/></svg>");
}
.ht-i-g-lock{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M6 22q-.825 0-1.412-.587A1.93 1.93 0 0 1 4 20V10q0-.825.588-1.412A1.93 1.93 0 0 1 6 8h1V6q0-2.075 1.463-3.537Q9.925 1 12 1t3.538 1.463Q17 3.925 17 6v2h1q.825 0 1.413.588Q20 9.175 20 10v10q0 .825-.587 1.413A1.93 1.93 0 0 1 18 22H6zm0-2h12V10H6v10zm6-3q.825 0 1.413-.587Q14 15.825 14 15t-.587-1.412A1.93 1.93 0 0 0 12 13q-.825 0-1.412.588A1.93 1.93 0 0 0 10 15q0 .825.588 1.413Q11.175 17 12 17zM9 8h6V6q0-1.25-.875-2.125T12 3q-1.25 0-2.125.875T9 6v2zM6 20V10v10z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M6 22q-.825 0-1.412-.587A1.93 1.93 0 0 1 4 20V10q0-.825.588-1.412A1.93 1.93 0 0 1 6 8h1V6q0-2.075 1.463-3.537Q9.925 1 12 1t3.538 1.463Q17 3.925 17 6v2h1q.825 0 1.413.588Q20 9.175 20 10v10q0 .825-.587 1.413A1.93 1.93 0 0 1 18 22H6zm0-2h12V10H6v10zm6-3q.825 0 1.413-.587Q14 15.825 14 15t-.587-1.412A1.93 1.93 0 0 0 12 13q-.825 0-1.412.588A1.93 1.93 0 0 0 10 15q0 .825.588 1.413Q11.175 17 12 17zM9 8h6V6q0-1.25-.875-2.125T12 3q-1.25 0-2.125.875T9 6v2zM6 20V10v10z'/></svg>");
}
.ht-i-g-crown{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M5 20h14v2H5v-2zm0-2 1.5-9 4.5 4 3-6 3 6 4.5-4L21 18H5zm2.4-2h9.2l.55-3.5-2.7 2.45-2.45-4.9-2.45 4.9-2.7-2.45L7.4 16zM12 16z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M5 20h14v2H5v-2zm0-2 1.5-9 4.5 4 3-6 3 6 4.5-4L21 18H5zm2.4-2h9.2l.55-3.5-2.7 2.45-2.45-4.9-2.45 4.9-2.7-2.45L7.4 16zM12 16z'/></svg>");
}
.ht-i-g-gift{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 22q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 20v-6h2v6h7v-8H3V8q0-.825.588-1.413A1.93 1.93 0 0 1 5 6h2.2a3 3 0 0 1-.15-.5A2.4 2.4 0 0 1 7 5q0-1.25.875-2.125T10 2q.65 0 1.213.275.562.275.987.775l.8 1.05.8-1.05q.45-.525 1-.788Q15.35 2 16 2q1.25 0 2.125.875T19 5q0 .275-.05.5a4.6 4.6 0 0 1-.15.5H21q.825 0 1.413.587Q23 7.175 23 8v4h-8v8h7v-6h2v6q0 .825-.587 1.413A1.93 1.93 0 0 1 22 22H4zM5 10h6V8H5v2zm6 4h2v-4h-2v4zm0-6h2V6h-2v2zm-1-2q.425 0 .713-.288A.97.97 0 0 0 11 5q0-.425-.287-.713A.97.97 0 0 0 10 4q-.425 0-.712.287A.97.97 0 0 0 9 5q0 .425.288.712.287.288.712.288zm6 0q.425 0 .713-.288A.97.97 0 0 0 17 5q0-.425-.287-.713A.97.97 0 0 0 16 4q-.425 0-.712.287A.97.97 0 0 0 15 5q0 .425.288.712.287.288.712.288zm-3 6zm6 0V8h-6v2h6z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 22q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 20v-6h2v6h7v-8H3V8q0-.825.588-1.413A1.93 1.93 0 0 1 5 6h2.2a3 3 0 0 1-.15-.5A2.4 2.4 0 0 1 7 5q0-1.25.875-2.125T10 2q.65 0 1.213.275.562.275.987.775l.8 1.05.8-1.05q.45-.525 1-.788Q15.35 2 16 2q1.25 0 2.125.875T19 5q0 .275-.05.5a4.6 4.6 0 0 1-.15.5H21q.825 0 1.413.587Q23 7.175 23 8v4h-8v8h7v-6h2v6q0 .825-.587 1.413A1.93 1.93 0 0 1 22 22H4zM5 10h6V8H5v2zm6 4h2v-4h-2v4zm0-6h2V6h-2v2zm-1-2q.425 0 .713-.288A.97.97 0 0 0 11 5q0-.425-.287-.713A.97.97 0 0 0 10 4q-.425 0-.712.287A.97.97 0 0 0 9 5q0 .425.288.712.287.288.712.288zm6 0q.425 0 .713-.288A.97.97 0 0 0 17 5q0-.425-.287-.713A.97.97 0 0 0 16 4q-.425 0-.712.287A.97.97 0 0 0 15 5q0 .425.288.712.287.288.712.288zm-3 6zm6 0V8h-6v2h6z'/></svg>");
}
.ht-i-g-code{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m8 18-6-6 6-6 1.425 1.425L4.825 12l4.6 4.6L8 18zm8 0-1.425-1.4 4.6-4.6-4.6-4.6L16 6l6 6-6 6z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m8 18-6-6 6-6 1.425 1.425L4.825 12l4.6 4.6L8 18zm8 0-1.425-1.4 4.6-4.6-4.6-4.6L16 6l6 6-6 6z'/></svg>");
}
.ht-i-g-movie{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m4 8 1.5 3h3l-1.5-3h2l1.5 3h3l-1.5-3h2l1.5 3h3l-1.5-3H20q.825 0 1.413.588Q22 9.175 22 10v8q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20H4q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V6.825L4 8zm0 10h16v-5H4v5zm0 0v-5 5z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m4 8 1.5 3h3l-1.5-3h2l1.5 3h3l-1.5-3h2l1.5 3h3l-1.5-3H20q.825 0 1.413.588Q22 9.175 22 10v8q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20H4q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V6.825L4 8zm0 10h16v-5H4v5zm0 0v-5 5z'/></svg>");
}
.ht-i-g-medal{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 22q-2.5 0-4.25-1.75T6 16q0-1.075.388-2.062Q6.775 12.95 7.5 12.2L3 3h6l3.05 6.1Q12.875 9 13.7 9.262 14.525 9.525 15.3 10L18 4h3l-4.45 8.95q.725.75 1.088 1.737Q18 15.675 18 16.75q0 2.5-1.75 4.25T12 22zm0-2q1.65 0 2.825-1.175Q16 17.65 16 16q0-1.65-1.175-2.825Q13.65 12 12 12q-1.65 0-2.825 1.175Q8 14.35 8 16q0 1.65 1.175 2.825Q10.35 20 12 20zm0-2.5L10.225 18.5l.45-1.95L9.2 15.25l1.975-.175L12 13.3l.775 1.75 1.975.175-1.475 1.275.45 1.95L12 17.5z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 22q-2.5 0-4.25-1.75T6 16q0-1.075.388-2.062Q6.775 12.95 7.5 12.2L3 3h6l3.05 6.1Q12.875 9 13.7 9.262 14.525 9.525 15.3 10L18 4h3l-4.45 8.95q.725.75 1.088 1.737Q18 15.675 18 16.75q0 2.5-1.75 4.25T12 22zm0-2q1.65 0 2.825-1.175Q16 17.65 16 16q0-1.65-1.175-2.825Q13.65 12 12 12q-1.65 0-2.825 1.175Q8 14.35 8 16q0 1.65 1.175 2.825Q10.35 20 12 20zm0-2.5L10.225 18.5l.45-1.95L9.2 15.25l1.975-.175L12 13.3l.775 1.75 1.975.175-1.475 1.275.45 1.95L12 17.5z'/></svg>");
}
.ht-i-g-school{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 21 4 16.7v-6L1 9l11-6 11 6v8h-2v-7.1l-2 1.1v6L12 21zm0-9.275L18.825 8 12 4.3 5.2 8 12 11.725zm0 7L18 15.45V11.8l-6 3.25-6-3.3v3.7L12 18.725zM12 8zm0 3.45zm0 0z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 21 4 16.7v-6L1 9l11-6 11 6v8h-2v-7.1l-2 1.1v6L12 21zm0-9.275L18.825 8 12 4.3 5.2 8 12 11.725zm0 7L18 15.45V11.8l-6 3.25-6-3.3v3.7L12 18.725zM12 8zm0 3.45zm0 0z'/></svg>");
}
.ht-i-g-explore{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m7.5 16.5 8.5-4-4-8.5L3.5 8l4 8.5zM12 13q-.425 0-.712-.288A.97.97 0 0 1 11 12q0-.425.288-.713A.97.97 0 0 1 12 11q.425 0 .713.287.287.288.287.713 0 .425-.287.712A.97.97 0 0 1 12 13zm0 9q-2.075 0-3.9-.788-1.825-.787-3.175-2.137Q3.575 17.725 2.788 15.9 2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175Q6.275 3.575 8.1 2.788 9.925 2 12 2t3.9.788q1.825.787 3.175 2.137 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22zm0-2q3.35 0 5.675-2.325Q20 15.35 20 12q0-3.35-2.325-5.675Q15.35 4 12 4 8.65 4 6.325 6.325 4 8.65 4 12q0 3.35 2.325 5.675Q8.65 20 12 20zm0-8z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m7.5 16.5 8.5-4-4-8.5L3.5 8l4 8.5zM12 13q-.425 0-.712-.288A.97.97 0 0 1 11 12q0-.425.288-.713A.97.97 0 0 1 12 11q.425 0 .713.287.287.288.287.713 0 .425-.287.712A.97.97 0 0 1 12 13zm0 9q-2.075 0-3.9-.788-1.825-.787-3.175-2.137Q3.575 17.725 2.788 15.9 2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175Q6.275 3.575 8.1 2.788 9.925 2 12 2t3.9.788q1.825.787 3.175 2.137 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22zm0-2q3.35 0 5.675-2.325Q20 15.35 20 12q0-3.35-2.325-5.675Q15.35 4 12 4 8.65 4 6.325 6.325 4 8.65 4 12q0 3.35 2.325 5.675Q8.65 20 12 20zm0-8z'/></svg>");
}
.ht-i-g-monitor{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M9 22v-2H4q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V5q0-.825.588-1.413A1.93 1.93 0 0 1 4 3h16q.825 0 1.413.587Q22 4.175 22 5v13q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20h-5v2H9zM4 18h16V5H4v13zm0 0V5v13z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M9 22v-2H4q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V5q0-.825.588-1.413A1.93 1.93 0 0 1 4 3h16q.825 0 1.413.587Q22 4.175 22 5v13q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20h-5v2H9zM4 18h16V5H4v13zm0 0V5v13z'/></svg>");
}
.ht-i-g-palette{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 22q-2.075 0-3.9-.788-1.825-.787-3.175-2.137Q3.575 17.725 2.788 15.9 2 14.075 2 12q0-2.05.813-3.875.812-1.825 2.187-3.175 1.375-1.35 3.213-2.15Q10.05 2 12.05 2q1.975 0 3.713.675 1.737.675 3.05 1.85 1.312 1.175 2.05 2.762.737 1.588.737 3.413 0 2.6-1.5 4.45T16 17h-1.75q-.475 0-.713.275a.99.99 0 0 0-.237.65q0 .5.3.85.3.35.3.825 0 .8-.475 1.6-.475.8-1.425.8zm-5.5-9q.65 0 1.075-.425.425-.425.425-1.075 0-.65-.425-1.075A1.46 1.46 0 0 0 6.5 10q-.65 0-1.075.425Q5 10.85 5 11.5q0 .65.425 1.075Q5.85 13 6.5 13zm3-4q.65 0 1.075-.425Q11 8.15 11 7.5q0-.65-.425-1.075A1.46 1.46 0 0 0 9.5 6q-.65 0-1.075.425Q8 6.85 8 7.5q0 .65.425 1.075Q8.85 9 9.5 9zm5 0q.65 0 1.075-.425Q16 8.15 16 7.5q0-.65-.425-1.075A1.46 1.46 0 0 0 14.5 6q-.65 0-1.075.425Q13 6.85 13 7.5q0 .65.425 1.075Q13.85 9 14.5 9zm3 4q.65 0 1.075-.425Q19 12.15 19 11.5q0-.65-.425-1.075A1.46 1.46 0 0 0 17.5 10q-.65 0-1.075.425Q16 10.85 16 11.5q0 .65.425 1.075Q16.85 13 17.5 13zM12 20q.225 0 .363-.125a.42.42 0 0 0 .137-.325q0-.275-.3-.55-.3-.275-.3-1.025 0-1.05.725-1.762Q13.35 15.5 14.4 15.5H16q1.65 0 2.825-1.213Q20 13.075 20 11.4q0-2.85-2.225-4.625Q15.55 5 12.5 5q-3.275 0-5.388 2.15Q5 9.3 5 12.45q0 3.025 2.125 5.288Q9.25 20 12 20z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 22q-2.075 0-3.9-.788-1.825-.787-3.175-2.137Q3.575 17.725 2.788 15.9 2 14.075 2 12q0-2.05.813-3.875.812-1.825 2.187-3.175 1.375-1.35 3.213-2.15Q10.05 2 12.05 2q1.975 0 3.713.675 1.737.675 3.05 1.85 1.312 1.175 2.05 2.762.737 1.588.737 3.413 0 2.6-1.5 4.45T16 17h-1.75q-.475 0-.713.275a.99.99 0 0 0-.237.65q0 .5.3.85.3.35.3.825 0 .8-.475 1.6-.475.8-1.425.8zm-5.5-9q.65 0 1.075-.425.425-.425.425-1.075 0-.65-.425-1.075A1.46 1.46 0 0 0 6.5 10q-.65 0-1.075.425Q5 10.85 5 11.5q0 .65.425 1.075Q5.85 13 6.5 13zm3-4q.65 0 1.075-.425Q11 8.15 11 7.5q0-.65-.425-1.075A1.46 1.46 0 0 0 9.5 6q-.65 0-1.075.425Q8 6.85 8 7.5q0 .65.425 1.075Q8.85 9 9.5 9zm5 0q.65 0 1.075-.425Q16 8.15 16 7.5q0-.65-.425-1.075A1.46 1.46 0 0 0 14.5 6q-.65 0-1.075.425Q13 6.85 13 7.5q0 .65.425 1.075Q13.85 9 14.5 9zm3 4q.65 0 1.075-.425Q19 12.15 19 11.5q0-.65-.425-1.075A1.46 1.46 0 0 0 17.5 10q-.65 0-1.075.425Q16 10.85 16 11.5q0 .65.425 1.075Q16.85 13 17.5 13zM12 20q.225 0 .363-.125a.42.42 0 0 0 .137-.325q0-.275-.3-.55-.3-.275-.3-1.025 0-1.05.725-1.762Q13.35 15.5 14.4 15.5H16q1.65 0 2.825-1.213Q20 13.075 20 11.4q0-2.85-2.225-4.625Q15.55 5 12.5 5q-3.275 0-5.388 2.15Q5 9.3 5 12.45q0 3.025 2.125 5.288Q9.25 20 12 20z'/></svg>");
}
.ht-i-g-user{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 12q-1.65 0-2.825-1.175Q8 9.65 8 8q0-1.65 1.175-2.825Q10.35 4 12 4q1.65 0 2.825 1.175Q16 6.35 16 8q0 1.65-1.175 2.825Q13.65 12 12 12zm-8 8v-2.8q0-.85.438-1.562.437-.713 1.162-1.088 1.55-.775 3.15-1.162Q10.35 13 12 13t3.25.388q1.6.387 3.15 1.162.725.375 1.163 1.088.437.712.437 1.562V20H4zm2-2h12v-.8a1 1 0 0 0-.5-.875q-1.35-.675-2.725-1Q13.4 15 12 15t-2.775.325Q7.85 15.65 6.5 16.325a1 1 0 0 0-.5.875v.8zm6-8q.825 0 1.413-.588Q14 8.825 14 8t-.587-1.413A1.93 1.93 0 0 0 12 6q-.825 0-1.412.587A1.93 1.93 0 0 0 10 8q0 .825.588 1.412Q11.175 10 12 10zm0-2zm0 8z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 12q-1.65 0-2.825-1.175Q8 9.65 8 8q0-1.65 1.175-2.825Q10.35 4 12 4q1.65 0 2.825 1.175Q16 6.35 16 8q0 1.65-1.175 2.825Q13.65 12 12 12zm-8 8v-2.8q0-.85.438-1.562.437-.713 1.162-1.088 1.55-.775 3.15-1.162Q10.35 13 12 13t3.25.388q1.6.387 3.15 1.162.725.375 1.163 1.088.437.712.437 1.562V20H4zm2-2h12v-.8a1 1 0 0 0-.5-.875q-1.35-.675-2.725-1Q13.4 15 12 15t-2.775.325Q7.85 15.65 6.5 16.325a1 1 0 0 0-.5.875v.8zm6-8q.825 0 1.413-.588Q14 8.825 14 8t-.587-1.413A1.93 1.93 0 0 0 12 6q-.825 0-1.412.587A1.93 1.93 0 0 0 10 8q0 .825.588 1.412Q11.175 10 12 10zm0-2zm0 8z'/></svg>");
}
/* AI / 智能 —— Material Symbols 「auto_awesome（四芒星 sparkle ✨）」
 * 业界 AI 视觉语言通用符号（Google Gemini / OpenAI 「闪光」按钮等都在用）。
 * 主大星 + 三颗小星，单色线条与本图标库其他 ht-g 风格一致。 */
.ht-i-g-ai{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m19 9 1.25-2.75L23 5l-2.75-1.25L19 1l-1.25 2.75L15 5l2.75 1.25L19 9zm-7.5.5L9 4 6.5 9.5 1 12l5.5 2.5L9 20l2.5-5.5L17 12l-5.5-2.5zM19 15l-1.25 2.75L15 19l2.75 1.25L19 23l1.25-2.75L23 19l-2.75-1.25L19 15z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m19 9 1.25-2.75L23 5l-2.75-1.25L19 1l-1.25 2.75L15 5l2.75 1.25L19 9zm-7.5.5L9 4 6.5 9.5 1 12l5.5 2.5L9 20l2.5-5.5L17 12l-5.5-2.5zM19 15l-1.25 2.75L15 19l2.75 1.25L19 23l1.25-2.75L23 19l-2.75-1.25L19 15z'/></svg>");
}
.ht-i-g-tool{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m19.575 22-7.05-7.05q-.75.275-1.55.413A8.7 8.7 0 0 1 9.5 15.5q-2.7 0-4.6-1.9T3 9q0-.875.225-1.7.225-.825.65-1.575l4.05 4.05 2.85-2.85L6.725 2.875Q7.475 2.45 8.3 2.225 9.125 2 10 2q2.7 0 4.6 1.9T16.5 8.5q0 .725-.137 1.475-.138.75-.413 1.55L23 18.575 19.575 22zm0-2.85.575-.575-7.45-7.45q.35-.65.575-1.413A6.4 6.4 0 0 0 13.5 8.5q0-1.4-.788-2.575A4 4 0 0 0 10.7 4.225L8.4 6.525l4.275 4.275-4.85 4.85L3.55 11.4q-.025.4 0 .75t.075.65q.5 1.9 2.025 3.05 1.525 1.15 3.5 1.15.65 0 1.213-.087.562-.088 1.412-.488l7.8 7.825z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m19.575 22-7.05-7.05q-.75.275-1.55.413A8.7 8.7 0 0 1 9.5 15.5q-2.7 0-4.6-1.9T3 9q0-.875.225-1.7.225-.825.65-1.575l4.05 4.05 2.85-2.85L6.725 2.875Q7.475 2.45 8.3 2.225 9.125 2 10 2q2.7 0 4.6 1.9T16.5 8.5q0 .725-.137 1.475-.138.75-.413 1.55L23 18.575 19.575 22zm0-2.85.575-.575-7.45-7.45q.35-.65.575-1.413A6.4 6.4 0 0 0 13.5 8.5q0-1.4-.788-2.575A4 4 0 0 0 10.7 4.225L8.4 6.525l4.275 4.275-4.85 4.85L3.55 11.4q-.025.4 0 .75t.075.65q.5 1.9 2.025 3.05 1.525 1.15 3.5 1.15.65 0 1.213-.087.562-.088 1.412-.488l7.8 7.825z'/></svg>");
}
.ht-i-g-news{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 22q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 20V8h2v12h14v2H4zm4-4q-.825 0-1.412-.587A1.93 1.93 0 0 1 6 16V4q0-.825.588-1.413A1.93 1.93 0 0 1 8 2h12q.825 0 1.413.587Q22 3.175 22 4v12q0 .825-.587 1.413A1.93 1.93 0 0 1 20 18H8zm0-2h12V4H8v12zm2-3h6v-2h-6v2zm0-3h8V8h-8v2zm0-3h8V5h-8v2z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 22q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 20V8h2v12h14v2H4zm4-4q-.825 0-1.412-.587A1.93 1.93 0 0 1 6 16V4q0-.825.588-1.413A1.93 1.93 0 0 1 8 2h12q.825 0 1.413.587Q22 3.175 22 4v12q0 .825-.587 1.413A1.93 1.93 0 0 1 20 18H8zm0-2h12V4H8v12zm2-3h6v-2h-6v2zm0-3h8V8h-8v2zm0-3h8V5h-8v2z'/></svg>");
}
.ht-i-g-heart{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m12 21-1.45-1.3q-2.525-2.275-4.175-3.937Q4.725 14.1 3.75 12.812 2.775 11.525 2.388 10.45 2 9.375 2 8.25 2 5.95 3.575 4.375 5.15 2.8 7.45 2.8q1.275 0 2.425.537Q11.025 3.875 12 4.85q.975-.975 2.125-1.512Q15.275 2.8 16.55 2.8q2.3 0 3.875 1.575Q22 5.95 22 8.25q0 1.125-.387 2.2-.388 1.075-1.363 2.363Q19.275 14.1 17.625 15.762 15.975 17.425 13.45 19.7L12 21zm0-2.7q2.4-2.15 3.95-3.687 1.55-1.538 2.45-2.675.9-1.138 1.25-2.025.35-.888.35-1.763 0-1.5-1-2.5T16.55 4.8q-1.175 0-2.175.687-1 .688-1.55 1.788h-1.65q-.55-1.1-1.55-1.787-1-.688-2.175-.688-1.5 0-2.5 1t-1 2.5q0 .875.35 1.762.35.888 1.25 2.025.9 1.138 2.45 2.688Q9.6 16.15 12 18.3zm0-6.75z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='m12 21-1.45-1.3q-2.525-2.275-4.175-3.937Q4.725 14.1 3.75 12.812 2.775 11.525 2.388 10.45 2 9.375 2 8.25 2 5.95 3.575 4.375 5.15 2.8 7.45 2.8q1.275 0 2.425.537Q11.025 3.875 12 4.85q.975-.975 2.125-1.512Q15.275 2.8 16.55 2.8q2.3 0 3.875 1.575Q22 5.95 22 8.25q0 1.125-.387 2.2-.388 1.075-1.363 2.363Q19.275 14.1 17.625 15.762 15.975 17.425 13.45 19.7L12 21zm0-2.7q2.4-2.15 3.95-3.687 1.55-1.538 2.45-2.675.9-1.138 1.25-2.025.35-.888.35-1.763 0-1.5-1-2.5T16.55 4.8q-1.175 0-2.175.687-1 .688-1.55 1.788h-1.65q-.55-1.1-1.55-1.787-1-.688-2.175-.688-1.5 0-2.5 1t-1 2.5q0 .875.35 1.762.35.888 1.25 2.025.9 1.138 2.45 2.688Q9.6 16.15 12 18.3zm0-6.75z'/></svg>");
}
.ht-i-g-folder{
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 20q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V6q0-.825.588-1.413A1.93 1.93 0 0 1 4 4h6l2 2h8q.825 0 1.413.588Q22 7.175 22 8v10q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20H4zm0-2h16V8h-8.825l-2-2H4v12zm0 0V6v12z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M4 20q-.825 0-1.412-.587A1.93 1.93 0 0 1 2 18V6q0-.825.588-1.413A1.93 1.93 0 0 1 4 4h6l2 2h8q.825 0 1.413.588Q22 7.175 22 8v10q0 .825-.587 1.413A1.93 1.93 0 0 1 20 20H4zm0-2h16V8h-8.825l-2-2H4v12zm0 0V6v12z'/></svg>");
}

/* ---------- 右键菜单：图标排版 ---------- */
.ht-ctxmenu-item{
  display: flex; align-items: center; gap: 10px;
}
.ht-ctxmenu-item .ht-i{
  font-size: 16px; opacity: .75;
}
.ht-ctxmenu-item:hover .ht-i,
.ht-ctxmenu-item.danger .ht-i{ opacity: 1; }
/* 自定义图标槽（用于「移动至分组」子菜单这类需要混排 <i>/<img>/emoji/首字 的场景）。
 * 固定 16×16 的方形槽位 —— 与左侧 .ht-i 视觉对齐，避免不同形态图标导致行高漂移。*/
.ht-ctxmenu-item .ht-ctxmenu-gicon{
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; flex: 0 0 16px;
  font-size: 14px; line-height: 1; opacity: .85;
}
.ht-ctxmenu-item:hover .ht-ctxmenu-gicon{ opacity: 1; }
.ht-ctxmenu-item .ht-ctxmenu-gicon > .ht-i{ font-size: 16px; opacity: 1; }
.ht-ctxmenu-item .ht-ctxmenu-gicon > img{
  width: 16px; height: 16px; object-fit: cover; border-radius: 3px; display: block;
}
.ht-ctxmenu-item .ht-ctxmenu-gicon-text{
  display: inline-block; line-height: 1;
  font-size: 13px; font-weight: 600;
}
/* 子菜单展开箭头：自动推到右侧 */
.ht-ctxmenu-item .ht-ctxmenu-caret{ margin-left: auto; font-size: 14px; opacity: .55; }
/* 子菜单选中标记 */
.ht-ctxmenu-item .ht-ctxmenu-check{ margin-left: auto; font-size: 14px; color: var(--ht-accent); }
.ht-ctxmenu-item:hover .ht-ctxmenu-check{ color: #fff; }


/* 图标类型 tab */
.ht-icon-type-tabs{
  display: flex; gap: 4px; margin-bottom: 8px;
  background: rgba(0,0,0,.04); padding: 4px; border-radius: 8px;
}
html[data-theme="dark"] .ht-icon-type-tabs,
html[data-theme="auto"] .ht-icon-type-tabs{ background: rgba(255,255,255,.06); }
.ht-icon-type-tab{
  flex: 1; padding: 6px 10px; border: none; background: transparent;
  border-radius: 6px; cursor: pointer; color: #64748b; font-size: 12px;
  transition: color .15s, background .15s, box-shadow .15s;
}
.ht-icon-type-tab.on{
  background: #fff; color: #1f2937;
  box-shadow: 0 1px 2px rgba(0,0,0,.1);
}
html[data-theme="dark"] .ht-icon-type-tab.on,
html[data-theme="auto"] .ht-icon-type-tab.on{ background: #3b3f52; color: #e5e7eb; }
.ht-icon-pane{ display: none; }
.ht-icon-pane.on{ display: block; }

/* 弹窗 */
.ht-modal{
  position: fixed; inset: 0; z-index: 9000; display: none;
}
.ht-modal.show{ display: block; }
.ht-modal-mask{
  position: absolute; inset: 0; background: rgba(15,17,21,.45);
  backdrop-filter: blur(4px);
}
.ht-modal-box{
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(580px, calc(100vw - 24px));
  max-height: calc(100vh - 40px);
  /* 移动端浏览器地址栏会动态收起/展开，使用 dvh 让 max-height 跟随实际可视高度，
     避免 foot 被裁掉（如"保存按钮"看不见）。不支持 dvh 的旧浏览器回落到 vh。 */
  max-height: calc(100dvh - 40px);
  background: #fff; color: #1f2937;
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,.35);
  /* 用 grid 而非 flex：head/foot 用 auto 行，body 用 1fr + min-height:0
     可被压缩出滚动条。这样无论内容多长，foot 都钉在底部、绝不被裁。 */
  display: grid;
  grid-template-rows: auto 1fr auto;
}
html[data-theme="dark"] .ht-modal-box,
html[data-theme="auto"] .ht-modal-box{
  background: #1f2230; color: #e5e7eb;
}
.ht-modal-head{
  display:flex; justify-content:space-between; align-items:center;
  padding: 14px 18px; border-bottom: 1px solid rgba(0,0,0,.06);
  /* 配合 body 的 min-height:0：head 也不被压缩，保证 Tab/标题/关闭按钮稳定可见。 */
  flex-shrink: 0;
}
html[data-theme="dark"] .ht-modal-head,
html[data-theme="auto"] .ht-modal-head{ border-bottom-color: rgba(255,255,255,.08); }
.ht-modal-title{ font-weight: 600; font-size: 15px; }
.ht-modal-close{
  background: transparent; border: none; font-size: 22px; cursor: pointer;
  color: inherit; line-height: 1; padding: 0 4px;
}
.ht-modal-body{
  padding: 16px 18px; overflow-y: auto; flex: 1 1 auto;
  /* 关键：flex 列布局下，子项默认 min-height: auto = 内容 min-content 高度，
     会把 body 撑到 ≥ 内容高度，进而把 foot 顶出 .ht-modal-box（overflow:hidden 裁掉），
     导致"保存按钮不可见"。强制 min-height:0 让 body 可被压缩，foot 始终可见。 */
  min-height: 0;
}
.ht-field{ margin-bottom: 12px; }
.ht-field > label{
  display:block; font-size: 12px; color: #64748b; margin-bottom: 4px;
}
html[data-theme="dark"] .ht-field > label,
html[data-theme="auto"] .ht-field > label{ color: #9ca3af; }

/* ============================================================
 *  横向字段（label + 输入区域 横向排列）
 *  仅作用于 .ht-field.ht-field-row：
 *    [label 100px] [.ht-input / .ht-row 占满剩余]
 * ============================================================ */
.ht-field.ht-field-row{
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 14px;
  width: 100%;
}
.ht-field.ht-field-row > label{
  flex: 0 0 84px; margin-bottom: 0;
  text-align: right; font-size: 12px; color: #64748b;
  line-height: 1.4;
}
html[data-theme="dark"] .ht-field.ht-field-row > label,
html[data-theme="auto"] .ht-field.ht-field-row > label{ color: #9ca3af; }
.ht-field.ht-field-row > .ht-input,
.ht-field.ht-field-row > .ht-row,
.ht-field.ht-field-row > .ht-size-picker,
.ht-field.ht-field-row > .ht-radio-group{
  flex: 1; min-width: 0;
}
/* 行内提示语：跟在 ht-row 末尾，和输入框同一行的小字 */
.ht-hint-inline{
  margin-top: 0; white-space: nowrap;
  color: #94a3b8; font-size: 11px;
}
/* ht-row 内的行内提示允许收缩，优先把空间让给 input */
.ht-row > .ht-hint-inline{
  flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis;
}
/* 视觉隐藏的表单字段（DOM 仍存在以承载数据） */
.ht-hidden-field{
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0; opacity: 0;
  pointer-events: none;
}
/* 窄屏：保留横向但 label 收紧；极窄退化成竖向以避免输入区被挤压 */
@media (max-width: 560px){
  .ht-field.ht-field-row{ flex-direction: column; align-items: stretch; gap: 4px; }
  .ht-field.ht-field-row > label{ flex: 0 0 auto; text-align: left; }
  .ht-hint-inline{ white-space: normal; }
}

.ht-row{ display:flex; gap:8px; align-items:center; min-width:0; }
.ht-input{
  flex: 1; padding: 8px 12px; font-size: 13px;
  border: 1px solid #cbd5e1; border-radius: 8px;
  background: #fff; color: #1f2937; outline: none;
  min-width: 0;
}
.ht-input:focus{ border-color: var(--ht-accent); box-shadow: 0 0 0 3px rgba(91,141,239,.15); }
html[data-theme="dark"] .ht-input,
html[data-theme="auto"] .ht-input{
  background: #2a2e3e; color: #e5e7eb; border-color: #3b3f52;
}
.ht-hint{ font-size: 11px; color: #94a3b8; margin-top: 4px; }

/* 「添加 / 编辑标签」表单里的卡片真实预览容器：
 *   - 内部承载一个真正的 <a class="halotab-card" data-size="...">，
 *     由 JS 用 renderCard() 复用桌面同一套渲染逻辑，所见即所得；
 *   - 容器本身只负责提供「桌面真实 grid 单元格」尺寸的版心，并屏蔽交互；
 *   - 预览里的卡片不参与桌面 grid 上下文，所以这里按 data-size 把宽高直接算出来，
 *     防止 .halotab-card 因外层无 grid-template-columns 而塌缩。
 *   - 尺寸来源：直接读 grid 自定义变量
 *       --ht-cell-w / --ht-cell-h / --ht-cell-gap / --ht-row-gap
 *     由 updatePreview 在打开时把当前桌面真实 grid 的值同步到 host，
 *     于是预览跟桌面 1:1 对齐，gap 变化时也能跟随，不再写死 80/110/176/206。
 *   - 兜底默认值跟 .halotab-grid 的初始值一致（cell 80×110，gap 16，row-gap 4）。
 */
.ht-card-preview-host{
  /* 兜底变量：JS 未写入时用与桌面一致的默认值 */
  --ht-cell-w: 80px;
  --ht-cell-h: 110px;
  --ht-cell-gap: 24px;
  --ht-row-gap: 2px;
  flex-shrink: 0;
  /* 屏蔽点击 / 拖拽 / hover 状态，避免预览影响真实表单交互 */
  pointer-events: none;
  user-select: none;
  /* 默认按 1×1 兜底（JS 未及时设置 data-size 时也不会塌缩） */
  width: var(--ht-cell-w);
  height: var(--ht-cell-h);
  transition: width .18s ease, height .18s ease;
}
/* 预览尺寸：与桌面 grid 完全等价的几何公式
 *   width  = N * cell-w + (N-1) * cell-gap
 *   height = M * cell-h + (M-1) * row-gap
 * 2x2 例外：跟桌面 .halotab-card[data-size="2x2"] 的高度修正保持一致
 *   height = 卡总宽 + 30 = (2*cell-w + cell-gap) + 30
 * 4x2 不做修正，沿用通用公式（横向 banner，与桌面 4x2 一致）。 */
.ht-card-preview-host[data-size="1x1"]{
  width:  var(--ht-cell-w);
  height: var(--ht-cell-h);
}
.ht-card-preview-host[data-size="2x1"]{
  width:  calc(var(--ht-cell-w) * 2 + var(--ht-cell-gap));
  height: var(--ht-cell-h);
}
.ht-card-preview-host[data-size="1x2"]{
  width:  var(--ht-cell-w);
  height: calc(var(--ht-cell-h) * 2 + var(--ht-row-gap));
}
.ht-card-preview-host[data-size="2x2"]{
  width:  calc(var(--ht-cell-w) * 2 + var(--ht-cell-gap));
  height: calc(var(--ht-cell-w) * 2 + var(--ht-cell-gap) + 30px);
}
.ht-card-preview-host[data-size="4x2"]{
  width:  calc(var(--ht-cell-w) * 4 + var(--ht-cell-gap) * 3);
  height: calc(var(--ht-cell-h) * 2 + var(--ht-row-gap));
}
/* 预览态：保留 .halotab-card-body 占位（30px 标题高度），但不显示标题文字，
   这样卡片整体高度跟桌面真实卡一致，图标块比例也保持正确。 */
.ht-card-preview-host .halotab-card-body{ visibility: hidden; }
.ht-card-preview-host > .halotab-card{
  /* 脱离 grid 上下文：不再用 grid-column/grid-row span，直接撑满 host */
  grid-column: auto !important;
  grid-row: auto !important;
  width: 100%; height: 100%;
  /* 预览不需要点击反馈 / 拖动光标 */
  cursor: default;
  transform: none !important;
}
/* 预览里的卡片不接受 :active 缩放（renderCard 会带 .halotab-card:not(.is-widget):active{transform:scale(.96)}） */
.ht-card-preview-host > .halotab-card:active{ transform: none !important; }

.ht-modal-foot{
  padding: 12px 18px; border-top: 1px solid rgba(0,0,0,.06);
  display:flex; justify-content:flex-end; gap: 8px;
  /* 配合 body 的 min-height:0：foot 不被压缩，保证保存/取消按钮始终可见。 */
  flex-shrink: 0;
}
html[data-theme="dark"] .ht-modal-foot,
html[data-theme="auto"] .ht-modal-foot{ border-top-color: rgba(255,255,255,.08); }
.ht-btn{
  padding: 8px 18px; border: none; border-radius: 8px; cursor: pointer;
  background: var(--ht-grad);
  color: #fff; font-size: 13px;
}
.ht-btn:hover{ opacity: .92; }
.ht-btn.gray{ background: #94a3b8; }
.ht-btn.danger{ background: linear-gradient(135deg, #ef4444, #dc2626); }
.ht-btn-mini{ padding: 7px 12px; font-size: 12px; }

/* 仅登录可见：用于「上传图标 / 上传背景图」一类需要鉴权的按钮。
   登录态由 halotab-app.js 在 syncState() 里维护 body.halotab-logged-in。 */
body:not(.halotab-logged-in) .ht-login-only{ display: none !important; }

/* ---------- 全局确认对话框 ----------
 * 复用 .ht-modal 框架，只调一个更紧凑的尺寸 + 图标层。
 * 通过 htConfirm({ title, message, okText, cancelText, danger }) 调用。
 */
.ht-confirm .ht-modal-box{
  width: 360px; max-width: calc(100vw - 32px);
}
/* 确认弹窗（删除分组/网址/组件等）通常是从其它弹窗里触发的，
 * 必须显示在所有普通弹窗之上，否则会被父弹窗的遮罩盖住、看起来像"按钮无响应"。 */
.ht-modal.ht-confirm{ z-index: 9500; }
.ht-confirm-body{
  padding: 20px 22px 8px; display: flex; gap: 14px; align-items: flex-start;
}
.ht-confirm-icon{
  flex: 0 0 auto;
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; line-height: 1;
  background: rgba(91,141,239,.15); color: var(--ht-accent);
}
.ht-confirm.is-danger .ht-confirm-icon{
  background: rgba(239,68,68,.15); color: #ef4444;
}
.ht-confirm-text{ flex: 1; min-width: 0; }
.ht-confirm-title{ font-size: 15px; font-weight: 600; margin-bottom: 6px; }
.ht-confirm-msg{
  font-size: 13px; line-height: 1.55; color: rgba(0,0,0,.66);
  word-break: break-all;
}
html[data-theme="dark"] .ht-confirm-msg,
html[data-theme="auto"] .ht-confirm-msg{ color: rgba(255,255,255,.72); }
.ht-confirm .ht-modal-foot{
  padding: 12px 18px 14px;
  border-top: none;
}

/* ---------- 通用渐隐 + 缩放动画（作用于所有 .ht-modal） ----------
 * 进入：mask 0 → 1 / box 微下移 + 缩 0.96 → 0,1
 * 退出：反向插值；时长 .18s / .22s，缓动 cubic-bezier
 * 通过双类切换：.show（占位 display:block） + .is-show（触发 transition）
 * 任何用 buildModal + openModal/closeModal 打开的弹窗自动具备此动画。
 */
.ht-modal .ht-modal-mask{
  opacity: 0;
  transition: opacity .18s ease;
}
.ht-modal .ht-modal-box{
  opacity: 0;
  /* 注意：原 box 的 transform 是 translate(-50%,-50%)，这里必须连写 */
  transform: translate(-50%, calc(-50% + 8px)) scale(.96);
  transition: opacity .22s cubic-bezier(.22, .61, .36, 1),
              transform .22s cubic-bezier(.22, .61, .36, 1);
  will-change: opacity, transform;
}
.ht-modal.is-show .ht-modal-mask{
  opacity: 1;
}
.ht-modal.is-show .ht-modal-box{
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
@media (prefers-reduced-motion: reduce){
  .ht-modal .ht-modal-mask,
  .ht-modal .ht-modal-box{ transition: none; }
}

/* 颜色选择 */
.ht-color{
  width: 40px; height: 36px; padding: 2px;
  border: 1px solid #cbd5e1; border-radius: 8px;
  background: #fff; cursor: pointer;
}
html[data-theme="dark"] .ht-color,
html[data-theme="auto"] .ht-color{ border-color: #3b3f52; background: #2a2e3e; }

/* ---------- iOS 风开关（用于「图标充满」等布尔开关字段） ----------
 * 用法：
 *   <label class="ht-switch">
 *     <input type="checkbox" name="..." />
 *     <span class="ht-switch-slider"></span>
 *   </label>
 * 视觉：
 *   - 关闭态：浅灰底 + 白圆点
 *   - 开启态：主题色底 + 白圆点右移
 *   - 自带平滑过渡，禁用 outline，键盘聚焦用 box-shadow 高亮
 */
.ht-switch{
  position: relative;
  display: inline-block;
  width: 44px; height: 24px;
  flex-shrink: 0;
  cursor: pointer;
  vertical-align: middle;
}
.ht-switch > input[type="checkbox"]{
  position: absolute;
  opacity: 0;
  width: 0; height: 0;
  margin: 0;
}
.ht-switch-slider{
  position: absolute;
  inset: 0;
  background: #d1d5db;            /* 关闭态轨道色 */
  border-radius: 999px;
  transition: background-color .18s ease;
}
.ht-switch-slider::before{
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 20px; height: 20px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0,0,0,.18);
  transition: transform .18s ease;
}
.ht-switch > input[type="checkbox"]:checked + .ht-switch-slider{
  background: var(--ht-accent, #5b8def);
}
.ht-switch > input[type="checkbox"]:checked + .ht-switch-slider::before{
  transform: translateX(20px);
}
.ht-switch > input[type="checkbox"]:focus-visible + .ht-switch-slider{
  box-shadow: 0 0 0 3px rgba(91,141,239,.25);
}
html[data-theme="dark"] .ht-switch-slider,
html[data-theme="auto"] .ht-switch-slider{ background: #3b3f52; }
html[data-theme="dark"] .ht-switch-slider::before,
html[data-theme="auto"] .ht-switch-slider::before{ background: #e5e7eb; }

/* ---------- 新建分组弹窗：图标网格选择 ----------
 * 参考 addPageGroupBox：5 列网格，单元 30×30，图标 24×24，
 * 选中态用主题色描边 + 浅色背景高亮（替代参考代码的 .selIconsClass）。
 */
.ht-icon-grid{
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  max-height: 240px;
  overflow-y: auto;
  padding: 4px 6px 4px 0;
  margin-top: 6px;
  scrollbar-width: thin;
}
.ht-icon-grid::-webkit-scrollbar{ width: 6px; }
.ht-icon-grid::-webkit-scrollbar-thumb{ background: rgba(0,0,0,.18); border-radius: 4px; }
html[data-theme="dark"] .ht-icon-grid::-webkit-scrollbar-thumb,
html[data-theme="auto"] .ht-icon-grid::-webkit-scrollbar-thumb{ background: rgba(255,255,255,.25); }

.ht-icon-cell{
  display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  margin: 0 auto;
  font-size: 22px; line-height: 1;
  color: #4b5563;             /* 给内置线条图标 currentColor 提供默认色 */
  border: 1px solid transparent;
  border-radius: 8px;
  cursor: pointer;
  background: transparent;
  transition: background .15s, border-color .15s, color .15s, transform .15s;
  user-select: none;
}
html[data-theme="dark"] .ht-icon-cell,
html[data-theme="auto"] .ht-icon-cell{ color: #d1d5db; }
.ht-icon-cell:hover{
  background: rgba(91,141,239,.12);
  color: var(--ht-accent);
}
.ht-icon-cell.on{
  border-color: var(--ht-accent);
  background: rgba(91,141,239,.18);
  box-shadow: 0 0 0 2px rgba(91,141,239,.18);
  color: var(--ht-accent);
}
.ht-icon-cell > .ht-i{ width: 22px; height: 22px; vertical-align: 0; }

/* tabs in appearance modal */
.ht-tabs{
  display:flex; gap: 4px; margin-bottom: 14px;
  background: rgba(0,0,0,.04); padding: 4px; border-radius: 8px;
}
html[data-theme="dark"] .ht-tabs,
html[data-theme="auto"] .ht-tabs{ background: rgba(255,255,255,.06); }
.ht-tab{
  flex:1; padding: 7px 10px; border: none; background: transparent;
  border-radius: 6px; cursor: pointer; color: #64748b; font-size: 13px;
}
.ht-tab.on{
  background: #fff; color: #1f2937;
  box-shadow: 0 1px 2px rgba(0,0,0,.1);
}
html[data-theme="dark"] .ht-tab.on,
html[data-theme="auto"] .ht-tab.on{ background: #3b3f52; color: #e5e7eb; }
.ht-tab-pane{ display: none; }
.ht-tab-pane.on{ display: block; }

.ht-divider{
  height: 1px; background: rgba(0,0,0,.06); margin: 16px 0;
}
html[data-theme="dark"] .ht-divider,
html[data-theme="auto"] .ht-divider{ background: rgba(255,255,255,.08); }

/* 背景图预设 */
.ht-presets{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 8px;
}
.ht-preset{
  position: relative; height: 64px; border-radius: 8px;
  border: 2px solid transparent; cursor: pointer;
  background-size: cover; background-position: center;
  background-color: #f1f5f9;
  overflow: hidden;
}
.ht-preset:hover{ border-color: var(--ht-accent); }
.ht-preset-default{
  background: linear-gradient(135deg, #c2e9fb 0%, #a1c4fd 50%, #fbc2eb 100%);
}
.ht-preset span{
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 4px 6px; font-size: 11px; color: #fff;
  background: linear-gradient(transparent, rgba(0,0,0,.55));
}

/* ----- 卡片尺寸选择器（弹窗内） ----- */
.ht-size-picker{
  display: flex; gap: 8px; flex-wrap: wrap;
}
.ht-size-opt{
  display: inline-flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 4px;
  padding: 8px 6px 6px;
  min-width: 64px;
  background: #f1f5f9;
  border: 1px solid #cbd5e1;
  border-radius: 8px;
  cursor: pointer;
  color: #475569;
  font-size: 12px;
  transition: border-color .15s, background .15s, color .15s;
}
.ht-size-opt em{ font-style: normal; font-size: 12px; }
.ht-size-opt:hover{ border-color: var(--ht-accent); color: #1f2937; }
.ht-size-opt.on{
  border-color: var(--ht-accent);
  background: #eef2ff;
  color: #1f2937;
  box-shadow: 0 0 0 3px rgba(91,141,239,.15);
}
html[data-theme="dark"] .ht-size-opt,
html[data-theme="auto"] .ht-size-opt{
  background: #2a2e3e; border-color: #3b3f52; color: #cbd5e1;
}
html[data-theme="dark"] .ht-size-opt.on,
html[data-theme="auto"] .ht-size-opt.on{
  background: rgba(91,141,239,.2); color: #e5e7eb;
}
.ht-size-box{
  display: block;
  background: var(--ht-grad);
  border-radius: 3px;
  opacity: .85;
}
/* 缩略图（基础格 8px） */
.ht-size-box.s1x1{ width: 16px; height: 16px; }
.ht-size-box.s2x1{ width: 34px; height: 16px; }
.ht-size-box.s1x2{ width: 16px; height: 34px; }
.ht-size-box.s2x2{ width: 34px; height: 34px; }
.ht-size-box.s4x2{ width: 70px; height: 34px; }

/* 单选分段（Radio Group）：用于「打开方式」等二选一/三选一表单项。
 * 视觉沿用 .ht-size-opt 的卡片化分段风格；用真 <input type="radio"> 承载语义，
 * 但视觉上隐藏原生圆点，靠外层 .ht-radio-opt.on 高亮当前项。 */
.ht-radio-group{
  display: flex; gap: 8px; flex-wrap: wrap;
}
.ht-radio-opt{
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px;
  background: #f1f5f9;
  border: 1px solid #cbd5e1;
  border-radius: 8px;
  cursor: pointer;
  color: #475569;
  font-size: 13px;
  transition: border-color .15s, background .15s, color .15s, box-shadow .15s;
  user-select: none;
}
.ht-radio-opt > input[type="radio"]{
  /* 视觉隐藏但保留可访问性（焦点 / 键盘） */
  position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; margin: 0;
}
.ht-radio-opt:hover{ border-color: var(--ht-accent); color: #1f2937; }
.ht-radio-opt.on{
  border-color: var(--ht-accent);
  background: #eef2ff;
  color: #1f2937;
  box-shadow: 0 0 0 3px rgba(91,141,239,.15);
}
html[data-theme="dark"] .ht-radio-opt,
html[data-theme="auto"] .ht-radio-opt{
  background: #2a2e3e; border-color: #3b3f52; color: #cbd5e1;
}
html[data-theme="dark"] .ht-radio-opt.on,
html[data-theme="auto"] .ht-radio-opt.on{
  background: rgba(91,141,239,.2); color: #e5e7eb;
}

/* Toast */
.ht-toast{
  position: fixed; left: 50%; top: 40px;
  /* 初始位置略上移，show 时滑入到 top:40px 处；从顶部弹出，避免被底部弹窗 footer 等遮挡 */
  transform: translateX(-50%) translateY(-20px);
  background: #111827; color: #fff;
  padding: 10px 18px; border-radius: 999px;
  font-size: 13px; opacity: 0; pointer-events: none;
  transition: opacity .2s, transform .2s;
  z-index: 9999;
  box-shadow: 0 10px 30px rgba(0,0,0,.3);
}
.ht-toast.show{ opacity: 1; transform: translateX(-50%) translateY(0); }
.ht-toast.err{ background: #ef4444; }

/* ============================================================
 *  内置 iframe 浏览弹窗（openIn = "iframe"）
 *  --------------------------------------------------------------
 *  弹层本体已统一使用 HaloTab.appBox（见 halotab-appbox.js）：
 *    - 遮罩 / 居中 / 入场动画 / ESC 关闭 / 锁滚动条 全部由 appBox 负责
 *    - 这里仅保留 iframe loading 转圈用的 keyframes（inline style 引用）
 *  ============================================================ */
@keyframes ht-iframe-spin{ to { transform: rotate(360deg); } }

/* ============================================================
 *  添加标签弹窗：固定尺寸 1024×630，左上角横排 Tab 切换
 *
 *  结构：
 *    .ht-modal.ht-add-modal
 *      └ .ht-modal-box                       (固定 1024×630)
 *           ├ .ht-modal-head.ht-add-head     (左上角 .ht-add-tabs + 右上角关闭)
 *           └ .ht-modal-body.ht-add-body     (承载 .ht-add-pane)
 *                ├ .ht-add-pane[data-add-pane=manual]   (字段 + sticky 底部 .ht-pane-foot)
 *                └ .ht-add-pane[data-add-pane=widget]   (组件网格，点击即添加，无按钮区)
 *  说明：
 *    · 「取消/保存」按钮内嵌在 manual pane 末尾的 .ht-pane-foot，
 *      用 position: sticky 钉在 pane 底部 → 字段再多也始终可见，
 *      切到 widget Tab 时随 pane 一并消失，无需 JS 控制按钮显隐。
 * ============================================================ */
/* 弹窗整体：固定 1024×630。窄屏由下方 @media 兜底缩到 100vw/100vh
 * 注意：max-height 用 100dvh（动态视口高度），避免移动端浏览器 100vh
 *       包含地址栏高度时，foot 被挤出可视区域（"保存按钮看不见"）。
 *       不支持 dvh 的旧浏览器自动回落到 vh。*/
.ht-modal.ht-add-modal .ht-modal-box{
  width: 1024px; height: 630px;
  max-width: calc(100vw - 24px);
  max-height: calc(100vh - 24px);
  max-height: calc(100dvh - 24px);
}

/* ----------------------------------------------------------
 *  壁纸弹窗（更换背景）：固定 1024×630
 *    - 复用公共 .ht-modal 框架，仅锁尺寸
 *    - .ht-modal-body 自身已 overflow-y:auto，配合 grid 1fr 自然滚
 * ---------------------------------------------------------- */
.ht-modal.ht-wp-modal .ht-modal-mask{
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.ht-modal.ht-wp-modal .ht-modal-box{
  width: 1024px; height: 630px;
  max-width: calc(100vw - 24px);
  max-height: calc(100vh - 24px);
  max-height: calc(100dvh - 24px);
}
.ht-modal.ht-wp-modal .ht-modal-foot{
  align-items: center;
  gap: 14px;
}
.ht-wp-effects{
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  color: #6b7280;
  font-size: 13px;
}
.ht-wp-effect-item{
  min-width: 0;
  display: grid;
  grid-template-columns: auto minmax(90px, 1fr) 44px;
  align-items: center;
  gap: 8px;
}
.ht-wp-effect-mask{ flex: 1 1 330px; }
.ht-wp-effect-blur{ flex: 0 1 230px; }
.ht-wp-effect-item span{ white-space: nowrap; }
.ht-wp-effect-item input[type="range"]{
  width: 100%;
  min-width: 0;
  accent-color: #3ba5ff;
}
.ht-wp-effect-item em{
  text-align: right;
  font-style: normal;
  color: #6b7280;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.ht-wp-effect-check{
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  color: #6b7280;
}
.ht-wp-effect-check input{ accent-color: #3ba5ff; }
.ht-wp-actions{
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-left: auto;
}
html[data-theme="dark"] .ht-wp-effects,
html[data-theme="auto"] .ht-wp-effects,
html[data-theme="dark"] .ht-wp-effect-item em,
html[data-theme="auto"] .ht-wp-effect-item em,
html[data-theme="dark"] .ht-wp-effect-check,
html[data-theme="auto"] .ht-wp-effect-check{ color: rgba(255,255,255,.68); }
@media (max-width: 760px){
  .ht-modal.ht-wp-modal .ht-modal-foot{
    align-items: stretch;
    flex-wrap: wrap;
  }
  .ht-wp-effects{
    flex-basis: 100%;
    flex-wrap: wrap;
  }
  .ht-wp-effect-mask,
  .ht-wp-effect-blur{ flex: 1 1 100%; }
  .ht-wp-actions{ width: 100%; }
}
/* 1024 宽下预设格子更宽松一点 */
.ht-modal.ht-wp-modal .ht-presets{
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
}
.ht-modal.ht-wp-modal .ht-preset{
  height: 80px;
}

/* 视觉上隐藏（保留可访问性 / DOM 节点） */
.ht-modal.ht-add-modal .sr-only{
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* head：左上角放 Tab，右上角放关闭按钮 */
.ht-add-head{
  gap: 12px;
  /* 复用 .ht-modal-head 自带的 padding/border-bottom */
}
.ht-add-head .ht-add-tabs{
  margin-right: auto;           /* 把关闭按钮顶到右边，自身保持自然宽度 */
}
.ht-add-head .ht-modal-close{
  flex: 0 0 auto;
  align-self: center;
}

/* body：固定高度下子项自滚 */
.ht-add-body{
  padding: 0;
  /* 滚动交给 .ht-add-pane.on 内部，body 自身不滚动，避免双重滚动条；
     这样\"取消/保存\"按钮（嵌在 pane 内的 .ht-pane-foot）可以用 position: sticky
     钉在 pane 底部，跟随 Tab 切换天然显隐，无需 JS 控制。 */
  overflow: hidden;
}

/* pane 容器：手动添加 pane 是\"字段区 + 底部按钮区\"两段，
 * 用 flex 列布局让 .ht-pane-foot 永远可见在 pane 底部；
 * 滚动发生在 pane 内部（而非 .ht-add-body 上），因此 pane 自身要 overflow: auto。 */
.ht-add-pane{ display: none; }
.ht-add-pane.on{
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: auto;
  padding: 16px 18px 0;
}
/* 字段区：占据 pane 剩余高度，避免按钮被字段挤到看不见的位置。
 * 注：字段没有专门容器，通过\"除最后一个 .ht-pane-foot 外\"的伪选择不好做，
 *     这里直接给 pane 设 flex:1 不必要 —— pane 自身可滚就够，
 *     .ht-pane-foot 用 sticky 钉到 pane 底部，无论 pane 内容多长，按钮始终在视野内。 */
/* 卡片组件 pane 内不需要按钮区，结构略有差异：保持原有 flex 列布局即可 */

/* pane 内嵌的取消/保存按钮区：
 * · 视觉上和原公共 .ht-modal-foot 完全一致；
 * · 通过 position: sticky 钉在 pane 底部（即 box 底部），无论字段多长都看得见；
 * · 仅出现在「手动添加」pane，组件 pane 没有这个元素 → 切 Tab 自动显隐，无需 JS。 */
.ht-pane-foot{
  position: sticky; bottom: 0;
  margin: 16px -18px 0;
  padding: 0 18px; background: #fff;
  border-top: 1px solid rgba(0,0,0,.06);
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  /* 固定 60px 高度：sticky 钉底时占位稳定，按钮垂直居中，不再受按钮自身高度/内边距影响 */
  height: 60px;
  flex: 0 0 60px;
  box-sizing: border-box;
}
html[data-theme="dark"] .ht-pane-foot,
html[data-theme="auto"] .ht-pane-foot{
  background: #2a2d3a;
  border-top-color: rgba(255,255,255,.08);
}

/* head 内的 Tab 容器：横排胶囊风格 */
.ht-add-tabs{
  display: flex; flex-direction: row; gap: 4px;
  background: rgba(0,0,0,.04); padding: 4px; border-radius: 10px;
  margin: 0;
}
html[data-theme="dark"] .ht-add-tabs,
html[data-theme="auto"] .ht-add-tabs{ background: rgba(255,255,255,.06); }

.ht-add-tab{
  position: relative;
  padding: 6px 16px; border: none; background: transparent;
  border-radius: 7px; cursor: pointer; color: #64748b;
  font-size: 13px; font-weight: 500; text-align: center;
  transition: background-color .15s, color .15s, box-shadow .15s;
}
.ht-add-tab:hover{ color: #1f2937; }
html[data-theme="dark"] .ht-add-tab:hover,
html[data-theme="auto"] .ht-add-tab:hover{ color: #e5e7eb; }
.ht-add-tab.on{
  background: #fff; color: #1f2937;
  box-shadow: 0 1px 3px rgba(0,0,0,.1);
}
html[data-theme="dark"] .ht-add-tab.on,
html[data-theme="auto"] .ht-add-tab.on{
  background: #3b3f52; color: #e5e7eb;
}

/* .ht-add-pane / .ht-add-pane.on 的 display 规则已统一在上方
 * （flex 列 + sticky 底部按钮区），此处不再重复定义，避免覆盖。 */

/* ---------- 「手动添加」pane 的左右分栏布局 ----------
 * 结构：
 *   .ht-add-pane[data-add-pane="manual"].on
 *     ├ .ht-add-split          ← 左右两栏容器
 *     │    ├ .ht-add-form      ← 左：所有字段（独立滚动）
 *     │    └ .ht-add-side      ← 右：实时预览卡（sticky 居中）
 *     └ .ht-pane-foot          ← 底：横跨两栏的 sticky 按钮区
 * 设计目的：
 *   - 1024 宽下尽量一屏看完所有字段，不再下拉滚很久才看到"保存"；
 *   - 预览不参与表单流，更直观看到 cardBg / iconFill / size 等视觉字段；
 *   - 右栏 sticky 居中：表单滚动时预览始终可见。
 * 窄屏（<860px）退化为上下单栏，预览自动放到字段下方。
 */
.ht-add-split{
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: 20px;
  align-items: stretch;
  /* 在 .ht-add-pane（flex 列容器）里吃掉剩余空间，
     让 .ht-pane-foot 始终贴 pane 底部，而不是被字段顶上去 */
  flex: 1;
  min-height: 0;
}
.ht-add-form{
  min-width: 0;        /* 允许 grid 子项收缩，避免长 URL/placeholder 撑爆 */
}
.ht-add-form > .ht-field:last-child{ margin-bottom: 0; }

.ht-add-side{
  position: sticky;
  top: 0;
  /* 由 .ht-add-split 的 align-items:stretch 决定高度：右栏卡槽撑满整个 split 高度，
     预览在内部垂直居中；不再用 align-self:start，避免和 stretch 冲突。 */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 12px;
  border-radius: 12px;
  background: rgba(0,0,0,.025);
  /* 卡槽最小高度：极少字段时也保留预览存在感 */
  min-height: 280px;
  /* sticky 元素若高于滚动容器视口，将无法完整显示 → 限制在 pane 视口内并允许内部滚动 */
  max-height: calc(100% - 8px);
  overflow: auto;
}
html[data-theme="dark"] .ht-add-side,
html[data-theme="auto"] .ht-add-side{
  background: rgba(255,255,255,.04);
}
.ht-add-side-label{
  font-size: 12px;
  color: #64748b;
  font-weight: 500;
  letter-spacing: .3px;
}
html[data-theme="dark"] .ht-add-side-label,
html[data-theme="auto"] .ht-add-side-label{ color: #9ca3af; }
.ht-add-side-hint{
  font-size: 11px;
  color: #94a3b8;
  text-align: center;
}

/* 左右布局下，预览容器仍按 data-size 取尺寸；这里仅去掉 flex 模式下的兜底顶部边距 */
.ht-add-side > .ht-card-preview-host{
  margin: 0;
}

/* 窄屏：退化成上下单栏（预览置底），保持原单列体验 */
@media (max-width: 860px){
  .ht-add-split{
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .ht-add-side{
    position: static;
    min-height: 0;
    padding: 12px;
  }
}

/* 窄屏兜底：视口不足 1024×630 时，弹窗自动适配（max-* 已生效），
 * 这里只对极窄屏（<560px）调整 head 的 padding 与 tab 字号，避免溢出 */
@media (max-width: 560px){
  .ht-add-head{ gap: 8px; padding: 10px 12px; }
  .ht-add-tab{ padding: 6px 10px; font-size: 12px; }
  .ht-add-pane.on{ padding: 14px 14px 0; }
  .ht-pane-foot{ margin: 14px -14px 0; padding: 0 14px; }
}

/* 卡片组件库：两列网格 + 真实组件预览
 * --------------------------------------------------------------
 * 布局：固定两列（含 1 列窄屏退化），每格内部 = "组件真实预览 + 元信息"。
 * 真实预览：复用首页 .halotab-grid 渲染管线，但用更小的 cell 尺寸。 */
.ht-widget-grid{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
/* 窄屏：两列下每格宽度不足以放下 4×2 预览（min-width: 400px + padding），
 * 退化为单列以保证 4×2 卡片完整可见。阈值经测算：
 *   两列每格内可用宽 ≈ (modal_width - 36padding - 16scrollbar - 12gap)/2 - 24item_padding
 *   要 ≥ 400 + 16(preview padding) = 416 → 模态宽 ≥ ~960px。 */
@media (max-width: 960px){
  .ht-widget-grid{ grid-template-columns: 1fr; }
}
.ht-widget-item{
  display: flex; flex-direction: column; gap: 10px;
  padding: 12px;
  background: rgba(0,0,0,.03);
  border: 1px solid rgba(0,0,0,.08);
  border-radius: 12px;
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .15s, box-shadow .2s;
  text-align: left;
  -webkit-user-select: none; user-select: none;
}
.ht-widget-item:hover{
  background: rgba(var(--ht-accent-rgb,59,165,255),.08);
  border-color: var(--ht-accent, #3ba5ff);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(var(--ht-accent-rgb,59,165,255),.18);
}
html[data-theme="dark"] .ht-widget-item,
html[data-theme="auto"] .ht-widget-item{
  background: rgba(255,255,255,.04);
  border-color: rgba(255,255,255,.1);
  color: #e5e7eb;
}

/* —— 预览容器 —— */
.ht-widget-preview{
  /* 横向居中放置 mini grid；预览块不参与点击穿透（由 .ht-widget-item 整体接管 click） */
  display: flex;
  align-items: center; justify-content: center;
  padding: 14px 8px;
  border-radius: 10px;
  background:
    radial-gradient(circle at 30% 20%, rgba(var(--ht-accent-rgb,59,165,255),.10), transparent 60%),
    linear-gradient(180deg, rgba(0,0,0,.02), rgba(0,0,0,.04));
  /* 4×2 widget 是 mini grid 中最宽的形态（与桌面 1:1）：4*80 + 3*16 = 368px。
   * 预览容器最小宽度 = 368 + 内边距(16) + 16px 余量 = 400px，
   * 确保所有窗口下都能完整放下且不被裁切；外层 .ht-widget-item / .ht-widget-grid 会随之撑开。 */
  min-width: 400px;
  min-height: 120px;
  /* 兜底：理论不可能溢出，但万一外层被压缩，至少保证不破坏布局。 */
  overflow: hidden;
}
html[data-theme="dark"] .ht-widget-preview,
html[data-theme="auto"] .ht-widget-preview{
  background:
    radial-gradient(circle at 30% 20%, rgba(var(--ht-accent-rgb,59,165,255),.18), transparent 60%),
    linear-gradient(180deg, rgba(255,255,255,.02), rgba(255,255,255,.04));
}

/* —— mini grid：复用首页 .halotab-grid 全部规则，仅覆盖列数 + 行高 ——
 * --ht-cols 由 JS 按 widget 自身宽度注入（1×1 → 1 列、4×2 → 4 列等），
 * 让卡片永远等宽于 mini grid，外层 flex 再做居中，避免小尺寸卡偏左上。
 *
 * 尺寸 1:1 复用桌面真实尺寸（不缩放），所见即所得：
 *   桌面 cell-h 110 = 图标区 80 + 标题区 30；预览态隐藏标题，cell-h 减 30 → 80
 *   cell 80×80  col-gap 16  row-gap 4
 *   4×2 = 4*80 + 3*16 × 2*80 + 1*4 = 368 × 164
 *   2×2 = 2*80 + 1*16 × 2*80 + 1*4 = 176 × 164
 *   1×1 = 80 × 80
 *
 * 注意：layoutGrids() 已显式跳过 .ht-widget-preview-grid，避免被回写覆盖。 */
.ht-widget-preview-grid{
  --ht-cell-w: 80px !important;
  --ht-cell-h: 80px !important;
  --ht-cell-gap: 16px !important;
  --ht-row-gap: 4px !important;
  /* mini grid 在预览块里居中显示，不需要撑满 */
  width: auto;
  margin: 0 auto;
  /* 覆盖 .halotab-page-group .halotab-grid 的 flex:1 1 auto，避免被父级拉伸 */
  flex: none;
}
/* 预览态卡片：禁止 hover 浮起 / 禁止指针手势影响整块 .ht-widget-item 的命中
 * 注意：JS 已把 realCard.style.pointerEvents = 'none'，这里再做样式兜底。 */
.ht-widget-preview-grid .halotab-card{
  pointer-events: none;
}
.ht-widget-preview-grid .halotab-card:hover{ transform: none; }
/* widget mini grid 用的是 cell-h=80（标题被隐藏），跟首页那条
   .halotab-card[data-size="2x2"]{ height:206px } 不兼容，这里恢复成
   跟随 grid 行轨道高度（80×2 + 4 = 164），保持 1:1 复用桌面尺寸的规则。 */
.ht-widget-preview-grid .halotab-card[data-size="2x2"]{
  align-self: stretch;
  height: auto;
}
/* 预览态隐藏卡片自身的标题：外层 .ht-widget-meta 已展示标题/描述/尺寸，
 * 卡片内部只保留 icon 视觉部分，避免重复且让 icon 占满空间。 */
.ht-widget-preview-grid .halotab-card-title{ display: none; }

/* —— 元信息 —— */
.ht-widget-meta{
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
}
.ht-widget-title{
  font-size: 14px; font-weight: 600; color: #1f2937;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html[data-theme="dark"] .ht-widget-title,
html[data-theme="auto"] .ht-widget-title{ color: #e5e7eb; }
.ht-widget-desc{
  font-size: 12px; color: #64748b;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ht-widget-size{
  font-size: 11px; color: #94a3b8; margin-top: 2px;
}
/* 兜底：fillWidgets 渲染失败时仍会用到的小图标块 */
.ht-widget-icon{
  flex: 0 0 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  font-size: 22px;
  color: #fff;
}

/* ============================================================
 *  卡片组件渲染（首页 grid 中的 widget 卡片）
 *
 *  布局规则：widget 卡片复用 .halotab-card 的"图标区 + 标题区"骨架，
 *  其中 widget 自渲染的内容塞进 .halotab-card-widget-icon（图标区槽位），
 *  下方 .halotab-card-body 保持 30px 标题区。这样：
 *    - 不同 data-size 卡片大小计算规则与普通卡完全一致；
 *    - widget 卡片始终显示标题，不会被 widget 内容吃掉。
 *  widget 自身的容器（.halotab-widget）只需要 height:100% 即可
 *  自然适配"图标区"的高度（卡高 - 20）。
 * ============================================================ */
.halotab-card.is-widget{
  background: transparent;        /* widget 卡片整体透明，背景由 widget 自己提供 */
  color: #1f2937;
}
html[data-theme="dark"] .halotab-card.is-widget,
html[data-theme="auto"] .halotab-card.is-widget{
  color: #e5e7eb;
}
/* widget 用图标槽位：与 .halotab-card-icon 共享尺寸/裁剪，但不带白底 + 阴影
 * （widget 通常自带主题背景，避免双重背景透出边缘）*/
.halotab-card-widget-icon{
  background: rgba(255,255,255,.92);
  box-shadow: 0 1px 3px rgba(0,0,0,.12);
}
html[data-theme="dark"] .halotab-card-widget-icon,
html[data-theme="auto"] .halotab-card-widget-icon{
  background: rgba(40,42,54,.85);
}

/* ----------------------------------------------------------
 * 1×1 widget 卡片：居中 48×48 功能图标 + 复用 2×2/4×2 卡的彩色背景
 *
 * 思路：mini 容器同时挂上 widget 根类名（halotab-widget-todo / -note / -cd /
 * -calendar / -weather / -tools），让各 widget 自己写好的彩色渐变背景 +
 * 暗色覆盖 + :has() 透明槽位等规则**自动生效**，从而 1×1 的卡片背景与
 * 2×2 / 4×2 完全同源（颜色一改全改）。
 *
 * .halotab-widget-mini 是布局重置标记：
 *   - 把各 widget 自带的 grid/padding/text-align 等内容布局清掉
 *   - 把容器撑满整个槽位（露出 widget 根类上的彩色背景）
 *   - 图标本体（svg/text）以 48×48 居中
 * 所有 reset 都用 !important，因为各 widget 根选择器优先级跟我们一样，
 * 但它们靠"后写后赢"在卡里生效，mini 这条更晚加载也能压过。
 * ---------------------------------------------------------- */
.halotab-card-widget-mini{
  /* 槽位让位给内层 widget 自带背景（透明 + 无阴影），与 :has() 规则保持一致 */
  background: transparent !important;
  box-shadow: none !important;
}
.halotab-widget-mini{
  /* 充满整个 1×1 卡的 icon 槽位，复用 widget 根类自带的彩色背景 */
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 100% !important;
  height: 100% !important;
  /* 清掉各 widget 根上可能存在的 grid 列定义、padding、gap 等 */
  grid-template-columns: none !important;
  grid-template-rows: none !important;
  gap: 0 !important;
  padding: 0 !important;
  text-align: center !important;
  /* 鼠标在卡上 = 可点击进入详情 */
  cursor: pointer;
  box-sizing: border-box;
}
/* 图标本体：48×48 居中 */
.halotab-widget-mini-svg,
.halotab-widget-mini-text{
  position: relative;       /* 盖在各 widget 装饰层之上 */
  z-index: 1;
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--mini-color, currentColor);
  line-height: 1;
  flex: 0 0 auto;
}
.halotab-widget-mini-svg svg{
  width: 100%;
  height: 100%;
  display: block;
}
.halotab-widget-mini-text{
  font-size: 28px;
  font-weight: 700;
}

/* ----------------------------------------------------------
 * 1×1 mini 卡片各 widget 的背景（与 2×2/4×2 卡颜色完全一致）
 *
 * 说明：todo / note / countdown 各自的根类 .halotab-widget-<id> 已经
 * 自带彩色渐变 background，所以 mini 直接复用即可；但 weather 的彩色
 * 渐变是写在 `.weather-app` 子元素上的（mini 不渲染那个子元素），
 * calendar 的颜色写在 `.halotab-widget-calendar-card` 上。这两个需要
 * 在 mini 状态下补一条同色渐变，与 4×2 卡片视觉一致。
 * 颜色与各 widget index.css 保持同步，改卡片色也请改这里。
 * ---------------------------------------------------------- */
.halotab-widget-weather.halotab-widget-mini{
  background: linear-gradient(to right top, #C5E5FE, #F7EEDA, #FBDBD9) !important;
  color: #1f2937;
}
html[data-theme="dark"] .halotab-widget-weather.halotab-widget-mini,
html[data-theme="auto"] .halotab-widget-weather.halotab-widget-mini{
  background: linear-gradient(to right top, #1f2a44, #2a2547, #3a2a4a) !important;
  color: #e6ecf7;
}
.halotab-widget-calendar.halotab-widget-mini{
  background: linear-gradient(to right top, #f5f3ff, #ede9fe, #ddd6fe) !important;
  color: #2b3138;
}
.halotab-widget{
  display: flex; flex-direction: column; align-items: stretch;
  width: 100%; height: 100%;
  box-sizing: border-box;
  overflow: hidden;
}

/* 搜索框 / 时钟组件样式已迁移到各组件目录：
 *   script/widgets/search/index.css
 *   script/widgets/clock/index.css
 * 由宿主自动注入，无需在此重复定义。
 */

/* 占位骨架（countdown / note / todo 等"待实现"组件统一用这套样式） */
.halotab-widget-stub{
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  width: 100%; height: 100%;
  gap: 6px; padding: 6px;
  text-align: center;
}
.halotab-widget-stub-icon{
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 10px;
  color: #fff; font-size: 20px;
}
.halotab-widget-stub-title{
  font-size: 13px; font-weight: 600;
}
.halotab-widget-stub-tip{
  font-size: 11px; opacity: .7;
}

/* 其它 widget 占位（兜底渲染） */
.halotab-widget-placeholder{
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  width: 100%; height: 100%;
  gap: 6px;
}
.halotab-widget-ph-icon{
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 10px;
  color: #fff; font-size: 22px;
}
.halotab-widget-ph-title{
  font-size: 13px; font-weight: 600;
}
.halotab-widget-ph-desc{
  font-size: 11px; opacity: .7;
}
