mirror of
https://github.com/Gloridust/WechatOnCloud.git
synced 2026-06-16 19:53:53 +08:00
0ccbaa3a35
绝对定位悬浮层(从按钮下方浮出),不再撑高卡片/顶走下方内容;展开时卡片 overflow:visible + z-index:5(盖住下方/同列卡片,仍低于弹窗);加点击外部 / 点击菜单项自动关闭。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2044 lines
41 KiB
CSS
2044 lines
41 KiB
CSS
/* WechatOnCloud 面板 —— 牛奶布艺(soft neumorphism)+ 微信绿 + iOS26 圆角极简
|
||
* 比喻:整个界面是盖在桌面上的一整块白布,组件是被布顶起的物体。
|
||
* - 高光在物体顶面(radial,中心偏上)
|
||
* - 阴影是布料折痕(小半径、紧贴边缘、冷灰蓝),不是悬浮投影
|
||
* - 组件亮度 ≥ 背景;层级靠明度,不靠边框/分割线 */
|
||
:root {
|
||
--base: #ebedf1; /* 整块布底色(立体档,91% 区间) */
|
||
--surface: #ffffff; /* 浮起表面:纯白 */
|
||
--trough: #e0e3ea; /* 凹槽:比 base 更暗(输入框/进度槽) */
|
||
--shadow: 51 66 102; /* 冷灰蓝阴影 RGB(配合 rgba()) */
|
||
|
||
--wx-green: #07c160;
|
||
--wx-green-dark: #06ad56;
|
||
--green-rgb: 7 193 96;
|
||
|
||
--text: #1a1d24;
|
||
--muted: #8a9099;
|
||
--danger: #fa5151;
|
||
--danger-rgb: 250 81 81;
|
||
|
||
--r-card: 28px;
|
||
--r-blob: 22px;
|
||
--r-small: 16px;
|
||
|
||
/* 布料折痕:两层,紧贴边缘 */
|
||
--crease: 0 1px 3px rgba(var(--shadow) / 0.4), 0 2px 8px rgba(var(--shadow) / 0.22);
|
||
--crease-press: 0 1px 2px rgba(var(--shadow) / 0.28), 0 1px 3px rgba(var(--shadow) / 0.16);
|
||
--crease-accent: 0 1px 3px rgba(var(--green-rgb) / 0.45), 0 4px 14px rgba(var(--green-rgb) / 0.32);
|
||
/* 顶面高光(中心偏上的 radial),所有浮起组件共用 */
|
||
--sheen: radial-gradient(
|
||
ellipse at 50% 28%,
|
||
rgba(255, 255, 255, 0.55) 0%,
|
||
rgba(255, 255, 255, 0.16) 38%,
|
||
transparent 74%
|
||
);
|
||
}
|
||
|
||
* {
|
||
box-sizing: border-box;
|
||
-webkit-tap-highlight-color: transparent;
|
||
}
|
||
|
||
html,
|
||
body,
|
||
#root {
|
||
height: 100%;
|
||
margin: 0;
|
||
}
|
||
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', 'Segoe UI', Roboto, sans-serif;
|
||
background: var(--base);
|
||
color: var(--text);
|
||
-webkit-font-smoothing: antialiased;
|
||
}
|
||
|
||
input,
|
||
button {
|
||
font-family: inherit;
|
||
}
|
||
|
||
.center-screen {
|
||
min-height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 24px;
|
||
padding-top: max(24px, env(safe-area-inset-top));
|
||
padding-bottom: max(24px, env(safe-area-inset-bottom));
|
||
}
|
||
|
||
/* ── 浮起原子:surface + 折痕 + 顶面高光 ──────────────────── */
|
||
.mf-raised,
|
||
.card,
|
||
.enter-card,
|
||
.list,
|
||
.wx-state {
|
||
position: relative;
|
||
background: var(--surface);
|
||
box-shadow: var(--crease);
|
||
}
|
||
.mf-raised::before,
|
||
.card::before,
|
||
.enter-card::before,
|
||
.list::before,
|
||
.wx-state::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
border-radius: inherit;
|
||
background: var(--sheen);
|
||
pointer-events: none;
|
||
}
|
||
.card > *,
|
||
.enter-card > *,
|
||
.list > *,
|
||
.wx-state > * {
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
|
||
.card {
|
||
border-radius: var(--r-card);
|
||
padding: 24px;
|
||
width: 100%;
|
||
max-width: 360px;
|
||
}
|
||
|
||
/* 登录 */
|
||
.login-screen {
|
||
background:
|
||
radial-gradient(60% 50% at 50% 0%, rgba(var(--green-rgb) / 0.1), transparent 70%),
|
||
var(--base);
|
||
}
|
||
.login-wrap {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 16px;
|
||
width: 100%;
|
||
max-width: 360px;
|
||
}
|
||
.login-card {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 14px;
|
||
padding: 28px 24px;
|
||
}
|
||
.login-foot {
|
||
font-size: 12px;
|
||
color: var(--muted);
|
||
text-align: center;
|
||
padding: 0 12px;
|
||
}
|
||
.brand {
|
||
text-align: center;
|
||
margin-bottom: 8px;
|
||
}
|
||
.brand-logo {
|
||
position: relative;
|
||
width: 60px;
|
||
height: 60px;
|
||
border-radius: 18px;
|
||
background: var(--wx-green);
|
||
color: #fff;
|
||
font-size: 32px;
|
||
font-weight: 700;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin: 0 auto 14px;
|
||
box-shadow: var(--crease-accent);
|
||
overflow: hidden;
|
||
}
|
||
.brand-logo img {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: block;
|
||
}
|
||
.brand-logo::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
background: var(--sheen);
|
||
pointer-events: none;
|
||
}
|
||
.brand h1 {
|
||
font-size: 22px;
|
||
font-weight: 700;
|
||
margin: 0 0 4px;
|
||
}
|
||
.muted {
|
||
color: var(--muted);
|
||
}
|
||
.small {
|
||
font-size: 12px;
|
||
}
|
||
|
||
/* 输入框:凹陷(trough fill + 顶部内阴影),聚焦叠绿色半透环 */
|
||
.input {
|
||
width: 100%;
|
||
height: 48px;
|
||
padding: 0 16px;
|
||
border: none;
|
||
border-radius: var(--r-small);
|
||
font-size: 16px;
|
||
outline: none;
|
||
color: var(--text);
|
||
background: var(--trough);
|
||
box-shadow: inset 0 1px 2px rgba(var(--shadow) / 0.18), inset 0 2px 6px rgba(var(--shadow) / 0.1);
|
||
transition: box-shadow 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
}
|
||
.input::placeholder {
|
||
color: var(--muted);
|
||
}
|
||
.input:focus {
|
||
box-shadow: inset 0 1px 2px rgba(var(--shadow) / 0.16), 0 0 0 3px rgba(var(--green-rgb) / 0.22);
|
||
}
|
||
|
||
/* 密码框 + 显示/隐藏切换 */
|
||
.pw-field {
|
||
position: relative;
|
||
}
|
||
.pw-field .input {
|
||
padding-right: 46px;
|
||
}
|
||
.pw-toggle {
|
||
position: absolute;
|
||
right: 6px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 36px;
|
||
height: 36px;
|
||
border: none;
|
||
background: none;
|
||
color: var(--muted);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
cursor: pointer;
|
||
border-radius: 10px;
|
||
}
|
||
.pw-toggle:active {
|
||
background: rgba(var(--shadow) / 0.06);
|
||
}
|
||
|
||
/* 按钮:浮起 blob,按下缩小 + 折痕收紧 */
|
||
.btn {
|
||
position: relative;
|
||
height: 48px;
|
||
border: none;
|
||
border-radius: var(--r-small);
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
background: var(--surface);
|
||
color: var(--text);
|
||
cursor: pointer;
|
||
box-shadow: var(--crease);
|
||
overflow: hidden;
|
||
transition: transform 0.18s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.18s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
}
|
||
.btn::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
background: var(--sheen);
|
||
pointer-events: none;
|
||
}
|
||
.btn:active:not(:disabled) {
|
||
transform: scale(0.97);
|
||
box-shadow: var(--crease-press);
|
||
}
|
||
.btn-primary {
|
||
background: var(--wx-green);
|
||
color: #fff;
|
||
box-shadow: var(--crease-accent);
|
||
}
|
||
/* 绿底上用更克制的顶面高光,避免白色 sheen 把绿冲淡 */
|
||
.btn-primary::before,
|
||
.wx-btn.btn-primary::before {
|
||
background: radial-gradient(
|
||
ellipse at 50% 22%,
|
||
rgba(255, 255, 255, 0.28) 0%,
|
||
rgba(255, 255, 255, 0.08) 42%,
|
||
transparent 72%
|
||
);
|
||
}
|
||
.btn-primary:active:not(:disabled) {
|
||
background: var(--wx-green-dark);
|
||
}
|
||
/* 危险动作按钮:红底,折痕用 danger 色 */
|
||
.btn-danger {
|
||
background: var(--danger);
|
||
color: #fff;
|
||
box-shadow: 0 1px 3px rgba(var(--danger-rgb) / 0.45), 0 4px 14px rgba(var(--danger-rgb) / 0.3);
|
||
}
|
||
.btn-danger::before {
|
||
background: radial-gradient(ellipse at 50% 22%, rgba(255, 255, 255, 0.26) 0%, rgba(255, 255, 255, 0.07) 42%, transparent 72%);
|
||
}
|
||
.btn-danger:active:not(:disabled) {
|
||
background: #e84444;
|
||
}
|
||
.btn:disabled {
|
||
opacity: 0.6;
|
||
cursor: default;
|
||
}
|
||
/* 文本按钮:无浮起,绿字,按下淡绿底 */
|
||
.btn-text {
|
||
background: none;
|
||
border: none;
|
||
color: var(--wx-green);
|
||
font-size: 15px;
|
||
cursor: pointer;
|
||
padding: 6px 10px;
|
||
border-radius: 10px;
|
||
transition: background 0.18s;
|
||
}
|
||
.btn-text:active {
|
||
background: rgba(var(--green-rgb) / 0.12);
|
||
}
|
||
.btn-text.danger {
|
||
color: var(--danger);
|
||
}
|
||
.btn-text.danger:active {
|
||
background: rgba(var(--danger-rgb) / 0.12);
|
||
}
|
||
|
||
/* 实例卡片操作:「管理」分类折叠菜单(默认收起,点开按运维/设置/危险分组展开文字操作) */
|
||
.inst-menu-toggle {
|
||
width: 100%;
|
||
height: 38px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 4px;
|
||
border: none;
|
||
border-radius: 12px;
|
||
background: var(--trough);
|
||
color: var(--text);
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
box-shadow: inset 0 1px 2px rgba(var(--shadow) / 0.1);
|
||
transition: background 0.15s;
|
||
}
|
||
.inst-menu-toggle:hover {
|
||
background: var(--base);
|
||
}
|
||
.inst-menu-caret {
|
||
display: inline-flex;
|
||
color: var(--muted);
|
||
transition: transform 0.18s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
}
|
||
.inst-menu-toggle.open .inst-menu-caret {
|
||
transform: rotate(180deg);
|
||
}
|
||
/* 「管理」菜单:绝对定位悬浮层,浮在下方内容之上,不把卡片撑高、不顶走后面的内容 */
|
||
.inst-menu-wrap {
|
||
position: relative;
|
||
margin-top: 10px;
|
||
}
|
||
.inst-menu {
|
||
position: absolute;
|
||
top: calc(100% + 6px);
|
||
left: 0;
|
||
right: 0;
|
||
z-index: 2;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 6px;
|
||
padding: 10px;
|
||
background: var(--surface);
|
||
border-radius: var(--r-small);
|
||
box-shadow: 0 6px 22px rgba(var(--shadow) / 0.26), 0 2px 6px rgba(var(--shadow) / 0.18);
|
||
animation: inst-menu-in 0.16s ease;
|
||
}
|
||
@keyframes inst-menu-in {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(-4px);
|
||
}
|
||
}
|
||
.inst-menu-label {
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
color: var(--muted);
|
||
letter-spacing: 0.04em;
|
||
margin: 2px 4px 2px;
|
||
}
|
||
.inst-menu-items {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 2px;
|
||
}
|
||
.inst-menu-danger {
|
||
margin-top: 2px;
|
||
padding-top: 8px;
|
||
border-top: 1px solid rgba(var(--shadow) / 0.08);
|
||
}
|
||
|
||
.error {
|
||
color: var(--danger);
|
||
font-size: 14px;
|
||
}
|
||
.ok {
|
||
color: var(--wx-green);
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* ── 页面骨架 ──────────────────────────────────────────── */
|
||
.page {
|
||
min-height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
/* 顶栏走浅色布面(不再整条绿),标题深色、操作绿字 —— iOS26 + 牛奶布艺 */
|
||
.topbar {
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 0 8px;
|
||
padding-top: env(safe-area-inset-top);
|
||
height: calc(52px + env(safe-area-inset-top));
|
||
background: var(--base);
|
||
}
|
||
.topbar-title {
|
||
font-size: 17px;
|
||
font-weight: 600;
|
||
color: var(--text);
|
||
position: absolute;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
}
|
||
.content {
|
||
flex: 1;
|
||
padding: 16px;
|
||
max-width: 560px;
|
||
width: 100%;
|
||
margin: 0 auto;
|
||
}
|
||
/* PC 大屏:加宽容器,实例网格自动多列卡片 */
|
||
@media (min-width: 880px) {
|
||
.content {
|
||
max-width: 940px;
|
||
padding: 20px 28px 40px;
|
||
}
|
||
.topbar {
|
||
padding-left: 16px;
|
||
padding-right: 16px;
|
||
}
|
||
}
|
||
|
||
.hello {
|
||
font-size: 22px;
|
||
font-weight: 700;
|
||
margin: 8px 4px 18px;
|
||
}
|
||
.tag {
|
||
display: inline-block;
|
||
font-size: 11px;
|
||
background: rgba(var(--green-rgb) / 0.14);
|
||
color: var(--wx-green-dark);
|
||
border-radius: 999px;
|
||
padding: 2px 9px;
|
||
margin-left: 8px;
|
||
vertical-align: middle;
|
||
font-weight: 600;
|
||
}
|
||
.tag-off {
|
||
background: rgba(var(--danger-rgb) / 0.14);
|
||
color: var(--danger);
|
||
}
|
||
|
||
/* 进入微信入口卡 */
|
||
.enter-card {
|
||
width: 100%;
|
||
border: none;
|
||
border-radius: var(--r-card);
|
||
padding: 20px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 14px;
|
||
cursor: pointer;
|
||
text-align: left;
|
||
transition: transform 0.18s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.18s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
}
|
||
.enter-card:active {
|
||
transform: scale(0.985);
|
||
box-shadow: var(--crease-press);
|
||
}
|
||
.enter-icon {
|
||
position: relative;
|
||
width: 46px;
|
||
height: 46px;
|
||
flex: none;
|
||
border-radius: 14px;
|
||
background: var(--wx-green);
|
||
color: #fff;
|
||
font-size: 24px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: var(--crease-accent);
|
||
overflow: hidden;
|
||
}
|
||
.enter-icon::after {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
background: var(--sheen);
|
||
pointer-events: none;
|
||
}
|
||
.enter-text {
|
||
flex: 1;
|
||
}
|
||
.enter-title {
|
||
font-size: 17px;
|
||
font-weight: 600;
|
||
}
|
||
.enter-sub {
|
||
font-size: 13px;
|
||
color: var(--muted);
|
||
margin-top: 3px;
|
||
}
|
||
.enter-arrow {
|
||
color: #c2c7d0;
|
||
font-size: 22px;
|
||
}
|
||
|
||
/* 列表卡:行间用折痕细缝分隔,不用 border */
|
||
.list {
|
||
margin-top: 16px;
|
||
border-radius: var(--r-card);
|
||
overflow: hidden;
|
||
}
|
||
.list-item {
|
||
position: relative;
|
||
z-index: 1;
|
||
width: 100%;
|
||
background: none;
|
||
border: none;
|
||
box-shadow: inset 0 -1px 0 rgba(var(--shadow) / 0.08);
|
||
padding: 16px 18px;
|
||
font-size: 16px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
transition: background 0.18s;
|
||
}
|
||
.list-item:active {
|
||
background: rgba(var(--shadow) / 0.04);
|
||
}
|
||
.list-item:last-child {
|
||
box-shadow: none;
|
||
}
|
||
|
||
/* 子账号列表 */
|
||
.user-row {
|
||
position: relative;
|
||
z-index: 1;
|
||
padding: 14px 18px;
|
||
box-shadow: inset 0 -1px 0 rgba(var(--shadow) / 0.08);
|
||
}
|
||
.user-row:last-child {
|
||
box-shadow: none;
|
||
}
|
||
.user-main {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
.user-name {
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
}
|
||
.user-actions {
|
||
display: flex;
|
||
gap: 4px;
|
||
margin-top: 6px;
|
||
}
|
||
|
||
/* ── 微信安装/更新状态卡(启动下载 + 更新到最新版) ──────── */
|
||
.wx-state {
|
||
margin-top: 16px;
|
||
border-radius: var(--r-card);
|
||
padding: 20px;
|
||
}
|
||
.wx-state-row {
|
||
position: relative;
|
||
z-index: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 14px;
|
||
}
|
||
.wx-state-text {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
.wx-state-title {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
}
|
||
.wx-state-sub {
|
||
font-size: 13px;
|
||
color: var(--muted);
|
||
margin-top: 3px;
|
||
}
|
||
.wx-btn {
|
||
height: 40px;
|
||
flex: none;
|
||
padding: 0 18px;
|
||
border-radius: 999px;
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
}
|
||
/* 进度条:凹槽轨 + 绿色带光晕填充 */
|
||
.wx-progress {
|
||
position: relative;
|
||
z-index: 1;
|
||
margin-top: 16px;
|
||
height: 8px;
|
||
border-radius: 999px;
|
||
background: var(--trough);
|
||
box-shadow: inset 0 1px 2px rgba(var(--shadow) / 0.2);
|
||
overflow: hidden;
|
||
}
|
||
.wx-progress-bar {
|
||
height: 100%;
|
||
border-radius: 999px;
|
||
background: linear-gradient(90deg, var(--wx-green-dark), var(--wx-green));
|
||
box-shadow: 0 0 8px rgba(var(--green-rgb) / 0.5);
|
||
transition: width 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
}
|
||
/* 进度不确定(拿不到总大小)时来回滑动 */
|
||
.wx-progress-bar.indeterminate {
|
||
width: 40%;
|
||
transition: none;
|
||
animation: wx-slide 1.1s ease-in-out infinite;
|
||
}
|
||
@keyframes wx-slide {
|
||
0% {
|
||
margin-left: -40%;
|
||
}
|
||
100% {
|
||
margin-left: 100%;
|
||
}
|
||
}
|
||
.wx-progress-text {
|
||
position: relative;
|
||
z-index: 1;
|
||
margin-top: 8px;
|
||
font-size: 12px;
|
||
color: var(--muted);
|
||
text-align: right;
|
||
}
|
||
|
||
/* ── 弹窗 ──────────────────────────────────────────────── */
|
||
.modal-mask {
|
||
position: fixed;
|
||
inset: 0;
|
||
background: rgba(26, 29, 36, 0.4);
|
||
-webkit-backdrop-filter: blur(6px);
|
||
backdrop-filter: blur(6px);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 24px;
|
||
z-index: 20;
|
||
}
|
||
.modal {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
border-radius: var(--r-card);
|
||
}
|
||
.modal h2 {
|
||
margin: 0 0 4px;
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
}
|
||
.modal-actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
.modal-actions .btn {
|
||
flex: 1;
|
||
}
|
||
|
||
/* ── 桌面 ──────────────────────────────────────────────── */
|
||
.desktop-wrap {
|
||
position: fixed;
|
||
inset: 0;
|
||
background: #000;
|
||
}
|
||
.desktop-frame {
|
||
width: 100%;
|
||
height: 100%;
|
||
border: none;
|
||
display: block;
|
||
}
|
||
/* 返回钮:浮起白色圆 blob */
|
||
.desktop-back {
|
||
position: fixed;
|
||
top: max(12px, env(safe-area-inset-top));
|
||
left: 12px;
|
||
width: 42px;
|
||
height: 42px;
|
||
border-radius: 50%;
|
||
border: none;
|
||
background: var(--surface);
|
||
color: var(--text);
|
||
font-size: 24px;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
z-index: 10;
|
||
box-shadow: var(--crease);
|
||
transition: transform 0.18s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.18s;
|
||
}
|
||
.desktop-back:active {
|
||
transform: scale(0.94);
|
||
box-shadow: var(--crease-press);
|
||
}
|
||
/* 文件按钮:返回钮下方 */
|
||
.desktop-files-btn {
|
||
position: fixed;
|
||
top: max(12px, env(safe-area-inset-top));
|
||
left: 64px;
|
||
width: 42px;
|
||
height: 42px;
|
||
border-radius: 50%;
|
||
border: none;
|
||
background: var(--surface);
|
||
color: var(--text);
|
||
font-size: 20px;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
z-index: 10;
|
||
box-shadow: var(--crease);
|
||
transition: transform 0.18s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
}
|
||
.desktop-files-btn:active {
|
||
transform: scale(0.94);
|
||
}
|
||
|
||
/* 拖拽落区 */
|
||
.drop-zone {
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: 30;
|
||
background: rgba(7, 193, 96, 0.16);
|
||
-webkit-backdrop-filter: blur(3px);
|
||
backdrop-filter: blur(3px);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.drop-card {
|
||
background: var(--surface);
|
||
border-radius: var(--r-card);
|
||
box-shadow: var(--crease);
|
||
padding: 28px 36px;
|
||
text-align: center;
|
||
border: 2px dashed rgba(var(--green-rgb) / 0.5);
|
||
}
|
||
.drop-icon {
|
||
font-size: 36px;
|
||
color: var(--wx-green);
|
||
}
|
||
.drop-title {
|
||
margin-top: 8px;
|
||
font-size: 17px;
|
||
font-weight: 700;
|
||
}
|
||
.drop-sub {
|
||
margin-top: 4px;
|
||
font-size: 13px;
|
||
color: var(--muted);
|
||
}
|
||
|
||
/* 文件传输面板 */
|
||
.files-panel {
|
||
position: fixed;
|
||
top: max(64px, calc(env(safe-area-inset-top) + 52px));
|
||
left: 12px;
|
||
width: min(330px, calc(100vw - 24px));
|
||
max-height: 70vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
background: var(--surface);
|
||
border-radius: var(--r-card);
|
||
box-shadow: var(--crease);
|
||
z-index: 11;
|
||
padding: 16px;
|
||
gap: 10px;
|
||
}
|
||
.files-head {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
}
|
||
.files-upload {
|
||
height: 42px;
|
||
font-size: 15px;
|
||
}
|
||
.clip-area {
|
||
width: 100%;
|
||
resize: vertical;
|
||
min-height: 96px;
|
||
padding: 10px 12px;
|
||
border-radius: 14px;
|
||
border: none;
|
||
background: var(--mf-trough, #edeef1);
|
||
color: var(--text, #1a1d24);
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
font-family: inherit;
|
||
box-shadow: inset 0 1px 3px rgba(51, 66, 102, 0.16);
|
||
outline: none;
|
||
box-sizing: border-box;
|
||
}
|
||
.clip-area:focus {
|
||
box-shadow: inset 0 1px 3px rgba(51, 66, 102, 0.16), 0 0 0 2px rgba(7, 193, 96, 0.35);
|
||
}
|
||
.security-status {
|
||
margin-top: 12px;
|
||
padding: 10px 14px;
|
||
border-radius: 14px;
|
||
background: var(--mf-trough, #edeef1);
|
||
box-shadow: inset 0 1px 3px rgba(51, 66, 102, 0.12);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 6px;
|
||
}
|
||
.security-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
font-size: 13px;
|
||
line-height: 1.4;
|
||
}
|
||
.iv-stuck-actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
margin-top: 14px;
|
||
}
|
||
.files-hint {
|
||
font-size: 12px;
|
||
color: var(--muted);
|
||
line-height: 1.5;
|
||
}
|
||
.files-list {
|
||
overflow-y: auto;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.files-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
box-shadow: inset 0 -1px 0 rgba(var(--shadow) / 0.08);
|
||
}
|
||
.files-item:last-child {
|
||
box-shadow: none;
|
||
}
|
||
.files-dl {
|
||
flex: 1;
|
||
min-width: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 10px;
|
||
padding: 11px 4px;
|
||
text-decoration: none;
|
||
color: var(--text);
|
||
font-size: 14px;
|
||
}
|
||
.files-name {
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.files-size {
|
||
flex: none;
|
||
color: var(--wx-green-dark);
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
}
|
||
.files-del {
|
||
flex: none;
|
||
width: 30px;
|
||
height: 30px;
|
||
border: none;
|
||
background: none;
|
||
color: var(--muted);
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
border-radius: 8px;
|
||
}
|
||
.files-del:active {
|
||
background: rgba(var(--danger-rgb) / 0.12);
|
||
color: var(--danger);
|
||
}
|
||
|
||
/* ── loading ───────────────────────────────────────────── */
|
||
.spinner {
|
||
width: 32px;
|
||
height: 32px;
|
||
border: 3px solid rgba(var(--green-rgb) / 0.2);
|
||
border-top-color: var(--wx-green);
|
||
border-radius: 50%;
|
||
animation: spin 0.8s linear infinite;
|
||
}
|
||
@keyframes spin {
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
/* ---------- 多实例:分区标题 ---------- */
|
||
.section-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin: 6px 6px 12px;
|
||
}
|
||
.section-title {
|
||
font-size: 15px;
|
||
font-weight: 700;
|
||
color: var(--text);
|
||
}
|
||
|
||
/* ---------- 实例网格 ---------- */
|
||
.inst-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||
gap: 14px;
|
||
margin-bottom: 22px;
|
||
/* 各卡片按自身内容高度,避免某张展开「管理」菜单时同行其它卡片被拉等高(显得也展开了) */
|
||
align-items: start;
|
||
}
|
||
.inst-card {
|
||
position: relative;
|
||
background: var(--surface);
|
||
border-radius: var(--r-card);
|
||
box-shadow: var(--crease);
|
||
padding: 18px;
|
||
overflow: hidden;
|
||
}
|
||
.inst-card::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
border-radius: inherit;
|
||
background: var(--sheen);
|
||
pointer-events: none;
|
||
}
|
||
.inst-card > * {
|
||
position: relative;
|
||
}
|
||
/* 菜单展开时:放开裁剪让悬浮层露出,并抬升层级盖住下方/同列卡片(仍低于弹窗 z-index 20) */
|
||
.inst-card.open-menu {
|
||
overflow: visible;
|
||
z-index: 5;
|
||
}
|
||
.inst-head {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 8px;
|
||
}
|
||
.inst-name {
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
color: var(--text);
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.inst-sub {
|
||
margin-top: 6px;
|
||
font-size: 13px;
|
||
color: var(--muted);
|
||
min-height: 18px;
|
||
}
|
||
.inst-actions {
|
||
display: flex;
|
||
gap: 8px;
|
||
margin-top: 14px;
|
||
}
|
||
.inst-enter {
|
||
flex: 1;
|
||
}
|
||
.inst-act {
|
||
flex: none;
|
||
}
|
||
.inst-act-wide {
|
||
flex: 1;
|
||
height: 42px;
|
||
font-size: 15px;
|
||
}
|
||
/* 管理卡片底部的文字操作(重命名/分配/删除) */
|
||
.inst-admin-links {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 2px;
|
||
margin-top: 10px;
|
||
padding-top: 8px;
|
||
box-shadow: inset 0 1px 0 rgba(var(--shadow) / 0.08);
|
||
}
|
||
.inst-admin-links .btn-text {
|
||
padding: 6px 8px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* 状态徽章配色 */
|
||
.tag-on {
|
||
background: rgba(var(--green-rgb) / 0.16);
|
||
color: var(--wx-green-dark);
|
||
}
|
||
.tag-busy {
|
||
background: rgba(51 102 204 / 0.16);
|
||
color: #2f5fd0;
|
||
}
|
||
.tag-warn {
|
||
background: rgba(245 158 11 / 0.18);
|
||
color: #b9770a;
|
||
}
|
||
|
||
/* ---------- chip 多选 / 展示 ---------- */
|
||
.field-label {
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
color: var(--muted);
|
||
margin: 14px 2px 8px;
|
||
}
|
||
.chip-row {
|
||
display: inline-flex;
|
||
flex-wrap: wrap;
|
||
gap: 6px;
|
||
margin-top: 4px;
|
||
}
|
||
.chip-row-pick {
|
||
display: flex;
|
||
}
|
||
.chip {
|
||
font-size: 12px;
|
||
border-radius: 999px;
|
||
padding: 5px 12px;
|
||
font-weight: 600;
|
||
line-height: 1.4;
|
||
}
|
||
.chip-static {
|
||
background: rgba(var(--green-rgb) / 0.12);
|
||
color: var(--wx-green-dark);
|
||
}
|
||
.chip-toggle {
|
||
border: none;
|
||
cursor: pointer;
|
||
background: var(--trough);
|
||
color: var(--muted);
|
||
box-shadow: inset 0 1px 2px rgba(var(--shadow) / 0.16);
|
||
transition: transform 0.15s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
}
|
||
.chip-toggle:active {
|
||
transform: scale(0.95);
|
||
}
|
||
.chip-toggle.on {
|
||
background: var(--wx-green);
|
||
color: #fff;
|
||
box-shadow: var(--crease-accent);
|
||
}
|
||
|
||
/* ---------- 空状态 ---------- */
|
||
.empty-state {
|
||
text-align: center;
|
||
padding: 30px 16px 36px;
|
||
}
|
||
.empty-action {
|
||
margin-top: 16px;
|
||
}
|
||
.empty-blob {
|
||
width: 96px;
|
||
height: 96px;
|
||
margin: 0 auto 16px;
|
||
border-radius: 50%;
|
||
background: var(--surface);
|
||
box-shadow: var(--crease);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 40px;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
.empty-blob::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
border-radius: inherit;
|
||
background: var(--sheen);
|
||
}
|
||
.empty-blob img {
|
||
width: 52px;
|
||
height: 52px;
|
||
position: relative;
|
||
}
|
||
.empty-title {
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
color: var(--text);
|
||
}
|
||
.empty-sub {
|
||
margin-top: 6px;
|
||
font-size: 13px;
|
||
color: var(--muted);
|
||
}
|
||
|
||
/* ── 默认密码安全告警条 ──────────────────────────────────── */
|
||
.warn-banner {
|
||
position: relative;
|
||
z-index: 1;
|
||
width: 100%;
|
||
text-align: left;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
border: none;
|
||
cursor: pointer;
|
||
background: rgba(var(--danger-rgb) / 0.1);
|
||
border-radius: var(--r-blob);
|
||
padding: 14px 16px;
|
||
margin: 4px 0 14px;
|
||
box-shadow: inset 0 0 0 1.5px rgba(var(--danger-rgb) / 0.3);
|
||
transition: transform 0.18s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
}
|
||
.warn-banner:active {
|
||
transform: scale(0.99);
|
||
}
|
||
.warn-icon {
|
||
flex: none;
|
||
width: 26px;
|
||
height: 26px;
|
||
border-radius: 50%;
|
||
background: var(--danger);
|
||
color: #fff;
|
||
font-weight: 800;
|
||
font-size: 16px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.warn-text {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
font-size: 13px;
|
||
color: var(--danger);
|
||
}
|
||
.warn-text b {
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* ── 删除实例:勾选是否连数据卷一起删 ──────────────────────── */
|
||
.purge-opt {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 10px;
|
||
cursor: pointer;
|
||
padding: 12px 14px;
|
||
border-radius: var(--r-small);
|
||
background: var(--trough);
|
||
font-size: 14px;
|
||
box-shadow: inset 0 1px 2px rgba(var(--shadow) / 0.14);
|
||
transition: box-shadow 0.18s;
|
||
}
|
||
.purge-opt.on {
|
||
box-shadow: inset 0 0 0 1.5px rgba(var(--danger-rgb) / 0.45);
|
||
}
|
||
.purge-check {
|
||
flex: none;
|
||
width: 20px;
|
||
height: 20px;
|
||
border-radius: 6px;
|
||
background: var(--surface);
|
||
box-shadow: var(--crease-press);
|
||
color: var(--danger);
|
||
font-weight: 800;
|
||
font-size: 13px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-top: 1px;
|
||
}
|
||
.purge-opt.on .purge-check {
|
||
background: var(--danger);
|
||
color: #fff;
|
||
}
|
||
|
||
/* ── Toast ──────────────────────────────────────────────── */
|
||
.toast-stack {
|
||
position: fixed;
|
||
left: 50%;
|
||
bottom: max(24px, env(safe-area-inset-bottom));
|
||
transform: translateX(-50%);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
align-items: center;
|
||
z-index: 50;
|
||
pointer-events: none;
|
||
}
|
||
.toast {
|
||
pointer-events: auto;
|
||
max-width: 80vw;
|
||
background: var(--surface);
|
||
color: var(--text);
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
padding: 11px 18px;
|
||
border-radius: 999px;
|
||
box-shadow: var(--crease);
|
||
animation: toast-in 0.32s cubic-bezier(0.2, 0.9, 0.2, 1);
|
||
}
|
||
.toast-ok {
|
||
color: var(--wx-green-dark);
|
||
}
|
||
.toast-error {
|
||
color: var(--danger);
|
||
}
|
||
@keyframes toast-in {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(10px) scale(0.96);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0) scale(1);
|
||
}
|
||
}
|
||
|
||
/* ── 桌面连接 loading 遮罩 ──────────────────────────────── */
|
||
.desktop-loading {
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: 5;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 14px;
|
||
background: var(--base);
|
||
}
|
||
.desktop-loading-text {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: var(--text);
|
||
}
|
||
.desktop-loading-sub {
|
||
font-size: 13px;
|
||
color: var(--muted);
|
||
text-align: center;
|
||
padding: 0 24px;
|
||
}
|
||
.desktop-loading-warn {
|
||
margin-top: 6px;
|
||
font-size: 12px;
|
||
color: var(--danger);
|
||
text-align: center;
|
||
padding: 0 24px;
|
||
}
|
||
|
||
/* ============================================================
|
||
* 微信 PC 式布局:左侧 tab 栏 + 右侧工作区
|
||
* ============================================================ */
|
||
.shell {
|
||
display: flex;
|
||
height: 100%;
|
||
min-height: 0;
|
||
background: var(--base);
|
||
}
|
||
|
||
/* —— 左侧栏 —— */
|
||
.sidebar {
|
||
flex: none;
|
||
width: 264px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
background: var(--surface);
|
||
box-shadow: 1px 0 0 rgba(var(--shadow) / 0.08), 4px 0 16px rgba(var(--shadow) / 0.05);
|
||
z-index: 20;
|
||
transition: width 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
padding-top: env(safe-area-inset-top);
|
||
}
|
||
.shell.collapsed .sidebar {
|
||
width: 64px;
|
||
}
|
||
.sb-top {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 8px;
|
||
padding: 14px 14px 10px;
|
||
}
|
||
.sb-brand {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
min-width: 0;
|
||
}
|
||
.sb-logo {
|
||
width: 30px;
|
||
height: 30px;
|
||
flex: none;
|
||
border-radius: 9px;
|
||
}
|
||
.sb-name {
|
||
font-size: 17px;
|
||
font-weight: 700;
|
||
white-space: nowrap;
|
||
}
|
||
.sb-collapse {
|
||
flex: none;
|
||
width: 32px;
|
||
height: 32px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border: none;
|
||
background: none;
|
||
color: var(--muted);
|
||
cursor: pointer;
|
||
border-radius: 9px;
|
||
}
|
||
.sb-collapse:active {
|
||
background: rgba(var(--shadow) / 0.06);
|
||
}
|
||
.collapsed .sb-top {
|
||
flex-direction: column;
|
||
}
|
||
|
||
.sb-nav {
|
||
padding: 4px 10px;
|
||
}
|
||
.sb-section {
|
||
padding: 12px 16px 6px;
|
||
font-size: 12px;
|
||
font-weight: 700;
|
||
color: var(--muted);
|
||
}
|
||
.sb-list {
|
||
flex: 1;
|
||
min-height: 0;
|
||
overflow-y: auto;
|
||
padding: 0 10px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
}
|
||
.sb-empty {
|
||
padding: 10px 16px;
|
||
font-size: 13px;
|
||
color: var(--muted);
|
||
}
|
||
|
||
.sb-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
width: 100%;
|
||
border: none;
|
||
background: none;
|
||
cursor: pointer;
|
||
padding: 9px 12px;
|
||
border-radius: 12px;
|
||
font-size: 15px;
|
||
color: var(--text);
|
||
text-align: left;
|
||
transition: background 0.15s;
|
||
}
|
||
.sb-item:hover {
|
||
background: rgba(var(--shadow) / 0.05);
|
||
}
|
||
.sb-item.on {
|
||
background: rgba(var(--green-rgb) / 0.12);
|
||
color: var(--wx-green-dark);
|
||
}
|
||
.sb-item.on .sb-ic {
|
||
color: var(--wx-green-dark);
|
||
}
|
||
.sb-ic {
|
||
flex: none;
|
||
width: 24px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: var(--muted);
|
||
}
|
||
.sb-label {
|
||
flex: 1;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
font-weight: 500;
|
||
}
|
||
.collapsed .sb-item {
|
||
justify-content: center;
|
||
padding: 9px 0;
|
||
}
|
||
|
||
/* 实例头像 + 状态点 */
|
||
.sb-avatar {
|
||
position: relative;
|
||
flex: none;
|
||
width: 34px;
|
||
height: 34px;
|
||
border-radius: 10px;
|
||
background: linear-gradient(150deg, var(--wx-green), var(--wx-green-dark));
|
||
color: #fff;
|
||
font-weight: 700;
|
||
font-size: 16px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-transform: uppercase;
|
||
}
|
||
.sb-dot {
|
||
position: absolute;
|
||
right: -2px;
|
||
bottom: -2px;
|
||
width: 11px;
|
||
height: 11px;
|
||
border-radius: 50%;
|
||
border: 2px solid var(--surface);
|
||
}
|
||
.sb-stxt {
|
||
flex: none;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
color: var(--muted);
|
||
}
|
||
.st-on {
|
||
background: #16c060;
|
||
color: var(--wx-green-dark);
|
||
}
|
||
.st-off {
|
||
background: #c2c7d0;
|
||
color: var(--muted);
|
||
}
|
||
.st-busy {
|
||
background: #2f7ad0;
|
||
color: #2f5fd0;
|
||
}
|
||
.st-warn {
|
||
background: #e6a23c;
|
||
color: #b9770a;
|
||
}
|
||
|
||
.sb-footer {
|
||
padding: 8px 10px calc(10px + env(safe-area-inset-bottom));
|
||
box-shadow: inset 0 1px 0 rgba(var(--shadow) / 0.08);
|
||
}
|
||
.sb-user {
|
||
padding: 8px 12px 2px;
|
||
font-size: 12px;
|
||
color: var(--muted);
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* —— 右侧工作区 —— */
|
||
.workspace {
|
||
flex: 1;
|
||
min-width: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100%;
|
||
min-height: 0;
|
||
}
|
||
.ws-page {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100%;
|
||
min-height: 0;
|
||
}
|
||
.ws-head {
|
||
flex: none;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
height: calc(52px + env(safe-area-inset-top));
|
||
padding: env(safe-area-inset-top) 16px 0;
|
||
background: var(--base);
|
||
box-shadow: inset 0 -1px 0 rgba(var(--shadow) / 0.07);
|
||
}
|
||
.ws-title {
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
flex: 1;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.ws-menu {
|
||
display: none;
|
||
flex: none;
|
||
width: 36px;
|
||
height: 36px;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border: none;
|
||
background: none;
|
||
color: var(--text);
|
||
cursor: pointer;
|
||
border-radius: 9px;
|
||
margin-left: -6px;
|
||
}
|
||
.ws-action {
|
||
flex: none;
|
||
border: none;
|
||
background: var(--surface);
|
||
color: var(--wx-green-dark);
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
padding: 6px 11px;
|
||
border-radius: 999px;
|
||
cursor: pointer;
|
||
box-shadow: var(--crease);
|
||
}
|
||
.ws-action:active {
|
||
transform: scale(0.96);
|
||
}
|
||
.ws-action.on {
|
||
background: var(--wx-green, #07c160);
|
||
color: #fff;
|
||
}
|
||
.ws-page .content {
|
||
flex: 1;
|
||
min-height: 0;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
/* 主页实例快捷卡 */
|
||
.home-card {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
width: 100%;
|
||
text-align: left;
|
||
border: none;
|
||
cursor: pointer;
|
||
background: var(--surface);
|
||
border-radius: var(--r-card);
|
||
padding: 16px;
|
||
box-shadow: var(--crease);
|
||
position: relative;
|
||
overflow: hidden;
|
||
transition: transform 0.16s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
}
|
||
.home-card::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
border-radius: inherit;
|
||
background: var(--sheen);
|
||
pointer-events: none;
|
||
}
|
||
.home-card:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: var(--crease-accent);
|
||
}
|
||
.home-card:active {
|
||
transform: scale(0.985);
|
||
}
|
||
.home-card-av {
|
||
position: relative;
|
||
flex: none;
|
||
width: 42px;
|
||
height: 42px;
|
||
border-radius: 12px;
|
||
background: linear-gradient(150deg, var(--wx-green), var(--wx-green-dark));
|
||
color: #fff;
|
||
font-weight: 700;
|
||
font-size: 20px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-transform: uppercase;
|
||
}
|
||
.home-card-main {
|
||
position: relative;
|
||
flex: 1;
|
||
min-width: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 3px;
|
||
}
|
||
.home-card-name {
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.home-card-meta {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
min-width: 0;
|
||
}
|
||
.home-card-st {
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
background: none !important;
|
||
flex: none;
|
||
}
|
||
.home-card-ver {
|
||
font-size: 12px;
|
||
color: var(--muted);
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.home-card-ver::before {
|
||
content: '·';
|
||
margin-right: 8px;
|
||
color: var(--muted);
|
||
}
|
||
|
||
/* —— 内嵌实例视图 —— */
|
||
.iv-stage {
|
||
position: relative;
|
||
flex: 1;
|
||
min-height: 0;
|
||
background: #000;
|
||
}
|
||
.iv-center {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: var(--base);
|
||
}
|
||
/* VNC 分支:纵向 flex —— 画面区(.iv-canvas, flex:1) 在上,中文输入条在下,互不重叠。
|
||
输入条占用布局空间 → iframe 区域变小 → resize=remote 让远端桌面同步缩小,微信画面完整可见、不被遮。 */
|
||
.iv-stage--vnc {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.iv-canvas {
|
||
position: relative;
|
||
flex: 1;
|
||
min-height: 0;
|
||
background: #000;
|
||
}
|
||
.iv-frame {
|
||
position: absolute;
|
||
inset: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
border: none;
|
||
display: block;
|
||
}
|
||
.iv-imebar {
|
||
flex: 0 0 auto;
|
||
display: flex;
|
||
gap: 8px;
|
||
align-items: center;
|
||
padding: 8px 12px;
|
||
/* 与顶部 nav 栏同款牛奶布艺浅色主题 + 顶部细折痕分隔 */
|
||
background: var(--base);
|
||
box-shadow: inset 0 1px 0 rgba(var(--shadow) / 0.07);
|
||
box-sizing: border-box;
|
||
}
|
||
.iv-imebar-input {
|
||
flex: 1;
|
||
height: 38px;
|
||
max-height: 38px;
|
||
resize: none;
|
||
padding: 9px 12px;
|
||
border-radius: 10px;
|
||
border: none;
|
||
outline: none;
|
||
font-size: 14px;
|
||
font-family: inherit;
|
||
line-height: 1.3;
|
||
/* 牛奶布艺凹槽输入框:与「剪贴板」文本框一致 */
|
||
background: var(--trough);
|
||
color: var(--text);
|
||
box-shadow: inset 0 1px 3px rgba(var(--shadow) / 0.16);
|
||
box-sizing: border-box;
|
||
}
|
||
.iv-imebar-input:focus {
|
||
box-shadow: inset 0 1px 3px rgba(var(--shadow) / 0.16), 0 0 0 2px rgba(7, 193, 96, 0.35);
|
||
}
|
||
.iv-imebar-send {
|
||
height: 38px;
|
||
flex: 0 0 auto;
|
||
padding: 0 18px;
|
||
}
|
||
.iv-loading,
|
||
.iv-drop {
|
||
position: absolute;
|
||
inset: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 12px;
|
||
z-index: 5;
|
||
}
|
||
.iv-loading {
|
||
background: var(--base);
|
||
}
|
||
.iv-loading-text {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
}
|
||
.iv-loading-sub {
|
||
font-size: 13px;
|
||
color: var(--muted);
|
||
text-align: center;
|
||
padding: 0 24px;
|
||
}
|
||
.iv-loading-warn {
|
||
margin-top: 4px;
|
||
font-size: 12px;
|
||
color: var(--danger);
|
||
text-align: center;
|
||
padding: 0 24px;
|
||
}
|
||
.iv-drop {
|
||
z-index: 30;
|
||
background: rgba(7, 193, 96, 0.16);
|
||
-webkit-backdrop-filter: blur(3px);
|
||
backdrop-filter: blur(3px);
|
||
}
|
||
.iv-files {
|
||
position: absolute;
|
||
top: 14px;
|
||
right: 14px;
|
||
width: min(330px, calc(100% - 28px));
|
||
max-height: calc(100% - 28px);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
background: var(--surface);
|
||
border-radius: var(--r-card);
|
||
box-shadow: var(--crease), 0 8px 30px rgba(var(--shadow) / 0.18);
|
||
z-index: 12;
|
||
padding: 16px;
|
||
}
|
||
/* 只读遮罩:他人正在操作时盖住 VNC,拦截键鼠(半透,仍能看到画面) */
|
||
.iv-lock {
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 8;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: rgba(26, 29, 36, 0.28);
|
||
-webkit-backdrop-filter: blur(1.5px);
|
||
backdrop-filter: blur(1.5px);
|
||
}
|
||
.iv-lock-card {
|
||
background: var(--surface);
|
||
border-radius: var(--r-card);
|
||
box-shadow: var(--crease), 0 8px 30px rgba(var(--shadow) / 0.25);
|
||
padding: 22px 26px;
|
||
text-align: center;
|
||
max-width: 320px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
.iv-lock-title {
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
}
|
||
.iv-lock-sub {
|
||
font-size: 13px;
|
||
color: var(--muted);
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.iv-notice {
|
||
text-align: center;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 14px;
|
||
padding: 24px;
|
||
}
|
||
.iv-notice-title {
|
||
font-size: 17px;
|
||
font-weight: 700;
|
||
}
|
||
.iv-notice-sub {
|
||
font-size: 13px;
|
||
color: var(--muted);
|
||
}
|
||
.iv-notice-btn {
|
||
padding: 0 22px;
|
||
height: 44px;
|
||
}
|
||
|
||
/* —— 移动端:侧栏变抽屉 —— */
|
||
.shell-backdrop {
|
||
display: none;
|
||
}
|
||
@media (max-width: 767px) {
|
||
.sidebar {
|
||
position: fixed;
|
||
top: 0;
|
||
bottom: 0;
|
||
left: 0;
|
||
width: 82vw;
|
||
max-width: 320px;
|
||
transform: translateX(-100%);
|
||
transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
box-shadow: 0 0 40px rgba(var(--shadow) / 0.35);
|
||
}
|
||
.shell.drawer-open .sidebar {
|
||
transform: none;
|
||
}
|
||
.shell.drawer-open .shell-backdrop {
|
||
display: block;
|
||
position: fixed;
|
||
inset: 0;
|
||
background: rgba(26, 29, 36, 0.4);
|
||
z-index: 15;
|
||
}
|
||
.ws-menu {
|
||
display: flex;
|
||
}
|
||
.ws-action {
|
||
padding: 7px 12px;
|
||
}
|
||
}
|
||
|
||
/* 宽屏:工作区内容容器更宽(实例网格多列) */
|
||
@media (min-width: 880px) {
|
||
.ws-page .content {
|
||
max-width: 940px;
|
||
}
|
||
}
|
||
|
||
/* ── 数据卷管理(管理员)──────────────────────────────────── */
|
||
.vol-modal {
|
||
width: 640px;
|
||
max-width: 92vw;
|
||
max-height: 86vh;
|
||
}
|
||
/* 运行中警示条:柔和琥珀,inset 凹槽质感(不是红色危险) */
|
||
.vol-warn {
|
||
background: rgba(245, 166, 35, 0.14);
|
||
color: #9a6400;
|
||
font-size: 13px;
|
||
line-height: 1.5;
|
||
padding: 9px 12px;
|
||
border-radius: var(--r-small);
|
||
}
|
||
/* 分区容器:内部元素紧凑成组(label 紧贴其内容),分区之间靠 .modal 的 12px gap 拉开 */
|
||
.vol-sec {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
}
|
||
.vol-section-label {
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
color: var(--muted);
|
||
}
|
||
.vol-hint {
|
||
font-size: 12px;
|
||
color: var(--muted);
|
||
line-height: 1.5;
|
||
}
|
||
.vol-topbar {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
/* 主操作:中号浮起胶囊(比默认 48px 更克制,和弹窗比例协调) */
|
||
.vol-topbar .btn {
|
||
height: 40px;
|
||
padding: 0 18px;
|
||
font-size: 14px;
|
||
flex: 0 0 auto;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-decoration: none;
|
||
}
|
||
.vol-crumbs {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: 2px;
|
||
font-size: 13px;
|
||
}
|
||
.vol-crumb {
|
||
border: none;
|
||
background: none;
|
||
color: var(--wx-green);
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
padding: 2px 4px;
|
||
border-radius: 8px;
|
||
}
|
||
.vol-crumb:active {
|
||
background: rgba(var(--green-rgb) / 0.12);
|
||
}
|
||
.vol-crumb:disabled {
|
||
color: var(--muted);
|
||
cursor: default;
|
||
}
|
||
.vol-sep {
|
||
color: var(--muted);
|
||
}
|
||
/* 工具栏:浮起小胶囊(绿字),和上面「扁平绿色面包屑」明显区分,读起来是"按钮"而非散落文字 */
|
||
.vol-tools {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
.vol-tools .btn-text {
|
||
background: var(--surface);
|
||
box-shadow: var(--crease-press);
|
||
font-size: 14px;
|
||
padding: 8px 14px;
|
||
}
|
||
.vol-tools .btn-text:active {
|
||
transform: scale(0.96);
|
||
}
|
||
.vol-tools .btn-text:disabled {
|
||
opacity: 0.5;
|
||
}
|
||
.vol-mkdir {
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
.vol-mkdir .input {
|
||
flex: 1;
|
||
}
|
||
.vol-busy {
|
||
font-size: 13px;
|
||
color: var(--wx-green-dark);
|
||
font-weight: 600;
|
||
}
|
||
/* 列表容器:凹槽(inset),内部条目为浮起 bump(hover) */
|
||
.vol-list {
|
||
background: var(--trough);
|
||
border-radius: var(--r-small);
|
||
padding: 6px;
|
||
max-height: 44vh;
|
||
overflow-y: auto;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
box-shadow: inset 0 1px 3px rgba(var(--shadow) / 0.22);
|
||
}
|
||
.vol-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
border-radius: 12px;
|
||
padding: 2px 4px 2px 6px;
|
||
}
|
||
.vol-row:hover {
|
||
background: var(--surface);
|
||
box-shadow: var(--crease-press);
|
||
}
|
||
.vol-main {
|
||
flex: 1;
|
||
min-width: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 9px;
|
||
border: none;
|
||
background: none;
|
||
text-align: left;
|
||
padding: 8px 4px;
|
||
color: var(--text);
|
||
font-size: 14px;
|
||
}
|
||
.vol-main:disabled {
|
||
opacity: 0.55;
|
||
}
|
||
.vol-up {
|
||
color: var(--muted);
|
||
}
|
||
.vol-ic {
|
||
flex: 0 0 auto;
|
||
width: 20px;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: var(--muted);
|
||
}
|
||
.vol-ic.dir {
|
||
color: var(--wx-green);
|
||
}
|
||
.vol-ic svg {
|
||
display: block;
|
||
}
|
||
.vol-nm {
|
||
flex: 1;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.vol-meta {
|
||
flex: 0 0 auto;
|
||
color: var(--muted);
|
||
font-size: 12px;
|
||
padding-left: 8px;
|
||
}
|
||
.vol-rename {
|
||
flex: 1;
|
||
margin: 2px 0;
|
||
}
|
||
.vol-acts {
|
||
flex: 0 0 auto;
|
||
display: flex;
|
||
gap: 3px;
|
||
}
|
||
.vol-act {
|
||
border: none;
|
||
background: var(--trough);
|
||
color: var(--muted);
|
||
width: 30px;
|
||
height: 30px;
|
||
border-radius: 9px;
|
||
cursor: pointer;
|
||
text-decoration: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: var(--crease-press);
|
||
}
|
||
.vol-row:hover .vol-act {
|
||
background: var(--base);
|
||
color: var(--text);
|
||
}
|
||
.vol-act:active {
|
||
transform: scale(0.92);
|
||
}
|
||
.vol-act.danger:hover {
|
||
color: var(--danger);
|
||
background: rgba(var(--danger-rgb) / 0.12);
|
||
}
|
||
.vol-act:disabled {
|
||
opacity: 0.4;
|
||
cursor: default;
|
||
}
|