Files
wordcloud/frontend/src/styles.css
T

3848 lines
91 KiB
CSS

@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,300&family=DM+Mono:wght@400;500&display=swap');
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
color-scheme: light;
--bg: #f4f6f8;
--workspace-bg: #eef1f5;
--bg-panel: #ffffff;
--bg-panel-alt: #f7f9fb;
--border: #d8dde5;
--border-focus: #3b82f6;
--text-primary: #171a1f;
--text-secondary: #4c5563;
--text-muted: #7f8a99;
--accent: #2563eb;
--accent-light: #e8f1ff;
--accent-hover: #1d4ed8;
--on-accent: #ffffff;
--danger: #d83a3a;
--danger-light: #fff0f0;
--on-danger: #ffffff;
--success: #0f8f62;
--success-light: #e8f7f0;
--warn: #b7791f;
--shadow-sm: 0 1px 3px rgba(0,0,0,0.06);
--shadow-md: 0 10px 28px rgba(17,24,39,0.10);
--shadow-lg: 0 22px 60px rgba(17,24,39,0.18);
--radius-sm: 8px;
--radius-md: 14px;
--radius-lg: 20px;
--nav-height: 56px;
--panel-width: 240px;
--transition: 200ms cubic-bezier(0.4, 0, 0.2, 1);
--modal-backdrop-duration: 260ms;
--modal-backdrop-opacity: 0.05;
--modal-backdrop-blur: 8px;
--modal-open-duration: 320ms;
--modal-open-delay: 60ms;
--modal-open-easing: cubic-bezier(0.22, 1, 0.36, 1);
--modal-content-duration: 200ms;
--modal-content-delay: 120ms;
--modal-content-stagger: 55ms;
--modal-exit-duration: 160ms;
--modal-exit-easing: cubic-bezier(0.4, 0, 0.2, 1);
--font-main: 'DM Sans', sans-serif;
--font-mono: 'DM Mono', monospace;
/* 液态玻璃 */
--glass-bg: rgba(255, 255, 255, 0.55);
--glass-border: rgba(255, 255, 255, 0.72);
--glass-ring: rgba(24, 36, 56, 0.10);
--glass-blur: 16px;
}
:root[data-theme="dark"] {
color-scheme: dark;
--bg: #101114;
--workspace-bg: #15181d;
--bg-panel: #1c1f24;
--bg-panel-alt: #23272e;
--border: #363c46;
--border-focus: #76a9ff;
--text-primary: #f2f5f8;
--text-secondary: #c4ccd6;
--text-muted: #8994a3;
--accent: #6ea8ff;
--accent-light: #24364f;
--accent-hover: #91bdff;
--on-accent: #09111f;
--danger: #ff7a7a;
--danger-light: #3b2428;
--on-danger: #1c1011;
--success: #58d69c;
--success-light: #1d3329;
--warn: #e4b95a;
--shadow-sm: 0 1px 3px rgba(0,0,0,0.36);
--shadow-md: 0 8px 22px rgba(0,0,0,0.34);
--shadow-lg: 0 18px 44px rgba(0,0,0,0.42);
--glass-bg: rgba(24, 28, 34, 0.52);
--glass-border: rgba(255, 255, 255, 0.14);
--glass-ring: rgba(0, 0, 0, 0.34);
}
html, body, #root {
height: 100%;
width: 100%;
overflow: hidden;
}
body {
font-family: var(--font-main);
background: var(--bg);
color: var(--text-primary);
font-size: 13px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
transition: background var(--transition), color var(--transition);
}
/* ===== APP LAYOUT ===== */
.app-layout {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
background: var(--bg);
}
/* ===== NAVBAR ===== */
.navbar {
height: var(--nav-height);
background: var(--bg-panel);
border-bottom: 1px solid var(--border);
display: flex;
align-items: stretch;
flex-shrink: 0;
box-shadow: var(--shadow-sm);
z-index: 100;
}
.navbar-brand {
display: flex;
align-items: center;
padding: 0 20px;
gap: 10px;
border-right: 1px solid var(--border);
min-width: 180px;
}
.navbar-brand-icon {
width: 28px;
height: 28px;
background: var(--accent);
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
color: var(--on-accent);
font-size: 14px;
}
.navbar-brand-name {
font-weight: 600;
font-size: 14px;
color: var(--text-primary);
letter-spacing: 0;
}
/* 线性主流程面包屑:玻璃 pill,当前步高亮 */
.breadcrumb {
display: flex;
align-items: center;
gap: 4px;
}
.crumb {
padding: 4px 10px;
border-radius: 9px;
font-size: 13px;
font-weight: 500;
cursor: pointer;
border: 1px solid var(--border);
background: var(--bg);
color: var(--text-secondary);
transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.crumb:hover:not(:disabled) {
background: var(--accent-light);
color: var(--text-primary);
}
.crumb.active {
background: var(--accent);
color: var(--on-accent);
font-weight: 600;
}
.crumb:disabled {
opacity: 0.55;
cursor: default;
}
.crumb-sep {
color: var(--text-muted);
font-weight: 300;
padding: 0 2px;
}
.crumb-wrap {
display: inline-flex;
align-items: center;
}
.navbar-mode-badge {
display: inline-flex;
align-items: center;
height: 22px;
padding: 0 8px;
border-radius: 999px;
background: color-mix(in srgb, var(--accent) 16%, transparent);
color: var(--accent);
border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
font-size: 11px;
font-weight: 600;
white-space: nowrap;
}
.navbar-actions {
display: flex;
flex: 1;
}
.nav-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 3px;
padding: 0 12px;
border: none;
background: transparent;
cursor: pointer;
color: var(--text-secondary);
font-family: var(--font-main);
font-size: 11px;
font-weight: 500;
letter-spacing: 0;
border-bottom: 2px solid transparent;
transition: all var(--transition);
position: relative;
}
.nav-btn:hover {
color: var(--text-primary);
background: var(--bg);
}
.nav-btn.active {
color: var(--accent);
border-bottom-color: var(--accent);
background: var(--accent-light);
}
.nav-btn-icon {
font-size: 14px;
line-height: 1;
}
.nav-btn-label {
line-height: 1;
}
.navbar-end {
display: flex;
align-items: center;
padding: 0 16px;
border-left: 1px solid var(--border);
gap: 8px;
}
.navbar-end .nav-btn {
height: var(--nav-height);
}
.app-settings {
position: relative;
display: inline-flex;
align-items: center;
}
.app-settings-trigger {
white-space: nowrap;
}
.settings-window {
position: absolute;
top: calc(100% + 8px);
right: 0;
width: 310px;
z-index: 500;
display: grid;
gap: 14px;
padding: 14px;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel);
box-shadow: var(--shadow-lg);
color: var(--text-primary);
}
.settings-window-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
}
.settings-window-title {
font-size: 14px;
font-weight: 700;
color: var(--text-primary);
}
.settings-window-subtitle {
margin-top: 2px;
font-size: 11px;
color: var(--text-muted);
}
.settings-section {
display: grid;
gap: 8px;
}
.settings-section-title {
font-size: 11px;
font-weight: 700;
color: var(--text-secondary);
}
.settings-segmented {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 3px;
padding: 3px;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel-alt);
}
.settings-segment {
min-width: 0;
height: 30px;
padding: 0 6px;
border: none;
border-radius: var(--radius-sm);
background: transparent;
color: var(--text-secondary);
font-family: var(--font-main);
font-size: 12px;
cursor: pointer;
}
.settings-segment:hover {
color: var(--text-primary);
background: var(--bg);
}
.settings-segment.active {
background: var(--accent);
color: var(--on-accent);
box-shadow: var(--shadow-sm);
}
.background-mode-control {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.settings-note {
padding: 9px 10px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel-alt);
color: var(--text-muted);
font-size: 12px;
line-height: 1.5;
}
.theme-switch {
display: flex;
align-items: center;
gap: 2px;
padding: 3px;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel-alt);
}
.theme-btn {
height: 28px;
min-width: 44px;
padding: 0 10px;
border: none;
border-radius: var(--radius-sm);
background: transparent;
color: var(--text-secondary);
cursor: pointer;
font-family: var(--font-main);
font-size: 12px;
font-weight: 500;
transition: background var(--transition), color var(--transition), box-shadow var(--transition);
}
.theme-btn:hover {
color: var(--text-primary);
background: var(--bg);
}
.theme-btn.active {
color: var(--on-accent);
background: var(--accent);
box-shadow: var(--shadow-sm);
}
/* ===== MAIN CONTENT ===== */
.main-content {
display: flex;
flex: 1;
overflow: hidden;
}
.workspace-shell {
position: relative;
isolation: isolate;
background:
linear-gradient(color-mix(in srgb, var(--border) 56%, transparent) 1px, transparent 1px),
linear-gradient(90deg, color-mix(in srgb, var(--border) 56%, transparent) 1px, transparent 1px),
var(--workspace-bg);
background-size: 24px 24px;
}
.workspace-canvas {
width: 100%;
}
.floating-panel {
position: absolute;
max-width: calc(100% - 16px);
max-height: calc(100% - 16px);
min-width: 220px;
min-height: 160px;
display: flex;
flex-direction: column;
overflow: hidden;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel);
box-shadow: var(--shadow-lg);
color: var(--text-primary);
}
.floating-panel-titlebar {
height: 34px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 0 8px 0 10px;
border-bottom: 1px solid var(--border);
background: var(--bg-panel-alt);
cursor: move;
user-select: none;
}
.floating-panel-title {
min-width: 0;
display: flex;
align-items: center;
gap: 7px;
font-size: 12px;
font-weight: 700;
color: var(--text-primary);
}
.floating-panel-title span:last-child {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.floating-panel-icon {
display: inline-flex;
color: var(--accent);
font-size: 14px;
flex-shrink: 0;
}
.floating-panel-close {
width: 24px;
height: 24px;
display: inline-flex;
align-items: center;
justify-content: center;
border: none;
border-radius: var(--radius-sm);
background: transparent;
color: var(--text-muted);
cursor: pointer;
flex-shrink: 0;
}
.floating-panel-close:hover {
background: var(--danger-light);
color: var(--danger);
}
.floating-panel-content {
min-height: 0;
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.floating-panel .panel-body {
padding: 10px;
}
.floating-panel .table-empty {
min-height: 120px;
}
.floating-resize {
position: absolute;
z-index: 2;
}
.floating-resize-n,
.floating-resize-s {
left: 12px;
right: 12px;
height: 8px;
cursor: ns-resize;
}
.floating-resize-n { top: -4px; }
.floating-resize-s { bottom: -4px; }
.floating-resize-e,
.floating-resize-w {
top: 12px;
bottom: 12px;
width: 8px;
cursor: ew-resize;
}
.floating-resize-e { right: -4px; }
.floating-resize-w { left: -4px; }
.floating-resize-ne,
.floating-resize-nw,
.floating-resize-se,
.floating-resize-sw {
width: 16px;
height: 16px;
}
.floating-resize-ne { top: -4px; right: -4px; cursor: nesw-resize; }
.floating-resize-nw { top: -4px; left: -4px; cursor: nwse-resize; }
.floating-resize-se { right: -4px; bottom: -4px; cursor: nwse-resize; }
.floating-resize-sw { left: -4px; bottom: -4px; cursor: nesw-resize; }
body.floating-panel-moving,
body.resizing {
user-select: none;
}
/* ===== DOCK SNAP / STACK TABS ===== */
/* Docked columns flush against the screen edges — strip every corner radius
so the column reads as a continuous slab instead of a clipped card. */
.floating-panel[data-docked="left"],
.floating-panel[data-docked="right"] {
border-radius: 0;
}
.floating-panel[data-hidden="true"] {
display: none;
}
.floating-panel-snap-guide {
position: absolute;
pointer-events: none;
border: 2px dashed var(--accent, #6c63ff);
background: rgba(108, 99, 255, 0.12);
border-radius: var(--radius-md);
z-index: 9999;
}
/* Early edge "虚影" — a slim translucent strip hugging the side, shown while
dragging near a dockable edge but before the snap commits. Lighter than the
full snap guide so the two states read as distinct. */
.floating-panel-edge-highlight {
position: absolute;
pointer-events: none;
border: 1px dashed var(--accent, #6c63ff);
background: rgba(108, 99, 255, 0.06);
border-radius: var(--radius-md);
z-index: 9998;
animation: floating-panel-edge-pulse 1.4s ease-in-out infinite;
}
@keyframes floating-panel-edge-pulse {
0%, 100% { background: rgba(108, 99, 255, 0.05); }
50% { background: rgba(108, 99, 255, 0.13); }
}
/* When a dock column has a stacked tab bar, the active panel should sit
*below* the tab bar so it doesn't cover the tabs. Tab bar height = 30px. */
.workspace-shell[data-has-dock-tabs="true"] .floating-panel[data-active-tab="true"] {
margin-top: 0;
}
.dock-tab-bar {
position: absolute;
z-index: 100;
display: flex;
align-items: stretch;
height: 30px;
overflow: hidden;
border-bottom: 1px solid var(--border);
background: var(--bg-panel-alt);
/* Docked tab dock-bar sits flush against the screen edge — no rounding. */
border-radius: 0;
}
.dock-tab {
flex: 1 1 0;
min-width: 0;
display: flex;
align-items: center;
gap: 6px;
padding: 0 8px;
border: none;
border-right: 1px solid var(--border);
background: transparent;
color: var(--text-muted);
font-size: 11px;
font-weight: 600;
cursor: pointer;
user-select: none;
}
.dock-tab:last-child {
border-right: none;
}
.dock-tab:hover {
background: rgba(0, 0, 0, 0.04);
}
.dock-tab.active {
background: var(--bg-panel);
color: var(--text-primary);
border-bottom: 2px solid var(--accent, #6c63ff);
}
.dock-tab.dragging {
cursor: grabbing;
opacity: 0.65;
box-shadow: inset 0 0 0 1px var(--accent, #6c63ff);
}
.dock-tab-icon {
display: inline-flex;
color: var(--accent, #6c63ff);
font-size: 13px;
flex-shrink: 0;
}
.dock-tab-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dock-tab-close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
border-radius: var(--radius-sm);
flex-shrink: 0;
cursor: pointer;
}
.dock-tab-close:hover {
background: var(--danger-light, rgba(220, 53, 69, 0.12));
color: var(--danger, #dc3545);
}
/* ===== SIDE PANEL ===== */
.side-panel {
width: var(--panel-width);
background: var(--bg-panel);
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
flex-shrink: 0;
overflow: hidden;
transition: width var(--transition), opacity var(--transition);
}
.side-panel.collapsed {
width: 0;
border-right: none;
}
.side-panel-inner {
display: flex;
flex-direction: column;
height: 100%;
min-width: var(--panel-width);
}
.panel-header {
padding: 8px 12px 6px;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.panel-title {
font-size: 10px;
font-weight: 600;
letter-spacing: 0;
text-transform: uppercase;
color: var(--text-muted);
}
.panel-body {
flex: 1;
overflow-y: auto;
padding: 8px;
display: flex;
flex-direction: column;
gap: 6px;
}
.panel-body::-webkit-scrollbar {
width: 4px;
}
.panel-body::-webkit-scrollbar-track {
background: transparent;
}
.panel-body::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: 2px;
}
.panel-footer {
padding: 8px;
border-top: 1px solid var(--border);
flex-shrink: 0;
}
/* ===== CANVAS AREA ===== */
.canvas-area {
flex: 1;
position: relative;
overflow: hidden;
background: var(--bg);
}
.canvas-inner {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.canvas-placeholder {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
color: var(--text-muted);
user-select: none;
}
.canvas-placeholder-icon {
font-size: 48px;
opacity: 0.3;
}
.canvas-placeholder-text {
font-size: 13px;
font-weight: 400;
}
.canvas-image-wrapper {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.canvas-image {
max-width: 100%;
max-height: 100%;
object-fit: contain;
transition: transform 0.3s ease;
transform-origin: center center;
}
.highlight-overlay {
position: absolute;
pointer-events: none;
z-index: 10;
}
.highlight-box {
position: absolute;
border: 2px solid var(--accent);
background: color-mix(in srgb, var(--accent) 20%, transparent);
border-radius: 2px;
animation: highlight-pulse 1.5s ease infinite;
}
@keyframes highlight-pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.6; transform: scale(1.05); }
}
/* ===== VIEW CONTROLS ===== */
.view-controls {
position: absolute;
bottom: 16px;
right: 16px;
display: flex;
align-items: center;
gap: 4px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: 3px;
box-shadow: var(--shadow-md);
height: 32px;
}
.view-btn {
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
border: none;
background: transparent;
border-radius: var(--radius-sm);
cursor: pointer;
color: var(--text-secondary);
font-size: 12px;
transition: all var(--transition);
}
.view-btn:hover {
background: var(--bg);
color: var(--text-primary);
}
.view-btn.active {
background: var(--accent);
color: var(--on-accent);
}
.view-divider {
width: 1px;
height: 20px;
background: var(--border);
margin: 0 2px;
}
/* ===== FORM ELEMENTS ===== */
.form-group {
display: flex;
flex-direction: column;
gap: 3px;
}
.form-label {
font-size: 11px;
font-weight: 500;
color: var(--text-secondary);
letter-spacing: 0;
}
.form-input {
width: 100%;
padding: 5px 8px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg);
color: var(--text-primary);
font-family: var(--font-main);
font-size: 12px;
transition: border-color var(--transition), box-shadow var(--transition);
outline: none;
}
.form-input:focus {
border-color: var(--border-focus);
box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 20%, transparent);
}
.form-input::placeholder {
color: var(--text-muted);
}
.form-input-with-suffix {
display: flex;
align-items: center;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg);
overflow: hidden;
transition: border-color var(--transition), box-shadow var(--transition);
}
.form-input-with-suffix:focus-within {
border-color: var(--border-focus);
box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 20%, transparent);
}
.form-input-with-suffix .form-input {
border: none;
background: transparent;
box-shadow: none;
flex: 1;
}
.form-input-suffix {
padding: 7px 10px;
color: var(--text-muted);
font-size: 11px;
font-family: var(--font-mono);
background: var(--bg-panel-alt);
border-left: 1px solid var(--border);
flex-shrink: 0;
}
.form-row {
display: flex;
gap: 8px;
align-items: flex-end;
}
.form-row .form-group {
flex: 1;
}
/* ===== BUTTONS ===== */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 6px 10px;
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
font-family: var(--font-main);
font-size: 12px;
font-weight: 500;
transition: all var(--transition);
white-space: nowrap;
line-height: 1;
}
.btn:disabled {
opacity: 0.4;
cursor: not-allowed;
}
.btn-primary {
background: var(--accent);
color: var(--on-accent);
}
.btn-primary:hover:not(:disabled) {
background: var(--accent-hover);
}
.btn-secondary {
background: transparent;
color: var(--text-primary);
border: 1px solid var(--border);
}
.btn-secondary:hover:not(:disabled) {
background: var(--bg);
border-color: var(--border-focus);
}
.btn-danger {
background: var(--danger);
color: var(--on-danger);
}
.btn-block {
width: 100%;
}
.btn-sm {
padding: 4px 8px;
font-size: 11px;
}
.btn-generate {
width: 100%;
padding: 10px;
background: var(--accent);
color: var(--on-accent);
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
font-family: var(--font-main);
font-size: 13px;
font-weight: 600;
letter-spacing: 0;
transition: all var(--transition);
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.btn-generate:hover:not(:disabled) {
background: var(--accent-hover);
transform: translateY(-1px);
box-shadow: 0 4px 12px color-mix(in srgb, var(--accent) 28%, transparent);
}
.btn-generate:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none;
}
/* ===== FILE UPLOAD ===== */
.upload-zone {
border: 1.5px dashed var(--border);
border-radius: var(--radius-md);
padding: 10px 8px;
text-align: center;
cursor: pointer;
transition: all var(--transition);
background: var(--bg-panel-alt);
position: relative;
}
.upload-zone:hover, .upload-zone.drag-over {
border-color: var(--border-focus);
background: var(--accent-light);
}
.upload-zone input[type="file"] {
position: absolute;
inset: 0;
opacity: 0;
cursor: pointer;
width: 100%;
height: 100%;
}
.upload-zone-text {
font-size: 11px;
color: var(--text-muted);
line-height: 1.5;
pointer-events: none;
}
.upload-zone-icon {
font-size: 20px;
margin-bottom: 6px;
display: block;
}
.status-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 10px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg);
font-size: 11px;
gap: 8px;
}
.status-bar.success {
border-color: var(--success);
background: var(--success-light);
}
.status-bar.error {
border-color: var(--danger);
background: var(--danger-light);
}
.status-bar-filename {
color: var(--text-primary);
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.status-bar-label {
flex-shrink: 0;
font-weight: 500;
}
.status-bar.success .status-bar-label {
color: var(--success);
}
.status-bar.error .status-bar-label {
color: var(--danger);
}
/* ===== SECTION DIVIDER ===== */
.section-title {
font-size: 10px;
font-weight: 600;
color: var(--text-muted);
letter-spacing: 0;
text-transform: uppercase;
margin-bottom: 4px;
margin-top: 2px;
}
.section-divider {
height: 1px;
background: var(--border);
margin: 4px 0;
}
/* ===== RADIO GROUP ===== */
.radio-group {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
.radio-label {
display: flex;
align-items: center;
gap: 5px;
cursor: pointer;
font-size: 12px;
color: var(--text-secondary);
}
.radio-label input[type="radio"] {
accent-color: var(--accent);
}
.radio-label:has(input:checked) {
color: var(--text-primary);
font-weight: 500;
}
/* ===== EXPORT PANEL ===== */
.export-split {
display: flex;
gap: 8px;
}
.export-col {
flex: 1;
display: flex;
flex-direction: column;
gap: 8px;
padding: 10px;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel-alt);
}
.export-col-title {
font-size: 10px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0;
}
.note-text {
font-size: 10px;
color: var(--danger);
line-height: 1.4;
}
/* ===== TABLE ===== */
.data-table-wrapper {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
border: 1px solid var(--border);
border-radius: var(--radius-md);
}
.data-table-header {
display: grid;
grid-template-columns: 1fr 1.5fr 0.7fr;
background: var(--bg-panel-alt);
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.data-table-head-cell {
padding: 7px 8px;
font-size: 10px;
font-weight: 600;
color: var(--text-muted);
letter-spacing: 0;
text-transform: uppercase;
border-right: 1px solid var(--border);
}
.data-table-head-cell:last-child {
border-right: none;
}
.data-table-body {
flex: 1;
overflow-y: auto;
}
.data-table-body::-webkit-scrollbar {
width: 4px;
}
.data-table-body::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: 2px;
}
.data-table-row {
display: grid;
grid-template-columns: 1fr 1.5fr 0.7fr;
border-bottom: 1px solid var(--border);
transition: background var(--transition);
}
.data-table-row:last-child {
border-bottom: none;
}
.data-table-row:hover {
background: var(--accent-light);
}
.data-table-cell {
padding: 5px 8px;
font-size: 12px;
border-right: 1px solid var(--border);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.data-table-cell:last-child {
border-right: none;
}
.data-table-cell input {
width: 100%;
border: none;
background: transparent;
font-family: var(--font-main);
font-size: 12px;
color: var(--text-primary);
outline: none;
padding: 0;
}
.data-table-cell input:focus {
background: var(--accent-light);
}
.table-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 32px;
color: var(--text-muted);
font-size: 12px;
gap: 8px;
}
/* ===== PROGRESS ===== */
.progress-panel {
position: absolute;
bottom: 60px;
right: 16px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 16px;
width: 280px;
box-shadow: var(--shadow-lg);
z-index: 50;
}
.progress-title {
font-size: 12px;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 10px;
}
.progress-stage {
font-size: 11px;
color: var(--text-secondary);
margin-bottom: 8px;
}
.progress-bar-track {
height: 4px;
background: var(--border);
border-radius: 2px;
overflow: hidden;
margin-bottom: 6px;
}
.progress-bar-fill {
height: 100%;
background: var(--accent);
border-radius: 2px;
transition: width 0.4s ease;
}
.progress-message {
font-size: 11px;
color: var(--text-muted);
font-family: var(--font-mono);
}
/* ===== FIND PANEL ===== */
.find-result-text {
font-size: 11px;
color: var(--text-secondary);
padding: 8px 10px;
background: var(--bg-panel-alt);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
line-height: 1.5;
}
.btn-group {
display: flex;
gap: 6px;
}
.btn-group .btn {
flex: 1;
}
.wordcloud-spacing-panel {
display: grid;
gap: 8px;
}
.metric-box {
min-height: 28px;
display: flex;
align-items: center;
padding: 5px 8px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel-alt);
color: var(--text-secondary);
font-family: var(--font-mono);
font-size: 12px;
}
.spacing-result,
.spacing-batch-list {
display: grid;
gap: 6px;
padding: 8px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel-alt);
}
.spacing-result.stale {
border-color: var(--warn);
}
.spacing-result-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
color: var(--text-secondary);
font-size: 12px;
}
.spacing-result-row span {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.spacing-result-row strong {
flex-shrink: 0;
color: var(--text-primary);
font-family: var(--font-mono);
font-size: 12px;
}
.spacing-result-meta,
.spacing-warning,
.spacing-error {
font-size: 11px;
line-height: 1.5;
}
.spacing-result-meta {
color: var(--text-muted);
}
.spacing-warning {
color: var(--warn);
}
.spacing-error {
color: var(--danger);
}
/* ===== LINK ===== */
.text-link {
color: var(--danger);
text-decoration: none;
font-size: 12px;
font-weight: 500;
cursor: pointer;
}
.text-link:hover {
text-decoration: underline;
}
/* ===== SCROLLBAR GLOBAL ===== */
* {
scrollbar-width: thin;
scrollbar-color: var(--border) transparent;
}
/* ===== LOADING SPINNER ===== */
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
width: 14px;
height: 14px;
border: 2px solid color-mix(in srgb, var(--on-accent) 42%, transparent);
border-top-color: var(--on-accent);
border-radius: 50%;
animation: spin 0.8s linear infinite;
flex-shrink: 0;
}
.spinner-dark {
border-color: color-mix(in srgb, var(--accent) 24%, transparent);
border-top-color: var(--accent);
}
/* ===== 3D VIEW ===== */
.view-3d-container {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
perspective: 1000px;
}
.view-3d-image {
max-width: 80%;
max-height: 80%;
object-fit: contain;
transform: rotateX(20deg) rotateY(-15deg);
box-shadow: 0 40px 80px rgba(0,0,0,0.2);
border-radius: var(--radius-md);
animation: float3d 4s ease-in-out infinite;
}
@keyframes float3d {
0%, 100% { transform: rotateX(20deg) rotateY(-15deg) translateY(0); }
50% { transform: rotateX(18deg) rotateY(-12deg) translateY(-10px); }
}
/* ===== PANEL SLIDE ANIMATION ===== */
@keyframes panel-in {
from { opacity: 0; transform: translateX(-8px); }
to { opacity: 1; transform: translateX(0); }
}
.side-panel:not(.collapsed) .side-panel-inner {
animation: panel-in 0.2s ease forwards;
}
/* ===== TOOLTIP ===== */
.tooltip-wrap {
position: relative;
}
/* ===== MISC ===== */
.text-muted {
color: var(--text-muted);
}
.text-danger {
color: var(--danger);
}
.text-xs {
font-size: 11px;
}
.flex-row {
display: flex;
align-items: center;
gap: 8px;
}
/* ===== CANVAS STUDIO ===== */
.studio-panel {
--panel-width: 280px;
}
.studio-properties {
border-left: 1px solid var(--border);
border-right: none;
}
.studio-workspace {
flex: 1;
position: relative;
overflow: hidden;
background:
linear-gradient(45deg, color-mix(in srgb, var(--border) 38%, transparent) 25%, transparent 25%),
linear-gradient(-45deg, color-mix(in srgb, var(--border) 38%, transparent) 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, color-mix(in srgb, var(--border) 38%, transparent) 75%),
linear-gradient(-45deg, transparent 75%, color-mix(in srgb, var(--border) 38%, transparent) 75%);
background-size: 28px 28px;
background-position: 0 0, 0 14px, 14px -14px, -14px 0;
}
.canvas-size-pill,
.zoom-controls {
display: flex;
align-items: center;
gap: 6px;
height: 34px;
padding: 0 10px;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel);
color: var(--text-secondary);
box-shadow: var(--shadow-sm);
pointer-events: auto;
}
.zoom-controls span {
min-width: 44px;
text-align: center;
font-family: var(--font-mono);
font-size: 11px;
}
.studio-stage-scroll {
width: 100%;
height: 100%;
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
padding: 32px 16px 80px;
}
.studio-stage {
position: relative;
flex-shrink: 0;
box-shadow: 0 16px 50px rgba(0,0,0,0.18);
transform-origin: center center;
/* 画布背景仅限于本身,设计元素允许越出画布继续编辑。 */
overflow: visible;
isolation: isolate;
background: transparent;
}
.studio-stage::before {
content: '';
position: absolute;
inset: 0;
z-index: 0;
background: var(--canvas-background, #ffffff);
pointer-events: none;
}
.studio-bottombar {
position: absolute;
bottom: 14px;
height: 38px;
z-index: 20;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
pointer-events: none;
}
.studio-bottombar .canvas-size-pill,
.studio-bottombar .zoom-controls {
pointer-events: auto;
}
.studio-element {
position: absolute;
transform-origin: center center;
cursor: move;
user-select: none;
}
.studio-element.selected {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.studio-element.locked {
cursor: default;
}
.studio-sticker-image,
.studio-shape-svg {
display: block;
width: 100%;
height: 100%;
pointer-events: none;
}
.studio-sticker-image {
object-fit: contain;
}
.studio-sticker-image.gray-mask {
filter: grayscale(1);
}
.studio-text-element {
width: 100%;
height: 100%;
display: flex;
align-items: center;
white-space: pre-wrap;
overflow: hidden;
line-height: 1.1;
outline: none;
}
.missing-sticker {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
border: 1px dashed var(--danger);
color: var(--danger);
background: var(--danger-light);
}
.resize-handle {
position: absolute;
right: -8px;
bottom: -8px;
width: 16px;
height: 16px;
border: 2px solid var(--bg-panel);
border-radius: 50%;
background: var(--accent);
cursor: nwse-resize;
box-shadow: var(--shadow-sm);
}
.tool-grid {
display: grid;
gap: 8px;
}
.layer-list,
.layer-export-list {
display: grid;
gap: 8px;
}
.layer-row,
.layer-group-row,
.checkbox-row {
display: grid;
align-items: center;
gap: 6px;
padding: 6px;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel-alt);
}
.layer-row {
grid-template-columns: 56px minmax(0, 1fr);
gap: 8px;
padding: 6px;
align-items: start;
}
.layer-info {
display: grid;
gap: 5px;
min-width: 0;
}
.layer-thumb-wrap {
position: relative;
width: 56px;
height: 56px;
overflow: hidden;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel);
}
.layer-thumb {
position: absolute;
inset: 0;
overflow: hidden;
background:
linear-gradient(45deg, color-mix(in srgb, var(--border) 32%, transparent) 25%, transparent 25%),
linear-gradient(-45deg, color-mix(in srgb, var(--border) 32%, transparent) 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, color-mix(in srgb, var(--border) 32%, transparent) 75%),
linear-gradient(-45deg, transparent 75%, color-mix(in srgb, var(--border) 32%, transparent) 75%);
background-size: 8px 8px;
background-position: 0 0, 0 4px, 4px -4px, -4px 0;
}
.layer-thumb-hidden {
opacity: 0.45;
}
.layer-thumb-scale {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
}
.layer-thumb-doc {
position: relative;
transform-origin: 0 0;
pointer-events: none;
}
.layer-thumb-image,
.layer-thumb-text,
.layer-thumb-shape,
.layer-thumb-line {
position: relative;
pointer-events: none;
user-select: none;
box-sizing: border-box;
}
.layer-thumb-image {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
.layer-thumb-text {
overflow: hidden;
white-space: pre-wrap;
word-break: break-word;
line-height: 1.1;
}
.layer-thumb-line {
display: flex;
align-items: center;
}
.layer-thumb-ellipse {
border-radius: 50%;
}
.layer-row.active {
border-color: var(--border-focus);
background: var(--accent-light);
}
.layer-group-row {
grid-template-columns: minmax(0, 1fr) auto 24px;
background: color-mix(in srgb, var(--accent-light) 55%, var(--bg-panel-alt));
}
.layer-main-line,
.layer-sub-line {
display: grid;
align-items: center;
gap: 5px;
}
.layer-main-line {
grid-template-columns: 22px 22px minmax(0, 1fr);
}
.layer-sub-line {
grid-template-columns: minmax(0, 1fr) auto;
}
.layer-action-group {
display: flex;
gap: 2px;
}
.layer-icon-btn {
width: 18px;
height: 18px;
font-size: 10px;
border-radius: 4px;
}
.layer-name-input {
min-width: 0;
width: 100%;
height: 22px;
padding: 2px 5px;
font-size: 12px;
}
.layer-group-select {
width: 100%;
min-width: 0;
height: 24px;
padding: 2px 5px;
font-size: 11px;
}
.element-group-row {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 6px;
}
.checkbox-row {
grid-template-columns: 18px minmax(0, 1fr) auto;
font-size: 12px;
color: var(--text-secondary);
}
.checkbox-row input {
margin: 0;
}
.template-save-box {
display: grid;
gap: 10px;
padding: 10px;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel-alt);
}
.template-list {
display: grid;
gap: 10px;
}
.template-card {
display: grid;
gap: 10px;
padding: 10px;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel-alt);
transition: border-color var(--transition), background var(--transition), box-shadow var(--transition);
}
.template-card.active {
border-color: var(--border-focus);
background: var(--accent-light);
box-shadow: var(--shadow-sm);
}
.template-card-head {
display: flex;
justify-content: space-between;
gap: 8px;
}
.template-title {
font-size: 13px;
font-weight: 600;
color: var(--text-primary);
word-break: break-word;
}
.template-description {
margin-top: 3px;
font-size: 11px;
line-height: 1.45;
color: var(--text-secondary);
word-break: break-word;
}
.template-active-badge {
align-self: flex-start;
flex-shrink: 0;
padding: 2px 6px;
border-radius: var(--radius-sm);
background: var(--accent);
color: var(--on-accent);
font-size: 10px;
font-weight: 600;
}
.template-meta {
display: flex;
flex-wrap: wrap;
gap: 5px;
}
.template-meta span {
padding: 3px 6px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg);
color: var(--text-muted);
font-family: var(--font-mono);
font-size: 10px;
line-height: 1;
}
.template-actions {
display: grid;
grid-template-columns: 1fr 1fr 28px 28px;
gap: 6px;
align-items: center;
}
.template-edit-form {
display: grid;
gap: 8px;
}
.sticker-list {
display: grid;
grid-template-columns: 1fr;
gap: 10px;
}
.sticker-card {
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel-alt);
overflow: hidden;
}
.sticker-preview {
width: 100%;
height: 110px;
padding: 10px;
border: none;
border-bottom: 1px solid var(--border);
background: var(--bg);
cursor: pointer;
}
.sticker-preview:hover {
background: var(--accent-light);
}
.sticker-preview img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
}
.sticker-card-footer {
height: 34px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 0 8px;
font-size: 12px;
color: var(--text-secondary);
}
.sticker-card-footer span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.icon-btn {
width: 24px;
height: 24px;
border: none;
border-radius: var(--radius-sm);
background: transparent;
color: var(--text-muted);
cursor: pointer;
font-size: 16px;
line-height: 1;
}
.icon-btn:hover {
background: var(--danger-light);
color: var(--danger);
}
.color-input {
height: 36px;
padding: 3px;
}
/* ===== HELP PAGE ===== */
.help-page {
height: 100vh;
background:
radial-gradient(85% 55% at 90% -8%, var(--lf-blob-1), transparent 60%),
radial-gradient(70% 50% at 0% 30%, var(--lf-blob-2), transparent 60%),
radial-gradient(80% 45% at 70% 115%, var(--lf-blob-3), transparent 60%),
linear-gradient(to bottom, var(--lf-bg-a) 0%, var(--lf-bg-b) 100%);
color: var(--text-primary);
overflow: hidden;
}
/* 帮助页玻璃化(复用 --lf-* 令牌) */
.help-page .navbar {
background: var(--lf-nav-bg);
-webkit-backdrop-filter: blur(20px) saturate(160%);
backdrop-filter: blur(20px) saturate(160%);
border-bottom: 1px solid var(--lf-nav-border);
box-shadow: none;
}
.help-page .navbar-brand-name { color: var(--lf-text); }
.help-page .navbar-mode-badge,
.help-page .nav-btn-label { color: var(--lf-text-dim); }
.help-page .help-hero,
.help-page .help-step,
.help-page .help-item,
.help-page .help-row {
background: var(--lf-glass-bg);
border: 1px solid var(--lf-glass-border);
-webkit-backdrop-filter: blur(18px) saturate(170%);
backdrop-filter: blur(18px) saturate(170%);
box-shadow: inset 0 1px 0 var(--lf-glass-highlight), 0 6px 20px var(--lf-shadow);
}
.help-page .help-hero h1 { color: var(--lf-text); }
.help-page .help-hero p,
.help-page .help-section h2 { color: var(--lf-text-dim); }
.help-page .help-kicker { color: var(--lf-accent); }
.help-main {
height: calc(100vh - var(--nav-height));
overflow: auto;
padding: 24px;
}
.help-hero {
min-height: 220px;
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: end;
gap: 24px;
padding: 28px;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel);
box-shadow: var(--shadow-sm);
}
.help-kicker {
margin-bottom: 8px;
font-family: var(--font-mono);
font-size: 11px;
color: var(--accent);
}
.help-hero h1 {
margin-bottom: 10px;
font-size: clamp(28px, 4vw, 48px);
line-height: 1;
letter-spacing: 0;
}
.help-hero p {
max-width: 720px;
color: var(--text-secondary);
font-size: 14px;
line-height: 1.75;
}
.help-shortcuts {
display: flex;
gap: 10px;
align-items: center;
flex-wrap: wrap;
}
.help-section {
margin-top: 22px;
}
.help-section h2 {
margin-bottom: 12px;
font-size: 18px;
letter-spacing: 0;
}
.help-steps {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 12px;
}
.help-step,
.help-item,
.help-row {
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel);
box-shadow: var(--shadow-sm);
}
.help-step {
display: grid;
gap: 8px;
padding: 14px;
}
.help-step span {
width: 28px;
height: 28px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: var(--accent);
color: var(--on-accent);
font-family: var(--font-mono);
font-size: 12px;
}
.help-step strong,
.help-item strong,
.help-row strong {
font-size: 13px;
color: var(--text-primary);
}
.help-step p,
.help-item p,
.help-row p {
margin: 0;
color: var(--text-secondary);
font-size: 12px;
line-height: 1.65;
}
.help-grid {
display: grid;
gap: 12px;
}
.help-grid.two {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.help-item {
padding: 14px;
}
.help-table {
display: grid;
border: 1px solid var(--border);
border-radius: var(--radius-md);
overflow: hidden;
background: var(--bg-panel);
box-shadow: var(--shadow-sm);
}
.help-row {
display: grid;
grid-template-columns: minmax(160px, 0.28fr) minmax(0, 1fr);
gap: 14px;
align-items: start;
padding: 12px 14px;
border-width: 0 0 1px;
border-radius: 0;
box-shadow: none;
}
.help-row:last-child {
border-bottom: none;
}
/* ===== TEMPLATE HOME ===== */
.template-home {
min-height: 100vh;
background: var(--bg);
color: var(--text-primary);
}
.template-home-main {
min-height: calc(100vh - 58px);
padding: 24px;
overflow: auto;
}
.template-masonry {
column-count: 4;
column-gap: 18px;
}
.template-masonry-card {
width: 100%;
display: inline-block;
margin: 0 0 18px;
padding: 0;
break-inside: avoid;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel);
text-align: left;
overflow: hidden;
box-shadow: var(--shadow-sm);
cursor: pointer;
transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}
.template-masonry-card:hover {
transform: translateY(-3px);
border-color: var(--border-focus);
box-shadow: var(--shadow-md);
}
.template-preview {
width: 100%;
aspect-ratio: 4 / 3;
background: var(--bg-panel-alt);
overflow: hidden;
}
.template-preview.large {
aspect-ratio: 4 / 3;
min-height: 300px;
}
.template-preview img {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
.template-masonry-info,
.template-modal-body {
padding: 12px;
}
.template-title.large {
font-size: 18px;
}
.template-empty {
max-width: 360px;
margin: 12vh auto;
display: grid;
justify-items: center;
gap: 14px;
padding: 24px;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel);
}
.template-empty-title {
font-size: 15px;
font-weight: 600;
color: var(--text-secondary);
}
.template-modal-backdrop {
position: fixed;
inset: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
padding: 28px;
/* 只模糊、不压暗:去掉黑遮罩,保留毛玻璃磨砂。
模糊从 0 缓慢增强到目标值(700ms ease-out),进展不突兀 */
background: rgba(255, 255, 255, var(--modal-backdrop-opacity));
backdrop-filter: blur(var(--modal-backdrop-blur));
animation: modal-backdrop-in var(--modal-backdrop-duration) cubic-bezier(0.22, 1, 0.36, 1);
}
:root[data-theme="dark"] .template-modal-backdrop {
background: rgba(10, 12, 18, calc(var(--modal-backdrop-opacity) * 2.4));
}
.template-modal {
width: min(960px, 100%);
max-height: calc(100vh - 56px);
display: grid;
grid-template-columns: minmax(0, 1.35fr) minmax(280px, 0.65fr);
overflow: hidden;
border: 1px solid var(--border);
border-radius: var(--radius-lg);
background: var(--bg-panel);
box-shadow: var(--shadow-lg);
animation: template-pop var(--modal-open-duration) var(--modal-open-easing) var(--modal-open-delay) backwards;
}
.template-modal-backdrop.template-modal-exiting {
animation: modal-backdrop-out var(--modal-exit-duration) var(--modal-exit-easing) forwards;
}
.template-modal.template-modal-exiting {
animation: template-exit var(--modal-exit-duration) var(--modal-exit-easing);
}
.modal-layer {
animation: modal-layer-in var(--modal-content-duration) var(--modal-open-easing)
calc(var(--modal-content-delay) + var(--modal-content-stagger) * var(--modal-layer, 0)) backwards;
}
.template-modal-exiting .modal-layer {
animation: modal-layer-out var(--modal-exit-duration) var(--modal-exit-easing);
}
.template-detail-panel {
min-width: 0;
min-height: 0;
display: flex;
flex-direction: column;
gap: 16px;
padding: 22px;
overflow-y: auto;
}
.template-detail-summary {
display: grid;
gap: 5px;
}
.template-detail-eyebrow,
.template-detail-section-label {
color: var(--lf-text-faint, var(--text-muted));
font-size: 11px;
font-weight: 700;
letter-spacing: 0.08em;
line-height: 1.2;
text-transform: uppercase;
}
.template-detail-title {
margin: 0;
color: var(--lf-text, var(--text-primary));
font-size: 22px;
line-height: 1.25;
overflow-wrap: anywhere;
}
.template-detail-description {
display: grid;
gap: 8px;
padding: 13px 14px;
border: 1px solid var(--lf-glass-soft, var(--border));
border-radius: var(--radius-md);
background: var(--lf-input-bg, var(--bg-panel-alt));
}
.template-detail-description p {
display: -webkit-box;
margin: 0;
overflow: hidden;
color: var(--lf-text-dim, var(--text-secondary));
font-size: 13px;
line-height: 1.55;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
}
.template-detail-specs {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px;
margin: 0;
}
.template-detail-spec {
min-width: 0;
padding: 11px 10px;
border: 1px solid var(--lf-glass-soft, var(--border));
border-radius: var(--radius-sm);
background: var(--lf-glass-bg, var(--bg-panel-alt));
}
.template-detail-spec dt {
margin-bottom: 6px;
color: var(--lf-text-faint, var(--text-muted));
font-size: 11px;
}
.template-detail-spec dd {
margin: 0;
overflow: hidden;
color: var(--lf-text, var(--text-primary));
font-family: var(--font-mono);
font-size: 12px;
line-height: 1.3;
text-overflow: ellipsis;
white-space: nowrap;
}
.template-detail-spec:first-child {
grid-column: 1 / -1;
}
.template-detail-references {
display: grid;
gap: 8px;
}
.template-detail-references .reference-strip {
margin: 0;
}
.template-detail-actions {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
margin-top: auto;
padding-top: 16px;
border-top: 1px solid var(--lf-glass-soft, var(--border));
}
.template-detail-actions .btn {
min-width: 0;
}
.template-detail-delete {
grid-column: 1 / -1;
}
.reference-strip {
display: flex;
gap: 8px;
margin: 14px 0;
overflow-x: auto;
}
.reference-strip img {
width: 82px;
height: 82px;
object-fit: cover;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel-alt);
flex-shrink: 0;
cursor: pointer;
transition: border-color 0.1s, outline 0.1s;
}
.reference-strip img.active {
outline: 2px solid var(--accent);
outline-offset: 1px;
}
.slide-arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: rgba(0, 0, 0, 0.45);
color: #fff;
border: none;
border-radius: 50%;
width: 32px;
height: 32px;
font-size: 20px;
line-height: 1;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
transition: background 0.15s, opacity 0.15s;
}
.slide-arrow:hover:not(:disabled) {
background: rgba(0, 0, 0, 0.7);
}
.slide-arrow:disabled {
opacity: 0.25;
cursor: default;
}
.slide-arrow-prev { left: 8px; }
.slide-arrow-next { right: 8px; }
@keyframes template-pop {
from {
opacity: 0;
transform: translateY(0) scale(0.98);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes modal-layer-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes template-exit {
from {
opacity: 1;
transform: translateY(0) scale(1);
}
to {
opacity: 0;
transform: translateY(0) scale(0.98);
}
}
@keyframes modal-layer-out {
from {
opacity: 1;
transform: translateY(0);
}
to {
opacity: 0;
transform: translateY(5px);
}
}
@keyframes modal-backdrop-out {
from {
opacity: 1;
-webkit-backdrop-filter: blur(var(--modal-backdrop-blur));
backdrop-filter: blur(var(--modal-backdrop-blur));
}
to {
opacity: 0;
-webkit-backdrop-filter: blur(0px);
backdrop-filter: blur(0px);
}
}
/* 遮罩只模糊不压暗 → 让模糊从 0 慢慢增强到目标值,而非瞬间全糊(进展缓一点) */
@keyframes modal-backdrop-in {
from {
opacity: 0;
-webkit-backdrop-filter: blur(0px);
backdrop-filter: blur(0px);
}
to {
opacity: 1;
-webkit-backdrop-filter: blur(var(--modal-backdrop-blur));
backdrop-filter: blur(var(--modal-backdrop-blur));
}
}
@media (max-width: 900px) {
.navbar {
min-width: 0;
}
.navbar-brand {
min-width: 132px;
padding: 0 12px;
}
.navbar-actions {
overflow-x: auto;
}
.navbar-end {
padding: 0 10px;
gap: 6px;
}
.floating-panel {
width: min(360px, calc(100% - 16px)) !important;
height: min(520px, calc(100% - 16px)) !important;
}
.help-hero {
grid-template-columns: 1fr;
align-items: start;
}
.help-steps {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.help-grid.two,
.help-row {
grid-template-columns: 1fr;
}
.studio-panel,
.studio-properties {
--panel-width: 220px;
}
.studio-stage-scroll {
justify-content: flex-start;
align-items: flex-start;
padding: 72px 28px 28px;
}
.template-masonry {
column-count: 2;
}
.template-modal {
grid-template-columns: 1fr;
}
}
@media (max-width: 560px) {
.floating-panel {
left: 8px !important;
top: 8px !important;
}
.help-main {
padding: 14px;
}
.help-hero {
padding: 18px;
}
.help-steps {
grid-template-columns: 1fr;
}
.template-home-main {
padding: 14px;
}
.template-masonry {
column-count: 1;
}
.template-modal-backdrop {
padding: 14px;
}
.template-detail-panel {
gap: 14px;
padding: 18px;
}
.template-detail-specs {
grid-template-columns: 1fr;
}
.template-detail-actions {
grid-template-columns: 1fr;
}
.template-detail-delete {
grid-column: auto;
}
}
/* ===== RESIZABLE PANEL HANDLE ===== */
.panel-resize-handle {
position: absolute;
top: 0;
bottom: 0;
width: 5px;
background: transparent;
cursor: ew-resize;
z-index: 10;
transition: background 0.15s ease;
}
.panel-resize-handle:hover {
background: var(--accent);
}
body.resizing {
user-select: none;
}
body.resizing .side-panel,
body.resizing .studio-panel {
transition: none !important;
}
/* ── TemplateHome(模板库)LeleFlix 玻璃化 ──────────
复用全局 --lf-* 令牌(:root / dark 各一套),仅作用域此页。 */
.template-home {
background:
radial-gradient(90% 60% at 85% -8%, var(--lf-blob-1), transparent 60%),
radial-gradient(70% 55% at 0% 20%, var(--lf-blob-2), transparent 60%),
radial-gradient(80% 50% at 70% 110%, var(--lf-blob-3), transparent 60%),
linear-gradient(to bottom, var(--lf-bg-a) 0%, var(--lf-bg-b) 100%);
}
.template-home .navbar {
background: var(--lf-nav-bg);
-webkit-backdrop-filter: blur(20px) saturate(160%);
backdrop-filter: blur(20px) saturate(160%);
border-bottom: 1px solid var(--lf-nav-border);
box-shadow: none;
}
.template-home .navbar-brand { border-right-color: var(--lf-glass-soft); }
.template-home .navbar-brand-name,
.template-home .template-title { color: var(--lf-text); }
.template-home .navbar-mode-badge,
.template-home .nav-btn-label { color: var(--lf-text-dim); }
/* 卡片 = 图片本身:卡片本体透明,圆角靠 overflow:hidden 裁出,阴影只留一层大投影(无玻璃衬底) */
.template-home .template-masonry-card {
position: relative;
background: transparent;
border: none;
box-shadow: 0 16px 40px var(--lf-shadow-strong);
}
.template-home .template-masonry-card:hover {
transform: translateY(-3px);
box-shadow: 0 22px 54px var(--lf-shadow-strong);
}
/* 图片填满卡片(透明卡片外框用它承载圆角+阴影),自身不圆角不投影 */
.template-home .template-masonry-card .template-preview {
background: #fff;
}
/* 标题悬浮玻璃条:新的一层圆角玻璃,浮在图片下部。
只模糊、不压暗——去掉 saturate 提饱和,底色压到很低透明,让图保持原亮度 */
.template-home .template-masonry-card .template-masonry-info {
position: absolute;
left: 12px; right: 12px; bottom: 12px;
background: rgba(255, 255, 255, 0.32);
border: 1px solid var(--lf-glass-border);
-webkit-backdrop-filter: blur(22px);
backdrop-filter: blur(22px);
border-radius: var(--radius-md);
box-shadow:
0 10px 26px var(--lf-shadow),
inset 0 1px 0 var(--lf-glass-highlight);
padding: 10px 14px 8px;
}
:root[data-theme="dark"] .template-home .template-masonry-card .template-masonry-info {
background: rgba(10, 12, 18, 0.38);
}
.template-home .template-masonry-card .template-description {
color: var(--lf-text-dim);
max-height: 2.6em; line-height: 1.3;
overflow: hidden; text-overflow: ellipsis; -webkit-line-clamp: 2; display: -webkit-box;
-webkit-box-orient: vertical;
}
.template-home .template-masonry-card .template-meta span {
border-color: var(--lf-glass-soft);
color: var(--lf-text-dim);
background: var(--lf-input-bg);
}
/* 模态大图预览(独立圆角层,不悬浮标题条) */
.template-home .template-modal .template-preview {
background: #fff;
border-radius: var(--radius-lg);
box-shadow: inset 0 0 0 1px var(--lf-glass-soft), 0 12px 34px var(--lf-shadow-strong);
}
/* 横向 SVG 使用满高白色画布承托,完整图形居中显示且不裁切。 */
.template-home .template-modal .template-preview.large {
align-self: stretch;
aspect-ratio: 4 / 3;
min-height: 300px;
background: #fff;
}
.template-home .template-modal .template-preview.large img {
height: 100%;
max-height: none;
}
/* SVG 常带透明背景,缩略图统一以白底承托,保证预览可见。 */
.template-home .template-detail-references .reference-strip img {
background: #fff;
}
/* 空态与模态玻璃化 */
.template-home .template-empty {
background: var(--lf-glass-bg);
border: 1px solid var(--lf-glass-border);
-webkit-backdrop-filter: blur(16px) saturate(170%);
backdrop-filter: blur(16px) saturate(170%);
box-shadow: inset 0 1px 0 var(--lf-glass-highlight), 0 10px 30px var(--lf-shadow);
}
.template-home .template-empty-title { color: var(--lf-text-dim); }
.template-home .template-modal {
background: var(--lf-glass-bg);
-webkit-backdrop-filter: blur(24px) saturate(180%);
backdrop-filter: blur(24px) saturate(180%);
box-shadow:
0 24px 70px var(--lf-shadow-strong),
inset 0 1px 0 var(--lf-glass-highlight);
}
/* ── OrdersPage(生产订单,登录后可见)──────────────
根背景多层光斑(复用 --lf-* 令牌),双主题随 :root。 */
.orders-page {
min-height: 100vh; display: flex; flex-direction: column;
background:
radial-gradient(85% 60% at 10% -5%, var(--lf-blob-2), transparent 60%),
radial-gradient(75% 55% at 92% 15%, var(--lf-blob-1), transparent 60%),
radial-gradient(90% 50% at 60% 115%, var(--lf-blob-3), transparent 60%),
linear-gradient(to bottom, var(--lf-bg-a) 0%, var(--lf-bg-b) 100%);
}
.orders-main { flex: 1; padding: 24px 32px; max-width: 1080px; width: 100%; margin: 0 auto; box-sizing: border-box; }
.orders-toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.orders-count { color: var(--text-secondary); font-size: 14px; }
.orders-error { color: var(--danger); background: var(--danger-light); padding: 10px 14px; border-radius: var(--radius-sm); margin: 12px 0; }
.orders-table { width: 100%; border-collapse: collapse; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-sm); }
.orders-table th, .orders-table td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--border); font-size: 13px; color: var(--text-primary); }
.orders-table th { color: var(--text-secondary); font-weight: 600; background: var(--bg-panel-alt); }
.orders-table tr:last-child td { border-bottom: none; }
.orders-status { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; text-transform: capitalize; }
.status-success { background: var(--success-light); color: var(--success); }
.status-running { background: var(--accent-light); color: var(--accent); }
.status-queued { background: var(--bg-panel-alt); color: var(--text-secondary); }
.status-failed { background: var(--danger-light); color: var(--danger); }
.mono { font-family: var(--font-mono); font-size: 12px; }
.orders-preview { color: var(--accent); text-decoration: none; }
.orders-preview:hover { text-decoration: underline; }
.login-card { max-width: 400px; margin: 80px auto; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 28px 32px; box-shadow: var(--shadow-md); }
.login-title { margin: 0 0 8px; font-size: 20px; color: var(--text-primary); }
.orders-hint { color: var(--text-secondary); font-size: 13px; margin: 0 0 18px; line-height: 1.5; }
.orders-input { width: 100%; box-sizing: border-box; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); color: var(--text-primary); font-size: 14px; margin-bottom: 12px; }
.orders-input:focus { outline: none; border-color: var(--border-focus); }
/* ── OrdersPage 双栏:左订单队列 / 右详情 ────────── */
.orders-layout { display: flex; gap: 20px; align-items: flex-start; max-width: 1280px; }
.orders-queue { width: 300px; flex-shrink: 0; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; align-self: stretch; max-height: calc(100vh - 140px); display: flex; flex-direction: column; }
.orders-queue-head { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--border); font-weight: 600; color: var(--text-primary); }
.orders-queue-list { flex: 1; overflow: auto; padding: 8px; }
.orders-q-item { display: block; width: 100%; text-align: left; background: transparent; border: 1px solid transparent; border-radius: var(--radius-sm); padding: 10px 12px; margin-bottom: 6px; cursor: pointer; }
.orders-q-item:hover { background: var(--bg-panel-alt); }
.orders-q-item.active { border-color: var(--accent); background: var(--accent-light); }
.orders-q-item-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.orders-q-item-sub { color: var(--text-muted); font-size: 12px; margin-top: 4px; }
.orders-detail { flex: 1; min-width: 0; }
.orders-detail-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 16px; }
.orders-detail-title { margin: 0 0 6px; font-size: 20px; color: var(--text-primary); }
.orders-detail-meta { color: var(--text-secondary); font-size: 12px; margin-left: 12px; }
.orders-detail-actions { display: flex; align-items: center; gap: 8px; }
.orders-preview-block { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 16px; }
.orders-preview-label { color: var(--text-secondary); font-size: 13px; font-weight: 600; margin-bottom: 12px; }
.orders-overall-img { max-width: 100%; max-height: 60vh; display: block; border-radius: var(--radius-sm); border: 1px solid var(--border); }
.layer-canvas { position: relative; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius-sm); background-size: cover; }
.layer-el { position: absolute; object-fit: contain; transform-origin: center; pointer-events: none; }
.orders-layer-list { display: flex; flex-wrap: wrap; gap: 12px; }
.orders-layer-item { width: 220px; }
.orders-layer-thumb { box-shadow: var(--shadow-sm); }
.orders-layer-name { color: var(--text-secondary); font-size: 12px; margin-top: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-btn-label.active { color: var(--accent); font-weight: 600; }
/* ── OrdersPage 已登录双栏玻璃化(复用 --lf-* 令牌)── */
.orders-page .navbar {
background: var(--lf-nav-bg);
-webkit-backdrop-filter: blur(20px) saturate(160%);
backdrop-filter: blur(20px) saturate(160%);
border-bottom: 1px solid var(--lf-nav-border);
box-shadow: none;
}
.orders-page .navbar-brand { border-right-color: var(--lf-glass-soft); }
.orders-page .navbar-brand-name,
.orders-page .orders-detail-title { color: var(--lf-text); }
.orders-page .navbar-mode-badge,
.orders-page .nav-btn-label,
.orders-page .orders-detail-meta,
.orders-page .orders-count,
.orders-page .orders-layer-name,
.orders-page .orders-preview-label { color: var(--lf-text-dim); }
/* 左侧订单队列玻璃 */
.orders-page .orders-queue {
background: var(--lf-glass-bg);
border: 1px solid var(--lf-glass-border);
-webkit-backdrop-filter: blur(18px) saturate(170%);
backdrop-filter: blur(18px) saturate(170%);
box-shadow: inset 0 1px 0 var(--lf-glass-highlight), inset 0 -1px 0 var(--lf-glass-shade), 0 6px 20px var(--lf-shadow);
}
.orders-page .orders-queue-head { border-bottom-color: var(--lf-glass-soft); color: var(--lf-text); }
.orders-page .orders-q-item:hover { background: var(--lf-accent-hover); }
.orders-page .orders-q-item.active { border-color: var(--lf-accent-border); background: var(--lf-accent-soft); }
.orders-page .orders-q-item-sub { color: var(--lf-text-faint); }
/* 右侧详情:预览卡片 / 表格玻璃化 */
.orders-page .orders-preview-block,
.orders-page .orders-table {
background: var(--lf-glass-bg);
border: 1px solid var(--lf-glass-border);
-webkit-backdrop-filter: blur(18px) saturate(170%);
backdrop-filter: blur(18px) saturate(170%);
box-shadow: inset 0 1px 0 var(--lf-glass-highlight), 0 6px 20px var(--lf-shadow);
}
.orders-page .orders-table th { background: var(--lf-input-bg); color: var(--lf-text-dim); }
.orders-page .orders-table td { color: var(--lf-text); }
.orders-page .orders-table tr:last-child td { border-bottom: none; }
/* 状态 pill 保留红/绿/蓝状态底色,只加玻璃内高光与描边 */
.orders-page .orders-status {
box-shadow: inset 0 1px 0 var(--lf-glass-highlight), 0 0 0 1px var(--lf-glass-soft);
}
.orders-page .status-success { color: var(--lf-text); }
.orders-page .status-running { color: var(--lf-accent); }
.orders-page .status-failed { color: var(--lf-text); }
.orders-page .status-queued { color: var(--lf-text-dim); }
/* ── CanvasStudio(画布)/ Wordcloud 壳玻璃化 ──────
只玻璃化面板/浮动窗/底部 pill;保留 workspace 棋盘格与透明底标识。 */
.side-panel,
.floating-panel {
background: var(--lf-glass-bg);
border-color: var(--lf-glass-border);
-webkit-backdrop-filter: blur(18px) saturate(170%);
backdrop-filter: blur(18px) saturate(170%);
box-shadow:
inset 0 1px 0 var(--lf-glass-highlight),
inset 0 -1px 0 var(--lf-glass-shade),
0 8px 26px var(--lf-shadow);
}
.floating-panel {
box-shadow:
0 22px 60px var(--lf-shadow-strong),
inset 0 1px 0 var(--lf-glass-highlight);
}
.studio-bottombar .canvas-size-pill,
.zoom-controls {
background: var(--lf-glass-bg);
border: 1px solid var(--lf-glass-border);
-webkit-backdrop-filter: blur(16px) saturate(170%);
backdrop-filter: blur(16px) saturate(170%);
color: var(--lf-text-dim);
box-shadow: inset 0 1px 0 var(--lf-glass-highlight), 0 4px 14px var(--lf-shadow);
}
.studio-bottombar .zoom-controls span { color: var(--lf-text); }
/* 词云工作台:舞台容器玻璃背景(网格底下透光斑) */
.canvas-area {
background:
radial-gradient(80% 55% at 85% -5%, var(--lf-blob-1), transparent 60%),
radial-gradient(70% 55% at 0% 25%, var(--lf-blob-2), transparent 60%),
radial-gradient(85% 50% at 75% 115%, var(--lf-blob-3), transparent 60%),
linear-gradient(to bottom, var(--lf-bg-a) 0%, var(--lf-bg-b) 100%);
}
/* ═══════════════════════════════════════════════════════════
FindPage — LeleFlix 设计语言(主题驱动,浅色/深色两套)
液体玻璃:blur+saturate+内高光+光折射扫过。
只影响查找页(.find-page 作用域),其余页面保持原主题。
═══════════════════════════════════════════════════════════ */
/* ── 设计令牌:浅色(默认)────────────────────────── */
:root {
--lf-bg-a: #eef3f9;
--lf-bg-b: #e6ebf4;
--lf-nav-bg: rgba(255, 255, 255, 0.62);
--lf-nav-border: rgba(17, 24, 39, 0.06);
--lf-text: #171a1f;
--lf-text-dim: rgba(30, 41, 59, 0.72);
--lf-text-faint: rgba(30, 41, 59, 0.5);
--lf-glass-bg: rgba(255, 255, 255, 0.62);
--lf-glass-border: rgba(255, 255, 255, 0.8);
--lf-glass-soft: rgba(17, 24, 39, 0.09);
--lf-glass-highlight: rgba(255, 255, 255, 0.9);
--lf-glass-shade: rgba(17, 24, 39, 0.08);
--lf-shadow: rgba(17, 24, 39, 0.15);
--lf-shadow-strong: rgba(17, 24, 39, 0.24);
--lf-input-bg: rgba(255, 255, 255, 0.7);
--lf-opt-bg: #ffffff;
--lf-accent: #2563eb;
--lf-accent-soft: rgba(59, 130, 246, 0.16);
--lf-accent-border: rgba(59, 130, 246, 0.5);
--lf-accent-hover: rgba(59, 130, 246, 0.24);
--lf-sweep: rgba(255, 255, 255, 0.65);
--lf-sweep-soft: rgba(255, 255, 255, 0.5);
--lf-frame-bg: #ffffff;
--lf-frame-shadow: rgba(17, 24, 39, 0.22);
--lf-err-bg: rgba(254, 226, 226, 0.75);
--lf-err-border: rgba(220, 38, 38, 0.28);
--lf-err-text: #b91c1c;
--lf-blob-1: rgba(96, 165, 250, 0.32);
--lf-blob-2: rgba(131, 120, 255, 0.22);
--lf-blob-3: rgba(16, 185, 129, 0.16);
}
/* ── 设计令牌(深色)─────────────────────────────── */
:root[data-theme="dark"] {
--lf-bg-a: #141824;
--lf-bg-b: #07080c;
--lf-nav-bg: rgba(8, 10, 15, 0.55);
--lf-nav-border: rgba(255, 255, 255, 0.06);
--lf-text: #f5f5f7;
--lf-text-dim: rgba(235, 235, 245, 0.62);
--lf-text-faint: rgba(235, 235, 245, 0.5);
--lf-glass-bg: rgba(16, 18, 24, 0.55);
--lf-glass-border: rgba(255, 255, 255, 0.10);
--lf-glass-soft: rgba(255, 255, 255, 0.06);
--lf-glass-highlight: rgba(255, 255, 255, 0.13);
--lf-glass-shade: rgba(0, 0, 0, 0.25);
--lf-shadow: rgba(0, 0, 0, 0.38);
--lf-shadow-strong: rgba(0, 0, 0, 0.5);
--lf-input-bg: rgba(8, 10, 15, 0.45);
--lf-opt-bg: #131621;
--lf-accent: #93c5fd;
--lf-accent-soft: rgba(96, 165, 250, 0.2);
--lf-accent-border: rgba(147, 197, 253, 0.55);
--lf-accent-hover: rgba(96, 165, 250, 0.3);
--lf-sweep: rgba(255, 255, 255, 0.10);
--lf-sweep-soft: rgba(255, 255, 255, 0.05);
--lf-frame-bg: #ffffff; /* 预览图底恒定白,保证名字可读 */
--lf-frame-shadow: rgba(0, 0, 0, 0.5);
--lf-err-bg: rgba(127, 29, 29, 0.5);
--lf-err-border: rgba(251, 113, 133, 0.25);
--lf-err-text: #fda4af;
--lf-blob-1: rgba(96, 165, 250, 0.34);
--lf-blob-2: rgba(131, 120, 255, 0.28);
--lf-blob-3: rgba(20, 201, 164, 0.2);
}
/* ── 页面基底(两套背景) ─────────────────────────── */
.find-page {
background:
radial-gradient(120% 80% at 50% -10%, var(--lf-bg-a) 0%, transparent 55%),
linear-gradient(to bottom, var(--lf-bg-b) 0%, var(--lf-bg-b) 100%);
}
.find-page .navbar {
background: var(--lf-nav-bg);
-webkit-backdrop-filter: blur(20px) saturate(160%);
backdrop-filter: blur(20px) saturate(160%);
border-bottom: 1px solid var(--lf-nav-border);
}
.find-page .navbar-brand-name { color: var(--lf-text); }
.find-page .nav-btn-label { color: var(--lf-text-dim); }
.find-page .find-page-bg .blob-1 { background: radial-gradient(circle, var(--lf-blob-1), transparent 70%); }
.find-page .find-page-bg .blob-2 { background: radial-gradient(circle, var(--lf-blob-2), transparent 70%); }
.find-page .find-page-bg .blob-3 { background: radial-gradient(circle, var(--lf-blob-3), transparent 70%); }
/* 液体玻璃通用(LeleFlix 配方) */
.find-page .glass,
.find-page .find-footer {
background: var(--lf-glass-bg);
border: 1px solid var(--lf-glass-border);
-webkit-backdrop-filter: blur(20px) saturate(180%);
backdrop-filter: blur(20px) saturate(180%);
box-shadow:
inset 0 1px 0 var(--lf-glass-highlight),
inset 0 -1px 0 var(--lf-glass-shade);
}
/* 词云视口:透明舞台 —— 不做大色板/遮罩,画布干净浮起,
玻璃效果只给按钮。
固定铺满视口可交互区(顶部避让玻璃工具条,底部避让结果 pill),
必须有真实宽高,ResizeObserver 才拿得到尺寸、画布才能适配进来 */
.find-page .find-stage {
position: fixed; left: 16px; right: 16px;
top: calc(var(--nav-height) + 100px);
bottom: 78px;
border-radius: 18px;
background: transparent;
touch-action: none;
}
.find-stage.panning { cursor: grabbing; }
.find-stage:not(.panning) { cursor: grab; }
.find-viewport { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
/* 离散跳转(放大定位 / 查看整图)时平滑过渡;拖动 / 捏合过程视图要即时跟手 → 无过渡 */
.find-viewport { transition: transform 0s; }
.find-viewport.animating { transition: transform 360ms cubic-bezier(0.22, 1, 0.36, 1); }
/* 预览图背景恒定白色,深色模式下名字依然清晰;
只留一道柔和投影让白色画布从页面浮起,不做厚重毛边/遮罩 */
.find-page .find-preview-frame {
position: relative; flex-shrink: 0;
background: var(--lf-frame-bg);
border-radius: 4px;
box-shadow: 0 14px 40px var(--lf-frame-shadow);
}
.find-preview-img { display: block; width: 100%; height: 100%; object-fit: contain; user-select: none; -webkit-user-drag: none; pointer-events: none; }
/* 悬浮玻璃工具条:LeleFlix 控制条风格(胶囊 + 光扫) */
.find-page .find-glassbar {
position: fixed; z-index: 30;
top: calc(var(--nav-height) + 14px);
left: 50%; transform: translateX(-50%);
display: flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: center;
padding: 12px 16px; border-radius: 24px;
max-width: calc(100vw - 24px);
background: var(--lf-glass-bg);
border: 1px solid var(--lf-glass-border);
-webkit-backdrop-filter: blur(22px) saturate(180%);
backdrop-filter: blur(22px) saturate(180%);
box-shadow:
inset 0 1px 0 var(--lf-glass-highlight),
inset 0 -1px 0 var(--lf-glass-shade);
overflow: hidden;
}
/* 光折射扫过(工具条静止时缓慢扫过,最像 LeleFlix 控制栏) */
.find-page .find-glassbar::before {
content: '';
position: absolute;
top: 0; left: -100%;
width: 45%; height: 100%;
background: linear-gradient(90deg, rgba(255,255,255,0) 0%, var(--lf-sweep-soft) 50%, rgba(255,255,255,0) 100%);
pointer-events: none;
animation: findGlassSweep 5.5s ease-in-out 1.2s infinite;
}
@keyframes findGlassSweep {
0% { left: -100%; }
55%, 100% { left: 220%; }
}
.find-page .find-glassbar .glass-field { display: flex; flex-direction: column; gap: 3px; }
.find-page .find-glassbar .glass-label { font-size: 11px; color: var(--lf-text-faint); padding-left: 4px; letter-spacing: 0.04em; }
.find-page .find-glassbar select,
.find-page .find-glassbar input[type="text"] {
border: 1px solid var(--lf-glass-soft); border-radius: 14px;
background: var(--lf-input-bg); color: var(--lf-text); font-size: 13px;
padding: 10px 12px; outline: none; font-family: var(--font-main);
-webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
transition: border-color var(--transition), box-shadow var(--transition);
}
.find-page .find-glassbar select { width: 230px; min-width: 150px; cursor: pointer; }
.find-page .find-glassbar input[type="text"] { width: 220px; }
.find-page .find-glassbar select:focus,
.find-page .find-glassbar input[type="text"]:focus {
border-color: var(--lf-accent-border);
box-shadow: 0 0 0 3px var(--lf-accent-soft);
}
.find-page .find-glassbar select option { background: var(--lf-opt-bg); color: var(--lf-text); }
.find-page .find-glassbar select:disabled { opacity: 0.5; }
/* 圆形液体玻璃媒体按钮(播放/暂停式) */
.find-page .find-actions { display: flex; align-items: center; gap: 10px; }
.find-page .find-btn {
width: 42px; height: 42px; padding: 0;
border-radius: 50%; cursor: pointer;
display: inline-flex; align-items: center; justify-content: center;
border: 1px solid var(--lf-glass-border);
background: var(--lf-glass-bg);
color: var(--lf-text); font-size: 13px; font-family: var(--font-main);
-webkit-backdrop-filter: blur(20px) saturate(180%);
backdrop-filter: blur(20px) saturate(180%);
box-shadow:
inset 0 1px 0 var(--lf-glass-highlight),
inset 0 -1px 0 var(--lf-glass-shade);
position: relative; overflow: hidden;
transition: transform var(--transition), background var(--transition), border-color var(--transition), box-shadow var(--transition);
}
/* 光折射扫过动画 */
.find-page .find-btn::before {
content: '';
position: absolute; top: 0; left: -100%;
width: 60%; height: 100%;
background: linear-gradient(90deg, rgba(255,255,255,0) 0%, var(--lf-sweep) 50%, rgba(255,255,255,0) 100%);
pointer-events: none;
}
.find-page .find-btn:hover:not(:disabled)::before { animation: findGlassSweep 0.9s ease-out forwards; }
/* 内发光层 */
.find-page .find-btn::after {
content: '';
position: absolute; inset: 0; border-radius: 50%;
background: linear-gradient(135deg, var(--lf-glass-highlight) 0%, rgba(255,255,255,0) 50%, var(--lf-glass-soft) 100%);
pointer-events: none;
}
.find-page .find-btn svg { position: relative; z-index: 2; flex-shrink: 0; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3)); }
.find-page .find-btn:hover:not(:disabled) {
background: var(--lf-accent-soft);
border-color: var(--lf-accent-border);
transform: scale(1.1);
box-shadow:
inset 0 1px 0 var(--lf-glass-highlight),
0 0 20px var(--lf-accent-soft);
}
.find-page .find-btn:active:not(:disabled) { transform: scale(0.96); }
.find-page .find-btn:disabled { opacity: 0.4; cursor: not-allowed; }
/* 查找 = 加大号主媒体按钮 */
.find-page .find-btn.find-btn-primary {
width: 48px; height: 48px;
background: var(--lf-accent-soft);
border: 1px solid var(--lf-accent-border);
color: var(--lf-accent);
}
.find-page .find-btn.find-btn-primary:hover:not(:disabled) {
background: var(--lf-accent-hover);
border-color: var(--lf-accent);
box-shadow:
0 14px 40px var(--lf-shadow-strong),
inset 0 1px 0 var(--lf-glass-highlight),
0 0 26px var(--lf-accent-soft);
}
.find-page .find-btn.find-btn-primary svg { filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.25)); }
/* 精确 / 包含 切换(玻璃胶囊) */
.find-page .mode-toggle {
display: inline-flex; gap: 2px;
border: 1px solid var(--lf-glass-soft); border-radius: 14px;
padding: 3px;
background: var(--lf-input-bg);
-webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.find-page .mode-toggle button {
flex: 1; padding: 8px 12px; border: none; border-radius: 11px;
background: transparent; color: var(--lf-text-dim);
font-size: 12px; font-family: var(--font-main); cursor: pointer;
transition: background var(--transition), color var(--transition), box-shadow var(--transition);
}
.find-page .mode-toggle button.active {
background: var(--lf-glass-bg);
color: var(--lf-text); font-weight: 600;
box-shadow: inset 0 1px 0 var(--lf-glass-highlight), 0 2px 8px var(--lf-shadow-strong);
}
/* 底部结果统计(玻璃 pill) */
.find-page .find-footer {
position: fixed; z-index: 30; bottom: 14px; left: 50%; transform: translateX(-50%);
color: var(--lf-text-dim); font-size: 13px;
padding: 8px 18px; border-radius: 999px;
white-space: nowrap; max-width: calc(100vw - 160px); overflow: hidden; text-overflow: ellipsis;
}
.find-page .find-footer strong { color: var(--lf-text); font-weight: 600; }
/* 右下角「查看整图 / 重新放大」:大玻璃胶囊 + 光扫 */
.find-page .find-corner-btn {
position: fixed; z-index: 30; right: 20px; bottom: 20px;
height: 46px; padding: 0 20px; border-radius: 23px; cursor: pointer;
border: 1px solid var(--lf-glass-border);
background: var(--lf-glass-bg); color: var(--lf-text);
font-size: 13px; font-family: var(--font-main); font-weight: 600;
display: inline-flex; align-items: center; gap: 8px;
-webkit-backdrop-filter: blur(22px) saturate(180%);
backdrop-filter: blur(22px) saturate(180%);
box-shadow:
inset 0 1px 0 var(--lf-glass-highlight),
inset 0 -1px 0 var(--lf-glass-shade);
overflow: hidden;
transition: transform var(--transition), background var(--transition), border-color var(--transition), box-shadow var(--transition);
}
.find-page .find-corner-btn::before {
content: '';
position: absolute; top: 0; left: -100%;
width: 50%; height: 100%;
background: linear-gradient(90deg, rgba(255,255,255,0) 0%, var(--lf-sweep) 50%, rgba(255,255,255,0) 100%);
pointer-events: none;
}
.find-page .find-corner-btn:hover:not(:disabled)::before { animation: findGlassSweep 1s ease-out forwards; }
.find-page .find-corner-btn svg { flex-shrink: 0; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.3)); }
.find-page .find-corner-btn:hover:not(:disabled) {
background: var(--lf-accent-soft);
border-color: var(--lf-accent-border);
transform: translateY(-2px);
box-shadow:
inset 0 1px 0 var(--lf-glass-highlight),
0 0 22px var(--lf-accent-soft);
}
.find-page .find-corner-btn:active:not(:disabled) { transform: translateY(0) scale(0.98); }
.find-page .find-corner-btn:disabled { opacity: 0.4; cursor: not-allowed; }
/* 缩放提示 */
.find-page .find-scale-tag {
position: fixed; z-index: 29; right: 22px; bottom: 78px;
font-size: 11px; color: var(--lf-text-faint); padding: 4px 12px; border-radius: 999px;
background: var(--lf-glass-bg); border: 1px solid var(--lf-glass-border);
-webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
user-select: none; pointer-events: none;
}
/* 悬浮错误提示(玻璃红条) */
.find-page .find-error-fixed {
position: fixed; z-index: 40;
top: calc(var(--nav-height) + 92px); left: 50%; transform: translateX(-50%);
color: var(--lf-err-text); background: var(--lf-err-bg);
border: 1px solid var(--lf-err-border);
padding: 8px 14px; border-radius: 12px; font-size: 13px;
-webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
white-space: nowrap; max-width: calc(100vw - 24px); overflow: hidden; text-overflow: ellipsis;
}
/* 登录卡片玻璃化 */
.orders-page .login-card,
.find-page .login-card {
background: var(--lf-glass-bg);
border: 1px solid var(--lf-glass-border);
-webkit-backdrop-filter: blur(22px) saturate(180%);
backdrop-filter: blur(22px) saturate(180%);
box-shadow: inset 0 1px 0 var(--lf-glass-highlight);
}
.orders-page .login-title,
.find-page .login-title { color: var(--lf-text); }
.orders-page .orders-hint,
.find-page .orders-hint { color: var(--lf-text-dim); }
.orders-page .orders-input,
.find-page .orders-input {
background: var(--lf-input-bg); border-color: var(--lf-glass-soft);
color: var(--lf-text);
}
.orders-page .orders-input:focus,
.find-page .orders-input:focus { border-color: var(--lf-accent-border); }
.find-page .orders-input:focus { border-color: var(--lf-accent-border); }
/* ===== 产品档案归档弹窗 ===== */
.product-archive-backdrop {
position: fixed;
inset: 0;
z-index: 110;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
background: rgba(255,255,255,var(--modal-backdrop-opacity));
backdrop-filter: blur(var(--modal-backdrop-blur));
}
:root[data-theme="dark"] .product-archive-backdrop {
background: rgba(10,12,18,calc(var(--modal-backdrop-opacity) * 2.4));
}
.product-archive-dialog {
width: min(920px, 100%);
max-height: calc(100vh - 48px);
display: grid;
grid-template-rows: auto minmax(0, 1fr);
overflow: hidden;
border: 1px solid var(--border);
border-radius: var(--radius-lg);
background: var(--bg-panel);
box-shadow: var(--shadow-lg);
animation: template-pop var(--modal-open-duration) var(--modal-open-easing) var(--modal-open-delay) backwards;
}
.product-archive-head {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 18px;
border-bottom: 1px solid var(--border);
}
.product-archive-eyebrow {
color: var(--text-muted);
font-size: 11px;
font-weight: 700;
letter-spacing: 0.06em;
display: inline-flex;
align-items: center;
gap: 5px;
}
.product-archive-title {
margin: 0;
color: var(--text-primary);
font-size: 15px;
font-weight: 600;
}
.product-archive-close {
margin-left: auto;
}
.product-archive-grid {
display: grid;
grid-template-columns: minmax(0, 0.9fr) minmax(300px, 1.1fr);
gap: 14px;
padding: 16px;
overflow-y: auto;
}
.product-archive-preview-panel,
.product-archive-form-panel {
min-width: 0;
min-height: 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.product-archive-preview-frame {
width: 100%;
aspect-ratio: 4 / 3;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel-alt);
overflow: hidden;
}
.product-archive-preview {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
.product-archive-preview-placeholder {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
font-family: var(--font-main);
font-size: 13px;
}
.product-archive-preview-note,
.product-archive-source-note {
margin: 0;
color: var(--text-secondary);
font-size: 12px;
line-height: 1.5;
overflow-wrap: anywhere;
}
.product-archive-source-note {
padding: 8px 10px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel-alt);
}
.product-archive-form {
display: flex;
flex-direction: column;
gap: 12px;
min-height: 0;
overflow-y: auto;
}
.product-archive-loading,
.product-archive-empty,
.product-archive-state {
color: var(--text-muted);
font-size: 13px;
}
.product-archive-error {
padding: 10px 12px;
border: 1px solid var(--danger);
border-radius: var(--radius-sm);
background: var(--danger-light);
color: var(--danger);
font-size: 13px;
overflow-wrap: anywhere;
}
.product-archive-empty-copy {
margin: 0;
padding: 9px 11px;
border: 1px solid var(--warn);
border-radius: var(--radius-sm);
background: var(--bg-panel-alt);
color: var(--warn);
font-size: 12px;
line-height: 1.5;
overflow-wrap: anywhere;
}
.product-archive-search-row {
display: grid;
gap: 5px;
color: var(--text-secondary);
font-size: 12px;
}
.product-archive-search,
.product-archive-input {
width: 100%;
padding: 7px 9px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel-alt);
color: var(--text-primary);
font-family: var(--font-main);
font-size: 13px;
}
.product-archive-search:focus,
.product-archive-input:focus {
outline: none;
border-color: var(--border-focus);
}
.product-archive-list {
display: flex;
flex-direction: column;
gap: 6px;
max-height: 150px;
overflow-y: auto;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel);
}
.product-archive-option {
width: 100%;
display: grid;
grid-template-columns: minmax(0, 1fr) auto auto;
align-items: center;
gap: 8px;
padding: 7px 9px;
border: 0;
border-radius: var(--radius-sm);
background: transparent;
color: var(--text-primary);
text-align: left;
cursor: pointer;
}
.product-archive-option.selected {
background: var(--accent-light);
box-shadow: inset 0 0 0 1px var(--border-focus);
}
.product-archive-option-name {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-family: var(--font-main);
font-size: 13px;
font-weight: 600;
}
.product-archive-option-sku {
color: var(--text-muted);
font-family: var(--font-mono);
font-size: 11px;
}
.product-archive-option-status {
display: inline-block;
padding: 2px 8px;
border-radius: 999px;
font-size: 11px;
line-height: 1.4;
white-space: nowrap;
}
.product-archive-create {
display: grid;
gap: 9px;
padding: 11px 12px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel-alt);
}
.product-archive-create-title {
color: var(--text-secondary);
font-size: 12px;
font-weight: 700;
}
.product-archive-create label {
display: grid;
gap: 4px;
color: var(--text-muted);
font-size: 11px;
}
.product-archive-meta-row {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px;
}
.product-archive-create-actions {
display: flex;
align-items: center;
gap: 8px;
}
.product-archive-create-note {
color: var(--text-muted);
font-size: 11px;
}
.product-archive-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
padding-top: 2px;
}
.product-archive-actions .btn-primary:disabled {
opacity: 0.55;
cursor: not-allowed;
}
.product-status-archived {
color: var(--success);
background: var(--success-light);
}
.product-status-empty {
color: var(--text-muted);
background: var(--bg-panel-alt);
}
.product-status-pending-cleanup {
color: var(--warn);
background: var(--accent-light);
}
.product-archive-toast {
position: fixed;
left: 50%;
bottom: 26px;
transform: translateX(-50%);
z-index: 120;
display: flex;
align-items: center;
gap: 8px;
max-width: min(720px, calc(100vw - 28px));
padding: 9px 14px;
border: 1px solid var(--success);
border-radius: var(--radius-sm);
background: var(--success-light);
color: var(--success);
font-size: 13px;
box-shadow: var(--shadow-md);
}
.product-archive-toast-icon {
display: inline-flex;
flex: 0 0 auto;
}
.product-archive-toast span:last-child {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@media (max-width: 720px) {
.product-archive-grid {
grid-template-columns: minmax(0, 1fr);
}
.product-archive-preview-panel {
max-height: 300px;
}
.product-archive-option {
grid-template-columns: minmax(0, 1fr) auto;
}
.product-archive-option-sku {
display: none;
}
.product-archive-meta-row {
grid-template-columns: minmax(0, 1fr);
}
}
/* ===== 产品档案管理页 ===== */
.product-archive-search-block {
display: flex;
gap: 6px;
padding: 10px 12px;
border-bottom: 1px solid var(--border);
}
.product-archive-search-block .orders-input {
margin-bottom: 0;
}
.product-archive-row {
width: 100%;
display: grid;
grid-template-columns: 64px minmax(0, 1fr) auto;
gap: 10px;
align-items: center;
padding: 9px 10px;
border: 1px solid transparent;
border-radius: var(--radius-sm);
background: transparent;
color: var(--text-primary);
text-align: left;
cursor: pointer;
}
.product-archive-row:hover,
.product-archive-row.active {
background: var(--accent-light);
border-color: var(--accent);
}
.product-archive-thumb {
width: 64px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel-alt);
}
.product-archive-thumb img {
width: 100%;
height: 100%;
object-fit: contain;
}
.product-archive-image-empty {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
font-size: 11px;
text-align: center;
}
.product-archive-thumb-empty,
.product-archive-cover-empty {
padding: 4px;
color: var(--text-muted);
font-size: 11px;
text-align: center;
}
.product-archive-row-body {
min-width: 0;
display: grid;
gap: 4px;
}
.product-archive-row-name,
.product-archive-row-meta {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.product-archive-row-name {
font-family: var(--font-main);
font-size: 13px;
font-weight: 600;
}
.product-archive-row-meta {
color: var(--text-secondary);
font-size: 11px;
}
.product-archive-warning {
margin-bottom: 12px;
}
.product-archive-detail {
display: grid;
grid-template-columns: minmax(260px, 0.75fr) minmax(0, 1fr);
gap: 16px;
}
.product-archive-cover {
min-height: 220px;
overflow: hidden;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg-panel-alt);
}
.product-archive-cover img {
width: 100%;
height: 100%;
object-fit: contain;
}
.product-archive-cover-empty {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.product-archive-detail-body {
min-width: 0;
display: grid;
gap: 14px;
}
.product-archive-metrics {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 10px;
}
.product-archive-metrics > div {
padding: 10px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel-alt);
}
.product-archive-metric-label {
display: block;
margin-bottom: 4px;
color: var(--text-secondary);
font-size: 11px;
}
.product-archive-metrics strong {
color: var(--text-primary);
font-size: 15px;
}
.product-archive-timeline {
padding: 12px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-panel-alt);
}
.product-archive-timeline h3 {
margin: 0 0 10px;
color: var(--text-primary);
font-size: 13px;
}
.product-archive-timeline p {
margin: 0;
color: var(--text-muted);
font-size: 12px;
}
.product-archive-version {
padding: 8px 0;
border-bottom: 1px solid var(--border);
}
.product-archive-version:last-child {
border-bottom: 0;
}
.product-archive-version > div {
display: flex;
justify-content: space-between;
gap: 10px;
color: var(--text-secondary);
font-size: 12px;
}
.product-archive-system {
padding: 10px;
border: 1px dashed var(--border);
border-radius: var(--radius-sm);
}
.product-archive-system summary {
color: var(--text-secondary);
cursor: pointer;
font-size: 12px;
}
.product-archive-system-row {
display: flex;
align-items: center;
gap: 8px;
margin: 10px 0;
color: var(--text-secondary);
font-size: 12px;
}
.product-archive-system-row code {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--text-primary);
font-family: var(--font-mono);
}
@media (max-width: 900px) {
.product-archive-detail {
grid-template-columns: minmax(0, 1fr);
}
.product-archive-row {
grid-template-columns: 48px minmax(0, 1fr);
}
.product-archive-row .product-status {
grid-column: 2;
justify-self: start;
}
}