@charset "UTF-8";

:root {
  color-scheme: light;
  /* 内容列宽:头部/主容器/页脚共用,手机端在 600px 断点只改这一个变量 */
  --container-w: min(1120px, calc(100% - 48px));
  --bg: #f0f3f7;
  --surface: #f0f3f7; /* 拟态前提:表面与背景同色,阴影才能无缝融合 */
  --surface-raised: #f0f3f7; /* 拟态下与背景同色 */
  --text: #182230;
  /* 次级文字对 --bg 的对比度需 ≥ 4.5:1(WCAG AA),#5c6a80 ≈ 4.93:1 */
  --text-secondary: #5c6a80;
  --border: #e4e7ec;
  --border-soft: color-mix(in srgb, var(--border) 30%, transparent);
  --accent: #5b64f0;
  --accent-hover: #4952e4;
  --accent-soft: #eef0fe; /* 预留:软强调背景,当前未使用 */
  --brand-gradient: linear-gradient(135deg, #4e7cf6, #8b5cf6);
  --control: rgba(240, 243, 247, 0.86);
  --shadow: 0 12px 32px rgba(16, 24, 40, 0.07);
  /* 轻拟态双阴影:浅色光从左上来,深色影向右下去 */
  --neu-light: rgba(255, 255, 255, 0.9);
  --neu-dark: rgba(163, 177, 198, 0.5);
  --neu-raised: 5px 5px 12px var(--neu-dark), -5px -5px 12px var(--neu-light);
  --neu-raised-lg: 8px 8px 18px var(--neu-dark), -8px -8px 18px var(--neu-light);
  --neu-raised-sm: 3px 3px 7px var(--neu-dark), -3px -3px 7px var(--neu-light);
  --neu-inset: inset 3px 3px 7px var(--neu-dark), inset -3px -3px 7px var(--neu-light);
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #1d222b;
  --surface: #1d222b; /* 拟态前提:表面与背景同色,阴影才能无缝融合 */
  --surface-raised: #1d222b; /* 拟态下与背景同色 */
  --text: #edf1f7;
  --text-secondary: #9aa6b5;
  --border: #2b333e;
  --accent: #8b93f8;
  --accent-hover: #a6acfa;
  --accent-soft: #262a4d; /* 预留:软强调背景,当前未使用 */
  --brand-gradient: linear-gradient(135deg, #5d86f7, #9a70f7);
  --control: rgba(29, 34, 43, 0.86);
  --shadow: 0 12px 32px rgba(0, 0, 0, 0.2);
  /* 轻拟态双阴影:微弱高光 + 深色投影,在暗色上拉开凹凸。
     几何参数与亮色完全一致,只需覆盖两个原子色,派生阴影令牌自动继承。 */
  --neu-light: rgba(255, 255, 255, 0.05);
  --neu-dark: rgba(0, 0, 0, 0.55);
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-width: 320px;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  /* 全面屏(viewport-fit=cover)下让内容避开刘海与底部横条;无 cover 的环境 env() 恒为 0 */
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  background: var(--bg);
  color: var(--text);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background-color 200ms ease, color 200ms ease;
}

main {
  flex: 1 0 auto;
}

button,
input {
  font: inherit;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

button {
  color: inherit;
}

a {
  color: inherit;
  text-decoration: none;
}

svg {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.8;
}

[hidden] {
  display: none !important;
}

.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;
}

.skip-link {
  position: fixed;
  top: calc(12px + env(safe-area-inset-top));
  left: calc(12px + env(safe-area-inset-left));
  z-index: 100;
  padding: 10px 16px;
  border-radius: 8px;
  background: var(--text);
  color: var(--bg);
  transform: translateY(-150%);
}

.skip-link:focus {
  transform: translateY(0);
}

.brand {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.brand-mark {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 28%, transparent);
  transition: transform 180ms ease, box-shadow 180ms ease;
}

.brand-name-sub {
  font-weight: 500;
  color: var(--text-secondary);
}

.theme-toggle {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: var(--neu-raised-sm);
  color: var(--text-secondary);
  cursor: pointer;
  transition: box-shadow 160ms ease, color 160ms ease;
}

.theme-toggle svg {
  width: 18px;
  height: 18px;
}

.moon-icon,
:root[data-theme="dark"] .sun-icon {
  display: none;
}

:root[data-theme="dark"] .moon-icon {
  display: block;
}

.container {
  width: var(--container-w);
  margin: 0 auto;
}

.controls {
  position: sticky;
  top: 0;
  z-index: 10;
  padding: 10px 0 0;
  background: var(--control);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

/* 吸顶后补状态栏安全区;未吸顶时由 body 的安全区 padding 负责,避免双重间距 */
.controls.is-stuck {
  padding-top: calc(10px + env(safe-area-inset-top));
}

.search-row {
  display: flex;
  align-items: center;
  gap: 14px;
}

/* 品牌与主题切换并入搜索行:吸顶后整行常驻,不再需要迷你品牌入口 */

.search-box {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
}

.search-box > svg {
  position: absolute;
  left: 16px;
  width: 20px;
  height: 20px;
  color: var(--text-secondary);
  pointer-events: none;
}

.search-box input {
  width: 100%;
  height: 48px;
  padding: 0 52px 0 48px;
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  outline: none;
  background: var(--surface);
  box-shadow: var(--neu-inset);
  color: var(--text);
  font-size: 16px;
  transition: border-color 160ms ease, box-shadow 200ms ease;
}

.search-box input::placeholder {
  color: var(--text-secondary);
}

/* 隐藏 WebKit 原生搜索清除按钮,避免与自定义 .search-clear 双 X 并存 */
.search-box input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

.search-box input:focus {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  box-shadow: var(--neu-inset), 0 0 0 4px color-mix(in srgb, var(--accent) 13%, transparent);
}

.search-shortcut {
  position: absolute;
  right: 12px;
  min-width: 26px;
  height: 26px;
  padding: 0 7px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 7px;
  background: var(--bg);
  box-shadow: var(--neu-raised-sm);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 12px;
  pointer-events: none;
}

.search-box input:focus ~ .search-shortcut,
.search-box input:not(:placeholder-shown) ~ .search-shortcut {
  display: none;
}

.category-list {
  position: relative;
  display: flex;
  gap: 8px;
  /* 出血位:滚动容器(overflow-x:auto)会连带裁切纵向,激活药丸的拟态阴影
     需要约 10px 外溢空间;用负外边距补偿,视觉间距与裁切前保持一致 */
  padding: 12px 14px;
  margin: 2px -14px -12px;
  overflow-x: auto;
  scrollbar-width: none;
}

.category-list::-webkit-scrollbar {
  display: none;
}

.category-list.has-overflow {
  mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent);
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent);
}

.category-button {
  position: relative;
  flex: 0 0 auto;
  min-height: 38px;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 14px;
  cursor: pointer;
  transition: color 160ms ease, background 160ms ease, box-shadow 160ms ease;
}

/* 热区竖向垫到 44px;横向不外扩,避免与相邻分类重叠 */
.category-button::after {
  content: '';
  position: absolute;
  top: -4px;
  bottom: -4px;
  left: 0;
  right: 0;
}

/* 激活分类凸起成药丸,替代原渐变下划线 */
.category-button[aria-pressed="true"] {
  background: var(--surface);
  box-shadow: var(--neu-raised-sm);
  color: var(--accent);
  font-weight: 600;
}

.results-meta {
  min-height: 58px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 2px 0;
  color: var(--text-secondary);
  font-size: 13px;
}

.results-meta p {
  margin: 0;
}

.text-button {
  padding: 12px 0 12px 12px;
  border: 0;
  background: transparent;
  color: var(--accent);
  font-size: 13px;
  cursor: pointer;
}

.site-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

.site-card {
  position: relative;
  min-width: 0;
  border: 1px solid color-mix(in srgb, var(--border) 45%, transparent);
  border-radius: 14px;
  background: var(--surface);
  box-shadow: var(--neu-raised);
  cursor: pointer;
  transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}

.site-card:focus-within {
  border-color: var(--accent);
}

.card-link {
  height: 100%;
  display: flex;
  gap: 12px;
  padding: 16px;
  border-radius: inherit;
}

.site-avatar {
  position: relative;
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--neu-inset);
}

.site-favicon {
  width: 22px;
  height: 22px;
  object-fit: contain;
}

.site-content {
  min-width: 0;
  flex: 1;
  display: block;
}

.site-name-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.site-name {
  overflow: hidden;
  padding-right: 36px;
  font-size: 15px;
  font-weight: 650;
  line-height: 1.4;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.site-description {
  display: block;
  margin-top: 5px;
  overflow: hidden;
  color: var(--text-secondary);
  font-size: 13px;
  line-height: 1.5;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.copy-button {
  position: absolute;
  right: 12px;
  top: 12px;
  z-index: 2;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: var(--surface);
  box-shadow: var(--neu-raised-sm);
  color: var(--text-secondary);
  cursor: pointer;
  transition: opacity 180ms ease, transform 180ms ease, box-shadow 180ms ease, background 180ms ease, color 180ms ease;
}

/* 视觉 28px,热区外扩到 44px,方便手指点按 */
.copy-button::after {
  content: '';
  position: absolute;
  inset: -8px;
}

/* 键盘聚焦时始终亮出复制按钮(触屏无 hover,依赖此规则可达) */
.site-card:focus-within .copy-button,
.copy-button:focus-visible {
  opacity: 1;
  transform: translateY(0);
}

.copy-button svg {
  grid-area: 1 / 1;
  width: 16px;
  height: 16px;
}

.check-icon {
  display: none;
}

.empty-state {
  padding: 80px 24px;
  border: 0;
  border-radius: 14px;
  box-shadow: var(--neu-inset);
  text-align: center;
}

.empty-icon {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  margin: 0 auto 18px;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-secondary);
}

.empty-icon svg {
  width: 22px;
  height: 22px;
}

.empty-state h2 {
  margin: 0;
  font-size: 18px;
}

.empty-state p {
  margin: 10px 0 24px;
  color: var(--text-secondary);
  font-size: 14px;
}

.primary-button {
  min-height: 42px;
  padding: 10px 18px;
  border: 0;
  border-radius: 9px;
  background: var(--accent);
  color: white;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  /* 强调色实心按钮只保留右下投影,左上高光对深色填充无意义 */
  box-shadow: 4px 4px 10px var(--neu-dark);
}

:root[data-theme="dark"] .primary-button {
  color: #101318;
}

.site-footer {
  width: var(--container-w);
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin: 48px auto 0;
  padding: 28px 0 36px;
  border-top: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: 12px;
}

.site-footer p {
  margin: 0;
}

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

/* 断点按卡片可读宽度推算:横向卡片放全名称约需 230px 卡宽,
   对应 4 列 ≥1000px、3 列 760-1000、2 列 520-760、手机单列。 */
@media (max-width: 1000px) {
  .site-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 760px) {
  .site-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* 手机宽度降为单列:横向卡片有全宽可用,名称与描述不再被截成两三个字。 */
@media (max-width: 520px) {
  .site-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition: none !important;
    animation: none !important;
  }

  /* 伪元素不受上面的 * 规则约束，需单独关闭视图过渡动画 */
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none;
  }
}

/* ============ 交互升级（2026-11-01） ============ */

/* 搜索命中高亮 */
mark {
  padding: 0 1px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  color: inherit;
}

/* favicon 加载失败：降级为首字符头像 */
.site-fallback {
  display: none;
  width: 100%;
  height: 100%;
  place-items: center;
  background: var(--bg);
  color: var(--text-secondary);
  font-size: 15px;
  font-weight: 700;
}

.site-avatar[data-fallback="true"] .site-favicon {
  display: none;
}

.site-avatar[data-fallback="true"] .site-fallback {
  display: grid;
}

/* 最近访问角标 */
.recent-dot {
  position: absolute;
  top: -3px;
  right: -3px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--surface);
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 160ms ease, transform 160ms ease;
}

.site-avatar[data-recent="true"] .recent-dot {
  opacity: 1;
  transform: scale(1);
}

/* 搜索框一键清除 */
.search-clear {
  position: absolute;
  right: 8px;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 160ms ease, color 160ms ease;
}

/* 热区外扩到 48px */
.search-clear::after {
  content: '';
  position: absolute;
  inset: -10px;
}

.search-clear svg {
  width: 14px;
  height: 14px;
  stroke-width: 2.2;
}

/* 卡片入场动画（仅切换分类 / 重置时触发） */
@keyframes card-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.site-grid[data-animate="true"] .site-card {
  animation: card-in 260ms cubic-bezier(0.22, 1, 0.36, 1) var(--delay, 0ms) backwards;
}

/* 按压反馈:拟态下按下去即凹陷 */
.site-card:active {
  transform: scale(0.985);
  box-shadow: var(--neu-inset);
}

/* 全局轻提示 */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(28px + env(safe-area-inset-bottom));
  z-index: 60;
  padding: 10px 18px;
  border-radius: 10px;
  background: var(--text);
  color: var(--bg);
  font-size: 13px;
  font-weight: 500;
  box-shadow: var(--shadow);
  transform: translate(-50%, 8px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 180ms ease, transform 180ms ease, visibility 180ms;
}

.toast[data-visible="true"] {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
}

/* 回到顶部 */
.back-to-top {
  position: fixed;
  right: calc(24px + env(safe-area-inset-right));
  bottom: calc(24px + env(safe-area-inset-bottom));
  z-index: 55;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-secondary);
  box-shadow: var(--neu-raised);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity 180ms ease, transform 180ms ease, visibility 180ms, box-shadow 160ms ease, color 160ms ease;
}

.back-to-top.is-visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.back-to-top svg {
  width: 18px;
  height: 18px;
}

/* 主题切换视图过渡（渐进增强） */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 200ms;
}

/* 快照拍摄期间禁用元素级过渡，保证新旧快照各自为纯净主题（否则新快照会拍到过渡起点的旧配色，
   与已瞬间翻转的背景类属性混杂交错淡化，产生块状痕迹） */
:root[data-theme-switching] *,
:root[data-theme-switching] *::before,
:root[data-theme-switching] *::after {
  transition: none !important;
}

/* 手机端覆盖统一收拢于此,且位于全部基准规则之后,保证同优先级覆盖生效 */
@media (max-width: 600px) {
  /* 小屏收敛拟态阴影:凹凸更精细,绘制成本更低;亮暗主题自动继承(--neu-dark/light 不变) */
  :root {
    --neu-raised: 4px 4px 9px var(--neu-dark), -4px -4px 9px var(--neu-light);
    --neu-raised-lg: 6px 6px 13px var(--neu-dark), -6px -6px 13px var(--neu-light);
    --neu-raised-sm: 2px 2px 5px var(--neu-dark), -2px -2px 5px var(--neu-light);
    --neu-inset: inset 2px 2px 5px var(--neu-dark), inset -2px -2px 5px var(--neu-light);
    --container-w: min(100% - 32px, 1120px);
  }

  .container,
  .site-footer {
    width: var(--container-w);
  }

  .controls {
    padding-top: 6px;
  }

  .controls.is-stuck {
    padding-top: calc(6px + env(safe-area-inset-top));
  }

  .search-box input {
    border-radius: 12px;
  }

  .search-shortcut {
    display: none;
  }

  .category-list {
    /* 基准出血位 padding-top 12px 不变,净间距 10px */
    margin-top: -2px;
  }

  .category-button {
    min-height: 36px;
    padding: 7px 8px;
    font-size: 13px;
  }

  .copy-button {
    right: 8px;
    top: 8px;
  }

  .site-footer {
    margin-top: 40px;
    flex-direction: column;
    gap: 8px;
  }

  .toast {
    bottom: calc(20px + env(safe-area-inset-bottom));
  }

  .back-to-top {
    right: calc(16px + env(safe-area-inset-right));
    bottom: calc(16px + env(safe-area-inset-bottom));
  }
}

/* 手机横握的矮视口:压缩纵向空间,保证首屏能看到首行卡片 */
@media (max-height: 480px) and (orientation: landscape) {
  .controls {
    padding-top: 8px;
  }

  .search-box input {
    height: 44px;
  }

  .category-list {
    /* 基准出血位 padding-top 12px 不变,净间距 8px */
    margin-top: -4px;
  }

  .empty-state {
    padding: 32px 24px;
  }
}

/* ============ 拖拽排序 ============ */
.site-grid.is-orderable .site-card {
  cursor: grab;
  -webkit-touch-callout: none;
}

.site-grid.is-orderable .card-link {
  -webkit-user-select: none;
  user-select: none;
}

/* 拖拽进行中:被拖卡片浮起,兄弟卡片只保留 FLIP 位移过渡 */
.site-grid.is-ordering .site-card {
  transition-property: transform;
}

.site-grid.is-ordering .site-card:not(.is-dragging) {
  pointer-events: none;
}

.site-card.is-dragging {
  position: relative;
  z-index: 5;
  cursor: grabbing;
  box-shadow: var(--shadow);
  transition: none;
}

/* ============ 悬停反馈(仅精确指针) ============ */
/* 触屏设备没有 hover,悬停样式限定在鼠标环境,避免点击后状态残留;
   复制按钮在触屏上因此常显,桌面端保留悬停浮现。 */
@media (hover: hover) and (pointer: fine) {
  .copy-button {
    opacity: 0;
    transform: translateY(2px);
  }

  .site-card:hover .copy-button {
    opacity: 1;
    transform: translateY(0);
  }

  .copy-button:hover {
    box-shadow: var(--neu-raised);
    background: var(--bg);
    color: var(--text);
  }

  .site-card:hover {
    transform: translateY(-2px);
    border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
    box-shadow: var(--neu-raised-lg);
  }

  .brand:hover .brand-mark {
    transform: scale(1.06);
    box-shadow: 0 4px 12px color-mix(in srgb, var(--accent) 35%, transparent);
  }

  .theme-toggle:hover {
    color: var(--text);
  }

  .category-button:hover {
    color: var(--text);
  }

  .text-button:hover {
    color: var(--accent-hover);
  }

  .search-clear:hover {
    background: var(--surface);
    color: var(--text);
  }

  .primary-button:hover {
    background: var(--accent-hover);
  }

  .back-to-top:hover {
    color: var(--text);
  }
}

/* 复制成功的状态指示优先于悬停样式 */
.copy-button[data-copied="true"] {
  box-shadow: var(--neu-raised-sm), 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
  color: var(--accent);
}

.copy-button[data-copied="true"] .copy-icon {
  display: none;
}

.copy-button[data-copied="true"] .check-icon {
  display: block;
}
