:root { --bg: #0b0e11; --surface: #14181d; --surface-alt: #1b2027; --border: #232830; --text: #e6e8eb; --text-dim: #8b93a1; --gain: #3ddc84; --loss: #ff6b5e; --accent: #e8b34c; --font-body: "Inter", system-ui, -apple-system, sans-serif; --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace; } * { box-sizing: border-box; } body { margin: 0; background: var(--bg); color: var(--text); font-family: var(--font-body); line-height: 1.5; } a { color: inherit; } .topbar { display: flex; align-items: center; justify-content: space-between; padding: 1.25rem 2rem; border-bottom: 1px solid var(--border); } .topbar-total { display: flex; align-items: baseline; gap: 0.6rem; text-decoration: none; font-family: var(--font-mono); font-variant-numeric: tabular-nums; } .topbar-value { font-weight: 700; font-size: 1.05rem; color: var(--text); } .topbar-pl { font-size: 0.85rem; color: var(--text-dim); } .topbar nav a { text-decoration: none; color: var(--text-dim); margin-left: 1.5rem; font-size: 0.9rem; transition: color 0.15s; } .topbar nav a:hover, .topbar nav a:focus-visible { color: var(--text); } main { max-width: 1200px; margin: 0 auto; padding: 2rem; } .topbar nav a.active { color: var(--text); } .tabbar { display: flex; gap: 0.35rem; margin-bottom: 1.25rem; overflow-x: auto; } .tab-btn { display: flex; align-items: center; gap: 0.5rem; background: transparent; color: var(--text-dim); border: 1px solid var(--border); border-radius: 8px 8px 0 0; border-bottom: none; padding: 0.5rem 0.9rem; font-family: var(--font-mono); font-size: 0.82rem; font-weight: 500; white-space: nowrap; cursor: pointer; } .tab-btn.active { color: var(--text); background: var(--surface); border-color: var(--border); } .tab-btn .tab-close { color: var(--text-dim); font-size: 0.75rem; line-height: 1; padding: 0.1rem 0.25rem; border-radius: 4px; } .tab-btn .tab-close:hover { color: var(--loss); background: var(--surface-alt); } .tab-panel { display: none; } .tab-panel.active { display: block; } .hero { padding: 2rem 0 2.5rem; } .hero-label { color: var(--text-dim); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 0.5rem; } .hero-value { font-family: var(--font-mono); font-size: clamp(2rem, 6vw, 3.5rem); font-weight: 600; font-variant-numeric: tabular-nums; } .hero-pl, .hero-sub { margin-top: 0.5rem; font-family: var(--font-mono); font-size: 1rem; color: var(--text-dim); } .back { text-decoration: none; color: var(--text-dim); } .back:hover { color: var(--accent); } .notice, .hint { color: var(--text-dim); font-size: 0.85rem; margin-top: 1rem; } .notice a, .hint a { color: var(--accent); } .notice.error { color: var(--loss); } .qr-code { display: block; width: 200px; height: 200px; margin: 0.75rem 0; border-radius: 8px; background: #fff; padding: 12px; } .secret-key { font-size: 1.1rem; letter-spacing: 0.08em; background: var(--surface-alt); border: 1px solid var(--border); border-radius: 8px; padding: 0.75rem 1rem; display: inline-block; word-break: break-all; } .logout-form { display: inline; margin-left: 1.5rem; } .logout-btn { background: none; border: none; padding: 0; color: var(--text-dim); font-size: 0.9rem; font-family: var(--font-body); cursor: pointer; transition: color 0.15s; } .logout-btn:hover { color: var(--text); } .login-body { margin: 0; min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--bg); } .login-main { width: 100%; max-width: 380px; padding: 1.5rem; } .login-panel { padding: 2rem; } .login-title { font-family: var(--font-mono); font-weight: 700; letter-spacing: 0.15em; color: var(--accent); font-size: 1.3rem; margin: 0 0 1.5rem; text-align: center; } .login-panel .form { flex-direction: column; align-items: stretch; } .login-panel .form label { flex: none; } .login-panel button[type="submit"] { margin-top: 0.5rem; } .modal-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.6); display: flex; align-items: center; justify-content: center; z-index: 100; padding: 1.5rem; } .modal-overlay[hidden] { display: none; } .modal { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 2rem; width: 100%; max-width: 340px; } .modal h2 { margin-top: 0; font-size: 1.05rem; } .modal .form { flex-direction: column; align-items: stretch; } .modal .form label { flex: none; } .modal button[type="submit"] { margin-top: 0.5rem; } .empty { color: var(--text-dim); } .table-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: 10px; } table.ledger { width: 100%; border-collapse: collapse; background: var(--surface); } .star-cell { width: 2rem; text-align: center !important; padding-left: 0.5rem !important; padding-right: 0.25rem !important; } .star-btn { background: none; border: none; color: var(--border); font-size: 1rem; cursor: pointer; padding: 0.15rem; line-height: 1; } .star-btn:hover { color: var(--accent); } .star-btn.active { color: var(--accent); } tr.is-favourite { background: rgba(232, 179, 76, 0.05); } .ledger th, .ledger td { padding: 0.65rem 0.5rem; text-align: right; white-space: nowrap; border-bottom: 1px solid var(--border); } .ledger th:first-of-type, .ledger td:first-of-type { padding-left: 0.75rem; } .ledger th:first-child, .ledger td:first-child { text-align: left; } .ledger th { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-dim); font-weight: 600; position: sticky; top: 0; background: var(--surface); } .ledger th[data-sort] { cursor: pointer; user-select: none; } .ledger th[data-sort]:hover { color: var(--text); } .ledger th[data-sort]::after { content: ""; display: inline-block; width: 0.6em; margin-left: 0.2em; opacity: 0.5; } .ledger th[data-sort].sort-asc::after { content: "▲"; opacity: 1; color: var(--accent); } .ledger th[data-sort].sort-desc::after { content: "▼"; opacity: 1; color: var(--accent); } .badge { display: inline-block; font-size: 0.72rem; font-weight: 600; padding: 0.15rem 0.5rem; border-radius: 5px; background: var(--surface-alt); color: var(--text-dim); } .badge.buy { color: var(--gain); background: rgba(61, 220, 132, 0.12); } .badge.sell { color: var(--loss); background: rgba(255, 107, 94, 0.12); } .badge.deposit { color: var(--accent); background: rgba(232, 179, 76, 0.12); } .badge.withdrawal { color: var(--text-dim); background: var(--surface-alt); } .ledger tbody tr:hover { background: var(--surface-alt); } .ledger tbody tr:last-child td { border-bottom: none; } .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; } .chip { display: inline-block; font-family: var(--font-mono); font-size: 0.78rem; font-weight: 600; padding: 0.2rem 0.5rem; border-radius: 6px; background: var(--surface-alt); color: var(--text-dim); } .chip.gain { color: var(--gain); background: rgba(61, 220, 132, 0.12); } .chip.loss { color: var(--loss); background: rgba(255, 107, 94, 0.12); } .gain { color: var(--gain); } .loss { color: var(--loss); } .flat { color: var(--text-dim); } #rows.pulse { animation: pulse 0.6s ease-out; } @keyframes pulse { from { opacity: 0.55; } to { opacity: 1; } } .panel { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 1.5rem 1.75rem; margin-bottom: 1.5rem; } .panel h2 { margin-top: 0; font-size: 1.05rem; } .status { color: var(--text-dim); font-size: 0.9rem; } .status.ok { color: var(--gain); } .form { display: flex; flex-wrap: wrap; gap: 1rem; align-items: end; } .form.grid label { min-width: 140px; } .form label { display: flex; flex-direction: column; gap: 0.35rem; font-size: 0.8rem; color: var(--text-dim); flex: 1 1 160px; } .form input, .form select { background: var(--surface-alt); border: 1px solid var(--border); border-radius: 6px; padding: 0.55rem 0.65rem; color: var(--text); font-family: var(--font-mono); font-size: 0.9rem; } .form input:focus-visible, .form select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; } button { background: var(--accent); color: #14181d; border: none; border-radius: 6px; padding: 0.6rem 1.1rem; font-weight: 600; font-size: 0.85rem; cursor: pointer; } button:hover { filter: brightness(1.08); } button:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; } .toggle-list { list-style: none; padding: 0; margin: 0; } .toggle-list li { display: flex; align-items: center; justify-content: space-between; padding: 0.6rem 0; border-bottom: 1px solid var(--border); } .toggle-list li:last-child { border-bottom: none; } .toggle { background: var(--surface-alt); color: var(--text); font-weight: 500; font-size: 0.78rem; padding: 0.35rem 0.7rem; } .toggle.is-hidden { color: var(--text-dim); } .chart-card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 1rem 1.25rem 0.5rem; margin-bottom: 1.5rem; } .chart-controls { display: flex; gap: 0.35rem; margin-bottom: 0.5rem; } .chart-controls button { background: var(--surface-alt); color: var(--text-dim); font-size: 0.72rem; font-weight: 600; padding: 0.3rem 0.6rem; } .chart-controls button.active { background: var(--accent); color: #14181d; } .chart-controls button.mode-toggle { margin-left: auto; } .chart { width: 100%; aspect-ratio: 600 / 220; height: auto; display: block; } .chart[hidden] { display: none; } .chart-line { fill: none; stroke-width: 1.6; vector-effect: non-scaling-stroke; } .chart-line.gain { stroke: var(--gain); } .chart-line.loss { stroke: var(--loss); } .chart-line.flat { stroke: var(--text-dim); } .chart-grid { stroke: var(--border); stroke-width: 1; stroke-dasharray: 2 3; } .chart-axis-label { font-family: var(--font-mono); font-size: 11px; fill: var(--text-dim); } .chart-axis-y { text-anchor: end; dominant-baseline: middle; } .chart-axis-x { text-anchor: middle; } .chart-empty { color: var(--text-dim); font-size: 0.85rem; padding: 2.5rem 0; text-align: center; } .chart-caption { color: var(--text-dim); font-size: 0.78rem; margin: 0.4rem 0 0.75rem; } .chart-sublabel { color: var(--text-dim); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; margin: 0.75rem 0 0.25rem; } .candle-chart { aspect-ratio: 600 / 260; } .rsi-chart { aspect-ratio: 600 / 90; margin-bottom: 0.5rem; } .candle-wick { stroke-width: 1; vector-effect: non-scaling-stroke; } .candle-wick.candle-up { stroke: var(--gain); } .candle-wick.candle-down { stroke: var(--loss); } .candle-body.candle-up { fill: var(--gain); } .candle-body.candle-down { fill: var(--loss); } .bb-band { fill: rgba(139, 147, 161, 0.08); stroke: none; } .bb-line { fill: none; stroke: var(--text-dim); stroke-width: 1; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; } .bb-mid { fill: none; stroke: var(--accent); stroke-width: 1; vector-effect: non-scaling-stroke; } .rsi-line { fill: none; stroke: var(--accent); stroke-width: 1.4; vector-effect: non-scaling-stroke; } .staked-note { color: var(--text-dim); font-size: 0.78rem; } @keyframes live-flash { from { background: rgba(232, 179, 76, 0.18); } to { background: transparent; } } .flash { animation: live-flash 0.8s ease-out; } tr.flash { animation: none; } /* row background flash would fight is-favourite tint; cells still flash individually via inherited rule below */ tr[data-ws-symbol].flash td { animation: live-flash 0.8s ease-out; } @media (max-width: 860px) { table.ledger thead { display: none; } table.ledger, table.ledger tbody, table.ledger tr, table.ledger td { display: block; width: 100%; } .table-scroll { overflow-x: visible; } table.ledger tr { border: 1px solid var(--border); border-radius: 8px; margin: 0.6rem; padding: 0.4rem 0.75rem; } table.ledger td { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px dashed var(--border); padding: 0.45rem 0; text-align: right; white-space: normal; } table.ledger td:last-child { border-bottom: none; } table.ledger td::before { content: attr(data-label); color: var(--text-dim); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; text-align: left; padding-right: 1rem; } table.ledger td.star-cell { justify-content: flex-end; padding: 0.3rem 0 !important; } table.ledger td.star-cell::before { content: ""; } } @media (max-width: 640px) { .topbar { padding: 1rem 1.25rem; } main { padding: 1.25rem; } .form { flex-direction: column; align-items: stretch; } } @media (prefers-reduced-motion: reduce) { #rows.pulse { animation: none; } }