candle-annotator/lovable_design_html/candles_lovable_design.html
Marko Djordjevic 4605283d2b feat: redesign UI to match lovable compact sidebar layout
- Replace green hacker theme with professional blue-toned design
- Light theme default, manual toggle only (no system detection)
- Compact w-60 sidebar with collapsible sections
- New CSS tokens: sidebar, chart, candle, annotation colors
- Tools displayed as compact grid buttons
- Color swatches as inline bar
- Chart top bar with keyboard shortcut hints
- Inter + JetBrains Mono font pairing
- All components updated for compact styling
- Tailwind config extended with sidebar/chart tokens
2026-02-16 20:50:30 +01:00

254 lines
36 KiB
HTML

<!DOCTYPE html>
<html lang="en" class=""><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- TODO: Set the document title to the name of your application -->
<title>Lovable App</title>
<meta name="description" content="Lovable Generated Project">
<meta name="author" content="Lovable">
<!-- TODO: Update og:title to match your application name -->
<meta property="og:title" content="Lovable App">
<meta property="og:description" content="Lovable Generated Project">
<meta property="og:type" content="website">
<meta property="og:image" content="https://pub-bb2e103a32db4e198524a2e9ed8f35b4.r2.dev/5dfab914-74ef-4034-9b4c-51ac54c01caf/id-preview-f51190d4--5c09681b-6d88-4768-8cd9-10f44aca2c2b.lovable.app-1771269570733.png">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@Lovable">
<meta name="twitter:image" content="https://pub-bb2e103a32db4e198524a2e9ed8f35b4.r2.dev/5dfab914-74ef-4034-9b4c-51ac54c01caf/id-preview-f51190d4--5c09681b-6d88-4768-8cd9-10f44aca2c2b.lovable.app-1771269570733.png">
<link rel="stylesheet" crossorigin="" href="index-DRgIPKRu.css">
<style>
@font-face {
font-family: 'CameraPlainVariable';
src: url('https://cdn.gpteng.co/mcp-widgets/v1/fonts/CameraPlainVariable.woff2') format('woff2');
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
#lovable-badge {
--badge-bg: #1b1b1b;
--badge-text: #c5c1b9;
--badge-text-hover: #dcdad5;
--badge-radius: 6px;
--badge-padding: 8px;
--badge-gap: 6px;
--badge-shadow:
0 0 0 1px rgba(0, 0, 0, 0.88),
0 1px 0 0 rgba(0, 0, 0, 0.04),
0 2px 2px -1px rgba(0, 0, 0, 0.08),
0 4px 4px -2px rgba(0, 0, 0, 0.08),
0 8px 8px -4px rgba(0, 0, 0, 0.08),
0 16px 16px -8px rgba(0, 0, 0, 0.08);
--badge-transition-duration: 0.2s;
--badge-transition-easing: cubic-bezier(0.16, 1, 0.32, 1);
--focus-color: #575ECF;
--focus-offset: 2px;
--focus-width: 2px;
position: fixed;
bottom: 12px;
right: 12px;
height: 24px;
display: flex;
align-items: center;
z-index: 1000000;
background-color: var(--badge-bg);
color: var(--badge-text);
border-radius: var(--badge-radius);
box-shadow: var(--badge-shadow);
font-size: 12px;
font-family: CameraPlainVariable, "CameraPlainVariable Fallback", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-weight: 400 !important;
text-transform: none !important;
font-feature-settings: normal !important;
transform: translateZ(0);
will-change: transform, opacity;
}
#lovable-badge-cta {
display: flex;
align-items: center;
gap: var(--badge-gap);
padding: 0 var(--badge-padding);
height: 100%;
color: inherit;
text-decoration: none;
white-space: nowrap;
border-radius: var(--badge-radius) 0 0 var(--badge-radius);
transition:
background-color var(--badge-transition-duration) ease,
color var(--badge-transition-duration) ease,
transform 0.1s ease;
}
#lovable-badge-cta:hover {
background: rgba(255, 255, 255, 0.04);
color: var(--badge-text-hover);
}
#lovable-badge-cta:active {
transform: scale(0.98);
}
#lovable-badge-cta:focus {
outline: none;
}
#lovable-badge-cta:focus-visible {
outline: var(--focus-width) solid var(--focus-color);
outline-offset: var(--focus-offset);
z-index: 1;
}
#lovable-badge-text {
line-height: 1;
}
#lovable-badge-divider {
width: 1px;
height: 24px;
background-color: rgba(255, 255, 255, 0.04);
flex-shrink: 0;
}
#lovable-badge-close {
width: 24px;
height: 24px;
min-width: 24px;
min-height: 24px;
cursor: pointer;
background: none;
border: none;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
border-radius: 0 var(--badge-radius) var(--badge-radius) 0;
flex-shrink: 0;
transition:
background-color var(--badge-transition-duration) ease,
transform 0.1s ease;
}
#lovable-badge-close:hover {
background: rgba(255, 255, 255, 0.04);
}
#lovable-badge-close:active {
transform: scale(0.92);
}
#lovable-badge-close:focus {
outline: none;
}
#lovable-badge-close:focus-visible {
outline: var(--focus-width) solid var(--focus-color);
outline-offset: calc(var(--focus-offset) * -1);
z-index: 1;
}
#lovable-badge-close svg path {
fill: var(--badge-text);
transition: fill var(--badge-transition-duration) ease;
}
#lovable-badge-close:hover svg path {
fill: var(--badge-text-hover);
}
@media (prefers-reduced-motion: reduce) {
#lovable-badge-cta,
#lovable-badge-close,
#lovable-badge-close svg path {
transition: none;
}
#lovable-badge-cta:active,
#lovable-badge-close:active {
transform: none;
}
}
@media (prefers-contrast: high) {
#lovable-badge {
--badge-bg: #000;
--badge-text: #fff;
--badge-text-hover: #fff;
border: 2px solid currentColor;
}
#lovable-badge-cta:focus-visible,
#lovable-badge-close:focus-visible {
outline-width: 3px;
}
}
</style>
<style type="text/css">:where(html[dir="ltr"]),:where([data-sonner-toaster][dir="ltr"]){--toast-icon-margin-start: -3px;--toast-icon-margin-end: 4px;--toast-svg-margin-start: -1px;--toast-svg-margin-end: 0px;--toast-button-margin-start: auto;--toast-button-margin-end: 0;--toast-close-button-start: 0;--toast-close-button-end: unset;--toast-close-button-transform: translate(-35%, -35%)}:where(html[dir="rtl"]),:where([data-sonner-toaster][dir="rtl"]){--toast-icon-margin-start: 4px;--toast-icon-margin-end: -3px;--toast-svg-margin-start: 0px;--toast-svg-margin-end: -1px;--toast-button-margin-start: 0;--toast-button-margin-end: auto;--toast-close-button-start: unset;--toast-close-button-end: 0;--toast-close-button-transform: translate(35%, -35%)}:where([data-sonner-toaster]){position:fixed;width:var(--width);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;--gray1: hsl(0, 0%, 99%);--gray2: hsl(0, 0%, 97.3%);--gray3: hsl(0, 0%, 95.1%);--gray4: hsl(0, 0%, 93%);--gray5: hsl(0, 0%, 90.9%);--gray6: hsl(0, 0%, 88.7%);--gray7: hsl(0, 0%, 85.8%);--gray8: hsl(0, 0%, 78%);--gray9: hsl(0, 0%, 56.1%);--gray10: hsl(0, 0%, 52.3%);--gray11: hsl(0, 0%, 43.5%);--gray12: hsl(0, 0%, 9%);--border-radius: 8px;box-sizing:border-box;padding:0;margin:0;list-style:none;outline:none;z-index:999999999;transition:transform .4s ease}:where([data-sonner-toaster][data-lifted="true"]){transform:translateY(-10px)}@media (hover: none) and (pointer: coarse){:where([data-sonner-toaster][data-lifted="true"]){transform:none}}:where([data-sonner-toaster][data-x-position="right"]){right:var(--offset-right)}:where([data-sonner-toaster][data-x-position="left"]){left:var(--offset-left)}:where([data-sonner-toaster][data-x-position="center"]){left:50%;transform:translate(-50%)}:where([data-sonner-toaster][data-y-position="top"]){top:var(--offset-top)}:where([data-sonner-toaster][data-y-position="bottom"]){bottom:var(--offset-bottom)}:where([data-sonner-toast]){--y: translateY(100%);--lift-amount: calc(var(--lift) * var(--gap));z-index:var(--z-index);position:absolute;opacity:0;transform:var(--y);filter:blur(0);touch-action:none;transition:transform .4s,opacity .4s,height .4s,box-shadow .2s;box-sizing:border-box;outline:none;overflow-wrap:anywhere}:where([data-sonner-toast][data-styled="true"]){padding:16px;background:var(--normal-bg);border:1px solid var(--normal-border);color:var(--normal-text);border-radius:var(--border-radius);box-shadow:0 4px 12px #0000001a;width:var(--width);font-size:13px;display:flex;align-items:center;gap:6px}:where([data-sonner-toast]:focus-visible){box-shadow:0 4px 12px #0000001a,0 0 0 2px #0003}:where([data-sonner-toast][data-y-position="top"]){top:0;--y: translateY(-100%);--lift: 1;--lift-amount: calc(1 * var(--gap))}:where([data-sonner-toast][data-y-position="bottom"]){bottom:0;--y: translateY(100%);--lift: -1;--lift-amount: calc(var(--lift) * var(--gap))}:where([data-sonner-toast]) :where([data-description]){font-weight:400;line-height:1.4;color:inherit}:where([data-sonner-toast]) :where([data-title]){font-weight:500;line-height:1.5;color:inherit}:where([data-sonner-toast]) :where([data-icon]){display:flex;height:16px;width:16px;position:relative;justify-content:flex-start;align-items:center;flex-shrink:0;margin-left:var(--toast-icon-margin-start);margin-right:var(--toast-icon-margin-end)}:where([data-sonner-toast][data-promise="true"]) :where([data-icon])>svg{opacity:0;transform:scale(.8);transform-origin:center;animation:sonner-fade-in .3s ease forwards}:where([data-sonner-toast]) :where([data-icon])>*{flex-shrink:0}:where([data-sonner-toast]) :where([data-icon]) svg{margin-left:var(--toast-svg-margin-start);margin-right:var(--toast-svg-margin-end)}:where([data-sonner-toast]) :where([data-content]){display:flex;flex-direction:column;gap:2px}[data-sonner-toast][data-styled=true] [data-button]{border-radius:4px;padding-left:8px;padding-right:8px;height:24px;font-size:12px;color:var(--normal-bg);background:var(--normal-text);margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end);border:none;cursor:pointer;outline:none;display:flex;align-items:center;flex-shrink:0;transition:opacity .4s,box-shadow .2s}:where([data-sonner-toast]) :where([data-button]):focus-visible{box-shadow:0 0 0 2px #0006}:where([data-sonner-toast]) :where([data-button]):first-of-type{margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end)}:where([data-sonner-toast]) :where([data-cancel]){color:var(--normal-text);background:rgba(0,0,0,.08)}:where([data-sonner-toast][data-theme="dark"]) :where([data-cancel]){background:rgba(255,255,255,.3)}:where([data-sonner-toast]) :where([data-close-button]){position:absolute;left:var(--toast-close-button-start);right:var(--toast-close-button-end);top:0;height:20px;width:20px;display:flex;justify-content:center;align-items:center;padding:0;color:var(--gray12);border:1px solid var(--gray4);transform:var(--toast-close-button-transform);border-radius:50%;cursor:pointer;z-index:1;transition:opacity .1s,background .2s,border-color .2s}[data-sonner-toast] [data-close-button]{background:var(--gray1)}:where([data-sonner-toast]) :where([data-close-button]):focus-visible{box-shadow:0 4px 12px #0000001a,0 0 0 2px #0003}:where([data-sonner-toast]) :where([data-disabled="true"]){cursor:not-allowed}:where([data-sonner-toast]):hover :where([data-close-button]):hover{background:var(--gray2);border-color:var(--gray5)}:where([data-sonner-toast][data-swiping="true"]):before{content:"";position:absolute;left:-50%;right:-50%;height:100%;z-index:-1}:where([data-sonner-toast][data-y-position="top"][data-swiping="true"]):before{bottom:50%;transform:scaleY(3) translateY(50%)}:where([data-sonner-toast][data-y-position="bottom"][data-swiping="true"]):before{top:50%;transform:scaleY(3) translateY(-50%)}:where([data-sonner-toast][data-swiping="false"][data-removed="true"]):before{content:"";position:absolute;inset:0;transform:scaleY(2)}:where([data-sonner-toast]):after{content:"";position:absolute;left:0;height:calc(var(--gap) + 1px);bottom:100%;width:100%}:where([data-sonner-toast][data-mounted="true"]){--y: translateY(0);opacity:1}:where([data-sonner-toast][data-expanded="false"][data-front="false"]){--scale: var(--toasts-before) * .05 + 1;--y: translateY(calc(var(--lift-amount) * var(--toasts-before))) scale(calc(-1 * var(--scale)));height:var(--front-toast-height)}:where([data-sonner-toast])>*{transition:opacity .4s}:where([data-sonner-toast][data-expanded="false"][data-front="false"][data-styled="true"])>*{opacity:0}:where([data-sonner-toast][data-visible="false"]){opacity:0;pointer-events:none}:where([data-sonner-toast][data-mounted="true"][data-expanded="true"]){--y: translateY(calc(var(--lift) * var(--offset)));height:var(--initial-height)}:where([data-sonner-toast][data-removed="true"][data-front="true"][data-swipe-out="false"]){--y: translateY(calc(var(--lift) * -100%));opacity:0}:where([data-sonner-toast][data-removed="true"][data-front="false"][data-swipe-out="false"][data-expanded="true"]){--y: translateY(calc(var(--lift) * var(--offset) + var(--lift) * -100%));opacity:0}:where([data-sonner-toast][data-removed="true"][data-front="false"][data-swipe-out="false"][data-expanded="false"]){--y: translateY(40%);opacity:0;transition:transform .5s,opacity .2s}:where([data-sonner-toast][data-removed="true"][data-front="false"]):before{height:calc(var(--initial-height) + 20%)}[data-sonner-toast][data-swiping=true]{transform:var(--y) translateY(var(--swipe-amount-y, 0px)) translate(var(--swipe-amount-x, 0px));transition:none}[data-sonner-toast][data-swiped=true]{user-select:none}[data-sonner-toast][data-swipe-out=true][data-y-position=bottom],[data-sonner-toast][data-swipe-out=true][data-y-position=top]{animation-duration:.2s;animation-timing-function:ease-out;animation-fill-mode:forwards}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=left]{animation-name:swipe-out-left}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=right]{animation-name:swipe-out-right}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=up]{animation-name:swipe-out-up}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=down]{animation-name:swipe-out-down}@keyframes swipe-out-left{0%{transform:var(--y) translate(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translate(calc(var(--swipe-amount-x) - 100%));opacity:0}}@keyframes swipe-out-right{0%{transform:var(--y) translate(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translate(calc(var(--swipe-amount-x) + 100%));opacity:0}}@keyframes swipe-out-up{0%{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) - 100%));opacity:0}}@keyframes swipe-out-down{0%{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) + 100%));opacity:0}}@media (max-width: 600px){[data-sonner-toaster]{position:fixed;right:var(--mobile-offset-right);left:var(--mobile-offset-left);width:100%}[data-sonner-toaster][dir=rtl]{left:calc(var(--mobile-offset-left) * -1)}[data-sonner-toaster] [data-sonner-toast]{left:0;right:0;width:calc(100% - var(--mobile-offset-left) * 2)}[data-sonner-toaster][data-x-position=left]{left:var(--mobile-offset-left)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--mobile-offset-bottom)}[data-sonner-toaster][data-y-position=top]{top:var(--mobile-offset-top)}[data-sonner-toaster][data-x-position=center]{left:var(--mobile-offset-left);right:var(--mobile-offset-right);transform:none}}[data-sonner-toaster][data-theme=light]{--normal-bg: #fff;--normal-border: var(--gray4);--normal-text: var(--gray12);--success-bg: hsl(143, 85%, 96%);--success-border: hsl(145, 92%, 91%);--success-text: hsl(140, 100%, 27%);--info-bg: hsl(208, 100%, 97%);--info-border: hsl(221, 91%, 91%);--info-text: hsl(210, 92%, 45%);--warning-bg: hsl(49, 100%, 97%);--warning-border: hsl(49, 91%, 91%);--warning-text: hsl(31, 92%, 45%);--error-bg: hsl(359, 100%, 97%);--error-border: hsl(359, 100%, 94%);--error-text: hsl(360, 100%, 45%)}[data-sonner-toaster][data-theme=light] [data-sonner-toast][data-invert=true]{--normal-bg: #000;--normal-border: hsl(0, 0%, 20%);--normal-text: var(--gray1)}[data-sonner-toaster][data-theme=dark] [data-sonner-toast][data-invert=true]{--normal-bg: #fff;--normal-border: var(--gray3);--normal-text: var(--gray12)}[data-sonner-toaster][data-theme=dark]{--normal-bg: #000;--normal-bg-hover: hsl(0, 0%, 12%);--normal-border: hsl(0, 0%, 20%);--normal-border-hover: hsl(0, 0%, 25%);--normal-text: var(--gray1);--success-bg: hsl(150, 100%, 6%);--success-border: hsl(147, 100%, 12%);--success-text: hsl(150, 86%, 65%);--info-bg: hsl(215, 100%, 6%);--info-border: hsl(223, 100%, 12%);--info-text: hsl(216, 87%, 65%);--warning-bg: hsl(64, 100%, 6%);--warning-border: hsl(60, 100%, 12%);--warning-text: hsl(46, 87%, 65%);--error-bg: hsl(358, 76%, 10%);--error-border: hsl(357, 89%, 16%);--error-text: hsl(358, 100%, 81%)}[data-sonner-toaster][data-theme=dark] [data-sonner-toast] [data-close-button]{background:var(--normal-bg);border-color:var(--normal-border);color:var(--normal-text)}[data-sonner-toaster][data-theme=dark] [data-sonner-toast] [data-close-button]:hover{background:var(--normal-bg-hover);border-color:var(--normal-border-hover)}[data-rich-colors=true][data-sonner-toast][data-type=success],[data-rich-colors=true][data-sonner-toast][data-type=success] [data-close-button]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=info],[data-rich-colors=true][data-sonner-toast][data-type=info] [data-close-button]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning],[data-rich-colors=true][data-sonner-toast][data-type=warning] [data-close-button]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=error],[data-rich-colors=true][data-sonner-toast][data-type=error] [data-close-button]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}.sonner-loading-wrapper{--size: 16px;height:var(--size);width:var(--size);position:absolute;inset:0;z-index:10}.sonner-loading-wrapper[data-visible=false]{transform-origin:center;animation:sonner-fade-out .2s ease forwards}.sonner-spinner{position:relative;top:50%;left:50%;height:var(--size);width:var(--size)}.sonner-loading-bar{animation:sonner-spin 1.2s linear infinite;background:var(--gray11);border-radius:6px;height:8%;left:-10%;position:absolute;top:-3.9%;width:24%}.sonner-loading-bar:nth-child(1){animation-delay:-1.2s;transform:rotate(.0001deg) translate(146%)}.sonner-loading-bar:nth-child(2){animation-delay:-1.1s;transform:rotate(30deg) translate(146%)}.sonner-loading-bar:nth-child(3){animation-delay:-1s;transform:rotate(60deg) translate(146%)}.sonner-loading-bar:nth-child(4){animation-delay:-.9s;transform:rotate(90deg) translate(146%)}.sonner-loading-bar:nth-child(5){animation-delay:-.8s;transform:rotate(120deg) translate(146%)}.sonner-loading-bar:nth-child(6){animation-delay:-.7s;transform:rotate(150deg) translate(146%)}.sonner-loading-bar:nth-child(7){animation-delay:-.6s;transform:rotate(180deg) translate(146%)}.sonner-loading-bar:nth-child(8){animation-delay:-.5s;transform:rotate(210deg) translate(146%)}.sonner-loading-bar:nth-child(9){animation-delay:-.4s;transform:rotate(240deg) translate(146%)}.sonner-loading-bar:nth-child(10){animation-delay:-.3s;transform:rotate(270deg) translate(146%)}.sonner-loading-bar:nth-child(11){animation-delay:-.2s;transform:rotate(300deg) translate(146%)}.sonner-loading-bar:nth-child(12){animation-delay:-.1s;transform:rotate(330deg) translate(146%)}@keyframes sonner-fade-in{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes sonner-fade-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.8)}}@keyframes sonner-spin{0%{opacity:1}to{opacity:.15}}@media (prefers-reduced-motion){[data-sonner-toast],[data-sonner-toast]>*,.sonner-loading-bar{transition:none!important;animation:none!important}}.sonner-loader{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;transition:opacity .2s,transform .2s}.sonner-loader[data-visible=false]{opacity:0;transform:scale(.8) translate(-50%,-50%)}
</style></head>
<body>
<div id="root"><div role="region" aria-label="Notifications (F8)" tabindex="-1" style="pointer-events: none;"><ol tabindex="-1" class="fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]"></ol></div><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><div class="flex h-screen w-full overflow-hidden bg-background"><div class="flex flex-col bg-sidebar border-r border-sidebar-border w-60 flex-shrink-0 animate-fade-in"><div class="flex items-center justify-between px-4 py-3 border-b border-sidebar-border"><div><h1 class="text-sm font-semibold text-foreground tracking-tight">Candle Annotator</h1><p class="text-[10px] text-muted-foreground">Chart annotation tool</p></div><div class="flex items-center gap-1"><button class="p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-secondary transition-colors" title="Toggle theme"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-moon w-3.5 h-3.5"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path></svg></button><button class="p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-secondary transition-colors"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-panel-left-close w-4 h-4"><rect width="18" height="18" x="3" y="3" rx="2"></rect><path d="M9 3v18"></path><path d="m16 15-3-3 3-3"></path></svg></button></div></div><div class="px-3 py-2 border-b border-sidebar-border"><button class="w-full flex items-center justify-between px-2 py-1.5 text-xs rounded bg-secondary/50 hover:bg-secondary text-foreground transition-colors"><span class="font-mono font-medium truncate">EURUSD</span><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down w-3 h-3 transition-transform"><path d="m6 9 6 6 6-6"></path></svg></button></div><div class="px-3 py-2 border-b border-sidebar-border"><input type="file" accept=".csv" class="hidden"><button class="w-full flex items-center justify-center gap-1.5 px-2 py-1.5 text-xs rounded border border-border bg-secondary/30 hover:bg-secondary text-muted-foreground hover:text-foreground transition-colors"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-upload w-3 h-3"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" x2="12" y1="3" y2="15"></line></svg> Upload CSV</button></div><div class="px-3 py-2 border-b border-sidebar-border space-y-1"><p class="text-[10px] font-medium text-muted-foreground uppercase tracking-wider mb-1">Tools</p><div class="flex gap-1"><button class="flex-1 flex items-center justify-center gap-1 px-1.5 py-1.5 text-xs rounded transition-colors bg-secondary/50 hover:bg-secondary text-muted-foreground hover:text-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rectangle-horizontal w-3.5 h-3.5"><rect width="20" height="12" x="2" y="6" rx="2"></rect></svg> Rect</button><button class="flex-1 flex items-center justify-center gap-1 px-1.5 py-1.5 text-xs rounded transition-colors bg-secondary/50 hover:bg-secondary text-muted-foreground hover:text-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layers w-3.5 h-3.5"><path d="m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z"></path><path d="m22 17.65-9.17 4.16a2 2 0 0 1-1.66 0L2 17.65"></path><path d="m22 12.65-9.17 4.16a2 2 0 0 1-1.66 0L2 12.65"></path></svg> Span</button><button class="flex-1 flex items-center justify-center gap-1 px-1.5 py-1.5 text-xs rounded transition-colors bg-secondary/50 hover:bg-secondary text-muted-foreground hover:text-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-minus w-3.5 h-3.5"><path d="M5 12h14"></path></svg> Line</button><button class="flex-1 flex items-center justify-center gap-1 px-1.5 py-1.5 text-xs rounded transition-colors bg-secondary/50 hover:bg-secondary text-muted-foreground hover:text-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash2 w-3.5 h-3.5"><path d="M3 6h18"></path><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path><line x1="10" x2="10" y1="11" y2="17"></line><line x1="14" x2="14" y1="11" y2="17"></line></svg> Del</button></div><div class="flex gap-1 pt-1"><button class="flex-1 h-6 rounded-sm border-2 transition-all opacity-60 hover:opacity-100" style="background-color: rgb(239, 68, 68); border-color: transparent; --tw-ring-color: #ef4444;" title="red"></button><button class="flex-1 h-6 rounded-sm border-2 transition-all opacity-60 hover:opacity-100" style="background-color: rgb(34, 197, 94); border-color: transparent; --tw-ring-color: #22c55e;" title="green"></button><button class="flex-1 h-6 rounded-sm border-2 transition-all scale-105 ring-1 ring-offset-1 ring-offset-sidebar" style="background-color: rgb(59, 130, 246); border-color: rgb(59, 130, 246); --tw-ring-color: #3b82f6;" title="blue"></button><button class="flex-1 h-6 rounded-sm border-2 transition-all opacity-60 hover:opacity-100" style="background-color: rgb(245, 158, 11); border-color: transparent; --tw-ring-color: #f59e0b;" title="orange"></button><button class="flex-1 h-6 rounded-sm border-2 transition-all opacity-60 hover:opacity-100" style="background-color: rgb(139, 92, 246); border-color: transparent; --tw-ring-color: #8b5cf6;" title="purple"></button></div></div><div class="flex-1 overflow-y-auto scrollbar-thin px-3 py-2 min-h-0"><button class="w-full flex items-center justify-between py-1"><span class="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">Annotations (0)</span><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down w-3 h-3 text-muted-foreground"><path d="m6 9 6 6 6-6"></path></svg></button><div class="space-y-1 mt-1"><p class="text-[10px] text-muted-foreground text-center py-3">No annotations yet.</p></div></div><div class="px-3 py-2 border-t border-sidebar-border"><button class="w-full flex items-center justify-between py-1"><div class="flex items-center gap-1.5"><div class="w-1.5 h-1.5 rounded-full bg-candle-bull" style="background-color: rgb(34, 197, 94);"></div><span class="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">Predictions</span></div><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down w-3 h-3 text-muted-foreground"><path d="m6 9 6 6 6-6"></path></svg></button><div class="mt-1 space-y-2"><div class="p-2 bg-secondary/30 rounded text-[10px] space-y-1"><div class="flex justify-between"><span class="text-muted-foreground">Model:</span><span class="font-mono text-foreground">best_model</span></div><div class="flex justify-between"><span class="text-muted-foreground">Version:</span><span class="font-mono text-foreground">local</span></div><div class="flex justify-between"><span class="text-muted-foreground">Type:</span><span class="text-foreground">unknown</span></div></div><div class="flex gap-1"><button class="flex-1 px-2 py-1.5 text-[10px] bg-primary text-primary-foreground rounded hover:opacity-90 transition-opacity">Run on Visible</button><button class="flex-1 px-2 py-1.5 text-[10px] bg-secondary text-secondary-foreground rounded hover:opacity-90 transition-opacity">Predict All</button></div><div><div class="flex justify-between items-center mb-1"><label class="text-[10px] text-muted-foreground">Confidence</label><span class="text-[10px] font-mono text-foreground">50%</span></div><input type="range" min="0" max="100" class="w-full h-1 bg-secondary rounded-lg appearance-none cursor-pointer accent-primary" value="50"></div><div class="flex items-center justify-between"><label class="text-[10px] text-muted-foreground">Show on chart</label><button class="px-2 py-0.5 text-[10px] rounded transition-colors bg-primary/20 text-primary">On</button></div><p class="text-[10px] text-muted-foreground text-center py-2">No predictions loaded.</p></div></div><div class="px-3 py-2 border-t border-sidebar-border"><button class="w-full flex items-center justify-center gap-1.5 px-2 py-1.5 text-xs rounded bg-primary/10 hover:bg-primary/20 text-primary transition-colors"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-download w-3 h-3"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" x2="12" y1="15" y2="3"></line></svg> Export JSON</button></div></div><div class="flex-1 flex flex-col min-w-0"><div class="flex items-center justify-between px-3 py-1.5 border-b border-border bg-card/50"><div class="flex items-center gap-3"><span class="font-mono text-sm font-semibold text-foreground">EURUSD</span><span class="text-[10px] text-muted-foreground font-mono">200 candles</span></div><div class="flex items-center gap-2 text-[10px] text-muted-foreground font-mono"><span class="px-1.5 py-0.5 rounded bg-secondary/50">R Rect</span><span class="px-1.5 py-0.5 rounded bg-secondary/50">S Span</span><span class="px-1.5 py-0.5 rounded bg-secondary/50">L Line</span><span class="px-1.5 py-0.5 rounded bg-secondary/50">D Del</span><span class="px-1.5 py-0.5 rounded bg-secondary/50">T Theme</span><span class="px-1.5 py-0.5 rounded bg-secondary/50">B Sidebar</span></div></div><div class="flex-1 min-h-0"><div class="relative w-full h-full overflow-hidden"><canvas style="width: 1800px; height: 964px;" class="cursor-grab" width="2250" height="1205"></canvas></div></div></div></div></div></script>
<aside id="lovable-badge" role="complementary" dir="ltr" lang="en" aria-label="Edit with Lovable">
<a id="lovable-badge-cta" target="_blank" href="https://lovable.dev/projects/5c09681b-6d88-4768-8cd9-10f44aca2c2b?utm_source=lovable-badge" rel="noopener" aria-label="Edit with Lovable">
<span id="lovable-badge-text">Edit with</span>
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="16" fill="none" viewBox="0 0 52 16">
<path fill="#FCFBF8" fill-rule="evenodd" d="M20.318 5.25c.643 0 1.206.14 1.69.418a2.81 2.81 0 0 1 1.118 1.191c.266.513.4 1.115.4 1.807s-.134 1.296-.4 1.812a2.81 2.81 0 0 1-1.118 1.193c-.484.278-1.047.418-1.69.418s-1.208-.14-1.695-.418a2.85 2.85 0 0 1-1.125-1.193c-.262-.516-.393-1.12-.393-1.812s.131-1.294.393-1.807a2.848 2.848 0 0 1 1.125-1.191c.487-.279 1.052-.418 1.695-.418Zm0 1.425c-.27 0-.504.076-.7.228-.193.147-.34.37-.443.67-.102.295-.153.66-.153 1.093 0 .435.05.801.153 1.1.102.3.25.524.443.676.196.147.43.22.7.22.27 0 .502-.073.694-.22.193-.152.341-.375.443-.67.103-.299.153-.667.153-1.106 0-.65-.112-1.145-.337-1.481a1.08 1.08 0 0 0-.953-.51ZM32.7 5.25c.61 0 1.127.1 1.549.3.422.197.74.48.953.849.217.368.325.809.325 1.32v2.704c0 .29.02.562.062.812.044.245.108.4.19.466V12h-1.935a5.895 5.895 0 0 1-.105-.684 7.745 7.745 0 0 1-.02-.228 2.293 2.293 0 0 1-.151.203c-.205.242-.47.437-.793.584-.32.143-.685.215-1.094.215-.406 0-.77-.08-1.094-.24a1.845 1.845 0 0 1-.756-.682 1.984 1.984 0 0 1-.27-1.045c0-.606.178-1.069.535-1.388.356-.324.87-.534 1.542-.633l1.125-.16c.225-.032.403-.074.534-.123a.622.622 0 0 0 .288-.196.549.549 0 0 0 .093-.327.65.65 0 0 0-.11-.367.702.702 0 0 0-.32-.27c-.14-.07-.31-.105-.51-.105-.32 0-.576.083-.768.251-.193.164-.298.39-.314.676h-1.923c.016-.434.147-.82.393-1.155.25-.34.596-.604 1.039-.792.442-.189.954-.283 1.535-.283Zm.99 3.498a.98.98 0 0 1-.215.14 2.49 2.49 0 0 1-.584.178l-.473.092c-.315.061-.553.156-.713.283-.155.127-.233.305-.233.534 0 .23.084.412.252.547.168.135.383.203.645.203s.494-.058.694-.173c.201-.118.355-.282.461-.49.11-.21.166-.448.166-.714v-.6Zm4.526-2.375c.065-.125.138-.243.221-.349.197-.25.437-.44.719-.571.282-.135.6-.203.952-.203.528 0 .988.138 1.377.412.389.275.688.67.896 1.186.21.512.314 1.12.314 1.824 0 .7-.107 1.309-.32 1.825-.213.512-.518.906-.915 1.18-.393.275-.854.412-1.383.412-.352 0-.667-.062-.946-.184a1.832 1.832 0 0 1-.7-.554 2.2 2.2 0 0 1-.234-.383V12h-1.843V3h1.862v3.373Zm1.284.296c-.274 0-.51.085-.707.253-.192.163-.338.397-.436.7a3.376 3.376 0 0 0-.148 1.05c0 .406.05.759.148 1.058.098.299.243.53.436.694.197.164.433.246.707.246.279 0 .512-.082.7-.246.193-.164.336-.395.43-.694.099-.3.148-.652.148-1.058 0-.405-.05-.757-.147-1.056-.095-.299-.238-.53-.43-.694a1.015 1.015 0 0 0-.7-.253Zm9.416-1.419c.602 0 1.136.131 1.604.393.466.262.829.643 1.086 1.143.263.5.394 1.097.394 1.794 0 .25-.002.449-.006.596H47.51c.018.288.071.538.164.75a1.3 1.3 0 0 0 .491.596c.214.13.465.196.757.196.319 0 .583-.082.792-.246.209-.167.34-.403.393-.706h1.862a2.48 2.48 0 0 1-.485 1.235 2.54 2.54 0 0 1-1.051.805c-.439.188-.949.283-1.53.283-.655 0-1.225-.125-1.708-.375a2.672 2.672 0 0 1-1.13-1.143c-.267-.508-.4-1.137-.4-1.887 0-.712.14-1.327.418-1.843a2.86 2.86 0 0 1 1.155-1.186c.491-.27 1.051-.405 1.678-.405Zm-.044 1.345c-.274 0-.516.068-.725.203a1.29 1.29 0 0 0-.479.59 2.045 2.045 0 0 0-.132.498h2.562a1.873 1.873 0 0 0-.138-.602 1.061 1.061 0 0 0-.418-.516 1.243 1.243 0 0 0-.67-.173Z" clip-rule="evenodd"></path>
<path fill="#FCFBF8" d="m26.605 9.995 1.342-4.566h1.924L27.628 12h-2.07l-2.33-6.57h1.98l1.397 4.565Zm-13.013.143h2.256c1.632 0 1.421 1.837 1.418 1.861h-5.603V3h1.93v7.138Zm31.516 1.861h-1.862V3h1.862v8.999Z"></path>
<path fill="url(#a)" fill-rule="evenodd" d="M2.7 3c1.492 0 2.7 1.192 2.7 2.663v1.012h.9c1.49 0 2.7 1.192 2.7 2.662S7.791 12 6.3 12H0V5.663C0 4.193 1.209 3 2.7 3Z" clip-rule="evenodd"></path>
<defs>
<radialGradient id="a" cx="0" cy="0" r="1" gradientTransform="matrix(-1.54236 7.07838 -10.231 -2.15602 4.627 5.022)" gradientUnits="userSpaceOnUse">
<stop offset=".106" stop-color="#FE7B02"></stop>
<stop offset=".394" stop-color="#FE3F21"></stop>
<stop offset=".608" stop-color="#F858BC"></stop>
<stop offset=".929" stop-color="#575ECF"></stop>
</radialGradient>
</defs>
</svg>
</a>
<span id="lovable-badge-divider" aria-hidden="true"></span>
<button id="lovable-badge-close" aria-label="Dismiss" title="Dismiss" type="button">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16" aria-hidden="true">
<path d="M10.646 4.646a.5.5 0 1 1 .707.708L8.707 8l2.646 2.646a.5.5 0 1 1-.707.707L8 8.707l-2.646 2.646a.5.5 0 1 1-.708-.707L7.293 8 4.646 5.354a.5.5 0 1 1 .708-.708L8 7.293l2.646-2.647Z"></path>
</svg>
</button>
</aside>
<script>
// Don't show the lovable-badge if the page is in an iframe or if it's being rendered by puppeteer (screenshot service)
if (window.self !== window.top || navigator.userAgent.includes('puppeteer')) {
// the page is in an iframe
var badge = document.getElementById('lovable-badge');
if (badge) {
badge.style.display = 'none';
}
}
// Add click event listener to close button with animation
var closeButton = document.getElementById('lovable-badge-close');
if (closeButton) {
closeButton.addEventListener('click', function(event) {
event.preventDefault();
event.stopPropagation();
var badge = document.getElementById('lovable-badge');
if (badge) {
badge.classList.add('closing');
setTimeout(function() {
if (badge) {
badge.style.display = 'none';
}
}, 240);
}
});
}
</script>
</body></html>