
:root{
  --bg:#040509;--bg-soft:#0e1118;
  --line:rgba(200,210,255,.08);--line-strong:rgba(200,210,255,.17);
  --text:#e8eaf0;--text-dim:#8a90a3;--text-faint:#565c6e;
  --accent:#8b93ff;--accent2:#6ee7d8;--accent-soft:rgba(139,147,255,.12);
  --r:14px;
  /* 原为 Google Fonts 的 Space Grotesk;CSP 只允许同源,外链字体会被拦,
     改用系统无衬线栈(苹果设备上即 SF Pro,与全站视觉一致) */
  --en:-apple-system,'SF Pro Display','Helvetica Neue',Arial,sans-serif;
  --cn:-apple-system,'PingFang SC','Hiragino Sans','Noto Sans SC',sans-serif;
  --mono:ui-monospace,'SF Mono',Consolas,monospace;
}
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;overflow:hidden}
body{background:var(--bg);color:var(--text);font-family:var(--cn);font-weight:300;
  -webkit-font-smoothing:antialiased;cursor:none;user-select:none;-webkit-user-select:none;touch-action:none}
a,button,input,textarea,dialog{cursor:none}
@media (pointer:coarse){body,a,button,input,textarea,dialog{cursor:auto}}
::selection{background:var(--accent-soft);color:var(--accent)}
@supports (corner-shape: squircle){dialog{corner-shape:squircle}}

.nebula{position:fixed;inset:0;z-index:0;pointer-events:none;filter:blur(70px);opacity:.3}
.nebula i{position:absolute;border-radius:50%;mix-blend-mode:screen}
.nebula .n1{width:46vw;height:46vw;left:8vw;top:-12vw;background:radial-gradient(circle,rgba(99,91,255,.26),transparent 65%);animation:drift1 26s ease-in-out infinite alternate}
.nebula .n2{width:38vw;height:38vw;right:-6vw;top:6vw;background:radial-gradient(circle,rgba(110,231,216,.13),transparent 65%);animation:drift2 32s ease-in-out infinite alternate}
.nebula .n3{width:42vw;height:42vw;left:30vw;bottom:-18vw;background:radial-gradient(circle,rgba(155,90,255,.11),transparent 65%);animation:drift1 40s ease-in-out infinite alternate-reverse}
@keyframes drift1{to{transform:translate(6vw,4vh) scale(1.12)}}
@keyframes drift2{to{transform:translate(-5vw,6vh) scale(.92)}}

canvas#sky{position:fixed;inset:0;z-index:1}
#cursor{position:fixed;z-index:99;width:6px;height:6px;border-radius:50%;pointer-events:none;
  background:var(--accent);box-shadow:0 0 12px 2px var(--accent-soft),0 0 4px var(--accent);
  transform:translate(-50%,-50%);transition:width .2s,height .2s;left:-50px;top:-50px}
#cursor.hot{width:12px;height:12px}
#cursor.star{width:16px;height:16px;background:transparent;border:1.5px solid var(--accent);box-shadow:0 0 14px var(--accent-soft)}
#cursor.grab{width:10px;height:10px;background:transparent;border:1.5px solid var(--text-dim)}
@media (pointer:coarse){#cursor{display:none}}

@keyframes up{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}

#searchWrap{position:fixed;top:22px;left:32px;z-index:6;width:min(250px,60vw);opacity:0}
body.ready #searchWrap{animation:up .8s ease .45s forwards}
#q{width:100%;background:rgba(14,17,24,.7);backdrop-filter:blur(10px);
  border:1px solid var(--line-strong);border-radius:9px;padding:9px 13px;
  color:var(--text);font-family:var(--mono);font-size:12px;letter-spacing:.05em;outline:none;
  transition:border-color .2s}
#q::placeholder{color:var(--text-faint);font-family:var(--cn)}
#q:focus{border-color:color-mix(in srgb,var(--accent) 50%,transparent)}
#qList{margin-top:6px;border-radius:9px;overflow:hidden;display:none;
  background:rgba(14,17,24,.92);backdrop-filter:blur(14px);border:1px solid var(--line-strong)}
#qList.on{display:block}
#qList .it{padding:9px 13px;font-size:12px;color:var(--text-dim);border-bottom:1px solid var(--line);transition:background .15s,color .15s}
#qList .it:last-child{border-bottom:none}
#qList .it:hover,#qList .it.sel{background:var(--accent-soft);color:var(--text)}
#qList .it b{color:var(--accent);font-weight:400;font-family:var(--mono);font-size:11px;margin-right:8px}
#qList .it small{color:var(--text-faint);font-size:10.5px;margin-left:6px}
@media (max-width:640px){#searchWrap{top:16px;left:16px}}

.hud{position:fixed;inset:14px;z-index:5;pointer-events:none}
.hud .c{position:absolute;width:18px;height:18px;border:1px solid var(--line-strong)}
.hud .c1{top:0;left:0;border-right:0;border-bottom:0}
.hud .c2{top:0;right:0;border-left:0;border-bottom:0}
.hud .c3{bottom:0;left:0;border-right:0;border-top:0}
.hud .c4{bottom:0;right:0;border-left:0;border-top:0}

.scan{position:fixed;inset:0;z-index:4;pointer-events:none;opacity:.05;mix-blend-mode:overlay;
  background:repeating-linear-gradient(0deg,transparent 0 2px,rgba(200,215,255,.6) 2px 3px)}

/* ===== 开场:同一个3D世界——窗内是实时天球 ===== */
#intro{position:fixed;inset:0;z-index:60;background:transparent}
#intro svg{width:100%;height:100%;display:block}
#intro .skip{position:absolute;bottom:26px;right:32px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.15em;color:var(--text-faint);opacity:.55}
#wallL,#midL,#nearL{transform-origin:600px 372px;
  transition:transform 2.3s cubic-bezier(.5,0,.78,.5), opacity .9s ease 1.2s}
#intro.fly #nearL{transform:scale(3.5) translateY(100px);opacity:0}
#intro.fly #midL{transform:scale(4.8);opacity:0}
#intro.fly #wallL{transform:scale(6.2);opacity:0}
#intro #tail{transform-origin:757px 610px;animation:sway 3.4s ease-in-out infinite}
@keyframes sway{0%,100%{transform:rotate(0)}50%{transform:rotate(9deg)}}
#intro #boy{animation:breathe 4.2s ease-in-out infinite}
@keyframes breathe{0%,100%{transform:translateY(0)}50%{transform:translateY(2px)}}
#intro #catHead{transition:transform .45s ease}
#intro #headB,#intro #headF{transition:opacity .3s ease}
#intro #headF{opacity:0}
#intro.s1 #catHead{transform:rotate(-9deg)}
#intro.s1 #headB{opacity:0}
#intro.s1 #headF{opacity:1}
#intro #meow{opacity:0}
#intro.s2 #meow{animation:pop .45s ease forwards}
@keyframes pop{0%{opacity:0;transform:scale(.5) translateY(8px)}60%{opacity:1;transform:scale(1.1)}100%{opacity:1;transform:scale(1)}}
#intro .eye{animation:blink 4.5s ease-in-out 1.2s infinite}
@keyframes blink{0%,4%,100%{transform:scaleY(1)}2%{transform:scaleY(.08)}}
#intro #curtain{animation:curt 7s ease-in-out infinite;transform-origin:920px 120px}
@keyframes curt{0%,100%{transform:skewX(0)}50%{transform:skewX(.6deg)}}

dialog{
  margin:auto;border:1px solid var(--line-strong);border-radius:var(--r);
  background:rgba(14,17,24,.92);backdrop-filter:blur(16px);
  color:var(--text);opacity:1;transform:scale(1);
  transition:opacity .35s ease, transform .35s ease, overlay .35s allow-discrete, display .35s allow-discrete;
}
@starting-style{dialog[open]{opacity:0;transform:scale(.93) translateY(12px)}}
dialog::backdrop{background:rgba(4,5,9,.5);backdrop-filter:blur(5px)}
dialog .row{display:flex;gap:10px;margin-top:18px}
dialog .row button{flex:1;padding:10px 0;border-radius:9px;border:none;font-family:var(--cn);font-size:13.5px;transition:opacity .18s}
dialog .go{background:var(--accent);color:#07080d;font-weight:500}
dialog .cancel{background:rgba(255,255,255,.06);color:var(--text-dim)}
dialog .row button:hover{opacity:.85}
dialog.shake{animation:shake .4s}
@keyframes shake{0%,100%{transform:none}25%{transform:translateX(-7px)}75%{transform:translateX(7px)}}

dialog#spanel{padding:30px 30px 24px;width:min(92vw,440px)}
.sp-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:14px;
  font-family:var(--mono);font-size:11px;letter-spacing:.15em}
.sp-code{color:var(--accent)}
.sp-star{color:var(--text-faint)}
dialog#spanel h3{font-weight:400;font-size:19px;margin-bottom:12px}
dialog#spanel #spBody{font-size:13.5px;color:var(--text-dim);line-height:1.7;min-height:40px}
.sp-cap{margin-bottom:14px}
.sp-cap input{width:100%;background:rgba(255,255,255,.04);border:1px solid var(--line-strong);
  border-radius:9px;padding:11px 14px;color:var(--text);font-family:var(--cn);font-size:13.5px;outline:none;transition:border-color .2s}
.sp-cap input:focus{border-color:color-mix(in srgb,var(--accent) 50%,transparent)}
.sp-entry{display:flex;gap:14px;padding:9px 0;border-bottom:1px solid var(--line)}
.sp-entry:last-child{border-bottom:none}
.sp-entry time{font-family:var(--mono);font-size:11px;color:var(--text-faint);white-space:nowrap;padding-top:3px}
.sp-entry .tag{margin-left:8px;font-size:11px;color:var(--accent)}
.sp-close{margin-top:20px;width:100%;padding:10px 0;border-radius:9px;border:none;
  background:rgba(255,255,255,.06);color:var(--text-dim);font-family:var(--cn);font-size:13.5px;transition:opacity .18s}
.sp-close:hover{opacity:.8}


dialog#ndlg{padding:28px 28px 22px;width:min(92vw,400px)}
dialog#ndlg h3{font-weight:400;font-size:17px;margin-bottom:12px}
dialog#ndlg textarea{width:100%;background:rgba(255,255,255,.04);border:1px solid var(--line-strong);
  border-radius:9px;padding:11px 14px;color:var(--text);font-family:var(--cn);font-size:13.5px;
  line-height:1.6;outline:none;resize:none;transition:border-color .2s}
dialog#ndlg textarea:focus{border-color:color-mix(in srgb,var(--accent) 50%,transparent)}

::view-transition-old(root){animation:vt-out .5s ease both}
::view-transition-new(root){animation:vt-gate .8s cubic-bezier(.4,0,.2,1) both}
@keyframes vt-out{to{opacity:.25;filter:blur(4px)}}
@keyframes vt-gate{
  from{clip-path:circle(0px at var(--vt-x,50%) var(--vt-y,50%))}
  to{clip-path:circle(150vmax at var(--vt-x,50%) var(--vt-y,50%))}
}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;animation-delay:0s!important;transition:none!important}
  nav,#searchWrap{opacity:1}
  ::view-transition-old(root),::view-transition-new(root){animation:none}
  #intro,.scan{display:none}
  body{cursor:auto}#cursor{display:none}
}

/* 原为内联 style 属性;CSP 的 style-src 回落到 default-src 'self' 会拦掉内联样式,
   故提取为类。数值与 demo 原样一致,勿改(与 SVG 视口坐标绑定) */
.tro1{transform-origin:712px 508px}
.tro2{transform-origin:701px 504px}
.tro3{transform-origin:726px 504px}
.tro4{transform-origin:790px 448px}
.sp-ready{margin-top:10px;font-family:var(--mono);font-size:11px;letter-spacing:.15em;color:var(--accent)}

/* 无 JS 时页面只剩一片黑,给这条入口一个能看清的样子 */
noscript a{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:70;
  padding:14px 26px;border:1px solid var(--line-strong);border-radius:980px;
  background:rgba(14,17,24,.92);color:var(--text);text-decoration:none;font-size:14px}
