/* ═══════════════════════════════════════════════════════════════════════════
   components.css —— 550v 网页家族的**单元层**（卡片 / 面板 / 圆盘 / 图例 / 行 / 药丸 / toast）

   依赖 `tokens.css`（变量都在那儿）。页面里只要：
     <link rel="stylesheet" href="tokens.css">
     <link rel="stylesheet" href="components.css">
     <link rel="stylesheet" href="自己的.css">     ← 只写这个页面特有的东西

   页面骨架（照抄就行）：
     <div class="wrap">
       <header>
         <div><div class="title">标题 <b>· 强调</b></div><div class="sub">副标题</div></div>
         <div class="clock"><div class="lbl">标签</div><div class="t">大数<small>小注</small></div></div>
       </header>
       <div class="att-nav"><a href="#" class="on">选项</a>…</div>
       <div class="two-col"><div class="col"><div class="stack">
         <section class="card"><h2 class="sec">标题<em>右侧灰副标</em></h2>
           <div class="cols"><div class="panel">…</div></div></section>
       </div></div></div>
       <footer>…</footer>
     </div>
     <div id="toast" class="toast" hidden></div>

   识别度最高的 5 条（改之前先知道）：
     ① 深底 + **无框卡片 + "光"当边框**（inset 呼吸 + conic 流光带）
     ② **圆盘 + 图例**（r=139.5 刻度圈 / r=118 数据圈 / 盘心 mono 大字）
     ③ `h2.sec` 标题行：3×13px lime 竖条 + 13px/600/1.5px 字距 + 右侧灰 em
     ④ **处处等宽小字 + 大写间距**（--mono 上的 10/11.5px）
     ⑤ 两套主题是两套物理（keyframes 换名 *-lt），几何与 10s/40% 节奏不动
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 底 ───────────────────────────────────────────────────────────────── */
*{box-sizing:border-box}
html{background:var(--bg)}
/* 两块装饰渐变必须挂 position:fixed 的伪元素上：body 的盒子只有"内容那么高"，
   挂 body 背景会被画到盒子之外，视口底部出现一条色差"断层"（全屏时最明显）。 */
body::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(900px 520px at 16% -10%,#131d28 0%,transparent 62%),
             radial-gradient(760px 440px at 92% -6%,#0d1a13 0%,transparent 58%)}
:root[data-theme="light"] body::before{
  background:radial-gradient(900px 520px at 16% -10%,#ffffff 0%,transparent 62%),
             radial-gradient(760px 440px at 92% -6%,#eaf1fb 0%,transparent 58%)}
body{margin:0;color:var(--text);
  font:15px/1.6 "Microsoft YaHei","PingFang SC",system-ui,sans-serif;-webkit-font-smoothing:antialiased}

/* 宽屏整屏（信息屏那种）：max-width 1880px + 纵向居中；长滚动页（考勤/账本）在页面 CSS 里
   覆盖成 max-width:1000px、不居中（见 README「三种版面」）。 */
.wrap{width:100%;max-width:1880px;margin:0 auto;
  padding:calc(18px * var(--u) + var(--fill) * .6) clamp(18px,2.2vw,40px) calc(20px * var(--u) + var(--fill) * .6)}

/* ── 顶栏 ─────────────────────────────────────────────────────────────── */
header{display:flex;flex-wrap:wrap;gap:16px;align-items:flex-end;justify-content:space-between}
.title{font-size:21px;font-weight:700;letter-spacing:1.5px}
.title b{color:var(--lime)}
.sub{font-size:12.5px;color:var(--dim2);margin-top:7px}
.clock{text-align:right;flex:none}
.clock .lbl{font-size:11px;color:var(--dim2);letter-spacing:1.5px}
.clock .t{font-family:var(--mono);font-size:44px;font-weight:700;letter-spacing:1px;line-height:1.05}
.clock .t small{font-size:17px;color:var(--dim);margin-left:4px}

/* ── 药丸导航 / 选项组 ─────────────────────────────────────────────────── */
.att-nav{display:flex;flex-wrap:wrap;gap:8px;margin:calc(16px * var(--u)) 0 calc(4px * var(--u))}
.att-nav a{font-size:calc(12px * var(--u));padding:calc(5px * var(--u)) calc(11px * var(--u));
  border-radius:999px;background:var(--card);border:1px solid var(--rule);color:var(--dim);
  text-decoration:none;white-space:nowrap;cursor:pointer;transition:color .12s,border-color .12s,background .12s}
.att-nav a:hover{color:var(--text);border-color:var(--dim2)}
.att-nav a.on{background:rgba(87,169,230,.16);border-color:var(--blue);color:var(--blue)}
:root[data-theme="light"] .att-nav a.on{background:rgba(47,111,168,.12)}

/* ── 版面 ─────────────────────────────────────────────────────────────── */
.two-col{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
  gap:calc(14px * var(--u) + var(--fill) * .5) calc(20px * var(--u));align-items:start}
.col{min-width:0}
.stack{display:grid;gap:calc(10px * var(--u) + var(--fill));align-content:start}
.cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr));gap:14px}

/* ── 标题行（家族识别度最高的一条）────────────────────────────────────── */
h2.sec{margin:calc(10px * var(--u) + var(--fill) * .5) 0 calc(6px * var(--u) + var(--fill) * .3);
  font-size:13px;font-weight:600;letter-spacing:1.5px;color:#c6cfd8;
  display:flex;align-items:center;gap:9px}
:root[data-theme="light"] h2.sec{color:#40506a}
h2.sec:before{content:"";width:3px;height:13px;background:var(--lime);border-radius:1px;flex:none}
h2.sec em{font-style:normal;font-weight:400;font-size:12px;color:var(--dim2)}
h2.sec .beat{margin-left:auto;display:flex;align-items:center;gap:6px;
  font-family:var(--mono);font-size:10.5px;color:var(--dim2)}
.card > .sec:first-child,.stack > .sec:first-child{margin-top:0}

/* ── 卡片 / 面板：无框，靠"光"当边框 ───────────────────────────────────── */
.card{min-width:0}
.panel,.disc-wrap{position:relative;background:var(--card);border:0;border-radius:12px;
  padding:16px 18px 18px;animation:framebreathe 10s ease-in-out infinite}
.disc-wrap{border-radius:18px;padding:24px 26px}
.panel:after,.disc-wrap:after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;padding:3px;
  background:conic-gradient(from var(--fa), rgba(0,0,0,0) 0deg 200deg, var(--spin-soft) 270deg,
              var(--spin-hot) 320deg, var(--spin-soft) 352deg, rgba(0,0,0,0) 360deg);
  filter:blur(.6px);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  animation:borderspin 12s linear infinite}
/* 只要"当前那张卡"呼吸：给当前卡加 .now（其余卡静态描边）*/
.card:not(.now) .panel{animation:none;box-shadow:inset 0 0 0 2px #1a2430}
:root[data-theme="light"] .card:not(.now) .panel{animation:none;box-shadow:inset 0 0 0 2px #dde4ee}
.card.now .panel{animation-name:framebreathe-warm}

/* ── 圆盘 + 环形进度/占比图 ───────────────────────────────────────────── */
/* DOM（SVG 内容由 JS 填，画法见 README「圆盘与圆环」）：
   <div class="disc-wrap"><div class="disc">
     <svg class="ringsvg" viewBox="0 0 300 300" aria-hidden="true"></svg>
     <div class="disc-face"><b>大字</b><span>小标</span></div>
   </div><div class="legend">…</div></div> */
.disc-wrap{display:grid;grid-template-columns:300px 1fr;gap:30px;align-items:center}
.disc{position:relative;width:300px;height:300px;border-radius:50%;
  background:radial-gradient(circle at 50% 50%, #0c121a 0%, #080d13 42%, #05080b 80%);
  animation:discbreathe 10s ease-in-out infinite}
:root[data-theme="light"] .disc{
  background:radial-gradient(circle at 50% 50%, #ffffff 0%, #f4f7fc 52%, #e6ecf5 100%);
  animation-name:discbreathe-lt}
.ringsvg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.disc-face{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;pointer-events:none;text-align:center}
.disc-face b{font-family:var(--mono);font-size:calc(50px * var(--u));font-weight:700;
  letter-spacing:-.02em;line-height:1}
.disc-face b.sm{font-size:calc(26px * var(--u))}   /* 数字长的时候挂 .sm */
.disc-face span{font-size:calc(11px * var(--u));color:var(--dim2);letter-spacing:.26em;
  margin-left:.26em;margin-top:6px}
/* 圆环着色（几何常量见 README；这两个类由页面覆盖成自己的配色）*/
.ring-scale{stroke:#26333f}
.ring-track{stroke:#141b24}
.ring-arc{opacity:.92;filter:drop-shadow(0 0 9px rgba(126,178,196,.35))}
.ring-glow{stroke-linecap:round;opacity:0;animation:headglowbreathe 10s ease-in-out infinite;pointer-events:none}
:root[data-theme="light"] .ring-scale{stroke:#c9d4e4}
:root[data-theme="light"] .ring-track{stroke:#e3e8f0}
:root[data-theme="light"] .ring-arc{opacity:1;filter:drop-shadow(0 1px 2px rgba(28,36,49,.18))}

/* 图例：14px 色块 + 大写间距的标签 + 右侧 mono 数字 */
.legend{display:grid;gap:16px}
.lg{display:grid;grid-template-columns:14px 1fr;gap:14px;align-items:start}
.lg i{width:14px;height:14px;border-radius:4px;margin-top:4px}
.lg .t{font-size:12.5px;letter-spacing:2.5px;color:var(--dim2)}
.lg .t b{float:right;font-family:var(--mono);font-size:19px;letter-spacing:0;font-weight:700;color:var(--text)}
.lg .s{margin-top:4px;font-family:var(--mono);font-size:11.5px;color:var(--dim);line-height:1.6}

/* ── 数字行（账本"账户/头寸"那种）────────────────────────────────────── */
.kv{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  padding:9px 0;border-top:1px solid var(--rule2)}
.kv:first-child{border-top:0;padding-top:0}
.kv .k{font-size:12.5px;color:var(--dim);letter-spacing:.5px}
.kv .k small{display:block;font:10px var(--mono);color:var(--dim2);letter-spacing:0;margin-top:2px}
.kv .v{font-family:var(--mono);font-size:20px;font-weight:700;white-space:nowrap}
.kv .v.neg{color:var(--fire)} .kv .v.pos{color:var(--green)} .kv .v.dim{color:var(--dim2);font-size:17px}
.big{font-family:var(--mono);font-size:26px;font-weight:700;letter-spacing:.3px}

/* ── 列表行（流水/记录）：三列 = 时刻 | 内容 | 数额 ───────────────────── */
.row{display:grid;grid-template-columns:92px minmax(0,1fr) auto;gap:12px;align-items:baseline;
  padding:calc(8px * var(--u)) 0;border-top:1px solid var(--rule2)}
.row:first-child{border-top:0}
.row .when{font:11px var(--mono);color:var(--dim2);letter-spacing:.3px;line-height:1.5}
.row .when b{display:block;color:var(--dim);font-weight:600}
.row .what{min-width:0}
.row .desc{font-size:13.5px;line-height:1.45;word-break:break-word}
.row .meta{margin-top:3px;display:flex;flex-wrap:wrap;gap:6px;align-items:center;
  font:11px var(--mono);color:var(--dim2)}
.row .amt{font-family:var(--mono);font-size:15.5px;font-weight:700;text-align:right;white-space:nowrap}
.amt.neg{color:var(--fire)} .amt.pos{color:var(--green)}
.badge{font:10.5px var(--mono);letter-spacing:.5px;padding:1px 6px;border-radius:5px;
  border:1px solid var(--rule2);color:var(--dim);white-space:nowrap}
.badge.cat{color:var(--batt);border-color:var(--rule)}
.badge.ch{color:var(--dim2)}
.tag{border:1px solid var(--rule);border-radius:999px;padding:1px 8px;font:10.5px var(--mono);
  color:var(--dim2);white-space:nowrap}
.tag.ok{color:var(--green);border-color:var(--green)}
.tag.bad{color:var(--fire);border-color:var(--fire)}
/* 可展开的详情（note/说明）：默认折起来，别把长文本铺在列表里 */
details.note{margin-top:5px}
details.note summary{font:11px var(--mono);color:var(--dim2);cursor:pointer;list-style:none;
  display:inline-flex;align-items:center;gap:5px;border-bottom:1px dashed var(--rule);padding-bottom:1px}
details.note summary::-webkit-details-marker{display:none}
details.note summary:hover{color:var(--text)}
.note-body{margin-top:6px;font-size:12px;line-height:1.7;color:var(--dim);
  border-left:2px solid var(--rule);padding:2px 0 2px 10px;word-break:break-word}
.note-body code{font:11.5px var(--mono);background:var(--card2);padding:1px 4px;border-radius:4px}
.note-body b{color:var(--text)}
.empty{font-size:12.5px;color:var(--dim2);padding:6px 0}

/* ── 输入 / 筛选条 ────────────────────────────────────────────────────── */
.filters{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}
.filters input,.filters select{font:inherit;font-size:calc(12.5px * var(--u));
  padding:calc(5px * var(--u)) calc(10px * var(--u));border-radius:999px;
  border:1px solid var(--rule);background:var(--card2);color:var(--text);min-width:0}
.filters input[type=search]{flex:1 1 200px}
.filters input:focus,.filters select:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(87,169,230,.16)}

/* ── 可点状态按钮（考勤的 `.att-st`；家里那台直接复用了这个类名）─────── */
.att-st{font:inherit;font-size:calc(11.5px * var(--u));padding:calc(4px * var(--u)) calc(10px * var(--u));
  border-radius:999px;border:1px solid var(--rule);background:transparent;color:var(--dim);
  cursor:pointer;white-space:nowrap;transition:color .12s,border-color .12s,background .12s,box-shadow .15s}
.att-st:hover{color:var(--text);border-color:#2f4054}
.att-st.on[data-k="ok"]     {background:rgba(108,207,158,.16);border-color:var(--green);color:var(--green);box-shadow:0 0 14px rgba(108,207,158,.25)}
.att-st.on[data-k="leave"]  {background:rgba(87,169,230,.16);border-color:var(--blue);color:var(--blue);box-shadow:0 0 14px rgba(87,169,230,.22)}
.att-st.on[data-k="ill"]    {background:rgba(232,160,106,.16);border-color:var(--fire);color:var(--fire);box-shadow:0 0 14px rgba(232,160,106,.22)}
.att-st.on[data-k="pause"]  {background:rgba(112,134,168,.18);border-color:var(--day);color:#a9bcd6}
.att-st.on[data-k="absent"] {background:rgba(224,104,94,.17);border-color:#e0685e;color:#f0857b;box-shadow:0 0 14px rgba(224,104,94,.24)}

/* 考勤那种"一行一条 + 节次徽标" */
.att-row{display:flex;flex-wrap:wrap;align-items:center;gap:9px;padding:calc(6px * var(--u)) 0;
  font-size:calc(13px * var(--u));border-top:1px solid var(--rule2)}
.att-slot{font:calc(11px * var(--u)) var(--mono);color:var(--batt);letter-spacing:.5px;
  padding:1px 5px;border:1px solid var(--rule2);border-radius:5px}

/* ── toast ────────────────────────────────────────────────────────────── */
.toast{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);
  background:#0c121a;color:var(--text);border:1px solid var(--rule);
  font-size:13px;padding:9px 16px;border-radius:999px;z-index:9;box-shadow:0 6px 20px rgba(0,0,0,.5)}
.toast.err{border-color:#e0685e;color:#f0857b}
:root[data-theme="light"] .toast{background:#fff;box-shadow:0 8px 24px rgba(28,36,49,.16)}
:root[data-theme="light"] .toast.err{border-color:#b3403a;color:#b3403a}

footer{margin-top:calc(18px * var(--u));font:11px var(--mono);color:var(--dim2);line-height:1.8}
footer a{color:var(--dim);text-decoration:none;border-bottom:1px dashed var(--rule)}
footer a:hover{color:var(--text)}

/* ═══ 动效：10s 一轮 = 4s 涨 / 6s 落（呼气长于吸气），峰值统一写在 40% ═══ */
@keyframes framebreathe{           /* 深色卡片的"光边框"呼吸 */
  0%,100%{box-shadow:inset 0 0 0 2px #1a2430, 0 0 0 0 rgba(126,178,196,0), inset 0 0 22px rgba(126,178,196,0)}
  40%    {box-shadow:inset 0 0 0 2px #3b5a79, 0 0 34px rgba(126,178,196,.20), inset 0 0 22px rgba(126,178,196,.07)}
}
@keyframes framebreathe-lt{        /* 亮色：内高光 + 外投影（不是深色那套的颜色反色） */
  0%,100%{box-shadow:inset 0 1px 0 rgba(255,255,255,1), 0 1px 2px rgba(28,36,49,.06), 0 4px 12px rgba(28,36,49,.07)}
  40%    {box-shadow:inset 0 1px 0 rgba(255,255,255,1), 0 2px 5px rgba(28,36,49,.09), 0 12px 32px rgba(28,36,49,.13)}
}
@keyframes framebreathe-warm{      /* "当前那张卡"的暖色变体 */
  0%,100%{box-shadow:inset 0 0 0 2px rgba(226,140,80,.34), 0 0 0 0 rgba(214,140,84,0), inset 0 0 22px rgba(226,140,80,.05)}
  40%    {box-shadow:inset 0 0 0 2px rgba(238,158,96,.62), 0 0 34px rgba(226,146,84,.22), inset 0 0 22px rgba(226,146,84,.09)}
}
@keyframes discbreathe{            /* 圆盘：压暗谷值 + 峰值往外铺 + 峰值色偏青 */
  0%,100%{box-shadow:inset 0 0 0 1px rgba(255,255,255,.05), 0 8px 40px rgba(0,0,0,.5), 0 0 14px 0 rgba(86,170,224,.04)}
  40%    {box-shadow:inset 0 0 0 1px rgba(255,255,255,.05), 0 8px 40px rgba(0,0,0,.5), 0 0 78px 16px rgba(92,184,240,.30)}
}
@keyframes discbreathe-lt{
  0%,100%{box-shadow:inset 0 1px 0 rgba(255,255,255,1), inset 0 -3px 9px rgba(28,36,49,.05),
          0 1px 2px rgba(28,36,49,.07), 0 4px 12px rgba(28,36,49,.09)}
  40%    {box-shadow:inset 0 1px 0 rgba(255,255,255,1), inset 0 -3px 9px rgba(28,36,49,.05),
          0 2px 5px rgba(28,36,49,.10), 0 14px 36px rgba(28,36,49,.18)}
}
@property --fa{syntax:"<angle>";inherits:false;initial-value:0deg}
@keyframes borderspin{to{--fa:360deg}}
@keyframes headglowbreathe{0%,100%{opacity:.12} 40%{opacity:.55}}
/* 亮色必须整套换名（keyframes 不读变量）*/
:root[data-theme="light"] .panel,
:root[data-theme="light"] .disc-wrap{animation-name:framebreathe-lt}
:root[data-theme="light"] .card.now .panel{animation-name:framebreathe-warm-lt}

/* ── 响应式：家族只有**一个**宽度断点 ─────────────────────────────────── */
@media (min-width:680px){
  .disc-wrap{grid-template-columns:280px minmax(0,1fr)}
  .disc{margin:0;width:280px;height:280px}
}
@media (max-width:679px){
  .disc-wrap{grid-template-columns:minmax(0,1fr);gap:calc(16px * var(--u))}
  .disc{width:min(280px,68vw);height:min(280px,68vw);margin:0 auto}
}
/* 让位给页面自己的 class 驱动（信息屏那套：.single 单列、.compact 收紧）*/
.single .two-col{grid-template-columns:minmax(0,1fr)}
.compact .panel{padding:10px 13px 12px}
.compact .wrap{padding:8px 16px 12px}

@media (prefers-reduced-motion:reduce){
  .panel,.disc,.disc-wrap{animation:none}
  .panel::after,.disc-wrap::after{animation:none;opacity:.45}
  .headglow{animation:none;opacity:.4}
  .panel,.disc-wrap{box-shadow:inset 0 0 0 2px var(--rule)}
}
