/* ============================================================ 流·Studio · Restraint 风格(Firecrawl-inspired) 适用所有页面 · 米白底 + 单橙 accent + 0 圆角硬边容器 ============================================================ */ * { box-sizing: border-box; margin: 0; padding: 0; } :root { --bg: #FAF9F5; --bg-soft: #F4F2EC; --card: #FFFFFF; --border: #E9E5DB; --border-soft: #EFEBE0; --ink: #15140F; --ink-2: #5A584F; --ink-3: #9C988C; --ink-4: #C8C4B8; --orange: #E55B26; --orange-soft: #FAE8DC; --orange-tint: #FFF4ED; --orange-hover: #D04E1F; --green: #3F6B3F; --green-bg: #EAF2EA; --green-bd: #D5E5D5; --red: #B33A2A; --red-bg: #FBEBE7; --red-bd: #F2D6CE; } html, body { background: var(--bg); color: var(--ink); font-family: 'Inter', 'PingFang SC', 'Microsoft YaHei', -apple-system, sans-serif; font-size: 13px; line-height: 1.5; -webkit-font-smoothing: antialiased; } a { color: inherit; text-decoration: none; } button { font: inherit; cursor: pointer; border: 0; background: none; color: inherit; } input, textarea, select { font: inherit; color: inherit; outline: none; } img, svg, video { display: block; max-width: 100%; } .num, .tnum { font-variant-numeric: tabular-nums; } .mono { font-family: 'JetBrains Mono', monospace; } .muted { color: var(--ink-2); } .muted-2 { color: var(--ink-3); } .spacer { flex: 1; } .hstack { display: flex; align-items: center; gap: 8px; } .vstack { display: flex; flex-direction: column; gap: 8px; } .divider { height: 1px; background: var(--border); margin: 14px 0; } /* ─── App shell ─── */ .app { display: grid; grid-template-columns: 248px 1fr; min-height: 100vh; } /* ─── Sidebar ─── */ aside.sidebar { padding: 18px 14px; border-right: 1px solid var(--border); background: var(--bg); position: sticky; top: 0; height: 100vh; overflow-y: auto; } .brand { display: flex; align-items: center; gap: 10px; padding: 6px 8px 14px; } .flame { width: 22px; height: 22px; color: var(--orange); } .flame svg { width: 100%; height: 100%; } .brand .name { font-weight: 700; font-size: 18px; letter-spacing: -.012em; } .search-box { display: flex; align-items: center; gap: 8px; padding: 9px 12px; background: var(--card); border: 1px solid var(--border); border-radius: 9px; color: var(--ink-3); margin-bottom: 14px; cursor: text; } .search-box svg { width: 14px; height: 14px; } .search-box input { flex: 1; border: 0; background: transparent; font-size: 13px; color: var(--ink); } .search-box input::placeholder { color: var(--ink-3); } .search-box .kbd { margin-left: auto; font-family: 'JetBrains Mono', monospace; font-size: 11px; background: var(--bg-soft); padding: 1px 6px; border-radius: 4px; border: 1px solid var(--border-soft); } .nav-section { font-size: 10.5px; color: var(--ink-3); padding: 14px 12px 6px; letter-spacing: .08em; text-transform: uppercase; font-weight: 600; } nav { display: flex; flex-direction: column; gap: 1px; } nav a { display: flex; align-items: center; gap: 11px; padding: 8px 12px; color: var(--ink-2); font-size: 13.5px; font-weight: 500; border-radius: 7px; cursor: pointer; user-select: none; } nav a:hover { background: var(--bg-soft); color: var(--ink); } nav a.active { background: var(--orange-tint); color: var(--orange); } nav a svg { width: 14px; height: 14px; opacity: .85; } nav a.active svg { opacity: 1; } nav a .pill-mini { margin-left: auto; font-family: 'JetBrains Mono', monospace; font-size: 9.5px; font-weight: 600; padding: 2px 6px; background: var(--card); color: var(--ink-3); border: 1px solid var(--border); border-radius: 999px; letter-spacing: .04em; } nav a.disabled { color: var(--ink-4); cursor: not-allowed; } nav a.disabled:hover { background: transparent; color: var(--ink-4); } .aside-foot { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); } .user { display: flex; align-items: center; gap: 9px; padding: 8px; border-radius: 8px; cursor: pointer; } .user:hover { background: var(--bg-soft); } .user .av { width: 24px; height: 24px; border-radius: 6px; background: var(--ink); color: #FFF; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 11px; } .user .em { font-size: 12.5px; } /* ─── Main + grid background ─── */ main { position: relative; overflow: hidden; background: var(--bg); } .grid-bg { position: absolute; inset: 0; pointer-events: none; background-image: url("data:image/svg+xml;utf8,"), url("data:image/svg+xml;utf8,"), url("data:image/svg+xml;utf8,"); background-size: 240px 240px, 60px 60px, 240px 240px; mask-image: radial-gradient(ellipse 95% 80% at 50% 35%, #000 25%, transparent 95%); -webkit-mask-image: radial-gradient(ellipse 95% 80% at 50% 35%, #000 25%, transparent 95%); } .scatter { position: absolute; font-family: 'JetBrains Mono', monospace; font-size: 8.5px; line-height: 1.05; color: var(--ink-4); white-space: pre; pointer-events: none; opacity: .8; letter-spacing: .04em; } .tag-corner { position: absolute; color: var(--ink-3); font-family: 'JetBrains Mono', monospace; font-size: 10.5px; letter-spacing: .06em; pointer-events: none; opacity: .85; z-index: 1; } .sq-mark { position: absolute; width: 5px; height: 5px; background: var(--ink-3); opacity: .55; pointer-events: none; } /* ─── Topbar ─── */ .topbar { display: flex; align-items: center; gap: 12px; padding: 12px 24px; border-bottom: 1px solid var(--border); background: var(--bg); position: relative; z-index: 2; } .crumbs { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-3); } .crumbs .sep { color: var(--ink-4); } .crumbs .here { color: var(--ink); font-weight: 500; } .crumbs a:hover { color: var(--ink); } .topbar .right { margin-left: auto; display: flex; align-items: center; gap: 8px; } .balance-chip { display: inline-flex; align-items: center; gap: 7px; padding: 6px 12px 6px 10px; background: var(--card); border: 1px solid var(--border); border-radius: 999px; font-size: 12.5px; color: var(--ink-2); cursor: pointer; } .balance-chip:hover { background: var(--bg-soft); } .balance-chip strong { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; } .balance-chip svg { width: 13px; height: 13px; color: var(--orange); } .icon-btn { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; background: var(--card); border: 1px solid var(--border); border-radius: 9px; color: var(--ink-2); cursor: pointer; position: relative; } .icon-btn:hover { background: var(--bg-soft); color: var(--ink); } .icon-btn svg { width: 15px; height: 15px; } .icon-btn .dot-noti { position: absolute; top: 8px; right: 9px; width: 7px; height: 7px; border-radius: 50%; background: var(--orange); border: 1.5px solid var(--card); } /* ─── Content ─── */ .content { padding: 36px 48px 60px; position: relative; z-index: 1; max-width: 1480px; } .page-head { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 28px; gap: 16px; flex-wrap: wrap; } .page-head h1 { font-size: 26px; font-weight: 600; letter-spacing: -.018em; line-height: 1.2; } .page-head .sub { font-size: 13.5px; color: var(--ink-2); margin-top: 6px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; } .page-head .sub .mono { font-family: 'JetBrains Mono', monospace; font-size: 11.5px; color: var(--ink-3); } .page-head .actions { display: flex; gap: 8px; align-items: center; } .section-h { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 12px; } .section-h h2 { font-size: 15px; font-weight: 600; letter-spacing: -.01em; } .section-h .more { font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--ink-3); letter-spacing: .04em; cursor: pointer; } .section-h .more:hover { color: var(--orange); } /* ─── Buttons ─── */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 14px; border-radius: 9px; font-size: 13px; font-weight: 500; border: 1px solid var(--border); background: var(--card); color: var(--ink); cursor: pointer; white-space: nowrap; font-family: inherit; } .btn:hover { background: var(--bg-soft); } .btn:disabled, .btn.disabled { color: var(--ink-3); background: var(--bg-soft); cursor: not-allowed; } .btn svg { width: 13px; height: 13px; } .btn-primary { background: var(--orange); color: #FFF; border-color: var(--orange); font-weight: 600; padding: 8px 16px; } .btn-primary:hover { background: var(--orange-hover); border-color: var(--orange-hover); } .btn-primary:disabled { background: var(--bg-soft); color: var(--ink-3); border-color: var(--border); } .btn-ghost { background: transparent; border-color: transparent; color: var(--ink-2); } .btn-ghost:hover { background: var(--bg-soft); color: var(--ink); } .btn-sm { padding: 5px 11px; font-size: 12px; border-radius: 7px; } .btn-lg { padding: 10px 18px; font-size: 13.5px; } /* ─── Pills ─── */ .pill { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; font-size: 11.5px; font-weight: 500; border: 1px solid var(--border); background: var(--card); color: var(--ink-2); white-space: nowrap; } .pill.info { background: var(--orange-tint); color: var(--orange); border-color: var(--orange-soft); } .pill.ok { background: var(--green-bg); color: var(--green); border-color: var(--green-bd); } .pill.err { background: var(--red-bg); color: var(--red); border-color: var(--red-bd); } .pill.neutral { background: var(--bg-soft); color: var(--ink-2); border-color: var(--border); } .pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; } /* ─── Cards / containers (0 圆角硬边) ─── */ .card-hard { background: var(--card); border: 1px solid var(--border); position: relative; } .card-hard.with-corners::before, .card-hard.with-corners::after, .with-corners .corner-tr, .with-corners .corner-bl { position: absolute; color: var(--ink-3); font-family: 'JetBrains Mono', monospace; font-size: 13px; line-height: 1; } .card-hard.with-corners::before { content: '+'; top: -8px; left: -8px; } .card-hard.with-corners::after { content: '+'; bottom: -8px; right: -8px; } .with-corners .corner-tr { top: -8px; right: -8px; } .with-corners .corner-bl { bottom: -8px; left: -8px; } /* ─── Stats (KPI bar) ─── */ .stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; background: var(--card); border: 1px solid var(--border); position: relative; margin-bottom: 32px; } .stat { padding: 22px 24px; border-right: 1px solid var(--border); position: relative; cursor: pointer; transition: background .15s; } .stat:hover { background: var(--bg-soft); } .stat:last-child { border-right: 0; } .stat .lbl { font-size: 12.5px; color: var(--ink-3); font-weight: 500; display: flex; align-items: center; gap: 6px; } .stat .lbl .badge { font-family: 'JetBrains Mono', monospace; font-size: 9.5px; color: var(--ink-3); background: var(--bg-soft); padding: 1px 6px; border-radius: 4px; border: 1px solid var(--border-soft); } .stat .v { font-size: 30px; font-weight: 600; letter-spacing: -.02em; line-height: 1; margin-top: 14px; font-variant-numeric: tabular-nums; } .stat .v small { font-size: 14px; color: var(--ink-3); font-weight: 500; margin-left: 2px; } .stat .delta { font-family: 'JetBrains Mono', monospace; font-size: 11px; margin-top: 8px; color: var(--ink-3); letter-spacing: .02em; } .stat .delta.up { color: var(--green); } .stat .bar { height: 5px; background: var(--bg-soft); border-radius: 3px; margin-top: 12px; overflow: hidden; } .stat .bar > span { display: block; height: 100%; background: var(--orange); border-radius: 3px; } .stat .sub { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: var(--ink-3); margin-top: 8px; letter-spacing: .02em; } /* ─── Form fields ─── */ .field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; } .field-label { font-size: 12.5px; font-weight: 500; color: var(--ink); } .field-label .req { color: var(--red); margin-left: 2px; } .field-hint { font-size: 12px; color: var(--ink-3); } .input, .textarea, .select { height: 36px; padding: 0 12px; background: var(--card); border: 1px solid var(--border); border-radius: 9px; font-size: 13px; width: 100%; font-family: inherit; color: var(--ink); } .input:focus, .textarea:focus, .select:focus { border-color: var(--orange); box-shadow: 0 0 0 3px rgba(229, 91, 38, 0.10); } .input::placeholder, .textarea::placeholder { color: var(--ink-3); } .textarea { height: auto; min-height: 80px; padding: 10px 12px; line-height: 1.55; resize: vertical; } .select { appearance: none; background-image: url("data:image/svg+xml;utf8,"); background-repeat: no-repeat; background-position: right 10px center; padding-right: 30px; } /* ─── Tabs ─── */ .tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 18px; } .tab { padding: 9px 14px; font-size: 13px; color: var(--ink-2); border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; font-weight: 500; user-select: none; } .tab:hover { color: var(--ink); } .tab.active { color: var(--orange); border-bottom-color: var(--orange); } .tab .count { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: var(--ink-3); margin-left: 6px; padding: 1px 6px; background: var(--bg-soft); border-radius: 4px; } .tab.active .count { background: var(--orange-tint); color: var(--orange); } /* ─── Filter chips ─── */ .chip { height: 32px; padding: 0 12px; border: 1px solid var(--border); background: var(--card); border-radius: 8px; font-size: 12.5px; color: var(--ink-2); display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-family: inherit; } .chip:hover { background: var(--bg-soft); } .chip.active { border-color: var(--orange); color: var(--orange); background: var(--orange-tint); } .chip svg { width: 12px; height: 12px; } /* ─── Toolbar ─── */ .toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; flex-wrap: wrap; } .toolbar .search-inline { position: relative; flex: 1; max-width: 320px; } .toolbar .search-inline svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--ink-3); width: 14px; height: 14px; } .toolbar .search-inline input { padding-left: 34px; } /* ─── Progress (5 段流水线) ─── */ .prog { display: flex; gap: 3px; } .prog span { width: 18px; height: 5px; border-radius: 2px; background: var(--bg-soft); } .prog span.done { background: var(--ink-2); } .prog span.cur { background: var(--orange); } .prog span.fail { background: var(--red); } /* ─── Table ─── */ table.t { width: 100%; border-collapse: collapse; background: var(--card); border: 1px solid var(--border); } table.t thead th { text-align: left; font-size: 11.5px; font-weight: 500; color: var(--ink-3); padding: 12px 14px; background: var(--bg-soft); border-bottom: 1px solid var(--border); letter-spacing: .04em; text-transform: uppercase; font-family: 'JetBrains Mono', monospace; } table.t tbody td { padding: 14px; border-bottom: 1px solid var(--border); font-size: 13px; vertical-align: middle; } table.t tbody tr:last-child td { border-bottom: 0; } table.t tbody tr { cursor: pointer; } table.t tbody tr:hover { background: var(--bg-soft); } /* ─── Placeholder thumb ─── */ .placeholder { background: repeating-linear-gradient(135deg, rgba(0,0,0,0.025) 0 1px, transparent 1px 12px), var(--bg-soft); border: 1px solid var(--border-soft); display: grid; place-items: center; color: var(--ink-3); font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: .04em; user-select: none; overflow: hidden; position: relative; text-align: center; padding: 6px; } .placeholder .ph-frame { background: rgba(255, 255, 255, 0.92); border: 1px solid var(--border); padding: 3px 8px; font-size: 10.5px; color: var(--ink-2); font-weight: 500; } /* ─── Toast ─── */ .toast { position: fixed; bottom: 24px; right: 24px; background: var(--card); border: 1px solid var(--border); padding: 12px 16px; display: flex; align-items: center; gap: 10px; box-shadow: 0 4px 20px rgba(21, 20, 15, 0.06); transform: translateX(420px); transition: transform .3s cubic-bezier(0.34, 1.56, 0.64, 1); z-index: 1000; min-width: 240px; } .toast.show { transform: translateX(0); } .toast .ic-t { width: 24px; height: 24px; background: var(--orange-tint); color: var(--orange); border: 1px solid var(--orange-soft); display: grid; place-items: center; flex-shrink: 0; } .toast .ic-t svg { width: 12px; height: 12px; } .toast .txt { font-size: 12.5px; color: var(--ink); } .toast .txt .mono { font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--ink-3); display: block; margin-top: 2px; letter-spacing: .02em; } /* ─── Modal ─── */ .modal-bg { position: fixed; inset: 0; background: rgba(21, 20, 15, .42); display: none; align-items: center; justify-content: center; z-index: 999; opacity: 0; transition: opacity .2s; } .modal-bg.show { display: flex; opacity: 1; } .modal { background: var(--card); border: 1px solid var(--border); max-width: 480px; width: 90%; position: relative; transform: scale(.96); transition: transform .25s cubic-bezier(0.34, 1.56, 0.64, 1); } .modal-bg.show .modal { transform: scale(1); } .modal::before, .modal::after { content: '+'; position: absolute; color: var(--ink-3); font-family: 'JetBrains Mono', monospace; font-size: 13px; line-height: 1; } .modal::before { top: -8px; left: -8px; } .modal::after { bottom: -8px; right: -8px; } .modal .corner-tr, .modal .corner-bl { position: absolute; color: var(--ink-3); font-family: 'JetBrains Mono', monospace; font-size: 13px; line-height: 1; } .modal .corner-tr { top: -8px; right: -8px; } .modal .corner-bl { bottom: -8px; left: -8px; } .modal-h { padding: 20px 24px 14px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 12px; } .modal-h .ic-m { width: 36px; height: 36px; background: var(--orange-tint); color: var(--orange); border: 1px solid var(--orange-soft); display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .modal-h .ic-m svg { width: 17px; height: 17px; } .modal-h .ti { font-size: 15px; font-weight: 600; } .modal-h .ti span { display: block; font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--ink-3); font-weight: 400; margin-top: 3px; letter-spacing: .02em; } .modal-b { padding: 18px 24px; font-size: 13px; color: var(--ink-2); line-height: 1.7; } .modal-b .mono-acc { font-family: 'JetBrains Mono', monospace; color: var(--orange); background: var(--orange-tint); padding: 1px 5px; font-size: 11.5px; border-radius: 3px; } .modal-f { padding: 14px 24px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 8px; } /* ─── Drawer ─── */ .drawer-bg { position: fixed; inset: 0; background: rgba(21, 20, 15, .32); display: none; z-index: 90; } .drawer-bg.show { display: block; } .drawer { position: fixed; right: 0; top: 0; bottom: 0; width: 540px; max-width: 100vw; background: var(--card); border-left: 1px solid var(--border); z-index: 95; transform: translateX(100%); transition: transform .25s cubic-bezier(.32, .72, 0, 1); display: flex; flex-direction: column; } .drawer.show { transform: translateX(0); } .drawer-h { padding: 18px 24px; border-bottom: 1px solid var(--border); display: flex; align-items: center; } .drawer-h h3 { font-size: 16px; font-weight: 600; } .drawer-h .x { margin-left: auto; width: 28px; height: 28px; border-radius: 6px; display: grid; place-items: center; color: var(--ink-2); cursor: pointer; } .drawer-h .x:hover { background: var(--bg-soft); color: var(--ink); } .drawer-b { padding: 20px 24px; overflow-y: auto; flex: 1; } .drawer-f { padding: 14px 24px; border-top: 1px solid var(--border); display: flex; gap: 8px; justify-content: flex-end; background: var(--bg-soft); } /* ─── Scrollbar ─── */ ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: var(--ink-3); } /* ─── Responsive ─── */ @media (max-width: 1100px) { .app { grid-template-columns: 1fr; } aside.sidebar { display: none; } .stats { grid-template-columns: repeat(2, 1fr); } .stat:nth-child(2) { border-right: 0; } .stat:nth-child(1), .stat:nth-child(2) { border-bottom: 1px solid var(--border); } .content { padding: 24px; } } /* ─── Spinner ─── */ .spinner { width: 18px; height: 18px; border: 2px solid var(--border); border-top-color: var(--orange); border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } }