/* Modern Apple-like Tech Aesthetic Variables */ :root { --bg-base: #fbfbfd; --text-primary: #1d1d1f; --text-secondary: #86868b; --accent-blue: #0071e3; --accent-green: #34c759; --accent-red: #ff3b30; --glass-bg: rgba(255, 255, 255, 0.7); --glass-border: rgba(255, 255, 255, 0.5); --glass-shadow: 0 8px 32px rgba(0, 0, 0, 0.04); --transition-smooth: all 0.5s cubic-bezier(0.25, 1, 0.5, 1); } /* Dark Mode Query Support */ @media (prefers-color-scheme: dark) { :root { --bg-base: #000000; --text-primary: #f5f5f7; --text-secondary: #86868b; --accent-blue: #2997ff; --glass-bg: rgba(28, 28, 30, 0.6); --glass-border: rgba(255, 255, 255, 0.08); --glass-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); } body { background: radial-gradient(circle at top right, #1d1d27, #000000) !important; } } * { margin: 0; padding: 0; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', sans-serif; -webkit-font-smoothing: antialiased; } body { background: var(--bg-base); color: var(--text-primary); min-height: 100vh; overflow-x: hidden; /* Soft mesh gradient background for premium feel */ background: radial-gradient(circle at top right, #e2eafc, #fbfbfd 60%); } .app-container { display: flex; height: 100vh; } /* Sidebar */ .sidebar { width: 240px; background: var(--glass-bg); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-right: 1px solid var(--glass-border); padding: 2rem 0; display: flex; flex-direction: column; z-index: 10; } .logo { display: flex; align-items: center; gap: 12px; padding: 0 24px; font-weight: 600; font-size: 1.1rem; letter-spacing: -0.5px; margin-bottom: 2.5rem; color: var(--text-primary); } .nav-menu { display: flex; flex-direction: column; gap: 4px; padding: 0 12px; } .nav-item { text-decoration: none; color: var(--text-secondary); padding: 10px 16px; border-radius: 8px; font-size: 0.95rem; font-weight: 500; transition: var(--transition-smooth); } .nav-item:hover { background: rgba(134, 134, 139, 0.1); color: var(--text-primary); transform: translateX(4px); } .nav-item.active { background: var(--text-primary); color: var(--bg-base); } /* Main Content */ .main-content { flex: 1; overflow-y: auto; padding: 2rem 3rem; } .top-nav { display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem; } /* Page title row: title + cutoff badge inline */ .page-title-row { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; } .page-title-row h1 { margin: 0; } /* Data cutoff date badge */ .data-cutoff-badge { font-size: 0.78rem; font-weight: 500; color: var(--text-secondary); background: rgba(0, 113, 227, 0.06); border: 1px solid rgba(0, 113, 227, 0.12); border-radius: 20px; padding: 4px 14px; white-space: nowrap; line-height: 1.4; } /* ============== Info Icon Tooltip ============== */ .info-icon { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; font-size: 0.72rem; font-style: normal; color: var(--text-secondary); background: rgba(134, 134, 139, 0.08); border: 1px solid rgba(134, 134, 139, 0.15); border-radius: 50%; cursor: help; position: relative; vertical-align: middle; margin-left: 4px; transition: all 0.2s; } .info-icon:hover { color: var(--accent-blue); background: rgba(0, 113, 227, 0.08); border-color: rgba(0, 113, 227, 0.3); } /* Smaller variant for table headers */ .info-icon-sm { width: 15px; height: 15px; font-size: 0.65rem; } /* Tooltip popup */ .info-icon::after { content: attr(data-tooltip); position: absolute; bottom: 130%; left: 50%; transform: translateX(-50%); background: rgba(28, 28, 30, 0.92); color: #f5f5f7; font-size: 0.75rem; font-weight: 400; line-height: 1.5; padding: 8px 12px; border-radius: 10px; width: max-content; max-width: 320px; white-space: normal; pointer-events: none; opacity: 0; visibility: hidden; transition: opacity 0.2s, visibility 0.2s; z-index: 100; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); backdrop-filter: blur(12px); } /* Tooltip arrow */ .info-icon::before { content: ''; position: absolute; bottom: 120%; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: rgba(28, 28, 30, 0.92); pointer-events: none; opacity: 0; visibility: hidden; transition: opacity 0.2s, visibility 0.2s; z-index: 101; } .info-icon:hover::after, .info-icon:hover::before { opacity: 1; visibility: visible; } @media (prefers-color-scheme: dark) { .data-cutoff-badge { background: rgba(0, 113, 227, 0.1); border-color: rgba(0, 113, 227, 0.2); } .info-icon { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.1); } .info-icon::after { background: rgba(44, 44, 46, 0.95); } .info-icon::before { border-top-color: rgba(44, 44, 46, 0.95); } } } .top-nav h1 { font-size: 2rem; font-weight: 600; letter-spacing: -1px; } .header-actions { display: flex; align-items: center; gap: 20px; } .btn-refresh { background: var(--glass-bg); border: 1px solid var(--glass-border); color: var(--text-primary); padding: 8px 16px; border-radius: 20px; font-size: 0.85rem; font-weight: 500; cursor: pointer; backdrop-filter: blur(10px); transition: var(--transition-smooth); box-shadow: 0 2px 8px rgba(0,0,0,0.05); } .btn-refresh:hover { background: var(--text-primary); color: var(--bg-base); transform: scale(1.05); } .user-profile img { border-radius: 50%; width: 36px; height: 36px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); } /* Glassmorphism Cards */ .glass-card { background: var(--glass-bg); backdrop-filter: blur(25px); -webkit-backdrop-filter: blur(25px); border: 1px solid var(--glass-border); border-radius: 24px; box-shadow: var(--glass-shadow); padding: 1.5rem; transition: var(--transition-smooth); } .glass-card:hover { transform: translateY(-4px); box-shadow: 0 12px 40px rgba(0, 0, 0, 0.08); } /* Chart header with optional controls */ .chart-header { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; margin-bottom: 1rem; } .chart-header h2 { margin: 0; } /* Apple-style Segmented Control */ .segment-control { display: inline-flex; background: rgba(134, 134, 139, 0.08); border-radius: 10px; padding: 3px; gap: 2px; } .segment-btn { padding: 5px 16px; border: none; border-radius: 8px; background: transparent; color: var(--text-secondary); font-size: 0.8rem; font-weight: 500; cursor: pointer; transition: all 0.25s ease; font-family: inherit; } .segment-btn:hover { color: var(--text-primary); } .segment-btn.active { background: var(--text-primary); color: var(--bg-base); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12); } /* Dashboard Grid */ .dashboard-grid { display: flex; flex-direction: column; gap: 2rem; } .metrics-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.5rem; } .metric-card { display: flex; flex-direction: column; gap: 12px; } .metric-card h3 { font-size: 0.9rem; font-weight: 500; color: var(--text-secondary); } .metric-card .value { font-size: 2.2rem; font-weight: 600; letter-spacing: -1px; } .trend { font-size: 0.8rem; font-weight: 500; display: flex; align-items: center; gap: 4px; } .trend.positive { color: var(--accent-green); } .trend.negative { color: var(--accent-red); } .trend.neutral { color: var(--text-secondary); } /* Chart Area */ .charts-row { display: grid; grid-template-columns: 1fr; } .chart-container { padding: 2rem; } .chart-header h2 { font-size: 1.2rem; font-weight: 600; margin-bottom: 20px; } /* Animations loading state */ .loading { opacity: 0.5; pointer-events: none; animation: pulse 1.5s infinite; } @keyframes pulse { 0% { opacity: 0.5; } 50% { opacity: 0.8; } 100% { opacity: 0.5; } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .metrics-row .metric-card { animation: fadeInUp 0.8s cubic-bezier(0.25, 1, 0.5, 1) forwards; opacity: 0; } .metrics-row .metric-card:nth-child(1) { animation-delay: 0.1s; } .metrics-row .metric-card:nth-child(2) { animation-delay: 0.2s; } .metrics-row .metric-card:nth-child(3) { animation-delay: 0.3s; } .metrics-row .metric-card:nth-child(4) { animation-delay: 0.4s; } .chart-container { animation: fadeInUp 0.8s cubic-bezier(0.25, 1, 0.5, 1) forwards; animation-delay: 0.5s; opacity: 0; } /* Tables for Data Grids */ .table-responsive { width: 100%; overflow-x: auto; } .data-table { width: 100%; border-collapse: separate; border-spacing: 0; margin-top: 10px; } .data-table th, .data-table td { padding: 14px 16px; text-align: left; border-bottom: 1px solid var(--glass-border); font-size: 0.9rem; } .data-table th { font-weight: 600; color: var(--text-secondary); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.5px; } .data-table tbody tr { transition: background-color 0.2s; } .data-table tbody tr:hover { background-color: rgba(134, 134, 139, 0.05); /* very subtle hover */ } .text-center { text-align: center !important; } /* Rank Badge styling for Repurchase / Matrix Tag */ .badge { padding: 4px 10px; border-radius: 12px; font-size: 0.75rem; font-weight: 600; display: inline-block; } .badge.primary { background: rgba(0, 113, 227, 0.1); color: var(--accent-blue); } .badge.danger { background: rgba(255, 59, 48, 0.1); color: var(--accent-red); } .badge.success { background: rgba(52, 199, 89, 0.1); color: var(--accent-green); } .badge.warning { background: rgba(255, 149, 0, 0.1); color: #ff9500; } /* ============== Ops Date Picker ============== */ .ops-date-row { display: flex; align-items: center; gap: 12px; margin-bottom: 1.25rem; padding: 12px 16px; border-radius: 12px; background: rgba(0, 113, 227, 0.04); border: 1px solid rgba(0, 113, 227, 0.1); } .ops-date-label { font-size: 0.9rem; font-weight: 600; color: var(--text-primary); white-space: nowrap; } .ops-date-input { font-family: inherit; font-size: 0.88rem; padding: 6px 12px; border: 1px solid var(--glass-border); border-radius: 8px; background: var(--glass-bg); color: var(--text-primary); outline: none; transition: border-color 0.3s; min-width: 160px; } .ops-date-input:focus { border-color: var(--accent-blue); box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.1); } .ops-date-hint { font-size: 0.78rem; color: var(--text-secondary); } @media (prefers-color-scheme: dark) { .ops-date-row { background: rgba(0, 113, 227, 0.06); border-color: rgba(0, 113, 227, 0.15); } .ops-date-input { background: rgba(28, 28, 30, 0.6); border-color: rgba(255, 255, 255, 0.1); } } /* ============== Ops Management Page ============== */ .ops-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; margin-bottom: 2rem; } @media (max-width: 1200px) { .ops-grid { grid-template-columns: repeat(3, 1fr); } } @media (max-width: 800px) { .ops-grid { grid-template-columns: repeat(2, 1fr); } } .ops-btn { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 2rem 1.25rem; border: none; border-radius: 20px; background: linear-gradient(135deg, rgba(255,255,255,0.85) 0%, rgba(240,240,245,0.7) 100%); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); cursor: pointer; transition: all 0.4s cubic-bezier(0.25, 1, 0.5, 1); color: var(--text-primary); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04), 0 8px 24px rgba(0, 0, 0, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.8); overflow: hidden; } .ops-btn::before { content: ''; position: absolute; inset: 0; border-radius: 20px; padding: 1px; background: linear-gradient(135deg, rgba(255,255,255,0.6), rgba(255,255,255,0.1)); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none; } .ops-btn:hover { transform: translateY(-6px) scale(1.02); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08), 0 20px 40px rgba(0, 113, 227, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.9); } .ops-btn:active { transform: translateY(-2px) scale(0.98); transition-duration: 0.1s; } .ops-btn-accent { background: linear-gradient(135deg, rgba(0, 113, 227, 0.08) 0%, rgba(88, 86, 214, 0.06) 100%); box-shadow: 0 2px 8px rgba(0, 113, 227, 0.08), 0 8px 24px rgba(0, 113, 227, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.6); } .ops-btn-accent:hover { box-shadow: 0 8px 20px rgba(0, 113, 227, 0.15), 0 20px 40px rgba(88, 86, 214, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.8); } @media (prefers-color-scheme: dark) { .ops-btn { background: linear-gradient(135deg, rgba(44, 44, 46, 0.8) 0%, rgba(28, 28, 30, 0.7) 100%); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2), 0 8px 24px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.06); } .ops-btn::before { background: linear-gradient(135deg, rgba(255,255,255,0.1), rgba(255,255,255,0.02)); } .ops-btn:hover { box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3), 0 20px 40px rgba(0, 113, 227, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.08); } .ops-btn-accent { background: linear-gradient(135deg, rgba(0, 113, 227, 0.15) 0%, rgba(88, 86, 214, 0.1) 100%); } } .ops-icon { font-size: 2.5rem; line-height: 1; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.1)); } .ops-label { font-size: 1rem; font-weight: 600; letter-spacing: -0.3px; } .ops-desc { font-size: 0.78rem; color: var(--text-secondary); font-weight: 400; } /* Running state - pulsing glow */ .ops-running { pointer-events: none; animation: opsPulse 1.5s ease-in-out infinite; } @keyframes opsPulse { 0%, 100% { opacity: 0.6; box-shadow: 0 0 0 0 rgba(0, 113, 227, 0); } 50% { opacity: 1; box-shadow: 0 0 30px rgba(0, 113, 227, 0.2); } } /* Success state - green glow */ .ops-done { background: linear-gradient(135deg, rgba(52, 199, 89, 0.1) 0%, rgba(48, 209, 88, 0.06) 100%) !important; box-shadow: 0 0 0 2px rgba(52, 199, 89, 0.4), 0 8px 24px rgba(52, 199, 89, 0.15) !important; } /* Error state - red glow */ .ops-error { background: linear-gradient(135deg, rgba(255, 59, 48, 0.1) 0%, rgba(255, 69, 58, 0.06) 100%) !important; box-shadow: 0 0 0 2px rgba(255, 59, 48, 0.4), 0 8px 24px rgba(255, 59, 48, 0.15) !important; } /* Log panel — terminal aesthetic */ .ops-log-container { margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid var(--glass-border); } .ops-log-container h3 { font-size: 1rem; font-weight: 600; letter-spacing: -0.3px; } .ops-log { font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'Menlo', 'Consolas', monospace; font-size: 0.82rem; line-height: 2; background: rgba(0, 0, 0, 0.04); border-radius: 16px; padding: 1.25rem 1.5rem; min-height: 80px; max-height: 300px; overflow-y: auto; color: var(--text-secondary); border: 1px solid var(--glass-border); } @media (prefers-color-scheme: dark) { .ops-log { background: rgba(255, 255, 255, 0.03); border-color: rgba(255, 255, 255, 0.06); } } .ops-log .log-entry { display: block; padding: 4px 0; border-bottom: 1px solid rgba(134, 134, 139, 0.08); animation: logFadeIn 0.3s ease; } .ops-log .log-entry:last-child { border-bottom: none; } .ops-log .log-entry .log-time { color: var(--text-secondary); opacity: 0.6; margin-right: 8px; } .ops-log .log-entry.log-success { color: var(--accent-green); } .ops-log .log-entry.log-error { color: var(--accent-red); } .ops-log .log-entry.log-pending { color: var(--accent-blue); } @keyframes logFadeIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }