@tradecanvas/chart 1.27.0 → 1.29.0
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/dist/Chart.d.ts +42 -1
- package/dist/Chart.d.ts.map +1 -1
- package/dist/LayoutSession-DhB5RGm1.cjs +2 -0
- package/dist/LayoutSession-DhB5RGm1.cjs.map +1 -0
- package/dist/{LayoutSession-CUS33zmB.js → LayoutSession-goRU8aOv.js} +92 -9
- package/dist/LayoutSession-goRU8aOv.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/widget/ChartWidget.d.ts +2 -0
- package/dist/widget/ChartWidget.d.ts.map +1 -1
- package/dist/widget/index.cjs +50 -11
- package/dist/widget/index.cjs.map +1 -1
- package/dist/widget/index.js +216 -192
- package/dist/widget/index.js.map +1 -1
- package/dist/widget/keyboardInset.d.ts +9 -0
- package/dist/widget/keyboardInset.d.ts.map +1 -0
- package/package.json +3 -3
- package/dist/LayoutSession-CUS33zmB.js.map +0 -1
- package/dist/LayoutSession-CYdvbLA3.cjs +0 -2
- package/dist/LayoutSession-CYdvbLA3.cjs.map +0 -1
package/dist/widget/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as e, a as t, c as n, i as r, n as i, o as a, r as o, t as s } from "../LayoutSession-
|
|
1
|
+
import { C as e, a as t, c as n, i as r, n as i, o as a, r as o, t as s } from "../LayoutSession-goRU8aOv.js";
|
|
2
2
|
import { a as c, c as l, i as u, n as d, o as f, r as p, s as m, t as h } from "../i18n-FG3D2x5m.js";
|
|
3
3
|
import { CHART_STYLE_KEYS as g, CHART_TYPE_ICONS as _, DARK_THEME as v, DEFAULT_SIGNAL_STYLE as y, DEFAULT_TRADE_ZONE_STYLE as b, DEFAULT_TRADING_CONFIG as x, DRAWING_TOOL_ICONS as ee, LIGHT_THEME as te, PRICE_SOURCES as ne, UI_ICONS as re, barTimeUnit as S, formatPrice as ie, iconSvg as ae, indicatorSource as oe, isTimeFrame as se, isValidTimeZone as ce, marketStatus as le, offsetAt as ue, parseIndicatorSource as de, readChartTypeOptions as fe, readNews as pe, readQuote as me, sanitizeDrawingOptions as he, sanitizeDrawingStyle as ge, tickBarCount as C, timeParts as _e, timeframeBucketStart as ve, timeframeToMs as w, tzLabel as ye, wallToUtc as be, zoneOffsetMinutes as xe } from "@tradecanvas/commons";
|
|
4
4
|
import { ChartStateManager as Se, MAX_ALERT_BARS as Ce, MIN_ALERT_BARS as we, RANGE_PRESETS as Te, indicatorValuePrecision as Ee, plotColor as De, plotShown as Oe, rangePresetStart as ke, servesTimeframe as Ae, sourceParam as je, withResampling as Me } from "@tradecanvas/core";
|
|
@@ -1459,7 +1459,7 @@ function Xe(e) {
|
|
|
1459
1459
|
return Ye.has(e) && r === "upColor" && (i = "settings.upBody"), Ye.has(e) && r === "downColor" && (i = "settings.downBody"), e === "baseline" && r === "upColor" && (i = "settings.aboveBase"), e === "baseline" && r === "downColor" && (i = "settings.belowBase"), T(i, n);
|
|
1460
1460
|
});
|
|
1461
1461
|
}
|
|
1462
|
-
var Ze = [...new Set([...Object.keys(g).filter((e) => e.startsWith("series.")), ...[...Ke, ...qe].flatMap((e) => e.rows.flatMap((e) => e.keys))])], Qe = "/* === TradeCanvas Widget — Premium Styles === */\n\n/*\n * The HTML `hidden` attribute only sets `display: none` via the UA stylesheet,\n * which any author `display` rule (e.g. `.tcw-alerts-panel { display: flex }`)\n * silently overrides — leaving panels stuck open when JS sets `el.hidden = true`.\n * Force `hidden` to win for every namespaced widget element. Scoped to `tcw-`\n * so it never touches the host page.\n */\n[class^=\"tcw-\"][hidden],\n[class*=\" tcw-\"][hidden] {\n display: none !important;\n}\n\n/* Control tooltips (WidgetTooltip): quick to appear, slide in from the control. */\n.tcw-tooltip {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 60;\n max-width: 240px;\n padding: 5px 8px;\n border-radius: var(--tcw-tooltip-radius);\n background: var(--tcw-tooltip-bg);\n color: var(--tcw-tooltip-fg);\n box-shadow: var(--tcw-tooltip-shadow);\n width: max-content;\n font-size: var(--tcw-font-size-xs);\n font-weight: var(--tcw-weight);\n line-height: 1.35;\n overflow-wrap: anywhere;\n pointer-events: none;\n opacity: 0;\n visibility: hidden;\n transform: translate(var(--tcw-tip-dx, 0), var(--tcw-tip-dy, 0));\n transition:\n opacity 110ms var(--tcw-ease-out),\n transform 110ms var(--tcw-ease-out),\n visibility 0s linear 110ms;\n}\n\n.tcw-tooltip--visible {\n opacity: 1;\n visibility: visible;\n transform: none;\n transition:\n opacity 110ms var(--tcw-ease-out),\n transform 110ms var(--tcw-ease-out),\n visibility 0s;\n}\n\n/* The modal portal: carries the tokens and fonts, but no box of its own. */\n.tcw-root.tcw-portal {\n display: contents;\n}\n\n/* Fullscreen: the root fills the screen; the chart resizes with it. */\n.tcw-root:fullscreen {\n width: 100vw;\n height: 100vh;\n}\n\n.tcw-root {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n font-family: var(--tcw-font);\n font-feature-settings: 'cv11', 'ss01', 'ss03';\n font-size: var(--tcw-font-size);\n line-height: 1.4;\n color: #d9dde4;\n background: #080b10;\n position: relative;\n overflow: hidden;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n\n /* --- Dark theme tokens (default) --- */\n --tcw-bg: #080b10;\n --tcw-bg-surface: #0c1016;\n --tcw-bg-elevated: #141922;\n --tcw-bg-overlay: rgba(20, 25, 34, 0.5);\n --tcw-border: #1f2630;\n --tcw-border-strong: #2a323e;\n --tcw-tooltip-bg: #262e3a;\n --tcw-tooltip-fg: #eef0f4;\n --tcw-text: #e7e9ee;\n --tcw-text-dim: #aab1bd;\n --tcw-text-muted: #758091;\n\n /* TradeCanvas amber. --tcw-accent-ink is the text colour on an accent fill. */\n --tcw-accent: #f2a93b;\n --tcw-accent-hover: #f5b95c;\n --tcw-accent-ink: #1a1204;\n --tcw-accent-soft: rgba(242, 169, 59, 0.14);\n --tcw-accent-glow: rgba(242, 169, 59, 0.22);\n --tcw-accent-line: rgba(242, 169, 59, 0.55);\n\n --tcw-red: #e8505b;\n --tcw-red-soft: rgba(232, 80, 91, 0.12);\n --tcw-green: #1fa874;\n --tcw-green-soft: rgba(31, 168, 116, 0.12);\n --tcw-amber: #ff9f43;\n\n --tcw-hover-bg: rgba(255, 255, 255, 0.05);\n --tcw-active-bg: rgba(255, 255, 255, 0.08);\n --tcw-divider: rgba(255, 255, 255, 0.06);\n\n /* Motion */\n --tcw-ease: cubic-bezier(0.2, 0, 0, 1);\n --tcw-ease-out: cubic-bezier(0.16, 1, 0.3, 1);\n --tcw-dur-fast: 120ms;\n --tcw-dur-normal: 180ms;\n --tcw-dur-slow: 260ms;\n\n /* The look (UI system): Studio's values. The `ui` option sets them inline. */\n --tcw-radius-xs: 3px;\n --tcw-radius-sm: 5px;\n --tcw-radius: 7px;\n --tcw-radius-lg: 11px;\n --tcw-radius-xl: 16px;\n --tcw-control-radius: var(--tcw-radius);\n --tcw-input-radius: var(--tcw-radius);\n --tcw-menu-radius: var(--tcw-radius-lg);\n --tcw-dialog-radius: var(--tcw-radius-xl);\n --tcw-panel-radius: var(--tcw-radius-lg);\n --tcw-tooltip-radius: var(--tcw-radius-sm);\n --tcw-tag-radius: var(--tcw-radius-sm);\n --tcw-toast-radius: var(--tcw-radius-lg);\n --tcw-toolbar-radius: 0px;\n --tcw-sidebar-radius: 0px;\n --tcw-toolbar-h: 46px;\n --tcw-control-h: 30px;\n --tcw-control-h-sm: 24px;\n --tcw-icon: 18px;\n --tcw-sidebar-w: 48px;\n --tcw-menu-item-h: 30px;\n --tcw-font: 'Manrope', 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n --tcw-font-size: 13px;\n --tcw-font-size-sm: 12px;\n --tcw-font-size-xs: 11px;\n --tcw-font-size-lg: 15px;\n --tcw-weight: 500;\n --tcw-weight-strong: 600;\n --tcw-label-case: none;\n --tcw-label-tracking: 0em;\n --tcw-border-w: 1px;\n --tcw-sep-w: 0px;\n --tcw-menu-shadow: var(--tcw-shadow-lg);\n --tcw-dialog-shadow: var(--tcw-shadow-xl);\n --tcw-tooltip-shadow: var(--tcw-shadow-md);\n --tcw-blur: 0px;\n --tcw-surface-opacity: 100%;\n\n /* Elevation */\n --tcw-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);\n --tcw-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.2);\n --tcw-shadow-lg: 0 12px 36px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3);\n --tcw-shadow-xl: 0 24px 64px rgba(0, 0, 0, 0.55), 0 12px 24px rgba(0, 0, 0, 0.35);\n --tcw-ring: 0 0 0 2px rgba(242, 169, 59, 0.45);\n\n /* Type */\n --tcw-font-mono: 'JetBrains Mono', 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', ui-monospace, monospace;\n}\n\n.tcw-root[data-tcw-theme='light'] {\n color: #0c1016;\n background: #fcfcfd;\n\n --tcw-bg: #fcfcfd;\n --tcw-bg-surface: #ffffff;\n --tcw-bg-elevated: #ffffff;\n --tcw-bg-overlay: rgba(255, 255, 255, 0.75);\n --tcw-border: #e3e6eb;\n --tcw-border-strong: #d2d6dd;\n --tcw-tooltip-bg: #1f2630;\n --tcw-tooltip-fg: #f4f5f8;\n --tcw-text: #0c1016;\n --tcw-text-dim: #3f4754;\n --tcw-text-muted: #626a77;\n\n /* Deeper amber: readable as text on the light ground, white text readable on it. */\n --tcw-accent: #a0610a;\n --tcw-accent-hover: #874f07;\n --tcw-accent-ink: #ffffff;\n --tcw-accent-soft: rgba(160, 97, 10, 0.10);\n --tcw-accent-glow: rgba(160, 97, 10, 0.16);\n --tcw-accent-line: rgba(160, 97, 10, 0.45);\n --tcw-ring: 0 0 0 2px rgba(160, 97, 10, 0.4);\n\n /* Darker semantic colours: used as text on white. */\n --tcw-red: #c42f3e;\n --tcw-red-soft: rgba(196, 47, 62, 0.10);\n --tcw-green: #0b7d50;\n --tcw-green-soft: rgba(11, 125, 80, 0.10);\n\n --tcw-hover-bg: rgba(0, 0, 0, 0.04);\n --tcw-active-bg: rgba(160, 97, 10, 0.08);\n --tcw-divider: rgba(0, 0, 0, 0.06);\n\n --tcw-shadow-sm: 0 1px 2px rgba(20, 28, 56, 0.05);\n --tcw-shadow-md: 0 4px 12px rgba(20, 28, 56, 0.08), 0 1px 3px rgba(20, 28, 56, 0.04);\n --tcw-shadow-lg: 0 12px 36px rgba(20, 28, 56, 0.14), 0 4px 12px rgba(20, 28, 56, 0.08);\n --tcw-shadow-xl: 0 24px 64px rgba(20, 28, 56, 0.18), 0 12px 24px rgba(20, 28, 56, 0.1);\n}\n\n/* === Toolbar === */\n\n.tcw-toolbar {\n display: flex;\n align-items: center;\n gap: 0;\n padding: 0 10px;\n height: var(--tcw-toolbar-h);\n border-bottom: var(--tcw-border-w) solid var(--tcw-border);\n background:\n linear-gradient(180deg, var(--tcw-bg-elevated) 0%, var(--tcw-bg-surface) 100%);\n flex-shrink: 0;\n position: relative;\n z-index: 20;\n box-shadow: var(--tcw-shadow-sm);\n}\n\n.tcw-toolbar-symbol {\n font-size: calc(var(--tcw-font-size) + 1px);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n display: inline-flex;\n align-items: center;\n height: var(--tcw-control-h);\n padding: 0 12px;\n white-space: nowrap;\n letter-spacing: -0.015em;\n cursor: pointer;\n border: none;\n background: transparent;\n font-family: inherit;\n border-radius: var(--tcw-control-radius);\n transition: background var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-toolbar-symbol:hover {\n background: var(--tcw-hover-bg);\n}\n\n/* With the symbol search switched off, the button only names the symbol. */\n.tcw-toolbar-symbol[aria-disabled=\"true\"] {\n cursor: default;\n}\n\n.tcw-toolbar-symbol[aria-disabled=\"true\"]:hover {\n background: transparent;\n}\n\n.tcw-toolbar-sep {\n width: var(--tcw-sep-w);\n height: 22px;\n background: var(--tcw-border);\n flex-shrink: 0;\n margin: 0 4px;\n}\n\n.tcw-toolbar-group {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 4px;\n}\n\n.tcw-toolbar-spacer {\n flex: 1;\n}\n\n.tcw-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: var(--tcw-control-h);\n padding: 0 10px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight);\n font-family: inherit;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n color var(--tcw-dur-fast) var(--tcw-ease),\n transform var(--tcw-dur-fast) var(--tcw-ease);\n white-space: nowrap;\n line-height: 1;\n letter-spacing: -0.005em;\n}\n\n.tcw-btn:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-btn:active {\n transform: translateY(0.5px);\n}\n\n.tcw-btn.tcw-active {\n background: var(--tcw-on-bg);\n color: var(--tcw-on-fg);\n font-weight: var(--tcw-weight-strong);\n box-shadow: var(--tcw-on-ring);\n}\n\n.tcw-btn:focus-visible,\n.tcw-btn-icon:focus-visible,\n.tcw-sidebar-btn:focus-visible,\n.tcw-dropdown-trigger:focus-visible {\n outline: none;\n box-shadow: var(--tcw-ring);\n}\n\n.tcw-btn-icon {\n width: var(--tcw-control-h);\n height: var(--tcw-control-h);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: inherit;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n color var(--tcw-dur-fast) var(--tcw-ease);\n line-height: 1;\n position: relative;\n}\n\n.tcw-btn-icon:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-btn-icon svg {\n display: block;\n width: var(--tcw-icon);\n height: var(--tcw-icon);\n}\n\n.tcw-badge-count {\n font-size: calc(var(--tcw-font-size) - 3px);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n padding: 1px 5px;\n border-radius: var(--tcw-tag-radius);\n font-family: var(--tcw-font-mono);\n}\n\n/* === Dropdown === */\n\n.tcw-dropdown-trigger {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: var(--tcw-control-h);\n padding: 0 10px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight);\n font-family: inherit;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n white-space: nowrap;\n line-height: 1;\n}\n\n.tcw-dropdown-trigger:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-dropdown {\n position: absolute;\n top: 100%;\n margin-top: 6px;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n z-index: 50;\n width: max-content;\n max-width: min(340px, calc(100vw - 16px));\n padding: 6px;\n max-height: 420px;\n overflow-y: auto;\n backdrop-filter: blur(var(--tcw-blur));\n -webkit-backdrop-filter: blur(var(--tcw-blur));\n animation: tcw-pop-in var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n@keyframes tcw-pop-in {\n from { opacity: 0; transform: translateY(-4px) scale(0.98); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n}\n\n.tcw-dropdown-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: var(--tcw-menu-item-h);\n padding: 4px 10px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n width: 100%;\n border: none;\n background: transparent;\n font-family: inherit;\n text-align: start;\n border-radius: var(--tcw-radius-sm);\n gap: 12px;\n}\n\n.tcw-dropdown-item:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n/* A menu row led by an icon (chart types): icon then label, not spread apart. */\n.tcw-dropdown-item--icon {\n justify-content: flex-start;\n gap: 10px;\n}\n\n.tcw-dropdown-item svg,\n.tcw-flyout-item svg {\n flex-shrink: 0;\n}\n\n/* The drawing-group button's icon holder: a plain box for the swapped SVG. */\n.tcw-sidebar-icon {\n display: inline-flex;\n}\n\n.tcw-dropdown-item.tcw-active {\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n font-weight: var(--tcw-weight-strong);\n}\n\n/* Timeframe menu: pick on the left, pin (star) on the right. */\n.tcw-tf-more {\n padding: 0 5px;\n}\n\n.tcw-tf-more svg {\n display: block;\n}\n\n.tcw-tf-row {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n\n.tcw-tf-row .tcw-dropdown-item {\n flex: 1;\n min-width: 0;\n}\n\n.tcw-tf-star {\n display: inline-grid;\n place-items: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n flex-shrink: 0;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n transition: color var(--tcw-dur-fast) var(--tcw-ease), background var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-tf-star:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-tf-star.tcw-active {\n color: var(--tcw-accent);\n}\n\n.tcw-tf-star.tcw-active svg {\n fill: currentColor;\n}\n\n.tcw-tf-star:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: -2px;\n}\n\n.tcw-tf-remove {\n display: inline-grid;\n place-items: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n flex-shrink: 0;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n opacity: 0;\n transition: opacity var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-tf-row:hover .tcw-tf-remove,\n.tcw-tf-remove:focus-visible {\n opacity: 1;\n}\n\n/* No hover on touch screens: keep it visible rather than a hidden tap target. */\n@media (hover: none) {\n .tcw-tf-remove { opacity: 1; }\n}\n\n.tcw-tf-remove:hover {\n color: var(--tcw-red);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-tf-remove:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: -2px;\n}\n\n/* Typed interval, under the list: stays in view while the list scrolls. */\n.tcw-tf-custom {\n position: sticky;\n bottom: -6px;\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin: 4px -6px -6px;\n padding: 6px 10px 8px;\n border-top: 1px solid var(--tcw-divider);\n background: var(--tcw-bg-elevated);\n}\n\n.tcw-tf-custom-hint:empty {\n display: none;\n}\n\n.tcw-tf-custom-hint {\n flex-basis: 100%;\n width: 0;\n min-width: 100%;\n color: var(--tcw-red);\n font-size: var(--tcw-font-size-xs);\n line-height: 1.35;\n}\n\n.tcw-tf-custom-input {\n flex: 1;\n min-width: 0;\n height: 26px;\n padding: 0 8px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-input-radius);\n background: var(--tcw-bg);\n color: var(--tcw-text);\n font: inherit;\n font-family: var(--tcw-font-mono);\n font-size: var(--tcw-font-size-sm);\n}\n\n.tcw-tf-custom-input::placeholder {\n color: var(--tcw-text-dim);\n}\n\n.tcw-tf-custom-input:focus {\n outline: none;\n border-color: var(--tcw-accent);\n box-shadow: 0 0 0 2px var(--tcw-accent-soft);\n}\n\n.tcw-tf-custom-input[aria-invalid='true'] {\n border-color: var(--tcw-red);\n box-shadow: 0 0 0 2px var(--tcw-red-soft);\n}\n\n.tcw-tf-custom-add {\n display: inline-grid;\n place-items: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n flex-shrink: 0;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-control-radius);\n background: var(--tcw-bg-surface);\n color: var(--tcw-text);\n cursor: pointer;\n}\n\n.tcw-tf-custom-add:hover {\n border-color: var(--tcw-accent);\n color: var(--tcw-accent);\n}\n\n.tcw-tf-custom-add:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: 1px;\n}\n\n.tcw-dropdown-label {\n text-transform: var(--tcw-label-case);\n font-size: calc(var(--tcw-font-size) - 3px);\n color: var(--tcw-text-muted);\n letter-spacing: var(--tcw-label-tracking);\n padding: 8px 10px 4px;\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-dropdown-divider {\n border-top: 1px solid var(--tcw-divider);\n margin: 6px 4px;\n}\n\n.tcw-tag {\n font-size: calc(var(--tcw-font-size) - 3px);\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n padding: 2px 6px;\n border-radius: var(--tcw-tag-radius);\n background: var(--tcw-hover-bg);\n letter-spacing: 0.02em;\n}\n\n/* === Body === */\n\n.tcw-body {\n position: relative;\n display: flex;\n flex: 1;\n min-height: 0;\n background: var(--tcw-bg);\n}\n\n.tcw-chart-container {\n flex: 1;\n min-width: 0;\n min-height: 0;\n width: 100%;\n height: 100%;\n position: relative;\n}\n\n/* === Symbol search results: name and exchange === */\n\n.tcw-cmd-item-desc {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size-sm);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.tcw-cmd-item-meta {\n flex-shrink: 0;\n color: var(--tcw-text-dim);\n font-size: var(--tcw-font-size-xs);\n letter-spacing: 0.02em;\n}\n\n/* === History pill (older bars loading at the left edge) === */\n\n.tcw-history-pill {\n position: absolute;\n top: 50%;\n left: 10px;\n z-index: 4;\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 5px 10px 5px 8px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-tag-radius);\n background: var(--tcw-bg-elevated);\n box-shadow: var(--tcw-shadow-sm);\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size-xs);\n line-height: 1;\n white-space: nowrap;\n transform: translateY(-50%);\n opacity: 1;\n transition: opacity var(--tcw-dur-normal) var(--tcw-ease-out);\n pointer-events: none;\n}\n\n.tcw-history-pill--hidden {\n opacity: 0;\n}\n\n.tcw-history-pill--error {\n border-color: color-mix(in srgb, var(--tcw-red) 45%, var(--tcw-border));\n color: var(--tcw-red);\n}\n\n.tcw-history-spinner {\n width: 10px;\n height: 10px;\n border: 1.5px solid var(--tcw-accent-soft);\n border-top-color: var(--tcw-accent);\n border-radius: 50%;\n animation: tcw-history-spin 0.8s linear infinite;\n}\n\n.tcw-history-pill--error .tcw-history-spinner {\n border-color: currentColor;\n animation: none;\n}\n\n@keyframes tcw-history-spin {\n to { transform: rotate(360deg); }\n}\n\n/* === Loading overlay (candle skeleton) === */\n\n.tcw-loading-overlay {\n /* Uses a modifier class rather than the `hidden` attribute — the global\n `[hidden] { display: none !important }` rule above would cut the\n opacity transition off before it can play. */\n position: absolute;\n inset: 0;\n z-index: 5;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--tcw-bg);\n opacity: 1;\n transition: opacity var(--tcw-dur-slow) var(--tcw-ease-out);\n pointer-events: none;\n}\n\n.tcw-loading-overlay--hidden {\n opacity: 0;\n}\n\n.tcw-loading-card {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 14px;\n padding: 22px 26px 20px;\n border: 1px solid transparent;\n border-radius: var(--tcw-panel-radius);\n}\n\n/* A slow switch: the previous chart stays readable underneath, dimmed, so the\n click visibly registered without blanking the screen. */\n.tcw-loading-overlay--veil {\n background: color-mix(in srgb, var(--tcw-bg) 55%, transparent);\n}\n\n.tcw-loading-overlay--veil .tcw-loading-card {\n background: var(--tcw-bg-elevated);\n border-color: var(--tcw-border);\n box-shadow: var(--tcw-menu-shadow);\n}\n\n.tcw-loading-candles {\n position: relative;\n display: flex;\n gap: 7px;\n height: 64px;\n}\n\n/* One candle: the element is the wick's column, ::before the wick, ::after the body. */\n.tcw-loading-candle {\n position: relative;\n width: 8px;\n height: 100%;\n color: var(--tcw-red);\n opacity: 0.28;\n animation: tcw-candle-light 1.6s var(--tcw-ease) infinite;\n animation-delay: var(--tcw-delay, 0ms);\n}\n\n.tcw-loading-candle--up { color: var(--tcw-green); }\n\n.tcw-loading-candle::before,\n.tcw-loading-candle::after {\n content: '';\n position: absolute;\n left: 50%;\n background: currentColor;\n transform: translateX(-50%);\n}\n\n.tcw-loading-candle::before {\n top: var(--tcw-wick-top);\n width: 1.5px;\n height: var(--tcw-wick-h);\n}\n\n.tcw-loading-candle::after {\n top: var(--tcw-body-top);\n width: 8px;\n height: var(--tcw-body-h);\n border-radius: 1.5px;\n}\n\n/* Each candle brightens and lifts slightly in turn, left to right. */\n@keyframes tcw-candle-light {\n 0%, 55%, 100% { opacity: 0.28; transform: translateY(0); }\n 20% { opacity: 1; transform: translateY(-2px); }\n}\n\n.tcw-loading-track {\n position: relative;\n width: 100%;\n min-width: 88px;\n height: 2px;\n border-radius: 1px;\n background: var(--tcw-border);\n overflow: hidden;\n}\n\n.tcw-loading-track > span {\n position: absolute;\n inset: 0;\n width: 40%;\n border-radius: 1px;\n background: linear-gradient(90deg, transparent, var(--tcw-accent), transparent);\n animation: tcw-loading-sweep 1.6s var(--tcw-ease) infinite;\n}\n\n@keyframes tcw-loading-sweep {\n from { transform: translateX(-100%); }\n to { transform: translateX(250%); }\n}\n\n/* The status text is announced, not shown — the candles say \"loading\". */\n.tcw-loading-label {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n.tcw-loading-overlay--error .tcw-loading-candles,\n.tcw-loading-overlay--error .tcw-loading-track {\n display: none;\n}\n\n/* A failure is shown: why the chart is empty and that a retry is running. */\n.tcw-loading-overlay--error .tcw-loading-label {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip-path: none;\n white-space: normal;\n max-width: 320px;\n text-align: center;\n color: var(--tcw-red);\n font-size: var(--tcw-font-size);\n}\n\n/* Reduced motion: nothing slides or lifts, but the candles still glow in\n turn and the track breathes, so the wait never looks frozen. */\n@media (prefers-reduced-motion: reduce) {\n .tcw-loading-candle {\n animation: tcw-candle-glow 2.4s ease-in-out infinite;\n animation-delay: var(--tcw-delay, 0ms);\n }\n .tcw-loading-track > span {\n width: 100%;\n background: var(--tcw-accent);\n animation: tcw-loading-breathe 2.4s ease-in-out infinite;\n }\n}\n\n@keyframes tcw-candle-glow {\n 0%, 60%, 100% { opacity: 0.28; }\n 25% { opacity: 0.9; }\n}\n\n@keyframes tcw-loading-breathe {\n 0%, 100% { opacity: 0.15; }\n 50% { opacity: 0.7; }\n}\n\n/* === On-chart indicator legend (WidgetIndicatorLegend) === */\n\n.tcw-ind-legend {\n position: absolute;\n z-index: 3;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 1px;\n max-width: calc(100% - 140px);\n pointer-events: none;\n}\n\n.tcw-ind-legend--collapsed > .tcw-ind-legend-row {\n display: none;\n}\n\n.tcw-ind-legend-row {\n display: flex;\n align-items: center;\n gap: 8px;\n max-width: 100%;\n padding: 0 4px;\n border-radius: var(--tcw-radius-sm);\n font-size: var(--tcw-font-size-xs);\n line-height: 19px;\n font-feature-settings: 'tnum';\n white-space: nowrap;\n color: var(--tcw-text-dim);\n pointer-events: auto;\n cursor: default;\n /* A narrow pane: the values shrink first, then the row is clipped. */\n overflow: hidden;\n}\n\n/* A pane's indicator: at the top of its pane, where the canvas title was,\n short enough to sit in the pane's header below the divider's grab zone. */\n.tcw-ind-legend-row--pane {\n position: absolute;\n z-index: 3;\n line-height: 15px;\n}\n\n.tcw-ind-legend-row:hover,\n.tcw-ind-legend-row:focus-within {\n background: color-mix(in srgb, var(--tcw-bg-elevated) 90%, transparent);\n box-shadow: 0 0 0 1px var(--tcw-border);\n}\n\n.tcw-ind-legend-name {\n padding: 0;\n border: none;\n background: none;\n font: inherit;\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n cursor: pointer;\n}\n\n.tcw-ind-legend-name:hover {\n color: var(--tcw-accent);\n}\n\n.tcw-ind-legend-values {\n display: inline-flex;\n gap: 7px;\n min-width: 0;\n overflow: hidden;\n}\n\n.tcw-ind-legend-row--hidden .tcw-ind-legend-name,\n.tcw-ind-legend-row--hidden .tcw-ind-legend-values {\n opacity: 0.45;\n}\n\n/* Show / settings / remove: on hover or keyboard focus (always on touch). */\n.tcw-ind-legend-actions {\n display: none;\n gap: 1px;\n margin-left: -2px;\n}\n\n.tcw-ind-legend-row:hover .tcw-ind-legend-actions,\n.tcw-ind-legend-row:focus-within .tcw-ind-legend-actions {\n display: inline-flex;\n}\n\n@media (hover: none) {\n .tcw-ind-legend-actions {\n display: inline-flex;\n }\n\n /* Finger-sized targets. */\n .tcw-ind-legend-act,\n .tcw-ind-legend-toggle {\n min-width: 28px;\n min-height: 24px;\n }\n}\n\n.tcw-ind-legend-act {\n display: inline-grid;\n place-items: center;\n width: 20px;\n height: 18px;\n padding: 0;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n}\n\n.tcw-ind-legend-act:hover {\n color: var(--tcw-text);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-ind-legend-act[data-act='remove']:hover {\n color: var(--tcw-red);\n}\n\n.tcw-ind-legend-toggle {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n margin-top: 1px;\n padding: 1px 5px;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n font: inherit;\n font-size: var(--tcw-font-size-xs);\n cursor: pointer;\n pointer-events: auto;\n}\n\n.tcw-ind-legend-toggle[hidden] {\n display: none;\n}\n\n.tcw-ind-legend-toggle:hover {\n color: var(--tcw-text);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-ind-legend-name:focus-visible,\n.tcw-ind-legend-act:focus-visible,\n.tcw-ind-legend-toggle:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: -2px;\n}\n\n/* === Sidebar === */\n\n.tcw-sidebar {\n width: var(--tcw-sidebar-w);\n flex-shrink: 0;\n background: linear-gradient(180deg, var(--tcw-bg-elevated) 0%, var(--tcw-bg-surface) 100%);\n border-inline-end: var(--tcw-border-w) solid var(--tcw-border);\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 6px 0;\n /* On a short screen the tools scroll; the menus sit outside it. */\n overflow-x: hidden;\n overflow-y: auto;\n scrollbar-width: none;\n box-shadow: var(--tcw-shadow-sm);\n}\n.tcw-sidebar::-webkit-scrollbar {\n display: none;\n}\n.tcw-sidebar > * {\n flex-shrink: 0;\n}\n\n.tcw-tool-group-wrap {\n position: relative;\n}\n\n.tcw-sidebar-btn {\n width: var(--tcw-control-h);\n height: var(--tcw-control-h);\n margin: 1px 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n font-family: inherit;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n color var(--tcw-dur-fast) var(--tcw-ease);\n position: relative;\n flex-shrink: 0;\n line-height: 1;\n border-radius: var(--tcw-control-radius);\n}\n\n.tcw-sidebar-btn svg {\n width: var(--tcw-icon);\n height: var(--tcw-icon);\n}\n\n.tcw-sidebar-btn:hover {\n color: var(--tcw-text);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-sidebar-btn.tcw-active {\n color: var(--tcw-on-icon-fg);\n background: var(--tcw-on-icon-bg);\n box-shadow: var(--tcw-on-icon-ring);\n}\n\n.tcw-sidebar-btn.tcw-danger:hover {\n color: var(--tcw-red);\n background: var(--tcw-red-soft);\n}\n\n.tcw-multi-dot {\n position: absolute;\n bottom: 3px;\n right: 3px;\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n opacity: 0.7;\n}\n\n/* The drawing tools' sections: always a hairline (it groups the tools), even in\n looks that drop the rules between toolbar groups. */\n.tcw-sidebar-divider {\n width: 20px;\n height: max(1px, var(--tcw-sep-w));\n background: var(--tcw-divider);\n margin: 5px 0;\n flex-shrink: 0;\n}\n\n.tcw-sidebar-spacer {\n flex: 1;\n}\n\n/* === Flyout === */\n\n.tcw-flyout {\n position: absolute;\n margin-inline-start: 6px;\n overflow-y: auto;\n overscroll-behavior: contain;\n min-width: 180px;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n z-index: 30;\n padding: 6px;\n backdrop-filter: blur(var(--tcw-blur));\n -webkit-backdrop-filter: blur(var(--tcw-blur));\n animation: tcw-slide-right var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n/* Spans the gap to the toolbar button: crossing it stays inside the menu. */\n.tcw-flyout::before {\n content: '';\n position: absolute;\n top: -1px;\n bottom: -1px;\n right: 100%;\n width: 8px;\n}\n\n@keyframes tcw-slide-right {\n from { opacity: 0; transform: translateX(-4px); }\n to { opacity: 1; transform: translateX(0); }\n}\n\n.tcw-flyout-header {\n text-transform: var(--tcw-label-case);\n font-size: calc(var(--tcw-font-size) - 3px);\n color: var(--tcw-text-muted);\n letter-spacing: var(--tcw-label-tracking);\n padding: 6px 10px 4px;\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-flyout-hint {\n padding: 6px 10px 2px;\n border-top: 1px solid var(--tcw-border);\n margin-top: 4px;\n font-size: calc(var(--tcw-font-size) - 2.5px);\n color: var(--tcw-text-muted);\n}\n\n.tcw-flyout-item {\n min-height: var(--tcw-menu-item-h);\n padding: 4px 10px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n cursor: pointer;\n width: 100%;\n display: flex;\n align-items: center;\n gap: 10px;\n border: none;\n background: transparent;\n text-align: start;\n font-family: inherit;\n border-radius: var(--tcw-radius-sm);\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-flyout-item:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n.tcw-flyout-item:focus-visible {\n outline: none;\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n box-shadow: inset 0 0 0 1px var(--tcw-accent);\n}\n\n.tcw-flyout-item.tcw-active {\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n font-weight: var(--tcw-weight-strong);\n}\n\n/* Pinned (favorited) flyout item — the icon set's star, filled, on the right. */\n.tcw-flyout-star {\n display: inline-flex;\n margin-inline-start: auto;\n color: var(--tcw-accent);\n}\n.tcw-flyout-star svg path { fill: currentColor; }\n\n/* Favorites strip — pinned drawing tools above the tool groups. */\n.tcw-sidebar-favorites {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.tcw-sidebar-favorites .tcw-sidebar-btn {\n position: relative;\n}\n.tcw-sidebar-favorites .tcw-sidebar-btn::before {\n content: '';\n position: absolute;\n top: 3px;\n right: 3px;\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--tcw-accent);\n opacity: 0.7;\n}\n\n/* === Modal === */\n\n.tcw-modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(8, 10, 18, 0.55);\n backdrop-filter: blur(6px) saturate(140%);\n -webkit-backdrop-filter: blur(6px) saturate(140%);\n z-index: 100;\n animation: tcw-fade-in var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n@keyframes tcw-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.tcw-modal {\n position: fixed;\n z-index: 101;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-dialog-radius);\n width: 520px;\n max-width: 92vw;\n max-height: 82vh;\n display: flex;\n flex-direction: column;\n box-shadow: var(--tcw-dialog-shadow);\n animation: tcw-modal-in var(--tcw-dur-slow) var(--tcw-ease-out);\n}\n\n@keyframes tcw-modal-in {\n from { opacity: 0; transform: translate(-50%, -48%) scale(0.96); }\n to { opacity: 1; transform: translate(-50%, -50%) scale(1); }\n}\n\n.tcw-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 22px;\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n.tcw-modal-header h3 {\n font-size: var(--tcw-font-size-lg);\n font-weight: var(--tcw-weight-strong);\n margin: 0;\n color: var(--tcw-text);\n letter-spacing: -0.015em;\n}\n\n.tcw-modal-close {\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n border-radius: var(--tcw-control-radius);\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-modal-close:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-modal-tabs {\n display: flex;\n /* Four tabs in a long language on a phone: they wrap rather than clip. No overflow here: in the\n dialog's column it would let a long body squash the tabs, and clip the underline of the active one. */\n flex-wrap: wrap;\n flex-shrink: 0;\n gap: 4px;\n padding: var(--tcw-tabs-pad-block) 18px;\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n.tcw-modal-tab {\n flex-shrink: 0;\n white-space: nowrap;\n height: var(--tcw-tab-h);\n padding: var(--tcw-tab-pad);\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight);\n color: var(--tcw-text-muted);\n border: none;\n background: transparent;\n cursor: pointer;\n border-bottom: var(--tcw-tab-line) solid transparent;\n border-radius: var(--tcw-tab-radius);\n margin-bottom: calc(var(--tcw-tab-line) / -2);\n transition: color var(--tcw-dur-fast) var(--tcw-ease), border-color var(--tcw-dur-fast) var(--tcw-ease);\n font-family: inherit;\n text-transform: capitalize;\n letter-spacing: -0.005em;\n}\n\n.tcw-modal-tab:hover {\n color: var(--tcw-text-dim);\n background: var(--tcw-tab-hover);\n}\n\n.tcw-modal-tab.tcw-active {\n color: var(--tcw-tab-on-fg);\n background: var(--tcw-tab-on-bg);\n border-bottom-color: var(--tcw-accent);\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-modal-body {\n padding: 20px 22px;\n overflow-y: auto;\n flex: 1;\n}\n\n.tcw-settings-section {\n margin-bottom: 22px;\n}\n\n.tcw-settings-section:last-child {\n margin-bottom: 0;\n}\n\n.tcw-settings-section-title {\n font-size: calc(var(--tcw-font-size) - 2.5px);\n font-weight: var(--tcw-weight-strong);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n color: var(--tcw-text-muted);\n margin-bottom: 12px;\n}\n\n.tcw-settings-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 0;\n}\n\n.tcw-settings-row + .tcw-settings-row {\n border-top: 1px solid var(--tcw-divider);\n}\n\n.tcw-settings-label {\n font-size: var(--tcw-font-size);\n color: var(--tcw-text-dim);\n letter-spacing: -0.005em;\n}\n\n.tcw-color-picker-wrap {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tcw-color-picker-wrap input[type='color'] {\n width: 28px;\n height: 28px;\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-radius-sm);\n background: transparent;\n cursor: pointer;\n padding: 2px;\n}\n\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch-wrapper {\n padding: 0;\n}\n\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch {\n border: none;\n border-radius: var(--tcw-radius-xs);\n}\n\n.tcw-color-hex {\n font-size: var(--tcw-font-size-xs);\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n min-width: 64px;\n letter-spacing: 0.01em;\n}\n\n/* A colour left to the part itself: the swatch shows where the picker starts, faded. */\n.tcw-color-auto input[type='color'] {\n opacity: 0.45;\n border-style: dashed;\n}\n\n.tcw-color-auto .tcw-color-hex {\n font-family: inherit;\n font-style: italic;\n}\n\n.tcw-color-auto-btn {\n height: 24px;\n padding: 0 8px;\n font: inherit;\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n background: transparent;\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-radius-sm);\n cursor: pointer;\n transition: color var(--tcw-dur-fast) var(--tcw-ease), border-color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-color-auto-btn:hover,\n.tcw-color-auto-btn:focus-visible {\n color: var(--tcw-text);\n border-color: var(--tcw-accent);\n}\n\n.tcw-toggle {\n width: 36px;\n height: 20px;\n background: rgba(255, 255, 255, 0.12);\n border-radius: 10px;\n position: relative;\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease);\n border: none;\n padding: 0;\n flex-shrink: 0;\n}\n\n.tcw-toggle::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n transition:\n left var(--tcw-dur-normal) var(--tcw-ease-out),\n background var(--tcw-dur-fast) var(--tcw-ease);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n}\n\n.tcw-toggle.tcw-on {\n background: var(--tcw-accent);\n box-shadow: 0 0 0 2px var(--tcw-accent-glow);\n}\n\n.tcw-toggle.tcw-on::after {\n left: 18px;\n background: #fff;\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle {\n background: rgba(0, 0, 0, 0.12);\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle::after {\n background: #999;\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle.tcw-on {\n background: var(--tcw-accent);\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle.tcw-on::after {\n background: #fff;\n}\n\n.tcw-settings-select {\n padding: 6px 10px;\n font-size: var(--tcw-font-size-sm);\n font-family: inherit;\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-input-radius);\n color: var(--tcw-text);\n cursor: pointer;\n transition: border-color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-settings-select:hover {\n border-color: var(--tcw-border-strong);\n}\n\n.tcw-settings-select:focus-visible {\n outline: none;\n border-color: var(--tcw-accent);\n box-shadow: var(--tcw-ring);\n}\n\n.tcw-modal-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 22px;\n border-top: 1px solid var(--tcw-divider);\n background: var(--tcw-bg-surface);\n border-radius: 0 0 var(--tcw-dialog-radius) var(--tcw-dialog-radius);\n}\n\n.tcw-reset-link {\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-muted);\n cursor: pointer;\n border: none;\n background: transparent;\n font-family: inherit;\n text-decoration: underline;\n text-underline-offset: 2px;\n text-decoration-color: var(--tcw-border-strong);\n transition: color var(--tcw-dur-fast) var(--tcw-ease), text-decoration-color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-reset-link:hover {\n color: var(--tcw-text-dim);\n text-decoration-color: currentColor;\n}\n\n.tcw-done-btn {\n padding: 8px 18px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n background: var(--tcw-accent);\n color: var(--tcw-accent-ink);\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n font-family: inherit;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n transform var(--tcw-dur-fast) var(--tcw-ease),\n box-shadow var(--tcw-dur-fast) var(--tcw-ease);\n letter-spacing: -0.005em;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.15);\n}\n\n.tcw-done-btn:hover {\n background: var(--tcw-accent-hover);\n box-shadow: var(--tcw-shadow-md), 0 0 0 3px var(--tcw-accent-glow);\n}\n\n.tcw-done-btn:active {\n transform: translateY(0.5px);\n}\n\n/* === Status Bar === */\n\n.tcw-statusbar {\n /* Above sidebar buttons that overflow a short chart; menus (z 30+) stay on top. */\n position: relative;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 7px 16px;\n border-top: 1px solid var(--tcw-border);\n background: var(--tcw-bg-surface);\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n flex-shrink: 0;\n font-feature-settings: 'tnum';\n}\n\n.tcw-status-right {\n display: flex;\n align-items: center;\n gap: 14px;\n margin-inline-start: auto;\n min-width: 0;\n white-space: nowrap;\n}\n\n/* Narrow screens: the toolbar already names the symbol and timeframe, so the\n range bar gets the room. */\n@media (max-width: 640px) {\n .tcw-status-info {\n display: none;\n }\n\n .tcw-range-btn {\n padding: 4px 5px;\n }\n}\n\n/* Range presets + go to date, bottom left */\n.tcw-range-bar {\n display: flex;\n align-items: center;\n gap: 1px;\n margin: -4px 12px -4px -8px;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.tcw-range-bar::-webkit-scrollbar {\n display: none;\n}\n\n.tcw-range-btn {\n flex-shrink: 0;\n padding: 4px 7px;\n font: inherit;\n font-weight: var(--tcw-weight-strong);\n letter-spacing: 0.02em;\n color: var(--tcw-text-muted);\n background: transparent;\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n transition: color var(--tcw-dur-fast) var(--tcw-ease), background var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-range-btn:hover {\n color: var(--tcw-text);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-range-btn:active {\n color: var(--tcw-accent);\n}\n\n.tcw-range-btn:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: -2px;\n}\n\n.tcw-range-goto {\n display: inline-grid;\n place-items: center;\n margin-inline-start: 6px;\n padding: 4px 6px;\n}\n\n.tcw-range-goto svg {\n display: block;\n}\n\n/* Go-to-date popover, anchored above the range bar */\n.tcw-goto {\n position: absolute;\n left: 10px;\n bottom: 40px;\n z-index: 40;\n display: grid;\n gap: 10px;\n width: 232px;\n padding: 14px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n color: var(--tcw-text);\n font-size: var(--tcw-font-size-sm);\n}\n\n.tcw-goto-title {\n font-weight: var(--tcw-weight-strong);\n font-size: var(--tcw-font-size);\n}\n\n.tcw-goto-field {\n display: grid;\n gap: 4px;\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size-xs);\n}\n\n.tcw-goto-input {\n height: 30px;\n padding: 0 8px;\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n background: var(--tcw-bg);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-input-radius);\n color-scheme: dark;\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-goto-input {\n color-scheme: light;\n}\n\n.tcw-goto-input:focus {\n outline: none;\n border-color: var(--tcw-accent);\n box-shadow: 0 0 0 2px var(--tcw-accent-soft);\n}\n\n.tcw-goto-actions {\n display: flex;\n justify-content: flex-end;\n gap: 6px;\n}\n\n.tcw-goto-submit {\n background: var(--tcw-accent);\n color: var(--tcw-accent-ink);\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-goto-submit:hover {\n background: var(--tcw-accent);\n color: var(--tcw-accent-ink);\n filter: brightness(1.08);\n}\n\n.tcw-status-indicator {\n display: flex;\n align-items: center;\n gap: 7px;\n font-weight: var(--tcw-weight);\n}\n\n.tcw-status-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n transition: background var(--tcw-dur-normal) var(--tcw-ease), box-shadow var(--tcw-dur-normal) var(--tcw-ease);\n position: relative;\n}\n\n.tcw-status-dot.tcw-connected {\n background: var(--tcw-green);\n box-shadow: 0 0 0 3px rgba(31, 168, 116, 0.18);\n}\n\n.tcw-status-dot.tcw-connected::after {\n content: '';\n position: absolute;\n inset: -3px;\n border-radius: 50%;\n border: 2px solid var(--tcw-green);\n opacity: 0;\n animation: tcw-pulse 2.2s ease-out infinite;\n}\n\n@keyframes tcw-pulse {\n 0% { opacity: 0.6; transform: scale(0.6); }\n 100% { opacity: 0; transform: scale(2.2); }\n}\n\n.tcw-status-dot.tcw-error {\n background: var(--tcw-red);\n box-shadow: 0 0 0 3px rgba(232, 80, 91, 0.2);\n}\n\n/* === Command Palette === */\n\n.tcw-cmd-palette {\n position: fixed;\n z-index: 102;\n top: 18%;\n left: 50%;\n transform: translateX(-50%);\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-dialog-radius);\n width: 560px;\n max-width: 92vw;\n max-height: 62vh;\n display: flex;\n flex-direction: column;\n box-shadow: var(--tcw-dialog-shadow);\n overflow: hidden;\n backdrop-filter: blur(var(--tcw-blur));\n -webkit-backdrop-filter: blur(var(--tcw-blur));\n animation: tcw-modal-in var(--tcw-dur-slow) var(--tcw-ease-out);\n}\n\n.tcw-cmd-header {\n display: flex;\n align-items: center;\n padding: 14px 18px;\n border-bottom: 1px solid var(--tcw-divider);\n gap: 12px;\n}\n\n.tcw-cmd-icon {\n color: var(--tcw-text-muted);\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n}\n\n.tcw-cmd-input {\n flex: 1;\n background: transparent;\n border: none;\n outline: none;\n font-size: calc(var(--tcw-font-size) + 1.5px);\n font-family: inherit;\n color: var(--tcw-text);\n caret-color: var(--tcw-accent);\n letter-spacing: -0.005em;\n}\n\n.tcw-cmd-input::placeholder {\n color: var(--tcw-text-muted);\n}\n\n.tcw-cmd-hint {\n font-size: calc(var(--tcw-font-size) - 3px);\n color: var(--tcw-text-muted);\n font-family: var(--tcw-font-mono);\n border: 1px solid var(--tcw-border);\n background: var(--tcw-bg-surface);\n padding: 3px 7px;\n border-radius: 4px;\n flex-shrink: 0;\n box-shadow: inset 0 -1px 0 var(--tcw-border);\n}\n\n.tcw-cmd-list {\n overflow-y: auto;\n flex: 1;\n padding: 6px;\n max-height: 380px;\n}\n\n.tcw-cmd-category {\n text-transform: var(--tcw-label-case);\n font-size: calc(var(--tcw-font-size) - 3px);\n color: var(--tcw-text-muted);\n letter-spacing: var(--tcw-label-tracking);\n padding: 10px 10px 4px;\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-cmd-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 9px 12px;\n font-size: var(--tcw-font-size);\n color: var(--tcw-text-dim);\n cursor: pointer;\n width: 100%;\n border: none;\n background: transparent;\n font-family: inherit;\n text-align: start;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n gap: 10px;\n border-radius: var(--tcw-radius);\n letter-spacing: -0.005em;\n}\n\n.tcw-cmd-item:hover,\n.tcw-cmd-item.tcw-selected {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-cmd-item.tcw-selected {\n box-shadow: inset 2px 0 0 var(--tcw-accent);\n}\n\n.tcw-cmd-item.tcw-active .tcw-cmd-item-label {\n color: var(--tcw-accent);\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-cmd-item-label {\n flex: 1;\n}\n\n.tcw-cmd-check {\n display: inline-flex;\n color: var(--tcw-accent);\n}\n\n.tcw-cmd-kbd {\n font-size: calc(var(--tcw-font-size) - 3px);\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n padding: 2px 6px;\n border-radius: var(--tcw-tag-radius);\n box-shadow: inset 0 -1px 0 var(--tcw-border);\n}\n\n.tcw-cmd-empty {\n padding: 32px 16px;\n text-align: center;\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size);\n}\n\n/* A key and what it does, in a list dialog's footer: keys in the shortcut chips (.tcw-cmd-kbd). */\n.tcw-cmd-help {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n}\n.tcw-cmd-help-text { margin-inline-start: 3px; }\n.tcw-cmd-key {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n font-style: normal;\n}\n\n.tcw-cmd-footer {\n display: flex;\n align-items: center;\n gap: 18px;\n padding: 10px 18px;\n border-top: 1px solid var(--tcw-divider);\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n background: var(--tcw-bg-surface);\n}\n\n/* === Watchlist === */\n\n.tcw-watchlist {\n width: 220px;\n flex-shrink: 0;\n background: var(--tcw-bg-surface);\n border-inline-start: 1px solid var(--tcw-border);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-shadow: var(--tcw-shadow-sm);\n}\n\n.tcw-watchlist-header {\n position: relative;\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 6px 8px 6px 8px;\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n/* The shown list's name: opens the lists menu. */\n.tcw-watchlist-name {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 6px;\n height: var(--tcw-control-h-sm);\n padding: 0 6px;\n border: 0;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-dim);\n font: inherit;\n font-size: var(--tcw-font-size-xs);\n font-weight: var(--tcw-weight-strong);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n text-align: start;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n cursor: pointer;\n}\n.tcw-watchlist-name::after {\n content: '';\n flex: none;\n width: 0;\n height: 0;\n margin-inline-start: auto;\n border: 4px solid transparent;\n border-top-color: currentColor;\n border-bottom-width: 0;\n opacity: 0.7;\n}\n\n.tcw-watchlist-add {\n flex: none;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: 0;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n font: inherit;\n font-size: var(--tcw-font-size-lg);\n line-height: 1;\n cursor: pointer;\n}\n\n.tcw-watchlist-name:hover,\n.tcw-watchlist-add:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n.tcw-watchlist-name:focus-visible,\n.tcw-watchlist-add:focus-visible,\n.tcw-watchlist-input:focus-visible {\n outline: none;\n box-shadow: var(--tcw-ring);\n}\n\n/* The lists menu, under the header. */\n.tcw-watchlist-menu {\n top: calc(100% - 2px);\n left: 6px;\n right: 6px;\n margin-top: 0;\n}\n.tcw-watchlist-count {\n color: var(--tcw-text-muted);\n font-family: var(--tcw-font-mono);\n font-size: var(--tcw-font-size-xs);\n}\n.tcw-watchlist-menu .tcw-danger {\n color: var(--tcw-red);\n}\n\n/* Naming a list in place. */\n.tcw-watchlist-input {\n flex: 1;\n min-width: 0;\n height: var(--tcw-control-h-sm);\n padding: 0 8px;\n border: var(--tcw-border-w) solid var(--tcw-border-strong);\n border-radius: var(--tcw-input-radius);\n background: var(--tcw-bg);\n color: var(--tcw-text);\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n}\n\n.tcw-watchlist-empty {\n padding: 16px 14px;\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size-sm);\n line-height: 1.5;\n}\n\n/* A row's remove button shows on hover or focus, over its numbers. */\n.tcw-watchlist-remove {\n position: absolute;\n top: 50%;\n right: 6px;\n display: grid;\n place-items: center;\n width: 20px;\n height: 20px;\n border: 0;\n border-radius: var(--tcw-radius-sm);\n background: var(--tcw-bg-elevated);\n color: var(--tcw-text-muted);\n font: inherit;\n font-size: var(--tcw-font-size);\n line-height: 1;\n opacity: 0;\n transform: translateY(-50%);\n cursor: pointer;\n transition: opacity var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-watchlist-row:hover .tcw-watchlist-remove,\n.tcw-watchlist-row:focus-within .tcw-watchlist-remove {\n opacity: 1;\n}\n.tcw-watchlist-remove:hover {\n color: var(--tcw-red);\n}\n.tcw-watchlist-row.tcw-watchlist-dragging {\n opacity: 0.45;\n}\n\n.tcw-watchlist-list {\n flex: 1;\n overflow-y: auto;\n padding: 4px 0;\n}\n\n.tcw-watchlist-row {\n position: relative;\n display: grid;\n grid-template-columns: 1fr auto auto;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease);\n border-inline-start: 2px solid transparent;\n outline: none;\n}\n\n.tcw-watchlist-row:hover {\n background: var(--tcw-hover-bg);\n}\n\n.tcw-watchlist-row:focus-visible {\n background: var(--tcw-hover-bg);\n border-inline-start-color: var(--tcw-accent);\n}\n\n.tcw-watchlist-row.tcw-watchlist-active {\n background: var(--tcw-accent-soft);\n border-inline-start-color: var(--tcw-accent);\n}\n\n.tcw-watchlist-symbol {\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n letter-spacing: -0.005em;\n white-space: nowrap;\n}\n\n.tcw-watchlist-spark {\n width: 56px;\n height: 22px;\n align-self: center;\n}\n\n.tcw-watchlist-stats {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 1px;\n font-variant-numeric: tabular-nums;\n font-family: var(--tcw-font-mono);\n}\n\n.tcw-watchlist-price {\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n font-weight: var(--tcw-weight);\n}\n\n.tcw-watchlist-change {\n font-size: calc(var(--tcw-font-size) - 2.5px);\n color: var(--tcw-text-muted);\n font-weight: var(--tcw-weight);\n}\n\n.tcw-watchlist-change.tcw-up {\n color: var(--tcw-green);\n}\n\n.tcw-watchlist-change.tcw-down {\n color: var(--tcw-red);\n}\n\n@media (max-width: 768px) {\n .tcw-watchlist {\n display: none;\n }\n}\n\n/* === Toast === */\n\n.tcw-toast-icon {\n display: inline-flex;\n vertical-align: -2px;\n margin-inline-end: 7px;\n color: var(--tcw-accent);\n}\n.tcw-toast-error .tcw-toast-icon { color: var(--tcw-red); }\n\n.tcw-toast {\n position: absolute;\n bottom: 60px;\n left: 50%;\n transform: translate(-50%, 12px);\n z-index: 40;\n padding: 9px 14px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-toast-radius);\n box-shadow: var(--tcw-menu-shadow);\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight);\n color: var(--tcw-text);\n opacity: 0;\n transition: opacity var(--tcw-dur-normal) var(--tcw-ease-out), transform var(--tcw-dur-normal) var(--tcw-ease-out);\n pointer-events: none;\n max-width: calc(100% - 32px);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n letter-spacing: -0.005em;\n}\n\n.tcw-toast.tcw-toast-in {\n opacity: 1;\n transform: translate(-50%, 0);\n}\n\n.tcw-toast-error {\n border-color: var(--tcw-red);\n color: var(--tcw-red);\n}\n\n/* === Replay scrubber === */\n\n/* Picking the replay start: the bars right of the pointer would be hidden. */\n.tcw-replay-shade {\n position: absolute;\n z-index: 4;\n pointer-events: none;\n background: color-mix(in srgb, var(--tcw-bg) 62%, transparent);\n border-inline-start: 1.5px dashed var(--tcw-accent);\n}\n\n.tcw-replay-group {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.tcw-replay-group[hidden] { display: none; }\n\n.tcw-replay-hint {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 0 4px;\n color: var(--tcw-text-dim);\n white-space: nowrap;\n}\n\n.tcw-replay-text-btn {\n height: 26px;\n padding: 0 10px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text);\n font: inherit;\n font-weight: var(--tcw-weight);\n white-space: nowrap;\n cursor: pointer;\n transition: background var(--tcw-dur-fast), border-color var(--tcw-dur-fast), color var(--tcw-dur-fast);\n}\n\n.tcw-replay-text-btn:hover { background: var(--tcw-hover-bg); border-color: var(--tcw-border-strong); }\n.tcw-replay-text-btn:focus-visible { outline: none; box-shadow: var(--tcw-ring); }\n\n/* At the last bar: the way out is the next thing to do. */\n.tcw-replay-bar--ended .tcw-replay-realtime {\n background: var(--tcw-accent);\n border-color: var(--tcw-accent);\n color: var(--tcw-accent-ink);\n}\n\n.tcw-replay-btn:disabled { opacity: 0.4; cursor: default; }\n\n@media (max-width: 640px) {\n .tcw-replay-bar {\n flex-wrap: wrap;\n justify-content: center;\n max-width: calc(100% - 24px);\n border-radius: var(--tcw-panel-radius);\n }\n .tcw-replay-hint { white-space: normal; }\n}\n\n.tcw-replay-bar {\n position: absolute;\n left: 50%;\n /* Above the 30px time axis, so its dates stay readable. */\n bottom: 40px;\n transform: translateX(-50%);\n z-index: 25;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n backdrop-filter: blur(var(--tcw-blur));\n -webkit-backdrop-filter: blur(var(--tcw-blur));\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n animation: tcw-pop-in var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n.tcw-replay-btn {\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--tcw-text-dim);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n font-family: inherit;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-replay-btn:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-replay-btn.tcw-replay-play {\n background: var(--tcw-accent);\n color: var(--tcw-accent-ink);\n width: 32px;\n height: 32px;\n box-shadow: 0 0 0 3px var(--tcw-accent-glow);\n}\n\n.tcw-replay-btn.tcw-replay-play:hover {\n background: var(--tcw-accent-hover);\n}\n\n.tcw-replay-scrubber {\n appearance: none;\n -webkit-appearance: none;\n width: 220px;\n height: 4px;\n background: var(--tcw-border-strong);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n}\n\n.tcw-replay-scrubber::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--tcw-accent);\n border: 2px solid var(--tcw-bg-elevated);\n box-shadow: 0 0 0 1px var(--tcw-accent), 0 2px 6px rgba(0, 0, 0, 0.3);\n cursor: pointer;\n}\n\n.tcw-replay-scrubber::-moz-range-thumb {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--tcw-accent);\n border: 2px solid var(--tcw-bg-elevated);\n box-shadow: 0 0 0 1px var(--tcw-accent), 0 2px 6px rgba(0, 0, 0, 0.3);\n cursor: pointer;\n}\n\n.tcw-replay-progress {\n font-size: var(--tcw-font-size-xs);\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n min-width: 64px;\n text-align: center;\n font-feature-settings: 'tnum';\n}\n\n.tcw-replay-speed {\n padding: 4px 8px;\n font-size: var(--tcw-font-size-xs);\n font-family: var(--tcw-font-mono);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-control-radius);\n color: var(--tcw-text-dim);\n cursor: pointer;\n}\n\n.tcw-replay-speed:hover {\n border-color: var(--tcw-border-strong);\n}\n\n@media (max-width: 640px) {\n .tcw-replay-scrubber {\n width: 140px;\n }\n .tcw-replay-progress {\n display: none;\n }\n}\n\n/* === Hotkey sheet === */\n\n.tcw-hotkey-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 24px 32px;\n}\n\n.tcw-hotkey-section .tcw-settings-section-title {\n margin-bottom: 8px;\n}\n\n.tcw-hotkey-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 6px 0;\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n.tcw-hotkey-row:last-child {\n border-bottom: none;\n}\n\n.tcw-hotkey-keys {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.tcw-hotkey-sep {\n font-size: calc(var(--tcw-font-size) - 3px);\n color: var(--tcw-text-muted);\n}\n\n.tcw-hotkey-label {\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n text-align: end;\n letter-spacing: -0.005em;\n}\n\n@media (max-width: 640px) {\n .tcw-hotkey-grid {\n grid-template-columns: 1fr;\n gap: 18px;\n }\n}\n\n/* === Scrollbar (subtle, premium feel) === */\n\n.tcw-dropdown::-webkit-scrollbar,\n.tcw-modal-body::-webkit-scrollbar,\n.tcw-cmd-list::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n.tcw-dropdown::-webkit-scrollbar-track,\n.tcw-modal-body::-webkit-scrollbar-track,\n.tcw-cmd-list::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.tcw-dropdown::-webkit-scrollbar-thumb,\n.tcw-modal-body::-webkit-scrollbar-thumb,\n.tcw-cmd-list::-webkit-scrollbar-thumb {\n background: var(--tcw-border-strong);\n border-radius: 4px;\n border: 2px solid transparent;\n background-clip: padding-box;\n}\n\n.tcw-dropdown::-webkit-scrollbar-thumb:hover,\n.tcw-modal-body::-webkit-scrollbar-thumb:hover,\n.tcw-cmd-list::-webkit-scrollbar-thumb:hover {\n background: var(--tcw-text-muted);\n background-clip: padding-box;\n border: 2px solid transparent;\n}\n\n/* === Responsive === */\n\n@media (max-width: 768px) {\n .tcw-toolbar {\n padding: 0 4px;\n height: max(44px, var(--tcw-toolbar-h)); /* Apple HIG minimum touch target */\n }\n .tcw-toolbar-sep {\n display: none;\n }\n .tcw-btn,\n .tcw-dropdown-trigger {\n height: max(40px, var(--tcw-control-h)); /* fatter tap target */\n padding: 0 12px;\n font-size: var(--tcw-font-size);\n }\n .tcw-btn-icon {\n width: max(40px, var(--tcw-control-h));\n height: max(40px, var(--tcw-control-h));\n }\n .tcw-sidebar {\n width: max(44px, var(--tcw-sidebar-w));\n }\n .tcw-sidebar-btn {\n width: max(40px, var(--tcw-control-h));\n height: max(40px, var(--tcw-control-h));\n }\n .tcw-modal,\n .tcw-cmd-palette {\n width: 94vw;\n border-radius: var(--tcw-dialog-radius);\n }\n\n /* Hide the right-side watchlist on tablets too — already declared but\n * grouped here for clarity. */\n .tcw-watchlist {\n display: none;\n }\n\n /* Replay scrubber compact mode */\n .tcw-replay-scrubber {\n width: 120px;\n }\n .tcw-replay-progress {\n display: none;\n }\n}\n\n/* === Mobile bottom-sheet pattern ===\n * On phones, swap floating-centered modals for full-width sheets that slide\n * up from the bottom. Bigger hit targets, no awkward off-screen clipping,\n * matches how every modern iOS/Android app handles overflow UI.\n */\n@media (max-width: 640px) {\n .tcw-modal,\n .tcw-cmd-palette {\n top: auto;\n bottom: 0;\n left: 0;\n right: 0;\n transform: none;\n width: 100vw;\n max-width: 100vw;\n max-height: 92vh;\n border-radius: var(--tcw-dialog-radius) var(--tcw-dialog-radius) 0 0;\n border-bottom: none;\n /* Grab handle */\n padding-top: 8px;\n }\n\n /* Visual \"grab handle\" affordance — a short pill at the top of every sheet */\n .tcw-modal::before,\n .tcw-cmd-palette::before {\n content: '';\n display: block;\n width: 36px;\n height: 4px;\n border-radius: 2px;\n background: var(--tcw-border-strong);\n margin: 0 auto 8px;\n opacity: 0.7;\n }\n\n /* Reuse the existing modal-in animation but slide from below instead of\n * popping from center, so the entrance reads as a sheet, not a dialog. */\n @keyframes tcw-modal-in {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .tcw-modal,\n .tcw-cmd-palette {\n animation: tcw-modal-in var(--tcw-dur-slow) var(--tcw-ease-out);\n }\n\n /* Safe-area-aware footer padding for iPhone notch / home indicator */\n .tcw-modal-footer,\n .tcw-cmd-footer {\n padding-bottom: max(14px, env(safe-area-inset-bottom));\n }\n\n /* Larger tap targets inside sheets */\n .tcw-modal-tab {\n padding: 14px 16px;\n }\n .tcw-cmd-item {\n padding: 12px 14px;\n font-size: calc(var(--tcw-font-size) + 1px);\n }\n .tcw-dropdown-item {\n padding: 12px 12px;\n font-size: calc(var(--tcw-font-size) + 1px);\n }\n\n /* Hotkey sheet — single column on phones */\n .tcw-hotkey-grid {\n grid-template-columns: 1fr;\n }\n}\n\n/* === Price alerts panel === */\n\n.tcw-alerts-panel {\n position: absolute;\n top: var(--tcw-panel-top);\n inset-inline-end: 12px;\n z-index: 40;\n width: 300px;\n max-width: calc(100vw - 24px);\n display: flex;\n flex-direction: column;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n overflow: hidden;\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n\n@keyframes tcw-alerts-in {\n from { opacity: 0; transform: translateY(-6px) scale(0.98); }\n to { opacity: 1; transform: none; }\n}\n\n.tcw-alerts-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n font-weight: var(--tcw-weight-strong);\n font-size: var(--tcw-font-size);\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-border);\n}\n\n.tcw-alerts-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-alerts-close:hover {\n background: var(--tcw-bg-surface);\n color: var(--tcw-text);\n}\n\n.tcw-alerts-form {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n padding: 12px;\n border-bottom: 1px solid var(--tcw-border);\n}\n\n.tcw-alerts-form input,\n.tcw-alerts-form select {\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n height: 32px;\n padding: 0 8px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-sm);\n outline: none;\n}\n.tcw-alerts-form input:focus,\n.tcw-alerts-form select:focus {\n border-color: var(--tcw-accent);\n box-shadow: 0 0 0 2px var(--tcw-accent-soft);\n}\n.tcw-alerts-message,\n.tcw-alerts-source {\n grid-column: 1 / -1;\n}\n\n.tcw-alerts-add {\n grid-column: 1 / -1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 34px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-accent-ink);\n background: var(--tcw-accent);\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-alerts-add:hover {\n background: var(--tcw-accent-hover);\n}\n\n.tcw-alerts-list {\n max-height: 260px;\n overflow-y: auto;\n padding: 6px;\n}\n\n.tcw-alerts-empty {\n padding: 18px 12px;\n text-align: center;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-muted);\n line-height: 1.5;\n}\n\n.tcw-alerts-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 8px 8px;\n border-radius: var(--tcw-radius-sm);\n}\n.tcw-alerts-row:hover {\n background: var(--tcw-bg-surface);\n}\n.tcw-alerts-triggered {\n background: var(--tcw-accent-soft);\n}\n\n.tcw-alerts-info {\n min-width: 0;\n}\n.tcw-alerts-row-main {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n font-variant-numeric: tabular-nums;\n}\n.tcw-alerts-row-note {\n margin-top: 2px;\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.tcw-alerts-badge {\n font-size: calc(var(--tcw-font-size) - 4px);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n padding: 2px 5px;\n border-radius: var(--tcw-tag-radius);\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n}\n\n.tcw-alerts-del {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-alerts-del:hover {\n background: var(--tcw-red-soft);\n color: var(--tcw-red);\n}\n\n@media (max-width: 640px) {\n .tcw-alerts-panel {\n top: auto;\n bottom: 0;\n left: 0;\n right: 0;\n width: 100vw;\n max-width: 100vw;\n border-radius: var(--tcw-radius-xl) var(--tcw-radius-xl) 0 0;\n }\n .tcw-alerts-list {\n max-height: 40vh;\n padding-bottom: max(8px, env(safe-area-inset-bottom));\n }\n}\n\n/* === Data Window === */\n\n.tcw-datawin {\n position: absolute;\n top: var(--tcw-panel-top);\n inset-inline-end: 12px;\n z-index: 38;\n width: 200px;\n display: flex;\n flex-direction: column;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n overflow: hidden;\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n.tcw-datawin-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 9px 12px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-datawin-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-datawin-close:hover { background: var(--tcw-bg-surface); color: var(--tcw-text); }\n.tcw-datawin-body { padding: 6px 4px; max-height: 360px; overflow-y: auto; }\n.tcw-datawin-empty { padding: 14px; text-align: center; font-size: var(--tcw-font-size-sm); color: var(--tcw-text-muted); }\n.tcw-datawin-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n padding: 3px 8px;\n font-size: var(--tcw-font-size-sm);\n}\n.tcw-datawin-label { color: var(--tcw-text-muted); }\n.tcw-datawin-value { color: var(--tcw-text); font-variant-numeric: tabular-nums; font-weight: var(--tcw-weight-strong); }\n.tcw-datawin-value.tcw-up { color: var(--tcw-green); }\n.tcw-datawin-value.tcw-down { color: var(--tcw-red); }\n.tcw-datawin-sub {\n margin: 6px 8px 2px;\n font-size: calc(var(--tcw-font-size) - 3px);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n color: var(--tcw-text-muted);\n border-top: 1px solid var(--tcw-border);\n padding-top: 6px;\n}\n\n@media (max-width: 640px) {\n .tcw-datawin { top: auto; bottom: 0; left: 0; right: 0; width: 100vw; border-radius: var(--tcw-radius-xl) var(--tcw-radius-xl) 0 0; }\n}\n\n/* === Depth-of-market ladder === */\n\n.tcw-ladder {\n position: absolute;\n top: var(--tcw-panel-top);\n inset-inline-end: 12px;\n z-index: 41;\n width: 240px;\n display: flex;\n flex-direction: column;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n overflow: hidden;\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n.tcw-ladder-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n font-size: var(--tcw-font-size);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-ladder-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-ladder-close:hover { background: var(--tcw-bg-surface); color: var(--tcw-text); }\n.tcw-ladder-cols {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n padding: 4px 0;\n font-size: calc(var(--tcw-font-size) - 3px);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n color: var(--tcw-text-muted);\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-ladder-cols span { text-align: center; }\n.tcw-ladder-body { max-height: 360px; overflow-y: auto; }\n.tcw-ladder-empty { padding: 18px; text-align: center; font-size: var(--tcw-font-size-sm); color: var(--tcw-text-muted); }\n\n.tcw-ladder-row {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n height: 22px;\n font-variant-numeric: tabular-nums;\n}\n.tcw-ladder-cell {\n position: relative;\n display: flex;\n align-items: center;\n border: none;\n background: transparent;\n font-size: var(--tcw-font-size-xs);\n cursor: pointer;\n font-variant-numeric: tabular-nums;\n overflow: hidden;\n}\n.tcw-ladder-cell:disabled { cursor: default; }\n/* Depth bar grows from the centre column outward. */\n.tcw-ladder-cell::before {\n content: '';\n position: absolute;\n top: 1px; bottom: 1px;\n width: var(--w, 0%);\n}\n.tcw-ladder-bid { justify-content: flex-end; padding-right: 8px; color: var(--tcw-green); }\n.tcw-ladder-bid::before { right: 0; background: var(--tcw-green-soft); }\n.tcw-ladder-bid span, .tcw-ladder-bid { position: relative; }\n.tcw-ladder-ask { justify-content: flex-start; padding-left: 8px; color: var(--tcw-red); }\n.tcw-ladder-ask::before { left: 0; background: var(--tcw-red-soft); }\n.tcw-ladder-cell:not(:disabled):hover::before { opacity: 0.7; filter: brightness(1.4); }\n.tcw-ladder-cell > * { position: relative; }\n.tcw-ladder-price {\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: var(--tcw-font-size-xs);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text-dim);\n border-inline-start: 1px solid var(--tcw-border);\n border-inline-end: 1px solid var(--tcw-border);\n}\n.tcw-ladder-price.tcw-ask { color: var(--tcw-red); }\n.tcw-ladder-price.tcw-bid { color: var(--tcw-green); }\n\n@media (max-width: 640px) {\n .tcw-ladder { top: auto; bottom: 0; left: 0; right: 0; width: 100vw; border-radius: var(--tcw-radius-xl) var(--tcw-radius-xl) 0 0; }\n .tcw-ladder-body { max-height: 45vh; padding-bottom: max(0px, env(safe-area-inset-bottom)); }\n}\n\n/* === Bracket order placement === */\n\n.tcw-btn-long:hover { color: var(--tcw-green) !important; }\n.tcw-btn-short:hover { color: var(--tcw-red) !important; }\n\n.tcw-bracket-bar {\n position: absolute;\n top: calc(var(--tcw-panel-top) + 2px);\n left: 50%;\n transform: translateX(-50%);\n z-index: 45;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 7px 8px 7px 14px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n.tcw-bracket-label {\n font-size: var(--tcw-font-size-sm);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n}\n.tcw-bracket-label[data-side='buy'] { color: var(--tcw-green); }\n.tcw-bracket-label[data-side='sell'] { color: var(--tcw-red); }\n.tcw-bracket-hint {\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n}\n.tcw-bracket-cancel, .tcw-bracket-confirm {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n height: 30px;\n padding: 0 12px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-bracket-cancel {\n color: var(--tcw-text-dim);\n background: var(--tcw-bg-surface);\n}\n.tcw-bracket-cancel:hover { color: var(--tcw-text); }\n.tcw-bracket-confirm {\n color: var(--tcw-accent-ink);\n background: var(--tcw-accent);\n}\n.tcw-bracket-confirm:hover { background: var(--tcw-accent-hover); }\n\n@media (max-width: 640px) {\n .tcw-bracket-bar { width: calc(100vw - 24px); justify-content: space-between; }\n .tcw-bracket-hint { display: none; }\n}\n\n/* === Drawing style + templates popover === */\n\n.tcw-style-panel {\n position: absolute;\n bottom: 12px;\n inset-inline-start: var(--tcw-panel-left);\n z-index: 40;\n width: 220px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n.tcw-style-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n}\n.tcw-style-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-style-close:hover { background: var(--tcw-bg-surface); color: var(--tcw-text); }\n\n.tcw-style-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }\n.tcw-style-swatch {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: 1px solid var(--tcw-border-strong);\n cursor: pointer;\n padding: 0;\n}\n.tcw-style-swatch.tcw-on { outline: 2px solid var(--tcw-accent); outline-offset: 1px; }\n.tcw-style-picker {\n width: 22px;\n height: 22px;\n padding: 0;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-sm);\n background: transparent;\n cursor: pointer;\n}\n.tcw-style-width, .tcw-style-dash {\n flex: 1;\n min-width: 0;\n height: 26px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-control-radius);\n color: var(--tcw-text-dim);\n cursor: pointer;\n font-size: var(--tcw-font-size-xs);\n}\n.tcw-style-width span { width: 16px; background: currentColor; border-radius: var(--tcw-radius-xs); }\n.tcw-style-width.tcw-on, .tcw-style-dash.tcw-on {\n border-color: var(--tcw-accent);\n color: var(--tcw-accent);\n}\n\n.tcw-style-subhead {\n font-size: calc(var(--tcw-font-size) - 3px);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n color: var(--tcw-text-muted);\n margin-top: 2px;\n}\n.tcw-style-save { display: flex; gap: 6px; }\n.tcw-style-name {\n flex: 1;\n min-width: 0;\n height: 28px;\n padding: 0 8px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-input-radius);\n outline: none;\n}\n.tcw-style-name:focus { border-color: var(--tcw-accent); }\n.tcw-style-savebtn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 10px;\n height: 28px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-accent-ink);\n background: var(--tcw-accent);\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-style-savebtn:hover { background: var(--tcw-accent-hover); }\n\n.tcw-style-templates { display: flex; flex-direction: column; gap: 2px; max-height: 140px; overflow-y: auto; }\n.tcw-style-empty { font-size: var(--tcw-font-size-xs); color: var(--tcw-text-muted); padding: 4px 0; }\n.tcw-style-template { display: flex; align-items: center; gap: 4px; }\n.tcw-style-apply {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 5px 7px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n background: transparent;\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n text-align: start;\n}\n.tcw-style-apply:hover { background: var(--tcw-bg-surface); }\n.tcw-style-tdot { flex-shrink: 0; width: 9px; height: 9px; border-radius: 50%; }\n.tcw-style-tdel {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-style-tdel:hover { background: var(--tcw-red-soft); color: var(--tcw-red); }\n\n/* === Settings range slider === */\n\n.tcw-settings-range {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.tcw-settings-range input[type='range'] {\n width: 110px;\n accent-color: var(--tcw-accent);\n cursor: pointer;\n}\n.tcw-settings-range-val {\n min-width: 38px;\n text-align: end;\n font-size: var(--tcw-font-size-sm);\n font-variant-numeric: tabular-nums;\n color: var(--tcw-text-dim);\n}\n\n/* === Indicator settings dialog === */\n\n/* Narrow on a desktop; on a phone a sheet across the screen like every dialog. */\n@media (min-width: 641px) {\n .tcw-modal-narrow {\n max-width: 360px;\n }\n}\n.tcw-indi-input {\n width: 110px;\n height: 30px;\n padding: 0 8px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-input-radius);\n outline: none;\n font-variant-numeric: tabular-nums;\n}\n.tcw-indi-input:focus {\n border-color: var(--tcw-accent);\n box-shadow: 0 0 0 2px var(--tcw-accent-soft);\n}\n.tcw-indi-select {\n width: 150px;\n padding-right: 4px;\n cursor: pointer;\n}\n/* A level: its value and a remove button. */\n.tcw-indi-level {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.tcw-indi-remove {\n display: inline-grid;\n place-items: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n padding: 0;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n}\n.tcw-indi-remove:hover {\n color: var(--tcw-red);\n background: var(--tcw-hover-bg);\n}\n.tcw-indi-remove:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: -2px;\n}\n.tcw-indi-add {\n margin-top: 8px;\n}\n.tcw-indi-color {\n width: 36px;\n height: 28px;\n padding: 2px;\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-sm);\n cursor: pointer;\n}\n\n/* === Object tree panel === */\n\n.tcw-tree-panel {\n position: absolute;\n top: var(--tcw-panel-top);\n inset-inline-end: 12px;\n z-index: 39;\n width: 280px;\n max-width: calc(100vw - 24px);\n display: flex;\n flex-direction: column;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n overflow: hidden;\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n\n.tcw-tree-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n font-weight: var(--tcw-weight-strong);\n font-size: var(--tcw-font-size);\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-tree-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-tree-close:hover {\n background: var(--tcw-bg-surface);\n color: var(--tcw-text);\n}\n\n.tcw-tree-section {\n padding: 6px;\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-tree-section:last-child {\n border-bottom: none;\n}\n.tcw-tree-section-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 8px 4px;\n font-size: calc(var(--tcw-font-size) - 3px);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n color: var(--tcw-text-muted);\n}\n.tcw-tree-add {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-tree-add:hover {\n background: var(--tcw-accent-soft);\n color: var(--tcw-accent);\n}\n.tcw-tree-dot {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n}\n.tcw-tree-list {\n max-height: 200px;\n overflow-y: auto;\n}\n\n.tcw-tree-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 6px 8px;\n border-radius: var(--tcw-radius-sm);\n}\n.tcw-tree-row:hover {\n background: var(--tcw-bg-surface);\n}\n.tcw-tree-hidden .tcw-tree-name {\n opacity: 0.5;\n}\n.tcw-tree-name {\n min-width: 0;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.tcw-tree-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-shrink: 0;\n}\n.tcw-tree-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-tree-btn:hover {\n background: var(--tcw-bg-elevated);\n color: var(--tcw-text);\n}\n.tcw-tree-btn.tcw-tree-on {\n color: var(--tcw-accent);\n}\n.tcw-tree-btn.tcw-tree-del:hover {\n background: var(--tcw-red-soft);\n color: var(--tcw-red);\n}\n.tcw-tree-group .tcw-tree-name {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: var(--tcw-weight-strong);\n}\n.tcw-tree-group .tcw-tree-name svg {\n flex: none;\n color: var(--tcw-text-muted);\n}\n.tcw-tree-member {\n margin-left: 14px;\n padding-left: 10px;\n border-inline-start: 1px solid var(--tcw-border-strong);\n border-radius: 0 var(--tcw-radius-sm) var(--tcw-radius-sm) 0;\n}\n.tcw-tree-rename {\n flex: 1;\n min-width: 0;\n padding: 3px 6px;\n border: 1px solid var(--tcw-accent-line);\n border-radius: var(--tcw-input-radius);\n background: var(--tcw-bg-surface);\n color: var(--tcw-text);\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n}\n.tcw-tree-rename:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--tcw-accent-soft);\n}\n.tcw-tree-empty {\n padding: 8px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-muted);\n}\n\n@media (max-width: 640px) {\n .tcw-tree-panel {\n top: auto;\n bottom: 0;\n left: 0;\n right: 0;\n width: 100vw;\n max-width: 100vw;\n border-radius: var(--tcw-radius-xl) var(--tcw-radius-xl) 0 0;\n }\n .tcw-tree-list {\n max-height: 30vh;\n }\n .tcw-tree-section:last-child {\n padding-bottom: max(6px, env(safe-area-inset-bottom));\n }\n}\n\n/* === Reduced motion === */\n\n@media (prefers-reduced-motion: reduce) {\n .tcw-root *,\n .tcw-root *::before,\n .tcw-root *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n /* Except the loader's slow glow (opacity only): without it a long wait\n looks frozen. */\n .tcw-root .tcw-loading-candle,\n .tcw-root .tcw-loading-track > span {\n animation-duration: 2.4s !important;\n animation-iteration-count: infinite !important;\n animation-delay: var(--tcw-delay, 0ms) !important;\n }\n}\n\n/* --- Drawing settings dialog --- */\n.tcw-drawing-settings .tcw-modal-footer { gap: 12px; }\n.tcw-drawing-settings-tools {\n display: flex;\n gap: 14px;\n margin-inline-end: auto;\n}\n.tcw-drawing-text {\n min-height: 56px;\n resize: vertical;\n font-family: inherit;\n}\n.tcw-levels-editor { display: grid; gap: 6px; margin-bottom: 10px; }\n.tcw-levels-grid {\n display: grid;\n gap: 4px;\n max-height: 260px;\n overflow-y: auto;\n padding-right: 2px;\n}\n.tcw-level-row {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) 32px 24px;\n align-items: center;\n gap: 8px;\n}\n.tcw-level-row input[type='checkbox'] { accent-color: var(--tcw-accent); }\n.tcw-level-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: 0;\n border-radius: var(--tcw-radius-sm, 4px);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n}\n.tcw-level-remove:hover { color: var(--tcw-text); background: var(--tcw-bg-elevated); }\n.tcw-level-remove:focus-visible { outline: 2px solid var(--tcw-accent); outline-offset: 1px; }\n.tcw-level-add { justify-self: start; }\n.tcw-drawing-templates { display: grid; gap: 2px; margin-bottom: 8px; }\n.tcw-drawing-alert { display: inline-flex; align-items: center; gap: 6px; }\n\n/* --- Context menu (right-click on a drawing) --- */\n.tcw-context-menu {\n position: absolute;\n z-index: 70;\n min-width: 200px;\n padding: 4px;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-divider);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n}\n.tcw-context-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n min-height: var(--tcw-menu-item-h);\n padding: 4px 10px;\n border: 0;\n border-radius: var(--tcw-radius-sm);\n background: transparent;\n color: var(--tcw-text);\n font: inherit;\n font-size: var(--tcw-font-size);\n text-align: start;\n cursor: pointer;\n}\n.tcw-context-item svg, .tcw-context-icon { flex: none; width: 14px; height: 14px; color: var(--tcw-text-muted); }\n.tcw-context-item:hover, .tcw-context-item:focus-visible { background: var(--tcw-bg-surface); outline: none; }\n.tcw-context-item:focus-visible { box-shadow: inset 0 0 0 1px var(--tcw-accent); }\n.tcw-context-danger, .tcw-context-danger svg { color: var(--tcw-red); }\n.tcw-context-sep { height: 1px; margin: 4px 6px; background: var(--tcw-divider); }\n/* --- Toolbar over a selected drawing --- */\n.tcw-sel-toolbar {\n position: absolute;\n z-index: 65;\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 3px;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-divider);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n font-family: var(--tcw-font);\n white-space: nowrap;\n animation: tcw-sel-in var(--tcw-dur-fast) var(--tcw-ease-out);\n}\n@keyframes tcw-sel-in { from { opacity: 0; transform: translateY(3px); } }\n.tcw-sel-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 5px;\n min-width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n padding: 0 6px;\n border: 0;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n font: inherit;\n font-size: var(--tcw-font-size-xs);\n font-variant-numeric: tabular-nums;\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-sel-btn svg { flex: none; }\n.tcw-sel-btn:hover, .tcw-sel-btn[aria-expanded=\"true\"] { background: var(--tcw-hover-bg); color: var(--tcw-text); }\n.tcw-sel-btn:focus-visible, .tcw-sel-swatch:focus-visible, .tcw-sel-option:focus-visible { outline: none; box-shadow: inset 0 0 0 1px var(--tcw-accent); }\n.tcw-sel-btn.tcw-sel-on { color: var(--tcw-accent); background: var(--tcw-accent-soft); }\n.tcw-sel-danger:hover { color: var(--tcw-red); background: var(--tcw-red-soft); }\n.tcw-sel-color {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tcw-text) 25%, transparent);\n}\n.tcw-sel-width {\n display: inline-block;\n width: 16px;\n height: var(--w, 1px);\n max-height: 6px;\n border-radius: 1px;\n background: currentColor;\n}\n.tcw-sel-sep { flex: none; width: 1px; height: 18px; margin: 0 3px; background: var(--tcw-divider); }\n.tcw-sel-pop {\n position: absolute;\n z-index: 66;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 120px;\n padding: 4px;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-divider);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n font-family: var(--tcw-font);\n}\n.tcw-sel-pop--color {\n display: grid;\n grid-template-columns: repeat(4, 24px);\n gap: 6px;\n min-width: 0;\n padding: 8px;\n}\n.tcw-sel-swatch {\n width: 24px;\n height: 24px;\n padding: 0;\n border: 0;\n border-radius: 50%;\n box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tcw-text) 20%, transparent);\n cursor: pointer;\n transition: transform var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-sel-swatch:hover { transform: scale(1.1); }\n.tcw-sel-swatch.tcw-sel-on { box-shadow: 0 0 0 2px var(--tcw-bg-elevated), 0 0 0 4px var(--tcw-accent); }\n.tcw-sel-option {\n display: flex;\n align-items: center;\n gap: 10px;\n min-height: var(--tcw-menu-item-h);\n padding: 4px 10px;\n border: 0;\n border-radius: var(--tcw-radius-sm);\n background: transparent;\n color: var(--tcw-text);\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n text-align: start;\n cursor: pointer;\n}\n.tcw-sel-option:hover { background: var(--tcw-bg-surface); }\n.tcw-sel-option.tcw-sel-on { color: var(--tcw-accent); }\n@media (prefers-reduced-motion: reduce) {\n .tcw-sel-toolbar { animation: none; }\n .tcw-sel-swatch { transition: none; }\n}\n\n/* --- Account panel (positions, orders, history) --- */\n.tcw-account-dock {\n flex: none;\n}\n.tcw-account {\n display: flex;\n flex-direction: column;\n height: 220px;\n border-top: 1px solid var(--tcw-border);\n background: var(--tcw-bg-surface);\n}\n.tcw-account-head {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px;\n border-bottom: 1px solid var(--tcw-divider);\n}\n.tcw-account-tabs {\n display: flex;\n gap: 2px;\n flex: 1;\n min-width: 0;\n overflow-x: auto;\n}\n.tcw-account-tab {\n padding: 6px 10px;\n border: 0;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n white-space: nowrap;\n cursor: pointer;\n}\n.tcw-account-tab:hover { color: var(--tcw-text); background: var(--tcw-hover-bg); }\n.tcw-account-tab[aria-selected=\"true\"] { color: var(--tcw-text); background: var(--tcw-active-bg); }\n.tcw-account-tab:focus-visible, .tcw-account-new:focus-visible { outline: none; box-shadow: inset 0 0 0 1px var(--tcw-accent); }\n.tcw-account-new {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 1px solid var(--tcw-accent-line);\n border-radius: var(--tcw-control-radius);\n background: var(--tcw-accent-soft);\n color: var(--tcw-accent);\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n cursor: pointer;\n}\n.tcw-account-new:hover { background: var(--tcw-accent-glow); }\n.tcw-account-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n}\n.tcw-account-table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--tcw-font-size-sm);\n font-variant-numeric: tabular-nums;\n}\n.tcw-account-table th {\n position: sticky;\n top: 0;\n padding: 6px 10px;\n background: var(--tcw-bg-surface);\n color: var(--tcw-text-muted);\n font-weight: var(--tcw-weight);\n text-align: start;\n border-bottom: 1px solid var(--tcw-divider);\n}\n.tcw-account-table td {\n padding: 5px 10px;\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-divider);\n white-space: nowrap;\n}\n.tcw-account-table tr:hover td { background: var(--tcw-hover-bg); }\n.tcw-account-side { font-weight: var(--tcw-weight-strong); }\n.tcw-account-buy, .tcw-account-up { color: var(--tcw-green); }\n.tcw-account-sell, .tcw-account-down { color: var(--tcw-red); }\n.tcw-account-actions { display: flex; gap: 2px; }\n.tcw-account-empty, .tcw-account-summary {\n margin: 0;\n padding: 14px 12px;\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size-sm);\n}\n.tcw-account-summary { padding: 8px 12px; color: var(--tcw-text-dim); }\n@media (max-width: 640px) {\n .tcw-account { height: 45vh; }\n}\n\n/* --- Order ticket --- */\n.tcw-ticket-side {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 6px;\n margin-bottom: 12px;\n}\n.tcw-ticket-side-btn {\n padding: 8px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n font: inherit;\n font-weight: var(--tcw-weight-strong);\n cursor: pointer;\n}\n.tcw-ticket-buy[aria-pressed=\"true\"] { background: var(--tcw-green-soft); border-color: var(--tcw-green); color: var(--tcw-green); }\n.tcw-ticket-sell[aria-pressed=\"true\"] { background: var(--tcw-red-soft); border-color: var(--tcw-red); color: var(--tcw-red); }\n.tcw-ticket-side-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--tcw-accent-soft); }\n.tcw-ticket-optional { display: flex; align-items: center; gap: 8px; }\n.tcw-ticket-optional > span { flex: 1; }\n.tcw-ticket-optional .tcw-indi-input { width: 110px; }\n.tcw-ticket-problems {\n min-height: 18px;\n padding: 0 22px 8px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n}\n.tcw-ticket-problems p { margin: 2px 0; }\n.tcw-ticket-problems.tcw-ticket-bad { color: var(--tcw-red); }\n.tcw-done-btn.tcw-ticket-sell { background: var(--tcw-red); color: #fff; }\n.tcw-done-btn:disabled { opacity: 0.45; cursor: not-allowed; }\n\n/* --- Named layouts --- */\n.tcw-layouts-btn { max-width: 190px; }\n.tcw-layouts-label {\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n.tcw-layouts-dirty {\n width: 6px;\n height: 6px;\n flex: none;\n border-radius: 50%;\n background: var(--tcw-accent);\n}\n.tcw-name-field { display: flex; flex-direction: column; gap: 6px; font-size: var(--tcw-font-size-sm); color: var(--tcw-text-dim); }\n.tcw-name-field .tcw-indi-input { width: 100%; height: 34px; font-size: var(--tcw-font-size); }\n.tcw-layouts-body { display: flex; flex-direction: column; gap: 10px; }\n.tcw-layouts-search { width: 100%; height: 32px; }\n.tcw-layouts-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n max-height: 50vh;\n overflow-y: auto;\n}\n.tcw-layouts-row {\n display: flex;\n align-items: center;\n gap: 6px;\n border-radius: var(--tcw-radius);\n}\n.tcw-layouts-row:hover { background: var(--tcw-hover-bg); }\n.tcw-layouts-open {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n padding: 7px 8px;\n border: none;\n background: transparent;\n color: var(--tcw-text);\n font: inherit;\n text-align: start;\n cursor: pointer;\n border-radius: var(--tcw-radius);\n}\n.tcw-layouts-open:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--tcw-accent-soft); }\n.tcw-layouts-name {\n display: flex;\n align-items: center;\n gap: 6px;\n max-width: 100%;\n font-size: var(--tcw-font-size);\n font-weight: var(--tcw-weight-strong);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.tcw-layouts-open[aria-current=\"true\"] .tcw-layouts-name { color: var(--tcw-accent); }\n.tcw-layouts-meta {\n max-width: 100%;\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n font-variant-numeric: tabular-nums;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.tcw-layouts-confirm {\n padding: 4px 10px;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: var(--tcw-red);\n color: #fff;\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n cursor: pointer;\n}\n.tcw-layouts-confirm:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--tcw-red-soft); }\n\n/* --- Chart grid --- */\n.tcw-grid { background: var(--tcw-bg); }\n.tcw-grid-bar {\n display: flex;\n align-items: center;\n gap: 6px;\n min-height: calc(var(--tcw-control-h) + 8px);\n padding: 0 8px;\n border-bottom: 1px solid var(--tcw-border);\n background: var(--tcw-bg-surface);\n overflow-x: auto;\n scrollbar-width: none;\n}\n.tcw-grid-bar::-webkit-scrollbar { display: none; }\n.tcw-grid-group { display: flex; align-items: center; gap: 2px; flex: none; }\n.tcw-grid-label {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n margin-right: 4px;\n font-size: var(--tcw-font-size-xs);\n font-weight: var(--tcw-weight-strong);\n letter-spacing: var(--tcw-label-tracking);\n text-transform: var(--tcw-label-case);\n color: var(--tcw-text-muted);\n}\n.tcw-grid-sync[aria-pressed=\"true\"] { color: var(--tcw-accent); }\n.tcw-grid-cells {\n flex: 1;\n min-height: 0;\n display: grid;\n gap: 1px;\n background: var(--tcw-border);\n}\n.tcw-grid-cell {\n position: relative;\n min-width: 0;\n min-height: 0;\n background: var(--tcw-bg);\n}\n.tcw-grid-cell-active::after {\n content: '';\n position: absolute;\n inset: 0;\n border: 1px solid var(--tcw-accent);\n pointer-events: none;\n z-index: 5;\n}\n\n/* --- Host toolbar buttons --- */\n.tcw-toolbar-host { display: inline-flex; align-items: center; gap: 2px; }\n.tcw-toolbar-host:empty { display: none; }\n.tcw-host-btn { display: inline-flex; align-items: center; gap: 4px; }\n\n/* --- Host sidebar buttons, status bar items, and the layer over the chart --- */\n.tcw-sidebar-host { display: flex; flex-direction: column; align-items: center; }\n.tcw-sidebar-host:empty { display: none; }\n.tcw-status-host { display: flex; align-items: center; gap: 10px; min-width: 0; }\n.tcw-status-host:empty { display: none; }\n.tcw-status-host-item { white-space: nowrap; }\n.tcw-status-host-btn {\n margin: -4px -6px;\n padding: 4px 6px;\n font: inherit;\n color: inherit;\n background: transparent;\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n transition: color var(--tcw-dur-fast) var(--tcw-ease), background var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-status-host-btn:hover { color: var(--tcw-text); background: var(--tcw-hover-bg); }\n.tcw-status-host-btn:focus-visible { outline: 2px solid var(--tcw-accent); outline-offset: -2px; }\n/* Over the plot and under the widget's own overlays; the pointer reaches the chart unless an element of yours takes it. */\n.tcw-host-layer { position: absolute; inset: 0; z-index: 2; pointer-events: none; }\n\n/* --- Pane buttons (move, fold, maximise) --- */\n.tcw-pane-controls {\n position: absolute;\n z-index: 4;\n display: flex;\n gap: 1px;\n transform: translateX(-100%);\n padding: 1px;\n border-radius: var(--tcw-radius-sm);\n background: color-mix(in srgb, var(--tcw-bg) 80%, transparent);\n opacity: 0.55;\n transition: opacity var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-pane-controls:hover,\n.tcw-pane-controls:focus-within { opacity: 1; }\n.tcw-pane-btn {\n display: inline-grid;\n place-items: center;\n width: 18px;\n height: 16px;\n padding: 0;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n}\n.tcw-pane-btn:hover { color: var(--tcw-text); background: var(--tcw-hover-bg); }\n.tcw-pane-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--tcw-accent-soft); }\n\n/* --- Typed interval --- */\n.tcw-interval-input {\n position: absolute;\n z-index: 20;\n left: 50%;\n top: 40%;\n transform: translate(-50%, -50%);\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 12px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-lg, 10px);\n background: var(--tcw-bg-elevated);\n box-shadow: var(--tcw-menu-shadow);\n}\n.tcw-interval-field {\n width: 150px;\n height: 36px;\n padding: 0 10px;\n font: inherit;\n font-size: calc(var(--tcw-font-size) + 5px);\n font-weight: var(--tcw-weight-strong);\n font-variant-numeric: tabular-nums;\n color: var(--tcw-text);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-accent);\n border-radius: var(--tcw-input-radius);\n outline: none;\n}\n.tcw-interval-field[aria-invalid] { border-color: var(--tcw-red); }\n.tcw-interval-hint { font-size: var(--tcw-font-size-xs); color: var(--tcw-text-muted); max-width: 170px; }\n\n/* --- Alerts: lines, moves, bar close, expiry --- */\n.tcw-alerts-source { grid-column: auto; }\n.tcw-alerts-row-fields {\n grid-column: 1 / -1;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n}\n.tcw-alerts-row-fields[hidden] { display: none; }\n.tcw-alerts-row-fields > input[hidden] { display: none; }\n.tcw-alerts-row-fields:has(> input[hidden]) { grid-template-columns: 1fr; }\n.tcw-alerts-options { align-items: center; }\n.tcw-alerts-form .tcw-alerts-check {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n}\n.tcw-alerts-form .tcw-alerts-check input { width: auto; height: auto; }\n.tcw-alerts-form input[aria-invalid=\"true\"] { border-color: var(--tcw-red); }\n.tcw-alerts-row-meta { margin-top: 2px; font-size: var(--tcw-font-size-xs); color: var(--tcw-text-muted); }\n.tcw-alerts-expired { opacity: 0.6; }\n\n/* --- Signal marker note --- */\n.tcw-marker-tip {\n position: absolute;\n z-index: 12;\n pointer-events: none;\n padding: 6px 8px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-tooltip-radius);\n background: var(--tcw-tooltip-bg);\n color: var(--tcw-tooltip-fg);\n font-size: var(--tcw-font-size-xs);\n line-height: 1.45;\n font-variant-numeric: tabular-nums;\n box-shadow: var(--tcw-menu-shadow);\n max-width: 240px;\n}\n.tcw-marker-tip strong { display: block; font-size: var(--tcw-font-size-sm); }\n\n/* === Navigation over the chart ===\n * Centred on the plot's bottom edge, shown while a mouse is over the chart. */\n.tcw-nav {\n position: absolute;\n z-index: 15;\n display: flex;\n gap: 2px;\n padding: 3px;\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: calc(var(--tcw-control-radius) + 3px);\n background: var(--tcw-bg-elevated);\n box-shadow: var(--tcw-menu-shadow);\n opacity: 0;\n pointer-events: none;\n transform: translate(-50%, calc(-100% - 12px));\n transition: opacity var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-nav.tcw-nav-shown {\n opacity: 1;\n pointer-events: auto;\n}\n.tcw-nav-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h);\n height: var(--tcw-control-h);\n border: 0;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-dim);\n cursor: pointer;\n touch-action: none;\n}\n.tcw-nav-btn:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n.tcw-nav-btn:active {\n background: var(--tcw-active-bg);\n}\n.tcw-nav-btn:focus-visible {\n outline: none;\n box-shadow: var(--tcw-ring);\n}\n.tcw-nav-btn svg {\n width: var(--tcw-icon);\n height: var(--tcw-icon);\n}\n@media (hover: none) {\n .tcw-nav { display: none; }\n}\n\n/* === Symbol info ===\n * Top left, beside the drawing tools: the panels on the right stay clear. */\n.tcw-syminfo {\n position: absolute;\n top: var(--tcw-panel-top);\n inset-inline-start: var(--tcw-panel-left);\n z-index: 38;\n width: 288px;\n max-height: calc(100% - var(--tcw-panel-top) - 12px);\n display: flex;\n flex-direction: column;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n overflow: hidden;\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n.tcw-syminfo-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 9px 12px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-syminfo-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n}\n.tcw-syminfo-close:hover { background: var(--tcw-bg-surface); color: var(--tcw-text); }\n.tcw-syminfo-body,\n.tcw-syminfo-news {\n padding: 12px 14px;\n overflow-y: auto;\n}\n.tcw-syminfo-body {\n display: grid;\n gap: 10px;\n}\n.tcw-syminfo-symbol {\n font-size: var(--tcw-font-size-lg);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n}\n.tcw-syminfo-desc {\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n}\n.tcw-syminfo-meta {\n margin-top: 2px;\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n}\n.tcw-syminfo-quote {\n display: flex;\n align-items: baseline;\n gap: 10px;\n font-family: var(--tcw-font-mono);\n font-variant-numeric: tabular-nums;\n}\n.tcw-syminfo-price {\n font-size: calc(var(--tcw-font-size) + 7px);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n}\n.tcw-syminfo-change { font-size: var(--tcw-font-size-sm); }\n.tcw-syminfo-change.tcw-up { color: var(--tcw-green); }\n.tcw-syminfo-change.tcw-down { color: var(--tcw-red); }\n.tcw-syminfo-status {\n display: flex;\n align-items: center;\n gap: 7px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n}\n.tcw-syminfo-status::before,\n.tcw-status-market::before {\n content: '';\n flex: none;\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n}\n.tcw-syminfo-status[data-state='open']::before,\n.tcw-syminfo-status[data-state='always']::before,\n.tcw-status-market[data-state='open']::before {\n background: var(--tcw-green);\n}\n.tcw-syminfo-stats {\n display: grid;\n gap: 4px;\n margin: 0;\n padding-top: 10px;\n border-top: 1px solid var(--tcw-divider);\n}\n.tcw-syminfo-stat {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n font-size: var(--tcw-font-size-sm);\n}\n.tcw-syminfo-stat dt { color: var(--tcw-text-muted); }\n.tcw-syminfo-stat dd {\n margin: 0;\n color: var(--tcw-text);\n text-align: end;\n font-variant-numeric: tabular-nums;\n overflow-wrap: anywhere;\n}\n.tcw-syminfo-news {\n border-top: 1px solid var(--tcw-divider);\n}\n.tcw-syminfo-news-title {\n margin-bottom: 8px;\n font-size: var(--tcw-font-size-xs);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text-muted);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n}\n.tcw-syminfo-news-list {\n display: grid;\n gap: 10px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.tcw-syminfo-news-item {\n font-size: var(--tcw-font-size-sm);\n line-height: 1.4;\n color: var(--tcw-text);\n}\n.tcw-syminfo-news-item a {\n color: var(--tcw-text);\n text-decoration: none;\n}\n.tcw-syminfo-news-item a:hover { color: var(--tcw-accent); text-decoration: underline; }\n.tcw-syminfo-news-item a:focus-visible { outline: none; box-shadow: var(--tcw-ring); border-radius: var(--tcw-radius-xs); }\n.tcw-syminfo-news-meta,\n.tcw-syminfo-news-note {\n margin-top: 2px;\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n}\n\n/* Numbers keep their sign on the left, and mixed text its own order, in a right-to-left widget too. */\n.tcw-watchlist-price,\n.tcw-watchlist-change,\n.tcw-syminfo-price,\n.tcw-syminfo-change {\n unicode-bidi: isolate;\n direction: ltr;\n}\n.tcw-syminfo-desc,\n.tcw-syminfo-meta,\n.tcw-syminfo-status,\n.tcw-syminfo-stat dd,\n.tcw-syminfo-news-meta {\n unicode-bidi: plaintext;\n}\n\n/* The market's status in the status bar. */\n.tcw-status-market {\n display: flex;\n align-items: center;\n gap: 7px;\n color: var(--tcw-text-muted);\n}\n\n@media (max-width: 640px) {\n .tcw-syminfo {\n top: auto;\n bottom: 0;\n left: 0;\n right: 0;\n width: 100vw;\n max-height: 70%;\n border-radius: var(--tcw-dialog-radius) var(--tcw-dialog-radius) 0 0;\n }\n}\n\n/* === The look: how chosen controls show, floating bars, segmented intervals ===\n * Each switch sets variables on its own root, which its parts read: a grid's\n * look never reaches into a chart that has one of its own. */\n\n/* A chosen button (`ui.active`): a tinted fill (default), a solid pill, or an underline.\n * Dialog tabs are chips, or underlined in the underline look. Panels sit below the\n * toolbar and beside the drawing tools. */\n.tcw-root {\n --tcw-on-bg: var(--tcw-accent-soft);\n --tcw-on-fg: var(--tcw-accent);\n --tcw-on-ring: none;\n --tcw-on-icon-bg: var(--tcw-accent-soft);\n --tcw-on-icon-fg: var(--tcw-accent);\n --tcw-on-icon-ring: none;\n --tcw-tabs-pad-block: 8px;\n --tcw-tab-h: var(--tcw-control-h);\n --tcw-tab-pad: 0 12px;\n --tcw-tab-line: 0px;\n --tcw-tab-radius: var(--tcw-control-radius);\n --tcw-tab-hover: var(--tcw-hover-bg);\n --tcw-tab-on-bg: var(--tcw-on-bg);\n --tcw-tab-on-fg: var(--tcw-on-fg);\n --tcw-panel-top: calc(var(--tcw-toolbar-h) + 6px);\n --tcw-panel-left: calc(var(--tcw-sidebar-w) + 12px);\n}\n.tcw-root[data-tcw-active='solid'] {\n --tcw-on-bg: var(--tcw-text);\n --tcw-on-fg: var(--tcw-bg);\n --tcw-on-icon-bg: var(--tcw-text);\n --tcw-on-icon-fg: var(--tcw-bg);\n}\n.tcw-root[data-tcw-active='underline'] {\n --tcw-on-bg: var(--tcw-active-bg);\n --tcw-on-fg: var(--tcw-text);\n --tcw-on-ring: inset 0 -2px 0 var(--tcw-accent);\n --tcw-on-icon-bg: var(--tcw-active-bg);\n --tcw-on-icon-fg: var(--tcw-accent);\n --tcw-on-icon-ring: inset 2px 0 0 var(--tcw-accent);\n --tcw-tabs-pad-block: 0px;\n --tcw-tab-h: auto;\n --tcw-tab-pad: 11px 14px;\n --tcw-tab-line: 2px;\n --tcw-tab-radius: 0px;\n --tcw-tab-hover: transparent;\n --tcw-tab-on-bg: transparent;\n --tcw-tab-on-fg: var(--tcw-accent);\n}\n.tcw-root[data-tcw-toolbar='floating'] {\n --tcw-panel-top: calc(var(--tcw-toolbar-h) + 2 * var(--tcw-border-w) + 14px);\n}\n.tcw-root[data-tcw-sidebar='floating'] {\n --tcw-panel-left: calc(var(--tcw-sidebar-w) + 2 * var(--tcw-border-w) + 22px);\n}\n\n/* The toolbar as an island (`ui.toolbar: 'floating'`). */\n.tcw-root[data-tcw-toolbar='floating'] > .tcw-toolbar {\n margin: 8px 10px 0;\n padding-inline: calc(min(var(--tcw-toolbar-radius), var(--tcw-toolbar-h) / 2) / 2 + 8px);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-toolbar-radius);\n background: var(--tcw-bg-elevated);\n box-shadow: var(--tcw-menu-shadow);\n}\n\n/* The drawing tools as an island (`ui.sidebar: 'floating'`). */\n.tcw-root[data-tcw-sidebar='floating'] > .tcw-body > .tcw-sidebar {\n align-self: flex-start;\n max-height: calc(100% - 20px);\n margin: 10px 6px 10px 10px;\n padding-block: calc(min(var(--tcw-sidebar-radius), var(--tcw-sidebar-w) / 2) / 2 + 6px);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-sidebar-radius);\n background: var(--tcw-bg-elevated);\n box-shadow: var(--tcw-menu-shadow);\n}\n\n/* Frosted menus (`ui.blur` above 0): the chart shows through, blurred. */\n@supports (background: color-mix(in srgb, red 50%, transparent)) {\n .tcw-dropdown,\n .tcw-flyout,\n .tcw-context-menu {\n background: color-mix(in srgb, var(--tcw-bg-elevated) var(--tcw-surface-opacity), transparent);\n }\n}\n\n/* The interval buttons in one track (`ui.intervals: 'segmented'`). */\n.tcw-root[data-tcw-intervals='segmented'] > .tcw-toolbar > .tcw-tf-group {\n gap: 2px;\n margin: 0 4px;\n padding: 3px;\n border-radius: calc(var(--tcw-control-radius) + 3px);\n background: var(--tcw-hover-bg);\n}\n.tcw-root[data-tcw-intervals='segmented'] > .tcw-toolbar > .tcw-tf-group .tcw-btn {\n height: calc(var(--tcw-control-h) - 6px);\n padding: 0 9px;\n}\n\n/* Phones: the variants keep comfortable tap targets and room for the bar. */\n@media (max-width: 768px) {\n .tcw-root[data-tcw-intervals='segmented'] > .tcw-toolbar > .tcw-tf-group .tcw-btn {\n height: max(34px, calc(var(--tcw-control-h) - 6px));\n padding: 0 10px;\n }\n .tcw-root[data-tcw-toolbar='floating'] > .tcw-toolbar {\n margin: 6px 6px 0;\n padding-inline: 4px;\n }\n .tcw-root[data-tcw-sidebar='floating'] > .tcw-body > .tcw-sidebar {\n margin: 6px 4px 6px 6px;\n }\n}\n", O = /* @__PURE__ */ "toolbar,sidebar,statusBar,alerts,objectTree,symbolInfo,symbolSearch,settings,indicatorSettings,drawingSettings,dataWindow,commandPalette,hotkeySheet,goToDate,replay,screenshot,copyImage,shareView,autoFib,themeToggle,fullscreen,accountPanel,orderTicket,bracketOrders,depthLadder,layouts,indicatorTemplates,compare,indicatorLegend,navigation,customTimeframes,intervalTyping,dragDropImport,hotkeys,toasts,toolbar.symbol,toolbar.symbolInfo,toolbar.timeframes,toolbar.timeframeMenu,toolbar.chartType,toolbar.indicators,toolbar.layouts,toolbar.replay,toolbar.bracketOrders,toolbar.depthLadder,toolbar.accountPanel,toolbar.objectTree,toolbar.alerts,toolbar.screenshot,toolbar.settings,toolbar.themeToggle,toolbar.fullscreen,sidebar.cursor,sidebar.favorites,sidebar.lines,sidebar.fibonacci,sidebar.patterns,sidebar.forecasting,sidebar.annotation,sidebar.style,sidebar.magnet,sidebar.eraser,sidebar.zoomArea,sidebar.stayInDrawing,sidebar.undo,sidebar.redo,sidebar.clear,statusBar.range,statusBar.goToDate,statusBar.market,statusBar.connection,statusBar.symbol,statusBar.rangeTimeframe,indicatorLegend.values,indicatorLegend.visibility,indicatorLegend.settings,indicatorLegend.remove,indicatorLegend.more,pane.move,pane.collapse,pane.maximize,navigation.zoom,navigation.scroll,navigation.reset,menu.chart,menu.chart.alert,menu.chart.order,menu.chart.orderTicket,menu.chart.horizontalLine,menu.chart.resetView,menu.chart.drawings,menu.chart.exportData,menu.chart.settings,menu.chart.scale,menu.chart.goToDate,menu.chart.paneScale,menu.priceAxisAdd,menu.drawing,menu.drawing.settings,menu.drawing.alert,menu.drawing.order,menu.drawing.group,menu.drawing.lock,menu.drawing.hide,menu.drawing.duplicate,menu.drawing.delete,selectionToolbar,hotkeys.commandPalette,hotkeys.symbolSearch,hotkeys.save,hotkeys.tools,hotkeys.invertScale,hotkeys.goToDate,hotkeys.help".split(","), $e = new Set(O), et = {
|
|
1462
|
+
var Ze = [...new Set([...Object.keys(g).filter((e) => e.startsWith("series.")), ...[...Ke, ...qe].flatMap((e) => e.rows.flatMap((e) => e.keys))])], Qe = "/* === TradeCanvas Widget — Premium Styles === */\n\n/*\n * The HTML `hidden` attribute only sets `display: none` via the UA stylesheet,\n * which any author `display` rule (e.g. `.tcw-alerts-panel { display: flex }`)\n * silently overrides — leaving panels stuck open when JS sets `el.hidden = true`.\n * Force `hidden` to win for every namespaced widget element. Scoped to `tcw-`\n * so it never touches the host page.\n */\n[class^=\"tcw-\"][hidden],\n[class*=\" tcw-\"][hidden] {\n display: none !important;\n}\n\n/* Control tooltips (WidgetTooltip): quick to appear, slide in from the control. */\n.tcw-tooltip {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 60;\n max-width: 240px;\n padding: 5px 8px;\n border-radius: var(--tcw-tooltip-radius);\n background: var(--tcw-tooltip-bg);\n color: var(--tcw-tooltip-fg);\n box-shadow: var(--tcw-tooltip-shadow);\n width: max-content;\n font-size: var(--tcw-font-size-xs);\n font-weight: var(--tcw-weight);\n line-height: 1.35;\n overflow-wrap: anywhere;\n pointer-events: none;\n opacity: 0;\n visibility: hidden;\n transform: translate(var(--tcw-tip-dx, 0), var(--tcw-tip-dy, 0));\n transition:\n opacity 110ms var(--tcw-ease-out),\n transform 110ms var(--tcw-ease-out),\n visibility 0s linear 110ms;\n}\n\n.tcw-tooltip--visible {\n opacity: 1;\n visibility: visible;\n transform: none;\n transition:\n opacity 110ms var(--tcw-ease-out),\n transform 110ms var(--tcw-ease-out),\n visibility 0s;\n}\n\n/* The modal portal: carries the tokens and fonts, but no box of its own. */\n.tcw-root.tcw-portal {\n display: contents;\n}\n\n/* Fullscreen: the root fills the screen; the chart resizes with it. */\n.tcw-root:fullscreen {\n width: 100vw;\n height: 100vh;\n height: 100dvh;\n}\n\n.tcw-root {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n font-family: var(--tcw-font);\n font-feature-settings: 'cv11', 'ss01', 'ss03';\n font-size: var(--tcw-font-size);\n line-height: 1.4;\n color: #d9dde4;\n background: #080b10;\n position: relative;\n overflow: hidden;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n\n /* --- Dark theme tokens (default) --- */\n --tcw-bg: #080b10;\n --tcw-bg-surface: #0c1016;\n --tcw-bg-elevated: #141922;\n --tcw-bg-overlay: rgba(20, 25, 34, 0.5);\n --tcw-border: #1f2630;\n --tcw-border-strong: #2a323e;\n --tcw-tooltip-bg: #262e3a;\n --tcw-tooltip-fg: #eef0f4;\n --tcw-text: #e7e9ee;\n --tcw-text-dim: #aab1bd;\n --tcw-text-muted: #758091;\n\n /* TradeCanvas amber. --tcw-accent-ink is the text colour on an accent fill. */\n --tcw-accent: #f2a93b;\n --tcw-accent-hover: #f5b95c;\n --tcw-accent-ink: #1a1204;\n --tcw-accent-soft: rgba(242, 169, 59, 0.14);\n --tcw-accent-glow: rgba(242, 169, 59, 0.22);\n --tcw-accent-line: rgba(242, 169, 59, 0.55);\n\n --tcw-red: #e8505b;\n --tcw-red-soft: rgba(232, 80, 91, 0.12);\n --tcw-green: #1fa874;\n --tcw-green-soft: rgba(31, 168, 116, 0.12);\n --tcw-amber: #ff9f43;\n\n --tcw-hover-bg: rgba(255, 255, 255, 0.05);\n --tcw-active-bg: rgba(255, 255, 255, 0.08);\n --tcw-divider: rgba(255, 255, 255, 0.06);\n\n /* Motion */\n --tcw-ease: cubic-bezier(0.2, 0, 0, 1);\n --tcw-ease-out: cubic-bezier(0.16, 1, 0.3, 1);\n --tcw-dur-fast: 120ms;\n --tcw-dur-normal: 180ms;\n --tcw-dur-slow: 260ms;\n\n /* The look (UI system): Studio's values. The `ui` option sets them inline. */\n --tcw-radius-xs: 3px;\n --tcw-radius-sm: 5px;\n --tcw-radius: 7px;\n --tcw-radius-lg: 11px;\n --tcw-radius-xl: 16px;\n --tcw-control-radius: var(--tcw-radius);\n --tcw-input-radius: var(--tcw-radius);\n --tcw-menu-radius: var(--tcw-radius-lg);\n --tcw-dialog-radius: var(--tcw-radius-xl);\n --tcw-panel-radius: var(--tcw-radius-lg);\n --tcw-tooltip-radius: var(--tcw-radius-sm);\n --tcw-tag-radius: var(--tcw-radius-sm);\n --tcw-toast-radius: var(--tcw-radius-lg);\n --tcw-toolbar-radius: 0px;\n --tcw-sidebar-radius: 0px;\n --tcw-toolbar-h: 46px;\n --tcw-control-h: 30px;\n --tcw-control-h-sm: 24px;\n --tcw-icon: 18px;\n --tcw-sidebar-w: 48px;\n --tcw-menu-item-h: 30px;\n --tcw-font: 'Manrope', 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n --tcw-font-size: 13px;\n --tcw-font-size-sm: 12px;\n --tcw-font-size-xs: 11px;\n --tcw-font-size-lg: 15px;\n --tcw-weight: 500;\n --tcw-weight-strong: 600;\n --tcw-label-case: none;\n --tcw-label-tracking: 0em;\n --tcw-border-w: 1px;\n --tcw-sep-w: 0px;\n --tcw-menu-shadow: var(--tcw-shadow-lg);\n --tcw-dialog-shadow: var(--tcw-shadow-xl);\n --tcw-tooltip-shadow: var(--tcw-shadow-md);\n --tcw-blur: 0px;\n --tcw-surface-opacity: 100%;\n\n /* Elevation */\n --tcw-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);\n --tcw-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.2);\n --tcw-shadow-lg: 0 12px 36px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3);\n --tcw-shadow-xl: 0 24px 64px rgba(0, 0, 0, 0.55), 0 12px 24px rgba(0, 0, 0, 0.35);\n --tcw-ring: 0 0 0 2px rgba(242, 169, 59, 0.45);\n\n /* Type */\n --tcw-font-mono: 'JetBrains Mono', 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', ui-monospace, monospace;\n}\n\n.tcw-root[data-tcw-theme='light'] {\n color: #0c1016;\n background: #fcfcfd;\n\n --tcw-bg: #fcfcfd;\n --tcw-bg-surface: #ffffff;\n --tcw-bg-elevated: #ffffff;\n --tcw-bg-overlay: rgba(255, 255, 255, 0.75);\n --tcw-border: #e3e6eb;\n --tcw-border-strong: #d2d6dd;\n --tcw-tooltip-bg: #1f2630;\n --tcw-tooltip-fg: #f4f5f8;\n --tcw-text: #0c1016;\n --tcw-text-dim: #3f4754;\n --tcw-text-muted: #626a77;\n\n /* Deeper amber: readable as text on the light ground, white text readable on it. */\n --tcw-accent: #a0610a;\n --tcw-accent-hover: #874f07;\n --tcw-accent-ink: #ffffff;\n --tcw-accent-soft: rgba(160, 97, 10, 0.10);\n --tcw-accent-glow: rgba(160, 97, 10, 0.16);\n --tcw-accent-line: rgba(160, 97, 10, 0.45);\n --tcw-ring: 0 0 0 2px rgba(160, 97, 10, 0.4);\n\n /* Darker semantic colours: used as text on white. */\n --tcw-red: #c42f3e;\n --tcw-red-soft: rgba(196, 47, 62, 0.10);\n --tcw-green: #0b7d50;\n --tcw-green-soft: rgba(11, 125, 80, 0.10);\n\n --tcw-hover-bg: rgba(0, 0, 0, 0.04);\n --tcw-active-bg: rgba(160, 97, 10, 0.08);\n --tcw-divider: rgba(0, 0, 0, 0.06);\n\n --tcw-shadow-sm: 0 1px 2px rgba(20, 28, 56, 0.05);\n --tcw-shadow-md: 0 4px 12px rgba(20, 28, 56, 0.08), 0 1px 3px rgba(20, 28, 56, 0.04);\n --tcw-shadow-lg: 0 12px 36px rgba(20, 28, 56, 0.14), 0 4px 12px rgba(20, 28, 56, 0.08);\n --tcw-shadow-xl: 0 24px 64px rgba(20, 28, 56, 0.18), 0 12px 24px rgba(20, 28, 56, 0.1);\n}\n\n/* === Toolbar === */\n\n.tcw-toolbar {\n display: flex;\n align-items: center;\n gap: 0;\n padding: 0 10px;\n height: var(--tcw-toolbar-h);\n border-bottom: var(--tcw-border-w) solid var(--tcw-border);\n background:\n linear-gradient(180deg, var(--tcw-bg-elevated) 0%, var(--tcw-bg-surface) 100%);\n flex-shrink: 0;\n position: relative;\n z-index: 20;\n box-shadow: var(--tcw-shadow-sm);\n}\n\n.tcw-toolbar-symbol {\n font-size: calc(var(--tcw-font-size) + 1px);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n display: inline-flex;\n align-items: center;\n height: var(--tcw-control-h);\n padding: 0 12px;\n white-space: nowrap;\n letter-spacing: -0.015em;\n cursor: pointer;\n border: none;\n background: transparent;\n font-family: inherit;\n border-radius: var(--tcw-control-radius);\n transition: background var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-toolbar-symbol:hover {\n background: var(--tcw-hover-bg);\n}\n\n/* With the symbol search switched off, the button only names the symbol. */\n.tcw-toolbar-symbol[aria-disabled=\"true\"] {\n cursor: default;\n}\n\n.tcw-toolbar-symbol[aria-disabled=\"true\"]:hover {\n background: transparent;\n}\n\n.tcw-toolbar-sep {\n width: var(--tcw-sep-w);\n height: 22px;\n background: var(--tcw-border);\n flex-shrink: 0;\n margin: 0 4px;\n}\n\n.tcw-toolbar-group {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 4px;\n}\n\n.tcw-toolbar-spacer {\n flex: 1;\n}\n\n.tcw-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: var(--tcw-control-h);\n padding: 0 10px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight);\n font-family: inherit;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n color var(--tcw-dur-fast) var(--tcw-ease),\n transform var(--tcw-dur-fast) var(--tcw-ease);\n white-space: nowrap;\n line-height: 1;\n letter-spacing: -0.005em;\n}\n\n.tcw-btn:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-btn:active {\n transform: translateY(0.5px);\n}\n\n.tcw-btn.tcw-active {\n background: var(--tcw-on-bg);\n color: var(--tcw-on-fg);\n font-weight: var(--tcw-weight-strong);\n box-shadow: var(--tcw-on-ring);\n}\n\n.tcw-btn:focus-visible,\n.tcw-btn-icon:focus-visible,\n.tcw-sidebar-btn:focus-visible,\n.tcw-dropdown-trigger:focus-visible {\n outline: none;\n box-shadow: var(--tcw-ring);\n}\n\n.tcw-btn-icon {\n width: var(--tcw-control-h);\n height: var(--tcw-control-h);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: inherit;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n color var(--tcw-dur-fast) var(--tcw-ease);\n line-height: 1;\n position: relative;\n}\n\n.tcw-btn-icon:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-btn-icon svg {\n display: block;\n width: var(--tcw-icon);\n height: var(--tcw-icon);\n}\n\n.tcw-badge-count {\n font-size: calc(var(--tcw-font-size) - 3px);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n padding: 1px 5px;\n border-radius: var(--tcw-tag-radius);\n font-family: var(--tcw-font-mono);\n}\n\n/* === Dropdown === */\n\n.tcw-dropdown-trigger {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: var(--tcw-control-h);\n padding: 0 10px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight);\n font-family: inherit;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n white-space: nowrap;\n line-height: 1;\n}\n\n.tcw-dropdown-trigger:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-dropdown {\n position: absolute;\n top: 100%;\n margin-top: 6px;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n z-index: 50;\n width: max-content;\n max-width: min(340px, calc(100vw - 16px));\n padding: 6px;\n max-height: 420px;\n overflow-y: auto;\n backdrop-filter: blur(var(--tcw-blur));\n -webkit-backdrop-filter: blur(var(--tcw-blur));\n animation: tcw-pop-in var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n@keyframes tcw-pop-in {\n from { opacity: 0; transform: translateY(-4px) scale(0.98); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n}\n\n.tcw-dropdown-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: var(--tcw-menu-item-h);\n padding: 4px 10px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n width: 100%;\n border: none;\n background: transparent;\n font-family: inherit;\n text-align: start;\n border-radius: var(--tcw-radius-sm);\n gap: 12px;\n}\n\n.tcw-dropdown-item:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n/* A menu row led by an icon (chart types): icon then label, not spread apart. */\n.tcw-dropdown-item--icon {\n justify-content: flex-start;\n gap: 10px;\n}\n\n.tcw-dropdown-item svg,\n.tcw-flyout-item svg {\n flex-shrink: 0;\n}\n\n/* The drawing-group button's icon holder: a plain box for the swapped SVG. */\n.tcw-sidebar-icon {\n display: inline-flex;\n}\n\n.tcw-dropdown-item.tcw-active {\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n font-weight: var(--tcw-weight-strong);\n}\n\n/* Timeframe menu: pick on the left, pin (star) on the right. */\n.tcw-tf-more {\n padding: 0 5px;\n}\n\n.tcw-tf-more svg {\n display: block;\n}\n\n.tcw-tf-row {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n\n.tcw-tf-row .tcw-dropdown-item {\n flex: 1;\n min-width: 0;\n}\n\n.tcw-tf-star {\n display: inline-grid;\n place-items: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n flex-shrink: 0;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n transition: color var(--tcw-dur-fast) var(--tcw-ease), background var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-tf-star:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-tf-star.tcw-active {\n color: var(--tcw-accent);\n}\n\n.tcw-tf-star.tcw-active svg {\n fill: currentColor;\n}\n\n.tcw-tf-star:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: -2px;\n}\n\n.tcw-tf-remove {\n display: inline-grid;\n place-items: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n flex-shrink: 0;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n opacity: 0;\n transition: opacity var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-tf-row:hover .tcw-tf-remove,\n.tcw-tf-remove:focus-visible {\n opacity: 1;\n}\n\n/* No hover on touch screens: keep it visible rather than a hidden tap target. */\n@media (hover: none) {\n .tcw-tf-remove { opacity: 1; }\n}\n\n.tcw-tf-remove:hover {\n color: var(--tcw-red);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-tf-remove:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: -2px;\n}\n\n/* Typed interval, under the list: stays in view while the list scrolls. */\n.tcw-tf-custom {\n position: sticky;\n bottom: -6px;\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin: 4px -6px -6px;\n padding: 6px 10px 8px;\n border-top: 1px solid var(--tcw-divider);\n background: var(--tcw-bg-elevated);\n}\n\n.tcw-tf-custom-hint:empty {\n display: none;\n}\n\n.tcw-tf-custom-hint {\n flex-basis: 100%;\n width: 0;\n min-width: 100%;\n color: var(--tcw-red);\n font-size: var(--tcw-font-size-xs);\n line-height: 1.35;\n}\n\n.tcw-tf-custom-input {\n flex: 1;\n /* Fills the row: its own width would follow the font (16px on touch). */\n width: 0;\n min-width: 0;\n height: 26px;\n padding: 0 8px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-input-radius);\n background: var(--tcw-bg);\n color: var(--tcw-text);\n font: inherit;\n font-family: var(--tcw-font-mono);\n font-size: var(--tcw-font-size-sm);\n}\n\n.tcw-tf-custom-input::placeholder {\n color: var(--tcw-text-dim);\n}\n\n.tcw-tf-custom-input:focus {\n outline: none;\n border-color: var(--tcw-accent);\n box-shadow: 0 0 0 2px var(--tcw-accent-soft);\n}\n\n.tcw-tf-custom-input[aria-invalid='true'] {\n border-color: var(--tcw-red);\n box-shadow: 0 0 0 2px var(--tcw-red-soft);\n}\n\n.tcw-tf-custom-add {\n display: inline-grid;\n place-items: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n flex-shrink: 0;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-control-radius);\n background: var(--tcw-bg-surface);\n color: var(--tcw-text);\n cursor: pointer;\n}\n\n.tcw-tf-custom-add:hover {\n border-color: var(--tcw-accent);\n color: var(--tcw-accent);\n}\n\n.tcw-tf-custom-add:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: 1px;\n}\n\n.tcw-dropdown-label {\n text-transform: var(--tcw-label-case);\n font-size: calc(var(--tcw-font-size) - 3px);\n color: var(--tcw-text-muted);\n letter-spacing: var(--tcw-label-tracking);\n padding: 8px 10px 4px;\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-dropdown-divider {\n border-top: 1px solid var(--tcw-divider);\n margin: 6px 4px;\n}\n\n.tcw-tag {\n font-size: calc(var(--tcw-font-size) - 3px);\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n padding: 2px 6px;\n border-radius: var(--tcw-tag-radius);\n background: var(--tcw-hover-bg);\n letter-spacing: 0.02em;\n}\n\n/* === Body === */\n\n.tcw-body {\n position: relative;\n display: flex;\n flex: 1;\n min-height: 0;\n background: var(--tcw-bg);\n}\n\n.tcw-chart-container {\n flex: 1;\n min-width: 0;\n min-height: 0;\n width: 100%;\n height: 100%;\n position: relative;\n}\n\n/* === Symbol search results: name and exchange === */\n\n.tcw-cmd-item-desc {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size-sm);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.tcw-cmd-item-meta {\n flex-shrink: 0;\n color: var(--tcw-text-dim);\n font-size: var(--tcw-font-size-xs);\n letter-spacing: 0.02em;\n}\n\n/* === History pill (older bars loading at the left edge) === */\n\n.tcw-history-pill {\n position: absolute;\n top: 50%;\n left: 10px;\n z-index: 4;\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 5px 10px 5px 8px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-tag-radius);\n background: var(--tcw-bg-elevated);\n box-shadow: var(--tcw-shadow-sm);\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size-xs);\n line-height: 1;\n white-space: nowrap;\n transform: translateY(-50%);\n opacity: 1;\n transition: opacity var(--tcw-dur-normal) var(--tcw-ease-out);\n pointer-events: none;\n}\n\n.tcw-history-pill--hidden {\n opacity: 0;\n}\n\n.tcw-history-pill--error {\n border-color: color-mix(in srgb, var(--tcw-red) 45%, var(--tcw-border));\n color: var(--tcw-red);\n}\n\n.tcw-history-spinner {\n width: 10px;\n height: 10px;\n border: 1.5px solid var(--tcw-accent-soft);\n border-top-color: var(--tcw-accent);\n border-radius: 50%;\n animation: tcw-history-spin 0.8s linear infinite;\n}\n\n.tcw-history-pill--error .tcw-history-spinner {\n border-color: currentColor;\n animation: none;\n}\n\n@keyframes tcw-history-spin {\n to { transform: rotate(360deg); }\n}\n\n/* === Loading overlay (candle skeleton) === */\n\n.tcw-loading-overlay {\n /* Uses a modifier class rather than the `hidden` attribute — the global\n `[hidden] { display: none !important }` rule above would cut the\n opacity transition off before it can play. */\n position: absolute;\n inset: 0;\n z-index: 5;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--tcw-bg);\n opacity: 1;\n transition: opacity var(--tcw-dur-slow) var(--tcw-ease-out);\n pointer-events: none;\n}\n\n.tcw-loading-overlay--hidden {\n opacity: 0;\n}\n\n.tcw-loading-card {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 14px;\n padding: 22px 26px 20px;\n border: 1px solid transparent;\n border-radius: var(--tcw-panel-radius);\n}\n\n/* A slow switch: the previous chart stays readable underneath, dimmed, so the\n click visibly registered without blanking the screen. */\n.tcw-loading-overlay--veil {\n background: color-mix(in srgb, var(--tcw-bg) 55%, transparent);\n}\n\n.tcw-loading-overlay--veil .tcw-loading-card {\n background: var(--tcw-bg-elevated);\n border-color: var(--tcw-border);\n box-shadow: var(--tcw-menu-shadow);\n}\n\n.tcw-loading-candles {\n position: relative;\n display: flex;\n gap: 7px;\n height: 64px;\n}\n\n/* One candle: the element is the wick's column, ::before the wick, ::after the body. */\n.tcw-loading-candle {\n position: relative;\n width: 8px;\n height: 100%;\n color: var(--tcw-red);\n opacity: 0.28;\n animation: tcw-candle-light 1.6s var(--tcw-ease) infinite;\n animation-delay: var(--tcw-delay, 0ms);\n}\n\n.tcw-loading-candle--up { color: var(--tcw-green); }\n\n.tcw-loading-candle::before,\n.tcw-loading-candle::after {\n content: '';\n position: absolute;\n left: 50%;\n background: currentColor;\n transform: translateX(-50%);\n}\n\n.tcw-loading-candle::before {\n top: var(--tcw-wick-top);\n width: 1.5px;\n height: var(--tcw-wick-h);\n}\n\n.tcw-loading-candle::after {\n top: var(--tcw-body-top);\n width: 8px;\n height: var(--tcw-body-h);\n border-radius: 1.5px;\n}\n\n/* Each candle brightens and lifts slightly in turn, left to right. */\n@keyframes tcw-candle-light {\n 0%, 55%, 100% { opacity: 0.28; transform: translateY(0); }\n 20% { opacity: 1; transform: translateY(-2px); }\n}\n\n.tcw-loading-track {\n position: relative;\n width: 100%;\n min-width: 88px;\n height: 2px;\n border-radius: 1px;\n background: var(--tcw-border);\n overflow: hidden;\n}\n\n.tcw-loading-track > span {\n position: absolute;\n inset: 0;\n width: 40%;\n border-radius: 1px;\n background: linear-gradient(90deg, transparent, var(--tcw-accent), transparent);\n animation: tcw-loading-sweep 1.6s var(--tcw-ease) infinite;\n}\n\n@keyframes tcw-loading-sweep {\n from { transform: translateX(-100%); }\n to { transform: translateX(250%); }\n}\n\n/* The status text is announced, not shown — the candles say \"loading\". */\n.tcw-loading-label {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n.tcw-loading-overlay--error .tcw-loading-candles,\n.tcw-loading-overlay--error .tcw-loading-track {\n display: none;\n}\n\n/* A failure is shown: why the chart is empty and that a retry is running. */\n.tcw-loading-overlay--error .tcw-loading-label {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip-path: none;\n white-space: normal;\n max-width: 320px;\n text-align: center;\n color: var(--tcw-red);\n font-size: var(--tcw-font-size);\n}\n\n/* Reduced motion: nothing slides or lifts, but the candles still glow in\n turn and the track breathes, so the wait never looks frozen. */\n@media (prefers-reduced-motion: reduce) {\n .tcw-loading-candle {\n animation: tcw-candle-glow 2.4s ease-in-out infinite;\n animation-delay: var(--tcw-delay, 0ms);\n }\n .tcw-loading-track > span {\n width: 100%;\n background: var(--tcw-accent);\n animation: tcw-loading-breathe 2.4s ease-in-out infinite;\n }\n}\n\n@keyframes tcw-candle-glow {\n 0%, 60%, 100% { opacity: 0.28; }\n 25% { opacity: 0.9; }\n}\n\n@keyframes tcw-loading-breathe {\n 0%, 100% { opacity: 0.15; }\n 50% { opacity: 0.7; }\n}\n\n/* === On-chart indicator legend (WidgetIndicatorLegend) === */\n\n.tcw-ind-legend {\n position: absolute;\n z-index: 3;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 1px;\n max-width: calc(100% - 140px);\n pointer-events: none;\n}\n\n.tcw-ind-legend--collapsed > .tcw-ind-legend-row {\n display: none;\n}\n\n.tcw-ind-legend-row {\n display: flex;\n align-items: center;\n gap: 8px;\n max-width: 100%;\n padding: 0 4px;\n border-radius: var(--tcw-radius-sm);\n font-size: var(--tcw-font-size-xs);\n line-height: 19px;\n font-feature-settings: 'tnum';\n white-space: nowrap;\n color: var(--tcw-text-dim);\n pointer-events: auto;\n cursor: default;\n /* A narrow pane: the values shrink first, then the row is clipped. */\n overflow: hidden;\n}\n\n/* A pane's indicator: at the top of its pane, where the canvas title was,\n short enough to sit in the pane's header below the divider's grab zone. */\n.tcw-ind-legend-row--pane {\n position: absolute;\n z-index: 3;\n line-height: 15px;\n}\n\n.tcw-ind-legend-row:hover,\n.tcw-ind-legend-row:focus-within {\n background: color-mix(in srgb, var(--tcw-bg-elevated) 90%, transparent);\n box-shadow: 0 0 0 1px var(--tcw-border);\n}\n\n.tcw-ind-legend-name {\n padding: 0;\n border: none;\n background: none;\n font: inherit;\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n cursor: pointer;\n}\n\n.tcw-ind-legend-name:hover {\n color: var(--tcw-accent);\n}\n\n.tcw-ind-legend-values {\n display: inline-flex;\n gap: 7px;\n min-width: 0;\n overflow: hidden;\n}\n\n.tcw-ind-legend-row--hidden .tcw-ind-legend-name,\n.tcw-ind-legend-row--hidden .tcw-ind-legend-values {\n opacity: 0.45;\n}\n\n/* Show / settings / remove: on hover or keyboard focus (always on touch). */\n.tcw-ind-legend-actions {\n display: none;\n gap: 1px;\n margin-left: -2px;\n}\n\n.tcw-ind-legend-row:hover .tcw-ind-legend-actions,\n.tcw-ind-legend-row:focus-within .tcw-ind-legend-actions {\n display: inline-flex;\n}\n\n@media (hover: none) {\n .tcw-ind-legend-actions {\n display: inline-flex;\n }\n\n /* Finger-sized targets. */\n .tcw-ind-legend-act,\n .tcw-ind-legend-toggle {\n min-width: 28px;\n min-height: 24px;\n }\n}\n\n.tcw-ind-legend-act {\n display: inline-grid;\n place-items: center;\n width: 20px;\n height: 18px;\n padding: 0;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n}\n\n.tcw-ind-legend-act:hover {\n color: var(--tcw-text);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-ind-legend-act[data-act='remove']:hover {\n color: var(--tcw-red);\n}\n\n.tcw-ind-legend-toggle {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n margin-top: 1px;\n padding: 1px 5px;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n font: inherit;\n font-size: var(--tcw-font-size-xs);\n cursor: pointer;\n pointer-events: auto;\n}\n\n.tcw-ind-legend-toggle[hidden] {\n display: none;\n}\n\n.tcw-ind-legend-toggle:hover {\n color: var(--tcw-text);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-ind-legend-name:focus-visible,\n.tcw-ind-legend-act:focus-visible,\n.tcw-ind-legend-toggle:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: -2px;\n}\n\n/* === Sidebar === */\n\n.tcw-sidebar {\n width: var(--tcw-sidebar-w);\n flex-shrink: 0;\n background: linear-gradient(180deg, var(--tcw-bg-elevated) 0%, var(--tcw-bg-surface) 100%);\n border-inline-end: var(--tcw-border-w) solid var(--tcw-border);\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 6px 0;\n /* On a short screen the tools scroll; the menus sit outside it. */\n overflow-x: hidden;\n overflow-y: auto;\n scrollbar-width: none;\n box-shadow: var(--tcw-shadow-sm);\n}\n.tcw-sidebar::-webkit-scrollbar {\n display: none;\n}\n.tcw-sidebar > * {\n flex-shrink: 0;\n}\n\n.tcw-tool-group-wrap {\n position: relative;\n}\n\n.tcw-sidebar-btn {\n width: var(--tcw-control-h);\n height: var(--tcw-control-h);\n margin: 1px 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n font-family: inherit;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n color var(--tcw-dur-fast) var(--tcw-ease);\n position: relative;\n flex-shrink: 0;\n line-height: 1;\n border-radius: var(--tcw-control-radius);\n}\n\n.tcw-sidebar-btn svg {\n width: var(--tcw-icon);\n height: var(--tcw-icon);\n}\n\n.tcw-sidebar-btn:hover {\n color: var(--tcw-text);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-sidebar-btn.tcw-active {\n color: var(--tcw-on-icon-fg);\n background: var(--tcw-on-icon-bg);\n box-shadow: var(--tcw-on-icon-ring);\n}\n\n.tcw-sidebar-btn.tcw-danger:hover {\n color: var(--tcw-red);\n background: var(--tcw-red-soft);\n}\n\n.tcw-multi-dot {\n position: absolute;\n bottom: 3px;\n right: 3px;\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n opacity: 0.7;\n}\n\n/* The drawing tools' sections: always a hairline (it groups the tools), even in\n looks that drop the rules between toolbar groups. */\n.tcw-sidebar-divider {\n width: 20px;\n height: max(1px, var(--tcw-sep-w));\n background: var(--tcw-divider);\n margin: 5px 0;\n flex-shrink: 0;\n}\n\n.tcw-sidebar-spacer {\n flex: 1;\n}\n\n/* === Flyout === */\n\n.tcw-flyout {\n position: absolute;\n margin-inline-start: 6px;\n overflow-y: auto;\n overscroll-behavior: contain;\n min-width: 180px;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n z-index: 30;\n padding: 6px;\n backdrop-filter: blur(var(--tcw-blur));\n -webkit-backdrop-filter: blur(var(--tcw-blur));\n animation: tcw-slide-right var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n/* Spans the gap to the toolbar button: crossing it stays inside the menu. */\n.tcw-flyout::before {\n content: '';\n position: absolute;\n top: -1px;\n bottom: -1px;\n right: 100%;\n width: 8px;\n}\n\n@keyframes tcw-slide-right {\n from { opacity: 0; transform: translateX(-4px); }\n to { opacity: 1; transform: translateX(0); }\n}\n\n.tcw-flyout-header {\n text-transform: var(--tcw-label-case);\n font-size: calc(var(--tcw-font-size) - 3px);\n color: var(--tcw-text-muted);\n letter-spacing: var(--tcw-label-tracking);\n padding: 6px 10px 4px;\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-flyout-hint {\n padding: 6px 10px 2px;\n border-top: 1px solid var(--tcw-border);\n margin-top: 4px;\n font-size: calc(var(--tcw-font-size) - 2.5px);\n color: var(--tcw-text-muted);\n}\n\n.tcw-flyout-item {\n min-height: var(--tcw-menu-item-h);\n padding: 4px 10px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n cursor: pointer;\n width: 100%;\n display: flex;\n align-items: center;\n gap: 10px;\n border: none;\n background: transparent;\n text-align: start;\n font-family: inherit;\n border-radius: var(--tcw-radius-sm);\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-flyout-item:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n.tcw-flyout-item:focus-visible {\n outline: none;\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n box-shadow: inset 0 0 0 1px var(--tcw-accent);\n}\n\n.tcw-flyout-item.tcw-active {\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n font-weight: var(--tcw-weight-strong);\n}\n\n/* Pinned (favorited) flyout item — the icon set's star, filled, on the right. */\n.tcw-flyout-star {\n display: inline-flex;\n margin-inline-start: auto;\n color: var(--tcw-accent);\n}\n.tcw-flyout-star svg path { fill: currentColor; }\n\n/* Favorites strip — pinned drawing tools above the tool groups. */\n.tcw-sidebar-favorites {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.tcw-sidebar-favorites .tcw-sidebar-btn {\n position: relative;\n}\n.tcw-sidebar-favorites .tcw-sidebar-btn::before {\n content: '';\n position: absolute;\n top: 3px;\n right: 3px;\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--tcw-accent);\n opacity: 0.7;\n}\n\n/* === Modal === */\n\n.tcw-modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(8, 10, 18, 0.55);\n backdrop-filter: blur(6px) saturate(140%);\n -webkit-backdrop-filter: blur(6px) saturate(140%);\n z-index: 100;\n animation: tcw-fade-in var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n@keyframes tcw-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.tcw-modal {\n position: fixed;\n z-index: 101;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-dialog-radius);\n width: 520px;\n max-width: 92vw;\n max-height: 82vh;\n max-height: 82dvh;\n display: flex;\n flex-direction: column;\n box-shadow: var(--tcw-dialog-shadow);\n animation: tcw-modal-in var(--tcw-dur-slow) var(--tcw-ease-out);\n}\n\n@keyframes tcw-modal-in {\n from { opacity: 0; transform: translate(-50%, -48%) scale(0.96); }\n to { opacity: 1; transform: translate(-50%, -50%) scale(1); }\n}\n\n.tcw-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 22px;\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n.tcw-modal-header h3 {\n font-size: var(--tcw-font-size-lg);\n font-weight: var(--tcw-weight-strong);\n margin: 0;\n color: var(--tcw-text);\n letter-spacing: -0.015em;\n}\n\n.tcw-modal-close {\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n border-radius: var(--tcw-control-radius);\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-modal-close:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-modal-tabs {\n display: flex;\n /* Four tabs in a long language on a phone: they wrap rather than clip. No overflow here: in the\n dialog's column it would let a long body squash the tabs, and clip the underline of the active one. */\n flex-wrap: wrap;\n flex-shrink: 0;\n gap: 4px;\n padding: var(--tcw-tabs-pad-block) 18px;\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n.tcw-modal-tab {\n flex-shrink: 0;\n white-space: nowrap;\n height: var(--tcw-tab-h);\n padding: var(--tcw-tab-pad);\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight);\n color: var(--tcw-text-muted);\n border: none;\n background: transparent;\n cursor: pointer;\n border-bottom: var(--tcw-tab-line) solid transparent;\n border-radius: var(--tcw-tab-radius);\n margin-bottom: calc(var(--tcw-tab-line) / -2);\n transition: color var(--tcw-dur-fast) var(--tcw-ease), border-color var(--tcw-dur-fast) var(--tcw-ease);\n font-family: inherit;\n text-transform: capitalize;\n letter-spacing: -0.005em;\n}\n\n.tcw-modal-tab:hover {\n color: var(--tcw-text-dim);\n background: var(--tcw-tab-hover);\n}\n\n.tcw-modal-tab.tcw-active {\n color: var(--tcw-tab-on-fg);\n background: var(--tcw-tab-on-bg);\n border-bottom-color: var(--tcw-accent);\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-modal-body {\n padding: 20px 22px;\n overflow-y: auto;\n flex: 1;\n}\n\n.tcw-settings-section {\n margin-bottom: 22px;\n}\n\n.tcw-settings-section:last-child {\n margin-bottom: 0;\n}\n\n.tcw-settings-section-title {\n font-size: calc(var(--tcw-font-size) - 2.5px);\n font-weight: var(--tcw-weight-strong);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n color: var(--tcw-text-muted);\n margin-bottom: 12px;\n}\n\n.tcw-settings-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 0;\n}\n\n.tcw-settings-row + .tcw-settings-row {\n border-top: 1px solid var(--tcw-divider);\n}\n\n.tcw-settings-label {\n font-size: var(--tcw-font-size);\n color: var(--tcw-text-dim);\n letter-spacing: -0.005em;\n}\n\n.tcw-color-picker-wrap {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tcw-color-picker-wrap input[type='color'] {\n width: 28px;\n height: 28px;\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-radius-sm);\n background: transparent;\n cursor: pointer;\n padding: 2px;\n}\n\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch-wrapper {\n padding: 0;\n}\n\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch {\n border: none;\n border-radius: var(--tcw-radius-xs);\n}\n\n.tcw-color-hex {\n font-size: var(--tcw-font-size-xs);\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n min-width: 64px;\n letter-spacing: 0.01em;\n}\n\n/* A colour left to the part itself: the swatch shows where the picker starts, faded. */\n.tcw-color-auto input[type='color'] {\n opacity: 0.45;\n border-style: dashed;\n}\n\n.tcw-color-auto .tcw-color-hex {\n font-family: inherit;\n font-style: italic;\n}\n\n.tcw-color-auto-btn {\n height: 24px;\n padding: 0 8px;\n font: inherit;\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n background: transparent;\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-radius-sm);\n cursor: pointer;\n transition: color var(--tcw-dur-fast) var(--tcw-ease), border-color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-color-auto-btn:hover,\n.tcw-color-auto-btn:focus-visible {\n color: var(--tcw-text);\n border-color: var(--tcw-accent);\n}\n\n.tcw-toggle {\n width: 36px;\n height: 20px;\n background: rgba(255, 255, 255, 0.12);\n border-radius: 10px;\n position: relative;\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease);\n border: none;\n padding: 0;\n flex-shrink: 0;\n}\n\n.tcw-toggle::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n transition:\n left var(--tcw-dur-normal) var(--tcw-ease-out),\n background var(--tcw-dur-fast) var(--tcw-ease);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n}\n\n.tcw-toggle.tcw-on {\n background: var(--tcw-accent);\n box-shadow: 0 0 0 2px var(--tcw-accent-glow);\n}\n\n.tcw-toggle.tcw-on::after {\n left: 18px;\n background: #fff;\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle {\n background: rgba(0, 0, 0, 0.12);\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle::after {\n background: #999;\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle.tcw-on {\n background: var(--tcw-accent);\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle.tcw-on::after {\n background: #fff;\n}\n\n.tcw-settings-select {\n padding: 6px 10px;\n font-size: var(--tcw-font-size-sm);\n font-family: inherit;\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-input-radius);\n color: var(--tcw-text);\n cursor: pointer;\n transition: border-color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-settings-select:hover {\n border-color: var(--tcw-border-strong);\n}\n\n.tcw-settings-select:focus-visible {\n outline: none;\n border-color: var(--tcw-accent);\n box-shadow: var(--tcw-ring);\n}\n\n.tcw-modal-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 22px;\n border-top: 1px solid var(--tcw-divider);\n background: var(--tcw-bg-surface);\n border-radius: 0 0 var(--tcw-dialog-radius) var(--tcw-dialog-radius);\n}\n\n.tcw-reset-link {\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-muted);\n cursor: pointer;\n border: none;\n background: transparent;\n font-family: inherit;\n text-decoration: underline;\n text-underline-offset: 2px;\n text-decoration-color: var(--tcw-border-strong);\n transition: color var(--tcw-dur-fast) var(--tcw-ease), text-decoration-color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-reset-link:hover {\n color: var(--tcw-text-dim);\n text-decoration-color: currentColor;\n}\n\n.tcw-done-btn {\n padding: 8px 18px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n background: var(--tcw-accent);\n color: var(--tcw-accent-ink);\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n font-family: inherit;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n transform var(--tcw-dur-fast) var(--tcw-ease),\n box-shadow var(--tcw-dur-fast) var(--tcw-ease);\n letter-spacing: -0.005em;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.15);\n}\n\n.tcw-done-btn:hover {\n background: var(--tcw-accent-hover);\n box-shadow: var(--tcw-shadow-md), 0 0 0 3px var(--tcw-accent-glow);\n}\n\n.tcw-done-btn:active {\n transform: translateY(0.5px);\n}\n\n/* === Status Bar === */\n\n.tcw-statusbar {\n /* Above sidebar buttons that overflow a short chart; menus (z 30+) stay on top. */\n position: relative;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 7px 16px;\n border-top: 1px solid var(--tcw-border);\n background: var(--tcw-bg-surface);\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n flex-shrink: 0;\n font-feature-settings: 'tnum';\n}\n\n.tcw-status-right {\n display: flex;\n align-items: center;\n gap: 14px;\n margin-inline-start: auto;\n min-width: 0;\n white-space: nowrap;\n}\n\n/* Narrow screens: the toolbar already names the symbol and timeframe, so the\n range bar gets the room. */\n@media (max-width: 640px) {\n .tcw-status-info {\n display: none;\n }\n\n .tcw-range-btn {\n padding: 4px 5px;\n }\n}\n\n/* Range presets + go to date, bottom left */\n.tcw-range-bar {\n display: flex;\n align-items: center;\n gap: 1px;\n margin: -4px 12px -4px -8px;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.tcw-range-bar::-webkit-scrollbar {\n display: none;\n}\n\n.tcw-range-btn {\n flex-shrink: 0;\n padding: 4px 7px;\n font: inherit;\n font-weight: var(--tcw-weight-strong);\n letter-spacing: 0.02em;\n color: var(--tcw-text-muted);\n background: transparent;\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n transition: color var(--tcw-dur-fast) var(--tcw-ease), background var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-range-btn:hover {\n color: var(--tcw-text);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-range-btn:active {\n color: var(--tcw-accent);\n}\n\n.tcw-range-btn:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: -2px;\n}\n\n.tcw-range-goto {\n display: inline-grid;\n place-items: center;\n margin-inline-start: 6px;\n padding: 4px 6px;\n}\n\n.tcw-range-goto svg {\n display: block;\n}\n\n/* Go-to-date popover, anchored above the range bar */\n.tcw-goto {\n position: absolute;\n left: 10px;\n bottom: 40px;\n z-index: 40;\n display: grid;\n gap: 10px;\n width: 232px;\n padding: 14px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n color: var(--tcw-text);\n font-size: var(--tcw-font-size-sm);\n}\n\n.tcw-goto-title {\n font-weight: var(--tcw-weight-strong);\n font-size: var(--tcw-font-size);\n}\n\n.tcw-goto-field {\n display: grid;\n gap: 4px;\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size-xs);\n}\n\n.tcw-goto-input {\n height: 30px;\n padding: 0 8px;\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n background: var(--tcw-bg);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-input-radius);\n color-scheme: dark;\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-goto-input {\n color-scheme: light;\n}\n\n.tcw-goto-input:focus {\n outline: none;\n border-color: var(--tcw-accent);\n box-shadow: 0 0 0 2px var(--tcw-accent-soft);\n}\n\n.tcw-goto-actions {\n display: flex;\n justify-content: flex-end;\n gap: 6px;\n}\n\n.tcw-goto-submit {\n background: var(--tcw-accent);\n color: var(--tcw-accent-ink);\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-goto-submit:hover {\n background: var(--tcw-accent);\n color: var(--tcw-accent-ink);\n filter: brightness(1.08);\n}\n\n.tcw-status-indicator {\n display: flex;\n align-items: center;\n gap: 7px;\n font-weight: var(--tcw-weight);\n}\n\n.tcw-status-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n transition: background var(--tcw-dur-normal) var(--tcw-ease), box-shadow var(--tcw-dur-normal) var(--tcw-ease);\n position: relative;\n}\n\n.tcw-status-dot.tcw-connected {\n background: var(--tcw-green);\n box-shadow: 0 0 0 3px rgba(31, 168, 116, 0.18);\n}\n\n.tcw-status-dot.tcw-connected::after {\n content: '';\n position: absolute;\n inset: -3px;\n border-radius: 50%;\n border: 2px solid var(--tcw-green);\n opacity: 0;\n animation: tcw-pulse 2.2s ease-out 3;\n}\n\n@keyframes tcw-pulse {\n 0% { opacity: 0.6; transform: scale(0.6); }\n 100% { opacity: 0; transform: scale(2.2); }\n}\n\n.tcw-status-dot.tcw-error {\n background: var(--tcw-red);\n box-shadow: 0 0 0 3px rgba(232, 80, 91, 0.2);\n}\n\n/* === Command Palette === */\n\n.tcw-cmd-palette {\n position: fixed;\n z-index: 102;\n top: 18%;\n left: 50%;\n transform: translateX(-50%);\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-dialog-radius);\n width: 560px;\n max-width: 92vw;\n max-height: 62vh;\n max-height: 62dvh;\n display: flex;\n flex-direction: column;\n box-shadow: var(--tcw-dialog-shadow);\n overflow: hidden;\n backdrop-filter: blur(var(--tcw-blur));\n -webkit-backdrop-filter: blur(var(--tcw-blur));\n animation: tcw-modal-in var(--tcw-dur-slow) var(--tcw-ease-out);\n}\n\n.tcw-cmd-header {\n display: flex;\n align-items: center;\n padding: 14px 18px;\n border-bottom: 1px solid var(--tcw-divider);\n gap: 12px;\n}\n\n.tcw-cmd-icon {\n color: var(--tcw-text-muted);\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n}\n\n.tcw-cmd-input {\n flex: 1;\n background: transparent;\n border: none;\n outline: none;\n font-size: calc(var(--tcw-font-size) + 1.5px);\n font-family: inherit;\n color: var(--tcw-text);\n caret-color: var(--tcw-accent);\n letter-spacing: -0.005em;\n}\n\n.tcw-cmd-input::placeholder {\n color: var(--tcw-text-muted);\n}\n\n.tcw-cmd-hint {\n font-size: calc(var(--tcw-font-size) - 3px);\n color: var(--tcw-text-muted);\n font-family: var(--tcw-font-mono);\n border: 1px solid var(--tcw-border);\n background: var(--tcw-bg-surface);\n padding: 3px 7px;\n border-radius: 4px;\n flex-shrink: 0;\n box-shadow: inset 0 -1px 0 var(--tcw-border);\n}\n\n.tcw-cmd-list {\n overflow-y: auto;\n flex: 1;\n padding: 6px;\n max-height: 380px;\n}\n\n.tcw-cmd-category {\n text-transform: var(--tcw-label-case);\n font-size: calc(var(--tcw-font-size) - 3px);\n color: var(--tcw-text-muted);\n letter-spacing: var(--tcw-label-tracking);\n padding: 10px 10px 4px;\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-cmd-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 9px 12px;\n font-size: var(--tcw-font-size);\n color: var(--tcw-text-dim);\n cursor: pointer;\n width: 100%;\n border: none;\n background: transparent;\n font-family: inherit;\n text-align: start;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n gap: 10px;\n border-radius: var(--tcw-radius);\n letter-spacing: -0.005em;\n}\n\n.tcw-cmd-item:hover,\n.tcw-cmd-item.tcw-selected {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-cmd-item.tcw-selected {\n box-shadow: inset 2px 0 0 var(--tcw-accent);\n}\n\n.tcw-cmd-item.tcw-active .tcw-cmd-item-label {\n color: var(--tcw-accent);\n font-weight: var(--tcw-weight-strong);\n}\n\n.tcw-cmd-item-label {\n flex: 1;\n}\n\n.tcw-cmd-check {\n display: inline-flex;\n color: var(--tcw-accent);\n}\n\n.tcw-cmd-kbd {\n font-size: calc(var(--tcw-font-size) - 3px);\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n padding: 2px 6px;\n border-radius: var(--tcw-tag-radius);\n box-shadow: inset 0 -1px 0 var(--tcw-border);\n}\n\n.tcw-cmd-empty {\n padding: 32px 16px;\n text-align: center;\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size);\n}\n\n/* A key and what it does, in a list dialog's footer: keys in the shortcut chips (.tcw-cmd-kbd). */\n.tcw-cmd-help {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n}\n.tcw-cmd-help-text { margin-inline-start: 3px; }\n.tcw-cmd-key {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n font-style: normal;\n}\n\n.tcw-cmd-footer {\n display: flex;\n align-items: center;\n gap: 18px;\n padding: 10px 18px;\n border-top: 1px solid var(--tcw-divider);\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n background: var(--tcw-bg-surface);\n}\n\n/* === Watchlist === */\n\n.tcw-watchlist {\n width: 220px;\n flex-shrink: 0;\n background: var(--tcw-bg-surface);\n border-inline-start: 1px solid var(--tcw-border);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-shadow: var(--tcw-shadow-sm);\n}\n\n.tcw-watchlist-header {\n position: relative;\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 6px 8px 6px 8px;\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n/* The shown list's name: opens the lists menu. */\n.tcw-watchlist-name {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 6px;\n height: var(--tcw-control-h-sm);\n padding: 0 6px;\n border: 0;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-dim);\n font: inherit;\n font-size: var(--tcw-font-size-xs);\n font-weight: var(--tcw-weight-strong);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n text-align: start;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n cursor: pointer;\n}\n.tcw-watchlist-name::after {\n content: '';\n flex: none;\n width: 0;\n height: 0;\n margin-inline-start: auto;\n border: 4px solid transparent;\n border-top-color: currentColor;\n border-bottom-width: 0;\n opacity: 0.7;\n}\n\n.tcw-watchlist-add {\n flex: none;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: 0;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n font: inherit;\n font-size: var(--tcw-font-size-lg);\n line-height: 1;\n cursor: pointer;\n}\n\n.tcw-watchlist-name:hover,\n.tcw-watchlist-add:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n.tcw-watchlist-name:focus-visible,\n.tcw-watchlist-add:focus-visible,\n.tcw-watchlist-input:focus-visible {\n outline: none;\n box-shadow: var(--tcw-ring);\n}\n\n/* The lists menu, under the header. */\n.tcw-watchlist-menu {\n top: calc(100% - 2px);\n left: 6px;\n right: 6px;\n margin-top: 0;\n}\n.tcw-watchlist-count {\n color: var(--tcw-text-muted);\n font-family: var(--tcw-font-mono);\n font-size: var(--tcw-font-size-xs);\n}\n.tcw-watchlist-menu .tcw-danger {\n color: var(--tcw-red);\n}\n\n/* Naming a list in place. */\n.tcw-watchlist-input {\n flex: 1;\n min-width: 0;\n height: var(--tcw-control-h-sm);\n padding: 0 8px;\n border: var(--tcw-border-w) solid var(--tcw-border-strong);\n border-radius: var(--tcw-input-radius);\n background: var(--tcw-bg);\n color: var(--tcw-text);\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n}\n\n.tcw-watchlist-empty {\n padding: 16px 14px;\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size-sm);\n line-height: 1.5;\n}\n\n/* A row's remove button shows on hover or focus, over its numbers. */\n.tcw-watchlist-remove {\n position: absolute;\n top: 50%;\n right: 6px;\n display: grid;\n place-items: center;\n width: 20px;\n height: 20px;\n border: 0;\n border-radius: var(--tcw-radius-sm);\n background: var(--tcw-bg-elevated);\n color: var(--tcw-text-muted);\n font: inherit;\n font-size: var(--tcw-font-size);\n line-height: 1;\n opacity: 0;\n transform: translateY(-50%);\n cursor: pointer;\n transition: opacity var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-watchlist-row:hover .tcw-watchlist-remove,\n.tcw-watchlist-row:focus-within .tcw-watchlist-remove {\n opacity: 1;\n}\n.tcw-watchlist-remove:hover {\n color: var(--tcw-red);\n}\n.tcw-watchlist-row.tcw-watchlist-dragging {\n opacity: 0.45;\n}\n\n.tcw-watchlist-list {\n flex: 1;\n overflow-y: auto;\n padding: 4px 0;\n}\n\n.tcw-watchlist-row {\n position: relative;\n display: grid;\n grid-template-columns: 1fr auto auto;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease);\n border-inline-start: 2px solid transparent;\n outline: none;\n}\n\n.tcw-watchlist-row:hover {\n background: var(--tcw-hover-bg);\n}\n\n.tcw-watchlist-row:focus-visible {\n background: var(--tcw-hover-bg);\n border-inline-start-color: var(--tcw-accent);\n}\n\n.tcw-watchlist-row.tcw-watchlist-active {\n background: var(--tcw-accent-soft);\n border-inline-start-color: var(--tcw-accent);\n}\n\n.tcw-watchlist-symbol {\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n letter-spacing: -0.005em;\n white-space: nowrap;\n}\n\n.tcw-watchlist-spark {\n width: 56px;\n height: 22px;\n align-self: center;\n}\n\n.tcw-watchlist-stats {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 1px;\n font-variant-numeric: tabular-nums;\n font-family: var(--tcw-font-mono);\n}\n\n.tcw-watchlist-price {\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n font-weight: var(--tcw-weight);\n}\n\n.tcw-watchlist-change {\n font-size: calc(var(--tcw-font-size) - 2.5px);\n color: var(--tcw-text-muted);\n font-weight: var(--tcw-weight);\n}\n\n.tcw-watchlist-change.tcw-up {\n color: var(--tcw-green);\n}\n\n.tcw-watchlist-change.tcw-down {\n color: var(--tcw-red);\n}\n\n@media (max-width: 768px) {\n .tcw-watchlist {\n display: none;\n }\n}\n\n/* === Toast === */\n\n.tcw-toast-icon {\n display: inline-flex;\n vertical-align: -2px;\n margin-inline-end: 7px;\n color: var(--tcw-accent);\n}\n.tcw-toast-error .tcw-toast-icon { color: var(--tcw-red); }\n\n.tcw-toast {\n position: absolute;\n bottom: 60px;\n left: 50%;\n transform: translate(-50%, 12px);\n z-index: 40;\n padding: 9px 14px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-toast-radius);\n box-shadow: var(--tcw-menu-shadow);\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight);\n color: var(--tcw-text);\n opacity: 0;\n transition: opacity var(--tcw-dur-normal) var(--tcw-ease-out), transform var(--tcw-dur-normal) var(--tcw-ease-out);\n pointer-events: none;\n max-width: calc(100% - 32px);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n letter-spacing: -0.005em;\n}\n\n.tcw-toast.tcw-toast-in {\n opacity: 1;\n transform: translate(-50%, 0);\n}\n\n.tcw-toast-error {\n border-color: var(--tcw-red);\n color: var(--tcw-red);\n}\n\n/* === Replay scrubber === */\n\n/* Picking the replay start: the bars right of the pointer would be hidden. */\n.tcw-replay-shade {\n position: absolute;\n z-index: 4;\n pointer-events: none;\n background: color-mix(in srgb, var(--tcw-bg) 62%, transparent);\n border-inline-start: 1.5px dashed var(--tcw-accent);\n}\n\n.tcw-replay-group {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.tcw-replay-group[hidden] { display: none; }\n\n.tcw-replay-hint {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 0 4px;\n color: var(--tcw-text-dim);\n white-space: nowrap;\n}\n\n.tcw-replay-text-btn {\n height: 26px;\n padding: 0 10px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text);\n font: inherit;\n font-weight: var(--tcw-weight);\n white-space: nowrap;\n cursor: pointer;\n transition: background var(--tcw-dur-fast), border-color var(--tcw-dur-fast), color var(--tcw-dur-fast);\n}\n\n.tcw-replay-text-btn:hover { background: var(--tcw-hover-bg); border-color: var(--tcw-border-strong); }\n.tcw-replay-text-btn:focus-visible { outline: none; box-shadow: var(--tcw-ring); }\n\n/* At the last bar: the way out is the next thing to do. */\n.tcw-replay-bar--ended .tcw-replay-realtime {\n background: var(--tcw-accent);\n border-color: var(--tcw-accent);\n color: var(--tcw-accent-ink);\n}\n\n.tcw-replay-btn:disabled { opacity: 0.4; cursor: default; }\n\n@media (max-width: 640px) {\n .tcw-replay-bar {\n flex-wrap: wrap;\n justify-content: center;\n max-width: calc(100% - 24px);\n border-radius: var(--tcw-panel-radius);\n }\n .tcw-replay-hint { white-space: normal; }\n}\n\n.tcw-replay-bar {\n position: absolute;\n left: 50%;\n /* Above the 30px time axis, so its dates stay readable. */\n bottom: 40px;\n transform: translateX(-50%);\n z-index: 25;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n backdrop-filter: blur(var(--tcw-blur));\n -webkit-backdrop-filter: blur(var(--tcw-blur));\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n animation: tcw-pop-in var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n.tcw-replay-btn {\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--tcw-text-dim);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n font-family: inherit;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-replay-btn:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-replay-btn.tcw-replay-play {\n background: var(--tcw-accent);\n color: var(--tcw-accent-ink);\n width: 32px;\n height: 32px;\n box-shadow: 0 0 0 3px var(--tcw-accent-glow);\n}\n\n.tcw-replay-btn.tcw-replay-play:hover {\n background: var(--tcw-accent-hover);\n}\n\n.tcw-replay-scrubber {\n appearance: none;\n -webkit-appearance: none;\n width: 220px;\n height: 4px;\n background: var(--tcw-border-strong);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n}\n\n.tcw-replay-scrubber::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--tcw-accent);\n border: 2px solid var(--tcw-bg-elevated);\n box-shadow: 0 0 0 1px var(--tcw-accent), 0 2px 6px rgba(0, 0, 0, 0.3);\n cursor: pointer;\n}\n\n.tcw-replay-scrubber::-moz-range-thumb {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--tcw-accent);\n border: 2px solid var(--tcw-bg-elevated);\n box-shadow: 0 0 0 1px var(--tcw-accent), 0 2px 6px rgba(0, 0, 0, 0.3);\n cursor: pointer;\n}\n\n.tcw-replay-progress {\n font-size: var(--tcw-font-size-xs);\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n min-width: 64px;\n text-align: center;\n font-feature-settings: 'tnum';\n}\n\n.tcw-replay-speed {\n padding: 4px 8px;\n font-size: var(--tcw-font-size-xs);\n font-family: var(--tcw-font-mono);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-control-radius);\n color: var(--tcw-text-dim);\n cursor: pointer;\n}\n\n.tcw-replay-speed:hover {\n border-color: var(--tcw-border-strong);\n}\n\n@media (max-width: 640px) {\n .tcw-replay-scrubber {\n width: 140px;\n }\n .tcw-replay-progress {\n display: none;\n }\n}\n\n/* === Hotkey sheet === */\n\n.tcw-hotkey-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 24px 32px;\n}\n\n.tcw-hotkey-section .tcw-settings-section-title {\n margin-bottom: 8px;\n}\n\n.tcw-hotkey-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 6px 0;\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n.tcw-hotkey-row:last-child {\n border-bottom: none;\n}\n\n.tcw-hotkey-keys {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.tcw-hotkey-sep {\n font-size: calc(var(--tcw-font-size) - 3px);\n color: var(--tcw-text-muted);\n}\n\n.tcw-hotkey-label {\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n text-align: end;\n letter-spacing: -0.005em;\n}\n\n@media (max-width: 640px) {\n .tcw-hotkey-grid {\n grid-template-columns: 1fr;\n gap: 18px;\n }\n}\n\n/* === Scrollbar (subtle, premium feel) === */\n\n.tcw-dropdown::-webkit-scrollbar,\n.tcw-modal-body::-webkit-scrollbar,\n.tcw-cmd-list::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n.tcw-dropdown::-webkit-scrollbar-track,\n.tcw-modal-body::-webkit-scrollbar-track,\n.tcw-cmd-list::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.tcw-dropdown::-webkit-scrollbar-thumb,\n.tcw-modal-body::-webkit-scrollbar-thumb,\n.tcw-cmd-list::-webkit-scrollbar-thumb {\n background: var(--tcw-border-strong);\n border-radius: 4px;\n border: 2px solid transparent;\n background-clip: padding-box;\n}\n\n.tcw-dropdown::-webkit-scrollbar-thumb:hover,\n.tcw-modal-body::-webkit-scrollbar-thumb:hover,\n.tcw-cmd-list::-webkit-scrollbar-thumb:hover {\n background: var(--tcw-text-muted);\n background-clip: padding-box;\n border: 2px solid transparent;\n}\n\n/* === Responsive === */\n\n@media (max-width: 768px) {\n .tcw-toolbar {\n padding: 0 4px;\n height: max(44px, var(--tcw-toolbar-h)); /* Apple HIG minimum touch target */\n }\n .tcw-toolbar-sep {\n display: none;\n }\n .tcw-btn,\n .tcw-dropdown-trigger {\n height: max(40px, var(--tcw-control-h)); /* fatter tap target */\n padding: 0 12px;\n font-size: var(--tcw-font-size);\n }\n .tcw-btn-icon {\n width: max(40px, var(--tcw-control-h));\n height: max(40px, var(--tcw-control-h));\n }\n .tcw-sidebar {\n width: max(44px, var(--tcw-sidebar-w));\n }\n .tcw-sidebar-btn {\n width: max(40px, var(--tcw-control-h));\n height: max(40px, var(--tcw-control-h));\n }\n .tcw-modal,\n .tcw-cmd-palette {\n width: 94vw;\n border-radius: var(--tcw-dialog-radius);\n }\n\n /* Hide the right-side watchlist on tablets too — already declared but\n * grouped here for clarity. */\n .tcw-watchlist {\n display: none;\n }\n\n /* Replay scrubber compact mode */\n .tcw-replay-scrubber {\n width: 120px;\n }\n .tcw-replay-progress {\n display: none;\n }\n}\n\n/* === Mobile bottom-sheet pattern ===\n * On phones, swap floating-centered modals for full-width sheets that slide\n * up from the bottom. Bigger hit targets, no awkward off-screen clipping,\n * matches how every modern iOS/Android app handles overflow UI.\n */\n@media (max-width: 640px) {\n .tcw-modal,\n .tcw-cmd-palette {\n top: auto;\n /* Above the on-screen keyboard (the widget sets it from visualViewport). */\n bottom: var(--tcw-keyboard-inset, 0px);\n padding-left: env(safe-area-inset-left, 0px);\n padding-right: env(safe-area-inset-right, 0px);\n left: 0;\n right: 0;\n transform: none;\n /* The border and the safe-area padding inside the screen's width. */\n box-sizing: border-box;\n width: 100vw;\n max-width: 100vw;\n max-height: 92vh;\n max-height: 92dvh;\n border-radius: var(--tcw-dialog-radius) var(--tcw-dialog-radius) 0 0;\n border-bottom: none;\n /* Grab handle */\n padding-top: 8px;\n }\n\n /* Visual \"grab handle\" affordance — a short pill at the top of every sheet */\n .tcw-modal::before,\n .tcw-cmd-palette::before {\n content: '';\n display: block;\n width: 36px;\n height: 4px;\n border-radius: 2px;\n background: var(--tcw-border-strong);\n margin: 0 auto 8px;\n opacity: 0.7;\n }\n\n /* Reuse the existing modal-in animation but slide from below instead of\n * popping from center, so the entrance reads as a sheet, not a dialog. */\n @keyframes tcw-modal-in {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .tcw-modal,\n .tcw-cmd-palette {\n animation: tcw-modal-in var(--tcw-dur-slow) var(--tcw-ease-out);\n }\n\n /* Safe-area-aware footer padding for iPhone notch / home indicator */\n .tcw-modal-footer,\n .tcw-cmd-footer {\n padding-bottom: max(14px, env(safe-area-inset-bottom));\n }\n\n /* Larger tap targets inside sheets */\n .tcw-modal-tab {\n padding: 14px 16px;\n }\n .tcw-cmd-item {\n padding: 12px 14px;\n font-size: calc(var(--tcw-font-size) + 1px);\n }\n .tcw-dropdown-item {\n padding: 12px 12px;\n font-size: calc(var(--tcw-font-size) + 1px);\n }\n\n /* Hotkey sheet — single column on phones */\n .tcw-hotkey-grid {\n grid-template-columns: 1fr;\n }\n}\n\n/* === Price alerts panel === */\n\n.tcw-alerts-panel {\n position: absolute;\n top: var(--tcw-panel-top);\n inset-inline-end: 12px;\n z-index: 40;\n width: 300px;\n max-width: calc(100vw - 24px);\n display: flex;\n flex-direction: column;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n overflow: hidden;\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n\n@keyframes tcw-alerts-in {\n from { opacity: 0; transform: translateY(-6px) scale(0.98); }\n to { opacity: 1; transform: none; }\n}\n\n.tcw-alerts-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n font-weight: var(--tcw-weight-strong);\n font-size: var(--tcw-font-size);\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-border);\n}\n\n.tcw-alerts-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-alerts-close:hover {\n background: var(--tcw-bg-surface);\n color: var(--tcw-text);\n}\n\n.tcw-alerts-form {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n padding: 12px;\n border-bottom: 1px solid var(--tcw-border);\n}\n\n.tcw-alerts-form input,\n.tcw-alerts-form select {\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n height: 32px;\n padding: 0 8px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-sm);\n outline: none;\n}\n.tcw-alerts-form input:focus,\n.tcw-alerts-form select:focus {\n border-color: var(--tcw-accent);\n box-shadow: 0 0 0 2px var(--tcw-accent-soft);\n}\n.tcw-alerts-message,\n.tcw-alerts-source {\n grid-column: 1 / -1;\n}\n\n.tcw-alerts-add {\n grid-column: 1 / -1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 34px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-accent-ink);\n background: var(--tcw-accent);\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-alerts-add:hover {\n background: var(--tcw-accent-hover);\n}\n\n.tcw-alerts-list {\n max-height: 260px;\n overflow-y: auto;\n padding: 6px;\n}\n\n.tcw-alerts-empty {\n padding: 18px 12px;\n text-align: center;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-muted);\n line-height: 1.5;\n}\n\n.tcw-alerts-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 8px 8px;\n border-radius: var(--tcw-radius-sm);\n}\n.tcw-alerts-row:hover {\n background: var(--tcw-bg-surface);\n}\n.tcw-alerts-triggered {\n background: var(--tcw-accent-soft);\n}\n\n.tcw-alerts-info {\n min-width: 0;\n}\n.tcw-alerts-row-main {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n font-variant-numeric: tabular-nums;\n}\n.tcw-alerts-row-note {\n margin-top: 2px;\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.tcw-alerts-badge {\n font-size: calc(var(--tcw-font-size) - 4px);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n padding: 2px 5px;\n border-radius: var(--tcw-tag-radius);\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n}\n\n.tcw-alerts-del {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-alerts-del:hover {\n background: var(--tcw-red-soft);\n color: var(--tcw-red);\n}\n\n@media (max-width: 640px) {\n .tcw-alerts-panel {\n top: auto;\n bottom: 0;\n left: 0;\n right: 0;\n width: 100vw;\n max-width: 100vw;\n border-radius: var(--tcw-radius-xl) var(--tcw-radius-xl) 0 0;\n }\n .tcw-alerts-list {\n max-height: 40vh;\n max-height: 40dvh;\n padding-bottom: max(8px, env(safe-area-inset-bottom));\n }\n}\n\n/* === Data Window === */\n\n.tcw-datawin {\n position: absolute;\n top: var(--tcw-panel-top);\n inset-inline-end: 12px;\n z-index: 38;\n width: 200px;\n display: flex;\n flex-direction: column;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n overflow: hidden;\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n.tcw-datawin-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 9px 12px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-datawin-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-datawin-close:hover { background: var(--tcw-bg-surface); color: var(--tcw-text); }\n.tcw-datawin-body { padding: 6px 4px; max-height: 360px; overflow-y: auto; }\n.tcw-datawin-empty { padding: 14px; text-align: center; font-size: var(--tcw-font-size-sm); color: var(--tcw-text-muted); }\n.tcw-datawin-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n padding: 3px 8px;\n font-size: var(--tcw-font-size-sm);\n}\n.tcw-datawin-label { color: var(--tcw-text-muted); }\n.tcw-datawin-value { color: var(--tcw-text); font-variant-numeric: tabular-nums; font-weight: var(--tcw-weight-strong); }\n.tcw-datawin-value.tcw-up { color: var(--tcw-green); }\n.tcw-datawin-value.tcw-down { color: var(--tcw-red); }\n.tcw-datawin-sub {\n margin: 6px 8px 2px;\n font-size: calc(var(--tcw-font-size) - 3px);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n color: var(--tcw-text-muted);\n border-top: 1px solid var(--tcw-border);\n padding-top: 6px;\n}\n\n@media (max-width: 640px) {\n .tcw-datawin { top: auto; bottom: 0; left: 0; right: 0; width: 100vw; border-radius: var(--tcw-radius-xl) var(--tcw-radius-xl) 0 0; }\n}\n\n/* === Depth-of-market ladder === */\n\n.tcw-ladder {\n position: absolute;\n top: var(--tcw-panel-top);\n inset-inline-end: 12px;\n z-index: 41;\n width: 240px;\n display: flex;\n flex-direction: column;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n overflow: hidden;\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n.tcw-ladder-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n font-size: var(--tcw-font-size);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-ladder-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-ladder-close:hover { background: var(--tcw-bg-surface); color: var(--tcw-text); }\n.tcw-ladder-cols {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n padding: 4px 0;\n font-size: calc(var(--tcw-font-size) - 3px);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n color: var(--tcw-text-muted);\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-ladder-cols span { text-align: center; }\n.tcw-ladder-body { max-height: 360px; overflow-y: auto; }\n.tcw-ladder-empty { padding: 18px; text-align: center; font-size: var(--tcw-font-size-sm); color: var(--tcw-text-muted); }\n\n.tcw-ladder-row {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n height: 22px;\n font-variant-numeric: tabular-nums;\n}\n.tcw-ladder-cell {\n position: relative;\n display: flex;\n align-items: center;\n border: none;\n background: transparent;\n font-size: var(--tcw-font-size-xs);\n cursor: pointer;\n font-variant-numeric: tabular-nums;\n overflow: hidden;\n}\n.tcw-ladder-cell:disabled { cursor: default; }\n/* Depth bar grows from the centre column outward. */\n.tcw-ladder-cell::before {\n content: '';\n position: absolute;\n top: 1px; bottom: 1px;\n width: var(--w, 0%);\n}\n.tcw-ladder-bid { justify-content: flex-end; padding-right: 8px; color: var(--tcw-green); }\n.tcw-ladder-bid::before { right: 0; background: var(--tcw-green-soft); }\n.tcw-ladder-bid span, .tcw-ladder-bid { position: relative; }\n.tcw-ladder-ask { justify-content: flex-start; padding-left: 8px; color: var(--tcw-red); }\n.tcw-ladder-ask::before { left: 0; background: var(--tcw-red-soft); }\n.tcw-ladder-cell:not(:disabled):hover::before { opacity: 0.7; filter: brightness(1.4); }\n.tcw-ladder-cell > * { position: relative; }\n.tcw-ladder-price {\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: var(--tcw-font-size-xs);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text-dim);\n border-inline-start: 1px solid var(--tcw-border);\n border-inline-end: 1px solid var(--tcw-border);\n}\n.tcw-ladder-price.tcw-ask { color: var(--tcw-red); }\n.tcw-ladder-price.tcw-bid { color: var(--tcw-green); }\n\n@media (max-width: 640px) {\n .tcw-ladder { top: auto; bottom: 0; left: 0; right: 0; width: 100vw; border-radius: var(--tcw-radius-xl) var(--tcw-radius-xl) 0 0; }\n .tcw-ladder-body { max-height: 45vh; max-height: 45dvh; padding-bottom: max(0px, env(safe-area-inset-bottom)); }\n}\n\n/* === Bracket order placement === */\n\n.tcw-btn-long:hover { color: var(--tcw-green) !important; }\n.tcw-btn-short:hover { color: var(--tcw-red) !important; }\n\n.tcw-bracket-bar {\n position: absolute;\n top: calc(var(--tcw-panel-top) + 2px);\n left: 50%;\n transform: translateX(-50%);\n z-index: 45;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 7px 8px 7px 14px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n.tcw-bracket-label {\n font-size: var(--tcw-font-size-sm);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n}\n.tcw-bracket-label[data-side='buy'] { color: var(--tcw-green); }\n.tcw-bracket-label[data-side='sell'] { color: var(--tcw-red); }\n.tcw-bracket-hint {\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n}\n.tcw-bracket-cancel, .tcw-bracket-confirm {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n height: 30px;\n padding: 0 12px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-bracket-cancel {\n color: var(--tcw-text-dim);\n background: var(--tcw-bg-surface);\n}\n.tcw-bracket-cancel:hover { color: var(--tcw-text); }\n.tcw-bracket-confirm {\n color: var(--tcw-accent-ink);\n background: var(--tcw-accent);\n}\n.tcw-bracket-confirm:hover { background: var(--tcw-accent-hover); }\n\n@media (max-width: 640px) {\n .tcw-bracket-bar { width: calc(100vw - 24px); justify-content: space-between; }\n .tcw-bracket-hint { display: none; }\n}\n\n/* === Drawing style + templates popover === */\n\n.tcw-style-panel {\n position: absolute;\n bottom: 12px;\n inset-inline-start: var(--tcw-panel-left);\n z-index: 40;\n width: 220px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n.tcw-style-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n}\n.tcw-style-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-style-close:hover { background: var(--tcw-bg-surface); color: var(--tcw-text); }\n\n.tcw-style-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }\n.tcw-style-swatch {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: 1px solid var(--tcw-border-strong);\n cursor: pointer;\n padding: 0;\n}\n.tcw-style-swatch.tcw-on { outline: 2px solid var(--tcw-accent); outline-offset: 1px; }\n.tcw-style-picker {\n width: 22px;\n height: 22px;\n padding: 0;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-sm);\n background: transparent;\n cursor: pointer;\n}\n.tcw-style-width, .tcw-style-dash {\n flex: 1;\n min-width: 0;\n height: 26px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-control-radius);\n color: var(--tcw-text-dim);\n cursor: pointer;\n font-size: var(--tcw-font-size-xs);\n}\n.tcw-style-width span { width: 16px; background: currentColor; border-radius: var(--tcw-radius-xs); }\n.tcw-style-width.tcw-on, .tcw-style-dash.tcw-on {\n border-color: var(--tcw-accent);\n color: var(--tcw-accent);\n}\n\n.tcw-style-subhead {\n font-size: calc(var(--tcw-font-size) - 3px);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n color: var(--tcw-text-muted);\n margin-top: 2px;\n}\n.tcw-style-save { display: flex; gap: 6px; }\n.tcw-style-name {\n flex: 1;\n min-width: 0;\n height: 28px;\n padding: 0 8px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-input-radius);\n outline: none;\n}\n.tcw-style-name:focus { border-color: var(--tcw-accent); }\n.tcw-style-savebtn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 10px;\n height: 28px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-accent-ink);\n background: var(--tcw-accent);\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-style-savebtn:hover { background: var(--tcw-accent-hover); }\n\n.tcw-style-templates { display: flex; flex-direction: column; gap: 2px; max-height: 140px; overflow-y: auto; }\n.tcw-style-empty { font-size: var(--tcw-font-size-xs); color: var(--tcw-text-muted); padding: 4px 0; }\n.tcw-style-template { display: flex; align-items: center; gap: 4px; }\n.tcw-style-apply {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 5px 7px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n background: transparent;\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n text-align: start;\n}\n.tcw-style-apply:hover { background: var(--tcw-bg-surface); }\n.tcw-style-tdot { flex-shrink: 0; width: 9px; height: 9px; border-radius: 50%; }\n.tcw-style-tdel {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-style-tdel:hover { background: var(--tcw-red-soft); color: var(--tcw-red); }\n\n/* === Settings range slider === */\n\n.tcw-settings-range {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.tcw-settings-range input[type='range'] {\n width: 110px;\n accent-color: var(--tcw-accent);\n cursor: pointer;\n}\n.tcw-settings-range-val {\n min-width: 38px;\n text-align: end;\n font-size: var(--tcw-font-size-sm);\n font-variant-numeric: tabular-nums;\n color: var(--tcw-text-dim);\n}\n\n/* === Indicator settings dialog === */\n\n/* Narrow on a desktop; on a phone a sheet across the screen like every dialog. */\n@media (min-width: 641px) {\n .tcw-modal-narrow {\n max-width: 360px;\n }\n}\n.tcw-indi-input {\n width: 110px;\n height: 30px;\n padding: 0 8px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-input-radius);\n outline: none;\n font-variant-numeric: tabular-nums;\n}\n.tcw-indi-input:focus {\n border-color: var(--tcw-accent);\n box-shadow: 0 0 0 2px var(--tcw-accent-soft);\n}\n.tcw-indi-select {\n width: 150px;\n padding-right: 4px;\n cursor: pointer;\n}\n/* A level: its value and a remove button. */\n.tcw-indi-level {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.tcw-indi-remove {\n display: inline-grid;\n place-items: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n padding: 0;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n}\n.tcw-indi-remove:hover {\n color: var(--tcw-red);\n background: var(--tcw-hover-bg);\n}\n.tcw-indi-remove:focus-visible {\n outline: 2px solid var(--tcw-accent);\n outline-offset: -2px;\n}\n.tcw-indi-add {\n margin-top: 8px;\n}\n.tcw-indi-color {\n width: 36px;\n height: 28px;\n padding: 2px;\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-sm);\n cursor: pointer;\n}\n\n/* === Object tree panel === */\n\n.tcw-tree-panel {\n position: absolute;\n top: var(--tcw-panel-top);\n inset-inline-end: 12px;\n z-index: 39;\n width: 280px;\n max-width: calc(100vw - 24px);\n display: flex;\n flex-direction: column;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n overflow: hidden;\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n\n.tcw-tree-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n font-weight: var(--tcw-weight-strong);\n font-size: var(--tcw-font-size);\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-tree-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-tree-close:hover {\n background: var(--tcw-bg-surface);\n color: var(--tcw-text);\n}\n\n.tcw-tree-section {\n padding: 6px;\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-tree-section:last-child {\n border-bottom: none;\n}\n.tcw-tree-section-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 8px 4px;\n font-size: calc(var(--tcw-font-size) - 3px);\n font-weight: calc(var(--tcw-weight-strong) + 100);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n color: var(--tcw-text-muted);\n}\n.tcw-tree-add {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-tree-add:hover {\n background: var(--tcw-accent-soft);\n color: var(--tcw-accent);\n}\n.tcw-tree-dot {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n}\n.tcw-tree-list {\n max-height: 200px;\n overflow-y: auto;\n}\n\n.tcw-tree-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 6px 8px;\n border-radius: var(--tcw-radius-sm);\n}\n.tcw-tree-row:hover {\n background: var(--tcw-bg-surface);\n}\n.tcw-tree-hidden .tcw-tree-name {\n opacity: 0.5;\n}\n.tcw-tree-name {\n min-width: 0;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.tcw-tree-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-shrink: 0;\n}\n.tcw-tree-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n}\n.tcw-tree-btn:hover {\n background: var(--tcw-bg-elevated);\n color: var(--tcw-text);\n}\n.tcw-tree-btn.tcw-tree-on {\n color: var(--tcw-accent);\n}\n.tcw-tree-btn.tcw-tree-del:hover {\n background: var(--tcw-red-soft);\n color: var(--tcw-red);\n}\n.tcw-tree-group .tcw-tree-name {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: var(--tcw-weight-strong);\n}\n.tcw-tree-group .tcw-tree-name svg {\n flex: none;\n color: var(--tcw-text-muted);\n}\n.tcw-tree-member {\n margin-left: 14px;\n padding-left: 10px;\n border-inline-start: 1px solid var(--tcw-border-strong);\n border-radius: 0 var(--tcw-radius-sm) var(--tcw-radius-sm) 0;\n}\n.tcw-tree-rename {\n flex: 1;\n min-width: 0;\n padding: 3px 6px;\n border: 1px solid var(--tcw-accent-line);\n border-radius: var(--tcw-input-radius);\n background: var(--tcw-bg-surface);\n color: var(--tcw-text);\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n}\n.tcw-tree-rename:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--tcw-accent-soft);\n}\n.tcw-tree-empty {\n padding: 8px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-muted);\n}\n\n@media (max-width: 640px) {\n .tcw-tree-panel {\n top: auto;\n bottom: 0;\n left: 0;\n right: 0;\n width: 100vw;\n max-width: 100vw;\n border-radius: var(--tcw-radius-xl) var(--tcw-radius-xl) 0 0;\n }\n .tcw-tree-list {\n max-height: 30vh;\n max-height: 30dvh;\n }\n .tcw-tree-section:last-child {\n padding-bottom: max(6px, env(safe-area-inset-bottom));\n }\n}\n\n/* === Reduced motion === */\n\n@media (prefers-reduced-motion: reduce) {\n .tcw-root *,\n .tcw-root *::before,\n .tcw-root *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n /* Except the loader's slow glow (opacity only): without it a long wait\n looks frozen. */\n .tcw-root .tcw-loading-candle,\n .tcw-root .tcw-loading-track > span {\n animation-duration: 2.4s !important;\n animation-iteration-count: infinite !important;\n animation-delay: var(--tcw-delay, 0ms) !important;\n }\n}\n\n/* --- Drawing settings dialog --- */\n.tcw-drawing-settings .tcw-modal-footer { gap: 12px; }\n.tcw-drawing-settings-tools {\n display: flex;\n gap: 14px;\n margin-inline-end: auto;\n}\n.tcw-drawing-text {\n min-height: 56px;\n resize: vertical;\n font-family: inherit;\n}\n.tcw-levels-editor { display: grid; gap: 6px; margin-bottom: 10px; }\n.tcw-levels-grid {\n display: grid;\n gap: 4px;\n max-height: 260px;\n overflow-y: auto;\n padding-right: 2px;\n}\n.tcw-level-row {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) 32px 24px;\n align-items: center;\n gap: 8px;\n}\n.tcw-level-row input[type='checkbox'] { accent-color: var(--tcw-accent); }\n.tcw-level-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: 0;\n border-radius: var(--tcw-radius-sm, 4px);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n}\n.tcw-level-remove:hover { color: var(--tcw-text); background: var(--tcw-bg-elevated); }\n.tcw-level-remove:focus-visible { outline: 2px solid var(--tcw-accent); outline-offset: 1px; }\n.tcw-level-add { justify-self: start; }\n.tcw-drawing-templates { display: grid; gap: 2px; margin-bottom: 8px; }\n.tcw-drawing-alert { display: inline-flex; align-items: center; gap: 6px; }\n\n/* --- Context menu (right-click on a drawing) --- */\n.tcw-context-menu {\n position: absolute;\n z-index: 70;\n min-width: 200px;\n padding: 4px;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-divider);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n}\n.tcw-context-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n min-height: var(--tcw-menu-item-h);\n padding: 4px 10px;\n border: 0;\n border-radius: var(--tcw-radius-sm);\n background: transparent;\n color: var(--tcw-text);\n font: inherit;\n font-size: var(--tcw-font-size);\n text-align: start;\n cursor: pointer;\n}\n.tcw-context-item svg, .tcw-context-icon { flex: none; width: 14px; height: 14px; color: var(--tcw-text-muted); }\n.tcw-context-item:hover, .tcw-context-item:focus-visible { background: var(--tcw-bg-surface); outline: none; }\n.tcw-context-item:focus-visible { box-shadow: inset 0 0 0 1px var(--tcw-accent); }\n.tcw-context-danger, .tcw-context-danger svg { color: var(--tcw-red); }\n.tcw-context-sep { height: 1px; margin: 4px 6px; background: var(--tcw-divider); }\n/* --- Toolbar over a selected drawing --- */\n.tcw-sel-toolbar {\n position: absolute;\n z-index: 65;\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 3px;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-divider);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n font-family: var(--tcw-font);\n white-space: nowrap;\n animation: tcw-sel-in var(--tcw-dur-fast) var(--tcw-ease-out);\n}\n@keyframes tcw-sel-in { from { opacity: 0; transform: translateY(3px); } }\n.tcw-sel-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 5px;\n min-width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n padding: 0 6px;\n border: 0;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n font: inherit;\n font-size: var(--tcw-font-size-xs);\n font-variant-numeric: tabular-nums;\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-sel-btn svg { flex: none; }\n.tcw-sel-btn:hover, .tcw-sel-btn[aria-expanded=\"true\"] { background: var(--tcw-hover-bg); color: var(--tcw-text); }\n.tcw-sel-btn:focus-visible, .tcw-sel-swatch:focus-visible, .tcw-sel-option:focus-visible { outline: none; box-shadow: inset 0 0 0 1px var(--tcw-accent); }\n.tcw-sel-btn.tcw-sel-on { color: var(--tcw-accent); background: var(--tcw-accent-soft); }\n.tcw-sel-danger:hover { color: var(--tcw-red); background: var(--tcw-red-soft); }\n.tcw-sel-color {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tcw-text) 25%, transparent);\n}\n.tcw-sel-width {\n display: inline-block;\n width: 16px;\n height: var(--w, 1px);\n max-height: 6px;\n border-radius: 1px;\n background: currentColor;\n}\n.tcw-sel-sep { flex: none; width: 1px; height: 18px; margin: 0 3px; background: var(--tcw-divider); }\n.tcw-sel-pop {\n position: absolute;\n z-index: 66;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 120px;\n padding: 4px;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-divider);\n border-radius: var(--tcw-menu-radius);\n box-shadow: var(--tcw-menu-shadow);\n font-family: var(--tcw-font);\n}\n.tcw-sel-pop--color {\n display: grid;\n grid-template-columns: repeat(4, 24px);\n gap: 6px;\n min-width: 0;\n padding: 8px;\n}\n.tcw-sel-swatch {\n width: 24px;\n height: 24px;\n padding: 0;\n border: 0;\n border-radius: 50%;\n box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tcw-text) 20%, transparent);\n cursor: pointer;\n transition: transform var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-sel-swatch:hover { transform: scale(1.1); }\n.tcw-sel-swatch.tcw-sel-on { box-shadow: 0 0 0 2px var(--tcw-bg-elevated), 0 0 0 4px var(--tcw-accent); }\n.tcw-sel-option {\n display: flex;\n align-items: center;\n gap: 10px;\n min-height: var(--tcw-menu-item-h);\n padding: 4px 10px;\n border: 0;\n border-radius: var(--tcw-radius-sm);\n background: transparent;\n color: var(--tcw-text);\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n text-align: start;\n cursor: pointer;\n}\n.tcw-sel-option:hover { background: var(--tcw-bg-surface); }\n.tcw-sel-option.tcw-sel-on { color: var(--tcw-accent); }\n@media (prefers-reduced-motion: reduce) {\n .tcw-sel-toolbar { animation: none; }\n .tcw-sel-swatch { transition: none; }\n}\n\n/* --- Account panel (positions, orders, history) --- */\n.tcw-account-dock {\n flex: none;\n}\n.tcw-account {\n display: flex;\n flex-direction: column;\n height: 220px;\n border-top: 1px solid var(--tcw-border);\n background: var(--tcw-bg-surface);\n}\n.tcw-account-head {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px;\n border-bottom: 1px solid var(--tcw-divider);\n}\n.tcw-account-tabs {\n display: flex;\n gap: 2px;\n flex: 1;\n min-width: 0;\n overflow-x: auto;\n}\n.tcw-account-tab {\n padding: 6px 10px;\n border: 0;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n white-space: nowrap;\n cursor: pointer;\n}\n.tcw-account-tab:hover { color: var(--tcw-text); background: var(--tcw-hover-bg); }\n.tcw-account-tab[aria-selected=\"true\"] { color: var(--tcw-text); background: var(--tcw-active-bg); }\n.tcw-account-tab:focus-visible, .tcw-account-new:focus-visible { outline: none; box-shadow: inset 0 0 0 1px var(--tcw-accent); }\n.tcw-account-new {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 1px solid var(--tcw-accent-line);\n border-radius: var(--tcw-control-radius);\n background: var(--tcw-accent-soft);\n color: var(--tcw-accent);\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n cursor: pointer;\n}\n.tcw-account-new:hover { background: var(--tcw-accent-glow); }\n.tcw-account-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n}\n.tcw-account-table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--tcw-font-size-sm);\n font-variant-numeric: tabular-nums;\n}\n.tcw-account-table th {\n position: sticky;\n top: 0;\n padding: 6px 10px;\n background: var(--tcw-bg-surface);\n color: var(--tcw-text-muted);\n font-weight: var(--tcw-weight);\n text-align: start;\n border-bottom: 1px solid var(--tcw-divider);\n}\n.tcw-account-table td {\n padding: 5px 10px;\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-divider);\n white-space: nowrap;\n}\n.tcw-account-table tr:hover td { background: var(--tcw-hover-bg); }\n.tcw-account-side { font-weight: var(--tcw-weight-strong); }\n.tcw-account-buy, .tcw-account-up { color: var(--tcw-green); }\n.tcw-account-sell, .tcw-account-down { color: var(--tcw-red); }\n.tcw-account-actions { display: flex; gap: 2px; }\n.tcw-account-empty, .tcw-account-summary {\n margin: 0;\n padding: 14px 12px;\n color: var(--tcw-text-muted);\n font-size: var(--tcw-font-size-sm);\n}\n.tcw-account-summary { padding: 8px 12px; color: var(--tcw-text-dim); }\n@media (max-width: 640px) {\n .tcw-account { height: 45vh; height: 45dvh; }\n}\n\n/* --- Order ticket --- */\n.tcw-ticket-side {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 6px;\n margin-bottom: 12px;\n}\n.tcw-ticket-side-btn {\n padding: 8px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n font: inherit;\n font-weight: var(--tcw-weight-strong);\n cursor: pointer;\n}\n.tcw-ticket-buy[aria-pressed=\"true\"] { background: var(--tcw-green-soft); border-color: var(--tcw-green); color: var(--tcw-green); }\n.tcw-ticket-sell[aria-pressed=\"true\"] { background: var(--tcw-red-soft); border-color: var(--tcw-red); color: var(--tcw-red); }\n.tcw-ticket-side-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--tcw-accent-soft); }\n.tcw-ticket-optional { display: flex; align-items: center; gap: 8px; }\n.tcw-ticket-optional > span { flex: 1; }\n.tcw-ticket-optional .tcw-indi-input { width: 110px; }\n.tcw-ticket-problems {\n min-height: 18px;\n padding: 0 22px 8px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n}\n.tcw-ticket-problems p { margin: 2px 0; }\n.tcw-ticket-problems.tcw-ticket-bad { color: var(--tcw-red); }\n.tcw-done-btn.tcw-ticket-sell { background: var(--tcw-red); color: #fff; }\n.tcw-done-btn:disabled { opacity: 0.45; cursor: not-allowed; }\n\n/* --- Named layouts --- */\n.tcw-layouts-btn { max-width: 190px; }\n.tcw-layouts-label {\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n.tcw-layouts-dirty {\n width: 6px;\n height: 6px;\n flex: none;\n border-radius: 50%;\n background: var(--tcw-accent);\n}\n.tcw-name-field { display: flex; flex-direction: column; gap: 6px; font-size: var(--tcw-font-size-sm); color: var(--tcw-text-dim); }\n.tcw-name-field .tcw-indi-input { width: 100%; height: 34px; font-size: var(--tcw-font-size); }\n.tcw-layouts-body { display: flex; flex-direction: column; gap: 10px; }\n.tcw-layouts-search { width: 100%; height: 32px; }\n.tcw-layouts-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n max-height: 50vh;\n max-height: 50dvh;\n overflow-y: auto;\n}\n.tcw-layouts-row {\n display: flex;\n align-items: center;\n gap: 6px;\n border-radius: var(--tcw-radius);\n}\n.tcw-layouts-row:hover { background: var(--tcw-hover-bg); }\n.tcw-layouts-open {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n padding: 7px 8px;\n border: none;\n background: transparent;\n color: var(--tcw-text);\n font: inherit;\n text-align: start;\n cursor: pointer;\n border-radius: var(--tcw-radius);\n}\n.tcw-layouts-open:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--tcw-accent-soft); }\n.tcw-layouts-name {\n display: flex;\n align-items: center;\n gap: 6px;\n max-width: 100%;\n font-size: var(--tcw-font-size);\n font-weight: var(--tcw-weight-strong);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.tcw-layouts-open[aria-current=\"true\"] .tcw-layouts-name { color: var(--tcw-accent); }\n.tcw-layouts-meta {\n max-width: 100%;\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n font-variant-numeric: tabular-nums;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.tcw-layouts-confirm {\n padding: 4px 10px;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: var(--tcw-red);\n color: #fff;\n font: inherit;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n cursor: pointer;\n}\n.tcw-layouts-confirm:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--tcw-red-soft); }\n\n/* --- Chart grid --- */\n.tcw-grid { background: var(--tcw-bg); }\n.tcw-grid-bar {\n display: flex;\n align-items: center;\n gap: 6px;\n min-height: calc(var(--tcw-control-h) + 8px);\n padding: 0 8px;\n border-bottom: 1px solid var(--tcw-border);\n background: var(--tcw-bg-surface);\n overflow-x: auto;\n scrollbar-width: none;\n}\n.tcw-grid-bar::-webkit-scrollbar { display: none; }\n.tcw-grid-group { display: flex; align-items: center; gap: 2px; flex: none; }\n.tcw-grid-label {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n margin-right: 4px;\n font-size: var(--tcw-font-size-xs);\n font-weight: var(--tcw-weight-strong);\n letter-spacing: var(--tcw-label-tracking);\n text-transform: var(--tcw-label-case);\n color: var(--tcw-text-muted);\n}\n.tcw-grid-sync[aria-pressed=\"true\"] { color: var(--tcw-accent); }\n.tcw-grid-cells {\n flex: 1;\n min-height: 0;\n display: grid;\n gap: 1px;\n background: var(--tcw-border);\n}\n.tcw-grid-cell {\n position: relative;\n min-width: 0;\n min-height: 0;\n background: var(--tcw-bg);\n}\n.tcw-grid-cell-active::after {\n content: '';\n position: absolute;\n inset: 0;\n border: 1px solid var(--tcw-accent);\n pointer-events: none;\n z-index: 5;\n}\n\n/* --- Host toolbar buttons --- */\n.tcw-toolbar-host { display: inline-flex; align-items: center; gap: 2px; }\n.tcw-toolbar-host:empty { display: none; }\n.tcw-host-btn { display: inline-flex; align-items: center; gap: 4px; }\n\n/* --- Host sidebar buttons, status bar items, and the layer over the chart --- */\n.tcw-sidebar-host { display: flex; flex-direction: column; align-items: center; }\n.tcw-sidebar-host:empty { display: none; }\n.tcw-status-host { display: flex; align-items: center; gap: 10px; min-width: 0; }\n.tcw-status-host:empty { display: none; }\n.tcw-status-host-item { white-space: nowrap; }\n.tcw-status-host-btn {\n margin: -4px -6px;\n padding: 4px 6px;\n font: inherit;\n color: inherit;\n background: transparent;\n border: none;\n border-radius: var(--tcw-control-radius);\n cursor: pointer;\n transition: color var(--tcw-dur-fast) var(--tcw-ease), background var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-status-host-btn:hover { color: var(--tcw-text); background: var(--tcw-hover-bg); }\n.tcw-status-host-btn:focus-visible { outline: 2px solid var(--tcw-accent); outline-offset: -2px; }\n/* Over the plot and under the widget's own overlays; the pointer reaches the chart unless an element of yours takes it. */\n.tcw-host-layer { position: absolute; inset: 0; z-index: 2; pointer-events: none; }\n\n/* --- Pane buttons (move, fold, maximise) --- */\n.tcw-pane-controls {\n position: absolute;\n z-index: 4;\n display: flex;\n gap: 1px;\n transform: translateX(-100%);\n padding: 1px;\n border-radius: var(--tcw-radius-sm);\n background: color-mix(in srgb, var(--tcw-bg) 80%, transparent);\n opacity: 0.55;\n transition: opacity var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-pane-controls:hover,\n.tcw-pane-controls:focus-within { opacity: 1; }\n.tcw-pane-btn {\n display: inline-grid;\n place-items: center;\n width: 18px;\n height: 16px;\n padding: 0;\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n}\n.tcw-pane-btn:hover { color: var(--tcw-text); background: var(--tcw-hover-bg); }\n.tcw-pane-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--tcw-accent-soft); }\n\n/* --- Typed interval --- */\n.tcw-interval-input {\n position: absolute;\n z-index: 20;\n left: 50%;\n top: 40%;\n transform: translate(-50%, -50%);\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 12px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-lg, 10px);\n background: var(--tcw-bg-elevated);\n box-shadow: var(--tcw-menu-shadow);\n}\n.tcw-interval-field {\n width: 150px;\n height: 36px;\n padding: 0 10px;\n font: inherit;\n font-size: calc(var(--tcw-font-size) + 5px);\n font-weight: var(--tcw-weight-strong);\n font-variant-numeric: tabular-nums;\n color: var(--tcw-text);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-accent);\n border-radius: var(--tcw-input-radius);\n outline: none;\n}\n.tcw-interval-field[aria-invalid] { border-color: var(--tcw-red); }\n.tcw-interval-hint { font-size: var(--tcw-font-size-xs); color: var(--tcw-text-muted); max-width: 170px; }\n\n/* --- Alerts: lines, moves, bar close, expiry --- */\n.tcw-alerts-source { grid-column: auto; }\n.tcw-alerts-row-fields {\n grid-column: 1 / -1;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n}\n.tcw-alerts-row-fields[hidden] { display: none; }\n.tcw-alerts-row-fields > input[hidden] { display: none; }\n.tcw-alerts-row-fields:has(> input[hidden]) { grid-template-columns: 1fr; }\n.tcw-alerts-options { align-items: center; }\n.tcw-alerts-form .tcw-alerts-check {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n}\n.tcw-alerts-form .tcw-alerts-check input { width: auto; height: auto; }\n.tcw-alerts-form input[aria-invalid=\"true\"] { border-color: var(--tcw-red); }\n.tcw-alerts-row-meta { margin-top: 2px; font-size: var(--tcw-font-size-xs); color: var(--tcw-text-muted); }\n.tcw-alerts-expired { opacity: 0.6; }\n\n/* --- Signal marker note --- */\n.tcw-marker-tip {\n position: absolute;\n z-index: 12;\n pointer-events: none;\n padding: 6px 8px;\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-tooltip-radius);\n background: var(--tcw-tooltip-bg);\n color: var(--tcw-tooltip-fg);\n font-size: var(--tcw-font-size-xs);\n line-height: 1.45;\n font-variant-numeric: tabular-nums;\n box-shadow: var(--tcw-menu-shadow);\n max-width: 240px;\n}\n.tcw-marker-tip strong { display: block; font-size: var(--tcw-font-size-sm); }\n\n/* === Navigation over the chart ===\n * Centred on the plot's bottom edge, shown while a mouse is over the chart. */\n.tcw-nav {\n position: absolute;\n z-index: 15;\n display: flex;\n gap: 2px;\n padding: 3px;\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: calc(var(--tcw-control-radius) + 3px);\n background: var(--tcw-bg-elevated);\n box-shadow: var(--tcw-menu-shadow);\n opacity: 0;\n pointer-events: none;\n transform: translate(-50%, calc(-100% - 12px));\n transition: opacity var(--tcw-dur-fast) var(--tcw-ease);\n}\n.tcw-nav.tcw-nav-shown {\n opacity: 1;\n pointer-events: auto;\n}\n.tcw-nav-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h);\n height: var(--tcw-control-h);\n border: 0;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-dim);\n cursor: pointer;\n touch-action: none;\n}\n.tcw-nav-btn:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n.tcw-nav-btn:active {\n background: var(--tcw-active-bg);\n}\n.tcw-nav-btn:focus-visible {\n outline: none;\n box-shadow: var(--tcw-ring);\n}\n.tcw-nav-btn svg {\n width: var(--tcw-icon);\n height: var(--tcw-icon);\n}\n@media (hover: none) {\n .tcw-nav { display: none; }\n}\n\n/* === Symbol info ===\n * Top left, beside the drawing tools: the panels on the right stay clear. */\n.tcw-syminfo {\n position: absolute;\n top: var(--tcw-panel-top);\n inset-inline-start: var(--tcw-panel-left);\n z-index: 38;\n width: 288px;\n max-height: calc(100% - var(--tcw-panel-top) - 12px);\n display: flex;\n flex-direction: column;\n background: var(--tcw-bg-elevated);\n border: var(--tcw-border-w) solid var(--tcw-border-strong);\n border-radius: var(--tcw-panel-radius);\n box-shadow: var(--tcw-menu-shadow);\n overflow: hidden;\n animation: tcw-alerts-in var(--tcw-dur, 160ms) var(--tcw-ease, ease) both;\n}\n.tcw-syminfo-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 9px 12px;\n font-size: var(--tcw-font-size-sm);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n border-bottom: 1px solid var(--tcw-border);\n}\n.tcw-syminfo-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--tcw-control-h-sm);\n height: var(--tcw-control-h-sm);\n border: none;\n border-radius: var(--tcw-control-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n}\n.tcw-syminfo-close:hover { background: var(--tcw-bg-surface); color: var(--tcw-text); }\n.tcw-syminfo-body,\n.tcw-syminfo-news {\n padding: 12px 14px;\n overflow-y: auto;\n}\n.tcw-syminfo-body {\n display: grid;\n gap: 10px;\n}\n.tcw-syminfo-symbol {\n font-size: var(--tcw-font-size-lg);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n}\n.tcw-syminfo-desc {\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n}\n.tcw-syminfo-meta {\n margin-top: 2px;\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n}\n.tcw-syminfo-quote {\n display: flex;\n align-items: baseline;\n gap: 10px;\n font-family: var(--tcw-font-mono);\n font-variant-numeric: tabular-nums;\n}\n.tcw-syminfo-price {\n font-size: calc(var(--tcw-font-size) + 7px);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text);\n}\n.tcw-syminfo-change { font-size: var(--tcw-font-size-sm); }\n.tcw-syminfo-change.tcw-up { color: var(--tcw-green); }\n.tcw-syminfo-change.tcw-down { color: var(--tcw-red); }\n.tcw-syminfo-status {\n display: flex;\n align-items: center;\n gap: 7px;\n font-size: var(--tcw-font-size-sm);\n color: var(--tcw-text-dim);\n}\n.tcw-syminfo-status::before,\n.tcw-status-market::before {\n content: '';\n flex: none;\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n}\n.tcw-syminfo-status[data-state='open']::before,\n.tcw-syminfo-status[data-state='always']::before,\n.tcw-status-market[data-state='open']::before {\n background: var(--tcw-green);\n}\n.tcw-syminfo-stats {\n display: grid;\n gap: 4px;\n margin: 0;\n padding-top: 10px;\n border-top: 1px solid var(--tcw-divider);\n}\n.tcw-syminfo-stat {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n font-size: var(--tcw-font-size-sm);\n}\n.tcw-syminfo-stat dt { color: var(--tcw-text-muted); }\n.tcw-syminfo-stat dd {\n margin: 0;\n color: var(--tcw-text);\n text-align: end;\n font-variant-numeric: tabular-nums;\n overflow-wrap: anywhere;\n}\n.tcw-syminfo-news {\n border-top: 1px solid var(--tcw-divider);\n}\n.tcw-syminfo-news-title {\n margin-bottom: 8px;\n font-size: var(--tcw-font-size-xs);\n font-weight: var(--tcw-weight-strong);\n color: var(--tcw-text-muted);\n text-transform: var(--tcw-label-case);\n letter-spacing: var(--tcw-label-tracking);\n}\n.tcw-syminfo-news-list {\n display: grid;\n gap: 10px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.tcw-syminfo-news-item {\n font-size: var(--tcw-font-size-sm);\n line-height: 1.4;\n color: var(--tcw-text);\n}\n.tcw-syminfo-news-item a {\n color: var(--tcw-text);\n text-decoration: none;\n}\n.tcw-syminfo-news-item a:hover { color: var(--tcw-accent); text-decoration: underline; }\n.tcw-syminfo-news-item a:focus-visible { outline: none; box-shadow: var(--tcw-ring); border-radius: var(--tcw-radius-xs); }\n.tcw-syminfo-news-meta,\n.tcw-syminfo-news-note {\n margin-top: 2px;\n font-size: var(--tcw-font-size-xs);\n color: var(--tcw-text-muted);\n}\n\n/* Numbers keep their sign on the left, and mixed text its own order, in a right-to-left widget too. */\n.tcw-watchlist-price,\n.tcw-watchlist-change,\n.tcw-syminfo-price,\n.tcw-syminfo-change {\n unicode-bidi: isolate;\n direction: ltr;\n}\n.tcw-syminfo-desc,\n.tcw-syminfo-meta,\n.tcw-syminfo-status,\n.tcw-syminfo-stat dd,\n.tcw-syminfo-news-meta {\n unicode-bidi: plaintext;\n}\n\n/* The market's status in the status bar. */\n.tcw-status-market {\n display: flex;\n align-items: center;\n gap: 7px;\n color: var(--tcw-text-muted);\n}\n\n@media (max-width: 640px) {\n .tcw-syminfo {\n top: auto;\n bottom: 0;\n left: 0;\n right: 0;\n width: 100vw;\n max-height: 70%;\n border-radius: var(--tcw-dialog-radius) var(--tcw-dialog-radius) 0 0;\n }\n}\n\n/* === The look: how chosen controls show, floating bars, segmented intervals ===\n * Each switch sets variables on its own root, which its parts read: a grid's\n * look never reaches into a chart that has one of its own. */\n\n/* A chosen button (`ui.active`): a tinted fill (default), a solid pill, or an underline.\n * Dialog tabs are chips, or underlined in the underline look. Panels sit below the\n * toolbar and beside the drawing tools. */\n.tcw-root {\n --tcw-on-bg: var(--tcw-accent-soft);\n --tcw-on-fg: var(--tcw-accent);\n --tcw-on-ring: none;\n --tcw-on-icon-bg: var(--tcw-accent-soft);\n --tcw-on-icon-fg: var(--tcw-accent);\n --tcw-on-icon-ring: none;\n --tcw-tabs-pad-block: 8px;\n --tcw-tab-h: var(--tcw-control-h);\n --tcw-tab-pad: 0 12px;\n --tcw-tab-line: 0px;\n --tcw-tab-radius: var(--tcw-control-radius);\n --tcw-tab-hover: var(--tcw-hover-bg);\n --tcw-tab-on-bg: var(--tcw-on-bg);\n --tcw-tab-on-fg: var(--tcw-on-fg);\n --tcw-panel-top: calc(var(--tcw-toolbar-h) + 6px);\n --tcw-panel-left: calc(var(--tcw-sidebar-w) + 12px);\n}\n.tcw-root[data-tcw-active='solid'] {\n --tcw-on-bg: var(--tcw-text);\n --tcw-on-fg: var(--tcw-bg);\n --tcw-on-icon-bg: var(--tcw-text);\n --tcw-on-icon-fg: var(--tcw-bg);\n}\n.tcw-root[data-tcw-active='underline'] {\n --tcw-on-bg: var(--tcw-active-bg);\n --tcw-on-fg: var(--tcw-text);\n --tcw-on-ring: inset 0 -2px 0 var(--tcw-accent);\n --tcw-on-icon-bg: var(--tcw-active-bg);\n --tcw-on-icon-fg: var(--tcw-accent);\n --tcw-on-icon-ring: inset 2px 0 0 var(--tcw-accent);\n --tcw-tabs-pad-block: 0px;\n --tcw-tab-h: auto;\n --tcw-tab-pad: 11px 14px;\n --tcw-tab-line: 2px;\n --tcw-tab-radius: 0px;\n --tcw-tab-hover: transparent;\n --tcw-tab-on-bg: transparent;\n --tcw-tab-on-fg: var(--tcw-accent);\n}\n.tcw-root[data-tcw-toolbar='floating'] {\n --tcw-panel-top: calc(var(--tcw-toolbar-h) + 2 * var(--tcw-border-w) + 14px);\n}\n.tcw-root[data-tcw-sidebar='floating'] {\n --tcw-panel-left: calc(var(--tcw-sidebar-w) + 2 * var(--tcw-border-w) + 22px);\n}\n\n/* The toolbar as an island (`ui.toolbar: 'floating'`). */\n.tcw-root[data-tcw-toolbar='floating'] > .tcw-toolbar {\n margin: 8px 10px 0;\n padding-inline: calc(min(var(--tcw-toolbar-radius), var(--tcw-toolbar-h) / 2) / 2 + 8px);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-toolbar-radius);\n background: var(--tcw-bg-elevated);\n box-shadow: var(--tcw-menu-shadow);\n}\n\n/* The drawing tools as an island (`ui.sidebar: 'floating'`). */\n.tcw-root[data-tcw-sidebar='floating'] > .tcw-body > .tcw-sidebar {\n align-self: flex-start;\n max-height: calc(100% - 20px);\n margin: 10px 6px 10px 10px;\n padding-block: calc(min(var(--tcw-sidebar-radius), var(--tcw-sidebar-w) / 2) / 2 + 6px);\n border: var(--tcw-border-w) solid var(--tcw-border);\n border-radius: var(--tcw-sidebar-radius);\n background: var(--tcw-bg-elevated);\n box-shadow: var(--tcw-menu-shadow);\n}\n\n/* Frosted menus (`ui.blur` above 0): the chart shows through, blurred. */\n@supports (background: color-mix(in srgb, red 50%, transparent)) {\n .tcw-dropdown,\n .tcw-flyout,\n .tcw-context-menu {\n background: color-mix(in srgb, var(--tcw-bg-elevated) var(--tcw-surface-opacity), transparent);\n }\n}\n\n/* The interval buttons in one track (`ui.intervals: 'segmented'`). */\n.tcw-root[data-tcw-intervals='segmented'] > .tcw-toolbar > .tcw-tf-group {\n gap: 2px;\n margin: 0 4px;\n padding: 3px;\n border-radius: calc(var(--tcw-control-radius) + 3px);\n background: var(--tcw-hover-bg);\n}\n.tcw-root[data-tcw-intervals='segmented'] > .tcw-toolbar > .tcw-tf-group .tcw-btn {\n height: calc(var(--tcw-control-h) - 6px);\n padding: 0 9px;\n}\n\n/* Phones: the variants keep comfortable tap targets and room for the bar. */\n@media (max-width: 768px) {\n .tcw-root[data-tcw-intervals='segmented'] > .tcw-toolbar > .tcw-tf-group .tcw-btn {\n height: max(34px, calc(var(--tcw-control-h) - 6px));\n padding: 0 10px;\n }\n .tcw-root[data-tcw-toolbar='floating'] > .tcw-toolbar {\n margin: 6px 6px 0;\n padding-inline: 4px;\n }\n .tcw-root[data-tcw-sidebar='floating'] > .tcw-body > .tcw-sidebar {\n margin: 6px 4px 6px 6px;\n }\n}\n\n/* --- Phones and tablets --- */\n\n/* Taps without the grey flash or the double-tap zoom's wait. The chart area\n sets its own touch-action for its gestures. */\n.tcw-root {\n -webkit-tap-highlight-color: transparent;\n touch-action: manipulation;\n}\n\n/* iOS zooms the page into an input under 16 px when it takes focus. */\n@media (pointer: coarse) {\n .tcw-root input:not([type='color']):not([type='range']):not([type='checkbox']):not([type='radio']),\n .tcw-root select,\n .tcw-root textarea {\n font-size: max(16px, 1em);\n }\n}\n\n/* Sheets and lists scroll on their own, without dragging the page behind them. */\n.tcw-modal,\n.tcw-cmd-palette,\n.tcw-cmd-list {\n overscroll-behavior: contain;\n}\n", O = /* @__PURE__ */ "toolbar,sidebar,statusBar,alerts,objectTree,symbolInfo,symbolSearch,settings,indicatorSettings,drawingSettings,dataWindow,commandPalette,hotkeySheet,goToDate,replay,screenshot,copyImage,shareView,autoFib,themeToggle,fullscreen,accountPanel,orderTicket,bracketOrders,depthLadder,layouts,indicatorTemplates,compare,indicatorLegend,navigation,customTimeframes,intervalTyping,dragDropImport,hotkeys,toasts,toolbar.symbol,toolbar.symbolInfo,toolbar.timeframes,toolbar.timeframeMenu,toolbar.chartType,toolbar.indicators,toolbar.layouts,toolbar.replay,toolbar.bracketOrders,toolbar.depthLadder,toolbar.accountPanel,toolbar.objectTree,toolbar.alerts,toolbar.screenshot,toolbar.settings,toolbar.themeToggle,toolbar.fullscreen,sidebar.cursor,sidebar.favorites,sidebar.lines,sidebar.fibonacci,sidebar.patterns,sidebar.forecasting,sidebar.annotation,sidebar.style,sidebar.magnet,sidebar.eraser,sidebar.zoomArea,sidebar.stayInDrawing,sidebar.undo,sidebar.redo,sidebar.clear,statusBar.range,statusBar.goToDate,statusBar.market,statusBar.connection,statusBar.symbol,statusBar.rangeTimeframe,indicatorLegend.values,indicatorLegend.visibility,indicatorLegend.settings,indicatorLegend.remove,indicatorLegend.more,pane.move,pane.collapse,pane.maximize,navigation.zoom,navigation.scroll,navigation.reset,menu.chart,menu.chart.alert,menu.chart.order,menu.chart.orderTicket,menu.chart.horizontalLine,menu.chart.resetView,menu.chart.drawings,menu.chart.exportData,menu.chart.settings,menu.chart.scale,menu.chart.goToDate,menu.chart.paneScale,menu.priceAxisAdd,menu.drawing,menu.drawing.settings,menu.drawing.alert,menu.drawing.order,menu.drawing.group,menu.drawing.lock,menu.drawing.hide,menu.drawing.duplicate,menu.drawing.delete,selectionToolbar,hotkeys.commandPalette,hotkeys.symbolSearch,hotkeys.save,hotkeys.tools,hotkeys.invertScale,hotkeys.goToDate,hotkeys.help".split(","), $e = new Set(O), et = {
|
|
1463
1463
|
toolbar: ["toolbar"],
|
|
1464
1464
|
drawingTools: [
|
|
1465
1465
|
"sidebar",
|
|
@@ -6946,9 +6946,28 @@ var Ri = class {
|
|
|
6946
6946
|
this.storage.setItem(this.storageKey, JSON.stringify(this.favorites));
|
|
6947
6947
|
} catch {}
|
|
6948
6948
|
}
|
|
6949
|
-
}
|
|
6950
|
-
|
|
6951
|
-
|
|
6949
|
+
};
|
|
6950
|
+
//#endregion
|
|
6951
|
+
//#region src/widget/keyboardInset.ts
|
|
6952
|
+
function zi(e) {
|
|
6953
|
+
let t = typeof window < "u" ? window.visualViewport : null;
|
|
6954
|
+
if (!t) return () => {};
|
|
6955
|
+
let n = -1, r = () => {
|
|
6956
|
+
let r = (t.scale ?? 1) > 1.01 ? 0 : Math.max(0, Math.round(window.innerHeight - t.height - t.offsetTop));
|
|
6957
|
+
if (r !== n) {
|
|
6958
|
+
n = r;
|
|
6959
|
+
for (let t of e) t.style.setProperty("--tcw-keyboard-inset", `${r}px`);
|
|
6960
|
+
}
|
|
6961
|
+
};
|
|
6962
|
+
return r(), t.addEventListener("resize", r), t.addEventListener("scroll", r), () => {
|
|
6963
|
+
t.removeEventListener("resize", r), t.removeEventListener("scroll", r);
|
|
6964
|
+
};
|
|
6965
|
+
}
|
|
6966
|
+
//#endregion
|
|
6967
|
+
//#region src/widget/WidgetGoToDate.ts
|
|
6968
|
+
var Bi = /^(\d{4})-(\d{2})-(\d{2})$/, Vi = /^(\d{2}):(\d{2})$/;
|
|
6969
|
+
function Hi(e, t, n) {
|
|
6970
|
+
let r = Bi.exec(e), i = t ? Vi.exec(t) : [
|
|
6952
6971
|
"",
|
|
6953
6972
|
"00",
|
|
6954
6973
|
"00"
|
|
@@ -6972,7 +6991,7 @@ function X(e, t) {
|
|
|
6972
6991
|
time: `${n(r.hours)}:${n(r.minutes)}`
|
|
6973
6992
|
};
|
|
6974
6993
|
}
|
|
6975
|
-
var
|
|
6994
|
+
var Ui = class {
|
|
6976
6995
|
form = null;
|
|
6977
6996
|
returnFocus = null;
|
|
6978
6997
|
opener = null;
|
|
@@ -7027,7 +7046,7 @@ var Hi = class {
|
|
|
7027
7046
|
let o = document.createElement("input");
|
|
7028
7047
|
return o.type = n, o.value = r, o.className = "tcw-goto-input", i.append(a, o), e.appendChild(i), o;
|
|
7029
7048
|
}
|
|
7030
|
-
}, Z = 8,
|
|
7049
|
+
}, Z = 8, Wi = 4, Gi = 3, Ki = "[title]:not([title=\"\"]), [data-tip]:not([data-tip=\"\"])", qi = class {
|
|
7031
7050
|
el;
|
|
7032
7051
|
target = null;
|
|
7033
7052
|
source = null;
|
|
@@ -7038,9 +7057,9 @@ var Hi = class {
|
|
|
7038
7057
|
observer;
|
|
7039
7058
|
constructor(e) {
|
|
7040
7059
|
this.root = e, this.el = document.createElement("div"), this.el.className = "tcw-tooltip", this.el.setAttribute("aria-hidden", "true"), e.appendChild(this.el), e.addEventListener("pointerover", this.onOver), e.addEventListener("pointerout", this.onOut), e.addEventListener("pointerdown", this.onPress, !0), e.addEventListener("keydown", this.onPress, !0), e.addEventListener("focusin", this.onFocus), e.addEventListener("focusout", this.onBlur), e.addEventListener("wheel", this.hide, { passive: !0 }), this.observer = new MutationObserver(() => {
|
|
7041
|
-
this.pressed?.hasAttribute("title") &&
|
|
7060
|
+
this.pressed?.hasAttribute("title") && Ji(this.pressed);
|
|
7042
7061
|
let e = this.target;
|
|
7043
|
-
!e || this.source !== "pointer" || !e.hasAttribute("title") || (
|
|
7062
|
+
!e || this.source !== "pointer" || !e.hasAttribute("title") || (Ji(e), this.isVisible() && this.show(e));
|
|
7044
7063
|
}), this.observer.observe(e, {
|
|
7045
7064
|
subtree: !0,
|
|
7046
7065
|
attributes: !0,
|
|
@@ -7048,24 +7067,24 @@ var Hi = class {
|
|
|
7048
7067
|
});
|
|
7049
7068
|
}
|
|
7050
7069
|
destroy() {
|
|
7051
|
-
this.hide(), this.pressed &&
|
|
7070
|
+
this.hide(), this.pressed && Yi(this.pressed), this.observer.disconnect(), this.root.removeEventListener("pointerover", this.onOver), this.root.removeEventListener("pointerout", this.onOut), this.root.removeEventListener("pointerdown", this.onPress, !0), this.root.removeEventListener("keydown", this.onPress, !0), this.root.removeEventListener("focusin", this.onFocus), this.root.removeEventListener("focusout", this.onBlur), this.root.removeEventListener("wheel", this.hide), this.el.remove();
|
|
7052
7071
|
}
|
|
7053
7072
|
onOver = (e) => {
|
|
7054
7073
|
if (e.pointerType === "touch") return;
|
|
7055
7074
|
let t = this.tipTarget(e.target);
|
|
7056
|
-
!t || t === this.pressed || t === this.target && this.source === "pointer" || (
|
|
7075
|
+
!t || t === this.pressed || t === this.target && this.source === "pointer" || (Ji(t), this.schedule(t, "pointer", Date.now() < this.warmUntil || this.isVisible()));
|
|
7057
7076
|
};
|
|
7058
7077
|
onOut = (e) => {
|
|
7059
7078
|
let t = e.relatedTarget, n = (e) => !!e && !!t && e.contains(t);
|
|
7060
|
-
this.pressed && !n(this.pressed) && (
|
|
7079
|
+
this.pressed && !n(this.pressed) && (Yi(this.pressed), this.pressed = null), this.source === "pointer" && !n(this.target) && this.hide();
|
|
7061
7080
|
};
|
|
7062
7081
|
onPress = () => {
|
|
7063
7082
|
let e = this.target, t = this.source === "pointer";
|
|
7064
|
-
this.warmUntil = 0, this.clearTimer(), cancelAnimationFrame(this.watchFrame), this.el.classList.remove("tcw-tooltip--visible"), this.target = null, this.source = null, this.pressed && this.pressed !== e &&
|
|
7083
|
+
this.warmUntil = 0, this.clearTimer(), cancelAnimationFrame(this.watchFrame), this.el.classList.remove("tcw-tooltip--visible"), this.target = null, this.source = null, this.pressed && this.pressed !== e && Yi(this.pressed), this.pressed = t ? e : null;
|
|
7065
7084
|
};
|
|
7066
7085
|
onFocus = (e) => {
|
|
7067
7086
|
let t = this.tipTarget(e.target);
|
|
7068
|
-
!t || !
|
|
7087
|
+
!t || !Qi(t) || t === this.pressed || this.schedule(t, "focus", !0);
|
|
7069
7088
|
};
|
|
7070
7089
|
onBlur = (e) => {
|
|
7071
7090
|
if (this.source !== "focus") return;
|
|
@@ -7073,16 +7092,16 @@ var Hi = class {
|
|
|
7073
7092
|
this.target && t && this.target.contains(t) || this.hide();
|
|
7074
7093
|
};
|
|
7075
7094
|
hide = () => {
|
|
7076
|
-
this.clearTimer(), cancelAnimationFrame(this.watchFrame), this.isVisible() && (this.warmUntil = Date.now() + 500), this.el.classList.remove("tcw-tooltip--visible"), this.target && this.source === "pointer" &&
|
|
7095
|
+
this.clearTimer(), cancelAnimationFrame(this.watchFrame), this.isVisible() && (this.warmUntil = Date.now() + 500), this.el.classList.remove("tcw-tooltip--visible"), this.target && this.source === "pointer" && Yi(this.target), this.target = null, this.source = null;
|
|
7077
7096
|
};
|
|
7078
7097
|
tipTarget(e) {
|
|
7079
7098
|
if (!(e instanceof Element)) return null;
|
|
7080
|
-
let t = e.closest(
|
|
7099
|
+
let t = e.closest(Ki);
|
|
7081
7100
|
return t && t !== this.el && this.root.contains(t) ? t : null;
|
|
7082
7101
|
}
|
|
7083
7102
|
schedule(e, t, n) {
|
|
7084
7103
|
let r = this.target;
|
|
7085
|
-
if (this.clearTimer(), cancelAnimationFrame(this.watchFrame), r && r !== e && this.source === "pointer" &&
|
|
7104
|
+
if (this.clearTimer(), cancelAnimationFrame(this.watchFrame), r && r !== e && this.source === "pointer" && Yi(r), this.target = e, this.source = t, n) {
|
|
7086
7105
|
this.show(e);
|
|
7087
7106
|
return;
|
|
7088
7107
|
}
|
|
@@ -7091,27 +7110,27 @@ var Hi = class {
|
|
|
7091
7110
|
}, 300);
|
|
7092
7111
|
}
|
|
7093
7112
|
show(e) {
|
|
7094
|
-
if (!
|
|
7113
|
+
if (!Zi(e)) {
|
|
7095
7114
|
this.hide();
|
|
7096
7115
|
return;
|
|
7097
7116
|
}
|
|
7098
|
-
this.el.textContent =
|
|
7117
|
+
this.el.textContent = Xi(e), this.place(e), this.el.classList.add("tcw-tooltip--visible"), this.watch(e);
|
|
7099
7118
|
}
|
|
7100
7119
|
watch(e) {
|
|
7101
7120
|
cancelAnimationFrame(this.watchFrame), this.watchFrame = requestAnimationFrame(() => {
|
|
7102
|
-
this.target === e && (
|
|
7121
|
+
this.target === e && (Zi(e) ? this.watch(e) : this.hide());
|
|
7103
7122
|
});
|
|
7104
7123
|
}
|
|
7105
7124
|
place(e) {
|
|
7106
|
-
let t = this.root.getBoundingClientRect(), n = e.getBoundingClientRect(), r = this.el.offsetWidth, i = this.el.offsetHeight, a = n.left - t.left, o = n.top - t.top, s =
|
|
7125
|
+
let t = this.root.getBoundingClientRect(), n = e.getBoundingClientRect(), r = this.el.offsetWidth, i = this.el.offsetHeight, a = n.left - t.left, o = n.top - t.top, s = $i(e);
|
|
7107
7126
|
s === "bottom" && o + n.height + Z + i > t.height ? s = "top" : s === "top" && o - Z - i < 0 ? s = "bottom" : s === "right" && a + n.width + Z + r > t.width && (s = "left");
|
|
7108
7127
|
let c, l;
|
|
7109
|
-
s === "top" || s === "bottom" ? (c = a + n.width / 2 - r / 2, l = s === "bottom" ? o + n.height + Z : o - Z - i) : (c = s === "right" ? a + n.width + Z : a - Z - r, l = o + n.height / 2 - i / 2), c = Math.max(
|
|
7128
|
+
s === "top" || s === "bottom" ? (c = a + n.width / 2 - r / 2, l = s === "bottom" ? o + n.height + Z : o - Z - i) : (c = s === "right" ? a + n.width + Z : a - Z - r, l = o + n.height / 2 - i / 2), c = Math.max(Wi, Math.min(t.width - r - Wi, c)), l = Math.max(Wi, Math.min(t.height - i - Wi, l)), this.el.style.left = `${Math.round(c)}px`, this.el.style.top = `${Math.round(l)}px`;
|
|
7110
7129
|
let u = {
|
|
7111
|
-
top: [0,
|
|
7112
|
-
bottom: [0, -
|
|
7113
|
-
left: [
|
|
7114
|
-
right: [-
|
|
7130
|
+
top: [0, Gi],
|
|
7131
|
+
bottom: [0, -Gi],
|
|
7132
|
+
left: [Gi, 0],
|
|
7133
|
+
right: [-Gi, 0]
|
|
7115
7134
|
}[s];
|
|
7116
7135
|
this.el.style.setProperty("--tcw-tip-dx", `${u[0]}px`), this.el.style.setProperty("--tcw-tip-dy", `${u[1]}px`), this.el.dataset.side = s;
|
|
7117
7136
|
}
|
|
@@ -7122,32 +7141,32 @@ var Hi = class {
|
|
|
7122
7141
|
this.showTimer !== null && (clearTimeout(this.showTimer), this.showTimer = null);
|
|
7123
7142
|
}
|
|
7124
7143
|
};
|
|
7125
|
-
function
|
|
7144
|
+
function Ji(e) {
|
|
7126
7145
|
let t = e.getAttribute("title");
|
|
7127
7146
|
t !== null && (e.dataset.tip = t, e.removeAttribute("title"));
|
|
7128
7147
|
}
|
|
7129
|
-
function
|
|
7148
|
+
function Yi(e) {
|
|
7130
7149
|
e.dataset.tip !== void 0 && !e.hasAttribute("title") && (e.setAttribute("title", e.dataset.tip), delete e.dataset.tip);
|
|
7131
7150
|
}
|
|
7132
|
-
function
|
|
7151
|
+
function Xi(e) {
|
|
7133
7152
|
return e.dataset.tip ?? e.getAttribute("title") ?? "";
|
|
7134
7153
|
}
|
|
7135
|
-
function
|
|
7154
|
+
function Zi(e) {
|
|
7136
7155
|
return e.isConnected && e.getClientRects().length > 0 && !e.disabled;
|
|
7137
7156
|
}
|
|
7138
|
-
function
|
|
7157
|
+
function Qi(e) {
|
|
7139
7158
|
try {
|
|
7140
7159
|
return e.matches(":focus-visible");
|
|
7141
7160
|
} catch {
|
|
7142
7161
|
return !1;
|
|
7143
7162
|
}
|
|
7144
7163
|
}
|
|
7145
|
-
function
|
|
7164
|
+
function $i(e) {
|
|
7146
7165
|
return e.dataset.tipSide || (e.closest(".tcw-sidebar") ? "right" : e.closest(".tcw-statusbar, .tcw-replay-bar") ? "top" : "bottom");
|
|
7147
7166
|
}
|
|
7148
7167
|
//#endregion
|
|
7149
7168
|
//#region src/widget/WidgetIndicatorLegend.ts
|
|
7150
|
-
var
|
|
7169
|
+
var ea = 2, ta = class {
|
|
7151
7170
|
stack;
|
|
7152
7171
|
toggle;
|
|
7153
7172
|
rows = /* @__PURE__ */ new Map();
|
|
@@ -7272,7 +7291,7 @@ var $i = 2, ea = class {
|
|
|
7272
7291
|
return this.stack.querySelectorAll(":scope > .tcw-ind-legend-row").length;
|
|
7273
7292
|
}
|
|
7274
7293
|
renderToggle(e) {
|
|
7275
|
-
let t = e >=
|
|
7294
|
+
let t = e >= ea;
|
|
7276
7295
|
!t && this.collapsed && this.setCollapsed(!1);
|
|
7277
7296
|
let n = `${t}|${this.collapsed}|${e}`;
|
|
7278
7297
|
if (n === this.toggleKey || (this.toggleKey = n, this.toggle.hidden = !t, !t)) return;
|
|
@@ -7287,7 +7306,7 @@ function Q(e, t, n) {
|
|
|
7287
7306
|
}
|
|
7288
7307
|
//#endregion
|
|
7289
7308
|
//#region src/widget/legendValues.ts
|
|
7290
|
-
function
|
|
7309
|
+
function na(e, t, n, r) {
|
|
7291
7310
|
if (!t) return [];
|
|
7292
7311
|
let i = e.plots;
|
|
7293
7312
|
if (!i) {
|
|
@@ -7317,20 +7336,20 @@ function ta(e, t, n, r) {
|
|
|
7317
7336
|
}
|
|
7318
7337
|
return o;
|
|
7319
7338
|
}
|
|
7320
|
-
var
|
|
7321
|
-
function
|
|
7322
|
-
let t =
|
|
7339
|
+
var ra = /* @__PURE__ */ new Map();
|
|
7340
|
+
function ia(e) {
|
|
7341
|
+
let t = ra.get(e);
|
|
7323
7342
|
return t || (t = new Intl.NumberFormat(e, {
|
|
7324
7343
|
notation: "compact",
|
|
7325
7344
|
maximumFractionDigits: 2
|
|
7326
|
-
}),
|
|
7345
|
+
}), ra.set(e, t)), t;
|
|
7327
7346
|
}
|
|
7328
|
-
function
|
|
7329
|
-
return Math.abs(e) >= 1e6 ?
|
|
7347
|
+
function aa(e, t = "en-US") {
|
|
7348
|
+
return Math.abs(e) >= 1e6 ? ia(t).format(e) : ie(e, Ee(e), t);
|
|
7330
7349
|
}
|
|
7331
7350
|
//#endregion
|
|
7332
7351
|
//#region src/widget/WidgetBracketBar.ts
|
|
7333
|
-
var
|
|
7352
|
+
var oa = class {
|
|
7334
7353
|
el;
|
|
7335
7354
|
labelEl;
|
|
7336
7355
|
callbacks;
|
|
@@ -7356,7 +7375,7 @@ var aa = class {
|
|
|
7356
7375
|
destroy() {
|
|
7357
7376
|
this.el.remove();
|
|
7358
7377
|
}
|
|
7359
|
-
},
|
|
7378
|
+
}, sa = class {
|
|
7360
7379
|
options;
|
|
7361
7380
|
audioCtx = null;
|
|
7362
7381
|
audioEl = null;
|
|
@@ -7419,7 +7438,7 @@ var aa = class {
|
|
|
7419
7438
|
};
|
|
7420
7439
|
//#endregion
|
|
7421
7440
|
//#region src/widget/ladderRows.ts
|
|
7422
|
-
function
|
|
7441
|
+
function ca(e, t = 12) {
|
|
7423
7442
|
let n = [...e.asks].sort((e, t) => e.price - t.price).slice(0, t), r = [...e.bids].sort((e, t) => t.price - e.price).slice(0, t), i = n.length > 0 ? n[0].price : null, a = r.length > 0 ? r[0].price : null, o = i !== null && a !== null ? (i + a) / 2 : null, s = /* @__PURE__ */ new Map(), c = (e) => {
|
|
7424
7443
|
let t = s.get(e);
|
|
7425
7444
|
return t || (t = {
|
|
@@ -7440,7 +7459,7 @@ function sa(e, t = 12) {
|
|
|
7440
7459
|
}
|
|
7441
7460
|
//#endregion
|
|
7442
7461
|
//#region src/widget/WidgetDepthLadder.ts
|
|
7443
|
-
var
|
|
7462
|
+
var la = class {
|
|
7444
7463
|
el;
|
|
7445
7464
|
bodyEl;
|
|
7446
7465
|
callbacks;
|
|
@@ -7478,7 +7497,7 @@ var ca = class {
|
|
|
7478
7497
|
this.renderEmpty();
|
|
7479
7498
|
return;
|
|
7480
7499
|
}
|
|
7481
|
-
this.render(
|
|
7500
|
+
this.render(ca(e, this.levels));
|
|
7482
7501
|
}
|
|
7483
7502
|
destroy() {
|
|
7484
7503
|
this.el.remove();
|
|
@@ -7498,20 +7517,20 @@ var ca = class {
|
|
|
7498
7517
|
let e = n.askVolume > 0, r = document.createElement("div");
|
|
7499
7518
|
r.className = "tcw-ladder-row";
|
|
7500
7519
|
let i = document.createElement("button");
|
|
7501
|
-
i.type = "button", i.className = "tcw-ladder-cell tcw-ladder-bid", n.bidVolume > 0 ? (i.textContent =
|
|
7520
|
+
i.type = "button", i.className = "tcw-ladder-cell tcw-ladder-bid", n.bidVolume > 0 ? (i.textContent = ua(n.bidVolume), i.style.setProperty("--w", `${(n.bidVolume * t * 100).toFixed(1)}%`), i.title = p(this.t("ladder.sellAt"), { price: this.callbacks.formatPrice(n.price) }), i.addEventListener("click", () => this.callbacks.onTrade("sell", n.price))) : i.disabled = !0;
|
|
7502
7521
|
let a = document.createElement("div");
|
|
7503
7522
|
a.className = `tcw-ladder-price ${e ? "tcw-ask" : "tcw-bid"}`, a.textContent = this.callbacks.formatPrice(n.price);
|
|
7504
7523
|
let o = document.createElement("button");
|
|
7505
|
-
o.type = "button", o.className = "tcw-ladder-cell tcw-ladder-ask", n.askVolume > 0 ? (o.textContent =
|
|
7524
|
+
o.type = "button", o.className = "tcw-ladder-cell tcw-ladder-ask", n.askVolume > 0 ? (o.textContent = ua(n.askVolume), o.style.setProperty("--w", `${(n.askVolume * t * 100).toFixed(1)}%`), o.title = p(this.t("ladder.buyAt"), { price: this.callbacks.formatPrice(n.price) }), o.addEventListener("click", () => this.callbacks.onTrade("buy", n.price))) : o.disabled = !0, r.appendChild(i), r.appendChild(a), r.appendChild(o), this.bodyEl.appendChild(r);
|
|
7506
7525
|
}
|
|
7507
7526
|
}
|
|
7508
7527
|
};
|
|
7509
|
-
function
|
|
7528
|
+
function ua(e) {
|
|
7510
7529
|
return e >= 1e3 ? (e / 1e3).toFixed(1) + "k" : e >= 1 ? e.toFixed(2).replace(/\.00$/, "") : e.toPrecision(2);
|
|
7511
7530
|
}
|
|
7512
7531
|
//#endregion
|
|
7513
7532
|
//#region src/widget/WidgetDataWindow.ts
|
|
7514
|
-
var
|
|
7533
|
+
var da = class {
|
|
7515
7534
|
el;
|
|
7516
7535
|
bodyEl;
|
|
7517
7536
|
callbacks;
|
|
@@ -7550,11 +7569,11 @@ var ua = class {
|
|
|
7550
7569
|
let t = this.callbacks.formatPrice, n = e.ohlc;
|
|
7551
7570
|
this.bodyEl.appendChild(this.row(this.t("dataWindow.open"), t(n.open))), this.bodyEl.appendChild(this.row(this.t("dataWindow.high"), t(n.high))), this.bodyEl.appendChild(this.row(this.t("dataWindow.low"), t(n.low))), this.bodyEl.appendChild(this.row(this.t("dataWindow.close"), t(n.close)));
|
|
7552
7571
|
let r = e.change > 0 ? "up" : e.change < 0 ? "down" : "", i = e.change > 0 ? "+" : "";
|
|
7553
|
-
this.bodyEl.appendChild(this.row(this.t("dataWindow.change"), `${i}${t(e.change)} (${i}${e.changePct.toFixed(2)}%)`, r)), this.bodyEl.appendChild(this.row(this.t("dataWindow.volume"),
|
|
7572
|
+
this.bodyEl.appendChild(this.row(this.t("dataWindow.change"), `${i}${t(e.change)} (${i}${e.changePct.toFixed(2)}%)`, r)), this.bodyEl.appendChild(this.row(this.t("dataWindow.volume"), pa(n.volume)));
|
|
7554
7573
|
for (let t of e.indicators) {
|
|
7555
7574
|
let e = document.createElement("div");
|
|
7556
7575
|
e.className = "tcw-datawin-sub", e.textContent = t.name, this.bodyEl.appendChild(e);
|
|
7557
|
-
for (let e of t.values) this.bodyEl.appendChild(this.row(e.key,
|
|
7576
|
+
for (let e of t.values) this.bodyEl.appendChild(this.row(e.key, fa(e.value)));
|
|
7558
7577
|
}
|
|
7559
7578
|
}
|
|
7560
7579
|
row(e, t, n = "") {
|
|
@@ -7566,43 +7585,43 @@ var ua = class {
|
|
|
7566
7585
|
return a.className = `tcw-datawin-value${n ? ` tcw-${n}` : ""}`, a.textContent = t, r.appendChild(i), r.appendChild(a), r;
|
|
7567
7586
|
}
|
|
7568
7587
|
};
|
|
7569
|
-
function
|
|
7588
|
+
function fa(e) {
|
|
7570
7589
|
if (!Number.isFinite(e)) return "—";
|
|
7571
7590
|
let t = Math.abs(e);
|
|
7572
7591
|
return t >= 1e3 ? e.toFixed(2) : t >= 1 ? e.toFixed(4) : e.toPrecision(4);
|
|
7573
7592
|
}
|
|
7574
|
-
function
|
|
7593
|
+
function pa(e) {
|
|
7575
7594
|
return e >= 1e9 ? (e / 1e9).toFixed(2) + "B" : e >= 1e6 ? (e / 1e6).toFixed(2) + "M" : e >= 1e3 ? (e / 1e3).toFixed(2) + "K" : e.toFixed(0);
|
|
7576
7595
|
}
|
|
7577
7596
|
//#endregion
|
|
7578
7597
|
//#region src/widget/widgetShareState.ts
|
|
7579
|
-
var
|
|
7580
|
-
function
|
|
7581
|
-
if (
|
|
7598
|
+
var ma = globalThis.Buffer;
|
|
7599
|
+
function ha(e) {
|
|
7600
|
+
if (ma) return ma.from(e, "utf8").toString("base64");
|
|
7582
7601
|
let t = new TextEncoder().encode(e), n = "";
|
|
7583
7602
|
for (let e of t) n += String.fromCharCode(e);
|
|
7584
7603
|
return btoa(n);
|
|
7585
7604
|
}
|
|
7586
|
-
function
|
|
7587
|
-
if (
|
|
7605
|
+
function ga(e) {
|
|
7606
|
+
if (ma) return ma.from(e, "base64").toString("utf8");
|
|
7588
7607
|
let t = atob(e), n = new Uint8Array(t.length);
|
|
7589
7608
|
for (let e = 0; e < t.length; e++) n[e] = t.charCodeAt(e);
|
|
7590
7609
|
return new TextDecoder().decode(n);
|
|
7591
7610
|
}
|
|
7592
|
-
function
|
|
7611
|
+
function _a(e) {
|
|
7593
7612
|
return e.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
7594
7613
|
}
|
|
7595
|
-
function
|
|
7614
|
+
function va(e) {
|
|
7596
7615
|
let t = e.replace(/-/g, "+").replace(/_/g, "/");
|
|
7597
7616
|
return t + (t.length % 4 == 0 ? "" : "=".repeat(4 - t.length % 4));
|
|
7598
7617
|
}
|
|
7599
|
-
function va(e) {
|
|
7600
|
-
return ga(ma(JSON.stringify(e)));
|
|
7601
|
-
}
|
|
7602
7618
|
function ya(e) {
|
|
7619
|
+
return _a(ha(JSON.stringify(e)));
|
|
7620
|
+
}
|
|
7621
|
+
function ba(e) {
|
|
7603
7622
|
if (!e) return null;
|
|
7604
7623
|
try {
|
|
7605
|
-
let t =
|
|
7624
|
+
let t = ga(va(e)), n = JSON.parse(t);
|
|
7606
7625
|
return !n || n.v !== 1 || typeof n.symbol != "string" ? null : {
|
|
7607
7626
|
v: 1,
|
|
7608
7627
|
symbol: n.symbol,
|
|
@@ -7616,20 +7635,20 @@ function ya(e) {
|
|
|
7616
7635
|
return null;
|
|
7617
7636
|
}
|
|
7618
7637
|
}
|
|
7619
|
-
var
|
|
7620
|
-
function
|
|
7638
|
+
var xa = "tcw";
|
|
7639
|
+
function Sa(e) {
|
|
7621
7640
|
let t = e.startsWith("#") ? e.slice(1) : e;
|
|
7622
7641
|
for (let e of t.split("&")) {
|
|
7623
7642
|
let t = e.indexOf("=");
|
|
7624
|
-
if (t > 0 && e.slice(0, t) ===
|
|
7643
|
+
if (t > 0 && e.slice(0, t) === xa) return decodeURIComponent(e.slice(t + 1));
|
|
7625
7644
|
}
|
|
7626
7645
|
return null;
|
|
7627
7646
|
}
|
|
7628
|
-
function
|
|
7647
|
+
function Ca(e, t) {
|
|
7629
7648
|
let [n] = e.split("#");
|
|
7630
|
-
return `${n}#${
|
|
7649
|
+
return `${n}#${xa}=${t}`;
|
|
7631
7650
|
}
|
|
7632
|
-
var
|
|
7651
|
+
var wa = [
|
|
7633
7652
|
[
|
|
7634
7653
|
34,
|
|
7635
7654
|
16,
|
|
@@ -7686,7 +7705,7 @@ var Ca = [
|
|
|
7686
7705
|
30,
|
|
7687
7706
|
!0
|
|
7688
7707
|
]
|
|
7689
|
-
],
|
|
7708
|
+
], Ta = class {
|
|
7690
7709
|
el;
|
|
7691
7710
|
label;
|
|
7692
7711
|
showTimer = null;
|
|
@@ -7696,7 +7715,7 @@ var Ca = [
|
|
|
7696
7715
|
let n = document.createElement("div");
|
|
7697
7716
|
n.className = "tcw-loading-card";
|
|
7698
7717
|
let r = document.createElement("div");
|
|
7699
|
-
r.className = "tcw-loading-candles", r.setAttribute("aria-hidden", "true"),
|
|
7718
|
+
r.className = "tcw-loading-candles", r.setAttribute("aria-hidden", "true"), wa.forEach(([e, t, n, i, a], o) => {
|
|
7700
7719
|
let s = document.createElement("span");
|
|
7701
7720
|
s.className = a ? "tcw-loading-candle tcw-loading-candle--up" : "tcw-loading-candle", s.style.setProperty("--tcw-body-top", `${e}px`), s.style.setProperty("--tcw-body-h", `${t}px`), s.style.setProperty("--tcw-wick-top", `${n}px`), s.style.setProperty("--tcw-wick-h", `${i}px`), s.style.setProperty("--tcw-delay", `${o * 110}ms`), r.appendChild(s);
|
|
7702
7721
|
}), n.appendChild(r);
|
|
@@ -7733,7 +7752,7 @@ var Ca = [
|
|
|
7733
7752
|
clearTimer() {
|
|
7734
7753
|
this.showTimer !== null && (clearTimeout(this.showTimer), this.showTimer = null);
|
|
7735
7754
|
}
|
|
7736
|
-
},
|
|
7755
|
+
}, Ea = 4e3, Da = class {
|
|
7737
7756
|
el;
|
|
7738
7757
|
text;
|
|
7739
7758
|
hideTimer = null;
|
|
@@ -7743,7 +7762,7 @@ var Ca = [
|
|
|
7743
7762
|
n.className = "tcw-history-spinner", n.setAttribute("aria-hidden", "true"), this.text = document.createElement("span"), this.el.append(n, this.text), e.appendChild(this.el);
|
|
7744
7763
|
}
|
|
7745
7764
|
update(e) {
|
|
7746
|
-
this.clearTimer(), e.state === "loading" ? this.show(this.texts.loading, !1) : e.state === "error" ? (this.show(this.texts.failed, !0), this.hideTimer = setTimeout(() => this.hide(),
|
|
7765
|
+
this.clearTimer(), e.state === "loading" ? this.show(this.texts.loading, !1) : e.state === "error" ? (this.show(this.texts.failed, !0), this.hideTimer = setTimeout(() => this.hide(), Ea)) : this.hide();
|
|
7747
7766
|
}
|
|
7748
7767
|
destroy() {
|
|
7749
7768
|
this.clearTimer(), this.el.remove();
|
|
@@ -7757,13 +7776,13 @@ var Ca = [
|
|
|
7757
7776
|
clearTimer() {
|
|
7758
7777
|
this.hideTimer !== null && clearTimeout(this.hideTimer), this.hideTimer = null;
|
|
7759
7778
|
}
|
|
7760
|
-
},
|
|
7761
|
-
function
|
|
7779
|
+
}, Oa = "host:";
|
|
7780
|
+
function ka(e, t) {
|
|
7762
7781
|
return [
|
|
7763
7782
|
...e,
|
|
7764
7783
|
...e.length > 0 && t.length > 0 ? ["separator"] : [],
|
|
7765
7784
|
...t.map((e, t) => ({
|
|
7766
|
-
id: `${
|
|
7785
|
+
id: `${Oa}${t}`,
|
|
7767
7786
|
label: e.label,
|
|
7768
7787
|
icon: e.icon,
|
|
7769
7788
|
danger: e.danger,
|
|
@@ -7771,12 +7790,12 @@ function Oa(e, t) {
|
|
|
7771
7790
|
}))
|
|
7772
7791
|
];
|
|
7773
7792
|
}
|
|
7774
|
-
function
|
|
7775
|
-
return e.startsWith(
|
|
7793
|
+
function Aa(e, t) {
|
|
7794
|
+
return e.startsWith(Oa) ? (t[Number(e.slice(5))]?.onSelect(), !0) : !1;
|
|
7776
7795
|
}
|
|
7777
7796
|
//#endregion
|
|
7778
7797
|
//#region src/widget/hostHotkeys.ts
|
|
7779
|
-
var
|
|
7798
|
+
var ja = typeof navigator < "u" && /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent), Ma = {
|
|
7780
7799
|
ctrl: "ctrl",
|
|
7781
7800
|
control: "ctrl",
|
|
7782
7801
|
cmd: "ctrl",
|
|
@@ -7787,7 +7806,7 @@ var Aa = typeof navigator < "u" && /mac|iphone|ipad|ipod/i.test(navigator.platfo
|
|
|
7787
7806
|
option: "alt",
|
|
7788
7807
|
opt: "alt",
|
|
7789
7808
|
shift: "shift"
|
|
7790
|
-
},
|
|
7809
|
+
}, Na = {
|
|
7791
7810
|
esc: "escape",
|
|
7792
7811
|
space: " ",
|
|
7793
7812
|
spacebar: " ",
|
|
@@ -7799,7 +7818,7 @@ var Aa = typeof navigator < "u" && /mac|iphone|ipad|ipod/i.test(navigator.platfo
|
|
|
7799
7818
|
return: "enter",
|
|
7800
7819
|
plus: "+"
|
|
7801
7820
|
};
|
|
7802
|
-
function
|
|
7821
|
+
function Pa(e) {
|
|
7803
7822
|
let t = e.split("+").map((e) => e.trim()), n = t.pop();
|
|
7804
7823
|
if (!n) return null;
|
|
7805
7824
|
let r = {
|
|
@@ -7809,23 +7828,23 @@ function Na(e) {
|
|
|
7809
7828
|
display: []
|
|
7810
7829
|
};
|
|
7811
7830
|
for (let e of t) {
|
|
7812
|
-
let t =
|
|
7831
|
+
let t = Ma[e.toLowerCase()];
|
|
7813
7832
|
if (!t) return null;
|
|
7814
7833
|
r[t] = !0;
|
|
7815
7834
|
}
|
|
7816
7835
|
let i = n.toLowerCase();
|
|
7817
|
-
if (
|
|
7836
|
+
if (Ma[i]) return null;
|
|
7818
7837
|
if (/^[a-z]$/.test(i)) r.code = `Key${i.toUpperCase()}`, r.char = i;
|
|
7819
7838
|
else if (/^[0-9]$/.test(i)) r.code = `Digit${i}`, r.char = i;
|
|
7820
|
-
else if (r.key =
|
|
7839
|
+
else if (r.key = Na[i] ?? i, r.shift && r.key.length === 1) return null;
|
|
7821
7840
|
return r.display = [
|
|
7822
|
-
...r.ctrl ? [
|
|
7841
|
+
...r.ctrl ? [ja ? "⌘" : "Ctrl"] : [],
|
|
7823
7842
|
...r.alt ? ["Alt"] : [],
|
|
7824
7843
|
...r.shift ? ["Shift"] : [],
|
|
7825
7844
|
r.key === " " ? "Space" : n.length === 1 ? n.toUpperCase() : n
|
|
7826
7845
|
], r;
|
|
7827
7846
|
}
|
|
7828
|
-
function
|
|
7847
|
+
function Fa(e, t) {
|
|
7829
7848
|
if ((e.ctrlKey || e.metaKey) !== t.ctrl || e.altKey !== t.alt) return !1;
|
|
7830
7849
|
if (t.code !== void 0) {
|
|
7831
7850
|
if (e.shiftKey !== t.shift) return !1;
|
|
@@ -7835,38 +7854,38 @@ function Pa(e, t) {
|
|
|
7835
7854
|
}
|
|
7836
7855
|
return t.shift && !e.shiftKey ? !1 : e.key.toLowerCase() === t.key;
|
|
7837
7856
|
}
|
|
7838
|
-
var
|
|
7839
|
-
function
|
|
7857
|
+
var Ia = new Set(/* @__PURE__ */ "escape(enter(delete(backspace(arrowleft(arrowright(arrowup(arrowdown(home(end(+(-(=( (,(.(ctrl+z(ctrl+shift+z(ctrl+y(ctrl+c(ctrl+v(ctrl+d(ctrl+g(ctrl+shift+g(ctrl+[(ctrl+]".split("("));
|
|
7858
|
+
function La(e) {
|
|
7840
7859
|
let t = `${e.ctrl ? "ctrl+" : ""}${e.alt ? "alt+" : ""}${e.shift ? "shift+" : ""}${e.char ?? e.key}`;
|
|
7841
|
-
return
|
|
7860
|
+
return Ia.has(t);
|
|
7842
7861
|
}
|
|
7843
|
-
function
|
|
7862
|
+
function Ra(e) {
|
|
7844
7863
|
let t = typeof e.composedPath == "function" ? e.composedPath()[0] : e.target;
|
|
7845
7864
|
return t instanceof HTMLElement ? t.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName) : !1;
|
|
7846
7865
|
}
|
|
7847
7866
|
//#endregion
|
|
7848
7867
|
//#region src/widget/ChartWidget.ts
|
|
7849
|
-
var
|
|
7850
|
-
function
|
|
7868
|
+
var za = 48, Ba = 5e4, Va = 100;
|
|
7869
|
+
function Ha() {
|
|
7851
7870
|
return new Promise((e) => {
|
|
7852
7871
|
if (typeof requestAnimationFrame != "function" || document.hidden) {
|
|
7853
7872
|
setTimeout(e, 0);
|
|
7854
7873
|
return;
|
|
7855
7874
|
}
|
|
7856
|
-
let t = setTimeout(e,
|
|
7875
|
+
let t = setTimeout(e, Va);
|
|
7857
7876
|
requestAnimationFrame(() => setTimeout(() => {
|
|
7858
7877
|
clearTimeout(t), e();
|
|
7859
7878
|
}, 0));
|
|
7860
7879
|
});
|
|
7861
7880
|
}
|
|
7862
|
-
var
|
|
7881
|
+
var Ua = [
|
|
7863
7882
|
"#4c8dff",
|
|
7864
7883
|
"#a57cff",
|
|
7865
7884
|
"#1398a8",
|
|
7866
7885
|
"#e25592",
|
|
7867
7886
|
"#8a93a3",
|
|
7868
7887
|
"#62c895"
|
|
7869
|
-
],
|
|
7888
|
+
], Wa = 4, Ga = 7, Ka = 17, qa = 3, Ja = [
|
|
7870
7889
|
"1m",
|
|
7871
7890
|
"3m",
|
|
7872
7891
|
"5m",
|
|
@@ -7876,17 +7895,17 @@ var Ha = [
|
|
|
7876
7895
|
"2h",
|
|
7877
7896
|
"4h",
|
|
7878
7897
|
"1d"
|
|
7879
|
-
],
|
|
7898
|
+
], Ya = 5e3, Xa = () => {
|
|
7880
7899
|
let e = document.activeElement;
|
|
7881
7900
|
return e instanceof Element && e.closest("[role=\"dialog\"], [aria-modal=\"true\"], [role=\"menu\"]") !== null;
|
|
7882
|
-
},
|
|
7901
|
+
}, Za = {
|
|
7883
7902
|
KeyT: "trendLine",
|
|
7884
7903
|
KeyH: "horizontalLine",
|
|
7885
7904
|
KeyJ: "horizontalRay",
|
|
7886
7905
|
KeyV: "verticalLine",
|
|
7887
7906
|
KeyC: "crossLine",
|
|
7888
7907
|
KeyF: "fibRetracement"
|
|
7889
|
-
},
|
|
7908
|
+
}, Qa = 229, $a = Ze.filter((e) => g[e] !== "color"), eo = () => typeof document < "u" && document.hidden, to = 200, no = class {
|
|
7890
7909
|
chart;
|
|
7891
7910
|
state;
|
|
7892
7911
|
themeOf = {
|
|
@@ -7902,6 +7921,7 @@ var Ha = [
|
|
|
7902
7921
|
indicatorLegend = null;
|
|
7903
7922
|
legendFrame = 0;
|
|
7904
7923
|
portal = document.createElement("div");
|
|
7924
|
+
stopKeyboardInset = null;
|
|
7905
7925
|
overlayHost = () => {
|
|
7906
7926
|
let e = document.fullscreenElement === this.root ? this.root : document.body;
|
|
7907
7927
|
return this.portal.parentElement !== e && e.appendChild(this.portal), this.portal;
|
|
@@ -7963,6 +7983,7 @@ var Ha = [
|
|
|
7963
7983
|
newsRequest = 0;
|
|
7964
7984
|
newsCache = /* @__PURE__ */ new Map();
|
|
7965
7985
|
marketTimer = null;
|
|
7986
|
+
onPageShown = null;
|
|
7966
7987
|
chartNav = null;
|
|
7967
7988
|
visibleBarCount = 50;
|
|
7968
7989
|
replayPollInterval = null;
|
|
@@ -8070,8 +8091,8 @@ var Ha = [
|
|
|
8070
8091
|
connectionState: t.adapter ? "connecting" : "disconnected",
|
|
8071
8092
|
connectionMessage: t.adapter ? this.t("status.connecting") : ""
|
|
8072
8093
|
}, ht(), this.root = document.createElement("div"), this.root.className = "tcw-root", this.root.dataset.tcwTheme = i ? "dark" : "light";
|
|
8073
|
-
let m = t.dir === "ltr" || t.dir === "rtl" ? t.dir :
|
|
8074
|
-
this.root.dir = m, this.portal.dir = m, e.appendChild(this.root), this.tooltip = new
|
|
8094
|
+
let m = t.dir === "ltr" || t.dir === "rtl" ? t.dir : mo(t.locale) ? "rtl" : "ltr";
|
|
8095
|
+
this.root.dir = m, this.portal.dir = m, e.appendChild(this.root), this.tooltip = new qi(this.root), this.portal.className = "tcw-root tcw-portal", this.portal.dataset.tcwTheme = this.root.dataset.tcwTheme, this.stopKeyboardInset = zi([this.root, this.portal]), this.ui = H(t.ui);
|
|
8075
8096
|
let h = t.ui !== void 0;
|
|
8076
8097
|
U(this.root, this.ui, { variables: h }), U(this.portal, this.ui, { variables: h }), this.markSwitchedOff(), this.toolbar = new Ot(this.root, {
|
|
8077
8098
|
symbols: this.symbols,
|
|
@@ -8127,7 +8148,7 @@ var Ha = [
|
|
|
8127
8148
|
},
|
|
8128
8149
|
onToggleStyle: () => this.drawingStyle?.toggle(),
|
|
8129
8150
|
onToggleStayInDrawing: () => this.handleToggleStayInDrawing()
|
|
8130
|
-
}, this.t), this.chartContainer = document.createElement("div"), this.chartContainer.className = "tcw-chart-container", this.chartContainer.dir = "ltr", g.appendChild(this.chartContainer), this.loading = new
|
|
8151
|
+
}, this.t), this.chartContainer = document.createElement("div"), this.chartContainer.className = "tcw-chart-container", this.chartContainer.dir = "ltr", g.appendChild(this.chartContainer), this.loading = new Ta(this.chartContainer, this.t("status.loading")), this.historyPill = new Da(this.chartContainer, {
|
|
8131
8152
|
loading: this.t("history.loading"),
|
|
8132
8153
|
failed: this.t("history.failed")
|
|
8133
8154
|
}), t.watchlist && this.createWatchlist(g, t.watchlist === !0 ? {} : t.watchlist), this.root.appendChild(g);
|
|
@@ -8167,7 +8188,9 @@ var Ha = [
|
|
|
8167
8188
|
this.toolbar?.setSymbolDescription(n || null), this.refreshMarket();
|
|
8168
8189
|
}), this.symbolInfoPanel = new Dn(this.root, this.t, { onToggle: (e) => {
|
|
8169
8190
|
this.toolbar?.setActive("symbolInfo", e), e && (this.refreshSymbolInfo(), this.loadNews());
|
|
8170
|
-
} }), this.marketTimer = setInterval(() => this.refreshMarket(), 3e4), this.
|
|
8191
|
+
} }), this.marketTimer = setInterval(() => this.refreshMarket(), 3e4), this.onPageShown = () => {
|
|
8192
|
+
eo() || this.refreshMarket();
|
|
8193
|
+
}, document.addEventListener("visibilitychange", this.onPageShown), this.dragDrop = new a(this.chartContainer, {
|
|
8171
8194
|
onData: (e, t, n) => {
|
|
8172
8195
|
this.setData(e);
|
|
8173
8196
|
let r = p(this.t("toast.fileLoaded"), {
|
|
@@ -8186,7 +8209,7 @@ var Ha = [
|
|
|
8186
8209
|
goToLabel: this.t("range.goTo"),
|
|
8187
8210
|
onPreset: (e) => void this.applyRangePreset(e),
|
|
8188
8211
|
onGoTo: () => this.toggleGoToDate()
|
|
8189
|
-
}), this.goToDate = new
|
|
8212
|
+
}), this.goToDate = new Ui(this.root, {
|
|
8190
8213
|
title: this.t("range.goTo"),
|
|
8191
8214
|
date: this.t("range.date"),
|
|
8192
8215
|
time: this.t("range.time"),
|
|
@@ -8221,7 +8244,7 @@ var Ha = [
|
|
|
8221
8244
|
eraser: t ?? this.state.eraser,
|
|
8222
8245
|
zoomArea: n ?? this.state.zoomArea
|
|
8223
8246
|
}, this.updateUI();
|
|
8224
|
-
}), this.chart.on("indicatorAdd", () => this.syncIndicatorsFromChart()), this.chart.on("indicatorRemove", () => this.syncIndicatorsFromChart()), this.chart.setPaneTitlesVisible(!this.featureState.indicatorLegend), this.indicatorLegend = new
|
|
8247
|
+
}), this.chart.on("indicatorAdd", () => this.syncIndicatorsFromChart()), this.chart.on("indicatorRemove", () => this.syncIndicatorsFromChart()), this.chart.setPaneTitlesVisible(!this.featureState.indicatorLegend), this.indicatorLegend = new ta(this.chartContainer, {
|
|
8225
8248
|
onToggleVisible: (e, t) => {
|
|
8226
8249
|
this.chart.setIndicatorVisible(e, t), this.scheduleLegend(), this.objectTree?.isOpen() && this.refreshObjects();
|
|
8227
8250
|
},
|
|
@@ -8274,7 +8297,7 @@ var Ha = [
|
|
|
8274
8297
|
if (this.replayBar?.getMode() !== "select" || !this.replayBar.isMounted()) return;
|
|
8275
8298
|
let t = e.payload.point;
|
|
8276
8299
|
this.positionReplayShade(t?.x ?? null);
|
|
8277
|
-
}), this.dataWindow = new
|
|
8300
|
+
}), this.dataWindow = new da(this.root, { formatPrice: (e) => this.formatAlertPrice(e) }, this.t), this.chart.on("crosshairMove", (e) => {
|
|
8278
8301
|
let t = e.payload;
|
|
8279
8302
|
this.lastHoverIndex = typeof t.barIndex == "number" ? t.barIndex : null, this.dataWindow?.isOpen() && this.dataWindow.render(this.buildDataWindowModel());
|
|
8280
8303
|
});
|
|
@@ -8288,7 +8311,7 @@ var Ha = [
|
|
|
8288
8311
|
},
|
|
8289
8312
|
toWallTime: (e) => X(e * S(this.chart.getData()), this.displayTimezone()),
|
|
8290
8313
|
fromWallTime: (e, t) => {
|
|
8291
|
-
let n =
|
|
8314
|
+
let n = Hi(e, t, this.displayTimezone());
|
|
8292
8315
|
return n === null ? null : n / S(this.chart.getData());
|
|
8293
8316
|
},
|
|
8294
8317
|
roundPrice: (e) => this.chart.roundPrice(e),
|
|
@@ -8405,7 +8428,7 @@ var Ha = [
|
|
|
8405
8428
|
"indicatorUpdate"
|
|
8406
8429
|
]) this.chart.on(e, () => this.refreshAccountSoon());
|
|
8407
8430
|
}
|
|
8408
|
-
t.trading !== !1 && (this.bracketBar = new
|
|
8431
|
+
t.trading !== !1 && (this.bracketBar = new oa(this.root, {
|
|
8409
8432
|
onConfirm: () => this.chart.confirmBracket(),
|
|
8410
8433
|
onCancel: () => {
|
|
8411
8434
|
this.chart.cancelBracket(), this.bracketBar?.hide();
|
|
@@ -8413,7 +8436,7 @@ var Ha = [
|
|
|
8413
8436
|
}, this.t), this.chart.on("bracketPlace", (e) => {
|
|
8414
8437
|
let t = e.payload;
|
|
8415
8438
|
this.bracketBar?.hide(), this.say(p(this.t(t.side === "buy" ? "bracket.longPlaced" : "bracket.shortPlaced"), { rr: t.riskReward.toFixed(2) }));
|
|
8416
|
-
}), t.depthLadder && (this.depthLadder = new
|
|
8439
|
+
}), t.depthLadder && (this.depthLadder = new la(this.root, {
|
|
8417
8440
|
onTrade: (e, t) => {
|
|
8418
8441
|
this.chart.placeOrderIntent({
|
|
8419
8442
|
side: e,
|
|
@@ -8444,7 +8467,7 @@ var Ha = [
|
|
|
8444
8467
|
}, this.t), this.chart.on("alertAdd", () => this.refreshAlerts()), this.chart.on("alertRemove", () => this.refreshAlerts()), this.chart.on("alertUpdate", () => this.refreshAlerts()), this.chart.on("alertExpired", (e) => {
|
|
8445
8468
|
let t = e.payload;
|
|
8446
8469
|
this.refreshAlerts(), this.featureState.alerts && this.say(p(this.t("alerts.expiredToast"), { text: t.message ?? this.alertText(t) }));
|
|
8447
|
-
}), t.alertNotifications && (this.alertNotifier = new
|
|
8470
|
+
}), t.alertNotifications && (this.alertNotifier = new sa(t.alertNotifications)), this.chart.on("alertTriggered", (e) => {
|
|
8448
8471
|
let t = e.payload;
|
|
8449
8472
|
if (this.refreshAlerts(), !this.featureState.alerts) return;
|
|
8450
8473
|
let n = `${this.alertText(t)}${t.message ? ` — ${t.message}` : ""}`;
|
|
@@ -8514,11 +8537,11 @@ var Ha = [
|
|
|
8514
8537
|
} else if ((e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && (e.key === "s" || e.key === "S")) {
|
|
8515
8538
|
if (!this.layoutSession || !n("hotkeys.save") || !this.featureState.layouts || Y() || !ji(this.root, !0)) return;
|
|
8516
8539
|
e.preventDefault(), this.saveLayout();
|
|
8517
|
-
} else if (e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey &&
|
|
8518
|
-
if (e.defaultPrevented || Y() || !t ||
|
|
8519
|
-
e.preventDefault(), this.handleDrawingTool(
|
|
8540
|
+
} else if (e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey && Za[e.code]) {
|
|
8541
|
+
if (e.defaultPrevented || Y() || !t || Xa() || !n("hotkeys.tools")) return;
|
|
8542
|
+
e.preventDefault(), this.handleDrawingTool(Za[e.code]);
|
|
8520
8543
|
} else if (/^[0-9]$/.test(e.key) && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
8521
|
-
if (e.defaultPrevented || !this.intervalInput || !n("intervalTyping") || Y() ||
|
|
8544
|
+
if (e.defaultPrevented || !this.intervalInput || !n("intervalTyping") || Y() || Xa() || !ji(this.root, !0)) return;
|
|
8522
8545
|
let t = document.activeElement;
|
|
8523
8546
|
if (t && t !== document.body && !this.root.contains(t)) return;
|
|
8524
8547
|
e.preventDefault(), this.intervalInput.open(e.key);
|
|
@@ -8541,7 +8564,7 @@ var Ha = [
|
|
|
8541
8564
|
}, document.addEventListener("keydown", this.boundGlobalKeydown), document.addEventListener("fullscreenchange", this.onFullscreenChange), this.unregisterKeys = Ai(this.root), t.adapter && (this.adapter = t.adapter, this.connectStream()), this.watchlist && (this.watchlistInterval = setInterval(() => this.tickWatchlist(), 1e3)), this.markSwitchedOff(), requestAnimationFrame(() => {
|
|
8542
8565
|
this.destroyed || (this.toolbar?.tidy(), this.sidebar?.tidy());
|
|
8543
8566
|
}), this.refreshMarket(), this.updateUI(), t.onReady?.(this.chart), t.shareUrl && typeof location < "u") {
|
|
8544
|
-
let e =
|
|
8567
|
+
let e = Sa(location.hash);
|
|
8545
8568
|
e && this.importState(e);
|
|
8546
8569
|
}
|
|
8547
8570
|
}
|
|
@@ -8586,6 +8609,7 @@ var Ha = [
|
|
|
8586
8609
|
n && !this.featureState.symbolInfo || (n ? t.open() : t.close());
|
|
8587
8610
|
}
|
|
8588
8611
|
refreshMarket() {
|
|
8612
|
+
if (eo()) return;
|
|
8589
8613
|
let e = le(this.chart.getSymbolInfo(), Date.now());
|
|
8590
8614
|
this.statusBar?.setMarket(e.state, this.t(e.state === "open" ? "symbolInfo.open" : "symbolInfo.closed")), this.refreshSymbolInfo();
|
|
8591
8615
|
}
|
|
@@ -8594,9 +8618,9 @@ var Ha = [
|
|
|
8594
8618
|
!e?.isOpen() || this.destroyed || e.render(this.symbolInfoView());
|
|
8595
8619
|
}
|
|
8596
8620
|
symbolInfoView() {
|
|
8597
|
-
let e = this.chart.getSymbolInfo(), t = this.state.symbol, n = this.quotes.get(t), r =
|
|
8621
|
+
let e = this.chart.getSymbolInfo(), t = this.state.symbol, n = this.quotes.get(t), r = co(this.chart.getData(), e?.timezone), i = (e) => this.formatAlertPrice(e), a = this.textLocale(), o = n?.last ?? r?.close, s = n?.prevClose ?? r?.prevClose, c = n?.change ?? (o !== void 0 && s !== void 0 ? o - s : void 0), l = o !== void 0 && c !== void 0 ? o - c : void 0, u = n?.changePercent ?? (c !== void 0 && l ? c / l * 100 : void 0), d = le(e, Date.now()), f = this.t(d.state === "open" ? "symbolInfo.open" : d.state === "closed" ? "symbolInfo.closed" : "symbolInfo.always");
|
|
8598
8622
|
if (d.state !== "always" && d.next !== null) {
|
|
8599
|
-
let e =
|
|
8623
|
+
let e = lo(d.next - Date.now(), a);
|
|
8600
8624
|
f += ` · ${p(this.t(d.state === "open" ? "symbolInfo.closesIn" : "symbolInfo.opensIn"), { when: e })}`;
|
|
8601
8625
|
}
|
|
8602
8626
|
let m = [], h = (e, t) => {
|
|
@@ -8607,7 +8631,7 @@ var Ha = [
|
|
|
8607
8631
|
}, g = (e) => e === void 0 ? void 0 : i(e);
|
|
8608
8632
|
h(this.t("dataWindow.open"), g(n?.open ?? r?.open)), h(this.t("dataWindow.high"), g(n?.high ?? r?.high)), h(this.t("dataWindow.low"), g(n?.low ?? r?.low)), h(this.t("symbolInfo.prevClose"), g(s));
|
|
8609
8633
|
let _ = n?.volume ?? r?.volume;
|
|
8610
|
-
h(this.t("dataWindow.volume"), _ === void 0 ? void 0 :
|
|
8634
|
+
h(this.t("dataWindow.volume"), _ === void 0 ? void 0 : uo(_, this.intlLocale())), h(this.t("symbolInfo.bid"), g(n?.bid)), h(this.t("symbolInfo.ask"), g(n?.ask)), h(this.t("symbolInfo.tick"), e?.minTick === void 0 ? void 0 : String(e.minTick)), h(this.t("symbolInfo.currency"), e?.currency), h(this.t("symbolInfo.timezone"), e?.timezone), h(this.t("symbolInfo.hours"), fo(e, a));
|
|
8611
8635
|
let v = (c ?? 0) >= 0 ? "+" : "-";
|
|
8612
8636
|
return {
|
|
8613
8637
|
symbol: t,
|
|
@@ -8640,17 +8664,17 @@ var Ha = [
|
|
|
8640
8664
|
items: t.map((e) => ({
|
|
8641
8665
|
title: e.title,
|
|
8642
8666
|
url: e.url,
|
|
8643
|
-
meta: [e.source,
|
|
8667
|
+
meta: [e.source, lo(e.time - Date.now(), n)].filter(Boolean).join(" · ")
|
|
8644
8668
|
}))
|
|
8645
8669
|
});
|
|
8646
8670
|
}, o = this.newsCache.get(r);
|
|
8647
|
-
if (o && Date.now() - o.at <
|
|
8671
|
+
if (o && Date.now() - o.at < oo) {
|
|
8648
8672
|
a(o.items);
|
|
8649
8673
|
return;
|
|
8650
8674
|
}
|
|
8651
|
-
e.renderNews({ kind: "loading" }), Promise.resolve().then(() => n(r,
|
|
8675
|
+
e.renderNews({ kind: "loading" }), Promise.resolve().then(() => n(r, ao)).then((e) => {
|
|
8652
8676
|
if (i !== this.newsRequest || this.destroyed) return;
|
|
8653
|
-
let t = pe(e,
|
|
8677
|
+
let t = pe(e, ao);
|
|
8654
8678
|
this.newsCache.set(r, {
|
|
8655
8679
|
at: Date.now(),
|
|
8656
8680
|
items: t
|
|
@@ -8666,7 +8690,7 @@ var Ha = [
|
|
|
8666
8690
|
return this.options.locale || "en";
|
|
8667
8691
|
}
|
|
8668
8692
|
createWatchlist(e, t) {
|
|
8669
|
-
let n = t.persist ?
|
|
8693
|
+
let n = t.persist ? io() : null, r = new En({
|
|
8670
8694
|
lists: t.lists,
|
|
8671
8695
|
activeList: t.activeList,
|
|
8672
8696
|
symbols: this.symbols,
|
|
@@ -8747,7 +8771,7 @@ var Ha = [
|
|
|
8747
8771
|
t.refPrice !== void 0 && this.hostWatchlistRefPrice.set(e, t.refPrice), this.watchlist?.setEntry(e, t);
|
|
8748
8772
|
}
|
|
8749
8773
|
tickWatchlist() {
|
|
8750
|
-
if (!this.watchlist || this.quotes.has(this.state.symbol)) return;
|
|
8774
|
+
if (!this.watchlist || this.quotes.has(this.state.symbol) || eo()) return;
|
|
8751
8775
|
let e = this.chart.getData();
|
|
8752
8776
|
if (e.length === 0) return;
|
|
8753
8777
|
let t = e[e.length - 1], n = this.hostWatchlistRefPrice.get(this.state.symbol);
|
|
@@ -8808,9 +8832,9 @@ var Ha = [
|
|
|
8808
8832
|
}
|
|
8809
8833
|
destroy() {
|
|
8810
8834
|
if (!this.destroyed) {
|
|
8811
|
-
this.destroyed = !0, this.boundGlobalKeydown && document.removeEventListener("keydown", this.boundGlobalKeydown), document.removeEventListener("fullscreenchange", this.onFullscreenChange), this.unregisterKeys(), this.tooltip.destroy(), this.legendFrame && cancelAnimationFrame(this.legendFrame), this.indicatorLegend?.destroy(), this.portal.remove(), document.fullscreenElement === this.root && document.exitFullscreen().catch(() => {}), this.flushActiveLayout(), this.commandPalette?.destroy(), this.symbolSearch?.destroy(), this.hotkeySheet?.destroy(), this.replayPollInterval && clearInterval(this.replayPollInterval), this.replayShade?.remove(), this.replayBar?.destroy(), this.dragDrop?.detach(), this.alertsPanel?.destroy(), this.objectTree?.destroy(), this.indicatorSettings?.destroy(), this.drawingStyle?.destroy(), this.drawingSettings?.destroy(), this.drawingMenu?.destroy(), this.selectionToolbar?.destroy(), this.selectionToolbarFrame !== null && cancelAnimationFrame(this.selectionToolbarFrame), this.chartMenu?.destroy(), this.legendMenu?.destroy();
|
|
8835
|
+
this.destroyed = !0, this.stopKeyboardInset?.(), this.stopKeyboardInset = null, this.boundGlobalKeydown && document.removeEventListener("keydown", this.boundGlobalKeydown), document.removeEventListener("fullscreenchange", this.onFullscreenChange), this.unregisterKeys(), this.tooltip.destroy(), this.legendFrame && cancelAnimationFrame(this.legendFrame), this.indicatorLegend?.destroy(), this.portal.remove(), document.fullscreenElement === this.root && document.exitFullscreen().catch(() => {}), this.flushActiveLayout(), this.commandPalette?.destroy(), this.symbolSearch?.destroy(), this.hotkeySheet?.destroy(), this.replayPollInterval && clearInterval(this.replayPollInterval), this.replayShade?.remove(), this.replayBar?.destroy(), this.dragDrop?.detach(), this.alertsPanel?.destroy(), this.objectTree?.destroy(), this.indicatorSettings?.destroy(), this.drawingStyle?.destroy(), this.drawingSettings?.destroy(), this.drawingMenu?.destroy(), this.selectionToolbar?.destroy(), this.selectionToolbarFrame !== null && cancelAnimationFrame(this.selectionToolbarFrame), this.chartMenu?.destroy(), this.legendMenu?.destroy();
|
|
8812
8836
|
for (let e of this.hostMenus) e.destroy();
|
|
8813
|
-
this.hostMenus.clear(), this.templatePrompt?.destroy(), this.intervalInput?.destroy(), this.markerTip?.remove(), this.layoutSession?.destroy(), this.layoutsUI?.destroy(), this.accountPanel?.destroy(), this.orderTicket?.destroy(), this.accountFrame && cancelAnimationFrame(this.accountFrame), this.bracketBar?.destroy(), this.alertNotifier?.destroy(), this.depthLadder?.destroy(), this.dataWindow?.destroy(), this.watchlistInterval && clearInterval(this.watchlistInterval), this.marketTimer && clearInterval(this.marketTimer), this.chartNav?.destroy(), this.symbolInfoPanel?.destroy(), this.stopQuotes?.(), this.stopQuotes = null, this.watchlist?.destroy(), this.toolbar?.destroy(), this.sidebar?.destroy(), this.settings?.destroy(), this.statusBar?.destroy(), this.goToDate?.destroy(), this.loading.destroy(), this.historyPill.destroy(), this.chart.destroy(), this.root.remove(), gt();
|
|
8837
|
+
this.hostMenus.clear(), this.templatePrompt?.destroy(), this.intervalInput?.destroy(), this.markerTip?.remove(), this.layoutSession?.destroy(), this.layoutsUI?.destroy(), this.accountPanel?.destroy(), this.orderTicket?.destroy(), this.accountFrame && cancelAnimationFrame(this.accountFrame), this.bracketBar?.destroy(), this.alertNotifier?.destroy(), this.depthLadder?.destroy(), this.dataWindow?.destroy(), this.watchlistInterval && clearInterval(this.watchlistInterval), this.marketTimer && clearInterval(this.marketTimer), this.onPageShown && document.removeEventListener("visibilitychange", this.onPageShown), this.onPageShown = null, this.chartNav?.destroy(), this.symbolInfoPanel?.destroy(), this.stopQuotes?.(), this.stopQuotes = null, this.watchlist?.destroy(), this.toolbar?.destroy(), this.sidebar?.destroy(), this.settings?.destroy(), this.statusBar?.destroy(), this.goToDate?.destroy(), this.loading.destroy(), this.historyPill.destroy(), this.chart.destroy(), this.root.remove(), gt();
|
|
8814
8838
|
}
|
|
8815
8839
|
}
|
|
8816
8840
|
handleSymbolClick() {
|
|
@@ -8849,7 +8873,7 @@ var Ha = [
|
|
|
8849
8873
|
for (; o > 0 && n[o - 1].time * r >= a;) o--;
|
|
8850
8874
|
let s = this.displayTimezone();
|
|
8851
8875
|
return Ti({
|
|
8852
|
-
dayShare: n.slice(
|
|
8876
|
+
dayShare: n.slice(-to).some((e) => {
|
|
8853
8877
|
let t = e.time * r, n = new Date(t + ue(s, t) * 6e4).getUTCDay();
|
|
8854
8878
|
return n === 0 || n === 6;
|
|
8855
8879
|
}) ? 1 : 5 / 7,
|
|
@@ -8907,7 +8931,7 @@ var Ha = [
|
|
|
8907
8931
|
e.hide();
|
|
8908
8932
|
return;
|
|
8909
8933
|
}
|
|
8910
|
-
let i = this.chartOffset(), a = this.chart.getPlotRect(), o =
|
|
8934
|
+
let i = this.chartOffset(), a = this.chart.getPlotRect(), o = po(r.map((e) => this.chart.getDrawingRect(e.id))) ?? {
|
|
8911
8935
|
x: a.x + a.width / 2,
|
|
8912
8936
|
y: a.y,
|
|
8913
8937
|
width: 0,
|
|
@@ -8972,11 +8996,11 @@ var Ha = [
|
|
|
8972
8996
|
id: e,
|
|
8973
8997
|
type: s.type,
|
|
8974
8998
|
selected: o
|
|
8975
|
-
}) ?? [] : [], l =
|
|
8999
|
+
}) ?? [] : [], l = ka(a, c);
|
|
8976
9000
|
if (l.length === 0) return;
|
|
8977
9001
|
let u = this.chartContainer.getBoundingClientRect(), d = this.root.getBoundingClientRect();
|
|
8978
9002
|
this.drawingMenu.open(l, u.left - d.left + t, u.top - d.top + n, (t) => {
|
|
8979
|
-
|
|
9003
|
+
Aa(t, c) || this.runDrawingMenuAction(e, o, t);
|
|
8980
9004
|
});
|
|
8981
9005
|
}
|
|
8982
9006
|
runDrawingMenuAction(e, t, n) {
|
|
@@ -9040,11 +9064,11 @@ var Ha = [
|
|
|
9040
9064
|
}
|
|
9041
9065
|
openChartMenu(e, t, n, r) {
|
|
9042
9066
|
if (!this.chartMenu) return;
|
|
9043
|
-
let i = this.options.chartMenuItems?.(r) ?? [], a =
|
|
9067
|
+
let i = this.options.chartMenuItems?.(r) ?? [], a = ka(e, i);
|
|
9044
9068
|
if (a.length === 0) return;
|
|
9045
9069
|
let o = this.chartContainer.getBoundingClientRect(), s = this.root.getBoundingClientRect();
|
|
9046
9070
|
this.chartMenu.open(a, o.left - s.left + t, o.top - s.top + n, (e) => {
|
|
9047
|
-
|
|
9071
|
+
Aa(e, i) || this.runChartMenuAction(e, r.price);
|
|
9048
9072
|
});
|
|
9049
9073
|
}
|
|
9050
9074
|
setFeatures(e) {
|
|
@@ -9094,9 +9118,9 @@ var Ha = [
|
|
|
9094
9118
|
for (let [n, r] of t) e(n) && r();
|
|
9095
9119
|
}
|
|
9096
9120
|
addHotkey(e) {
|
|
9097
|
-
let t =
|
|
9121
|
+
let t = Pa(e.keys);
|
|
9098
9122
|
if (!t) return console.warn(`[ChartWidget] Can't read the shortcut "${e.keys}": modifiers (Ctrl, Alt, Shift) and a key, joined by +.`), null;
|
|
9099
|
-
|
|
9123
|
+
La(t) && console.warn(`[ChartWidget] The chart answers ${e.keys} itself (drawings, scrolling or zoom): both will run.`);
|
|
9100
9124
|
let n = {
|
|
9101
9125
|
spec: e,
|
|
9102
9126
|
parsed: t
|
|
@@ -9106,8 +9130,8 @@ var Ha = [
|
|
|
9106
9130
|
} };
|
|
9107
9131
|
}
|
|
9108
9132
|
handleHostHotkey(e) {
|
|
9109
|
-
if (this.hostHotkeys.length === 0 || !this.featureState.hotkeys || e.isComposing || e.keyCode ===
|
|
9110
|
-
let t = this.hostHotkeys.find((t) =>
|
|
9133
|
+
if (this.hostHotkeys.length === 0 || !this.featureState.hotkeys || e.isComposing || e.keyCode === Qa || e.getModifierState?.("AltGraph") || e.defaultPrevented || Y() || Ra(e) || Xa()) return !1;
|
|
9134
|
+
let t = this.hostHotkeys.find((t) => Fa(e, t.parsed));
|
|
9111
9135
|
if (!t) return !1;
|
|
9112
9136
|
let n = !t.parsed.ctrl && !t.parsed.alt;
|
|
9113
9137
|
if (!ji(this.root, n)) return !1;
|
|
@@ -9115,7 +9139,7 @@ var Ha = [
|
|
|
9115
9139
|
return n && r && r !== document.body && !this.root.contains(r) ? !1 : (e.preventDefault(), t.spec.onPress(e), !0);
|
|
9116
9140
|
}
|
|
9117
9141
|
keepingLook(e) {
|
|
9118
|
-
let t = this.chart.getOverrides?.({ layer: "user" }) ?? {}, n = Object.fromEntries(
|
|
9142
|
+
let t = this.chart.getOverrides?.({ layer: "user" }) ?? {}, n = Object.fromEntries($a.filter((e) => t[e] !== void 0).map((e) => [e, t[e]]));
|
|
9119
9143
|
e(), Object.keys(n).length > 0 && this.chart.applyOverrides(n, { layer: "user" });
|
|
9120
9144
|
}
|
|
9121
9145
|
sheetKeyOn(e) {
|
|
@@ -9167,7 +9191,7 @@ var Ha = [
|
|
|
9167
9191
|
let r = e.items();
|
|
9168
9192
|
if (r.length === 0) return;
|
|
9169
9193
|
let i = t.getBoundingClientRect(), a = this.root.getBoundingClientRect();
|
|
9170
|
-
n.open(
|
|
9194
|
+
n.open(ka([], r), i.left - a.left, i.bottom - a.top + 2, (e) => Aa(e, r), t);
|
|
9171
9195
|
}
|
|
9172
9196
|
});
|
|
9173
9197
|
return r.setAttribute("aria-haspopup", "menu"), r.setAttribute("aria-expanded", "false"), t.tidy(), {
|
|
@@ -9349,7 +9373,7 @@ var Ha = [
|
|
|
9349
9373
|
e.length !== 0 && this.goToDate.open(X(e[e.length - 1].time * S(e), this.displayTimezone()), this.root.querySelector("[data-role=\"goto\"]"));
|
|
9350
9374
|
}
|
|
9351
9375
|
goToWallTime(e, t) {
|
|
9352
|
-
let n =
|
|
9376
|
+
let n = Hi(e, t, this.displayTimezone()), r = this.chart.getData();
|
|
9353
9377
|
if (n === null || r.length === 0) return;
|
|
9354
9378
|
let i = n / S(r);
|
|
9355
9379
|
this.chart.goToTime(i), i < r[0].time && this.say(this.t("range.beforeData"));
|
|
@@ -9426,9 +9450,9 @@ var Ha = [
|
|
|
9426
9450
|
}
|
|
9427
9451
|
async switchLocalTimeframe() {
|
|
9428
9452
|
if (!this.baseSeries) return;
|
|
9429
|
-
let e = ++this.localSeq, t = this.lastLocalSwitchMs >=
|
|
9453
|
+
let e = ++this.localSeq, t = this.lastLocalSwitchMs >= za || this.baseSeries.length >= Ba;
|
|
9430
9454
|
try {
|
|
9431
|
-
if (t && (this.loading.begin(this.chart.getData().length > 0, !0), await
|
|
9455
|
+
if (t && (this.loading.begin(this.chart.getData().length > 0, !0), await Ha(), e !== this.localSeq || this.destroyed)) return;
|
|
9432
9456
|
this.applyTimeframeData();
|
|
9433
9457
|
} finally {
|
|
9434
9458
|
e === this.localSeq && this.loading.end();
|
|
@@ -9485,7 +9509,7 @@ var Ha = [
|
|
|
9485
9509
|
id: e.id,
|
|
9486
9510
|
params: e.params
|
|
9487
9511
|
}));
|
|
9488
|
-
return
|
|
9512
|
+
return ya({
|
|
9489
9513
|
v: 1,
|
|
9490
9514
|
symbol: this.state.symbol,
|
|
9491
9515
|
timeframe: this.state.timeframe,
|
|
@@ -9496,7 +9520,7 @@ var Ha = [
|
|
|
9496
9520
|
});
|
|
9497
9521
|
}
|
|
9498
9522
|
async importState(e) {
|
|
9499
|
-
let t =
|
|
9523
|
+
let t = ba(e);
|
|
9500
9524
|
return t ? (t.symbol && t.symbol !== this.state.symbol && await this.setSymbol(t.symbol), t.timeframe && t.timeframe !== this.state.timeframe && await this.setTimeframe(t.timeframe), t.chartType && this.applyChartType(t.chartType), this.chart.setScaleMode(t.scaleMode), this.chart.applyIndicatorSetup(t.indicators.map((e, t) => ({
|
|
9501
9525
|
id: e.id,
|
|
9502
9526
|
instanceId: `shared_${t}`,
|
|
@@ -9508,7 +9532,7 @@ var Ha = [
|
|
|
9508
9532
|
this.say(e ? this.t("toast.imageCopied") : this.t("toast.imageCopyFailed"), e ? "info" : "error");
|
|
9509
9533
|
}
|
|
9510
9534
|
async copyShareLink() {
|
|
9511
|
-
let e =
|
|
9535
|
+
let e = Ca(typeof location < "u" ? location.href : "", this.exportState());
|
|
9512
9536
|
try {
|
|
9513
9537
|
await navigator.clipboard.writeText(e), this.say(this.t("toast.linkCopied"));
|
|
9514
9538
|
} catch {
|
|
@@ -9569,7 +9593,7 @@ var Ha = [
|
|
|
9569
9593
|
defaults: n.descriptor.defaultConfig,
|
|
9570
9594
|
params: n.params,
|
|
9571
9595
|
inputs: n.descriptor.inputs,
|
|
9572
|
-
lineSources:
|
|
9596
|
+
lineSources: ro(e, t),
|
|
9573
9597
|
plots: n.descriptor.plots,
|
|
9574
9598
|
colors: r?.colors,
|
|
9575
9599
|
lineWidth: r?.lineWidths[0],
|
|
@@ -9667,7 +9691,7 @@ var Ha = [
|
|
|
9667
9691
|
return;
|
|
9668
9692
|
}
|
|
9669
9693
|
if (this.compares.some((t) => t.symbol === e)) return;
|
|
9670
|
-
let n =
|
|
9694
|
+
let n = Ua[this.compares.length % Ua.length], r = `cmp_${e}`;
|
|
9671
9695
|
try {
|
|
9672
9696
|
let t = await Me(this.adapter).fetchHistory(e, this.state.timeframe, this.options.historyLimit ?? 500);
|
|
9673
9697
|
this.compares.length === 0 && this.chart.setCompareMode("percent"), this.chart.addCompareSymbol(r, e, t, n), this.compares = [...this.compares, {
|
|
@@ -10164,7 +10188,7 @@ var Ha = [
|
|
|
10164
10188
|
}
|
|
10165
10189
|
replayStepOptions() {
|
|
10166
10190
|
let e = w(this.state.timeframe);
|
|
10167
|
-
return
|
|
10191
|
+
return Ja.filter((t) => {
|
|
10168
10192
|
let n = w(t);
|
|
10169
10193
|
return !(n < e) || e % n !== 0 ? !1 : this.adapter ? Ae(this.adapter, t) : this.baseSeries !== null && this.baseTimeframeMs > 0 && n >= this.baseTimeframeMs && n % this.baseTimeframeMs === 0;
|
|
10170
10194
|
});
|
|
@@ -10174,7 +10198,7 @@ var Ha = [
|
|
|
10174
10198
|
if (this.replayStepsCache?.key === t) return this.replayStepsCache.steps;
|
|
10175
10199
|
let n = null;
|
|
10176
10200
|
if (this.adapter) {
|
|
10177
|
-
let t = Math.max(1, Math.round(w(this.state.timeframe) / w(e))), r = Math.min(
|
|
10201
|
+
let t = Math.max(1, Math.round(w(this.state.timeframe) / w(e))), r = Math.min(Ya, Math.max(this.chart.getData().length, 100) * t);
|
|
10178
10202
|
try {
|
|
10179
10203
|
n = await Me(this.adapter).fetchHistory(this.state.symbol, e, r);
|
|
10180
10204
|
} catch {
|
|
@@ -10341,25 +10365,25 @@ var Ha = [
|
|
|
10341
10365
|
row: n
|
|
10342
10366
|
}));
|
|
10343
10367
|
let a = this.settingsState.numberLocale || "en-US", o = this.chart.getActiveIndicators().map((t) => {
|
|
10344
|
-
let n = i.get(t.instanceId) ?? null, o = r >= 0 ? this.chart.getIndicatorOutput(t.instanceId)?.series?.[r] : null, s = this.chart.getIndicatorStyle(t.instanceId), c =
|
|
10368
|
+
let n = i.get(t.instanceId) ?? null, o = r >= 0 ? this.chart.getIndicatorOutput(t.instanceId)?.series?.[r] : null, s = this.chart.getIndicatorStyle(t.instanceId), c = na(t.descriptor, o, s?.colors ?? [], s?.plots);
|
|
10345
10369
|
return {
|
|
10346
10370
|
instanceId: t.instanceId,
|
|
10347
10371
|
label: e(t.id, t.params, t.descriptor.defaultConfig, t.descriptor.shortName),
|
|
10348
10372
|
visible: t.visible,
|
|
10349
10373
|
values: c.map((e) => ({
|
|
10350
|
-
text: n ?
|
|
10374
|
+
text: n ? aa(e.value, a) : this.chart.formatPrice(e.value),
|
|
10351
10375
|
color: e.color
|
|
10352
10376
|
})),
|
|
10353
10377
|
pane: n ? {
|
|
10354
|
-
x: n.x +
|
|
10355
|
-
y: n.y + Math.min(
|
|
10356
|
-
width: n.width - 2 *
|
|
10378
|
+
x: n.x + Wa,
|
|
10379
|
+
y: n.y + Math.min(Ga + n.row * Ka, Math.max(Ga, n.height - Ka)),
|
|
10380
|
+
width: n.width - 2 * Wa
|
|
10357
10381
|
} : null
|
|
10358
10382
|
};
|
|
10359
10383
|
}), s = this.chart.getPlotRect(), c = this.chart.getMaximizedPane(), l = (e) => o.find((t) => t.instanceId === e)?.label ?? "", u = this.chart.getIndicatorPanes().map((e) => ({
|
|
10360
10384
|
instanceId: e.instanceId,
|
|
10361
|
-
x: e.rect.x + e.rect.width -
|
|
10362
|
-
y: e.rect.y +
|
|
10385
|
+
x: e.rect.x + e.rect.width - Wa,
|
|
10386
|
+
y: e.rect.y + qa,
|
|
10363
10387
|
label: l(e.instanceId),
|
|
10364
10388
|
collapsed: this.chart.isPaneCollapsed(e.instanceId),
|
|
10365
10389
|
maximized: c === e.instanceId,
|
|
@@ -10367,7 +10391,7 @@ var Ha = [
|
|
|
10367
10391
|
canMoveDown: this.chart.canMovePane(e.instanceId, 1)
|
|
10368
10392
|
}));
|
|
10369
10393
|
this.indicatorLegend.update(o, {
|
|
10370
|
-
left: s.x +
|
|
10394
|
+
left: s.x + Wa,
|
|
10371
10395
|
top: this.chart.getLegendBottom() + 1
|
|
10372
10396
|
}, u);
|
|
10373
10397
|
}
|
|
@@ -10413,11 +10437,11 @@ var Ha = [
|
|
|
10413
10437
|
let u = this.chart.getActiveIndicators().find((t) => t.instanceId === e)?.id ?? "", d = this.options.indicatorMenuItems?.({
|
|
10414
10438
|
instanceId: e,
|
|
10415
10439
|
indicatorId: u
|
|
10416
|
-
}) ?? [], f =
|
|
10440
|
+
}) ?? [], f = ka(c, d);
|
|
10417
10441
|
if (f.length === 0) return;
|
|
10418
10442
|
let p = t.getBoundingClientRect(), m = this.root.getBoundingClientRect();
|
|
10419
10443
|
n.open(f, p.left - m.left, p.bottom - m.top + 2, (t) => {
|
|
10420
|
-
|
|
10444
|
+
Aa(t, d) || (t === "settings" ? this.openIndicatorSettings(e) : t === "remove" ? this.handleRemoveIndicator(e) : t.startsWith("move:") && this.chart.moveIndicatorToPane(e, t.slice(5)), this.scheduleLegend());
|
|
10421
10445
|
}, t);
|
|
10422
10446
|
}
|
|
10423
10447
|
updateUI() {
|
|
@@ -10442,7 +10466,7 @@ var Ha = [
|
|
|
10442
10466
|
return !0;
|
|
10443
10467
|
}
|
|
10444
10468
|
};
|
|
10445
|
-
function
|
|
10469
|
+
function ro(t, n) {
|
|
10446
10470
|
let r = (e) => {
|
|
10447
10471
|
let t = je(e.descriptor);
|
|
10448
10472
|
return t && de(e.params[t])?.instanceId || null;
|
|
@@ -10465,19 +10489,19 @@ function to(t, n) {
|
|
|
10465
10489
|
}
|
|
10466
10490
|
return a;
|
|
10467
10491
|
}
|
|
10468
|
-
function
|
|
10492
|
+
function io() {
|
|
10469
10493
|
try {
|
|
10470
10494
|
return typeof localStorage < "u" ? localStorage : null;
|
|
10471
10495
|
} catch {
|
|
10472
10496
|
return null;
|
|
10473
10497
|
}
|
|
10474
10498
|
}
|
|
10475
|
-
var
|
|
10476
|
-
function
|
|
10499
|
+
var ao = 10, oo = 5 * 6e4, so = 864e5;
|
|
10500
|
+
function co(e, t) {
|
|
10477
10501
|
if (e.length === 0) return null;
|
|
10478
10502
|
let n = t && ce(t) ? t : null, r = S(e), i = (e) => {
|
|
10479
10503
|
let t = e * r;
|
|
10480
|
-
return Math.floor((t + (n ? xe(n, t) * 6e4 : 0)) /
|
|
10504
|
+
return Math.floor((t + (n ? xe(n, t) * 6e4 : 0)) / so);
|
|
10481
10505
|
}, a = e[e.length - 1], o = i(a.time), s = e.length - 1;
|
|
10482
10506
|
for (; s > 0 && i(e[s - 1].time) === o;) s--;
|
|
10483
10507
|
let c = -Infinity, l = Infinity, u = 0;
|
|
@@ -10491,7 +10515,7 @@ function oo(e, t) {
|
|
|
10491
10515
|
prevClose: s > 0 ? e[s - 1].close : void 0
|
|
10492
10516
|
};
|
|
10493
10517
|
}
|
|
10494
|
-
function
|
|
10518
|
+
function lo(e, t) {
|
|
10495
10519
|
let n = e / 6e4, [r, i] = Math.abs(n) < 60 ? [Math.round(n) || Math.sign(n) || 1, "minute"] : Math.abs(n) < 1440 ? [Math.round(n / 60), "hour"] : [Math.round(n / 1440), "day"];
|
|
10496
10520
|
try {
|
|
10497
10521
|
return new Intl.RelativeTimeFormat(t, { numeric: "auto" }).format(r, i);
|
|
@@ -10499,7 +10523,7 @@ function so(e, t) {
|
|
|
10499
10523
|
return new Intl.RelativeTimeFormat("en", { numeric: "auto" }).format(r, i);
|
|
10500
10524
|
}
|
|
10501
10525
|
}
|
|
10502
|
-
function
|
|
10526
|
+
function uo(e, t) {
|
|
10503
10527
|
try {
|
|
10504
10528
|
return new Intl.NumberFormat(t, {
|
|
10505
10529
|
notation: "compact",
|
|
@@ -10509,7 +10533,7 @@ function co(e, t) {
|
|
|
10509
10533
|
return String(e);
|
|
10510
10534
|
}
|
|
10511
10535
|
}
|
|
10512
|
-
function
|
|
10536
|
+
function fo(e, t) {
|
|
10513
10537
|
let n = e?.sessions ?? [];
|
|
10514
10538
|
if (n.length === 0) return;
|
|
10515
10539
|
let r;
|
|
@@ -10536,7 +10560,7 @@ function lo(e, t) {
|
|
|
10536
10560
|
};
|
|
10537
10561
|
return n.map((e) => [`${e.start}–${e.end}`, i(e.days)].filter(Boolean).join(" ")).join(", ");
|
|
10538
10562
|
}
|
|
10539
|
-
function
|
|
10563
|
+
function po(e) {
|
|
10540
10564
|
let t = e.filter((e) => e !== null);
|
|
10541
10565
|
if (t.length === 0) return null;
|
|
10542
10566
|
let n = Math.min(...t.map((e) => e.x)), r = Math.min(...t.map((e) => e.y)), i = Math.max(...t.map((e) => e.x + e.width)), a = Math.max(...t.map((e) => e.y + e.height));
|
|
@@ -10547,19 +10571,19 @@ function uo(e) {
|
|
|
10547
10571
|
height: a - r
|
|
10548
10572
|
};
|
|
10549
10573
|
}
|
|
10550
|
-
function
|
|
10574
|
+
function mo(e) {
|
|
10551
10575
|
return !!e && /^(ar|he|iw|fa|ur|ps|yi|dv|ckb|sd|ug)(-|$)/i.test(e);
|
|
10552
10576
|
}
|
|
10553
10577
|
//#endregion
|
|
10554
10578
|
//#region src/widget/ChartWidgetGrid.ts
|
|
10555
|
-
var
|
|
10579
|
+
var ho = {
|
|
10556
10580
|
symbol: !1,
|
|
10557
10581
|
interval: !1,
|
|
10558
10582
|
crosshair: !0,
|
|
10559
10583
|
time: !1,
|
|
10560
10584
|
drawings: !1,
|
|
10561
10585
|
replay: !1
|
|
10562
|
-
},
|
|
10586
|
+
}, go = [
|
|
10563
10587
|
"symbol",
|
|
10564
10588
|
"interval",
|
|
10565
10589
|
"crosshair",
|
|
@@ -10600,25 +10624,25 @@ var po = {
|
|
|
10600
10624
|
rows: 3
|
|
10601
10625
|
}
|
|
10602
10626
|
};
|
|
10603
|
-
function
|
|
10627
|
+
function _o(e) {
|
|
10604
10628
|
return typeof e == "string" && Object.prototype.hasOwnProperty.call($, e);
|
|
10605
10629
|
}
|
|
10606
|
-
function
|
|
10630
|
+
function vo(e) {
|
|
10607
10631
|
return JSON.parse(JSON.stringify(e));
|
|
10608
10632
|
}
|
|
10609
|
-
function
|
|
10633
|
+
function yo(e, t, n = 16) {
|
|
10610
10634
|
let r = (20 - 2 * (e - 1)) / e, i = (20 - 2 * (t - 1)) / t, a = "";
|
|
10611
10635
|
for (let n = 0; n < t; n++) for (let t = 0; t < e; t++) a += `<rect x="${2 + t * (r + 2)}" y="${2 + n * (i + 2)}" width="${r}" height="${i}" rx="1"/>`;
|
|
10612
10636
|
return `<svg width="${n}" height="${n}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true">${a}</svg>`;
|
|
10613
10637
|
}
|
|
10614
|
-
function
|
|
10638
|
+
function bo(e) {
|
|
10615
10639
|
if (typeof e != "object" || !e) return null;
|
|
10616
10640
|
let t = e;
|
|
10617
|
-
if (t.v !== 1 || t.kind !== "grid" || !
|
|
10641
|
+
if (t.v !== 1 || t.kind !== "grid" || !_o(t.layout) || !Array.isArray(t.cells)) return null;
|
|
10618
10642
|
let n = t.cells.map(Fi);
|
|
10619
10643
|
if (n.some((e) => e === null)) return null;
|
|
10620
|
-
let r = typeof t.sync == "object" && t.sync !== null ? t.sync : {}, i = { ...
|
|
10621
|
-
for (let e of
|
|
10644
|
+
let r = typeof t.sync == "object" && t.sync !== null ? t.sync : {}, i = { ...ho };
|
|
10645
|
+
for (let e of go) typeof r[e] == "boolean" && (i[e] = r[e]);
|
|
10622
10646
|
let a = typeof t.active == "number" && Number.isInteger(t.active) ? t.active : 0;
|
|
10623
10647
|
return {
|
|
10624
10648
|
v: 1,
|
|
@@ -10629,7 +10653,7 @@ function vo(e) {
|
|
|
10629
10653
|
cells: n
|
|
10630
10654
|
};
|
|
10631
10655
|
}
|
|
10632
|
-
var
|
|
10656
|
+
var xo = class {
|
|
10633
10657
|
root;
|
|
10634
10658
|
cellsEl;
|
|
10635
10659
|
cells = [];
|
|
@@ -10656,8 +10680,8 @@ var yo = class {
|
|
|
10656
10680
|
!(e.ctrlKey || e.metaKey) || e.altKey || e.shiftKey || e.key !== "s" && e.key !== "S" || !this.layoutsUI || Y() || !ji(this.root, !0) || (e.preventDefault(), this.layoutsUI.save());
|
|
10657
10681
|
};
|
|
10658
10682
|
constructor(e, t = {}) {
|
|
10659
|
-
this.options = t, this.layout =
|
|
10660
|
-
...
|
|
10683
|
+
this.options = t, this.layout = _o(t.layout) ? t.layout : "1x2", this.sync = {
|
|
10684
|
+
...ho,
|
|
10661
10685
|
...t.sync
|
|
10662
10686
|
}, this.t = d(f(t.widget?.locale, t.widget?.messages)), ht(), this.root = document.createElement("div"), this.root.className = "tcw-root tcw-grid", this.root.dataset.tcwTheme = t.widget?.theme === "light" ? "light" : "dark", U(this.root, H(t.widget?.ui), { variables: t.widget?.ui !== void 0 }), t.bar !== !1 && this.root.appendChild(this.buildBar()), this.cellsEl = document.createElement("div"), this.cellsEl.className = "tcw-grid-cells", this.root.appendChild(this.cellsEl), e.appendChild(this.root), this.applyShape();
|
|
10663
10687
|
for (let e = 0; e < this.shapeCount(); e++) this.cells.push(this.createCell(e));
|
|
@@ -10695,7 +10719,7 @@ var yo = class {
|
|
|
10695
10719
|
return this.layout;
|
|
10696
10720
|
}
|
|
10697
10721
|
setLayout(e) {
|
|
10698
|
-
if (e === this.layout || !
|
|
10722
|
+
if (e === this.layout || !_o(e)) return;
|
|
10699
10723
|
this.layout = e;
|
|
10700
10724
|
let t = this.shapeCount();
|
|
10701
10725
|
for (; this.cells.length > t;) {
|
|
@@ -10785,7 +10809,7 @@ var yo = class {
|
|
|
10785
10809
|
return JSON.stringify(this.captureLayout());
|
|
10786
10810
|
}
|
|
10787
10811
|
async applyLayoutContent(e) {
|
|
10788
|
-
let t =
|
|
10812
|
+
let t = bo(Ii(e));
|
|
10789
10813
|
return t ? (await this.restoreLayout(t), !0) : !1;
|
|
10790
10814
|
}
|
|
10791
10815
|
destroy() {
|
|
@@ -10806,7 +10830,7 @@ var yo = class {
|
|
|
10806
10830
|
createCell(e) {
|
|
10807
10831
|
let t = document.createElement("div");
|
|
10808
10832
|
t.className = "tcw-grid-cell", t.setAttribute("role", "region"), t.setAttribute("aria-label", p(this.t("grid.chart"), { n: e + 1 })), this.cellsEl.appendChild(t);
|
|
10809
|
-
let n = this.options.widget ?? {}, r = this.options.cells?.[e] ?? {}, i = this.cells[this.active]?.widget, a = {}, o = new
|
|
10833
|
+
let n = this.options.widget ?? {}, r = this.options.cells?.[e] ?? {}, i = this.cells[this.active]?.widget, a = {}, o = new no(t, {
|
|
10810
10834
|
...n,
|
|
10811
10835
|
...r,
|
|
10812
10836
|
...i && this.sync.symbol ? { symbol: i.getSymbol() } : {},
|
|
@@ -10855,7 +10879,7 @@ var yo = class {
|
|
|
10855
10879
|
t.replaySeekToTime(n);
|
|
10856
10880
|
return;
|
|
10857
10881
|
}
|
|
10858
|
-
let r =
|
|
10882
|
+
let r = So(t.getData(), n);
|
|
10859
10883
|
r >= 0 && t.replayStart({
|
|
10860
10884
|
startIndex: r,
|
|
10861
10885
|
paused: !0
|
|
@@ -10900,7 +10924,7 @@ var yo = class {
|
|
|
10900
10924
|
copyDrawings(e) {
|
|
10901
10925
|
let t = e.widget.getSymbol(), n = e.widget.getChart().getDrawings();
|
|
10902
10926
|
this.quietly(() => {
|
|
10903
|
-
for (let r of this.cells) r !== e && r.widget.getSymbol() === t && r.widget.getChart().setDrawings(
|
|
10927
|
+
for (let r of this.cells) r !== e && r.widget.getSymbol() === t && r.widget.getChart().setDrawings(vo(n));
|
|
10904
10928
|
});
|
|
10905
10929
|
}
|
|
10906
10930
|
mergeDrawings() {
|
|
@@ -10912,7 +10936,7 @@ var yo = class {
|
|
|
10912
10936
|
let e = /* @__PURE__ */ new Map();
|
|
10913
10937
|
for (let n of t) for (let t of n.widget.getChart().getDrawings()) e.has(t.id) || e.set(t.id, t);
|
|
10914
10938
|
let n = [...e.values()];
|
|
10915
|
-
for (let e of t) e.widget.getChart().setDrawings(
|
|
10939
|
+
for (let e of t) e.widget.getChart().setDrawings(vo(n));
|
|
10916
10940
|
}
|
|
10917
10941
|
});
|
|
10918
10942
|
}
|
|
@@ -10930,20 +10954,20 @@ var yo = class {
|
|
|
10930
10954
|
e.className = "tcw-grid-bar", e.setAttribute("role", "toolbar"), e.setAttribute("aria-label", this.t("grid.bar"));
|
|
10931
10955
|
let t = document.createElement("div");
|
|
10932
10956
|
t.className = "tcw-grid-group", t.setAttribute("role", "group"), t.setAttribute("aria-label", this.t("grid.layout"));
|
|
10933
|
-
let n = this.options.layoutChoices?.filter(
|
|
10957
|
+
let n = this.options.layoutChoices?.filter(_o) ?? Object.keys($);
|
|
10934
10958
|
for (let e of n) {
|
|
10935
10959
|
let { cols: n, rows: r } = $[e], i = n * r === 1 ? this.t("grid.single") : p(this.t("grid.layoutOption"), {
|
|
10936
10960
|
count: n * r,
|
|
10937
10961
|
cols: n,
|
|
10938
10962
|
rows: r
|
|
10939
10963
|
}), a = document.createElement("button");
|
|
10940
|
-
a.type = "button", a.className = "tcw-btn-icon", a.title = i, a.setAttribute("aria-label", i), a.innerHTML =
|
|
10964
|
+
a.type = "button", a.className = "tcw-btn-icon", a.title = i, a.setAttribute("aria-label", i), a.innerHTML = yo(n, r), a.addEventListener("click", () => this.setLayout(e)), this.layoutButtons.set(e, a), t.appendChild(a);
|
|
10941
10965
|
}
|
|
10942
10966
|
let r = document.createElement("div");
|
|
10943
10967
|
r.className = "tcw-grid-group", r.setAttribute("role", "group"), r.setAttribute("aria-label", this.t("grid.sync"));
|
|
10944
10968
|
let i = document.createElement("span");
|
|
10945
10969
|
i.className = "tcw-grid-label", i.innerHTML = `${j("link", 13)}<span>${N(this.t("grid.sync"))}</span>`, r.appendChild(i);
|
|
10946
|
-
for (let e of
|
|
10970
|
+
for (let e of go) {
|
|
10947
10971
|
let t = document.createElement("button");
|
|
10948
10972
|
t.type = "button", t.className = "tcw-btn tcw-grid-sync", t.textContent = this.t(`grid.sync.${e}`), t.title = this.t(`grid.sync.${e}.hint`), t.addEventListener("click", () => this.setSync({ [e]: !this.sync[e] })), this.syncButtons.set(e, t), r.appendChild(t);
|
|
10949
10973
|
}
|
|
@@ -11004,12 +11028,12 @@ var yo = class {
|
|
|
11004
11028
|
this.cells[this.active]?.widget.toast(e, t);
|
|
11005
11029
|
}
|
|
11006
11030
|
};
|
|
11007
|
-
function
|
|
11031
|
+
function So(e, t) {
|
|
11008
11032
|
let n = -1;
|
|
11009
11033
|
for (let r = 0; r < e.length && e[r].time < t; r++) n = r;
|
|
11010
11034
|
return n;
|
|
11011
11035
|
}
|
|
11012
11036
|
//#endregion
|
|
11013
|
-
export { _ as CHART_TYPE_ICONS,
|
|
11037
|
+
export { _ as CHART_TYPE_ICONS, no as ChartWidget, xo as ChartWidgetGrid, ho as DEFAULT_GRID_SYNC, ee as DRAWING_TOOL_ICONS, l as EN_MESSAGES, $ as GRID_SHAPES, s as LayoutSession, i as MAX_LAYOUT_NAME, re as UI_ICONS, m as VI_MESSAGES, O as WIDGET_FEATURES, Gn as WIDGET_UI_PRESETS, U as applyWidgetUI, o as cleanLayoutName, vt as createChartTypeIcon, j as createIcon, M as createToolIcon, u as findWidgetLocale, ae as iconSvg, r as localStorageLayouts, t as memoryLayouts, bo as readGridLayout, wn as readWatchlists, Fi as readWidgetLayout, c as registerWidgetLocale, H as resolveWidgetUI, Qn as widgetUIVariables };
|
|
11014
11038
|
|
|
11015
11039
|
//# sourceMappingURL=index.js.map
|