/* money-trace ยท dark finance-terminal aesthetic */ :root { --bg: #090b0f; --bg-grid: rgba(255,255,255,0.022); --panel: #10141b; --panel-2: #161b24; --line: rgba(255,255,255,0.075); --line-2: rgba(255,255,255,0.13); --ink: #eaeff7; --ink-mute: #8b95a6; --ink-dim: #545d6d; --c-income: #2ee6a6; /* real money in */ --c-spend: #ff5f73; /* real money out */ --c-person: #b98cff; /* inter-person */ --c-fee: #ffc24b; /* fees & interest*/ --c-internal:#4b5466; /* cycles / noise */ --glow: 1; /* 0..1, multiplied into drop-shadows */ --link-op: 0.62; /* base opacity of real links */ --font-ui: 'Space Grotesk', system-ui, sans-serif; --font-num: 'IBM Plex Mono', ui-monospace, monospace; } * { box-sizing: border-box; } html, body { margin: 0; height: 100%; } body { background: radial-gradient(1200px 700px at 78% -8%, rgba(46,230,166,0.05), transparent 60%), radial-gradient(900px 600px at 6% 110%, rgba(185,140,255,0.045), transparent 55%), linear-gradient(0deg, var(--bg-grid) 1px, transparent 1px) 0 0 / 100% 34px, var(--bg); color: var(--ink); font-family: var(--font-ui); -webkit-font-smoothing: antialiased; overflow: hidden; } .num { font-family: var(--font-num); font-feature-settings: 'tnum' 1; letter-spacing: -0.01em; } /* ---- app frame ---- */ #app { display: flex; flex-direction: column; height: 100vh; } /* ---- header / summary bar ---- */ header.bar { display: flex; align-items: stretch; gap: 0; padding: 14px 22px 13px; border-bottom: 1px solid var(--line); background: linear-gradient(180deg, rgba(255,255,255,0.018), transparent); } .brand { display: flex; flex-direction: column; justify-content: center; min-width: 168px; } .brand .mark { font-weight: 600; font-size: 15px; letter-spacing: 0.26em; text-transform: uppercase; color: var(--ink); } .brand .mark b { color: var(--c-income); font-weight: 600; } .brand .sub { font-size: 11px; color: var(--ink-dim); letter-spacing: 0.04em; margin-top: 3px; } .stats { display: flex; gap: 30px; margin-left: auto; align-items: center; } .stat { display: flex; flex-direction: column; gap: 4px; min-width: 132px; } .stat .lab { font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-mute); display: flex; align-items: center; gap: 6px; } .stat .lab i { width: 7px; height: 7px; border-radius: 2px; display: inline-block; } .stat .val { font-size: 27px; font-weight: 500; line-height: 1; } .stat .val small { font-size: 13px; color: var(--ink-dim); margin-left: 2px; } .stat.income .val { color: var(--c-income); } .stat.spend .val { color: var(--c-spend); } .stat.internal .val { color: var(--ink-mute); } .stat.net .val { color: var(--ink); } .stat .delta { font-size: 11px; color: var(--ink-dim); } /* ---- controls strip ---- */ .controls { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; padding: 11px 22px; border-bottom: 1px solid var(--line); background: var(--panel); } .seg { display: inline-flex; background: var(--bg); border: 1px solid var(--line); border-radius: 9px; padding: 3px; gap: 2px; } .seg button { font-family: var(--font-ui); font-size: 12.5px; color: var(--ink-mute); background: transparent; border: 0; padding: 7px 15px; border-radius: 6px; cursor: pointer; display: flex; align-items: center; gap: 7px; transition: .16s; } .seg button:hover { color: var(--ink); } .seg button.on { background: var(--panel-2); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-2); } .seg button svg { width: 14px; height: 14px; } .toggle { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; user-select: none; } .toggle .track { width: 38px; height: 21px; border-radius: 20px; background: var(--bg); border: 1px solid var(--line-2); position: relative; transition: .18s; } .toggle .track::after { content: ''; position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 50%; background: var(--ink-mute); transition: .18s; } .toggle.on .track { background: rgba(46,230,166,0.22); border-color: var(--c-income); } .toggle.on .track::after { left: 19px; background: var(--c-income); } .toggle .lbl { font-size: 12.5px; color: var(--ink); } .toggle .hint { font-size: 11px; color: var(--ink-dim); } .ctl-label { font-size: 10.5px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-dim); margin-right: -8px; } /* month scrubber */ .scrub { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 280px; max-width: 560px; } .scrub .play { width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line); background: var(--bg); color: var(--ink); cursor: pointer; display: grid; place-items: center; } .scrub .play:hover { border-color: var(--line-2); } .scrub .track-wrap { flex: 1; } .scrub .months { display: flex; justify-content: space-between; font-size: 10px; color: var(--ink-dim); margin-bottom: 5px; } .scrub .months b { color: var(--c-income); font-weight: 500; font-family: var(--font-num); } .bars { display: flex; gap: 2px; align-items: flex-end; height: 30px; } .bars .b { flex: 1; background: var(--line); border-radius: 2px 2px 0 0; cursor: pointer; transition: .14s; min-height: 2px; } .bars .b:hover { background: var(--ink-dim); } .bars .b.active { background: linear-gradient(180deg, var(--c-income), rgba(46,230,166,0.35)); } /* bank filter */ .dropdown { position: relative; } .dropdown > .btn { font-family: var(--font-ui); font-size: 12.5px; color: var(--ink); background: var(--bg); border: 1px solid var(--line); border-radius: 8px; padding: 8px 13px; cursor: pointer; display: flex; align-items: center; gap: 8px; } .dropdown > .btn .cnt { color: var(--ink-dim); font-family: var(--font-num); font-size: 11px; } .dropdown .menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 40; background: var(--panel-2); border: 1px solid var(--line-2); border-radius: 10px; padding: 8px; width: 220px; box-shadow: 0 18px 50px rgba(0,0,0,0.55); display: none; max-height: 360px; overflow: auto; } .dropdown.open .menu { display: block; } .dropdown .menu .row { display: flex; align-items: center; gap: 9px; padding: 7px 9px; border-radius: 7px; cursor: pointer; font-size: 12.5px; } .dropdown .menu .row:hover { background: var(--panel); } .dropdown .menu .row .ck { width: 15px; height: 15px; border-radius: 4px; border: 1px solid var(--line-2); display: grid; place-items: center; color: var(--bg); } .dropdown .menu .row.on .ck { background: var(--c-income); border-color: var(--c-income); } .dropdown .menu .row .n { color: var(--ink-dim); margin-left: auto; font-family: var(--font-num); font-size: 11px; } .dropdown .menu .sep { height: 1px; background: var(--line); margin: 6px 4px; } .dropdown .menu .all { font-size: 11px; color: var(--c-income); padding: 6px 9px; cursor: pointer; } /* ---- legend ---- */ .legend { display: flex; align-items: center; gap: 16px; margin-left: auto; } .legend .item { display: flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--ink-mute); } .legend .item i { width: 16px; height: 3px; border-radius: 2px; display: inline-block; } .legend .item.dash i { height: 0; border-top: 2px dashed var(--c-internal); width: 18px; } /* ---- view area ---- */ .view { position: relative; flex: 1; overflow: hidden; } .view svg { width: 100%; height: 100%; display: block; } /* sankey */ .node-rect { transition: opacity .18s; } .node-label { fill: var(--ink); font-size: 12.5px; font-family: var(--font-ui); } .node-sub { fill: var(--ink-dim); font-size: 10px; font-family: var(--font-num); } .node-val { fill: var(--ink-mute); font-size: 10.5px; font-family: var(--font-num); } .colhead { fill: var(--ink-dim); font-size: 10.5px; letter-spacing: 0.16em; text-transform: uppercase; font-family: var(--font-ui); } .link { fill: none; transition: opacity .18s, stroke-opacity .18s; } .link.real { opacity: var(--link-op); } .link.internal { opacity: 0.4; } .link.income { stroke: var(--c-income); } .link.inter_in, .link.inter_out { stroke: var(--c-person); } .link.expense { stroke: var(--c-spend); } .link.fee { stroke: var(--c-fee); } .link.internal_card, .link.internal_line, .link.internal_self { stroke: var(--c-internal); stroke-dasharray: 5 5; } .glow-real { filter: drop-shadow(0 0 calc(5px * var(--glow)) currentColor); } .dim { opacity: 0.07 !important; } .hl { opacity: 0.95 !important; } /* ---- tooltip ---- */ #tip { position: fixed; z-index: 80; pointer-events: none; max-width: 320px; background: rgba(13,17,23,0.96); border: 1px solid var(--line-2); border-radius: 11px; padding: 12px 13px; box-shadow: 0 16px 44px rgba(0,0,0,0.6); backdrop-filter: blur(8px); opacity: 0; transform: translateY(4px); transition: opacity .12s, transform .12s; font-size: 12.5px; } #tip.show { opacity: 1; transform: translateY(0); } #tip .t-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; } #tip .t-dot { width: 9px; height: 9px; border-radius: 3px; } #tip .t-title { font-weight: 600; font-size: 13px; } #tip .t-amt { font-family: var(--font-num); font-size: 19px; margin: 2px 0 9px; } #tip .t-meta { color: var(--ink-mute); font-size: 11px; margin-bottom: 9px; } #tip .t-rows { display: flex; flex-direction: column; gap: 5px; border-top: 1px solid var(--line); padding-top: 9px; max-height: 200px; overflow: hidden; } #tip .t-row { display: flex; gap: 10px; font-size: 11.5px; align-items: baseline; } #tip .t-row .d { color: var(--ink-dim); font-family: var(--font-num); font-size: 10.5px; width: 42px; flex: none; } #tip .t-row .desc { color: var(--ink-mute); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } #tip .t-row .a { font-family: var(--font-num); color: var(--ink); } #tip .t-more { color: var(--ink-dim); font-size: 10.5px; margin-top: 7px; } /* orbit view */ .orbit-ring { fill: none; stroke: var(--line); stroke-width: 1; } .orbit-node-label { fill: var(--ink); font-size: 11.5px; font-family: var(--font-ui); } .orbit-sub { fill: var(--ink-dim); font-size: 9.5px; font-family: var(--font-num); } .orbit-center-lab { fill: var(--ink); font-size: 14px; font-family: var(--font-ui); font-weight: 600; } /* empty state */ .empty { position: absolute; inset: 0; display: grid; place-items: center; color: var(--ink-dim); font-size: 14px; } /* loading */ #loading { position: fixed; inset: 0; display: grid; place-items: center; background: var(--bg); z-index: 200; color: var(--ink-mute); font-family: var(--font-num); font-size: 13px; letter-spacing: 0.1em; }