/* ==========================================================================
   三角洲赛事系统 — 设计令牌 (Design Tokens)
   亮色作业面 + 深墨框架 · 战场蓝/金强调色
   三层架构：Primitive（原始值） → Semantic（语义） → Component（组件）
   换肤只改这一份：组件层一律读语义令牌，不直接读 --p-* 原语。
   2026-10-09 全站改版定稿：A「指挥所」骨架（冷中性阶 / 紧圆角 / 短动效无回弹 /
   撤毛玻璃 / crisp 阴影 / 后台密档）；观众侧卡片的立体感用 B 的分层投影，
   靠「两种作用域挂不同阴影档」实现，模板不动。
   ========================================================================== */

/* ---------- Layer 1: Primitive Tokens（原始设计值，不含语义） ---------- */
:root {
  /* 深墨阶 — 深墨框架（顶栏 / 后台侧栏）与需要"重"的地方 */
  --p-ink-900: #070C12;   /* 标题墨色 */
  --p-ink-850: #0B1219;
  --p-ink-800: #111A24;
  --p-ink-700: #1A2531;
  --p-ink-600: #26313F;
  --p-ink-500: #3A4756;
  --p-ink-400: #556375;
  --p-ink-300: #74808F;   /* 边框/弱强调 */
  --p-ink-200: #94A1B1;   /* 弱边框/分隔 */
  --p-ink-150: #B3BFCC;
  --p-ink-100: #CFD8E2;
  --p-ink-050: #E2E8EF;
  --p-white:   #FFFFFF;

  /* 纸白阶 — 亮色主题的表面（页面 / 卡片 / 下沉 / 悬停），冷调不带暖味 */
  --p-paper-0: #FFFFFF;   /* 卡片、弹层 */
  --p-paper-1: #F2F5F9;   /* 卡片内的次级表面 */
  --p-paper-2: #E7ECF3;   /* 次级表面、表头 */
  --p-paper-3: #DBE3EC;   /* 下沉、骨架 */
  --p-paper-4: #C9D4E0;   /* 更重的分隔面 */
  /* 页面底色：比卡片深两档，白卡才「浮」得起来；亮色主题最容易翻车的就是白压白 */
  --p-paper-bg:  #EDF1F6;

  /* 墨字阶 — 亮色底上的正文（对白实测对比度见文件末尾备注）
     slate-400 是小字正文下限（对白 7.1），slate-300 只用于边框/装饰 */
  --p-slate-900: #0A1017;
  --p-slate-700: #242F3C;
  --p-slate-500: #41505F;
  --p-slate-400: #576473;
  --p-slate-300: #75828F;

  /* 战场蓝 (Battlefield Blue) — 深钴：白底上的按钮与链接都读 600/700 */
  --p-blue-700: #044F9E;
  --p-blue-600: #0A5BC4;
  --p-blue-500: #2E7BDC;
  --p-blue-400: #69A2EC;
  --p-blue-300: #A6C8F5;

  /* 军用金 (Military Gold) — 白底上的金色文字只用 700/800 这两档；
     300/400 是「压在深墨上」那两档，当全局色实测只有 1.41:1（排行榜纸白底） */
  --p-gold-800: #5C3F00;
  --p-gold-700: #7A5400;  /* 亮底上的金色文字（对白 5.9） */
  --p-gold-600: #9E6C00;
  --p-gold-500: #C68A00;
  --p-gold-400: #E0A600;
  --p-gold-300: #F2C75B;

  /* 功能色 (亮色系统色：文字级对比度) */
  --p-green-600: #0A6B36;
  --p-green-500: #0F8347;
  --p-red-600:   #AF1F14;
  --p-red-500:   #D3392C;
  --p-orange-600:#9C4A05;
  --p-orange-500:#C46608;
  --p-orange-700:#934605;
  --p-purple-600:#6C34A4;
  --p-purple-500:#8750BE;
  --p-teal-600:  #07617B;
  --p-teal-500:  #0E87A6;

  /* 深墨框架 (chrome) — 公开站顶栏 + 后台侧栏；作业面永远纸白。
     框架上的文字要「直接给 color」：body 的墨色一路继承下来时 var() 已经算成实色，
     只在这个作用域换 --text-* 挡不住（实测用户名 1.02:1 黑压黑）。见 app.css 深色框架段。 */
  --chrome:         #0C1219;
  --chrome-raised:  #151E28;
  --chrome-rule:    rgba(226, 238, 250, 0.14);
  --chrome-ink:     #EAF1F8;
  --chrome-dim:     #9DB0C4;
  --signal:         #E07B18;   /* 实心信号块：只标「轮到你动手」 */
  --signal-ink:     #9C4A05;   /* 同一语义的文字档 */

  /* 字体族 */
  --p-font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
                 "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --p-font-mono: "SF Mono", ui-monospace, "Cascadia Code", "JetBrains Mono", Menlo,
                 Consolas, "Liberation Mono", monospace;

  /* 字号阶 (type scale) */
  --p-fs-11: 0.6875rem;  /* 11px */
  --p-fs-12: 0.75rem;
  --p-fs-13: 0.8125rem;
  --p-fs-14: 0.875rem;
  --p-fs-15: 0.9375rem;
  --p-fs-16: 1rem;
  --p-fs-18: 1.125rem;
  --p-fs-20: 1.25rem;
  --p-fs-24: 1.5rem;
  --p-fs-28: 1.75rem;
  --p-fs-34: 2.125rem;
  --p-fs-44: 2.75rem;

  /* 字重 */
  --p-fw-regular: 400;
  --p-fw-medium:  500;
  --p-fw-semi:    600;
  --p-fw-bold:    700;

  /* 间距阶 (4pt 基准 · Apple 8pt 网格) */
  --p-sp-1: 4px;
  --p-sp-2: 8px;
  --p-sp-3: 12px;
  --p-sp-4: 16px;
  --p-sp-5: 20px;
  --p-sp-6: 24px;
  --p-sp-8: 32px;
  --p-sp-10: 40px;
  --p-sp-12: 48px;
  --p-sp-16: 64px;

  /* 圆角：仪器盘的紧。卡片 7 / 弹层 9 / 大画面 11，
     旧值（20/28）是「幽灵卡片」的一部分，别再往回改 */
  --p-r-xs: 3px;
  --p-r-sm: 5px;
  --p-r-md: 7px;
  --p-r-lg: 9px;
  --p-r-xl: 11px;
  --p-r-pill: 999px;

  /* 动效时长与缓动：短、无回弹。
     --p-ease-spring 故意换成 expo-out —— app.css 里按钮/开关那几处弹跳一起消掉，
     不用逐条覆盖（留这个名字是给老代码的，别再当「有弹性」理解）。 */
  --p-dur-fast: 110ms;
  --p-dur-base: 160ms;
  --p-dur-slow: 240ms;
  --p-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --p-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --p-ease-spring: cubic-bezier(0.22, 1, 0.36, 1);

  /* 层级 (z-index scale) */
  --p-z-base: 0;
  --p-z-nav: 100;
  --p-z-dropdown: 200;
  --p-z-sticky: 300;
  --p-z-overlay: 900;
  --p-z-modal: 1000;
  --p-z-toast: 1100;
}

/* ---------- Layer 2: Semantic Tokens（语义化，组件消费这些） ---------- */
:root {
  /* 表面 */
  --bg-app:        var(--p-paper-bg);
  --bg-elevated:   var(--p-paper-0);
  --bg-panel:      var(--p-paper-0);
  --bg-subtle:     var(--p-paper-2);
  --bg-muted:      var(--p-paper-3);
  --bg-hover:      rgba(12, 22, 36, 0.055);
  --bg-active:     rgba(12, 22, 36, 0.09);
  --bg-sunken:     var(--p-paper-2);
  --bg-chip:       var(--p-paper-2);

  /* 玻璃全撤：导航与侧栏换成实色深墨，弹层直接纸白。
     名字留着（三处组件读它），值不再是半透明白——「仪器盘不透过表面看东西」。 */
  --glass-nav:     var(--chrome);
  --glass-panel:   var(--p-paper-0);
  --glass-blur:    none;
  --glass-border:  var(--chrome-rule);

  /* 文字 */
  --text-primary:   var(--p-slate-900);
  --text-secondary: var(--p-slate-700);
  --text-tertiary:  var(--p-slate-500);
  --text-quaternary:var(--p-slate-400);
  --text-inverse:   var(--p-ink-900);
  --text-link:      var(--p-blue-600);

  /* 边框与分隔 */
  --border-default: var(--p-paper-4);
  --border-subtle:  rgba(12, 22, 36, 0.09);
  --border-strong:  #AEBBCA;
  --separator:      rgba(12, 22, 36, 0.10);

  /* 品牌与强调 */
  --accent:         var(--p-blue-600);
  --accent-hover:   var(--p-blue-700);
  --accent-press:   #043F7E;
  --accent-soft:    rgba(10, 91, 196, 0.09);
  --accent-text:    #FFFFFF;

  --gold:           var(--p-gold-700);
  --gold-strong:    var(--p-gold-800);
  --gold-soft:      rgba(198, 138, 0, 0.14);

  /* 状态语义色 */
  --success:        var(--p-green-600);
  --success-soft:   rgba(15, 131, 71, 0.12);
  --danger:         var(--p-red-600);
  --danger-soft:    rgba(211, 57, 44, 0.12);
  /* warning 的 600 档在卡片标题带那档浅底上实测只有 4.45，取 700 才留得住余量（4.85） */
  --warning:        var(--p-orange-700);
  --warning-soft:   rgba(196, 102, 8, 0.14);
  --info:           var(--p-teal-600);
  --info-soft:      rgba(14, 135, 166, 0.13);
  --neutral-soft:   rgba(12, 22, 36, 0.07);

  /* 阴影：crisp —— 一档 1px 内抬 + 短模糊，靠边框撑结构，不留大光晕。
     观众侧的立体感用下面的 --shadow-stage*（分层长投影），两套档按作用域挂，
     同一张卡片不要同时出现「可见 1px 边框 + ≥16px 模糊」（幽灵卡片）。 */
  --shadow-sm: 0 1px 2px rgba(7, 12, 18, 0.10);
  --shadow-md: 0 1px 0 rgba(7, 12, 18, 0.04), 0 2px 6px rgba(7, 12, 18, 0.10);
  --shadow-lg: 0 2px 4px rgba(7, 12, 18, 0.08), 0 6px 14px rgba(7, 12, 18, 0.12);
  --shadow-xl: 0 4px 8px rgba(7, 12, 18, 0.10), 0 10px 24px rgba(7, 12, 18, 0.16);
  --shadow-glow-blue: 0 0 0 1px var(--p-blue-600), 0 2px 6px rgba(10, 91, 196, 0.18);
  --shadow-glow-gold: 0 0 0 1px var(--p-gold-500), 0 2px 6px rgba(198, 138, 0, 0.18);
  --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.6);

  /* 焦点环：白描边 + 实色外环，深墨框架和纸白作业面上都看得见 */
  --focus-ring: 0 0 0 2px var(--p-paper-0), 0 0 0 4px var(--p-blue-600);

  /* 字体语义 */
  --font-sans: var(--p-font-sans);
  --font-mono: var(--p-font-mono);

  /* 布局尺寸 */
  --nav-height: 56px;
  --sidebar-width: 248px;
  --sidebar-width-collapsed: 68px;
  --content-max: 1320px;
  --content-wide: 1600px;
}

/* ---------- Layer 3: Component Tokens（组件级，可局部覆盖） ---------- */
:root {
  /* 按钮 */
  --btn-height-sm: 30px;
  --btn-height-md: 38px;
  --btn-height-lg: 48px;
  --btn-radius: var(--p-r-sm);
  --btn-px-sm: var(--p-sp-3);
  --btn-px-md: var(--p-sp-4);
  --btn-px-lg: var(--p-sp-6);

  /* 卡片 */
  --card-radius: var(--p-r-md);
  --card-padding: var(--p-sp-5);
  --card-bg: var(--bg-panel);
  --card-border: var(--border-subtle);

  /* 输入框 */
  --input-height: 40px;
  --input-radius: var(--p-r-sm);
  /* 白卡里的输入框给纯白 + 实边框；极浅灰底在新中性阶上会糊成一片 */
  --input-bg: var(--p-paper-0);
  --input-border: var(--border-default);
  --input-border-focus: var(--accent);

  /* 表格 */
  --table-row-height: 48px;
  --table-head-bg: var(--p-paper-2);
  --table-border: var(--border-subtle);
  --table-hover: var(--bg-hover);

  /* 徽章：方角 20 高，胶囊只留给纯标签（.badge-outline 那种） */
  --badge-radius: var(--p-r-xs);
  --badge-height: 20px;

  /* 对阵树节点 */
  --bracket-node-w: 240px;
  --bracket-node-h: 76px;
  --bracket-gap-x: 56px;
  --bracket-gap-y: 20px;
}

/* ---------- 作用域档 1：后台与执裁台变密（前台/大屏不受影响） ----------
   执裁台走的是公开站外壳（.nav + .container[data-page=referee]），不在 .admin-shell 里，
   所以那一档密度要单独挂上，否则「后台变密」只覆盖到后台，裁判那一屏还是 52 高。
   实测坑：--table-row-height 压到 40 只到 52 —— 行里的 32px 头像顶住了高度，
   所以头像/徽标这类行内块要跟着收一档（见 app.css 的同名作用域）。 */
.admin-shell, [data-page="referee"] {
  --p-fs-11: 10px; --p-fs-12: 11.5px; --p-fs-13: 12.5px;
  --p-fs-14: 13.5px; --p-fs-15: 14px; --p-fs-16: 15px; --p-fs-18: 17px;
  --p-fs-20: 19px; --p-fs-24: 23px; --p-fs-28: 27px; --p-fs-34: 30px;
  --table-row-height: 40px;
  --btn-height-md: 32px; --btn-height-sm: 26px; --btn-height-lg: 40px;
  --input-height: 34px;
  --card-padding: 16px;
  --p-sp-6: 16px; --p-sp-8: 24px; --p-sp-16: 44px;
}

/* ---------- 作用域档 2：观众侧的卡片立体感（分层长投影） ----------
   「给人看」的页面上卡片的高度靠长投影撑：边框转透明，别和可见 1px 边框叠在一起。
   后台、运营台、执裁台、队长作业页读默认档（crisp 短投影）—— 一张卡不会同时出现两种立体语言。
   三条容易踩的：
   ① 后台的赛事详情（admin/tournament_detail）不在这一档里。它是 .admin-shell 的作业面，
      以前挂在上面会让后台某一页的卡片比别的页高出一档投影，看着像另一套系统。
   ② 直播大屏 live.html 与只读分享页 share.html **不加载这份 token**（前者整页内联样式，
      后者只吃 print.css）：这两个页面的同档投影各自写在自己那份里，改数值要三处一起对。
   ③ 模态框与 Toast 在观众侧页面上也还是「可见边框 + 短投影」，这不是漏改：
      两者由 core.js 挂在 document.body 上，落在 [data-page] 作用域外面，读的是默认档。
      浮层压在遮罩或别的内容上，靠边缘撑，长投影在没有地平面的东西上只会糊出一圈。 */
[data-page="index"], [data-page="tournament"], [data-page="leaderboard"],
[data-page="team_home"], [data-page="player_home"], [data-page="calendar"],
[data-page="notifications"], [data-page="security"], [data-page="my_home"],
[data-page="identity"], [data-page="claim"], [data-page="invite"],
[data-page="error"], [data-page="auth"] {
  --shadow-sm: 0 1px 2px rgba(8, 20, 42, 0.10), 0 2px 6px -2px rgba(8, 20, 42, 0.12);
  --shadow-md: 0 2px 4px rgba(8, 20, 42, 0.08), 0 12px 26px -8px rgba(8, 20, 42, 0.24);
  --shadow-lg: 0 4px 8px rgba(8, 20, 42, 0.08), 0 20px 44px -12px rgba(8, 20, 42, 0.32);
  --shadow-xl: 0 8px 18px rgba(8, 20, 42, 0.10), 0 34px 64px -20px rgba(8, 20, 42, 0.36);
  --card-border: transparent;
  /* 边框转透明后，卡片（#FFFFFF）与页底（#EDF1F6）只差 1.06:1：长投影撑得起高度，
     但「这张卡到哪儿结束」那条界会糊掉。用一圈 inset 内描边把边界钉住 ——
     它不占布局、不是 border，所以不会和长投影叠成幽灵卡片（那是「可见 border + ≥16px 模糊」才有的毛病）。 */
  --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.75), inset 0 0 0 1px rgba(8, 20, 42, 0.055);
  --card-radius: var(--p-r-lg);
  --card-padding: var(--p-sp-6);
}

/* ---------- 作用域档 3：进门那三页把控件放大一号 ----------
   登录/注册/找回密码多数是从群里点进来在手机上半只手点的，触控档按 44 那一档给；
   后台与执裁台正好反过来（上面那档收紧）。这里只挂令牌，模板与组件层不写死高度。 */
[data-page="auth"] {
  --input-height: 46px;
  --btn-height-md: 44px;
  /* 这一屏只有两三样东西，卡里的空档给到 32：比作业面那档松，人才不至于一进来就觉得
     站在一张后台表单前面。*/
  --card-padding: var(--p-sp-8);
}

/* ---------- 全局重置基线 ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  font-size: 16px;
  scroll-behavior: smooth;
  /* 让原生控件（下拉、日期、滚动条、自动填充）走亮色，否则白页里会冒出黑色系统弹层 */
  color-scheme: light;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--p-fs-15);
  line-height: 1.5;
  color: var(--text-primary);
  background-color: var(--bg-app);
  /* 底色不是死灰：顶部一层白雾把页面「打亮」，右侧冷蓝、左下暖金各留一点偏色 */
  background-image:
    linear-gradient(180deg, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0) 380px),
    radial-gradient(1000px 460px at 104% 0%, rgba(10, 91, 196, 0.07), transparent 58%),
    radial-gradient(900px 520px at -6% 100%, rgba(198, 138, 0, 0.06), transparent 60%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  min-height: 100dvh;
}

/* 数字使用等宽表格数字，防止跳动 */
.num, .score, .seed, td.num, .tabular {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

::selection { background: rgba(10, 91, 196, 0.20); color: var(--text-primary); }

/* 滚动条 (WebKit) — Apple 细滚动条 */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: rgba(12, 22, 36, 0.22);
  border-radius: var(--p-r-pill);
  border: 2px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: rgba(12, 22, 36, 0.36); background-clip: content-box; }

/* 无障碍：尊重减少动效偏好 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* 全局焦点可见性 */
:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--p-r-xs);
}
