@mulsok/traders-client 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/README.md +42 -5
- package/bin/cli.js +618 -38
- package/dist/server/auth/admin.js +32 -0
- package/dist/server/auth/admin.js.map +1 -0
- package/dist/server/broker/kiwoom/_helpers/symbol-code.js +21 -0
- package/dist/server/broker/kiwoom/_helpers/symbol-code.js.map +1 -0
- package/dist/server/broker/kiwoom/client.js +23 -4
- package/dist/server/broker/kiwoom/client.js.map +1 -1
- package/dist/server/broker/kiwoom/endpoints/account.js +14 -6
- package/dist/server/broker/kiwoom/endpoints/account.js.map +1 -1
- package/dist/server/broker/kiwoom/endpoints/quote.js +99 -13
- package/dist/server/broker/kiwoom/endpoints/quote.js.map +1 -1
- package/dist/server/broker/kiwoom/index.js +1 -1
- package/dist/server/broker/kiwoom/index.js.map +1 -1
- package/dist/server/broker/kiwoom/order-tracker.js +13 -0
- package/dist/server/broker/kiwoom/order-tracker.js.map +1 -1
- package/dist/server/broker/kiwoom/price-feed.js +13 -0
- package/dist/server/broker/kiwoom/price-feed.js.map +1 -1
- package/dist/server/broker/kiwoom/ws/endpoints/condition.js +3 -2
- package/dist/server/broker/kiwoom/ws/endpoints/condition.js.map +1 -1
- package/dist/server/calendar/kst-marker.js +68 -0
- package/dist/server/calendar/kst-marker.js.map +1 -0
- package/dist/server/config.js +370 -72
- package/dist/server/config.js.map +1 -1
- package/dist/server/db/sqlite.js +53 -29
- package/dist/server/db/sqlite.js.map +1 -1
- package/dist/server/diary/writer.js +151 -46
- package/dist/server/diary/writer.js.map +1 -1
- package/dist/server/index.js +166 -11
- package/dist/server/index.js.map +1 -1
- package/dist/server/jobs/universe-sync.js +48 -11
- package/dist/server/jobs/universe-sync.js.map +1 -1
- package/dist/server/jobs/watchdog.js +4 -0
- package/dist/server/jobs/watchdog.js.map +1 -1
- package/dist/server/journal/telemetry.js +11 -0
- package/dist/server/journal/telemetry.js.map +1 -1
- package/dist/server/journal/trade-journal.js +42 -16
- package/dist/server/journal/trade-journal.js.map +1 -1
- package/dist/server/llm/context-builder.js +9 -5
- package/dist/server/llm/context-builder.js.map +1 -1
- package/dist/server/personas/loader.js +46 -16
- package/dist/server/personas/loader.js.map +1 -1
- package/dist/server/personas/persona-agent.js +93 -21
- package/dist/server/personas/persona-agent.js.map +1 -1
- package/dist/server/personas/persona-state.js +198 -19
- package/dist/server/personas/persona-state.js.map +1 -1
- package/dist/server/personas/runner.js +29 -0
- package/dist/server/personas/runner.js.map +1 -1
- package/dist/server/personas/schema.js +13 -0
- package/dist/server/personas/schema.js.map +1 -1
- package/dist/server/personas/wake-plan.js +4 -67
- package/dist/server/personas/wake-plan.js.map +1 -1
- package/dist/server/readiness.js +70 -0
- package/dist/server/readiness.js.map +1 -1
- package/dist/server/routes.js +300 -13
- package/dist/server/routes.js.map +1 -1
- package/dist/server/screener/engine.js +110 -1
- package/dist/server/screener/engine.js.map +1 -1
- package/dist/server/screener/indicators.js +63 -0
- package/dist/server/screener/indicators.js.map +1 -0
- package/dist/server/server-sync.js +387 -126
- package/dist/server/server-sync.js.map +1 -1
- package/dist/server/share/postgres-publish.js +139 -0
- package/dist/server/share/postgres-publish.js.map +1 -0
- package/dist/server/share/prepare-state.js +50 -0
- package/dist/server/share/prepare-state.js.map +1 -0
- package/dist/server/share/prepare.js +61 -0
- package/dist/server/share/prepare.js.map +1 -0
- package/dist/server/share/publish-cron.js +96 -0
- package/dist/server/share/publish-cron.js.map +1 -0
- package/dist/server/share/snapshot.js +81 -0
- package/dist/server/share/snapshot.js.map +1 -0
- package/dist/server/watchers/condition-watcher.js +57 -16
- package/dist/server/watchers/condition-watcher.js.map +1 -1
- package/dist/web/assets/index-B1C-UX9W.js +88 -0
- package/dist/web/assets/index-N7Xwheka.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +4 -5
- package/dist/web/assets/index-62SMpbaf.js +0 -79
- package/dist/web/assets/index-BPLQR0wt.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--bg-stop-1: #DBEAFE;--bg-stop-2: #FCE7F3;--bg-stop-3: #DBF4F0;--bg-stop-4: #FEF3C7;--bg-base: #F8FAFC;--bg-mesh: radial-gradient(circle at 18% 22%, var(--bg-stop-1) 0%, transparent 38%), radial-gradient(circle at 82% 14%, var(--bg-stop-2) 0%, transparent 36%), radial-gradient(circle at 8% 80%, var(--bg-stop-3) 0%, transparent 38%), radial-gradient(circle at 90% 88%, var(--bg-stop-4) 0%, transparent 38%), var(--bg-base);--glass: rgba(255, 255, 255, .62);--glass-2: rgba(255, 255, 255, .78);--glass-3: rgba(255, 255, 255, .88);--glass-border: rgba(255, 255, 255, .95);--glass-line: rgba(15, 23, 41, .06);--glass-divider: rgba(15, 23, 41, .08);--ink-900: #0F172A;--ink-800: #1E293B;--ink-700: #334155;--ink-mute: #475569;--ink-dim: #94A3B8;--ink-faint: #CBD5E1;--accent: #6366F1;--accent-2: #EC4899;--accent-3: #818CF8;--accent-grad: linear-gradient(135deg, var(--accent), var(--accent-2));--accent-soft: rgba(99, 102, 241, .1);--accent-tint: rgba(99, 102, 241, .18);--gain: #10B981;--gain-soft: rgba(16, 185, 129, .18);--loss: #EF4444;--loss-soft: rgba(239, 68, 68, .1);--loss-tint: rgba(239, 68, 68, .18);--warn: #F59E0B;--warn-soft: rgba(245, 158, 11, .18);--info: var(--accent);--grad-purple: linear-gradient(135deg, #6366F1, #818CF8);--grad-pink: linear-gradient(135deg, #EC4899, #F472B6);--grad-green: linear-gradient(135deg, #10B981, #34D399);--grad-amber: linear-gradient(135deg, #F59E0B, #FBBF24);--grad-rose: linear-gradient(135deg, #F43F5E, #FB7185);--grad-sky: linear-gradient(135deg, #0EA5E9, #38BDF8);--persona-neoul: #0EA5E9;--persona-unknown: #94A3B8;--font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Pretendard Variable", Pretendard, system-ui, sans-serif;--font-mono: "SF Mono", "JetBrains Mono", ui-monospace, monospace;--fs-hero: 44px;--fs-h1: 32px;--fs-h2: 22px;--fs-h3: 19px;--fs-lg: 17px;--fs-body: 15px;--fs-sm: 13px;--fs-xs: 12px;--fs-tiny: 11px;--fw-bold: 800;--fw-semi: 700;--fw-medium: 600;--fw-regular: 500;--sp-1: 4px;--sp-2: 8px;--sp-3: 12px;--sp-4: 16px;--sp-5: 22px;--sp-6: 30px;--sp-7: 44px;--sp-8: 64px;--r-xs: 6px;--r-sm: 10px;--r-md: 12px;--r-lg: 18px;--r-xl: 22px;--r-2xl: 24px;--r-3xl: 28px;--r-pill: 999px;--shadow-sm: 0 1px 3px rgba(15, 23, 41, .04);--shadow: 0 8px 32px rgba(15, 23, 41, .06), 0 2px 6px rgba(15, 23, 41, .04);--shadow-lg: 0 24px 60px rgba(15, 23, 41, .1), 0 4px 12px rgba(15, 23, 41, .05);--shadow-icon: 0 2px 6px rgba(15, 23, 41, .1);--shadow-icon-color-purple: 0 2px 8px rgba(99, 102, 241, .25);--shadow-icon-color-pink: 0 2px 8px rgba(236, 72, 153, .25);--shadow-icon-color-green: 0 2px 8px rgba(16, 185, 129, .25);--blur-sm: blur(12px) saturate(180%);--blur: blur(20px) saturate(180%);--blur-lg: blur(28px) saturate(180%);--tx-fast: all .15s ease;--tx: all .2s ease;--tx-slow: all .3s ease;--bg: #FFFFFF;--surface: var(--glass-2);--border: var(--glass-line);--border-strong: var(--glass-divider);--ease-out: cubic-bezier(.4, 0, .2, 1);--fw-semibold: var(--fw-semi)}*{box-sizing:border-box;margin:0;padding:0}html,body,#root{height:100%;background:var(--bg-mesh);background-attachment:fixed}html{font-size:16px}body{font-family:var(--font-sans);color:var(--ink-900);line-height:1.5;-webkit-font-smoothing:antialiased;letter-spacing:-.011em}button{font-family:inherit;cursor:pointer;border:0;background:transparent;color:inherit}input,select,textarea{font-family:inherit;color:inherit}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}hr{border:0;height:1px;background:var(--glass-line);margin:var(--sp-5) 0}.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}.app-shell{min-height:100vh;display:flex;flex-direction:column}.app-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);padding:12px var(--sp-4);max-width:1140px;width:calc(100% - var(--sp-7) * 2);margin:var(--sp-4) auto 0;background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r-3xl);backdrop-filter:var(--blur-lg);-webkit-backdrop-filter:var(--blur-lg);box-shadow:var(--shadow);position:sticky;top:var(--sp-4);z-index:10}@media(max-width:720px){.app-bar{width:calc(100% - var(--sp-4) * 2)}}.brand{display:flex;align-items:center;gap:10px;padding-left:var(--sp-3);font-size:var(--fs-lg);font-weight:var(--fw-semi);letter-spacing:-.02em;color:var(--ink-900);text-decoration:none}.brand:hover{text-decoration:none}.brand-mark{width:34px;height:34px;border-radius:11px;background:var(--accent-grad);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:var(--fw-bold);font-size:16px;box-shadow:var(--shadow-icon-color-purple)}.brand-word{font-weight:var(--fw-semi)}.app-nav{display:flex;gap:4px;padding:0 var(--sp-2)}.app-nav button{padding:8px 16px;border-radius:var(--r-pill);font-size:var(--fs-sm);font-weight:var(--fw-medium);color:var(--ink-mute);transition:var(--tx)}.app-nav button:hover{background:#fff9;color:var(--ink-900)}.app-nav button.is-active{background:var(--ink-900);color:#fff;font-weight:var(--fw-semi);box-shadow:0 2px 6px #0f172926}.user-pill{display:flex;align-items:center;gap:var(--sp-2);padding:8px 14px;border-radius:var(--r-pill);background:var(--glass-2);font-size:var(--fs-sm);font-weight:var(--fw-medium);color:var(--ink-800);margin-right:var(--sp-2)}.user-pill .dot{width:7px;height:7px;border-radius:50%;background:var(--gain);box-shadow:0 0 0 3px #10b98133}.user-pill.is-warn .dot{background:var(--warn);box-shadow:0 0 0 3px var(--warn-soft)}.user-pill.is-halt .dot{background:var(--loss);box-shadow:0 0 0 3px var(--loss-soft)}.app-bar-right{display:flex;align-items:center;gap:var(--sp-2)}.app-main{flex:1;min-height:0;max-width:1140px;width:100%;margin:0 auto;padding:var(--sp-6) var(--sp-7) var(--sp-7);display:flex;flex-direction:column;gap:var(--sp-5)}.glass{background:var(--glass-2);border:1px solid var(--glass-border);border-radius:var(--r-2xl);backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur);box-shadow:var(--shadow)}.glass-lg{background:var(--glass-2);border:1px solid var(--glass-border);border-radius:var(--r-3xl);backdrop-filter:var(--blur-lg);-webkit-backdrop-filter:var(--blur-lg);box-shadow:var(--shadow-lg)}.glass-pad{padding:var(--sp-6)}.glass-pad-lg,.hero{padding:var(--sp-7)}.hero .pill{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:var(--r-pill);background:var(--accent-soft);color:var(--accent);font-size:var(--fs-xs);font-weight:var(--fw-medium);margin-bottom:var(--sp-4)}.hero h1{font-size:var(--fs-hero);font-weight:var(--fw-bold);letter-spacing:-.035em;line-height:1.1;color:var(--ink-900);margin-bottom:var(--sp-3)}.hero h1 .grad{background:var(--accent-grad);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.hero p{font-size:var(--fs-lg);color:var(--ink-mute);max-width:50ch}.dash-kpi-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:var(--sp-3);margin-bottom:var(--sp-5)}.dash-kpi{padding:var(--sp-4);background:var(--glass);border:1px solid var(--border);border-radius:var(--r-md, 12px);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);display:grid;grid-template-columns:36px 1fr;gap:var(--sp-3);align-items:start;transition:border-color .12s}.dash-kpi:hover{border-color:var(--ink-300)}.dash-kpi-icon{font-size:28px;line-height:1;display:flex;align-items:center;justify-content:center;width:36px;height:36px;background:var(--surface, rgba(0, 0, 0, .04));border-radius:10px;flex-shrink:0}.dash-kpi-body{display:flex;flex-direction:column;gap:2px;min-width:0}.dash-kpi-label{font-size:var(--fs-tiny);color:var(--ink-500);font-weight:600;letter-spacing:.04em}.dash-kpi-value{font-size:var(--fs-h2);font-weight:700;color:var(--ink-900);line-height:1.15;letter-spacing:-.4px;font-variant-numeric:tabular-nums}.dash-kpi-value-sm{font-size:var(--fs-body);font-weight:600;color:var(--ink-700);margin-top:2px}.dash-kpi-sub{font-size:var(--fs-tiny);color:var(--ink-500);margin-top:2px}.dash-kpi-pnl.is-gain{border-color:color-mix(in oklab,var(--gain) 35%,var(--border));background:color-mix(in oklab,var(--gain) 6%,var(--glass))}.dash-kpi-pnl.is-loss{border-color:color-mix(in oklab,var(--loss) 35%,var(--border));background:color-mix(in oklab,var(--loss) 6%,var(--glass))}.dash-kpi-value.is-gain{color:var(--gain)}.dash-kpi-value.is-loss{color:var(--loss)}.wake-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:var(--sp-3);margin-top:var(--sp-3)}.wake-card{background:var(--glass);border:1px solid var(--border);border-radius:var(--r-md);padding:var(--sp-4);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.wake-card-head{display:flex;justify-content:space-between;align-items:baseline;padding-bottom:var(--sp-3);margin-bottom:var(--sp-3);border-bottom:1px solid var(--border)}.wake-persona{font-size:var(--fs-h3);font-weight:700;color:var(--ink-900);letter-spacing:-.3px}.wake-count{font-size:var(--fs-tiny);font-weight:600;color:var(--ink-500);background:var(--accent-soft);padding:2px 10px;border-radius:999px;font-variant-numeric:tabular-nums}.wake-list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:var(--sp-3)}.wake-row{display:grid;grid-template-columns:auto 1fr auto;gap:var(--sp-3);align-items:start}.wake-when{font-size:var(--fs-h3);font-weight:700;color:var(--ink-900);font-variant-numeric:tabular-nums;letter-spacing:-.3px;white-space:nowrap;line-height:1.3}.wake-intent{font-size:var(--fs-body);color:var(--ink-700);line-height:1.5;word-break:keep-all;align-self:center}.wake-type{font-size:var(--fs-tiny);font-weight:600;padding:2px 10px;border-radius:999px;white-space:nowrap;letter-spacing:.04em;align-self:center;border:1px solid transparent}.wake-type-time{background:var(--accent-soft);color:var(--accent);border-color:color-mix(in oklab,var(--accent) 25%,transparent)}.wake-type-price{background:color-mix(in oklab,var(--warn) 14%,transparent);color:var(--warn);border-color:color-mix(in oklab,var(--warn) 30%,transparent)}.wake-type-event{background:var(--glass);color:var(--ink-700);border-color:var(--border)}.stat-row{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-4)}.stat-card{padding:var(--sp-4) var(--sp-5);display:grid;grid-template-columns:40px 1fr;gap:var(--sp-3);align-items:center;position:relative;overflow:hidden}.stat-card .icon{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:18px;box-shadow:var(--shadow-icon)}.stat-card .icon.purple{background:var(--grad-purple);color:#fff}.stat-card .icon.pink{background:var(--grad-pink);color:#fff}.stat-card .icon.green{background:var(--grad-green);color:#fff}.stat-card .icon.amber{background:var(--grad-amber);color:#fff}.stat-card .icon.rose{background:var(--grad-rose);color:#fff}.stat-card .icon.sky{background:var(--grad-sky);color:#fff}.stat-card .v{font-size:24px;font-weight:var(--fw-bold);letter-spacing:-.025em;color:var(--ink-900);line-height:1.05}.stat-card .v.gain{color:var(--gain)}.stat-card .v.loss{color:var(--loss)}.stat-card .v.warn{color:var(--warn)}.stat-card .k{font-size:var(--fs-xs);color:var(--ink-mute);font-weight:var(--fw-medium);margin-top:2px}.stat-card .stat-body{display:flex;flex-direction:column;min-width:0}.stat-card.is-clickable{cursor:pointer;border:1px solid var(--glass-line);text-align:left;font:inherit;width:100%;transition:var(--tx-fast)}.stat-card.is-clickable:hover{transform:translateY(-2px);box-shadow:var(--shadow)}.stat-card.is-clickable:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.stat-card.is-clickable:after{content:"↗";position:absolute;top:8px;right:10px;font-size:12px;color:var(--ink-dim);opacity:0;transition:opacity .15s;pointer-events:none}.stat-card.is-clickable:hover:after,.stat-card.is-clickable:focus-visible:after{opacity:1}.section-head{display:flex;align-items:baseline;justify-content:space-between;padding:0 var(--sp-3);margin-bottom:var(--sp-4)}.section-head h2{font-size:var(--fs-h2);font-weight:var(--fw-semi);letter-spacing:-.025em}.section-head .meta{font-size:var(--fs-sm);color:var(--ink-mute);font-weight:var(--fw-medium)}.persona-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--sp-4)}@media(min-width:1280px){.persona-grid{grid-template-columns:repeat(3,1fr)}}.trader-card{padding:var(--sp-5);display:flex;flex-direction:column;gap:var(--sp-3);cursor:pointer;transition:var(--tx-fast);border:1px solid var(--glass-line);text-align:left;font:inherit;width:100%;background:var(--glass-2)}.trader-card:hover{transform:translateY(-2px);box-shadow:var(--shadow);border-color:var(--ink-faint)}.trader-card:focus-visible{outline:2px solid var(--persona-color, var(--accent));outline-offset:2px}.trader-card .head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);padding-bottom:var(--sp-3);border-bottom:1px solid var(--glass-line)}.trader-card .name-row{display:flex;align-items:center;gap:8px;min-width:0}.trader-card .name-row:before{content:"";width:8px;height:8px;border-radius:50%;background:var(--persona-color, var(--accent));flex-shrink:0}.trader-card .name{font-size:var(--fs-h2);font-weight:var(--fw-semi);letter-spacing:-.02em;color:var(--ink-900)}.trader-card .ver{font-family:var(--font-mono);font-size:var(--fs-tiny);color:var(--ink-dim)}.trader-card .display-name{font-size:var(--fs-sm);color:var(--ink-mute);font-weight:var(--fw-medium);line-height:1.4}.trader-card .style-chips{display:flex;flex-wrap:wrap;gap:4px}.trader-card .style-chip{font-size:var(--fs-tiny);color:var(--ink-700);background:#fff;border:1px solid var(--glass-line);padding:2px 8px;border-radius:var(--r-pill);font-weight:var(--fw-medium)}.trader-card .stats{display:flex;flex-wrap:wrap;gap:4px var(--sp-3);align-items:baseline;padding-top:var(--sp-3);margin-top:auto;border-top:1px solid var(--glass-line);font-size:var(--fs-sm);color:var(--ink-700)}.trader-card .stats .sep{color:var(--ink-faint)}.trader-card .stats .stat-k{color:var(--ink-mute);font-size:var(--fs-xs)}.trader-card .stats .stat-v{color:var(--ink-900);font-weight:var(--fw-semi);font-variant-numeric:tabular-nums}.trader-card .stats .stat-v.sm{font-weight:var(--fw-medium);color:var(--ink-700);font-size:var(--fs-xs)}.verdict-pill{font-size:var(--fs-tiny);font-weight:var(--fw-semi);padding:4px 10px;border-radius:var(--r-pill);letter-spacing:.02em;display:inline-block;white-space:nowrap}.verdict-pill.hold{background:#94a3b82e;color:var(--ink-mute)}.verdict-pill.buy{background:var(--gain-soft);color:var(--gain)}.verdict-pill.sell{background:var(--loss-soft);color:var(--loss)}.verdict-pill.skip{background:var(--accent-soft);color:var(--accent)}.diary{background:#0f172906;border:1px solid var(--glass-line);border-radius:var(--r-2xl);padding:var(--sp-6);position:relative}.diary .head{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-4)}.diary .avatar{width:40px;height:40px;border-radius:14px;background:var(--accent-grad);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:var(--fw-semi);font-size:var(--fs-body)}.diary .who{font-weight:var(--fw-semi);font-size:var(--fs-body)}.diary .when{font-size:var(--fs-xs);color:var(--ink-mute)}.diary .body{font-size:var(--fs-lg);line-height:1.75;color:var(--ink-800);white-space:pre-wrap}.diary .body.empty{color:var(--ink-mute);font-style:italic}.sched{border-radius:var(--r-2xl);overflow:hidden}.sched .row{display:grid;grid-template-columns:110px 1fr 100px;gap:var(--sp-4);padding:var(--sp-4) var(--sp-5);border-bottom:1px solid var(--glass-line);align-items:center}.sched .row:last-child{border-bottom:0}.sched .when{font-family:var(--font-mono);font-size:var(--fs-sm);font-weight:var(--fw-semi);color:var(--accent)}.sched .what{font-size:var(--fs-body);color:var(--ink-900)}.sched .type{font-size:var(--fs-tiny);padding:4px 10px;border-radius:var(--r-pill);background:#0f17290f;color:var(--ink-mute);font-weight:var(--fw-medium);text-align:center;justify-self:end}.btn{padding:12px var(--sp-5);border-radius:var(--r-md);border:1px solid var(--glass-border);background:var(--glass-2);color:var(--ink-900);font-size:var(--fs-sm);font-weight:var(--fw-semi);display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur);box-shadow:var(--shadow-sm);transition:var(--tx)}.btn:hover{transform:translateY(-1px);box-shadow:var(--shadow);border-color:var(--ink-faint)}.btn:disabled{opacity:.5;cursor:not-allowed;transform:none}.btn.primary{background:var(--ink-900);color:#fff;border-color:var(--ink-900)}.btn.primary:hover{background:var(--accent);border-color:var(--accent)}.btn.danger{background:var(--loss-soft);color:var(--loss);border-color:#ef444433}.btn.danger:hover{background:var(--loss-tint);border-color:#ef444466}.btn.ghost{background:transparent;border-color:var(--glass-line);box-shadow:none;color:var(--ink-mute)}.btn.ghost:hover{color:var(--ink-900);background:var(--glass)}.btn.full{width:100%}.btn.lg{padding:14px var(--sp-6);font-size:var(--fs-body);border-radius:var(--r-xl)}.btn.sm{padding:6px 12px;font-size:var(--fs-xs);border-radius:var(--r-sm)}.btn-row{display:flex;gap:var(--sp-3)}.btn-row .btn{flex:1}.field{display:flex;flex-direction:column;gap:var(--sp-2);margin-bottom:var(--sp-5)}.field:last-child{margin-bottom:0}.field-label{font-size:var(--fs-sm);font-weight:var(--fw-semi);color:var(--ink-700);letter-spacing:-.005em}.field-hint{font-size:var(--fs-xs);color:var(--ink-mute);line-height:1.5}.field input[type=text],.field input[type=number],.field input[type=password],.field select,.field textarea{padding:12px var(--sp-4);border-radius:var(--r-md);border:1px solid var(--glass-line);background:var(--glass-3);font-size:var(--fs-body);width:100%;outline:none;transition:var(--tx-fast);line-height:1.5}.field input:hover,.field select:hover,.field textarea:hover{border-color:var(--ink-faint)}.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);background:#fff}.field input:disabled,.field select:disabled,.field textarea:disabled{background:var(--glass);color:var(--ink-dim);cursor:not-allowed;border-color:var(--glass-line)}.field-row{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4)}.field-group{background:var(--glass);border:1px solid var(--glass-line);border-radius:var(--r-lg);padding:var(--sp-5);margin-bottom:var(--sp-5)}.field-group:last-child{margin-bottom:0}.field-group .group-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--sp-4)}.field-group .group-title{font-size:var(--fs-sm);font-weight:var(--fw-semi);color:var(--ink-700);letter-spacing:.02em;text-transform:uppercase}.field-group .group-meta{font-size:var(--fs-tiny);color:var(--ink-mute)}.toggle{position:relative;display:inline-block;width:48px;height:28px;flex-shrink:0}.toggle input{opacity:0;width:0;height:0}.toggle .slider{position:absolute;top:0;right:0;bottom:0;left:0;background:#0f172926;border-radius:var(--r-pill);transition:var(--tx);cursor:pointer}.toggle .slider:before{content:"";position:absolute;width:22px;height:22px;left:3px;top:3px;background:#fff;border-radius:50%;box-shadow:0 2px 4px #0f172933;transition:var(--tx)}.toggle input:checked+.slider{background:var(--gain)}.toggle input:checked+.slider:before{transform:translate(20px)}.toggle.danger input:checked+.slider{background:var(--loss)}.toggle-row{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);padding:var(--sp-4) var(--sp-5);background:var(--glass);border:1px solid var(--glass-line);border-radius:var(--r-lg)}.toggle-row .label{font-size:var(--fs-body);font-weight:var(--fw-medium);color:var(--ink-900)}.toggle-row .label-meta{font-size:var(--fs-xs);color:var(--ink-mute);margin-top:2px;font-weight:var(--fw-regular)}.setup-grid{display:grid;grid-template-columns:240px 1fr;gap:var(--sp-5)}.setup-nav{padding:var(--sp-3);display:flex;flex-direction:column;gap:6px;align-self:start;position:sticky;top:110px}.setup-nav button{text-align:left;padding:var(--sp-3) var(--sp-4);border-radius:var(--r-md);font-size:var(--fs-sm);color:var(--ink-mute);font-weight:var(--fw-medium);display:flex;align-items:center;gap:var(--sp-3);transition:var(--tx-fast);position:relative}.setup-nav button:hover{background:#ffffff80;color:var(--ink-900)}.setup-nav button.is-active{background:var(--ink-900);color:#fff}.setup-nav button.is-active .nav-meta{color:#ffffffb3}.setup-nav button .nav-icon{font-size:18px;width:24px;text-align:center;flex-shrink:0}.setup-nav button .nav-text{display:flex;flex-direction:column;gap:2px;flex:1}.setup-nav button .nav-meta{font-size:var(--fs-tiny);color:var(--ink-dim);font-weight:var(--fw-regular)}.setup-section{padding:var(--sp-6) var(--sp-6) 0;display:flex;flex-direction:column}.setup-section h2{font-size:var(--fs-h2);font-weight:var(--fw-semi);letter-spacing:-.025em;margin-bottom:var(--sp-3)}.setup-section .lead{font-size:var(--fs-sm);color:var(--ink-mute);margin-bottom:var(--sp-7);line-height:1.6;max-width:60ch}.setup-form{max-width:640px;width:100%;margin:0 auto;padding-bottom:var(--sp-6)}.save-bar{position:sticky;bottom:0;margin:0 calc(var(--sp-6) * -1);padding:var(--sp-4) var(--sp-6);background:linear-gradient(180deg,transparent 0%,rgba(255,255,255,.85) 30%,var(--glass-3) 100%);backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur);border-top:1px solid var(--glass-line);display:flex;gap:var(--sp-3);align-items:center;z-index:5;border-radius:0 0 var(--r-3xl) var(--r-3xl)}.save-bar .spacer{flex:1}.setup-section .banner{position:sticky;top:110px;z-index:4;margin-bottom:var(--sp-5);box-shadow:var(--shadow)}.banner{padding:var(--sp-4) var(--sp-5);border-radius:var(--r-xl);display:flex;align-items:center;gap:var(--sp-3);font-size:var(--fs-sm)}.banner.success{background:var(--gain-soft);color:var(--gain)}.banner.warn{background:var(--warn-soft);color:var(--warn)}.banner.danger{background:var(--loss-soft);color:var(--loss)}.banner.info{background:var(--accent-soft);color:var(--accent)}.empty{padding:var(--sp-8);text-align:center;color:var(--ink-mute);font-size:var(--fs-sm)}.journal-grid{display:grid;grid-template-columns:380px 1fr;gap:var(--sp-4);align-items:start;max-width:1100px}.journal-list{display:flex;flex-direction:column;gap:6px;padding:var(--sp-3)}.pagination{display:flex;align-items:center;justify-content:space-between;padding:var(--sp-3) var(--sp-4);margin-top:var(--sp-2);border-top:1px solid var(--glass-line);font-size:var(--fs-xs);color:var(--ink-mute)}.pagination .pages{display:flex;gap:4px;align-items:center}.pagination .page-btn{padding:6px 10px;border-radius:var(--r-sm);border:1px solid transparent;background:transparent;color:var(--ink-mute);font-size:var(--fs-xs);font-weight:var(--fw-medium);cursor:pointer;transition:var(--tx-fast);min-width:28px}.pagination .page-btn:hover:not(:disabled){background:var(--glass);color:var(--ink-900)}.pagination .page-btn:disabled{opacity:.35;cursor:not-allowed}.pagination .page-num{font-family:var(--font-mono);font-size:var(--fs-xs);color:var(--ink-mute);padding:0 var(--sp-2)}.pagination .page-num strong{color:var(--ink-900);font-weight:var(--fw-semi)}.journal-list .item{padding:var(--sp-3) var(--sp-4);border-radius:var(--r-md);border:1px solid transparent;background:var(--glass);cursor:pointer;display:flex;flex-direction:column;gap:4px;transition:var(--tx-fast);text-align:left;width:100%}.journal-list .item:hover{background:var(--glass-2);border-color:var(--glass-line)}.journal-list .item.is-active{background:var(--ink-900);color:#fff;border-color:var(--ink-900)}.journal-list .item.is-active .ev-meta{color:#ffffffb3}.journal-list .item.is-active .ev-summary{color:#fff}.journal-list .item.is-active .ev-time{color:#ffffffb3}.journal-list .item .ev-row{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-2)}.journal-list .item .ev-time{font-family:var(--font-mono);font-size:var(--fs-tiny);color:var(--ink-mute)}.journal-list .item .ev-summary{font-size:var(--fs-sm);color:var(--ink-900);line-height:1.4}.journal-list .item .ev-meta{font-size:var(--fs-tiny);color:var(--ink-dim)}.journal-detail{padding:var(--sp-5) var(--sp-6)}.journal-detail h3{font-size:var(--fs-h2);font-weight:var(--fw-semi);margin-bottom:var(--sp-3);letter-spacing:-.025em}.journal-detail .reasoning{font-size:var(--fs-body);line-height:1.7;color:var(--ink-800);white-space:pre-wrap;background:var(--glass);border:1px solid var(--glass-line);padding:var(--sp-4) var(--sp-5);border-radius:var(--r-md);margin-bottom:var(--sp-4)}.journal-detail .reasoning.markdown{white-space:normal}.journal-detail .reasoning.markdown>*:first-child{margin-top:0}.journal-detail .reasoning.markdown>*:last-child{margin-bottom:0}.journal-detail .reasoning.markdown h1,.journal-detail .reasoning.markdown h2,.journal-detail .reasoning.markdown h3,.journal-detail .reasoning.markdown h4{font-weight:var(--fw-semi);letter-spacing:-.02em;color:var(--ink-900);margin:var(--sp-5) 0 var(--sp-3);line-height:1.3}.journal-detail .reasoning.markdown h1{font-size:var(--fs-h2)}.journal-detail .reasoning.markdown h2{font-size:calc(var(--fs-h3) * 1.05)}.journal-detail .reasoning.markdown h3{font-size:var(--fs-h3)}.journal-detail .reasoning.markdown h4{font-size:var(--fs-body-lg)}.journal-detail .reasoning.markdown p{margin:0 0 var(--sp-3)}.journal-detail .reasoning.markdown strong{font-weight:var(--fw-semi);color:var(--ink-900)}.journal-detail .reasoning.markdown em{font-style:italic;color:var(--ink-700)}.journal-detail .reasoning.markdown ul,.journal-detail .reasoning.markdown ol{margin:0 0 var(--sp-3);padding-left:var(--sp-5)}.journal-detail .reasoning.markdown li{margin-bottom:var(--sp-2)}.journal-detail .reasoning.markdown li>p{margin-bottom:var(--sp-1)}.journal-detail .reasoning.markdown a{color:var(--accent);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px}.journal-detail .reasoning.markdown code{font-family:var(--font-mono);font-size:.9em;background:var(--glass-strong, rgba(0,0,0,.05));padding:.1em .35em;border-radius:var(--r-sm);color:var(--ink-900)}.journal-detail .reasoning.markdown pre{font-family:var(--font-mono);font-size:var(--fs-sm);background:var(--glass-strong, rgba(0,0,0,.05));border:1px solid var(--glass-line);border-radius:var(--r-md);padding:var(--sp-3) var(--sp-4);margin:0 0 var(--sp-3);overflow-x:auto;line-height:1.55}.journal-detail .reasoning.markdown pre code{background:transparent;padding:0;border-radius:0}.journal-detail .reasoning.markdown blockquote{margin:0 0 var(--sp-3);padding:var(--sp-2) var(--sp-4);border-left:3px solid var(--accent);background:var(--glass);border-radius:0 var(--r-sm) var(--r-sm) 0;color:var(--ink-700)}.journal-detail .reasoning.markdown hr{border:0;border-top:1px solid var(--glass-line);margin:var(--sp-4) 0}.journal-detail .reasoning.markdown table{width:100%;border-collapse:collapse;margin:0 0 var(--sp-4);font-size:var(--fs-sm);font-variant-numeric:tabular-nums;display:block;overflow-x:auto}.journal-detail .reasoning.markdown thead{background:var(--glass);border-bottom:2px solid var(--glass-line)}.journal-detail .reasoning.markdown th,.journal-detail .reasoning.markdown td{text-align:left;padding:var(--sp-2) var(--sp-3);border-bottom:1px solid var(--glass-line);vertical-align:top}.journal-detail .reasoning.markdown th{font-weight:var(--fw-semi);color:var(--ink-900);white-space:nowrap}.journal-detail .reasoning.markdown tbody tr:hover{background:var(--glass)}.journal-detail .reasoning.markdown tbody tr:last-child td{border-bottom:0}.kv-list{display:grid;grid-template-columns:max-content 1fr;gap:var(--sp-2) var(--sp-4);font-size:var(--fs-sm)}.kv-list dt{color:var(--ink-mute);font-weight:var(--fw-medium);white-space:nowrap}.kv-list dd{color:var(--ink-900);font-weight:var(--fw-medium);word-break:break-word;min-width:0}.filter-bar{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap}.filter-bar select,.filter-bar input{padding:8px var(--sp-3);border-radius:var(--r-sm);border:1px solid var(--glass-line);background:var(--glass-2);font-size:var(--fs-sm);outline:none;cursor:pointer;transition:var(--tx-fast)}.filter-bar select:hover,.filter-bar input:hover{border-color:var(--ink-faint);background:var(--glass-3)}.filter-bar select:focus,.filter-bar input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}.alloc-list,.sub-list{display:flex;flex-direction:column;gap:var(--sp-3)}.alloc-row{display:grid;grid-template-columns:100px 1fr 200px auto;gap:var(--sp-4);padding:var(--sp-4) var(--sp-5);border-radius:var(--r-lg);background:var(--glass);border:1px solid var(--glass-line);align-items:center}.alloc-row .slug{font-size:var(--fs-body);font-weight:var(--fw-semi)}.alloc-row .name{font-size:var(--fs-sm);color:var(--ink-mute)}.alloc-row .name strong{color:var(--ink-900);font-weight:var(--fw-semi)}.alloc-row input{padding:10px var(--sp-3);border-radius:var(--r-sm);border:1px solid var(--glass-line);background:#fff;font-family:var(--font-mono);text-align:right;font-size:var(--fs-sm)}.alloc-row input:focus{border-color:var(--accent);outline:0;box-shadow:0 0 0 3px var(--accent-soft)}.alloc-row .actions{display:flex;gap:var(--sp-2)}.sub-row{display:grid;grid-template-columns:48px 1fr auto;gap:var(--sp-4);padding:var(--sp-4) var(--sp-5);border-radius:var(--r-lg);background:var(--glass);border:1px solid var(--glass-line);align-items:center}.sub-row .avatar{width:36px;height:36px;border-radius:11px;background:var(--accent-grad);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:var(--fw-semi);font-size:var(--fs-body)}.sub-row .info{display:flex;flex-direction:column;gap:2px;min-width:0}.sub-row .info .name{font-size:var(--fs-body);font-weight:var(--fw-semi);color:var(--ink-900);display:flex;align-items:baseline;gap:var(--sp-2)}.sub-row .info .ver{font-family:var(--font-mono);font-size:var(--fs-tiny);color:var(--ink-dim);font-weight:var(--fw-regular)}.sub-row .info .meta{font-size:var(--fs-xs);color:var(--ink-mute)}.sub-row .status{font-size:var(--fs-tiny);font-weight:var(--fw-semi);padding:4px 10px;border-radius:var(--r-pill);background:var(--gain-soft);color:var(--gain);letter-spacing:.02em}.sub-row .status.idle{background:#94a3b82e;color:var(--ink-mute)}.step-list{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--sp-3)}.step-chip{padding:var(--sp-4);display:flex;flex-direction:column;gap:6px}.step-chip .icon{width:28px;height:28px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:var(--fs-sm);font-weight:var(--fw-bold)}.step-chip .icon.is-ok{background:var(--gain-soft);color:var(--gain)}.step-chip .icon.is-fail{background:var(--loss-soft);color:var(--loss)}.step-chip .label{font-size:var(--fs-sm);font-weight:var(--fw-semi);color:var(--ink-900)}.step-chip .detail{font-size:var(--fs-tiny);color:var(--ink-mute);line-height:1.4}.disclaimer{margin-top:var(--sp-5);padding:var(--sp-4) var(--sp-5);font-size:var(--fs-tiny);color:var(--ink-mute);line-height:1.7;text-align:center}.dialog-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#0f172966;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:100;display:flex;align-items:center;justify-content:center;padding:var(--sp-4)}.dialog{background:var(--glass-3);border:1px solid var(--glass-border);border-radius:var(--r-3xl);padding:var(--sp-7);max-width:800px;width:100%;max-height:80vh;overflow-y:auto;backdrop-filter:var(--blur-lg);-webkit-backdrop-filter:var(--blur-lg);box-shadow:var(--shadow-lg);position:relative}.dialog .close{position:absolute;top:var(--sp-4);right:var(--sp-4);width:32px;height:32px;border-radius:50%;background:var(--glass-2);display:flex;align-items:center;justify-content:center;font-size:18px;color:var(--ink-mute)}.dialog .close:hover{color:var(--ink-900);background:#fff}.metric-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3);background:#0f172908;border-radius:var(--r-lg);padding:var(--sp-4);margin-bottom:var(--sp-4)}.metric-grid .item{display:flex;justify-content:space-between;font-size:var(--fs-sm);padding:var(--sp-2) 0;border-bottom:1px solid var(--glass-line)}.metric-grid .item:nth-last-child(-n+2){border-bottom:0}.metric-grid .item .k{color:var(--ink-mute)}.metric-grid .item .v{color:var(--ink-900);font-weight:var(--fw-semi)}.dialog-section{margin-bottom:var(--sp-5)}.dialog-section+.dialog-section{padding-top:var(--sp-4);border-top:1px solid var(--glass-line)}.dialog-section h3{font-size:var(--fs-h3);font-weight:var(--fw-semi);margin-bottom:var(--sp-3);letter-spacing:-.02em}.dialog-section .sub{font-size:var(--fs-sm);color:var(--ink-mute);margin-bottom:var(--sp-3)}.persona-chip{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-sm);font-weight:var(--fw-medium);color:var(--ink-800)}.persona-chip .dot{width:8px;height:8px;border-radius:50%;background:var(--persona-color, var(--persona-unknown));box-shadow:0 0 0 2px var(--persona-color-soft, transparent)}.bar-row{display:grid;grid-template-columns:90px 1fr 70px;gap:var(--sp-3);align-items:center;padding:var(--sp-2) 0}.bar-row .bar-label{font-size:var(--fs-sm);color:var(--ink-700);font-weight:var(--fw-medium);display:flex;align-items:center;gap:6px;min-width:0}.bar-row .bar-label .dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.bar-row .bar-label .name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bar-row .bar-track{height:8px;background:var(--glass);border-radius:var(--r-pill);overflow:hidden;position:relative}.bar-row .bar-fill{height:100%;border-radius:var(--r-pill);transition:width .3s ease;background:var(--bar-color, var(--accent))}.bar-row .bar-value{text-align:right;font-size:var(--fs-sm);color:var(--ink-900);font-weight:var(--fw-semi);font-variant-numeric:tabular-nums}.mini-chart{background:var(--glass);border:1px solid var(--glass-line);border-radius:var(--r-md);padding:var(--sp-4);margin-bottom:var(--sp-3)}.mini-chart svg{width:100%;height:auto;display:block}.mini-chart .axis{fill:var(--ink-dim);font-size:10px;font-family:var(--font-mono)}.watcher-group{margin-bottom:var(--sp-4)}.watcher-group .group-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--sp-2)}.watcher-group .count{font-size:var(--fs-xs);color:var(--ink-mute);font-weight:var(--fw-medium)}.watcher-row{display:grid;grid-template-columns:1fr auto;gap:var(--sp-3);padding:var(--sp-3);background:var(--glass);border:1px solid var(--glass-line);border-radius:var(--r-sm);margin-bottom:6px;align-items:center}.watcher-row .intent{font-size:var(--fs-sm);color:var(--ink-900);font-weight:var(--fw-medium);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.watcher-row .symbol{font-family:var(--font-mono);font-size:var(--fs-xs);color:var(--ink-mute);margin-top:2px}.watcher-row .status{font-size:var(--fs-xs);font-weight:var(--fw-medium);padding:2px 8px;border-radius:var(--r-pill);background:var(--gain-soft);color:var(--gain)}.watcher-row .status.expired{background:var(--glass);color:var(--ink-dim)}.watcher-row .status.triggered{background:var(--accent-soft);color:var(--accent)}.watcher-row .status.revoked{background:var(--loss-soft);color:var(--loss)}.matrix-table{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--fs-sm)}.matrix-table th,.matrix-table td{padding:var(--sp-2) var(--sp-3);text-align:right;font-variant-numeric:tabular-nums}.matrix-table thead th{font-weight:var(--fw-medium);color:var(--ink-mute);font-size:var(--fs-xs);border-bottom:1px solid var(--glass-line)}.matrix-table tbody td{color:var(--ink-800);border-bottom:1px solid var(--glass-line)}.matrix-table tbody tr:last-child td{border-bottom:0}.matrix-table .row-head{text-align:left;font-weight:var(--fw-medium);color:var(--ink-900)}.matrix-table .total{font-weight:var(--fw-semi);color:var(--ink-900)}.matrix-table .zero{color:var(--ink-faint)}.dialog.trader-detail{background:#fff}.trader-detail .detail-head{margin-bottom:var(--sp-5);display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-4)}.trader-detail .detail-title{min-width:0}.trader-detail .detail-title h2{font-size:var(--fs-h1);font-weight:var(--fw-bold);letter-spacing:-.02em;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}.trader-detail .detail-title h2 .ver{font-family:var(--font-mono);font-size:var(--fs-sm);color:var(--ink-dim);font-weight:var(--fw-regular)}.trader-detail .detail-title .tagline{color:var(--ink-mute);font-size:var(--fs-sm);font-style:italic;margin-top:4px;line-height:1.4}.trader-detail .detail-title .funnel{margin-top:6px;font-size:var(--fs-xs);color:var(--ink-dim);font-variant-numeric:tabular-nums}.trader-detail .detail-title .funnel .arrow{color:var(--ink-faint);margin:0 4px}.trader-detail .candidate-bar{position:sticky;top:calc(var(--sp-7) * -1);margin:0 calc(var(--sp-7) * -1);padding:var(--sp-3) var(--sp-7);background:transparent;border-bottom:1px solid var(--glass-line);z-index:1;display:flex;flex-direction:row;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-4)}.trader-detail .candidate-bar .filter-bar{flex:1;min-width:0}.trader-detail .candidate-bar .pager{flex-shrink:0;display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-xs);color:var(--ink-mute)}.trader-detail .candidate-bar .pager .count{font-variant-numeric:tabular-nums;white-space:nowrap}.trader-detail .candidate-bar:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;background:#fff;z-index:-1}.trader-detail .cand-head{margin-bottom:var(--sp-4)}.trader-detail .cand-head .row{display:flex;align-items:baseline;gap:var(--sp-3);flex-wrap:wrap;margin-bottom:6px}.trader-detail .cand-head h3{font-size:var(--fs-h2);font-weight:var(--fw-semi);letter-spacing:-.02em}.trader-detail .cand-head .code{font-family:var(--font-mono);font-size:var(--fs-xs);color:var(--ink-mute)}.trader-detail .cand-head .quote{display:flex;gap:var(--sp-4);font-size:var(--fs-sm);flex-wrap:wrap;color:var(--ink-700)}.pattern-chip{display:inline-flex;align-items:center;gap:4px;font-size:var(--fs-xs);font-weight:var(--fw-medium);padding:3px 10px;border-radius:var(--r-pill);background:var(--glass);border:1px solid var(--glass-line);color:var(--ink-700)}.pattern-chip:before{content:"▲";font-size:9px;color:var(--ink-dim)}.metric-group{margin-bottom:var(--sp-4)}.metric-group .group-head{font-size:var(--fs-sm);font-weight:var(--fw-semi);color:var(--ink-700);margin-bottom:6px;padding-left:2px}.metric-group .metric-grid{margin-bottom:0}.watchlist-section{margin-bottom:var(--sp-5)}.watchlist-section.empty{padding:var(--sp-5);background:#0f172906;border-radius:var(--r-md);text-align:center;color:var(--ink-mute);font-size:var(--fs-sm);margin-bottom:var(--sp-5)}.watchlist-section .memory-meta{display:flex;flex-wrap:wrap;gap:var(--sp-3);font-size:var(--fs-xs);color:var(--ink-mute);padding:var(--sp-3) var(--sp-4);background:#0f172906;border-radius:var(--r-md);margin-bottom:var(--sp-4)}.watchlist-section .memory-meta strong{color:var(--ink-700);font-weight:var(--fw-semi)}.dialog-section-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-3);margin-bottom:var(--sp-2);flex-wrap:wrap}.dialog-section-head h3{font-size:var(--fs-h3);font-weight:var(--fw-semi);letter-spacing:-.02em;color:var(--ink-900)}.dialog-section-head .sub{font-size:var(--fs-xs);color:var(--ink-dim)}.empty-line{font-size:var(--fs-sm);color:var(--ink-mute);padding:var(--sp-3) var(--sp-4);background:#0f172905;border-radius:var(--r-sm)}.watchlist-list{display:flex;flex-direction:column;gap:var(--sp-2);margin-bottom:var(--sp-3)}.watchlist-chips{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-bottom:var(--sp-3)}.watchlist-detail{padding:var(--sp-4);background:#0f172908;border-radius:var(--r-md);border-left:3px solid var(--accent);margin-bottom:var(--sp-4)}.watchlist-detail .head{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--sp-2);margin-bottom:6px}.watchlist-detail .head .name{font-weight:var(--fw-semi);color:var(--ink-900);font-size:var(--fs-h3);letter-spacing:-.02em}.watchlist-detail .head .code{font-family:var(--font-mono);font-size:var(--fs-xs);color:var(--ink-mute)}.watchlist-detail .head .pattern{font-size:var(--fs-xs);color:var(--accent);background:var(--accent-soft);padding:2px 8px;border-radius:var(--r-pill);font-weight:var(--fw-medium)}.watchlist-detail .head .trigger{font-family:var(--font-mono);font-size:var(--fs-xs);color:var(--ink-700);font-weight:var(--fw-medium);margin-left:auto}.watchlist-detail .reason{font-size:var(--fs-sm);color:var(--ink-700);line-height:1.6;margin:6px 0 8px}.watchlist-detail .meta{display:flex;flex-wrap:wrap;gap:var(--sp-3);font-size:var(--fs-xs);color:var(--ink-mute);margin-bottom:var(--sp-3)}.watchlist-detail .meta strong{color:var(--ink-700);font-weight:var(--fw-medium)}.watchlist-detail .watchlist-chart{margin-top:var(--sp-3);padding-top:var(--sp-3);border-top:1px dashed var(--glass-line)}.watchlist-row{padding:var(--sp-3) var(--sp-4);background:#0f172908;border-radius:var(--r-md);border-left:3px solid var(--accent);transition:var(--tx-fast)}.watchlist-row.is-selected{background:#6366f10f;border-left-color:var(--accent);box-shadow:0 1px 3px #0f17290a}.watchlist-row-head{background:transparent;border:0;padding:0;margin:0 0 4px;cursor:pointer;width:100%;text-align:left;font:inherit;color:inherit}.watchlist-row-head:hover .name{color:var(--accent)}.watchlist-row-head:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-sm)}.watchlist-row .head{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--sp-2);margin-bottom:4px}.watchlist-row .head .caret{color:var(--ink-dim);font-size:10px;width:10px;display:inline-block}.watchlist-chart{margin-top:var(--sp-3);padding-top:var(--sp-3);border-top:1px dashed var(--glass-line)}.watchlist-row .head .name{font-weight:var(--fw-semi);color:var(--ink-900);font-size:var(--fs-body)}.watchlist-row .head .code{font-family:var(--font-mono);font-size:var(--fs-xs);color:var(--ink-mute)}.watchlist-row .head .pattern{font-size:var(--fs-xs);color:var(--accent);background:var(--accent-soft);padding:2px 8px;border-radius:var(--r-pill);font-weight:var(--fw-medium)}.watchlist-row .head .trigger{font-family:var(--font-mono);font-size:var(--fs-xs);color:var(--ink-700);font-weight:var(--fw-medium);margin-left:auto}.watchlist-row .reason{font-size:var(--fs-sm);color:var(--ink-700);line-height:1.5;margin:4px 0 6px}.watchlist-row .meta{display:flex;flex-wrap:wrap;gap:var(--sp-3);font-size:var(--fs-xs);color:var(--ink-mute)}.watchlist-row .meta strong{color:var(--ink-700);font-weight:var(--fw-medium)}.market-view{font-size:var(--fs-sm);color:var(--ink-700);line-height:1.6;white-space:pre-wrap;padding:var(--sp-4);background:#0f172906;border-radius:var(--r-md);margin-bottom:var(--sp-3)}.candle-chart{background:#0f172906;border:1px solid var(--glass-line);border-radius:var(--r-md);padding:var(--sp-3) var(--sp-3) var(--sp-2);margin-bottom:var(--sp-4)}.candle-chart svg{width:100%;height:auto;display:block}.candle-chart .axis{fill:var(--ink-dim);font-size:10px;font-family:var(--font-mono)}.candle-chart .legend{display:flex;align-items:center;gap:var(--sp-3);margin-top:6px;font-size:var(--fs-xs);color:var(--ink-mute);flex-wrap:wrap}.candle-chart .legend .item{display:inline-flex;align-items:center;gap:4px}.candle-chart .legend .swatch{display:inline-block;width:10px;height:10px;border-radius:2px}.candle-chart .legend .swatch.ma5{background:#f59e0b;height:2px;border-radius:999px;width:14px}.candle-chart .legend .swatch.ma20{background:var(--ink-mute);height:2px;border-radius:999px;width:14px}.candle-chart .legend .swatch.up{background:var(--gain)}.candle-chart .legend .swatch.down{background:var(--loss)}.candle-chart .legend .swatch.decision-line{background:transparent;border-top:2px dashed var(--accent);width:14px;height:0;border-radius:0;align-self:center}.candle-chart .data-caption{margin-top:4px;font-size:var(--fs-xs);color:var(--ink-mute);font-variant-numeric:tabular-nums;line-height:1.4}.candle-chart .data-caption strong{color:var(--ink-700);font-weight:var(--fw-semi)}.candle-chart .legend .spacer{flex:1}.candle-chart .legend .meta{font-variant-numeric:tabular-nums}.candle-chart.loading,.candle-chart.empty{min-height:80px;display:flex;align-items:center;justify-content:center}.candle-chart .msg{font-size:var(--fs-sm);color:var(--ink-mute)}.reasons-toggle{margin-top:var(--sp-3);border:1px solid var(--glass-line);background:var(--glass);border-radius:var(--r-md);padding:0;transition:var(--tx-fast)}.reasons-toggle[open]{border-color:var(--ink-faint);background:#0f172906}.reasons-toggle>summary{cursor:pointer;list-style:none;padding:var(--sp-3) var(--sp-4);font-size:var(--fs-sm);color:var(--ink-mute);font-weight:var(--fw-medium);display:flex;align-items:center;gap:6px}.reasons-toggle>summary::-webkit-details-marker{display:none}.reasons-toggle>summary:before{content:"▸";font-size:10px;color:var(--ink-dim);transition:transform .15s}.reasons-toggle[open]>summary:before{transform:rotate(90deg)}.reasons-toggle[open]>summary{color:var(--ink-700)}.reasons-toggle .reasons-list{padding:0 var(--sp-4) var(--sp-4) var(--sp-7);margin:0;font-size:var(--fs-sm);color:var(--ink-700);line-height:1.6}.mode-badge{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-xs);font-weight:var(--fw-semi);padding:4px 10px;border-radius:var(--r-pill);letter-spacing:.02em}.mode-badge .dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.mode-badge.live{background:var(--loss-soft);color:var(--loss)}.mode-badge.live .dot{background:var(--loss);box-shadow:0 0 0 3px var(--loss-soft);animation:pulse 2s ease-in-out infinite}.mode-badge.paper{background:var(--glass);color:var(--ink-700);border:1px solid var(--glass-line)}.mode-badge.paper .dot{background:var(--ink-mute)}.mode-badge.halted{background:#94a3b82e;color:var(--ink-mute)}.mode-badge.halted .dot{background:var(--ink-mute)}@keyframes pulse{0%,to{opacity:1}50%{opacity:.4}}.toast-stack{position:fixed;right:var(--sp-5);bottom:var(--sp-5);z-index:200;display:flex;flex-direction:column;gap:var(--sp-3);pointer-events:none;max-width:380px}.toast{pointer-events:auto;background:var(--glass-3);backdrop-filter:var(--blur-lg);-webkit-backdrop-filter:var(--blur-lg);border:1px solid var(--glass-border);border-radius:var(--r-lg);padding:var(--sp-4) var(--sp-5);box-shadow:var(--shadow-lg);display:grid;grid-template-columns:28px 1fr auto;gap:var(--sp-3);align-items:start;animation:toast-in .25s ease-out}.toast.is-leaving{animation:toast-out .2s ease-in forwards}.toast .icon{width:28px;height:28px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:14px;flex-shrink:0}.toast.success .icon{background:var(--gain-soft);color:var(--gain)}.toast.danger .icon{background:var(--loss-soft);color:var(--loss)}.toast.warn .icon{background:var(--warn-soft);color:var(--warn)}.toast.info .icon{background:var(--accent-soft);color:var(--accent)}.toast .body{min-width:0}.toast .title{font-size:var(--fs-sm);font-weight:var(--fw-semi);color:var(--ink-900);line-height:1.3}.toast .desc{font-size:var(--fs-xs);color:var(--ink-mute);margin-top:2px;line-height:1.4}.toast .close{background:transparent;border:none;color:var(--ink-dim);cursor:pointer;font-size:18px;padding:0 4px;line-height:1}.toast .close:hover{color:var(--ink-900)}@keyframes toast-in{0%{transform:translateY(8px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes toast-out{to{transform:translateY(8px);opacity:0}}.dialog-backdrop.is-confirm{z-index:300}.confirm-panel{max-width:600px;width:100%}.confirm-panel .alert-icon{width:56px;height:56px;border-radius:50%;background:var(--loss-soft);color:var(--loss);display:flex;align-items:center;justify-content:center;font-size:28px;margin-bottom:var(--sp-4)}.confirm-panel h2{font-size:var(--fs-h2);font-weight:var(--fw-bold);letter-spacing:-.02em;margin-bottom:var(--sp-3)}.confirm-panel .desc{font-size:var(--fs-body);color:var(--ink-700);line-height:1.6;margin-bottom:var(--sp-4)}.confirm-panel ul{background:var(--loss-soft);border-radius:var(--r-md);padding:var(--sp-4) var(--sp-5);margin-bottom:var(--sp-5);list-style:none}.confirm-panel ul li{font-size:var(--fs-sm);color:var(--loss);padding:4px 0;display:flex;gap:8px}.confirm-panel ul li:before{content:"•";flex-shrink:0;font-weight:700}.confirm-panel .actions{display:flex;gap:var(--sp-3);justify-content:flex-end}.confirm-panel .actions .btn{min-width:100px}.btn.live{background:var(--loss);color:#fff;border-color:var(--loss)}.btn.live:hover:not(:disabled){background:#dc2626;border-color:#dc2626}.dots-loading:after{content:"";display:inline-block;width:12px;text-align:left;animation:dots 1.5s steps(4,end) infinite}@keyframes dots{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}to{content:""}}@media(max-width:1100px){.stat-row{grid-template-columns:repeat(2,1fr)}.persona-grid{grid-template-columns:1fr 1fr}.journal-grid{grid-template-columns:1fr}.journal-detail{position:static}.setup-grid{grid-template-columns:1fr}.setup-nav{position:static;flex-direction:row;flex-wrap:wrap}}@media(max-width:720px){.app-bar{flex-wrap:wrap}.stat-row{grid-template-columns:1fr 1fr}.persona-grid{grid-template-columns:1fr}.step-list{grid-template-columns:1fr 1fr}.alloc-row{grid-template-columns:1fr}}.page-hero{margin:0 0 var(--sp-6);padding:var(--sp-5) var(--sp-3) 0;display:flex;align-items:flex-end;justify-content:space-between;gap:var(--sp-4);flex-wrap:wrap}.page-hero-text{display:flex;flex-direction:column;gap:var(--sp-2);min-width:0}.page-hero-eyebrow{font-size:var(--fs-tiny);font-weight:var(--fw-bold);color:var(--accent);letter-spacing:.18em;text-transform:uppercase;display:inline-flex;align-items:center;gap:var(--sp-2)}.page-hero-eyebrow:before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 4px var(--accent-soft)}.page-hero h1{font-size:var(--fs-h1);font-weight:var(--fw-bold);letter-spacing:-.02em;color:var(--ink-900);line-height:1.15}.page-hero-sub{font-size:var(--fs-sm);color:var(--ink-mute);font-weight:var(--fw-medium)}.page-hero-meta{display:flex;gap:var(--sp-2);flex-wrap:wrap}.page-hero-pill{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:var(--sp-1) var(--sp-3);font-size:var(--fs-tiny);color:var(--ink-mute);display:inline-flex;align-items:center;gap:6px}.page-hero-pill strong{color:var(--ink-900);font-weight:var(--fw-semi)}.section-label{font-size:var(--fs-tiny);font-weight:var(--fw-bold);color:var(--ink-mute);letter-spacing:.16em;text-transform:uppercase;margin-bottom:var(--sp-2);padding:0 var(--sp-3)}.dash-kpi-hero{margin-bottom:var(--sp-5)}.dash-kpi-hero-card{background:linear-gradient(135deg,var(--surface),rgba(99,102,241,.04));border:1px solid var(--border);border-radius:var(--r-xl);padding:var(--sp-6) var(--sp-7);display:flex;align-items:center;gap:var(--sp-6);position:relative;overflow:hidden}.dash-kpi-hero-card:before{content:"";position:absolute;top:0;right:0;bottom:0;width:6px;background:var(--ink-faint);transition:background var(--ease-out) .2s}.dash-kpi-hero-card.is-gain:before{background:var(--gain)}.dash-kpi-hero-card.is-loss:before{background:var(--loss)}.dash-kpi-hero-icon{font-size:36px;flex-shrink:0}.dash-kpi-hero-body{display:flex;flex-direction:column;gap:var(--sp-1);flex:1 1 auto;min-width:0}.dash-kpi-hero-label{font-size:var(--fs-tiny);font-weight:var(--fw-bold);color:var(--ink-mute);letter-spacing:.14em;text-transform:uppercase}.dash-kpi-hero-value{font-size:40px;font-weight:var(--fw-bold);letter-spacing:-.03em;color:var(--ink-900);line-height:1.1;font-variant-numeric:tabular-nums}.dash-kpi-hero-value.is-gain{color:var(--gain)}.dash-kpi-hero-value.is-loss{color:var(--loss)}.dash-kpi-hero-sub{font-size:var(--fs-sm);color:var(--ink-mute)}.dash-kpi-row.is-secondary{grid-template-columns:repeat(3,1fr)}.dash-kpi-row.is-secondary .dash-kpi{padding:var(--sp-4) var(--sp-5)}.dash-kpi-row.is-secondary .dash-kpi-value{font-size:var(--fs-h3)}.empty-card{border:1px dashed var(--border-strong);border-radius:var(--r-xl);padding:var(--sp-6) var(--sp-5);text-align:center;display:flex;flex-direction:column;gap:var(--sp-3);align-items:center;background:var(--surface)}.empty-card-icon{font-size:28px}.empty-card-title{font-size:var(--fs-body);font-weight:var(--fw-semi);color:var(--ink-900)}.empty-card-sub{font-size:var(--fs-sm);color:var(--ink-mute);max-width:480px;line-height:1.55}.empty-card-actions{display:flex;gap:var(--sp-2);flex-wrap:wrap;justify-content:center}section.is-accent{position:relative;background:linear-gradient(135deg,#6366f10d,#ec489908);border-radius:var(--r-xl);padding:var(--sp-5) 0 var(--sp-2);border:1px solid var(--accent-soft);margin:var(--sp-5) 0}section.is-accent .section-head,section.is-accent .section-label{padding-left:var(--sp-5);padding-right:var(--sp-5)}section.is-accent .wake-grid{padding:0 var(--sp-5) var(--sp-3)}.banner.is-compact{padding:var(--sp-2) var(--sp-4);font-size:var(--fs-xs);border-radius:var(--r-md);display:flex;justify-content:space-between;align-items:center;gap:var(--sp-2);margin-bottom:var(--sp-3)}.banner.is-compact strong{font-weight:var(--fw-semi)}@media(max-width:720px){.page-hero{flex-direction:column;align-items:flex-start}.dash-kpi-hero-card{flex-direction:column;align-items:flex-start;gap:var(--sp-3);padding:var(--sp-5)}.dash-kpi-hero-value{font-size:32px}.dash-kpi-row.is-secondary{grid-template-columns:1fr 1fr}}.disclaimer-meta{margin-top:var(--sp-2);display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;opacity:.7}.holdings-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2)}.holding-row{width:100%;display:grid;grid-template-columns:1.4fr 1.4fr .8fr .7fr 24px;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);cursor:pointer;text-align:left;font:inherit;color:var(--ink-900);transition:transform var(--ease-out) .12s,border-color var(--ease-out) .12s,background var(--ease-out) .12s}.holding-row:hover{transform:translateY(-1px);border-color:var(--accent);background:linear-gradient(135deg,var(--surface),var(--accent-soft))}.holding-row:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.holding-row.is-gain{border-left:3px solid var(--gain)}.holding-row.is-loss{border-left:3px solid var(--loss)}.holding-row .hr-name{display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap;min-width:0}.holding-row .hr-name strong{font-weight:var(--fw-semi);font-size:var(--fs-body)}.hr-code{font-family:var(--font-mono);font-size:var(--fs-tiny);color:var(--ink-mute);background:var(--bg);padding:2px var(--sp-2);border-radius:var(--r-sm)}.hr-tag{font-size:var(--fs-tiny);background:var(--accent-soft);color:var(--accent);padding:2px var(--sp-2);border-radius:var(--r-sm);font-weight:var(--fw-semi)}.hr-qty{color:var(--ink-mute);font-size:var(--fs-sm)}.hr-price{font-weight:var(--fw-semi);text-align:right;font-size:var(--fs-body)}.hr-pnl{text-align:right;font-weight:var(--fw-bold);font-size:var(--fs-body)}.hr-pnl.is-gain{color:var(--gain)}.hr-pnl.is-loss{color:var(--loss)}.hr-arrow{color:var(--ink-mute);font-size:var(--fs-sm);text-align:right;transition:transform var(--ease-out) .12s,color var(--ease-out) .12s}.holding-row:hover .hr-arrow{color:var(--accent);transform:translate(2px)}.modal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;background:#0f172a8c;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);display:flex;align-items:center;justify-content:center;padding:var(--sp-4);animation:modalFadeIn .16s var(--ease-out)}@keyframes modalFadeIn{0%{opacity:0}to{opacity:1}}.modal-dialog{background:var(--bg);border-radius:var(--r-xl);box-shadow:0 24px 60px #00000040;width:100%;max-width:720px;max-height:calc(100vh - var(--sp-8));display:flex;flex-direction:column;overflow:hidden;animation:modalSlideIn .18s var(--ease-out);outline:none}.modal-dialog.is-wide{max-width:880px}@keyframes modalSlideIn{0%{opacity:0;transform:translateY(6px) scale(.99)}to{opacity:1;transform:translateY(0) scale(1)}}.modal-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);padding:var(--sp-4) var(--sp-5);border-bottom:1px solid var(--border);flex-shrink:0}.modal-title{font-size:var(--fs-lg);font-weight:var(--fw-semi);color:var(--ink-900)}.modal-title .symbol-code{font-family:var(--font-mono);font-size:var(--fs-sm);color:var(--ink-mute);margin-left:var(--sp-1);background:var(--surface);padding:2px var(--sp-2);border-radius:var(--r-sm)}.modal-head-actions{display:flex;align-items:center;gap:var(--sp-2)}.modal-close{width:32px;height:32px;border:none;background:var(--surface);border-radius:var(--r-md);cursor:pointer;font-size:var(--fs-lg);color:var(--ink-mute);display:flex;align-items:center;justify-content:center;transition:background var(--ease-out) .12s,color var(--ease-out) .12s}.modal-close:hover{background:var(--loss-soft);color:var(--loss)}.modal-body{padding:var(--sp-5);overflow-y:auto}.holding-modal-kpi{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-3);margin-bottom:var(--sp-5)}.holding-modal-kpi .kpi-cell{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:var(--sp-3) var(--sp-4);display:flex;flex-direction:column;gap:2px}.holding-modal-kpi .kpi-cell.is-gain{border-color:var(--gain)}.holding-modal-kpi .kpi-cell.is-loss{border-color:var(--loss)}.holding-modal-kpi .kpi-cell .k{font-size:var(--fs-tiny);color:var(--ink-mute);font-weight:var(--fw-semi);text-transform:uppercase;letter-spacing:.08em}.holding-modal-kpi .kpi-cell .v{font-size:var(--fs-h3);font-weight:var(--fw-bold);letter-spacing:-.02em;color:var(--ink-900)}.holding-modal-kpi .kpi-cell.is-gain .v{color:var(--gain)}.holding-modal-kpi .kpi-cell.is-loss .v{color:var(--loss)}.holding-modal-kpi .kpi-cell .sub{font-size:var(--fs-tiny);color:var(--ink-mute)}.strategy-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:var(--sp-4) var(--sp-5);display:flex;flex-direction:column;gap:var(--sp-3)}.strategy-row{display:flex;gap:var(--sp-3);align-items:baseline;font-size:var(--fs-sm)}.strategy-row .k{min-width:80px;color:var(--ink-mute);font-weight:var(--fw-semi);font-size:var(--fs-tiny);text-transform:uppercase;letter-spacing:.06em}.strategy-row .v{color:var(--ink-900);font-weight:var(--fw-medium)}.strategy-rationale{display:flex;flex-direction:column;gap:var(--sp-2);padding-top:var(--sp-2);border-top:1px dashed var(--border)}.strategy-rationale .k{color:var(--ink-mute);font-weight:var(--fw-semi);font-size:var(--fs-tiny);text-transform:uppercase;letter-spacing:.06em}.strategy-rationale p{color:var(--ink-900);font-size:var(--fs-sm);line-height:1.6;margin:0}.strategy-empty{font-size:var(--fs-sm);color:var(--ink-mute);background:var(--surface);border:1px dashed var(--border-strong);border-radius:var(--r-md);padding:var(--sp-4);text-align:center}.watcher-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2)}.watcher-row{display:grid;grid-template-columns:64px 1fr auto;gap:var(--sp-3);align-items:center;padding:var(--sp-3) var(--sp-4);background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md)}.watcher-row .watcher-type{text-align:center;font-size:var(--fs-tiny);font-weight:var(--fw-bold);padding:2px var(--sp-2);border-radius:var(--r-sm)}.watcher-row .watcher-body{display:flex;flex-direction:column;gap:2px;min-width:0}.watcher-row .watcher-intent{font-size:var(--fs-sm);color:var(--ink-900);font-weight:var(--fw-medium)}.watcher-row .watcher-detail{font-size:var(--fs-tiny);color:var(--ink-mute)}.watcher-row .watcher-id{font-family:var(--font-mono);font-size:var(--fs-tiny);color:var(--ink-dim);background:var(--bg);padding:2px var(--sp-2);border-radius:var(--r-sm)}@media(max-width:720px){.holding-row{grid-template-columns:1fr .6fr 24px;grid-template-areas:"name pnl arrow" "qty price arrow";row-gap:4px}.holding-row .hr-name{grid-area:name}.holding-row .hr-pnl{grid-area:pnl}.holding-row .hr-qty{grid-area:qty}.holding-row .hr-price{grid-area:price}.holding-row .hr-arrow{grid-area:arrow}.holding-modal-kpi{grid-template-columns:1fr 1fr}.modal-body{padding:var(--sp-4)}}.tools-row{display:flex;justify-content:flex-end;align-items:center;gap:var(--sp-2);margin-bottom:var(--sp-3)}.helper-note{text-align:center;color:var(--ink-dim);font-size:var(--fs-sm);padding:var(--sp-5) 0 0}.helper-note strong{color:var(--ink-mute)}.trader-card-pnl{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-weight:var(--fw-bold);font-size:var(--fs-sm);padding:2px var(--sp-2);border-radius:var(--r-sm)}.trader-card-pnl.is-gain{color:var(--gain);background:var(--gain-soft)}.trader-card-pnl.is-loss{color:var(--loss);background:var(--loss-soft)}.trader-card-pnl.is-zero{color:var(--ink-dim);background:var(--surface)}.trader-card-perf{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;font-size:var(--fs-tiny);color:var(--ink-mute);padding-top:var(--sp-2);margin-top:var(--sp-2);border-top:1px dashed var(--border)}.trader-card-perf .perf-cell{display:inline-flex;align-items:baseline;gap:4px}.trader-card-perf .perf-k{color:var(--ink-dim);letter-spacing:.06em;text-transform:uppercase}.trader-card-perf .perf-v{color:var(--ink-900);font-weight:var(--fw-semi);font-family:var(--font-mono)}.trader-card-perf .perf-v.is-gain{color:var(--gain)}.trader-card-perf .perf-v.is-loss{color:var(--loss)}.trader-detail-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-4);flex-wrap:wrap;margin-bottom:var(--sp-4)}.trader-detail-head .tagline{margin:var(--sp-1) 0 0;font-style:italic;color:var(--ink-mute);font-size:var(--fs-sm)}.trader-detail-head .funnel{margin:var(--sp-2) 0 0;font-size:var(--fs-tiny);color:var(--ink-dim);display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap}.trader-detail-head .funnel strong{color:var(--ink-mute);font-family:var(--font-mono)}.trader-detail-head .funnel .arrow{color:var(--ink-faint)}.trader-detail-head .ver{font-size:var(--fs-tiny);color:var(--ink-dim);font-weight:var(--fw-medium);margin-left:var(--sp-2);font-family:var(--font-mono)}.confirm-modal{text-align:center;display:flex;flex-direction:column;align-items:center;gap:var(--sp-3)}.confirm-modal .alert-icon{font-size:32px;color:var(--warn);margin-bottom:var(--sp-1)}.confirm-modal h3{font-size:var(--fs-h3);font-weight:var(--fw-bold);margin:0;color:var(--ink-900)}.confirm-modal .desc{font-size:var(--fs-sm);color:var(--ink-mute);line-height:1.55;margin:0}.confirm-modal ul{text-align:left;font-size:var(--fs-sm);color:var(--ink-700);background:var(--surface);border-radius:var(--r-md);padding:var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-6);margin:0;line-height:1.6;width:100%;box-sizing:border-box}.confirm-modal ul li{margin:2px 0}.confirm-modal .actions{display:flex;gap:var(--sp-2);justify-content:flex-end;width:100%;margin-top:var(--sp-2)}@media(max-width:720px){.trader-detail-head{flex-direction:column;align-items:stretch}.trader-card-perf{font-size:10px;gap:var(--sp-1)}}.memory-meta-warn{color:var(--warn)}.dialog-section-head.is-spaced{margin-top:var(--sp-4)}.journal-grid>.glass{display:flex;flex-direction:column}.journal-section-head{display:flex;align-items:baseline;justify-content:space-between;column-gap:var(--sp-3);row-gap:var(--sp-2);flex-wrap:wrap;margin-bottom:var(--sp-4)}.journal-section-head h2{font-size:var(--fs-h3);font-weight:var(--fw-semi);letter-spacing:-.025em;margin:0}.journal-list .item .ev-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--ink-faint);margin-right:var(--sp-2);flex-shrink:0;vertical-align:middle}.journal-list .item .ev-dot.is-decision{background:var(--accent)}.journal-list .item .ev-dot.is-buy{background:var(--gain)}.journal-list .item .ev-dot.is-sell{background:var(--loss)}.journal-list .item .ev-dot.is-watcher{background:var(--warn)}.journal-list .item .ev-dot.is-order{background:var(--accent-3)}.journal-list .item .ev-dot.is-rejected{background:var(--loss);box-shadow:0 0 0 2px var(--loss-soft)}.pagination .pages-total{color:var(--ink-dim)}.journal-detail-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-3);margin-bottom:var(--sp-3)}.journal-detail-head h3{font-size:var(--fs-lg);font-weight:var(--fw-semi);margin:0}.journal-detail-head .ev-time-mono{font-family:var(--font-mono);font-size:var(--fs-sm);color:var(--ink-mute)}.journal-decision-head{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-4);flex-wrap:wrap}.journal-decision-head .symbol-mono{font-family:var(--font-mono);color:var(--ink-mute);font-size:var(--fs-sm)}.kv-list dd.is-mono{font-family:var(--font-mono);font-size:var(--fs-xs);color:var(--ink-700);word-break:break-all}.kv-list dd.is-loss{color:var(--loss)}.kv-list dd.is-warn{color:var(--warn)}.kv-list dd.is-truncated{color:var(--loss);font-weight:var(--fw-bold);margin-left:var(--sp-1)}.card-dialog-head{margin-bottom:var(--sp-5)}.card-dialog-head h2{font-size:var(--fs-h1);font-weight:var(--fw-bold);letter-spacing:-.02em;margin:0}.card-dialog-head .sub{color:var(--ink-mute);font-size:var(--fs-sm);margin-top:4px}.mono-mute{font-family:var(--font-mono);color:var(--ink-mute)}.journal-page{display:flex;flex-direction:column;flex:1;min-height:0}.journal-page>.journal-grid{flex:1 1 auto;min-height:0}.journal-page>.journal-grid>.glass{max-height:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}@media(max-width:900px){.journal-page{flex:initial;min-height:auto}.journal-page>.journal-grid{flex:initial;min-height:auto}.journal-page>.journal-grid>.glass{max-height:none;overflow-y:visible}}.diary-page{display:flex;flex-direction:column;flex:1;min-height:0}.diary-persona-tabs{display:flex;gap:var(--sp-2);margin-bottom:var(--sp-4);border-bottom:1px solid var(--glass-line);padding-bottom:var(--sp-2)}.diary-persona-tab{padding:var(--sp-2) var(--sp-4);background:transparent;border:1px solid transparent;border-radius:var(--r-md);font:inherit;color:var(--ink-mute);cursor:pointer;display:inline-flex;align-items:center;gap:var(--sp-2);transition:var(--tx-fast)}.diary-persona-tab:hover{color:var(--ink-900);background:var(--glass)}.diary-persona-tab.is-active{background:var(--accent-soft);color:var(--accent);border-color:var(--accent);font-weight:var(--fw-semi)}.diary-persona-tab .count{font-size:var(--fs-tiny);color:var(--ink-dim);background:var(--bg);padding:2px var(--sp-2);border-radius:var(--r-sm)}.diary-grid{display:grid;grid-template-columns:280px 1fr;gap:var(--sp-4);flex:1 1 auto;min-height:0}.diary-list-pane{display:flex;flex-direction:column;max-height:100%;overflow-y:auto;padding:var(--sp-3);-webkit-overflow-scrolling:touch}.diary-list-head{display:flex;justify-content:space-between;align-items:baseline;padding:var(--sp-2) var(--sp-3) var(--sp-3);font-weight:var(--fw-semi);color:var(--ink-900);border-bottom:1px solid var(--glass-line);margin-bottom:var(--sp-2)}.diary-list-head .meta{font-size:var(--fs-tiny);color:var(--ink-mute);font-weight:var(--fw-medium)}.diary-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2)}.diary-list-item{width:100%;text-align:left;background:var(--glass);border:1px solid transparent;border-radius:var(--r-md);padding:var(--sp-3) var(--sp-4);cursor:pointer;font:inherit;display:flex;flex-direction:column;gap:var(--sp-2);transition:var(--tx-fast)}.diary-list-item:hover{background:var(--glass-2);border-color:var(--glass-line)}.diary-list-item.is-active{background:var(--accent-soft);border-color:var(--accent)}.diary-list-item .row{display:flex;justify-content:space-between;align-items:baseline;gap:var(--sp-2)}.diary-list-item .date{font-weight:var(--fw-semi);color:var(--ink-900);font-size:var(--fs-sm)}.diary-list-item .len{font-size:var(--fs-tiny);color:var(--ink-dim)}.diary-list-item .excerpt{margin:0;font-size:var(--fs-tiny);color:var(--ink-mute);line-height:1.55;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.diary-body-pane{max-height:100%;overflow-y:auto;padding:var(--sp-6) var(--sp-7);-webkit-overflow-scrolling:touch}.diary-body-head{margin-bottom:var(--sp-5);padding-bottom:var(--sp-3);border-bottom:1px solid var(--glass-line)}.diary-body-head .date-label{font-size:var(--fs-sm);color:var(--ink-mute);font-weight:var(--fw-medium)}.diary-md{font-size:var(--fs-body);color:var(--ink-900);line-height:1.85}.diary-md h1{font-size:var(--fs-h1);font-weight:var(--fw-bold);letter-spacing:-.02em;margin:0 0 var(--sp-5);color:var(--ink-900);line-height:1.2}.diary-md h2{font-size:var(--fs-h3);font-weight:var(--fw-semi);margin:var(--sp-6) 0 var(--sp-3);color:var(--ink-900)}.diary-md h3{font-size:var(--fs-lg);font-weight:var(--fw-semi);margin:var(--sp-5) 0 var(--sp-2);color:var(--ink-900)}.diary-md p{margin:0 0 var(--sp-4)}.diary-md p:last-child{margin-bottom:0}.diary-md strong{color:var(--ink-900);font-weight:var(--fw-semi)}.diary-md em{color:var(--ink-700);font-style:italic}.diary-md ul,.diary-md ol{padding-left:var(--sp-5);margin:0 0 var(--sp-4)}.diary-md li{margin-bottom:var(--sp-2);line-height:1.7}.diary-md code{background:var(--glass-2);padding:1px 6px;border-radius:var(--r-sm);font-family:var(--font-mono);font-size:.9em;color:var(--accent)}.diary-md blockquote{border-left:3px solid var(--accent);padding:var(--sp-2) var(--sp-4);margin:var(--sp-4) 0;background:var(--accent-soft);color:var(--ink-700);border-radius:0 var(--r-md) var(--r-md) 0}.diary-md hr{border:none;border-top:1px solid var(--glass-line);margin:var(--sp-6) 0}@media(max-width:900px){.diary-page{flex:initial;min-height:auto}.diary-grid{grid-template-columns:1fr;flex:initial}.diary-list-pane,.diary-body-pane{max-height:none;overflow-y:visible}.diary-list-pane{max-height:320px;overflow-y:auto}}.section-label,.stat-row{margin-bottom:var(--sp-3)}.journal-section-head{padding-top:var(--sp-1)}.journal-list{padding:var(--sp-4);gap:var(--sp-2)}.journal-detail,.stat-card{padding:var(--sp-5) var(--sp-6)}
|
package/dist/web/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>mulsok</title>
|
|
7
7
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css" />
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-B1C-UX9W.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-N7Xwheka.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mulsok/traders-client",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "mulsok-traders 데스크톱 클라이언트 · 한국 주식 AI 자율 트레이더 (macOS · claude CLI)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -27,9 +27,6 @@
|
|
|
27
27
|
"engines": {
|
|
28
28
|
"node": ">=20.0.0"
|
|
29
29
|
},
|
|
30
|
-
"os": [
|
|
31
|
-
"darwin"
|
|
32
|
-
],
|
|
33
30
|
"bin": {
|
|
34
31
|
"mulsok-client": "bin/cli.js"
|
|
35
32
|
},
|
|
@@ -39,7 +36,8 @@
|
|
|
39
36
|
"scripts/com.mulsok.traders.client.plist.template",
|
|
40
37
|
"scripts/install-daemon.sh",
|
|
41
38
|
"scripts/uninstall-daemon.sh",
|
|
42
|
-
"README.md"
|
|
39
|
+
"README.md",
|
|
40
|
+
"CHANGELOG.md"
|
|
43
41
|
],
|
|
44
42
|
"scripts": {
|
|
45
43
|
"dev": "concurrently -n server,web -c blue,green \"npm run dev:server\" \"npm run dev:web\"",
|
|
@@ -65,6 +63,7 @@
|
|
|
65
63
|
},
|
|
66
64
|
"dependencies": {
|
|
67
65
|
"@fastify/static": "^8.0.3",
|
|
66
|
+
"@supabase/supabase-js": "^2.105.4",
|
|
68
67
|
"better-sqlite3": "^12.9.0",
|
|
69
68
|
"dotenv": "^17.4.2",
|
|
70
69
|
"fastify": "^5.1.0",
|