/* ════════════════════════════════════════════════════════════
   阿皮公益站 —— 搪瓷公示牌
   结构色只有靛青和墨；描红、釉绿、姜黄三色只给状态，别的地方不许用。
   ════════════════════════════════════════════════════════════ */

:root{
  /* 色 */
  --porcelain:  #F1F3EE;   /* 瓷白，页面底 */
  --porcelain-hi:#FDFEFB;  /* 牌面 */
  --indigo:     #1B3A6B;   /* 靛青，结构 */
  --indigo-ink: #142C52;
  --vermilion:  #C6362C;   /* 描红，只给印章和停摆 */
  --glaze:      #2E6F52;   /* 釉绿，通行 */
  --ginger:     #B4801F;   /* 姜黄，拥挤 */
  --ink:        #191C1A;   /* 墨，正文 */
  --ink-60:     #5C625E;
  --ink-35:     #9AA09B;
  --hair:       rgba(27,58,107,.16);

  /* 字 */
  --sans: "Microsoft YaHei UI","Microsoft YaHei","PingFang SC","Hiragino Sans GB",system-ui,sans-serif;
  --song: "FangSong","仿宋","FangSong_GB2312","STFangsong",serif;  /* 公文体，用来说公示话 */
  --mono: "IBM Plex Mono",Consolas,"Cascadia Mono",ui-monospace,monospace;

  /* 间距 */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px; --s8:72px;
  --gutter: clamp(20px, 5vw, 56px);
  --maxw: 1180px;
}

*,*::before,*::after{ box-sizing:border-box; }

html{ -webkit-text-size-adjust:100%; }

body{
  margin:0;
  background:var(--porcelain);
  color:var(--ink);
  font:400 15px/1.65 var(--sans);
  /* 搪瓷胎上极淡的颗粒 */
  background-image:
    radial-gradient(circle at 18% 12%, rgba(27,58,107,.035), transparent 42%),
    radial-gradient(circle at 84% 78%, rgba(27,58,107,.028), transparent 46%);
}

a{ color:inherit; }

:focus-visible{
  outline:2.5px solid var(--indigo);
  outline-offset:3px;
  border-radius:2px;
}

.wrap{ max-width:var(--maxw); margin:0 auto; padding:0 var(--gutter); }

/* 搪瓷牌配方：厚靛青边 + 里面一圈白釉 + 一圈淡影，四角微圆
   这三层叠起来才是搪瓷，少一层就变成普通描边卡片。 */
.enamel{
  background:var(--porcelain-hi);
  border:2px solid var(--indigo);
  border-radius:5px;
  box-shadow:
    inset 0 0 0 1.5px #fff,
    inset 0 0 0 3.5px rgba(27,58,107,.15),
    0 1px 2px rgba(25,28,26,.07);
}

/* ── 顶栏 ─────────────────────────────────────────────────── */
.topbar{
  position:sticky; top:0; z-index:20;
  background:var(--indigo);
  color:#EAF0F7;
  border-bottom:2px solid var(--indigo-ink);
}
.topbar-in{
  max-width:var(--maxw); margin:0 auto;
  padding:0 var(--gutter);
  height:52px;
  display:flex; align-items:center; gap:var(--s4);
}
.topbar-no{
  font:500 11.5px/1 var(--mono);
  letter-spacing:.1em;
  color:rgba(234,240,247,.62);
  white-space:nowrap;
}
.topbar-rule{
  flex:1; height:0;
  border-top:1px dashed rgba(234,240,247,.26);
}
.search{
  position:relative; flex:0 0 auto; width:min(280px,44vw);
}
.search-input{
  width:100%; height:32px;
  padding:0 30px 0 var(--s3);
  font:400 13.5px/1 var(--sans);
  color:#fff;
  background:rgba(255,255,255,.11);
  border:1.5px solid rgba(234,240,247,.3);
  border-radius:3px;
}
.search-input::placeholder{ color:rgba(234,240,247,.5); }
.search-input:hover{ background:rgba(255,255,255,.16); }
.search-input:focus{ outline:none; background:rgba(255,255,255,.2); border-color:#fff; }
.search-key{
  position:absolute; right:7px; top:50%; transform:translateY(-50%);
  font:500 10.5px/16px var(--mono);
  min-width:16px; text-align:center;
  color:rgba(234,240,247,.62);
  border:1px solid rgba(234,240,247,.34);
  border-radius:2px;
  pointer-events:none;
}
.search-input:focus ~ .search-key{ opacity:0; }

/* ── 抬头：搪瓷大牌 + 今日公示 ────────────────────────────── */
.head{
  display:grid;
  grid-template-columns:minmax(0,1fr) 232px;
  gap:var(--s5);
  align-items:stretch;
  padding-top:var(--s7);
}

.board{
  position:relative;
  padding:var(--s6) var(--s6) var(--s7);
}
.board-name{
  margin:0;
  font-family:var(--sans);
  font-weight:700;
  font-size:clamp(34px,5.6vw,56px);
  line-height:1.04;
  letter-spacing:-.022em;
  color:var(--indigo);
}
.board-name em{
  font-style:normal;
  /* 「公益」两个字压在青底上，像牌子上单独烧的一块 */
  background:var(--indigo);
  color:var(--porcelain-hi);
  padding:0 .1em .06em;
  margin:0 .02em;
  border-radius:2px;
}
.board-tag{
  margin:var(--s4) 0 0;
  max-width:34ch;
  font:400 16px/1.8 var(--song);
  color:var(--ink-60);
  /* 中文没有词边界，交给浏览器断行常会把词劈开。
     所以断行点写在 data/sites.js 的 tagline 里（用 \n），这里只负责认它。 */
  white-space:pre-line;
  line-break:strict;
}
/* 这一行是整页的承诺，也是把大牌下半截填实的东西 */
.board-vow{
  margin:var(--s5) 0 0;
  padding-top:var(--s4);
  max-width:34ch;
  border-top:1px dashed var(--hair);
  font:400 13px/1.75 var(--sans);
  color:var(--ink-35);
  line-break:strict;
}

/* 印章：压在牌角上，唯一的红。整页就冒这一个险。
   印文按现代阅读顺序从左到右排（免费/公用）。传统印章是从右往左读的，
   但这枚章是给群里点进来的人看的，认得出比讲究更重要。 */
.seal{
  position:absolute; right:var(--s5); bottom:var(--s5);
  width:98px; height:98px;
  padding:15px;
  display:grid;
  grid-template-columns:1fr 1fr; grid-template-rows:1fr 1fr;
  place-items:center;
  color:var(--vermilion);
  border:2.5px solid currentColor;
  border-radius:50%;
  box-shadow:inset 0 0 0 2px #fff, inset 0 0 0 3.5px currentColor;
  transform:rotate(-9deg);
  mix-blend-mode:multiply;
  opacity:.9;
}
.seal span{
  font:700 19px/1 var(--sans);
  letter-spacing:0;
}

/* 今日公示：右边这块用公文体，语气是通知不是营销 */
.notice{
  padding:var(--s5);
  display:flex; flex-direction:column;
}
.notice-h{
  margin:0 0 var(--s3);
  padding-bottom:var(--s2);
  font:700 13px/1 var(--sans);
  letter-spacing:.16em;
  color:var(--indigo);
  border-bottom:1.5px solid var(--hair);
}
/* 三行数字居中占住中段，不在面板底部留空洞 */
.notice-list{
  flex:1 1 auto;
  display:flex; flex-direction:column; justify-content:center;
  gap:var(--s1);
}
.notice-row{
  display:flex; align-items:baseline; gap:var(--s2);
  font:400 14px/1.4 var(--song);
  color:var(--ink-60);
}
.notice-n{
  font:600 24px/1.1 var(--mono);
  min-width:1.7em;
  text-align:right;
  font-variant-numeric:tabular-nums;
}
.notice-row.up    .notice-n{ color:var(--glaze); }
.notice-row.busy  .notice-n{ color:var(--ginger); }
.notice-row.down  .notice-n{ color:var(--vermilion); }
.notice-foot{
  margin:var(--s4) 0 0; padding-top:var(--s3);
  border-top:1px dashed var(--hair);
  font:400 12px/1.5 var(--mono);
  color:var(--ink-35);
}

/* ── 交流群门牌 ────────────────────────────────────────────
   不做成第四块站点牌（那会让人以为群也是个中转站），
   做成挂在公示牌旁边的一枚横向小门牌：靛青实底、左边一道留白凹槽。
   整页唯一的靛青实底元素，所以它自然成为公示牌之后第二个落眼点。 */
.plate{
  display:flex; align-items:center; gap:var(--s4);
  margin-top:var(--s5);
  padding:var(--s4) var(--s5);
  text-decoration:none;
  color:var(--porcelain-hi);
  background:var(--indigo);
  border:2px solid var(--indigo);
  border-radius:5px;
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.14);
  transition:background .16s ease, transform .16s ease;
}
.plate:hover{
  background:var(--indigo-ink);
  transform:translateY(-2px);
}

/* 竖排的「交流群」，像门牌左边烧上去的那一格 */
.plate-k{
  flex:0 0 auto;
  padding-right:var(--s4);
  border-right:1px solid rgba(255,255,255,.22);
  font:700 12px/1.5 var(--sans);
  letter-spacing:.28em;
  color:rgba(255,255,255,.62);
  writing-mode:vertical-rl;
  text-orientation:upright;
}

.plate-body{ flex:1 1 auto; min-width:0; }

.plate-name{
  display:block;
  font:700 17px/1.4 var(--sans);
  letter-spacing:-.005em;
}
.plate-desc{
  display:block;
  margin-top:2px;
  font:400 13px/1.6 var(--song);
  color:rgba(255,255,255,.72);
}

.plate-go{
  flex:0 0 auto;
  display:flex; align-items:center; gap:var(--s2);
  font:500 11.5px/1 var(--mono);
  letter-spacing:.06em;
  color:rgba(255,255,255,.72);
}
.plate-arrow{ transition:transform .16s ease; font-size:14px; }
.plate:hover .plate-arrow{ transform:translateX(3px); }

.plate:focus-visible{
  outline:2.5px solid var(--indigo);
  outline-offset:3px;
}

@media (max-width:640px){
  .plate{
    align-items:stretch;
    gap:var(--s3);
    padding:var(--s4);
  }
  .plate-k{
    writing-mode:horizontal-tb;
    padding:0 0 var(--s2);
    border-right:0;
    border-bottom:1px solid rgba(255,255,255,.22);
    letter-spacing:.2em;
  }
  /* 窄屏改成竖排：门牌左格挪到顶部，箭头行落到底部 */
  .plate{ flex-direction:column; }
  .plate-go{ justify-content:space-between; padding-top:var(--s2); }
}

/* ── 筛选条 ───────────────────────────────────────────────── */
.filters{
  display:flex; flex-wrap:wrap; align-items:center; gap:var(--s2);
  padding-top:var(--s7);
}
.chip{
  appearance:none;
  padding:6px 15px;
  font:500 13.5px/1.4 var(--sans);
  color:var(--indigo);
  background:transparent;
  border:1.5px solid var(--hair);
  border-radius:99px;
  cursor:pointer;
  transition:background .14s, border-color .14s, color .14s;
}
.chip:hover{ border-color:var(--indigo); background:rgba(27,58,107,.05); }
.chip[aria-pressed="true"]{
  background:var(--indigo); border-color:var(--indigo); color:var(--porcelain-hi);
}
.filters-sp{ flex:1 1 var(--s5); min-width:var(--s3); }
.toggle{
  display:inline-flex; align-items:center; gap:var(--s2);
  font:400 13.5px/1.4 var(--sans);
  color:var(--ink-60);
  cursor:pointer; user-select:none;
}
.toggle input{
  width:15px; height:15px; margin:0;
  accent-color:var(--indigo);
  cursor:pointer;
}
.toggle:hover{ color:var(--indigo); }

/* ── 分区 ─────────────────────────────────────────────────── */
/* 自建 / 公益 不是装饰性分栏，它编码的是「出事找谁修」。 */
.group{ padding-top:var(--s7); }

.group-h{
  display:flex; align-items:baseline; gap:var(--s3);
  padding-bottom:var(--s5);
}
.group-bar{
  flex:0 0 auto;
  width:5px; height:19px;
  border-radius:1px;
  transform:translateY(2px);
}
.group-self .group-bar{ background:var(--indigo); }
.group-pub  .group-bar{ background:var(--ink); }
.group-t{
  margin:0;
  font:700 19px/1.2 var(--sans);
  letter-spacing:.01em;
  color:var(--ink);
}
.group-sub{
  font:400 13.5px/1.4 var(--song);
  color:var(--ink-35);
}
.group-rule{ flex:1 1 auto; height:0; border-top:1px solid var(--hair); transform:translateY(-3px); }
.group-n{
  font:500 12px/1 var(--mono);
  color:var(--ink-35);
  font-variant-numeric:tabular-nums;
}

.grid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(262px,1fr));
  gap:var(--s4);
  list-style:none; margin:0; padding:0;
}

/* ── 一个入口 = 一块小搪瓷牌 ──────────────────────────────── */
/* 牌面是 .card-body，链接和「复制地址」是它里面两个并列的东西，
   不嵌套、不抢同一个角，所以不需要靠 :hover 互相覆盖。 */
.card{ display:flex; }

.card-body{
  display:flex; flex-direction:column;
  flex:1 1 auto;
  padding:var(--s5) var(--s5) var(--s3);
  transition:transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.card:hover .card-body{
  transform:translateY(-2px);
  border-color:var(--indigo-ink);
  box-shadow:
    inset 0 0 0 1.5px #fff,
    inset 0 0 0 3.5px rgba(27,58,107,.24),
    0 5px 14px rgba(25,28,26,.10);
}

.card-link{
  display:block;
  flex:1 1 auto;
  text-decoration:none;
}
.card-top{
  display:flex; align-items:flex-start; justify-content:space-between; gap:var(--s3);
}
.card-name{
  margin:0;
  font:700 17px/1.35 var(--sans);
  letter-spacing:-.005em;
  color:var(--indigo);
}
.card-name::after{
  content:"↗";
  display:inline-block;
  margin-left:.35em;
  font-weight:400;
  font-size:.82em;
  opacity:.4;
  transition:opacity .16s ease, transform .16s ease;
}
.card:hover .card-name::after{ opacity:1; transform:translate(2px,-2px); }

.card-desc{
  margin:var(--s2) 0 0;
  font:400 13.5px/1.65 var(--sans);
  color:var(--ink-60);
}
/* 模型标签：现在是每张牌上最要紧的信息，所以给它重量。
   用靛青（结构色），不新开颜色——状态色三个已经够用了。 */
.models{
  display:flex; flex-wrap:wrap; gap:var(--s1);
  margin:var(--s3) 0 0; padding:0;
  list-style:none;
}
.model{
  padding:3px 9px;
  font:600 12px/1.4 var(--mono);
  letter-spacing:.02em;
  color:var(--porcelain-hi);
  background:var(--indigo);
  border-radius:2px;
}
/* 「未知」不是一个能挑的模型，只是还没试出来——所以做成空心的 */
.model-unknown{
  color:var(--ink-35);
  background:transparent;
  border:1.5px dashed var(--hair);
  font-weight:400;
}

/* 门槛：进去之前的第一道关，用等宽体单独占一行 */
.card-gate{
  margin:var(--s3) 0 0;
  font:400 12.5px/1.5 var(--mono);
  color:var(--ink-60);
}
.gate-k{
  display:inline-block;
  margin-right:var(--s2);
  font:600 10.5px/1.4 var(--sans);
  letter-spacing:.14em;
  color:var(--ink-35);
}

/* note 在任何状态下都显示：通行的站写补充，出问题的站写怎么了。
   默认是靛青（中性告知），busy/down 才染成警示色。 */
.card-note{
  margin:var(--s3) 0 0;
  padding-left:var(--s3);
  border-left:2px solid currentColor;
  font:400 13px/1.6 var(--song);
  color:var(--indigo);
}
.card-busy .card-note{ color:var(--ginger); }
.card-down .card-note{ color:var(--vermilion); }

.card-foot{
  display:flex; align-items:center; justify-content:space-between; gap:var(--s2);
  margin-top:var(--s4);
  padding-top:var(--s2);
  border-top:1px dashed var(--hair);
}
.card-host{
  min-width:0;
  font:400 11.5px/1 var(--mono);
  letter-spacing:.01em;
  color:var(--ink-35);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.copy{
  flex:0 0 auto;
  padding:4px 8px;
  font:500 11px/1.35 var(--sans);
  color:var(--ink-35);
  background:transparent;
  border:1.5px solid transparent;
  border-radius:3px;
  cursor:pointer;
  transition:color .14s, border-color .14s;
}
.copy:hover{ color:var(--indigo); border-color:var(--hair); }

/* 状态签 */
.tag{
  flex:0 0 auto;
  padding:3px 8px;
  font:600 11px/1.35 var(--sans);
  letter-spacing:.08em;
  border-radius:2px;
  color:#fff;
  white-space:nowrap;
}
.tag-up   { background:var(--glaze); }
.tag-busy { background:var(--ginger); }
.tag-down { background:var(--vermilion); }

/* 停摆的牌子不藏起来，照样挂着，但看起来就是块掉了釉的旧牌 */
.card-down .card-body{
  background:#F6F5F1;
  border-color:rgba(27,58,107,.4);
  border-style:dashed;
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.7);
}
.card-down .card-name{ color:var(--ink-60); }
.card-down .card-desc{ color:var(--ink-35); }
.card-down:hover .card-body{
  transform:none;
  border-color:var(--vermilion);
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.7), 0 3px 10px rgba(25,28,26,.07);
}

/* ── 空态：是邀请，不是道歉 ───────────────────────────────── */
.empty{
  padding:var(--s8) var(--s5);
  text-align:center;
  font:400 15px/1.8 var(--song);
  color:var(--ink-60);
}
.empty b{ color:var(--indigo); font-weight:700; }

/* ── 页脚：钱和约定 ───────────────────────────────────────── */
.foot{
  margin-top:var(--s8);
  padding:var(--s6) 0 var(--s8);
  border-top:2px solid var(--indigo);
}
.foot-in{
  display:grid;
  grid-template-columns:minmax(0,300px) minmax(0,1fr);
  gap:var(--s7) var(--s8);
}
/* 只剩一栏约定时，别把它压在 300px 的窄列里 */
.foot-solo{
  grid-template-columns:minmax(0,72ch);
}
.foot-h{
  margin:0 0 var(--s3);
  font:700 13px/1 var(--sans);
  letter-spacing:.16em;
  color:var(--indigo);
}
.rules{ margin:0; padding:0; list-style:none; }
.rules li{
  padding:var(--s2) 0 var(--s2) var(--s5);
  position:relative;
  font:400 14px/1.7 var(--song);
  color:var(--ink-60);
  border-bottom:1px dashed var(--hair);
}
.rules li:last-child{ border-bottom:0; }
.rules li::before{
  content:"—";
  position:absolute; left:0; top:var(--s2);
  color:var(--indigo);
  font-family:var(--mono);
}
.rules code{
  padding:1px 5px;
  font:400 12.5px/1.4 var(--mono);
  color:var(--indigo);
  background:rgba(27,58,107,.06);
  border-radius:2px;
}

/* ── 已复制提示 ───────────────────────────────────────────── */
.toast{
  position:fixed; left:50%; bottom:28px;
  transform:translate(-50%,14px);
  padding:9px 18px;
  font:500 13px/1.4 var(--sans);
  color:var(--porcelain-hi);
  background:var(--indigo);
  border-radius:3px;
  box-shadow:0 4px 16px rgba(25,28,26,.2);
  opacity:0; pointer-events:none;
  transition:opacity .18s, transform .18s;
  z-index:40;
}
.toast.on{ opacity:1; transform:translate(-50%,0); }

/* ── 进场：整页只有这一段编排好的动作 ─────────────────────── */
/* backwards 会让元素在 delay 期间停在起始帧（opacity:0）——
   所以延迟必须短，否则慢网络下截图/首屏看起来像空页。
   起始透明度不给 0，给 .001 也不行（同样看不见），
   办法是把总延迟压到 0.2s 以内，并且从 opacity:.35 起跳。 */
@keyframes rise{
  from{ opacity:.35; transform:translateY(8px); }
  to{ opacity:1; transform:none; }
}
@keyframes stamp{
  from{ opacity:0; transform:rotate(-9deg) scale(1.5); }
  60%{ opacity:.9; }
  to{ opacity:.9; transform:rotate(-9deg) scale(1); }
}
.is-enter .enter{ animation:rise .34s cubic-bezier(.2,.7,.3,1) backwards; }
.is-enter .seal{ animation:stamp .3s cubic-bezier(.3,1.5,.5,1) .3s backwards; }

/* ── 窄屏 ─────────────────────────────────────────────────── */
@media (max-width:880px){
  .head{ grid-template-columns:1fr; padding-top:var(--s6); }
  .board{ padding:var(--s5) var(--s5) var(--s6); }
  .seal{ width:74px; height:74px; right:var(--s4); bottom:var(--s4); }
  .seal span{ font-size:14px; }
  .board-tag{ max-width:none; padding-right:86px; }
  .foot-in{ grid-template-columns:1fr; gap:var(--s6); }
}
@media (max-width:560px){
  .topbar-no{ display:none; }
  .search{ width:100%; }
  .search-input{ height:36px; }
  .grid{ grid-template-columns:1fr; }
  .board-tag{ padding-right:0; }
  .seal{ position:static; margin:var(--s5) 0 0; }
}

/* 触摸设备上把小目标撑到能点的大小 */
@media (hover:none){
  .copy{ padding:9px 12px; margin:-5px -4px; }
  .toggle{ padding:8px 0; }
  .toggle input{ width:19px; height:19px; }
  .chip{ padding:9px 16px; }
}

@media (prefers-reduced-motion:reduce){
  *{ animation:none !important; transition:none !important; }
  .card:hover .card-body{ transform:none; }
  .card:hover .card-name::after{ transform:none; }
}

@media print{
  .topbar,.filters,.copy,.toast{ display:none; }
  body{ background:#fff; }
}
