/* cczz2.xyz — FX layer (pairs with fx.js). Pure presentation on top of
   app.css: pointer-driven 3D, aurora edges, holo foil, magnetic controls,
   light sweeps. Only transform/opacity/translate move; the one registered
   property (--ang) rotates a conic edge on two cards. Everything here is
   switched off by body.lite and prefers-reduced-motion. */

@property --ang{syntax:'<angle>';inherits:false;initial-value:0deg}

/* ---- overlays ---- */
.fx-progress{position:fixed;left:0;right:0;top:0;height:2px;z-index:61;pointer-events:none}
.fx-progress i{display:block;height:100%;background:var(--signal);transform:scaleX(0);transform-origin:0 50%;box-shadow:0 0 10px rgba(18,194,173,.6)}
.fx-sweep{position:fixed;left:0;top:0;width:100%;height:3px;z-index:62;pointer-events:none;
  background:linear-gradient(90deg,transparent,#12c2ad 30%,#2bb3d9 50%,#ff6b7f 70%,transparent);filter:drop-shadow(0 0 8px rgba(18,194,173,.8))}

/* aurora edge: a comet of signal colour circling the card border */
.fx-edge{position:absolute;inset:-1px;border-radius:inherit;padding:1px;pointer-events:none;z-index:3;opacity:.85;
  background:conic-gradient(from var(--ang),transparent 0 58%,rgba(18,194,173,0) 60%,#12c2ad 70%,#2bb3d9 79%,#ff6b7f 90%,#ffa15a 96%,transparent 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;
  filter:drop-shadow(0 0 5px rgba(18,194,173,.35));animation:edgeSpin 9s linear infinite}
.auth-card .fx-edge{animation-duration:12s;opacity:.7}
@keyframes edgeSpin{to{--ang:360deg}}

/* ---- small signatures ---- */
.mega{text-shadow:-1.2px 0 rgba(255,107,127,.2),1.2px 0 rgba(18,194,173,.2)}
.tabs-ink{box-shadow:var(--s2),0 0 26px -6px rgba(18,194,173,.55)}
tbody tr:hover td:first-child{box-shadow:inset 2px 0 0 var(--mint)}
.terminal{overflow:hidden}
.terminal::after{content:"";position:absolute;left:0;right:0;top:0;height:90px;pointer-events:none;border-radius:inherit;
  background:linear-gradient(180deg,transparent,rgba(18,194,173,.08),transparent);transform:translateY(-100%);animation:termScan 8s linear infinite}
@keyframes termScan{0%{transform:translateY(-100%)}55%,100%{transform:translateY(520%)}}
.trend-wrap::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,transparent 40%,rgba(255,255,255,.35) 50%,transparent 60%) -120% 0/60% 100% no-repeat;animation:trendGlint 9s var(--e-out) infinite}
@keyframes trendGlint{0%{background-position:-120% 0}22%,100%{background-position:240% 0}}

/* ---- degradation ---- */
body.lite .fx-edge,body.lite .terminal::after,body.lite .trend-wrap::after{animation:none}
body.lite .fx-edge{filter:none}
body.lite .trend-wrap::after{display:none}
@media(prefers-reduced-motion:reduce){
  .fx-edge,.fx-progress,.fx-sweep{display:none}
}

/* ---- diagram, orbit, empty-state graphics ---- */
.flow{display:block;width:100%;max-width:640px;height:300px;margin-top:30px}
.rg-spin{transform-origin:60px 60px;animation:spin 7s linear infinite}
.rg-orbit{fill:#fff;stroke:var(--mint);stroke-width:1.6;filter:drop-shadow(0 0 4px rgba(18,194,173,.8))}
#donut .dn-ghost{fill:none;stroke:rgba(17,26,34,.16);stroke-width:12;stroke-dasharray:.7 2.1}
#donut .dn-scan{fill:none;stroke:url(#rg-grad);stroke-width:12;stroke-linecap:round;transform-box:fill-box;transform-origin:center;animation:spin 3.2s var(--e-out) infinite;opacity:.85}
body.lite .rg-spin,body.lite #donut .dn-scan{animation:none}
@media(max-width:980px){.flow{height:220px;margin-top:22px}}
@media(prefers-reduced-motion:reduce){.rg-spin,#donut .dn-scan{animation:none}}

/* ---- 3D world (world.js) ---- */
/* the entrance belongs to the brain itself: it settles in from slightly larger,
   so the first thing the page shows is the same organ the console lives on and
   nothing is drawn twice. Keyframes (not transitions) because the class that
   starts it lands in the frame after the canvas exists. */
#world{position:absolute;inset:0;width:100%;height:100%;opacity:0}
.three-on #world{opacity:1;animation:worldIn 1.9s var(--e-out) both}
@keyframes worldIn{from{opacity:0}to{opacity:1}}
.three .space{background:transparent}
.three #bg-gl{display:none}
#bg-orbs{position:absolute;inset:0;width:100%;height:100%;opacity:0}
.orbs body:not(.in-app) #bg-orbs{opacity:1;animation:orbsIn 1.6s var(--e-out) both}
@keyframes orbsIn{from{opacity:0;transform:scale(1.07)}to{opacity:1;transform:none}}
.orbs body:not(.in-app) #bg-gl{opacity:0}
/* sign-in / sign-up: no pointer reactions of any kind */
.auth .hero::before{content:"";position:absolute;inset:-10% -18% -10% -30%;z-index:-1;pointer-events:none;background:radial-gradient(closest-side,rgba(247,250,250,.95),rgba(246,250,250,.72) 52%,transparent 78%)}
#auth .button:hover:not(:disabled),#auth .button:active:not(:disabled){transform:none}
.w3d canvas.w3d-canvas{position:absolute;inset:0;width:100%;height:100%;border-radius:inherit;pointer-events:none}
.w3d{position:relative}
.ring-gauge.w3d svg,.donut-wrap.w3d svg{opacity:0;transition:opacity .4s}
.ring-gauge.w3d .rg-label{z-index:3}
.stage{display:none}
.three .stage{display:block;pointer-events:none}
.three .welcome{min-height:150px;align-items:center}
.three .welcome .stage{flex:1;align-self:stretch;min-width:120px}
.three .ring-gauge{flex-basis:168px;width:168px;height:168px}
@media(max-width:980px){.three .ring-gauge{flex-basis:120px;width:120px;height:120px}}
@media(max-width:640px){.three .welcome{min-height:0}.three .welcome .stage{display:none}}

/* ---- management views (keys, usage, recharge, account) ---- */
.view-head .welcome-title{white-space:nowrap}
.icon-btn{display:inline-grid;place-items:center;width:34px;height:34px;border-radius:10px;border:1px solid var(--line-2);background:#fff;color:var(--muted);cursor:pointer;
  transition:color var(--d-small),border-color var(--d-small),transform var(--d-small) var(--e-spring)}
.icon-btn svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.icon-btn:hover,.icon-btn.on{color:var(--teal);border-color:rgba(12,150,140,.45)}
.chip{display:inline-flex;align-items:center;padding:3px 9px;border-radius:99px;font:650 11px/1.3 var(--mono);color:var(--ink-2);background:rgba(17,26,34,.05)}
.empty-state{display:flex;flex-direction:column;align-items:center;gap:14px;padding:42px 20px;text-align:center}
.es-orb{width:54px;height:54px;border-radius:50%;background:radial-gradient(circle at 34% 30%,#fff,rgba(255,255,255,0) 42%),conic-gradient(from 210deg,#12c2ad,#2bb3d9,#ff6b7f,#ffa15a,#12c2ad);
  box-shadow:0 14px 34px -14px rgba(12,150,140,.7);animation:orb 6s ease-in-out infinite}
@keyframes orb{50%{transform:translate3d(0,-6px,0) rotate(160deg)}}

/* keys */
.composer{display:flex;gap:18px;align-items:flex-end}
.composer form{flex:1}
.composer-glyph{flex-shrink:0;width:50px;height:50px;border-radius:16px;display:grid;place-items:center;background:var(--signal);box-shadow:0 12px 26px -12px rgba(12,150,140,.75)}
.composer-glyph svg{width:26px;height:26px;fill:none;stroke:#fff;stroke-width:2;stroke-linecap:round}
.composer .note{flex-basis:100%}
.key-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:16px;margin-bottom:18px}
.key-card{position:relative;display:flex;flex-direction:column;gap:14px;padding:20px 20px 14px;border-radius:var(--r-lg);overflow:hidden;
  background:linear-gradient(150deg,rgba(255,255,255,.95),rgba(240,251,248,.85) 55%,rgba(255,243,245,.85));border:1px solid rgba(255,255,255,.95);box-shadow:inset 0 0 0 1px var(--hair),var(--s2);
  transition:box-shadow var(--d-medium)}
.key-card:hover{box-shadow:inset 0 0 0 1px var(--hair),var(--s3)}
.key-card::before{content:"";position:absolute;right:-60px;top:-60px;width:180px;height:180px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(18,194,173,.16),transparent 70%)}
.key-card header{display:flex;align-items:center;gap:9px;min-width:0}
.key-card header strong{font-size:15px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.key-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;background:var(--green);box-shadow:0 0 0 0 rgba(14,163,107,.5);animation:ping 2.6s var(--e-out) infinite}
.key-card.off .key-dot{background:var(--dim);animation:none}
.key-state{margin-left:auto;font:650 11px/1 var(--mono);color:var(--green)}
.key-card.off .key-state{color:var(--dim)}
.key-line{display:flex;align-items:center;gap:8px}
.key-code{flex:1;min-width:0;padding:11px 13px;font-size:13.5px;letter-spacing:.02em;color:#8ff3e1;background:var(--graphite);border-color:rgba(18,194,173,.28);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;overflow-wrap:normal}
/* per-key daily allowance: usage / limit, editable right on the card */
.key-limits{display:flex;align-items:center;gap:10px;min-width:0}
.key-daily{flex:1;min-width:0;font:600 12px/1.3 var(--mono);color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.key-daily.off{color:var(--dim);font-weight:500}
.key-daily::before{content:"";display:inline-block;width:6px;height:6px;margin:0 8px 1px 0;border-radius:50%;background:var(--signal);vertical-align:middle;opacity:.9}
.key-daily.off::before{background:var(--dim);opacity:.45}
.key-limit-edit{flex-shrink:0;padding:6px 10px!important;font-size:11.5px!important;color:var(--teal)!important}
#key-limit-dialog label small{display:block;font-weight:500;color:var(--dim);margin-top:8px;font-size:11.5px;line-height:1.65}
#key-limit-state{margin:2px 0 4px}
.key-meter{height:4px;border-radius:4px;background:rgba(17,26,34,.07);overflow:hidden}
.key-meter i{display:block;height:100%;background:var(--signal);transform:scaleX(var(--fill,0));transform-origin:0 50%;transition:transform 1.1s var(--e-out) .2s}
.key-meter.open i{transform:scaleX(1);opacity:.25;background:repeating-linear-gradient(90deg,var(--mint) 0 6px,transparent 6px 10px)}
.key-card footer{display:flex;align-items:center;gap:14px;font:500 11.5px/1 var(--mono);color:var(--muted)}
.key-card footer .button{margin-left:auto}
.danger-text{color:var(--danger)!important}
.danger-text.armed{background:rgba(217,67,91,.1)!important;border-color:rgba(217,67,91,.35)!important}
.key-card .button.copied{transform:scale(1.04)}

/* usage ledger */
.ledger{padding-top:10px}
.ledger tbody tr.day td{padding:20px 10px 8px;border-bottom:0;background:transparent!important;box-shadow:none!important}
.ledger tr.day td{display:table-cell}
.ledger tr.day span{font-weight:750;font-size:13px;color:var(--ink)}
.ledger tr.day b{float:right;font:650 11px/1.2 var(--mono);color:var(--muted)}
.model-pill{display:inline-flex;align-items:center;gap:7px;padding:4px 10px 4px 8px;border-radius:99px;font:600 12px/1.2 var(--mono);background:rgba(17,26,34,.045)}
.model-pill i{width:7px;height:7px;border-radius:50%}
.model-pill.m0 i{background:#12c2ad}.model-pill.m1 i{background:#ff6b7f}.model-pill.m2 i{background:#ffa15a}.model-pill.m3 i{background:#2bb3d9}.model-pill.m4 i{background:#8a7cf0}.model-pill.m5 i{background:#9aa6b0}
td.cost{position:relative;font-weight:700}
.cost-bar{position:absolute;right:10px;bottom:5px;height:2px;width:calc(var(--w,0) * 60%);border-radius:2px;background:var(--signal);opacity:.55}

/* recharge */
.checkout{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(300px,1fr);gap:18px;align-items:start;margin-bottom:18px}
.checkout .card{margin-bottom:0}
.picker .field-title:first-child{margin-top:4px}
.picker .amounts{grid-template-columns:repeat(3,minmax(0,1fr))}
.amount{display:flex;flex-direction:column;align-items:center;gap:6px;padding:20px 6px;font-size:19px}
.amount em{font:700 10.5px/1 var(--mono);font-style:normal;color:#fff;background:linear-gradient(90deg,#ff6b7f,#ffa15a);padding:3px 7px;border-radius:99px}
.method{display:flex;align-items:center;justify-content:center;gap:10px;padding:16px 10px}
.m-glyph{display:inline-grid;place-items:center;width:26px;height:26px;border-radius:8px;font-weight:800;font-size:13px;line-height:1;font-style:normal;color:#fff;background:#1677ff;flex-shrink:0}
.method.wxpay .m-glyph,.m-glyph.wxpay{background:#07c160}
.receipt{position:sticky;top:96px;padding-top:20px;background:linear-gradient(180deg,#fff,rgba(250,252,252,.96));
  -webkit-mask:radial-gradient(circle 9px at 0 64px,transparent 98%,#000) left/51% 100% no-repeat,radial-gradient(circle 9px at 100% 64px,transparent 98%,#000) right/51% 100% no-repeat;
  mask:radial-gradient(circle 9px at 0 64px,transparent 98%,#000) left/51% 100% no-repeat,radial-gradient(circle 9px at 100% 64px,transparent 98%,#000) right/51% 100% no-repeat}
.receipt-head{display:flex;justify-content:space-between;align-items:center;padding-bottom:22px;margin-bottom:16px;border-bottom:1px dashed var(--line-2);font:650 12px/1 var(--mono);color:var(--muted)}
.receipt .summary{background:transparent;border:0;padding:0 2px;margin-bottom:20px}
.receipt .sum-row.total strong{font-size:30px;display:inline-block}
.timeline{position:relative;padding-left:4px}
.timeline .tl-item{position:relative;display:flex;align-items:center;gap:12px;padding:13px 10px 13px 22px;margin:0 -10px;border-top:0}
.timeline .tl-item>span{flex:1}
.tl-dot{position:absolute;left:4px;top:50%;width:9px;height:9px;margin-top:-4.5px;border-radius:50%;background:var(--dim);box-shadow:0 0 0 4px #fff}
.timeline .tl-item::before{content:"";position:absolute;left:8px;top:0;bottom:0;width:1px;background:var(--line)}
.timeline .tl-item:first-child::before{top:50%}.timeline .tl-item:last-child::before{bottom:50%}
.tl-item.completed .tl-dot,.tl-item.paid .tl-dot{background:var(--green)}
.tl-item.pending .tl-dot,.tl-item.recharging .tl-dot{background:#e0a238}
.timeline .row strong{font-family:var(--mono)}

/* account */
.profile-card{display:flex;align-items:center;gap:20px;padding:26px}
.avatar{position:relative;width:64px;height:64px;border-radius:22px;display:grid;place-items:center;flex-shrink:0;font-weight:800;font-size:26px;line-height:1;color:#fff;background:var(--signal);
  box-shadow:0 16px 34px -14px rgba(12,150,140,.75),inset 0 1px 0 rgba(255,255,255,.5);overflow:hidden}
.avatar::after{content:"";position:absolute;inset:0;background:linear-gradient(135deg,rgba(255,255,255,.55),transparent 48%)}
.profile-main{display:flex;flex-direction:column;gap:7px;min-width:0;flex:1}
.profile-main strong{font:700 18px/1.25 var(--mono);overflow:hidden;text-overflow:ellipsis}
.profile-main small{color:var(--muted);font-size:12.5px}
.security-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:18px;align-items:start}
.sec-col{display:flex;flex-direction:column;gap:18px}
.security-grid .card{margin-bottom:0}
.sec-card .stack-form{max-width:none}

body.lite .es-orb,body.lite .key-dot{animation:none}
@media(max-width:980px){
  .checkout,.security-grid{grid-template-columns:1fr}
  .receipt{position:relative;top:0}
}
@media(max-width:640px){
  .composer{flex-direction:column;align-items:stretch}
  .composer-glyph{display:none}
  .key-grid{grid-template-columns:1fr}
  .profile-card{flex-wrap:wrap;padding:20px}
  .profile-card .pill{width:100%;justify-content:center}
  /* the ledger becomes cards on phones */
  .ledger thead{display:none}
  .ledger table,.ledger tbody,.ledger tr,.ledger td{display:block;width:100%}
  .ledger tbody tr:not(.day){display:grid;grid-template-columns:auto 1fr auto;grid-template-areas:"time key cost" "model model cost";gap:8px 10px;padding:12px 4px;border-bottom:1px solid var(--hair)}
  .ledger tbody tr:not(.day) td{padding:0;border:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ledger td[data-label="时间"]{grid-area:time;color:var(--muted);font:500 11.5px/1.4 var(--mono)}
  .ledger td[data-label="密钥"]{grid-area:key;color:var(--muted);font-size:12px;line-height:1.4}
  .ledger td[data-label="模型"]{grid-area:model}
  .ledger td.cost{grid-area:cost;align-self:center;font-size:15px}
  .ledger td[data-label="输入"],.ledger td[data-label="输出"]{display:none}
  .ledger tr.day td{display:flex;justify-content:space-between}
  .cost-bar{right:0;bottom:-4px}
}
@media(prefers-reduced-motion:reduce){.es-orb,.key-dot{animation:none}}

.key-grid .key-card{align-items:stretch;justify-content:flex-start;margin:0;border-top:1px solid rgba(255,255,255,.95)}
.key-grid .key-card:hover{background:linear-gradient(150deg,#fff,rgba(236,251,247,.9) 55%,rgba(255,241,243,.9))}
.timeline .tl-item>span{display:flex;flex-direction:column;gap:5px;min-width:0}
.timeline .tl-item small{color:var(--dim);font:500 11px/1.2 var(--mono)}
.timeline .tl-item:hover{background:rgba(18,194,173,.05)}

/* ---- the brain behind the glass: UI frames pick up its light (set by world.js, one way) ---- */
.card,.stat{isolation:isolate}
.brain-lum{position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:-1;opacity:var(--ba,0);
  background:radial-gradient(ellipse 85% 120% at var(--bx,50%) var(--by,50%),rgba(var(--brgb,18,194,173),.32),rgba(var(--brgb,18,194,173),.09) 58%,transparent);
  box-shadow:inset 0 0 0 1px rgba(var(--brgb,18,194,173),.34),inset 0 0 30px rgba(var(--brgb,18,194,173),.18)}
.topbar .brain-lum{opacity:calc(var(--ba,0)*.7)}
.three{--glass:rgba(255,255,255,.1)}
/* UI frames are transparent: the brain shows through; a light blur and a hairline keep the text readable */
.three .glass{-webkit-backdrop-filter:blur(5px) saturate(1.25);backdrop-filter:blur(5px) saturate(1.25);border-color:rgba(255,255,255,.7);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.75),inset 0 0 0 1px rgba(17,26,34,.04),0 18px 40px -26px rgba(17,26,34,.35)}
.three .auth-card.glass{--glass:rgba(255,255,255,.14)}
.three .topbar.glass{--glass:rgba(255,255,255,.2)}
.three .balance-card{background:linear-gradient(135deg,rgba(255,255,255,.2),rgba(238,250,247,.1) 50%,rgba(255,240,242,.1))}
.three .card:not(.terminal),.three .stat{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.7);box-shadow:inset 0 1px 0 rgba(255,255,255,.7),inset 0 0 0 1px rgba(17,26,34,.05),0 18px 40px -28px rgba(17,26,34,.3);
  -webkit-backdrop-filter:blur(5px) saturate(1.25);backdrop-filter:blur(5px) saturate(1.25)}
.three .terminal{background:linear-gradient(170deg,rgba(24,34,42,.6),rgba(16,23,29,.5));-webkit-backdrop-filter:blur(6px) saturate(1.2);backdrop-filter:blur(6px) saturate(1.2)}
.three .receipt{background:rgba(255,255,255,.1)}
body.lite .brain-lum{display:none}
body.lite .card:not(.terminal),body.lite .stat{-webkit-backdrop-filter:none;backdrop-filter:none;background:rgba(255,255,255,.7)}
@media(prefers-reduced-motion:reduce){.brain-lum{display:none}
  #world,#bg-orbs{animation:none;transform:none}}

/* daily allowance row: one line on desktop, stacked on a phone */
@media(max-width:640px){
  .key-limits{gap:6px}
  .key-daily{font-size:11.5px;white-space:normal;line-height:1.45}
  .key-limit-edit{padding:5px 8px!important}
}
