/*
 * 液态玻璃设计系统 · 门户与管理后台共用
 *
 * 这里只放「材质」：设计令牌、玻璃配方、背景板与高光。布局与组件样式
 * 留在各自页面（public/index.html、public/admin/admin.css）。
 *
 * 关键约束：玻璃必须能透出背后的网格细节。若填充太实，面板会退化成磨砂
 * 塑料；因此填充保持低不透明度，边框推到接近纯白——边缘才是这个物体的
 * 全部轮廓。
 */

:root {
  color-scheme: light;
  --bg: #f5f6f3;
  --surface: #ffffff;
  --surface-subtle: #eff2ec;
  --border: #dfe4da;
  --border-hover: #c2ccb9;
  --text: #141712;
  --text-secondary: #4a5246;
  --text-muted: #717b6a;

  --brand-green: #4b7f2b;
  --brand-green-soft: rgba(75, 127, 43, 0.1);
  --brand-green-border: rgba(75, 127, 43, 0.24);
  --primary: #141712;
  --primary-fg: #ffffff;

  --status-online: #4b7f2b;
  --status-maint: #d97706;
  --status-offline: #dc2626;
  --danger: #dc2626;

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-lg: 22px;
  --shadow-card: 0 10px 30px -10px rgba(20, 23, 18, 0.06), 0 1px 3px rgba(20, 23, 18, 0.04);
  --shadow-modal: 0 24px 60px -12px rgba(20, 23, 18, 0.22);

  /* ===== 液态玻璃材质 ===== */
  --glass-blur: 22px;
  --glass-saturate: 190%;
  --glass-brightness: 1.06;
  --glass-fill: linear-gradient(145deg, rgba(255, 255, 255, 0.42) 0%, rgba(255, 255, 255, 0.22) 48%, rgba(255, 255, 255, 0.12) 100%);
  --glass-fill-soft: linear-gradient(145deg, rgba(255, 255, 255, 0.32) 0%, rgba(255, 255, 255, 0.13) 100%);
  --glass-stroke: rgba(255, 255, 255, 0.9);
  --glass-stroke-soft: rgba(255, 255, 255, 0.6);
  --glass-divider: rgba(20, 23, 18, 0.08);
  --glass-glow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 0 0 1px rgba(255, 255, 255, 0.34),
    inset 0 -18px 30px -22px rgba(20, 23, 18, 0.3);
  --glass-shadow: 0 20px 44px -20px rgba(20, 23, 18, 0.36), 0 2px 10px -4px rgba(20, 23, 18, 0.1);
  --glass-sheen:
    radial-gradient(105% 58% at 6% -14%, rgba(255, 255, 255, 0.24), transparent 62%),
    linear-gradient(118deg, transparent 38%, rgba(255, 255, 255, 0.08) 48%, transparent 58%);
  --field-bg: rgba(255, 255, 255, 0.26);
  --glass-fill-dialog: linear-gradient(145deg, rgba(255, 255, 255, 0.92) 0%, rgba(249, 250, 248, 0.87) 100%);

  /* ===== 单色浅色背景板 ===== */
  --board-base: #eef0ec;
  --board-1: #fdfdfc;
  --board-2: #e8ebe5;
  --board-3: #d5dad1;
  --board-glow-a: rgba(255, 255, 255, 0.95);
  --board-glow-b: rgba(222, 227, 217, 0.85);
  --mesh-dot: rgba(20, 23, 18, 0.1);
  --board-vignette: rgba(20, 23, 18, 0.07);

  /* 整块板上唯一的彩色记号：局部绿光，而不是一层绿色滤镜。 */
  --glint-core: rgba(138, 202, 84, 0.62);
  --glint-halo: rgba(104, 168, 64, 0.16);
  --glint-blend: normal;
  --glint-core-size: 400px;
  --glint-halo-size: 780px;
  --glint-opacity: 0.55;

  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  --font-mono: "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
}

[data-theme="dark"] {
  --bg: #0b0d0a;
  --surface: #121611;
  --surface-subtle: #191f17;
  --border: #252d22;
  --border-hover: #384534;
  --text: #f2f5f0;
  --text-secondary: #95a08e;
  --text-muted: #7e897a;

  --brand-green: #69a942;
  --brand-green-soft: rgba(105, 169, 66, 0.14);
  --brand-green-border: rgba(105, 169, 66, 0.3);
  --primary: #f2f5f0;
  --primary-fg: #0b0d0a;

  --status-online: #69a942;
  --shadow-card: 0 14px 36px -10px rgba(0, 0, 0, 0.55);
  --shadow-modal: 0 24px 64px -12px rgba(0, 0, 0, 0.78);

  /* ===== 液态玻璃材质（深色） ===== */
  --glass-blur: 24px;
  --glass-saturate: 165%;
  --glass-brightness: 0.9;
  --glass-fill: linear-gradient(145deg, rgba(42, 43, 41, 0.46) 0%, rgba(27, 28, 27, 0.3) 52%, rgba(18, 19, 18, 0.18) 100%);
  --glass-fill-soft: linear-gradient(145deg, rgba(44, 45, 43, 0.28) 0%, rgba(23, 24, 23, 0.15) 100%);
  --glass-stroke: rgba(255, 255, 255, 0.22);
  --glass-stroke-soft: rgba(255, 255, 255, 0.12);
  --glass-divider: rgba(255, 255, 255, 0.09);
  --glass-glow:
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    inset 0 0 0 1px rgba(255, 255, 255, 0.06),
    inset 0 -18px 30px -22px rgba(0, 0, 0, 0.6);
  --glass-shadow: 0 22px 48px -22px rgba(0, 0, 0, 0.72), 0 2px 10px -4px rgba(0, 0, 0, 0.4);
  --glass-sheen:
    radial-gradient(105% 58% at 6% -14%, rgba(255, 255, 255, 0.1), transparent 62%),
    linear-gradient(118deg, transparent 38%, rgba(255, 255, 255, 0.05) 48%, transparent 58%);
  --field-bg: rgba(255, 255, 255, 0.06);
  --glass-fill-dialog: linear-gradient(145deg, rgba(30, 35, 28, 0.95) 0%, rgba(19, 23, 18, 0.92) 100%);

  /* ===== 单色背景板（深色） =====
     不是浅色板的反转：黑底从上方照亮，渐变由炭黑走向近黑。网格翻成
     低透明度白点，色相保持中性——绿光是唯一允许带颜色的记号。 */
  --board-base: #0b0c0b;
  --board-1: #1c1e1c;
  --board-2: #121412;
  --board-3: #070807;
  --board-glow-a: rgba(74, 76, 73, 0.5);
  --board-glow-b: rgba(42, 44, 42, 0.6);
  --mesh-dot: rgba(255, 255, 255, 0.075);
  --board-vignette: rgba(0, 0, 0, 0.55);

  --glint-core: rgba(196, 246, 150, 0.62);
  --glint-halo: rgba(105, 169, 66, 0.26);
  --glint-blend: screen;
  --glint-core-size: 560px;
  --glint-halo-size: 1040px;
  --glint-opacity: 0.55;
}

/* ==================== 背景板 ====================
   一块单色板而不是照片：层叠的明暗面板、细点网格、缓慢漂移。网格是
   背景里唯一的高频细节，而高频细节正是让模糊读作「玻璃」而不是「雾」的
   东西——没有它，backdrop-filter 无物可糊，面板只会显得奶白。 */

.ambient {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--board-base);
}

.board {
  position: absolute;
  inset: -12%;
  background:
    radial-gradient(56% 50% at 50% 28%, var(--board-glow-a), transparent 72%),
    radial-gradient(42% 38% at 12% 84%, var(--board-glow-b), transparent 74%),
    radial-gradient(38% 34% at 88% 60%, var(--board-glow-b), transparent 76%),
    linear-gradient(var(--board-angle, 160deg), var(--board-1) 0%, var(--board-2) 52%, var(--board-3) 100%);
  animation: boardDrift 44s ease-in-out infinite alternate;
  will-change: transform;
}

@keyframes boardDrift {
  0%   { transform: translate3d(-1.2%, -0.8%, 0) scale(1.02); }
  50%  { transform: translate3d(1%, 1.2%, 0) scale(1.06); }
  100% { transform: translate3d(-0.4%, 0.6%, 0) scale(1.03); }
}

/* 点阵而非网格线：可见网格像绘图纸，点阵只在边缘感知阈值附近，消融在玻璃
   之下成为颗粒。遮罩保证它不触及屏幕边缘。 */
.board-mesh {
  position: absolute;
  inset: -8%;
  background-image: radial-gradient(var(--mesh-dot) 1px, transparent 1.4px);
  background-size: 30px 30px;
  -webkit-mask-image: radial-gradient(72% 64% at 50% 40%, #000 0%, transparent 78%);
  mask-image: radial-gradient(72% 64% at 50% 40%, #000 0%, transparent 78%);
  animation: meshDrift 68s linear infinite;
  will-change: transform;
}

@keyframes meshDrift {
  0%   { transform: translate3d(0, 0, 0); }
  50%  { transform: translate3d(15px, 30px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

.board-vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(130% 100% at 50% 34%, transparent 46%, var(--board-vignette) 100%);
}

/* 绿光：两团缓慢漂移的柔光，周期不同所以不会重复对齐。紧核配长尾才是
   「光」，而不是「盘」。刻意不做指针跟随：绿光是环境光，跟随光标会变成
   鼠标特效，与玻璃内部的错觉相冲突。 */
.glint-field {
  position: absolute;
  inset: 0;
}

.glint-orb {
  position: absolute;
  left: 0;
  top: 0;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--glint-core) 0%, var(--glint-halo) 32%, transparent 72%);
  mix-blend-mode: var(--glint-blend, normal);
  will-change: transform;
  transform: translate3d(50vw, 38vh, 0);
  animation: glintDrift 26s ease-in-out infinite alternate;
}

.glint-orb:nth-child(2) {
  animation-duration: 34s;
  animation-direction: alternate-reverse;
}

@keyframes glintDrift {
  0%   { transform: translate3d(30vw, 28vh, 0) scale(0.94); }
  50%  { transform: translate3d(58vw, 46vh, 0) scale(1.06); }
  100% { transform: translate3d(72vw, 24vh, 0) scale(1); }
}

.glint-orb:nth-child(1) {
  width: var(--glint-core-size, 620px);
  height: var(--glint-core-size, 620px);
  margin: calc(var(--glint-core-size, 620px) / -2) 0 0 calc(var(--glint-core-size, 620px) / -2);
  opacity: calc(var(--glint-opacity, 0.55) * 0.9);
}

.glint-orb:nth-child(2) {
  width: var(--glint-halo-size, 1180px);
  height: var(--glint-halo-size, 1180px);
  margin: calc(var(--glint-halo-size, 1180px) / -2) 0 0 calc(var(--glint-halo-size, 1180px) / -2);
  opacity: calc(var(--glint-opacity, 0.55) * 0.55);
}

/* ==================== 玻璃配方 ====================
   材质只在这里定义一次。下面每个表面通过读取 --glass-fill / --glass-glow
   来「选择加入」，这样不支持 backdrop-filter 的浏览器可以在同一处换成
   不透明填充。 */

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root {
    --glass-fill: linear-gradient(145deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.88) 100%);
    --glass-fill-soft: linear-gradient(145deg, rgba(255, 255, 255, 0.91), rgba(250, 251, 249, 0.85));
    --glass-stroke: rgba(255, 255, 255, 0.95);
    --glass-stroke-soft: rgba(20, 23, 18, 0.1);
    --field-bg: rgba(255, 255, 255, 0.92);
  }
  [data-theme="dark"] {
    --glass-fill: linear-gradient(145deg, rgba(28, 34, 26, 0.96), rgba(20, 26, 18, 0.92));
    --glass-fill-soft: linear-gradient(145deg, rgba(32, 39, 29, 0.92), rgba(22, 28, 20, 0.86));
    --glass-stroke: rgba(255, 255, 255, 0.1);
    --glass-stroke-soft: rgba(255, 255, 255, 0.08);
    --field-bg: rgba(255, 255, 255, 0.06);
  }
  .glass-surface, .glass-soft, .glass-pane {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
}

/* 主玻璃面板：填充 + 高光 + 描边 + 内发光。 */
.glass-surface {
  background-image: var(--glass-sheen), var(--glass-fill);
  border: 1px solid var(--glass-stroke);
  box-shadow: var(--glass-glow), var(--glass-shadow);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate)) brightness(var(--glass-brightness));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate)) brightness(var(--glass-brightness));
}

/* 轻量玻璃：控件与小面板，填充更薄。 */
.glass-soft {
  background-image: var(--glass-sheen), var(--glass-fill-soft);
  border: 1px solid var(--glass-stroke-soft);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(14px) saturate(200%) brightness(var(--glass-brightness));
  backdrop-filter: blur(14px) saturate(200%) brightness(var(--glass-brightness));
}

/* ==================== 指针高光 ====================
   两道渐变随光标滑过面板：前导的紧致白色高光点，滞后在对侧的大范围暗
   弱反光。光与其反射相向运动，才读出「厚度」；单点辉光只会像灰污渍。
   --glare-x / --glare-y 由指针追踪脚本写入。 */

.glass-specular {
  position: relative;
}

.glass-specular::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 3;
  background:
    radial-gradient(var(--glare-size, 190px) var(--glare-size, 190px) at var(--glare-x, 50%) var(--glare-y, 0%),
      rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.42) 26%, rgba(255, 255, 255, 0.12) 48%, transparent 68%),
    radial-gradient(calc(var(--glare-size, 190px) * 2) calc(var(--glare-size, 190px) * 2) at calc(100% - var(--glare-x, 50%)) calc(100% - var(--glare-y, 0%)),
      rgba(75, 127, 43, 0.18), transparent 72%);
  opacity: 0;
  transition: opacity 240ms var(--ease-out);
}

/* 小控件收紧光斑，让辉光留在形状内。 */
.glass-small {
  --glare-size: 95px;
}

[data-theme="dark"] .glass-specular::after {
  background:
    radial-gradient(var(--glare-size, 190px) var(--glare-size, 190px) at var(--glare-x, 50%) var(--glare-y, 0%),
      rgba(255, 255, 255, 0.34), rgba(255, 255, 255, 0.12) 26%, rgba(255, 255, 255, 0.03) 48%, transparent 68%),
    radial-gradient(calc(var(--glare-size, 190px) * 2) calc(var(--glare-size, 190px) * 2) at calc(100% - var(--glare-x, 50%)) calc(100% - var(--glare-y, 0%)),
      rgba(105, 169, 66, 0.24), transparent 72%);
}

/* 贴合边框的高光：画成两层遮罩，只让轮廓亮起。这才让边缘像真正的玻璃
   棱线，而不是面板内部的一团白斑。 */
.glass-specular::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  pointer-events: none;
  z-index: 4;
  background:
    radial-gradient(220px 220px at var(--glare-x, 50%) var(--glare-y, 0%),
      rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.45) 45%, transparent 72%),
    radial-gradient(260px 260px at calc(100% - var(--glare-x, 50%)) calc(100% - var(--glare-y, 0%)),
      rgba(75, 127, 43, 0.5), transparent 76%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  transition: opacity 240ms var(--ease-out);
}

[data-theme="dark"] .glass-specular::before {
  background:
    radial-gradient(220px 220px at var(--glare-x, 50%) var(--glare-y, 0%),
      rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0.2) 45%, transparent 72%),
    radial-gradient(260px 260px at calc(100% - var(--glare-x, 50%)) calc(100% - var(--glare-y, 0%)),
      rgba(105, 169, 66, 0.55), transparent 76%);
}

.glass-specular-active::before,
.glass-specular-active::after {
  opacity: 1;
}

.access-spinner, [data-loading="true"]::before {
  content: ""; display: inline-block; width: 18px; height: 18px; flex-shrink: 0;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: access-spin .8s linear infinite; vertical-align: middle;
}
[data-loading="true"]::before { width: 14px; height: 14px; margin-right: 9px; }
.access-feedback { margin: 12px 0 0; font-size: 13px; line-height: 1.7; color: var(--text-secondary); }
.access-loading { max-width: 460px; margin: 64px auto; padding: 28px; }
.access-loading-heading { display: flex; align-items: center; gap: 12px; }
.access-loading .access-spinner { color: var(--brand-green); }
.access-loading h2 { margin: 0; font-size: 18px; }
.access-loading p { margin: 12px 0 0; color: var(--text-secondary); font-size: 13px; line-height: 1.7; }
@keyframes access-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .access-spinner, [data-loading="true"]::before { animation: none; }
  .board, .board-mesh, .glint-orb { animation: none; }
  .glass-specular::before, .glass-specular::after { transition: none; }
}
