made-refine 0.2.20 → 0.3.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/index.mjs CHANGED
@@ -7,7 +7,7 @@ import * as React8 from "react";
7
7
  import * as React from "react";
8
8
 
9
9
  // dist/styles.css
10
- var styles_default = '/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--font-weight-thin:100;--font-weight-extralight:200;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-weight-black:900;--leading-relaxed:1.625;--radius-sm:calc(.5rem - 4px);--radius-md:calc(.5rem - 2px);--radius-xl:.75rem;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-border:#e6e6e6;--color-ring:#262626;--color-background:#fff;--color-foreground:#171717;--color-primary:#171717;--color-primary-foreground:#fafafa;--color-secondary-foreground:#171717;--color-destructive:#ef4444;--color-destructive-foreground:#fafafa;--color-muted:#f2f2f2;--color-muted-foreground:#737373;--color-popover-foreground:#171717}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root,:host{color-scheme:light;color:var(--color-foreground)}@media (prefers-color-scheme:dark){:root,:host(:not([data-theme])),:host([data-theme=system]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}}:host([data-theme=dark]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}*,:before,:after{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:var(--color-background);--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;border-color:var(--color-border)}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing)*0)}.top-1\\/2{top:50%}.left-1\\.5{left:calc(var(--spacing)*1.5)}.left-1\\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-3{left:calc(var(--spacing)*3)}.z-\\[99990\\]{z-index:99990}.z-\\[99991\\]{z-index:99991}.z-\\[99998\\]{z-index:99998}.z-\\[99999\\]{z-index:99999}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-4{margin:calc(var(--spacing)*4)}.mx-0\\.5{margin-inline:calc(var(--spacing)*.5)}.mx-2{margin-inline:calc(var(--spacing)*2)}.my-0\\.5{margin-block:calc(var(--spacing)*.5)}.my-1{margin-block:calc(var(--spacing)*1)}.mt-0{margin-top:calc(var(--spacing)*0)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2\\.5{margin-top:calc(var(--spacing)*2.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.ml-0{margin-left:calc(var(--spacing)*0)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.block{display:block}.contents{display:contents}.flex{display:flex}.flow-root{display:flow-root}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.inline-grid{display:inline-grid}.list-item{display:list-item}.size-1{width:calc(var(--spacing)*1);height:calc(var(--spacing)*1)}.size-2\\.5{width:calc(var(--spacing)*2.5);height:calc(var(--spacing)*2.5)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-full{width:100%;height:100%}.h-0\\.5{height:calc(var(--spacing)*.5)}.h-2{height:calc(var(--spacing)*2)}.h-3\\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-\\[150px\\]{height:150px}.h-auto{height:auto}.h-fit{height:fit-content}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-\\[240px\\]{max-height:240px}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\\[18px\\]{min-height:18px}.w-0\\.5{width:calc(var(--spacing)*.5)}.w-2{width:calc(var(--spacing)*2)}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-14{width:calc(var(--spacing)*14)}.w-\\[1\\.5px\\]{width:1.5px}.w-\\[60px\\]{width:60px}.w-\\[68px\\]{width:68px}.w-\\[180px\\]{width:180px}.w-\\[200px\\]{width:200px}.w-\\[240px\\]{width:240px}.w-\\[260px\\]{width:260px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-\\[18px\\]{min-width:18px}.min-w-\\[20px\\]{min-width:20px}.min-w-\\[100px\\]{min-width:100px}.min-w-\\[120px\\]{min-width:120px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.origin-\\(--transform-origin\\){transform-origin:var(--transform-origin)}.-translate-x-1\\/2{--tw-translate-x:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.\\[appearance\\:textfield\\]{appearance:textfield}.appearance-none{appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\\[0fr\\]{grid-template-columns:0fr}.grid-cols-\\[1fr\\]{grid-template-columns:1fr}.grid-rows-\\[0fr\\]{grid-template-rows:0fr}.grid-rows-\\[1fr\\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-around{justify-content:space-around}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-evenly{justify-content:space-evenly}.justify-start{justify-content:flex-start}.gap-0\\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-\\[2px\\]{gap:2px}.gap-\\[4px\\]{gap:4px}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-hidden{overflow-y:hidden}.rounded{border-radius:.25rem}.rounded-\\[6px\\]{border-radius:6px}.rounded-\\[8px\\]{border-radius:8px}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-tl{border-top-left-radius:.25rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-bl{border-bottom-left-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-dotted{--tw-border-style:dotted;border-style:dotted}.border-double{--tw-border-style:double;border-style:double}.border-none{--tw-border-style:none;border-style:none}.border-solid{--tw-border-style:solid;border-style:solid}.\\[border-top-style\\:solid\\]{border-top-style:solid}.\\[border-right-style\\:dashed\\]{border-right-style:dashed}.\\[border-bottom-style\\:dashed\\]{border-bottom-style:dashed}.\\[border-bottom-style\\:dotted\\]{border-bottom-style:dotted}.\\[border-bottom-style\\:solid\\]{border-bottom-style:solid}.\\[border-left-style\\:double\\]{border-left-style:double}.\\[border-left-style\\:solid\\]{border-left-style:solid}.border-border{border-color:var(--color-border)}.border-border\\/30{border-color:#e6e6e64d}@supports (color:color-mix(in lab, red, red)){.border-border\\/30{border-color:color-mix(in oklab,var(--color-border)30%,transparent)}}.border-border\\/50{border-color:#e6e6e680}@supports (color:color-mix(in lab, red, red)){.border-border\\/50{border-color:color-mix(in oklab,var(--color-border)50%,transparent)}}.border-foreground\\/10{border-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.border-foreground\\/10{border-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.border-transparent{border-color:#0000}.border-white{border-color:var(--color-white)}.bg-\\[canvas\\]{background-color:canvas}.bg-background{background-color:var(--color-background)}.bg-background\\/85{background-color:#ffffffd9}@supports (color:color-mix(in lab, red, red)){.bg-background\\/85{background-color:color-mix(in oklab,var(--color-background)85%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-border{background-color:var(--color-border)}.bg-destructive{background-color:var(--color-destructive)}.bg-foreground{background-color:var(--color-foreground)}.bg-foreground\\/25{background-color:#17171740}@supports (color:color-mix(in lab, red, red)){.bg-foreground\\/25{background-color:color-mix(in oklab,var(--color-foreground)25%,transparent)}}.bg-muted{background-color:var(--color-muted)}.bg-muted-foreground\\/30{background-color:#7373734d}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\\/30{background-color:color-mix(in oklab,var(--color-muted-foreground)30%,transparent)}}.bg-primary{background-color:var(--color-primary)}.bg-transparent{background-color:#0000}.fill-border{fill:var(--color-border)}.p-0{padding:calc(var(--spacing)*0)}.p-0\\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-0{padding-block:calc(var(--spacing)*0)}.py-0\\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-3\\.5{padding-block:calc(var(--spacing)*3.5)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2\\.5{padding-top:calc(var(--spacing)*2.5)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pt-\\[13px\\]{padding-top:13px}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-1\\.5{padding-right:calc(var(--spacing)*1.5)}.pr-2{padding-right:calc(var(--spacing)*2)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-1\\.5{padding-bottom:calc(var(--spacing)*1.5)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pl-0{padding-left:calc(var(--spacing)*0)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-7{padding-left:calc(var(--spacing)*7)}.text-center{text-align:center}.text-justify{text-align:justify}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[7px\\]{font-size:7px}.text-\\[9px\\]{font-size:9px}.text-\\[10px\\]{font-size:10px}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-extralight{--tw-font-weight:var(--font-weight-extralight);font-weight:var(--font-weight-extralight)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.font-thin{--tw-font-weight:var(--font-weight-thin);font-weight:var(--font-weight-thin)}.\\[overflow-wrap\\:anywhere\\]{overflow-wrap:anywhere}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-background{color:var(--color-background)}.text-blue-500{color:var(--color-blue-500)}.text-destructive-foreground{color:var(--color-destructive-foreground)}.text-foreground{color:var(--color-foreground)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-muted-foreground{color:var(--color-muted-foreground)}.text-popover-foreground{color:var(--color-popover-foreground)}.text-primary{color:var(--color-primary)}.text-primary-foreground{color:var(--color-primary-foreground)}.text-red-500{color:var(--color-red-500)}.text-secondary-foreground{color:var(--color-secondary-foreground)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xs{--tw-shadow:0 1px var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.3\\)\\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_4px_6px_-1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[inset_0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-white{--tw-ring-color:var(--color-white)}.outline,.outline-1{outline-style:var(--tw-outline-style);outline-width:1px}.outline-border{outline-color:var(--color-border)}.outline-foreground\\/10{outline-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.outline-foreground\\/10{outline-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.outline-red-500\\/70{outline-color:#fb2c36b3}@supports (color:color-mix(in lab, red, red)){.outline-red-500\\/70{outline-color:color-mix(in oklab,var(--color-red-500)70%,transparent)}}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[color\\,background-color\\]{transition-property:color,background-color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[opacity\\,background-color\\,color\\]{transition-property:opacity,background-color,color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[transform\\,scale\\,opacity\\]{transition-property:transform,scale,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.animate-in{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\\[-ms-overflow-style\\:none\\]{-ms-overflow-style:none}.\\[scrollbar-width\\:none\\]{scrollbar-width:none}.duration-150{animation-duration:.15s}.duration-200{animation-duration:.2s}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{animation-timing-function:cubic-bezier(0,0,.2,1)}.fade-in-0{--tw-enter-opacity:0}.running{animation-play-state:running}.zoom-in-95{--tw-enter-scale:.95}@media (hover:hover){.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\\/pin\\:inline:is(:where(.group\\/pin):hover *){display:inline}}.file\\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\\:bg-transparent::file-selector-button{background-color:#0000}.file\\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\\:text-foreground::file-selector-button{color:var(--color-foreground)}.placeholder\\:text-muted-foreground::placeholder{color:var(--color-muted-foreground)}.placeholder\\:text-red-400::placeholder{color:var(--color-red-400)}.focus-within\\:ring-1:focus-within{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-within\\:ring-ring:focus-within{--tw-ring-color:var(--color-ring)}.focus-within\\:outline-none:focus-within{--tw-outline-style:none;outline-style:none}.focus-within\\:ring-inset:focus-within{--tw-ring-inset:inset}@media (hover:hover){.hover\\:scale-\\[1\\.67\\]:hover{scale:1.67}.hover\\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\\:bg-destructive\\/90:hover{background-color:#ef4444e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-destructive\\/90:hover{background-color:color-mix(in oklab,var(--color-destructive)90%,transparent)}}.hover\\:bg-foreground\\/80:hover{background-color:#171717cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-foreground\\/80:hover{background-color:color-mix(in oklab,var(--color-foreground)80%,transparent)}}.hover\\:bg-muted:hover{background-color:var(--color-muted)}.hover\\:bg-muted-foreground\\/10:hover{background-color:#7373731a}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted-foreground\\/10:hover{background-color:color-mix(in oklab,var(--color-muted-foreground)10%,transparent)}}.hover\\:bg-muted\\/50:hover{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/50:hover{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.hover\\:bg-muted\\/80:hover{background-color:#f2f2f2cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/80:hover{background-color:color-mix(in oklab,var(--color-muted)80%,transparent)}}.hover\\:bg-primary\\/90:hover{background-color:#171717e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-primary\\/90:hover{background-color:color-mix(in oklab,var(--color-primary)90%,transparent)}}.hover\\:text-foreground:hover{color:var(--color-foreground)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\:ring-ring:focus-visible{--tw-ring-color:var(--color-ring)}.focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-inset:focus-visible{--tw-ring-inset:inset}.active\\:cursor-grabbing:active{cursor:grabbing}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.data-ending-style\\:scale-90[data-ending-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-ending-style\\:opacity-0[data-ending-style]{opacity:0}.data-instant\\:transition-none[data-instant]{transition-property:none}.data-starting-style\\:scale-90[data-starting-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-starting-style\\:opacity-0[data-starting-style]{opacity:0}.data-\\[highlighted\\]\\:bg-muted[data-highlighted]{background-color:var(--color-muted)}.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.data-\\[highlighted\\]\\:text-foreground[data-highlighted]{color:var(--color-foreground)}@media (prefers-color-scheme:dark){.dark\\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dark\\:-outline-offset-1{outline-offset:calc(1px*-1)}}.\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.\\[\\&_svg\\]\\:size-3\\.5 svg{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.\\[\\&\\:\\:-webkit-inner-spin-button\\]\\:appearance-none::-webkit-inner-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-outer-spin-button\\]\\:appearance-none::-webkit-outer-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-scrollbar\\]\\:hidden::-webkit-scrollbar{display:none}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition:none;animation:none}}.lucide{stroke-width:1px}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes pulse{50%{opacity:.5}}';
10
+ var styles_default = '/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--font-weight-thin:100;--font-weight-extralight:200;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-weight-black:900;--leading-relaxed:1.625;--radius-sm:calc(.5rem - 4px);--radius-md:calc(.5rem - 2px);--radius-xl:.75rem;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-border:#e6e6e6;--color-ring:#262626;--color-background:#fff;--color-foreground:#171717;--color-primary:#171717;--color-primary-foreground:#fafafa;--color-secondary-foreground:#171717;--color-destructive:#ef4444;--color-destructive-foreground:#fafafa;--color-muted:#f2f2f2;--color-muted-foreground:#737373;--color-popover-foreground:#171717}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root,:host{color-scheme:light;color:var(--color-foreground)}@media (prefers-color-scheme:dark){:root,:host(:not([data-theme])),:host([data-theme=system]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}}:host([data-theme=dark]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}*,:before,:after{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:var(--color-background);--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;border-color:var(--color-border)}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing)*0)}.top-1\\/2{top:50%}.left-1\\.5{left:calc(var(--spacing)*1.5)}.left-1\\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-3{left:calc(var(--spacing)*3)}.isolate{isolation:isolate}.z-\\[99990\\]{z-index:99990}.z-\\[99991\\]{z-index:99991}.z-\\[99998\\]{z-index:99998}.z-\\[99999\\]{z-index:99999}.\\!container{width:100%!important}@media (min-width:40rem){.\\!container{max-width:40rem!important}}@media (min-width:48rem){.\\!container{max-width:48rem!important}}@media (min-width:64rem){.\\!container{max-width:64rem!important}}@media (min-width:80rem){.\\!container{max-width:80rem!important}}@media (min-width:96rem){.\\!container{max-width:96rem!important}}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-4{margin:calc(var(--spacing)*4)}.mx-0\\.5{margin-inline:calc(var(--spacing)*.5)}.mx-2{margin-inline:calc(var(--spacing)*2)}.my-0\\.5{margin-block:calc(var(--spacing)*.5)}.my-1{margin-block:calc(var(--spacing)*1)}.mt-0{margin-top:calc(var(--spacing)*0)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2\\.5{margin-top:calc(var(--spacing)*2.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.ml-0{margin-left:calc(var(--spacing)*0)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.block{display:block}.contents{display:contents}.flex{display:flex}.flow-root{display:flow-root}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.inline-grid{display:inline-grid}.list-item{display:list-item}.table{display:table}.size-1{width:calc(var(--spacing)*1);height:calc(var(--spacing)*1)}.size-2\\.5{width:calc(var(--spacing)*2.5);height:calc(var(--spacing)*2.5)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-full{width:100%;height:100%}.h-0\\.5{height:calc(var(--spacing)*.5)}.h-2{height:calc(var(--spacing)*2)}.h-3\\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-\\[150px\\]{height:150px}.h-auto{height:auto}.h-fit{height:fit-content}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-\\[240px\\]{max-height:240px}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\\[18px\\]{min-height:18px}.w-0\\.5{width:calc(var(--spacing)*.5)}.w-2{width:calc(var(--spacing)*2)}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-14{width:calc(var(--spacing)*14)}.w-\\[1\\.5px\\]{width:1.5px}.w-\\[60px\\]{width:60px}.w-\\[68px\\]{width:68px}.w-\\[180px\\]{width:180px}.w-\\[200px\\]{width:200px}.w-\\[240px\\]{width:240px}.w-\\[260px\\]{width:260px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-\\[18px\\]{min-width:18px}.min-w-\\[20px\\]{min-width:20px}.min-w-\\[100px\\]{min-width:100px}.min-w-\\[120px\\]{min-width:120px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.origin-\\(--transform-origin\\){transform-origin:var(--transform-origin)}.-translate-x-1\\/2{--tw-translate-x:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.rotate-45{rotate:45deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.\\[appearance\\:textfield\\]{appearance:textfield}.appearance-none{appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\\[0fr\\]{grid-template-columns:0fr}.grid-cols-\\[1fr\\]{grid-template-columns:1fr}.grid-rows-\\[0fr\\]{grid-template-rows:0fr}.grid-rows-\\[1fr\\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-around{justify-content:space-around}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-evenly{justify-content:space-evenly}.justify-start{justify-content:flex-start}.gap-0\\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-\\[2px\\]{gap:2px}.gap-\\[4px\\]{gap:4px}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-hidden{overflow-y:hidden}.rounded{border-radius:.25rem}.rounded-\\[6px\\]{border-radius:6px}.rounded-\\[8px\\]{border-radius:8px}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-tl{border-top-left-radius:.25rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-bl{border-bottom-left-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-dotted{--tw-border-style:dotted;border-style:dotted}.border-double{--tw-border-style:double;border-style:double}.border-none{--tw-border-style:none;border-style:none}.border-solid{--tw-border-style:solid;border-style:solid}.\\[border-top-style\\:solid\\]{border-top-style:solid}.\\[border-right-style\\:dashed\\]{border-right-style:dashed}.\\[border-bottom-style\\:dashed\\]{border-bottom-style:dashed}.\\[border-bottom-style\\:dotted\\]{border-bottom-style:dotted}.\\[border-bottom-style\\:solid\\]{border-bottom-style:solid}.\\[border-left-style\\:double\\]{border-left-style:double}.\\[border-left-style\\:solid\\]{border-left-style:solid}.border-border{border-color:var(--color-border)}.border-border\\/30{border-color:#e6e6e64d}@supports (color:color-mix(in lab, red, red)){.border-border\\/30{border-color:color-mix(in oklab,var(--color-border)30%,transparent)}}.border-border\\/50{border-color:#e6e6e680}@supports (color:color-mix(in lab, red, red)){.border-border\\/50{border-color:color-mix(in oklab,var(--color-border)50%,transparent)}}.border-foreground\\/10{border-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.border-foreground\\/10{border-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.border-transparent{border-color:#0000}.border-white{border-color:var(--color-white)}.bg-\\[canvas\\]{background-color:canvas}.bg-background{background-color:var(--color-background)}.bg-background\\/85{background-color:#ffffffd9}@supports (color:color-mix(in lab, red, red)){.bg-background\\/85{background-color:color-mix(in oklab,var(--color-background)85%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-border{background-color:var(--color-border)}.bg-destructive{background-color:var(--color-destructive)}.bg-foreground{background-color:var(--color-foreground)}.bg-foreground\\/25{background-color:#17171740}@supports (color:color-mix(in lab, red, red)){.bg-foreground\\/25{background-color:color-mix(in oklab,var(--color-foreground)25%,transparent)}}.bg-muted{background-color:var(--color-muted)}.bg-muted-foreground\\/30{background-color:#7373734d}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\\/30{background-color:color-mix(in oklab,var(--color-muted-foreground)30%,transparent)}}.bg-primary{background-color:var(--color-primary)}.bg-red-500{background-color:var(--color-red-500)}.bg-transparent{background-color:#0000}.fill-border{fill:var(--color-border)}.p-0{padding:calc(var(--spacing)*0)}.p-0\\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-0{padding-block:calc(var(--spacing)*0)}.py-0\\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-3\\.5{padding-block:calc(var(--spacing)*3.5)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2\\.5{padding-top:calc(var(--spacing)*2.5)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pt-\\[13px\\]{padding-top:13px}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-1\\.5{padding-right:calc(var(--spacing)*1.5)}.pr-2{padding-right:calc(var(--spacing)*2)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-1\\.5{padding-bottom:calc(var(--spacing)*1.5)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pl-0{padding-left:calc(var(--spacing)*0)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-7{padding-left:calc(var(--spacing)*7)}.text-center{text-align:center}.text-justify{text-align:justify}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[7px\\]{font-size:7px}.text-\\[9px\\]{font-size:9px}.text-\\[10px\\]{font-size:10px}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-extralight{--tw-font-weight:var(--font-weight-extralight);font-weight:var(--font-weight-extralight)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.font-thin{--tw-font-weight:var(--font-weight-thin);font-weight:var(--font-weight-thin)}.\\[overflow-wrap\\:anywhere\\]{overflow-wrap:anywhere}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-background{color:var(--color-background)}.text-blue-500{color:var(--color-blue-500)}.text-destructive-foreground{color:var(--color-destructive-foreground)}.text-foreground{color:var(--color-foreground)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-muted-foreground{color:var(--color-muted-foreground)}.text-popover-foreground{color:var(--color-popover-foreground)}.text-primary{color:var(--color-primary)}.text-primary-foreground{color:var(--color-primary-foreground)}.text-red-500{color:var(--color-red-500)}.text-secondary-foreground{color:var(--color-secondary-foreground)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xs{--tw-shadow:0 1px var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.3\\)\\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_4px_6px_-1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[inset_0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-white{--tw-ring-color:var(--color-white)}.outline,.outline-1{outline-style:var(--tw-outline-style);outline-width:1px}.outline-border{outline-color:var(--color-border)}.outline-foreground\\/10{outline-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.outline-foreground\\/10{outline-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.outline-red-500\\/70{outline-color:#fb2c36b3}@supports (color:color-mix(in lab, red, red)){.outline-red-500\\/70{outline-color:color-mix(in oklab,var(--color-red-500)70%,transparent)}}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[color\\,background-color\\]{transition-property:color,background-color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[opacity\\,background-color\\,color\\]{transition-property:opacity,background-color,color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[transform\\,scale\\,opacity\\]{transition-property:transform,scale,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.animate-in{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\\[-ms-overflow-style\\:none\\]{-ms-overflow-style:none}.\\[scrollbar-width\\:none\\]{scrollbar-width:none}.duration-150{animation-duration:.15s}.duration-200{animation-duration:.2s}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{animation-timing-function:cubic-bezier(0,0,.2,1)}.fade-in-0{--tw-enter-opacity:0}.running{animation-play-state:running}.zoom-in-95{--tw-enter-scale:.95}@media (hover:hover){.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\\/pin\\:inline:is(:where(.group\\/pin):hover *){display:inline}}.file\\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\\:bg-transparent::file-selector-button{background-color:#0000}.file\\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\\:text-foreground::file-selector-button{color:var(--color-foreground)}.placeholder\\:text-muted-foreground::placeholder{color:var(--color-muted-foreground)}.placeholder\\:text-red-400::placeholder{color:var(--color-red-400)}.focus-within\\:ring-1:focus-within{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-within\\:ring-ring:focus-within{--tw-ring-color:var(--color-ring)}.focus-within\\:outline-none:focus-within{--tw-outline-style:none;outline-style:none}.focus-within\\:ring-inset:focus-within{--tw-ring-inset:inset}@media (hover:hover){.hover\\:scale-\\[1\\.67\\]:hover{scale:1.67}.hover\\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\\:bg-destructive\\/90:hover{background-color:#ef4444e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-destructive\\/90:hover{background-color:color-mix(in oklab,var(--color-destructive)90%,transparent)}}.hover\\:bg-foreground\\/80:hover{background-color:#171717cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-foreground\\/80:hover{background-color:color-mix(in oklab,var(--color-foreground)80%,transparent)}}.hover\\:bg-muted:hover{background-color:var(--color-muted)}.hover\\:bg-muted-foreground\\/10:hover{background-color:#7373731a}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted-foreground\\/10:hover{background-color:color-mix(in oklab,var(--color-muted-foreground)10%,transparent)}}.hover\\:bg-muted\\/50:hover{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/50:hover{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.hover\\:bg-muted\\/80:hover{background-color:#f2f2f2cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/80:hover{background-color:color-mix(in oklab,var(--color-muted)80%,transparent)}}.hover\\:bg-primary\\/90:hover{background-color:#171717e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-primary\\/90:hover{background-color:color-mix(in oklab,var(--color-primary)90%,transparent)}}.hover\\:text-foreground:hover{color:var(--color-foreground)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\:ring-ring:focus-visible{--tw-ring-color:var(--color-ring)}.focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-inset:focus-visible{--tw-ring-inset:inset}.active\\:cursor-grabbing:active{cursor:grabbing}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.data-ending-style\\:scale-90[data-ending-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-ending-style\\:opacity-0[data-ending-style]{opacity:0}.data-instant\\:transition-none[data-instant]{transition-property:none}.data-starting-style\\:scale-90[data-starting-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-starting-style\\:opacity-0[data-starting-style]{opacity:0}.data-\\[highlighted\\]\\:bg-muted[data-highlighted]{background-color:var(--color-muted)}.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.data-\\[highlighted\\]\\:text-foreground[data-highlighted]{color:var(--color-foreground)}@media (prefers-color-scheme:dark){.dark\\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dark\\:-outline-offset-1{outline-offset:calc(1px*-1)}}.\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.\\[\\&_svg\\]\\:size-3\\.5 svg{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.\\[\\&\\:\\:-webkit-inner-spin-button\\]\\:appearance-none::-webkit-inner-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-outer-spin-button\\]\\:appearance-none::-webkit-outer-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-scrollbar\\]\\:hidden::-webkit-scrollbar{display:none}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition:none;animation:none}}.lucide{stroke-width:1px}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes pulse{50%{opacity:.5}}';
11
11
 
12
12
  // src/portal-container.tsx
13
13
  import { jsx } from "react/jsx-runtime";
@@ -397,10 +397,30 @@ function getSourceFromFiber(fiber) {
397
397
  if (fromDebugStack?.fileName) return fromDebugStack;
398
398
  return null;
399
399
  }
400
+ var REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref");
401
+ var REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo");
402
+ function resolveComponentName(type) {
403
+ let current = type;
404
+ for (let depth = 0; depth < 4 && current != null; depth++) {
405
+ const name = current.displayName || (typeof current === "function" ? current.name : void 0);
406
+ if (name) return name;
407
+ if (typeof current !== "object") return null;
408
+ if (current.$$typeof === REACT_MEMO_TYPE) {
409
+ current = current.type;
410
+ continue;
411
+ }
412
+ if (current.$$typeof === REACT_FORWARD_REF_TYPE) {
413
+ current = current.render;
414
+ continue;
415
+ }
416
+ return null;
417
+ }
418
+ return null;
419
+ }
400
420
  function buildFrame(fiber) {
401
421
  const type = fiber?.type;
402
422
  if (typeof type !== "function" && typeof type !== "object") return null;
403
- const name = type?.displayName || type?.name || null;
423
+ const name = resolveComponentName(type);
404
424
  if (!name || name === "Fragment") return null;
405
425
  const frame = { name };
406
426
  const source = getSourceFromFiber(fiber);
@@ -472,14 +492,7 @@ function getReactComponentInfo(element) {
472
492
  }
473
493
  return { ...getRenderStack(fiber), elementSourceFile };
474
494
  }
475
- var EXCLUDED_PROP_KEYS = /* @__PURE__ */ new Set([
476
- "className",
477
- "style",
478
- "children",
479
- "ref",
480
- "key",
481
- "render"
482
- ]);
495
+ var EXCLUDED_PROP_KEYS = /* @__PURE__ */ new Set(["className", "style", "children", "ref", "key", "render"]);
483
496
  function serializePropValue(value) {
484
497
  if (typeof value === "function") return "[function]";
485
498
  if (typeof value === "symbol") return void 0;
@@ -590,19 +603,7 @@ function classifyComponentFiber(fiber, frames, elementSourceFile) {
590
603
  return { isComponentPrimitive: false };
591
604
  }
592
605
 
593
- // src/utils.ts
594
- function clamp(value, min, max) {
595
- if (!Number.isFinite(value)) return min;
596
- if (max < min) return min;
597
- return Math.max(min, Math.min(max, value));
598
- }
599
- function isInputFocused() {
600
- let active = document.activeElement;
601
- while (active?.shadowRoot?.activeElement) {
602
- active = active.shadowRoot.activeElement;
603
- }
604
- return active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable;
605
- }
606
+ // src/utils/computed-styles.ts
606
607
  function getComputedStyles(element) {
607
608
  const computed = window.getComputedStyle(element);
608
609
  return {
@@ -711,6 +712,255 @@ function getOriginalInlineStyles(element) {
711
712
  }
712
713
  return styles;
713
714
  }
715
+ function getComputedTypography(element) {
716
+ const computed = window.getComputedStyle(element);
717
+ let textVerticalAlign = "flex-start";
718
+ if (computed.display === "flex" || computed.display === "inline-flex") {
719
+ const alignItems = computed.alignItems;
720
+ if (alignItems === "center") textVerticalAlign = "center";
721
+ else if (alignItems === "flex-end" || alignItems === "end") textVerticalAlign = "flex-end";
722
+ }
723
+ const lineHeight = computed.lineHeight === "normal" ? {
724
+ numericValue: parseFloat(computed.fontSize) * 1.2,
725
+ unit: "px",
726
+ raw: `${Math.round(parseFloat(computed.fontSize) * 1.2)}px`
727
+ } : parsePropertyValue(computed.lineHeight);
728
+ const fontSize = parseFloat(computed.fontSize);
729
+ let letterSpacing;
730
+ if (computed.letterSpacing === "normal") {
731
+ letterSpacing = { numericValue: 0, unit: "em", raw: "0em" };
732
+ } else {
733
+ const parsed = parsePropertyValue(computed.letterSpacing);
734
+ if (parsed.unit === "px" && fontSize > 0) {
735
+ const emValue = Math.round(parsed.numericValue / fontSize * 100) / 100;
736
+ letterSpacing = { numericValue: emValue, unit: "em", raw: `${emValue}em` };
737
+ } else {
738
+ letterSpacing = parsed;
739
+ }
740
+ }
741
+ return {
742
+ fontFamily: computed.fontFamily,
743
+ fontWeight: computed.fontWeight,
744
+ fontSize: parsePropertyValue(computed.fontSize),
745
+ lineHeight,
746
+ letterSpacing,
747
+ textAlign: computed.textAlign,
748
+ textVerticalAlign
749
+ };
750
+ }
751
+ function getComputedSizing(element) {
752
+ return {
753
+ width: getSizingValue(element, "width"),
754
+ height: getSizingValue(element, "height")
755
+ };
756
+ }
757
+ var TEXT_ELEMENT_TAGS = /* @__PURE__ */ new Set([
758
+ "p",
759
+ "h1",
760
+ "h2",
761
+ "h3",
762
+ "h4",
763
+ "h5",
764
+ "h6",
765
+ "span",
766
+ "label",
767
+ "a",
768
+ "strong",
769
+ "em",
770
+ "small",
771
+ "blockquote",
772
+ "li",
773
+ "td",
774
+ "th",
775
+ "caption",
776
+ "figcaption",
777
+ "legend",
778
+ "dt",
779
+ "dd",
780
+ "abbr",
781
+ "cite",
782
+ "code",
783
+ "pre"
784
+ ]);
785
+ function hasDirectNonWhitespaceText(element) {
786
+ return Array.from(element.childNodes).some(
787
+ (node) => node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())
788
+ );
789
+ }
790
+ var TRANSPARENT_COLOR = { hex: "000000", alpha: 0, raw: "transparent" };
791
+ function isVisibleBorderSide(side) {
792
+ return side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0;
793
+ }
794
+ function hasVisibleOutline(computed) {
795
+ return computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
796
+ }
797
+ function parseVisibleColor(value, fallbackCurrentColor) {
798
+ const raw = value.trim();
799
+ const lowered = raw.toLowerCase();
800
+ if (!raw || lowered === "none" || lowered === "transparent") {
801
+ return null;
802
+ }
803
+ const resolved = /^currentcolor$/i.test(raw) ? fallbackCurrentColor ?? raw : raw;
804
+ const parsed = parseColorValue(resolved);
805
+ if (parsed.alpha <= 0) {
806
+ return null;
807
+ }
808
+ return parsed;
809
+ }
810
+ function addUniqueColor(colors, color) {
811
+ if (!color) return;
812
+ colors.set(`${color.hex}:${color.alpha}`, color);
813
+ }
814
+ function isTextRenderingFormControl(element) {
815
+ if (element instanceof HTMLTextAreaElement) return true;
816
+ if (element instanceof HTMLSelectElement) return true;
817
+ if (element instanceof HTMLButtonElement) return true;
818
+ if (element instanceof HTMLInputElement) {
819
+ const textlessInputTypes = /* @__PURE__ */ new Set([
820
+ "hidden",
821
+ "checkbox",
822
+ "radio",
823
+ "range",
824
+ "color",
825
+ "file",
826
+ "image"
827
+ ]);
828
+ return !textlessInputTypes.has(element.type.toLowerCase());
829
+ }
830
+ return false;
831
+ }
832
+ function hasRenderableTextNode(element) {
833
+ if (element.isContentEditable) return true;
834
+ if (isTextRenderingFormControl(element)) return true;
835
+ if (!element.textContent?.trim()) return false;
836
+ if (hasDirectNonWhitespaceText(element)) return true;
837
+ const tagName = element.tagName.toLowerCase();
838
+ return TEXT_ELEMENT_TAGS.has(tagName) || element.children.length === 0;
839
+ }
840
+ function getComputedBoxShadow(element) {
841
+ const computed = window.getComputedStyle(element);
842
+ const value = computed.boxShadow.trim();
843
+ return value || "none";
844
+ }
845
+ function getComputedColorStyles(element) {
846
+ const computed = window.getComputedStyle(element);
847
+ const borderSides = [
848
+ {
849
+ style: computed.borderTopStyle,
850
+ width: computed.borderTopWidth,
851
+ color: computed.borderTopColor
852
+ },
853
+ {
854
+ style: computed.borderRightStyle,
855
+ width: computed.borderRightWidth,
856
+ color: computed.borderRightColor
857
+ },
858
+ {
859
+ style: computed.borderBottomStyle,
860
+ width: computed.borderBottomWidth,
861
+ color: computed.borderBottomColor
862
+ },
863
+ {
864
+ style: computed.borderLeftStyle,
865
+ width: computed.borderLeftWidth,
866
+ color: computed.borderLeftColor
867
+ }
868
+ ];
869
+ const visibleBorderSide = borderSides.find((side) => isVisibleBorderSide(side));
870
+ const hasBorder = Boolean(visibleBorderSide);
871
+ const hasOutline = hasVisibleOutline(computed);
872
+ return {
873
+ backgroundColor: parseColorValue(computed.backgroundColor),
874
+ color: parseColorValue(computed.color),
875
+ borderColor: hasBorder && visibleBorderSide ? parseColorValue(visibleBorderSide.color) : TRANSPARENT_COLOR,
876
+ outlineColor: hasOutline ? parseColorValue(computed.outlineColor) : TRANSPARENT_COLOR
877
+ };
878
+ }
879
+ function getSelectionColors(element) {
880
+ const uniqueColors = /* @__PURE__ */ new Map();
881
+ const queue = [element];
882
+ for (let index = 0; index < queue.length; index++) {
883
+ const node = queue[index];
884
+ const computed = window.getComputedStyle(node);
885
+ if (computed.display === "none") {
886
+ continue;
887
+ }
888
+ const isVisibilityHidden = computed.visibility === "hidden" || computed.visibility === "collapse";
889
+ const currentTextColor = computed.color;
890
+ if (!isVisibilityHidden) {
891
+ addUniqueColor(uniqueColors, parseVisibleColor(computed.backgroundColor));
892
+ if (node instanceof HTMLElement && hasRenderableTextNode(node)) {
893
+ addUniqueColor(uniqueColors, parseVisibleColor(currentTextColor));
894
+ }
895
+ const borderSides = [
896
+ {
897
+ style: computed.borderTopStyle,
898
+ width: computed.borderTopWidth,
899
+ color: computed.borderTopColor
900
+ },
901
+ {
902
+ style: computed.borderRightStyle,
903
+ width: computed.borderRightWidth,
904
+ color: computed.borderRightColor
905
+ },
906
+ {
907
+ style: computed.borderBottomStyle,
908
+ width: computed.borderBottomWidth,
909
+ color: computed.borderBottomColor
910
+ },
911
+ {
912
+ style: computed.borderLeftStyle,
913
+ width: computed.borderLeftWidth,
914
+ color: computed.borderLeftColor
915
+ }
916
+ ];
917
+ for (const side of borderSides) {
918
+ if (!isVisibleBorderSide(side)) continue;
919
+ addUniqueColor(uniqueColors, parseVisibleColor(side.color, currentTextColor));
920
+ }
921
+ if (hasVisibleOutline(computed)) {
922
+ addUniqueColor(uniqueColors, parseVisibleColor(computed.outlineColor, currentTextColor));
923
+ }
924
+ if (node instanceof SVGElement) {
925
+ const fillColor = parseVisibleColor(computed.getPropertyValue("fill"), currentTextColor) ?? parseVisibleColor(node.getAttribute("fill") ?? "", currentTextColor);
926
+ const strokeColor = parseVisibleColor(computed.getPropertyValue("stroke"), currentTextColor) ?? parseVisibleColor(node.getAttribute("stroke") ?? "", currentTextColor);
927
+ addUniqueColor(uniqueColors, fillColor);
928
+ addUniqueColor(uniqueColors, strokeColor);
929
+ }
930
+ }
931
+ for (const child of node.children) {
932
+ queue.push(child);
933
+ }
934
+ }
935
+ return Array.from(uniqueColors.values());
936
+ }
937
+ function getAllComputedStyles(element) {
938
+ const { spacing, borderRadius, flex } = getComputedStyles(element);
939
+ return {
940
+ spacing,
941
+ borderRadius,
942
+ border: getComputedBorderStyles(element),
943
+ flex,
944
+ sizing: getComputedSizing(element),
945
+ color: getComputedColorStyles(element),
946
+ boxShadow: getComputedBoxShadow(element),
947
+ typography: getComputedTypography(element)
948
+ };
949
+ }
950
+
951
+ // src/utils.ts
952
+ function clamp(value, min, max) {
953
+ if (!Number.isFinite(value)) return min;
954
+ if (max < min) return min;
955
+ return Math.max(min, Math.min(max, value));
956
+ }
957
+ function isInputFocused() {
958
+ let active = document.activeElement;
959
+ while (active?.shadowRoot?.activeElement) {
960
+ active = active.shadowRoot.activeElement;
961
+ }
962
+ return active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable;
963
+ }
714
964
  var spacingScale = { 0: "0", 1: "px", 2: "0.5", 4: "1", 8: "2", 12: "3", 16: "4", 20: "5", 24: "6", 32: "8" };
715
965
  var tailwindClassMap = {
716
966
  padding: { prefix: "p", scale: spacingScale },
@@ -1037,7 +1287,7 @@ var typographyPropertyToCSSMap = {
1037
1287
  textAlign: "text-align",
1038
1288
  textVerticalAlign: "align-items"
1039
1289
  };
1040
- var TEXT_ELEMENT_TAGS = /* @__PURE__ */ new Set([
1290
+ var TEXT_ELEMENT_TAGS2 = /* @__PURE__ */ new Set([
1041
1291
  "p",
1042
1292
  "h1",
1043
1293
  "h2",
@@ -1065,55 +1315,23 @@ var TEXT_ELEMENT_TAGS = /* @__PURE__ */ new Set([
1065
1315
  "code",
1066
1316
  "pre"
1067
1317
  ]);
1068
- function hasDirectNonWhitespaceText(element) {
1318
+ function hasDirectNonWhitespaceText2(element) {
1069
1319
  return Array.from(element.childNodes).some(
1070
1320
  (node) => node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())
1071
1321
  );
1072
1322
  }
1073
1323
  function isTextElement2(element) {
1074
1324
  const tagName = element.tagName.toLowerCase();
1075
- if (TEXT_ELEMENT_TAGS.has(tagName)) {
1076
- return true;
1077
- }
1078
- if (hasDirectNonWhitespaceText(element)) {
1079
- return true;
1080
- }
1081
- if (element.children.length === 0 && element.textContent?.trim()) {
1082
- return true;
1083
- }
1084
- return false;
1085
- }
1086
- function getComputedTypography(element) {
1087
- const computed = window.getComputedStyle(element);
1088
- let textVerticalAlign = "flex-start";
1089
- if (computed.display === "flex" || computed.display === "inline-flex") {
1090
- const alignItems = computed.alignItems;
1091
- if (alignItems === "center") textVerticalAlign = "center";
1092
- else if (alignItems === "flex-end" || alignItems === "end") textVerticalAlign = "flex-end";
1093
- }
1094
- const lineHeight = computed.lineHeight === "normal" ? { numericValue: parseFloat(computed.fontSize) * 1.2, unit: "px", raw: `${Math.round(parseFloat(computed.fontSize) * 1.2)}px` } : parsePropertyValue(computed.lineHeight);
1095
- const fontSize = parseFloat(computed.fontSize);
1096
- let letterSpacing;
1097
- if (computed.letterSpacing === "normal") {
1098
- letterSpacing = { numericValue: 0, unit: "em", raw: "0em" };
1099
- } else {
1100
- const parsed = parsePropertyValue(computed.letterSpacing);
1101
- if (parsed.unit === "px" && fontSize > 0) {
1102
- const emValue = Math.round(parsed.numericValue / fontSize * 100) / 100;
1103
- letterSpacing = { numericValue: emValue, unit: "em", raw: `${emValue}em` };
1104
- } else {
1105
- letterSpacing = parsed;
1106
- }
1107
- }
1108
- return {
1109
- fontFamily: computed.fontFamily,
1110
- fontWeight: computed.fontWeight,
1111
- fontSize: parsePropertyValue(computed.fontSize),
1112
- lineHeight,
1113
- letterSpacing,
1114
- textAlign: computed.textAlign,
1115
- textVerticalAlign
1116
- };
1325
+ if (TEXT_ELEMENT_TAGS2.has(tagName)) {
1326
+ return true;
1327
+ }
1328
+ if (hasDirectNonWhitespaceText2(element)) {
1329
+ return true;
1330
+ }
1331
+ if (element.children.length === 0 && element.textContent?.trim()) {
1332
+ return true;
1333
+ }
1334
+ return false;
1117
1335
  }
1118
1336
  function detectSizingMode(element, dimension) {
1119
1337
  const computed = window.getComputedStyle(element);
@@ -1162,12 +1380,6 @@ function getSizingValue(element, dimension) {
1162
1380
  }
1163
1381
  };
1164
1382
  }
1165
- function getComputedSizing(element) {
1166
- return {
1167
- width: getSizingValue(element, "width"),
1168
- height: getSizingValue(element, "height")
1169
- };
1170
- }
1171
1383
  function sizingValueToCSS(sizing) {
1172
1384
  switch (sizing.mode) {
1173
1385
  case "fill":
@@ -1276,134 +1488,6 @@ function parseColorValue(cssValue) {
1276
1488
  }
1277
1489
  return parseNamedColor(raw);
1278
1490
  }
1279
- var TRANSPARENT_COLOR = { hex: "000000", alpha: 0, raw: "transparent" };
1280
- function isVisibleBorderSide(side) {
1281
- return side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0;
1282
- }
1283
- function hasVisibleOutline(computed) {
1284
- return computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
1285
- }
1286
- function parseVisibleColor(value, fallbackCurrentColor) {
1287
- const raw = value.trim();
1288
- const lowered = raw.toLowerCase();
1289
- if (!raw || lowered === "none" || lowered === "transparent") {
1290
- return null;
1291
- }
1292
- const resolved = /^currentcolor$/i.test(raw) ? fallbackCurrentColor ?? raw : raw;
1293
- const parsed = parseColorValue(resolved);
1294
- if (parsed.alpha <= 0) {
1295
- return null;
1296
- }
1297
- return parsed;
1298
- }
1299
- function addUniqueColor(colors, color) {
1300
- if (!color) return;
1301
- colors.set(`${color.hex}:${color.alpha}`, color);
1302
- }
1303
- function isTextRenderingFormControl(element) {
1304
- if (element instanceof HTMLTextAreaElement) return true;
1305
- if (element instanceof HTMLSelectElement) return true;
1306
- if (element instanceof HTMLButtonElement) return true;
1307
- if (element instanceof HTMLInputElement) {
1308
- const textlessInputTypes = /* @__PURE__ */ new Set([
1309
- "hidden",
1310
- "checkbox",
1311
- "radio",
1312
- "range",
1313
- "color",
1314
- "file",
1315
- "image"
1316
- ]);
1317
- return !textlessInputTypes.has(element.type.toLowerCase());
1318
- }
1319
- return false;
1320
- }
1321
- function hasRenderableTextNode(element) {
1322
- if (element.isContentEditable) return true;
1323
- if (isTextRenderingFormControl(element)) return true;
1324
- if (!element.textContent?.trim()) return false;
1325
- if (hasDirectNonWhitespaceText(element)) return true;
1326
- const tagName = element.tagName.toLowerCase();
1327
- return TEXT_ELEMENT_TAGS.has(tagName) || element.children.length === 0;
1328
- }
1329
- function getComputedBoxShadow(element) {
1330
- const computed = window.getComputedStyle(element);
1331
- const value = computed.boxShadow.trim();
1332
- return value || "none";
1333
- }
1334
- function getComputedColorStyles(element) {
1335
- const computed = window.getComputedStyle(element);
1336
- const borderSides = [
1337
- { style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
1338
- { style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
1339
- { style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
1340
- { style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
1341
- ];
1342
- const visibleBorderSide = borderSides.find((side) => isVisibleBorderSide(side));
1343
- const hasBorder = Boolean(visibleBorderSide);
1344
- const hasOutline = hasVisibleOutline(computed);
1345
- return {
1346
- backgroundColor: parseColorValue(computed.backgroundColor),
1347
- color: parseColorValue(computed.color),
1348
- borderColor: hasBorder && visibleBorderSide ? parseColorValue(visibleBorderSide.color) : TRANSPARENT_COLOR,
1349
- outlineColor: hasOutline ? parseColorValue(computed.outlineColor) : TRANSPARENT_COLOR
1350
- };
1351
- }
1352
- function getSelectionColors(element) {
1353
- const uniqueColors = /* @__PURE__ */ new Map();
1354
- const queue = [element];
1355
- for (let index = 0; index < queue.length; index++) {
1356
- const node = queue[index];
1357
- const computed = window.getComputedStyle(node);
1358
- if (computed.display === "none") {
1359
- continue;
1360
- }
1361
- const isVisibilityHidden = computed.visibility === "hidden" || computed.visibility === "collapse";
1362
- const currentTextColor = computed.color;
1363
- if (!isVisibilityHidden) {
1364
- addUniqueColor(uniqueColors, parseVisibleColor(computed.backgroundColor));
1365
- if (node instanceof HTMLElement && hasRenderableTextNode(node)) {
1366
- addUniqueColor(uniqueColors, parseVisibleColor(currentTextColor));
1367
- }
1368
- const borderSides = [
1369
- { style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
1370
- { style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
1371
- { style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
1372
- { style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
1373
- ];
1374
- for (const side of borderSides) {
1375
- if (!isVisibleBorderSide(side)) continue;
1376
- addUniqueColor(uniqueColors, parseVisibleColor(side.color, currentTextColor));
1377
- }
1378
- if (hasVisibleOutline(computed)) {
1379
- addUniqueColor(uniqueColors, parseVisibleColor(computed.outlineColor, currentTextColor));
1380
- }
1381
- if (node instanceof SVGElement) {
1382
- const fillColor = parseVisibleColor(computed.getPropertyValue("fill"), currentTextColor) ?? parseVisibleColor(node.getAttribute("fill") ?? "", currentTextColor);
1383
- const strokeColor = parseVisibleColor(computed.getPropertyValue("stroke"), currentTextColor) ?? parseVisibleColor(node.getAttribute("stroke") ?? "", currentTextColor);
1384
- addUniqueColor(uniqueColors, fillColor);
1385
- addUniqueColor(uniqueColors, strokeColor);
1386
- }
1387
- }
1388
- for (const child of node.children) {
1389
- queue.push(child);
1390
- }
1391
- }
1392
- return Array.from(uniqueColors.values());
1393
- }
1394
- function getAllComputedStyles(element) {
1395
- const { spacing, borderRadius, flex } = getComputedStyles(element);
1396
- return {
1397
- spacing,
1398
- borderRadius,
1399
- border: getComputedBorderStyles(element),
1400
- flex,
1401
- sizing: getComputedSizing(element),
1402
- color: getComputedColorStyles(element),
1403
- boxShadow: getComputedBoxShadow(element),
1404
- typography: getComputedTypography(element)
1405
- };
1406
- }
1407
1491
  var colorPropertyToCSSMap = {
1408
1492
  backgroundColor: "background-color",
1409
1493
  color: "color",
@@ -1858,7 +1942,7 @@ function findChildAtPoint(parent, clientX, clientY) {
1858
1942
  return clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom;
1859
1943
  });
1860
1944
  if (hit) return hit;
1861
- if (children.length === 1 && !hasDirectNonWhitespaceText(parent)) return children[0];
1945
+ if (children.length === 1 && !hasDirectNonWhitespaceText2(parent)) return children[0];
1862
1946
  return null;
1863
1947
  }
1864
1948
  function elementFromPointWithoutOverlays(x, y) {
@@ -2412,7 +2496,7 @@ function buildElementContext(locator) {
2412
2496
  return buildLocatorContextLines(locator).join("\n");
2413
2497
  }
2414
2498
  function hasSessionEditChanges(edit) {
2415
- return Object.keys(edit.pendingStyles).length > 0 || Boolean(edit.textEdit) || Boolean(edit.move);
2499
+ return Object.keys(edit.pendingStyles).length > 0 || Boolean(edit.textEdit) || Boolean(edit.move) || Boolean(edit.deleted);
2416
2500
  }
2417
2501
  function partitionMultiSelectedEdits(elements, sessionEditsRef) {
2418
2502
  const editsWithChanges = [];
@@ -2934,7 +3018,7 @@ function buildMoveEntries(edits) {
2934
3018
  let noopMoveCount = 0;
2935
3019
  for (const edit of edits) {
2936
3020
  const move = edit.move;
2937
- if (!move) continue;
3021
+ if (!move || edit.deleted) continue;
2938
3022
  const subject = buildAnchorRef(
2939
3023
  getElementDisplayName(edit.element) || edit.locator.tagName,
2940
3024
  edit.locator.domSelector,
@@ -3093,19 +3177,22 @@ function getExportContentProfile(edits, comments, movePlanOrContext) {
3093
3177
  hasCssEdits: edits.some((e) => Object.keys(e.pendingStyles).length > 0),
3094
3178
  hasTextEdits: edits.some((e) => e.textEdit != null),
3095
3179
  hasMoves: moveOpCount > 0,
3096
- hasComments: comments.length > 0
3180
+ hasComments: comments.length > 0,
3181
+ hasDeletes: edits.some((e) => e.deleted)
3097
3182
  };
3098
3183
  }
3099
3184
  function buildExportInstruction(profile) {
3100
3185
  const { hasCssEdits, hasTextEdits, hasMoves, hasComments } = profile;
3101
- if (!hasCssEdits && !hasTextEdits && !hasMoves && !hasComments) return "";
3102
- if (!hasCssEdits && !hasTextEdits && !hasMoves) {
3186
+ const hasDeletes = Boolean(profile.hasDeletes);
3187
+ if (!hasCssEdits && !hasTextEdits && !hasMoves && !hasComments && !hasDeletes) return "";
3188
+ if (!hasCssEdits && !hasTextEdits && !hasMoves && !hasDeletes) {
3103
3189
  return hasComments ? "Address this feedback on the UI. Use the provided source location and selector to find each element in the codebase." : "";
3104
3190
  }
3105
3191
  const parts = [];
3106
3192
  if (hasCssEdits) parts.push("Apply the CSS changes to the targeted elements using the project's existing styling approach (Tailwind, CSS modules, etc.). Map values to existing CSS variables, design tokens, or utility classes already used in the project whenever possible.");
3107
3193
  if (hasTextEdits) parts.push("Update the text content as specified.");
3108
3194
  if (hasMoves) parts.push("Implement the move plan below directly in source code. For `structural_move`, reorder/reparent elements using the target anchors. For `layout_refactor`, apply the listed flex/grid refactor steps. Do NOT simulate movement with absolute positioning, left/top offsets, transform, or margin hacks.");
3195
+ if (hasDeletes) parts.push("Delete the elements marked for deletion from the source code \u2014 remove their markup/JSX (and any now-dead props, handlers, or imports they solely used).");
3109
3196
  if (hasComments) parts.push("Address the comments on the relevant elements.");
3110
3197
  return `${parts.join(" ")} Use the provided source locations, selectors, and context HTML to locate each element in the codebase.`;
3111
3198
  }
@@ -3140,6 +3227,13 @@ function buildSessionExport(edits, comments = [], options) {
3140
3227
  blocks.push(planLines.join("\n"));
3141
3228
  }
3142
3229
  for (const edit of edits) {
3230
+ if (edit.deleted) {
3231
+ const lines = buildLocatorContextLines(edit.locator);
3232
+ lines.push("");
3233
+ lines.push("action: delete this element \u2014 remove it from the source");
3234
+ blocks.push(lines.join("\n"));
3235
+ continue;
3236
+ }
3143
3237
  const moveIntent = getMoveIntentForEdit(edit, planContext);
3144
3238
  const hasMove = Boolean(moveIntent);
3145
3239
  const hasStyleOrText = Object.keys(edit.pendingStyles).length > 0 || edit.textEdit != null;
@@ -4048,6 +4142,7 @@ function useSessionManager({
4048
4142
  sessionEditsRef,
4049
4143
  removedSessionEditsRef,
4050
4144
  undoStackRef,
4145
+ onElementInsertedRef,
4051
4146
  pushUndo,
4052
4147
  setState,
4053
4148
  setSessionEditCount
@@ -4244,27 +4339,48 @@ function useSessionManager({
4244
4339
  selectElement(firstChild);
4245
4340
  }
4246
4341
  }, [getSelectableChild, selectElement]);
4342
+ const centerElementOnBody = React3.useCallback((element, size) => {
4343
+ const bodyRect = document.body.getBoundingClientRect();
4344
+ const scaleX = document.body.offsetWidth > 0 ? bodyRect.width / document.body.offsetWidth : 1;
4345
+ const scaleY = document.body.offsetHeight > 0 ? bodyRect.height / document.body.offsetHeight : 1;
4346
+ const fallbackWidth = size?.width ?? element.offsetWidth ?? 0;
4347
+ const fallbackHeight = size?.height ?? element.offsetHeight ?? 0;
4348
+ const measuredRect = element.getBoundingClientRect();
4349
+ const width = measuredRect.width || fallbackWidth;
4350
+ const height = measuredRect.height || fallbackHeight;
4351
+ const left = Math.round((window.innerWidth / 2 - bodyRect.left) / scaleX - width / 2);
4352
+ const top = Math.round((window.innerHeight / 2 - bodyRect.top) / scaleY - height / 2);
4353
+ element.style.left = `${left}px`;
4354
+ element.style.top = `${top}px`;
4355
+ }, []);
4247
4356
  const insertElement = React3.useCallback((kind) => {
4248
4357
  if (!stateRef.current.editModeActive) return;
4249
4358
  saveCurrentToSession();
4250
4359
  const restoreSelection = buildSelectionSnapshot();
4251
4360
  const selectedEl = stateRef.current.selectedElement;
4252
- const hasSelection = kind === "frame" && selectedEl !== null && selectedEl !== document.body && selectedEl.parentElement !== null;
4253
- const width = kind === "frame" ? 100 : 160;
4254
- const height = kind === "frame" ? 100 : 96;
4255
- const element = document.createElement("div");
4361
+ const insertsAsSibling = kind === "frame" || kind === "text";
4362
+ const hasSelection = insertsAsSibling && selectedEl !== null && selectedEl !== document.body && selectedEl.parentElement !== null;
4363
+ const element = document.createElement(kind === "text" ? "p" : "div");
4256
4364
  element.id = nextGeneratedCanvasId(kind);
4257
4365
  element.setAttribute(GENERATED_CANVAS_NODE_ATTR, kind);
4258
- element.style.width = `${width}px`;
4259
- element.style.height = `${height}px`;
4260
4366
  element.style.boxSizing = "border-box";
4261
4367
  if (kind === "frame") {
4368
+ element.style.width = "100px";
4369
+ element.style.height = "100px";
4262
4370
  element.style.background = "#F5F5F5";
4263
4371
  element.style.border = "1px solid #E0E0E0";
4264
- } else {
4372
+ } else if (kind === "div") {
4373
+ element.style.width = "160px";
4374
+ element.style.height = "96px";
4265
4375
  element.style.borderRadius = "12px";
4266
4376
  element.style.border = "1px solid rgba(13, 153, 255, 0.35)";
4267
4377
  element.style.background = "rgba(13, 153, 255, 0.08)";
4378
+ } else {
4379
+ element.textContent = "Text";
4380
+ element.style.display = "inline-block";
4381
+ element.style.margin = "0";
4382
+ element.style.minHeight = "24px";
4383
+ element.style.textAlign = "center";
4268
4384
  }
4269
4385
  if (hasSelection) {
4270
4386
  const insertionParent = selectedEl.parentElement;
@@ -4275,16 +4391,22 @@ function useSessionManager({
4275
4391
  insertionParent.appendChild(element);
4276
4392
  }
4277
4393
  } else {
4278
- const bodyRect = document.body.getBoundingClientRect();
4279
- const scaleX = document.body.offsetWidth > 0 ? bodyRect.width / document.body.offsetWidth : 1;
4280
- const scaleY = document.body.offsetHeight > 0 ? bodyRect.height / document.body.offsetHeight : 1;
4281
- const left = Math.round((window.innerWidth / 2 - bodyRect.left) / scaleX - width / 2);
4282
- const top = Math.round((window.innerHeight / 2 - bodyRect.top) / scaleY - height / 2);
4283
4394
  element.style.position = "absolute";
4284
- element.style.left = `${left}px`;
4285
- element.style.top = `${top}px`;
4286
4395
  element.style.zIndex = "1";
4287
- document.body.appendChild(element);
4396
+ if (kind === "text") {
4397
+ element.style.left = "0px";
4398
+ element.style.top = "0px";
4399
+ element.style.visibility = "hidden";
4400
+ document.body.appendChild(element);
4401
+ centerElementOnBody(element);
4402
+ element.style.visibility = "";
4403
+ } else {
4404
+ centerElementOnBody(
4405
+ element,
4406
+ kind === "frame" ? { width: 100, height: 100 } : { width: 160, height: 96 }
4407
+ );
4408
+ document.body.appendChild(element);
4409
+ }
4288
4410
  }
4289
4411
  pushUndo({
4290
4412
  type: "structure",
@@ -4299,7 +4421,8 @@ function useSessionManager({
4299
4421
  primaryElement: element,
4300
4422
  pushUndo: false
4301
4423
  });
4302
- }, [applySelection, buildSelectionSnapshot, pushUndo, saveCurrentToSession, stateRef]);
4424
+ onElementInsertedRef.current?.(kind, element);
4425
+ }, [applySelection, buildSelectionSnapshot, centerElementOnBody, onElementInsertedRef, pushUndo, saveCurrentToSession, stateRef]);
4303
4426
  const groupSelection = React3.useCallback(() => {
4304
4427
  const selected = getSanitizedSelection(stateRef.current.selectedElements);
4305
4428
  if (selected.length < 2) return;
@@ -4395,9 +4518,17 @@ function useSessionManager({
4395
4518
  }));
4396
4519
  const sessionSnapshots = /* @__PURE__ */ new Map();
4397
4520
  for (const el of selected) {
4398
- const edit = sessionEditsRef.current.get(el);
4399
- if (edit) sessionSnapshots.set(el, edit);
4400
- sessionEditsRef.current.delete(el);
4521
+ const existing = sessionEditsRef.current.get(el);
4522
+ sessionSnapshots.set(el, existing ?? null);
4523
+ sessionEditsRef.current.set(el, existing ? { ...existing, deleted: true } : {
4524
+ element: el,
4525
+ locator: getElementLocator(el),
4526
+ originalStyles: {},
4527
+ pendingStyles: {},
4528
+ move: null,
4529
+ textEdit: null,
4530
+ deleted: true
4531
+ });
4401
4532
  }
4402
4533
  syncSessionItemCount();
4403
4534
  for (const { element } of snapshots) {
@@ -4418,7 +4549,8 @@ function useSessionManager({
4418
4549
  }
4419
4550
  }
4420
4551
  for (const [el, edit] of sessionSnapshots) {
4421
- sessionEditsRef.current.set(el, edit);
4552
+ if (edit) sessionEditsRef.current.set(el, edit);
4553
+ else sessionEditsRef.current.delete(el);
4422
4554
  }
4423
4555
  syncSessionItemCount();
4424
4556
  }
@@ -4809,7 +4941,7 @@ function useSessionManager({
4809
4941
  saveCurrentToSession();
4810
4942
  const edits = [];
4811
4943
  for (const edit of sessionEditsRef.current.values()) {
4812
- if (!edit.element.isConnected) {
4944
+ if (!edit.element.isConnected && !edit.deleted) {
4813
4945
  sessionEditsRef.current.delete(edit.element);
4814
4946
  continue;
4815
4947
  }
@@ -4978,6 +5110,7 @@ ${exportMarkdown}`);
4978
5110
 
4979
5111
  // src/use-text-and-comments.ts
4980
5112
  import * as React4 from "react";
5113
+ var GENERATED_CANVAS_NODE_ATTR2 = "data-made-refine-canvas-node";
4981
5114
  function clampUnit(value) {
4982
5115
  if (!Number.isFinite(value)) return 0;
4983
5116
  return Math.max(0, Math.min(1, value));
@@ -5013,6 +5146,94 @@ function useTextAndComments({
5013
5146
  editingElement.style.outlineOffset = "";
5014
5147
  editingElement.style.cursor = originalCursor;
5015
5148
  editingElement.blur();
5149
+ const isGeneratedTextElement = editingElement.getAttribute(GENERATED_CANVAS_NODE_ATTR2) === "text";
5150
+ const shouldDeleteGeneratedText = isGeneratedTextElement && newText.trim().length === 0;
5151
+ if (shouldDeleteGeneratedText) {
5152
+ const parent = editingElement.parentElement;
5153
+ const nextSibling = editingElement.nextSibling;
5154
+ const current = stateRef.current;
5155
+ const removedComments = current.comments.filter((comment) => comment.element === editingElement);
5156
+ const removedCommentIds = new Set(removedComments.map((comment) => comment.id));
5157
+ const remainingComments = current.comments.filter((comment) => comment.element !== editingElement);
5158
+ const restoredActiveCommentId = current.activeCommentId && removedCommentIds.has(current.activeCommentId) ? current.activeCommentId : null;
5159
+ const existingSessionEdit = existing ? {
5160
+ ...existing,
5161
+ originalStyles: { ...existing.originalStyles },
5162
+ pendingStyles: { ...existing.pendingStyles },
5163
+ move: existing.move ? { ...existing.move } : null,
5164
+ textEdit: existing.textEdit ? { ...existing.textEdit } : null
5165
+ } : null;
5166
+ const restoreSelection = {
5167
+ isOpen: current.isOpen,
5168
+ selectedElement: current.selectedElement,
5169
+ selectedElements: [...current.selectedElements],
5170
+ selectionAnchorElement: current.selectionAnchorElement,
5171
+ originalStyles: { ...current.originalStyles },
5172
+ pendingStyles: { ...current.pendingStyles }
5173
+ };
5174
+ sessionEditsRef.current.delete(editingElement);
5175
+ if (editingElement.isConnected) {
5176
+ editingElement.remove();
5177
+ }
5178
+ pushUndo({
5179
+ type: "structure",
5180
+ restoreSelection,
5181
+ undo: () => {
5182
+ editingElement.textContent = previousText;
5183
+ if (!editingElement.isConnected && parent?.isConnected) {
5184
+ if (nextSibling && nextSibling.parentNode === parent) {
5185
+ parent.insertBefore(editingElement, nextSibling);
5186
+ } else {
5187
+ parent.appendChild(editingElement);
5188
+ }
5189
+ }
5190
+ if (existingSessionEdit) {
5191
+ sessionEditsRef.current.set(editingElement, existingSessionEdit);
5192
+ }
5193
+ setState((prev) => ({
5194
+ ...prev,
5195
+ comments: current.comments,
5196
+ activeCommentId: restoredActiveCommentId ?? prev.activeCommentId
5197
+ }));
5198
+ syncSessionItemCount(current.comments);
5199
+ }
5200
+ });
5201
+ syncSessionItemCount(remainingComments);
5202
+ setState((prev) => {
5203
+ const selectionContainsElement = prev.selectedElement === editingElement || prev.selectionAnchorElement === editingElement || prev.selectedElements.includes(editingElement);
5204
+ if (!selectionContainsElement) {
5205
+ return prev.textEditingElement === editingElement ? {
5206
+ ...prev,
5207
+ comments: prev.comments.filter((comment) => comment.element !== editingElement),
5208
+ activeCommentId: prev.activeCommentId && removedCommentIds.has(prev.activeCommentId) ? null : prev.activeCommentId,
5209
+ textEditingElement: null
5210
+ } : prev;
5211
+ }
5212
+ return {
5213
+ ...prev,
5214
+ isOpen: false,
5215
+ selectedElement: null,
5216
+ selectedElements: [],
5217
+ selectionAnchorElement: null,
5218
+ elementInfo: null,
5219
+ computedSpacing: null,
5220
+ computedBorderRadius: null,
5221
+ computedBorder: null,
5222
+ computedFlex: null,
5223
+ computedSizing: null,
5224
+ computedColor: null,
5225
+ computedBoxShadow: null,
5226
+ computedTypography: null,
5227
+ isComponentPrimitive: false,
5228
+ comments: remainingComments,
5229
+ activeCommentId: restoredActiveCommentId ? null : prev.activeCommentId,
5230
+ originalStyles: {},
5231
+ pendingStyles: {},
5232
+ textEditingElement: null
5233
+ };
5234
+ });
5235
+ return;
5236
+ }
5016
5237
  if (newText !== previousText) {
5017
5238
  pushUndo({ type: "textEdit", element: editingElement, originalText, previousText });
5018
5239
  removedSessionEditsRef.current.delete(editingElement);
@@ -5531,28 +5752,30 @@ async function toClientResponse(response) {
5531
5752
  const data = await readJsonRecord(response);
5532
5753
  const bodyOk = data?.ok;
5533
5754
  const parsedOk = typeof bodyOk === "boolean" ? bodyOk : response.ok;
5755
+ const ok = parsedOk && response.ok;
5534
5756
  return {
5535
- ok: parsedOk && response.ok,
5536
- id: readString(data, "id") ?? ""
5757
+ ok,
5758
+ id: readString(data, "id") ?? "",
5759
+ ...!ok ? { errorKind: "rejected" } : {}
5537
5760
  };
5538
5761
  }
5539
5762
  async function postWithSessionToken(path, payload) {
5540
5763
  const idempotencyKey = createIdempotencyKey();
5541
5764
  let session = await bootstrapSession();
5542
- if (!session) return { ok: false, id: "" };
5765
+ if (!session) return { ok: false, id: "", errorKind: "network" };
5543
5766
  let response;
5544
5767
  try {
5545
5768
  response = await sendAnnotationRequest(session, path, payload, idempotencyKey);
5546
5769
  } catch {
5547
- return { ok: false, id: "" };
5770
+ return { ok: false, id: "", errorKind: "network" };
5548
5771
  }
5549
5772
  if (response.status === 401 || response.status === 403) {
5550
5773
  session = await refreshSessionToken(session) ?? await bootstrapSession(true);
5551
- if (!session) return { ok: false, id: "" };
5774
+ if (!session) return { ok: false, id: "", errorKind: "network" };
5552
5775
  try {
5553
5776
  response = await sendAnnotationRequest(session, path, payload, idempotencyKey);
5554
5777
  } catch {
5555
- return { ok: false, id: "" };
5778
+ return { ok: false, id: "", errorKind: "network" };
5556
5779
  }
5557
5780
  }
5558
5781
  return toClientResponse(response);
@@ -5605,8 +5828,10 @@ function buildLocatorPayload(locator) {
5605
5828
  }
5606
5829
  function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrentToSession, removeSessionEdit, deleteComment }) {
5607
5830
  const [agentAvailable, setAgentAvailable] = React5.useState(false);
5831
+ const [lastSendFailure, setLastSendFailure] = React5.useState(null);
5608
5832
  const isMountedRef = React5.useRef(true);
5609
5833
  React5.useEffect(() => {
5834
+ isMountedRef.current = true;
5610
5835
  return () => {
5611
5836
  isMountedRef.current = false;
5612
5837
  };
@@ -5663,7 +5888,7 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
5663
5888
  const resolvedPlanContext = movePlanContext ?? buildMovePlanContext(editsForPlan);
5664
5889
  const includeBatchMoveEnvelope = Boolean(options?.includeBatchMoveEnvelope && sessionEdit.move);
5665
5890
  const isBatchSend = Boolean(allEdits && allEdits.length > 1);
5666
- const exportMarkdown = sessionEdit.move ? buildSessionExport(
5891
+ const exportMarkdown = sessionEdit.move || sessionEdit.deleted ? buildSessionExport(
5667
5892
  includeBatchMoveEnvelope ? editsForPlan : [sessionEdit],
5668
5893
  [],
5669
5894
  {
@@ -5679,7 +5904,7 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
5679
5904
  }));
5680
5905
  const moveIntent = sessionEdit.move ? getMoveIntentForEdit(sessionEdit, resolvedPlanContext) : null;
5681
5906
  const movePlan = includeBatchMoveEnvelope ? resolvedPlanContext.movePlan : null;
5682
- const hasMeaningfulPayload = changes.length > 0 || sessionEdit.textEdit != null || moveIntent != null;
5907
+ const hasMeaningfulPayload = changes.length > 0 || sessionEdit.textEdit != null || moveIntent != null || Boolean(sessionEdit.deleted);
5683
5908
  if (!hasMeaningfulPayload) return true;
5684
5909
  const profile = getExportContentProfile(
5685
5910
  [sessionEdit],
@@ -5693,17 +5918,44 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
5693
5918
  textChange: sessionEdit.textEdit ?? null,
5694
5919
  moveIntent,
5695
5920
  ...movePlan ? { movePlan } : {},
5921
+ ...sessionEdit.deleted ? { deleted: true } : {},
5696
5922
  exportMarkdown: withInstruction(profile, exportMarkdown)
5697
5923
  });
5698
5924
  if (result.ok) {
5699
5925
  removeSessionEdit(sessionEdit.element);
5926
+ updateAgentAvailability(true);
5927
+ } else {
5928
+ const kind = result.errorKind === "network" ? "unreachable" : "rejected";
5929
+ updateAgentAvailability(result.errorKind === "network" ? false : true);
5930
+ if (options?._isBatchCall) {
5931
+ options._batchFailKinds?.push(result.errorKind ?? "rejected");
5932
+ } else if (isMountedRef.current) {
5933
+ setLastSendFailure({
5934
+ reason: kind,
5935
+ failedEditElements: [sessionEdit.element],
5936
+ failedCommentIds: [],
5937
+ at: Date.now()
5938
+ });
5939
+ }
5700
5940
  }
5701
- return updateAgentAvailability(result.ok);
5702
- } catch {
5703
- return updateAgentAvailability(false);
5941
+ return result.ok;
5942
+ } catch (err) {
5943
+ updateAgentAvailability(false);
5944
+ if (options?._isBatchCall) {
5945
+ throw err;
5946
+ }
5947
+ if (isMountedRef.current) {
5948
+ setLastSendFailure({
5949
+ reason: "unreachable",
5950
+ failedEditElements: [sessionEdit.element],
5951
+ failedCommentIds: [],
5952
+ at: Date.now()
5953
+ });
5954
+ }
5955
+ return false;
5704
5956
  }
5705
5957
  }, [updateAgentAvailability, removeSessionEdit]);
5706
- const sendSessionCommentToAgent = React5.useCallback(async (comment) => {
5958
+ const sendSessionCommentToAgent = React5.useCallback(async (comment, _options) => {
5707
5959
  const exportMarkdown = buildCommentExport(comment.locator, comment.text, comment.replies);
5708
5960
  const commentProfile = { hasCssEdits: false, hasTextEdits: false, hasMoves: false, hasComments: true };
5709
5961
  try {
@@ -5715,13 +5967,40 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
5715
5967
  });
5716
5968
  if (result.ok) {
5717
5969
  deleteComment(comment.id);
5970
+ updateAgentAvailability(true);
5971
+ } else {
5972
+ const kind = result.errorKind === "network" ? "unreachable" : "rejected";
5973
+ updateAgentAvailability(result.errorKind === "network" ? false : true);
5974
+ if (_options?._isBatchCall) {
5975
+ _options._batchFailKinds?.push(result.errorKind ?? "rejected");
5976
+ } else if (isMountedRef.current) {
5977
+ setLastSendFailure({
5978
+ reason: kind,
5979
+ failedEditElements: [],
5980
+ failedCommentIds: [comment.id],
5981
+ at: Date.now()
5982
+ });
5983
+ }
5718
5984
  }
5719
- return updateAgentAvailability(result.ok);
5720
- } catch {
5721
- return updateAgentAvailability(false);
5985
+ return result.ok;
5986
+ } catch (err) {
5987
+ updateAgentAvailability(false);
5988
+ if (_options?._isBatchCall) {
5989
+ throw err;
5990
+ }
5991
+ if (isMountedRef.current) {
5992
+ setLastSendFailure({
5993
+ reason: "unreachable",
5994
+ failedEditElements: [],
5995
+ failedCommentIds: [comment.id],
5996
+ at: Date.now()
5997
+ });
5998
+ }
5999
+ return false;
5722
6000
  }
5723
6001
  }, [updateAgentAvailability, deleteComment]);
5724
6002
  const sendEditToAgent2 = React5.useCallback(async () => {
6003
+ if (isMountedRef.current) setLastSendFailure(null);
5725
6004
  const current = stateRef.current;
5726
6005
  if (current.selectedElements.length > 1) {
5727
6006
  saveCurrentToSession();
@@ -5756,9 +6035,28 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
5756
6035
  removeSessionEdit(el);
5757
6036
  }
5758
6037
  }
6038
+ updateAgentAvailability(true);
6039
+ } else {
6040
+ updateAgentAvailability(result.errorKind === "network" ? false : true);
6041
+ if (isMountedRef.current) {
6042
+ setLastSendFailure({
6043
+ reason: result.errorKind === "network" ? "unreachable" : "rejected",
6044
+ failedEditElements: editsWithChanges.map((e) => e.element),
6045
+ failedCommentIds: [],
6046
+ at: Date.now()
6047
+ });
6048
+ }
5759
6049
  }
5760
- return updateAgentAvailability(result.ok);
6050
+ return result.ok;
5761
6051
  } catch {
6052
+ if (isMountedRef.current) {
6053
+ setLastSendFailure({
6054
+ reason: "unreachable",
6055
+ failedEditElements: editsWithChanges.map((e) => e.element),
6056
+ failedCommentIds: [],
6057
+ at: Date.now()
6058
+ });
6059
+ }
5762
6060
  return updateAgentAvailability(false);
5763
6061
  }
5764
6062
  }
@@ -5781,11 +6079,13 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
5781
6079
  return sendSessionEditToAgent(editToSend);
5782
6080
  }, [canSendEditToAgent, sendSessionEditToAgent, saveCurrentToSession]);
5783
6081
  const sendCommentToAgent2 = React5.useCallback(async (id) => {
6082
+ if (isMountedRef.current) setLastSendFailure(null);
5784
6083
  const comment = stateRef.current.comments.find((c) => c.id === id);
5785
6084
  if (!comment) return false;
5786
6085
  return sendSessionCommentToAgent(comment);
5787
6086
  }, [sendSessionCommentToAgent]);
5788
6087
  const sendAllSessionItemsToAgent = React5.useCallback(async () => {
6088
+ if (isMountedRef.current) setLastSendFailure(null);
5789
6089
  const items = getSessionItems();
5790
6090
  const current = stateRef.current;
5791
6091
  const contextOnlyBlocks = getContextOnlyBlocks(current.selectedElements, items);
@@ -5794,25 +6094,44 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
5794
6094
  const movePlanContext = buildMovePlanContext(allEdits);
5795
6095
  let moveEnvelopeSent = false;
5796
6096
  let allSucceeded = true;
6097
+ const failedEditElements = [];
6098
+ const failedCommentIds = [];
6099
+ let anyThrown = false;
6100
+ const batchFailKinds = [];
5797
6101
  for (const item of items) {
5798
6102
  let succeeded;
5799
6103
  if (item.type === "edit") {
5800
6104
  const hasMoveIntent = Boolean(item.edit.move && getMoveIntentForEdit(item.edit, movePlanContext));
5801
6105
  const includeBatchMoveEnvelope = hasMoveIntent && !moveEnvelopeSent;
5802
- succeeded = await sendSessionEditToAgent(
5803
- item.edit,
5804
- allEdits,
5805
- movePlanContext,
5806
- { includeBatchMoveEnvelope }
5807
- );
6106
+ try {
6107
+ succeeded = await sendSessionEditToAgent(
6108
+ item.edit,
6109
+ allEdits,
6110
+ movePlanContext,
6111
+ { includeBatchMoveEnvelope, _isBatchCall: true, _batchFailKinds: batchFailKinds }
6112
+ );
6113
+ if (!succeeded) failedEditElements.push(item.edit.element);
6114
+ } catch {
6115
+ succeeded = false;
6116
+ anyThrown = true;
6117
+ failedEditElements.push(item.edit.element);
6118
+ }
5808
6119
  if (includeBatchMoveEnvelope) moveEnvelopeSent = true;
5809
6120
  } else {
5810
- succeeded = await sendSessionCommentToAgent(item.comment);
6121
+ try {
6122
+ succeeded = await sendSessionCommentToAgent(item.comment, { _isBatchCall: true, _batchFailKinds: batchFailKinds });
6123
+ if (!succeeded) failedCommentIds.push(item.comment.id);
6124
+ } catch {
6125
+ succeeded = false;
6126
+ anyThrown = true;
6127
+ failedCommentIds.push(item.comment.id);
6128
+ }
5811
6129
  }
5812
6130
  if (!succeeded) {
5813
6131
  allSucceeded = false;
5814
6132
  }
5815
6133
  }
6134
+ let contextBlockFailed = false;
5816
6135
  if (contextOnlyBlocks.length > 0) {
5817
6136
  const primaryEl = current.selectedElements.find(
5818
6137
  (el) => el.isConnected && !allEdits.some((e) => e.element === el)
@@ -5826,16 +6145,39 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
5826
6145
  moveIntent: null,
5827
6146
  exportMarkdown: contextOnlyBlocks.join("\n\n")
5828
6147
  });
5829
- if (!result.ok) allSucceeded = false;
6148
+ if (result.ok) {
6149
+ updateAgentAvailability(true);
6150
+ } else {
6151
+ updateAgentAvailability(result.errorKind === "network" ? false : true);
6152
+ allSucceeded = false;
6153
+ contextBlockFailed = true;
6154
+ }
5830
6155
  } catch {
6156
+ updateAgentAvailability(false);
5831
6157
  allSucceeded = false;
6158
+ anyThrown = true;
6159
+ contextBlockFailed = true;
5832
6160
  }
5833
6161
  }
5834
6162
  }
6163
+ if (!allSucceeded && isMountedRef.current) {
6164
+ const reason = anyThrown || batchFailKinds.includes("network") ? "unreachable" : "rejected";
6165
+ setLastSendFailure({
6166
+ reason,
6167
+ failedEditElements,
6168
+ failedCommentIds,
6169
+ at: Date.now()
6170
+ });
6171
+ }
5835
6172
  return allSucceeded;
5836
- }, [getSessionItems, sendSessionCommentToAgent, sendSessionEditToAgent]);
6173
+ }, [getSessionItems, sendSessionCommentToAgent, sendSessionEditToAgent, updateAgentAvailability]);
6174
+ const clearSendFailure = React5.useCallback(() => {
6175
+ if (isMountedRef.current) setLastSendFailure(null);
6176
+ }, []);
5837
6177
  return {
5838
6178
  agentAvailable,
6179
+ lastSendFailure,
6180
+ clearSendFailure,
5839
6181
  canSendEditToAgent,
5840
6182
  sendEditToAgent: sendEditToAgent2,
5841
6183
  sendCommentToAgent: sendCommentToAgent2,
@@ -5882,7 +6224,9 @@ function useKeyboardShortcuts({
5882
6224
  const s = stateRef.current;
5883
6225
  const undoShortcutPressed = usesMetaForUndo ? e.metaKey && !e.ctrlKey && !e.altKey : e.ctrlKey && !e.metaKey && !e.altKey;
5884
6226
  if (undoShortcutPressed && e.key === "z" && !e.shiftKey) {
6227
+ if (!s.editModeActive) return;
5885
6228
  if (s.textEditingElement) return;
6229
+ if (isInputFocused()) return;
5886
6230
  e.preventDefault();
5887
6231
  undo();
5888
6232
  return;
@@ -5937,6 +6281,11 @@ function useKeyboardShortcuts({
5937
6281
  insertElement("frame");
5938
6282
  return;
5939
6283
  }
6284
+ if (lowerKey === "t") {
6285
+ e.preventDefault();
6286
+ insertElement("text");
6287
+ return;
6288
+ }
5940
6289
  if (lowerKey === "d") {
5941
6290
  e.preventDefault();
5942
6291
  insertElement("div");
@@ -6599,6 +6948,10 @@ function DirectEditProvider({ children }) {
6599
6948
  const undoStackRef = React8.useRef([]);
6600
6949
  const sessionEditsRef = React8.useRef(/* @__PURE__ */ new Map());
6601
6950
  const removedSessionEditsRef = React8.useRef(/* @__PURE__ */ new WeakSet());
6951
+ const commentDraftTextRef = React8.useRef("");
6952
+ const commentDraftBlockedHandlerRef = React8.useRef(null);
6953
+ const onElementInsertedRef = React8.useRef(null);
6954
+ const textInsertRafRef = React8.useRef(null);
6602
6955
  const [sessionEditCount, setSessionEditCount] = React8.useState(0);
6603
6956
  const stateRef = React8.useRef(state);
6604
6957
  React8.useEffect(() => {
@@ -6633,12 +6986,13 @@ function DirectEditProvider({ children }) {
6633
6986
  clearSessionEdits,
6634
6987
  groupSelection,
6635
6988
  deleteSelection,
6636
- insertElement
6989
+ insertElement: insertElementBase
6637
6990
  } = useSessionManager({
6638
6991
  stateRef,
6639
6992
  sessionEditsRef,
6640
6993
  removedSessionEditsRef,
6641
6994
  undoStackRef,
6995
+ onElementInsertedRef,
6642
6996
  pushUndo,
6643
6997
  setState,
6644
6998
  setSessionEditCount
@@ -6688,6 +7042,41 @@ function DirectEditProvider({ children }) {
6688
7042
  syncSessionItemCount,
6689
7043
  setState
6690
7044
  });
7045
+ React8.useEffect(() => {
7046
+ onElementInsertedRef.current = (kind, element) => {
7047
+ if (kind === "text") {
7048
+ if (textInsertRafRef.current) {
7049
+ cancelAnimationFrame(textInsertRafRef.current);
7050
+ }
7051
+ textInsertRafRef.current = requestAnimationFrame(() => {
7052
+ textInsertRafRef.current = null;
7053
+ if (element.isConnected) {
7054
+ startTextEditing(element);
7055
+ }
7056
+ });
7057
+ }
7058
+ };
7059
+ return () => {
7060
+ if (textInsertRafRef.current) {
7061
+ cancelAnimationFrame(textInsertRafRef.current);
7062
+ textInsertRafRef.current = null;
7063
+ }
7064
+ onElementInsertedRef.current = null;
7065
+ };
7066
+ }, [startTextEditing]);
7067
+ const setCommentDraftText = React8.useCallback((text) => {
7068
+ commentDraftTextRef.current = text;
7069
+ }, []);
7070
+ const setCommentDraftBlockedHandler = React8.useCallback((handler) => {
7071
+ commentDraftBlockedHandlerRef.current = handler;
7072
+ }, []);
7073
+ const hasPendingCommentDraft = React8.useCallback(() => {
7074
+ const activeCommentId = stateRef.current.activeCommentId;
7075
+ if (!activeCommentId) return false;
7076
+ const active = stateRef.current.comments.find((comment) => comment.id === activeCommentId);
7077
+ if (!active) return false;
7078
+ return active.text.trim().length === 0 && commentDraftTextRef.current.trim().length > 0;
7079
+ }, []);
6691
7080
  const { toggleCanvas, enterCanvas, exitCanvas, setCanvasZoom, fitCanvasToViewport, zoomCanvasTo100 } = useCanvas({
6692
7081
  stateRef,
6693
7082
  setState
@@ -6824,6 +7213,8 @@ function DirectEditProvider({ children }) {
6824
7213
  }, [state.editModeActive]);
6825
7214
  const {
6826
7215
  agentAvailable,
7216
+ lastSendFailure,
7217
+ clearSendFailure,
6827
7218
  canSendEditToAgent,
6828
7219
  sendEditToAgent: sendEditToAgent2,
6829
7220
  sendCommentToAgent: sendCommentToAgent2,
@@ -6850,6 +7241,16 @@ function DirectEditProvider({ children }) {
6850
7241
  } catch {
6851
7242
  }
6852
7243
  }, []);
7244
+ const insertElement = React8.useCallback((kind) => {
7245
+ if (hasPendingCommentDraft()) {
7246
+ commentDraftBlockedHandlerRef.current?.();
7247
+ return;
7248
+ }
7249
+ if (stateRef.current.textEditingElement) {
7250
+ commitTextEditing();
7251
+ }
7252
+ insertElementBase(kind);
7253
+ }, [commitTextEditing, hasPendingCommentDraft, insertElementBase, stateRef]);
6853
7254
  useKeyboardShortcuts({
6854
7255
  stateRef,
6855
7256
  toggleEditMode,
@@ -6879,9 +7280,10 @@ function DirectEditProvider({ children }) {
6879
7280
  const stateContextValue = React8.useMemo(() => ({
6880
7281
  ...state,
6881
7282
  agentAvailable,
7283
+ lastSendFailure,
6882
7284
  sessionEditCount,
6883
7285
  multiSelectContextCount
6884
- }), [agentAvailable, state, sessionEditCount, multiSelectContextCount]);
7286
+ }), [agentAvailable, lastSendFailure, state, sessionEditCount, multiSelectContextCount]);
6885
7287
  const actionsContextValue = React8.useMemo(() => ({
6886
7288
  selectElement,
6887
7289
  selectElements,
@@ -6904,6 +7306,7 @@ function DirectEditProvider({ children }) {
6904
7306
  updateTypographyProperty,
6905
7307
  resetToOriginal,
6906
7308
  exportEdits,
7309
+ clearSendFailure,
6907
7310
  canSendEditToAgent,
6908
7311
  sendEditToAgent: sendEditToAgent2,
6909
7312
  sendAllSessionItemsToAgent,
@@ -6928,6 +7331,8 @@ function DirectEditProvider({ children }) {
6928
7331
  removeSessionEdit,
6929
7332
  startTextEditing,
6930
7333
  commitTextEditing,
7334
+ setCommentDraftText,
7335
+ setCommentDraftBlockedHandler,
6931
7336
  groupSelection,
6932
7337
  deleteSelection,
6933
7338
  insertElement,
@@ -6957,6 +7362,7 @@ function DirectEditProvider({ children }) {
6957
7362
  updateTypographyProperty,
6958
7363
  resetToOriginal,
6959
7364
  exportEdits,
7365
+ clearSendFailure,
6960
7366
  canSendEditToAgent,
6961
7367
  sendEditToAgent2,
6962
7368
  sendAllSessionItemsToAgent,
@@ -6981,6 +7387,8 @@ function DirectEditProvider({ children }) {
6981
7387
  removeSessionEdit,
6982
7388
  startTextEditing,
6983
7389
  commitTextEditing,
7390
+ setCommentDraftText,
7391
+ setCommentDraftBlockedHandler,
6984
7392
  groupSelection,
6985
7393
  deleteSelection,
6986
7394
  insertElement,
@@ -7332,10 +7740,223 @@ function createDragInteractionGuard() {
7332
7740
  };
7333
7741
  }
7334
7742
  return {
7335
- activate,
7336
- deactivate
7743
+ activate,
7744
+ deactivate
7745
+ };
7746
+ }
7747
+
7748
+ // src/utils/resize-geometry.ts
7749
+ function toFinite(value, fallback) {
7750
+ if (!Number.isFinite(value)) return fallback;
7751
+ return value;
7752
+ }
7753
+ function multiplyMatrix(left, right) {
7754
+ return {
7755
+ a: left.a * right.a + left.c * right.b,
7756
+ b: left.b * right.a + left.d * right.b,
7757
+ c: left.a * right.c + left.c * right.d,
7758
+ d: left.b * right.c + left.d * right.d
7759
+ };
7760
+ }
7761
+ function splitTransformArgs(raw) {
7762
+ return raw.trim().replace(/,/g, " ").split(/\s+/).filter(Boolean);
7763
+ }
7764
+ function parseAngleRadians(value) {
7765
+ const numeric = Number.parseFloat(value);
7766
+ if (!Number.isFinite(numeric)) return 0;
7767
+ const unit = value.trim().replace(String(numeric), "").trim().toLowerCase();
7768
+ switch (unit) {
7769
+ case "rad":
7770
+ return numeric;
7771
+ case "turn":
7772
+ return numeric * Math.PI * 2;
7773
+ case "grad":
7774
+ return numeric * Math.PI / 200;
7775
+ case "deg":
7776
+ case "":
7777
+ default:
7778
+ return numeric * Math.PI / 180;
7779
+ }
7780
+ }
7781
+ function parseTransformFunction(name, rawArgs) {
7782
+ const args = splitTransformArgs(rawArgs);
7783
+ switch (name.toLowerCase()) {
7784
+ case "matrix": {
7785
+ if (args.length < 4) return null;
7786
+ const [a, b, c, d] = args.map(Number.parseFloat);
7787
+ if (![a, b, c, d].every(Number.isFinite)) return null;
7788
+ return { a, b, c, d };
7789
+ }
7790
+ case "matrix3d": {
7791
+ if (args.length < 16) return null;
7792
+ const values = args.map(Number.parseFloat);
7793
+ if (!values.every(Number.isFinite)) return null;
7794
+ return { a: values[0], b: values[1], c: values[4], d: values[5] };
7795
+ }
7796
+ case "scale": {
7797
+ const scaleX = Number.parseFloat(args[0] ?? "1");
7798
+ const scaleY = Number.parseFloat(args[1] ?? args[0] ?? "1");
7799
+ if (!Number.isFinite(scaleX) || !Number.isFinite(scaleY)) return null;
7800
+ return { a: scaleX, b: 0, c: 0, d: scaleY };
7801
+ }
7802
+ case "scalex": {
7803
+ const scaleX = Number.parseFloat(args[0] ?? "1");
7804
+ if (!Number.isFinite(scaleX)) return null;
7805
+ return { a: scaleX, b: 0, c: 0, d: 1 };
7806
+ }
7807
+ case "scaley": {
7808
+ const scaleY = Number.parseFloat(args[0] ?? "1");
7809
+ if (!Number.isFinite(scaleY)) return null;
7810
+ return { a: 1, b: 0, c: 0, d: scaleY };
7811
+ }
7812
+ case "rotate": {
7813
+ const angle = parseAngleRadians(args[0] ?? "0deg");
7814
+ const cos = Math.cos(angle);
7815
+ const sin = Math.sin(angle);
7816
+ return { a: cos, b: sin, c: -sin, d: cos };
7817
+ }
7818
+ case "translate":
7819
+ case "translatex":
7820
+ case "translatey":
7821
+ return { a: 1, b: 0, c: 0, d: 1 };
7822
+ default:
7823
+ return null;
7824
+ }
7825
+ }
7826
+ function parseTransformMatrix(transform) {
7827
+ const functionPattern = /([a-zA-Z0-9]+)\(([^)]*)\)/g;
7828
+ let matrix = { a: 1, b: 0, c: 0, d: 1 };
7829
+ let matched = false;
7830
+ for (const match of transform.matchAll(functionPattern)) {
7831
+ const next = parseTransformFunction(match[1], match[2]);
7832
+ if (!next) return null;
7833
+ matrix = multiplyMatrix(matrix, next);
7834
+ matched = true;
7835
+ }
7836
+ return matched ? matrix : null;
7837
+ }
7838
+ function scaleFromMatrix(matrix) {
7839
+ return {
7840
+ scaleX: Math.hypot(matrix.a, matrix.b) || 1,
7841
+ scaleY: Math.hypot(matrix.c, matrix.d) || 1
7842
+ };
7843
+ }
7844
+ function getRenderedOffsetScale(element) {
7845
+ const rect = element.getBoundingClientRect();
7846
+ const width = element.offsetWidth;
7847
+ const height = element.offsetHeight;
7848
+ if (width <= 0 || height <= 0 || rect.width <= 0 || rect.height <= 0) return null;
7849
+ return {
7850
+ scaleX: rect.width / width,
7851
+ scaleY: rect.height / height
7852
+ };
7853
+ }
7854
+ function clampSize(value, minSize = 1) {
7855
+ const safeMin = Math.max(1, toFinite(minSize, 1));
7856
+ const safeValue = toFinite(value, safeMin);
7857
+ return Math.max(safeMin, safeValue);
7858
+ }
7859
+ function getElementScale(element) {
7860
+ const transform = getComputedStyle(element).transform;
7861
+ if (!transform || transform === "none") {
7862
+ return getRenderedOffsetScale(element) ?? { scaleX: 1, scaleY: 1 };
7863
+ }
7864
+ let transformMatrix = null;
7865
+ if (typeof DOMMatrix !== "undefined") {
7866
+ try {
7867
+ const matrix = new DOMMatrix(transform);
7868
+ transformMatrix = matrix;
7869
+ } catch {
7870
+ }
7871
+ }
7872
+ transformMatrix = transformMatrix ?? parseTransformMatrix(transform);
7873
+ if (!transformMatrix) return getRenderedOffsetScale(element) ?? { scaleX: 1, scaleY: 1 };
7874
+ const localScale = scaleFromMatrix(transformMatrix);
7875
+ const rect = element.getBoundingClientRect();
7876
+ const width = element.offsetWidth;
7877
+ const height = element.offsetHeight;
7878
+ if (width <= 0 || height <= 0 || rect.width <= 0 || rect.height <= 0) return localScale;
7879
+ const transformedWidth = Math.abs(transformMatrix.a) * width + Math.abs(transformMatrix.c) * height;
7880
+ const transformedHeight = Math.abs(transformMatrix.b) * width + Math.abs(transformMatrix.d) * height;
7881
+ if (transformedWidth <= 0 || transformedHeight <= 0) return localScale;
7882
+ return {
7883
+ scaleX: rect.width / transformedWidth * localScale.scaleX,
7884
+ scaleY: rect.height / transformedHeight * localScale.scaleY
7337
7885
  };
7338
7886
  }
7887
+ function computeEdgeSize({
7888
+ handle,
7889
+ startWidth,
7890
+ startHeight,
7891
+ dx,
7892
+ dy,
7893
+ minSize = 1
7894
+ }) {
7895
+ const baseWidth = clampSize(startWidth, minSize);
7896
+ const baseHeight = clampSize(startHeight, minSize);
7897
+ switch (handle) {
7898
+ case "right":
7899
+ return { width: clampSize(baseWidth + dx, minSize), height: baseHeight };
7900
+ case "left":
7901
+ return { width: clampSize(baseWidth - dx, minSize), height: baseHeight };
7902
+ case "bottom":
7903
+ return { width: baseWidth, height: clampSize(baseHeight + dy, minSize) };
7904
+ case "top":
7905
+ return { width: baseWidth, height: clampSize(baseHeight - dy, minSize) };
7906
+ }
7907
+ }
7908
+ function computeCornerProportionalSize({
7909
+ handle,
7910
+ startWidth,
7911
+ startHeight,
7912
+ dx,
7913
+ dy,
7914
+ minSize = 1
7915
+ }) {
7916
+ const baseWidth = clampSize(startWidth, minSize);
7917
+ const baseHeight = clampSize(startHeight, minSize);
7918
+ const ratio = baseWidth > 0 && baseHeight > 0 ? baseWidth / baseHeight : 1;
7919
+ const widthSign = handle === "top-left" || handle === "bottom-left" ? -1 : 1;
7920
+ const heightSign = handle === "top-left" || handle === "top-right" ? -1 : 1;
7921
+ const rawWidth = baseWidth + widthSign * dx;
7922
+ const rawHeight = baseHeight + heightSign * dy;
7923
+ const widthIntent = clampSize(rawWidth, minSize);
7924
+ const heightIntent = clampSize(rawHeight, minSize);
7925
+ const widthChange = Math.abs(widthIntent - baseWidth) / Math.max(baseWidth, 1);
7926
+ const heightChange = Math.abs(heightIntent - baseHeight) / Math.max(baseHeight, 1);
7927
+ if (widthChange >= heightChange) {
7928
+ const width2 = clampSize(widthIntent, minSize);
7929
+ const height2 = clampSize(width2 / Math.max(ratio, 1e-4), minSize);
7930
+ return { width: width2, height: height2 };
7931
+ }
7932
+ const height = clampSize(heightIntent, minSize);
7933
+ const width = clampSize(height * ratio, minSize);
7934
+ return { width, height };
7935
+ }
7936
+ function computeFillRenderedWidth(element) {
7937
+ const parent = element.parentElement;
7938
+ if (!parent) return null;
7939
+ const parentComputed = window.getComputedStyle(parent);
7940
+ const elementComputed = window.getComputedStyle(element);
7941
+ const parentClientWidth = parent.clientWidth;
7942
+ const parentPaddingLeft = parseFloat(parentComputed.paddingLeft) || 0;
7943
+ const parentPaddingRight = parseFloat(parentComputed.paddingRight) || 0;
7944
+ const parentContentWidth = parentClientWidth - parentPaddingLeft - parentPaddingRight;
7945
+ if (!Number.isFinite(parentContentWidth) || parentContentWidth <= 0) {
7946
+ return null;
7947
+ }
7948
+ const elementPaddingLeft = parseFloat(elementComputed.paddingLeft) || 0;
7949
+ const elementPaddingRight = parseFloat(elementComputed.paddingRight) || 0;
7950
+ const elementBorderLeft = parseFloat(elementComputed.borderLeftWidth) || 0;
7951
+ const elementBorderRight = parseFloat(elementComputed.borderRightWidth) || 0;
7952
+ if (elementComputed.boxSizing === "border-box") {
7953
+ return clampSize(parentContentWidth, 1);
7954
+ }
7955
+ return clampSize(
7956
+ parentContentWidth + elementPaddingLeft + elementPaddingRight + elementBorderLeft + elementBorderRight,
7957
+ 1
7958
+ );
7959
+ }
7339
7960
 
7340
7961
  // src/use-move.ts
7341
7962
  var INITIAL_DRAG_STATE = {
@@ -7409,10 +8030,14 @@ function useMove({ onMoveComplete }) {
7409
8030
  const onMoveCompleteRef = React12.useRef(onMoveComplete);
7410
8031
  const dragOptionsRef = React12.useRef(DEFAULT_DRAG_OPTIONS);
7411
8032
  const dragGuardRef = React12.useRef(createDragInteractionGuard());
7412
- const initialRectRef = React12.useRef(
7413
- { x: 0, y: 0, scaleX: 1, scaleY: 1 }
7414
- );
8033
+ const initialRectRef = React12.useRef({
8034
+ x: 0,
8035
+ y: 0,
8036
+ scaleX: 1,
8037
+ scaleY: 1
8038
+ });
7415
8039
  const originalTransformRef = React12.useRef("");
8040
+ const composeBaseRef = React12.useRef("");
7416
8041
  const reorderPreviewRef = React12.useRef(/* @__PURE__ */ new Map());
7417
8042
  React12.useEffect(() => {
7418
8043
  dragStateRef.current = dragState;
@@ -7426,79 +8051,85 @@ function useMove({ onMoveComplete }) {
7426
8051
  }
7427
8052
  reorderPreviewRef.current.clear();
7428
8053
  }, []);
7429
- const setReorderPreviewTransform = React12.useCallback((element, transform) => {
7430
- const existing = reorderPreviewRef.current.get(element);
7431
- if (!existing) {
7432
- reorderPreviewRef.current.set(element, {
7433
- transform: element.style.transform,
7434
- transition: element.style.transition
7435
- });
7436
- }
7437
- const originalTransition = reorderPreviewRef.current.get(element)?.transition ?? element.style.transition;
7438
- element.style.transition = withTransformTransition(originalTransition);
7439
- element.style.transform = transform;
7440
- }, []);
7441
- const applyReorderPreview = React12.useCallback((target, draggedElement, originalParent) => {
7442
- if (!target || !draggedElement) {
7443
- clearReorderPreview();
7444
- return;
7445
- }
7446
- const container = target.container;
7447
- const containerChildren = Array.from(container.children).filter(
7448
- (child) => child instanceof HTMLElement
7449
- );
7450
- const siblings = containerChildren.filter((child) => child !== draggedElement);
7451
- const insertIndex = getInsertIndex(siblings, target.insertBefore);
7452
- if (insertIndex === null) {
7453
- clearReorderPreview();
7454
- return;
7455
- }
7456
- const draggedRect = draggedElement.getBoundingClientRect();
7457
- const isHorizontal = isHorizontalDirection(target.flexDirection);
7458
- const dragSize = isHorizontal ? draggedRect.width : draggedRect.height;
7459
- if (!Number.isFinite(dragSize) || dragSize <= 0) {
7460
- clearReorderPreview();
7461
- return;
7462
- }
7463
- const sign = forwardVisualSign(target.flexDirection);
7464
- const shiftedElements = /* @__PURE__ */ new Map();
7465
- if (container === originalParent) {
7466
- const originalIndex = containerChildren.indexOf(draggedElement);
7467
- if (originalIndex >= 0) {
7468
- if (insertIndex > originalIndex) {
7469
- const shift = -sign * dragSize;
7470
- for (let i = originalIndex; i < insertIndex; i++) {
7471
- const sibling = siblings[i];
7472
- if (sibling) shiftedElements.set(sibling, shift);
7473
- }
7474
- } else if (insertIndex < originalIndex) {
7475
- const shift = sign * dragSize;
7476
- for (let i = insertIndex; i < originalIndex; i++) {
7477
- const sibling = siblings[i];
7478
- if (sibling) shiftedElements.set(sibling, shift);
8054
+ const setReorderPreviewTransform = React12.useCallback(
8055
+ (element, transform) => {
8056
+ const existing = reorderPreviewRef.current.get(element);
8057
+ if (!existing) {
8058
+ reorderPreviewRef.current.set(element, {
8059
+ transform: element.style.transform,
8060
+ transition: element.style.transition
8061
+ });
8062
+ }
8063
+ const originalTransition = reorderPreviewRef.current.get(element)?.transition ?? element.style.transition;
8064
+ element.style.transition = withTransformTransition(originalTransition);
8065
+ element.style.transform = transform;
8066
+ },
8067
+ []
8068
+ );
8069
+ const applyReorderPreview = React12.useCallback(
8070
+ (target, draggedElement, originalParent) => {
8071
+ if (!target || !draggedElement) {
8072
+ clearReorderPreview();
8073
+ return;
8074
+ }
8075
+ const container = target.container;
8076
+ const containerChildren = Array.from(container.children).filter(
8077
+ (child) => child instanceof HTMLElement
8078
+ );
8079
+ const siblings = containerChildren.filter((child) => child !== draggedElement);
8080
+ const insertIndex = getInsertIndex(siblings, target.insertBefore);
8081
+ if (insertIndex === null) {
8082
+ clearReorderPreview();
8083
+ return;
8084
+ }
8085
+ const draggedRect = draggedElement.getBoundingClientRect();
8086
+ const isHorizontal = isHorizontalDirection(target.flexDirection);
8087
+ const dragSize = isHorizontal ? draggedRect.width : draggedRect.height;
8088
+ if (!Number.isFinite(dragSize) || dragSize <= 0) {
8089
+ clearReorderPreview();
8090
+ return;
8091
+ }
8092
+ const sign = forwardVisualSign(target.flexDirection);
8093
+ const shiftedElements = /* @__PURE__ */ new Map();
8094
+ if (container === originalParent) {
8095
+ const originalIndex = containerChildren.indexOf(draggedElement);
8096
+ if (originalIndex >= 0) {
8097
+ if (insertIndex > originalIndex) {
8098
+ const shift = -sign * dragSize;
8099
+ for (let i = originalIndex; i < insertIndex; i++) {
8100
+ const sibling = siblings[i];
8101
+ if (sibling) shiftedElements.set(sibling, shift);
8102
+ }
8103
+ } else if (insertIndex < originalIndex) {
8104
+ const shift = sign * dragSize;
8105
+ for (let i = insertIndex; i < originalIndex; i++) {
8106
+ const sibling = siblings[i];
8107
+ if (sibling) shiftedElements.set(sibling, shift);
8108
+ }
7479
8109
  }
7480
8110
  }
8111
+ } else {
8112
+ const shift = sign * dragSize;
8113
+ for (let i = insertIndex; i < siblings.length; i++) {
8114
+ shiftedElements.set(siblings[i], shift);
8115
+ }
7481
8116
  }
7482
- } else {
7483
- const shift = sign * dragSize;
7484
- for (let i = insertIndex; i < siblings.length; i++) {
7485
- shiftedElements.set(siblings[i], shift);
8117
+ const axis = isHorizontal ? "x" : "y";
8118
+ const keep = new Set(shiftedElements.keys());
8119
+ for (const [element, snapshot2] of reorderPreviewRef.current) {
8120
+ if (!keep.has(element)) {
8121
+ element.style.transform = snapshot2.transform;
8122
+ element.style.transition = snapshot2.transition;
8123
+ reorderPreviewRef.current.delete(element);
8124
+ }
7486
8125
  }
7487
- }
7488
- const axis = isHorizontal ? "x" : "y";
7489
- const keep = new Set(shiftedElements.keys());
7490
- for (const [element, snapshot2] of reorderPreviewRef.current) {
7491
- if (!keep.has(element)) {
7492
- element.style.transform = snapshot2.transform;
7493
- element.style.transition = snapshot2.transition;
7494
- reorderPreviewRef.current.delete(element);
8126
+ for (const [element, shift] of shiftedElements) {
8127
+ const baseTransform = reorderPreviewRef.current.get(element)?.transform ?? element.style.transform;
8128
+ setReorderPreviewTransform(element, withAxisTranslate(baseTransform, axis, shift));
7495
8129
  }
7496
- }
7497
- for (const [element, shift] of shiftedElements) {
7498
- const baseTransform = reorderPreviewRef.current.get(element)?.transform ?? element.style.transform;
7499
- setReorderPreviewTransform(element, withAxisTranslate(baseTransform, axis, shift));
7500
- }
7501
- }, [clearReorderPreview, setReorderPreviewTransform]);
8130
+ },
8131
+ [clearReorderPreview, setReorderPreviewTransform]
8132
+ );
7502
8133
  const cancelDrag = React12.useCallback(() => {
7503
8134
  const current = dragStateRef.current;
7504
8135
  if (current.draggedElement) {
@@ -7507,6 +8138,7 @@ function useMove({ onMoveComplete }) {
7507
8138
  }
7508
8139
  clearReorderPreview();
7509
8140
  originalTransformRef.current = "";
8141
+ composeBaseRef.current = "";
7510
8142
  initialRectRef.current = { x: 0, y: 0, scaleX: 1, scaleY: 1 };
7511
8143
  dragOptionsRef.current = DEFAULT_DRAG_OPTIONS;
7512
8144
  dragGuardRef.current.deactivate();
@@ -7528,6 +8160,7 @@ function useMove({ onMoveComplete }) {
7528
8160
  draggedElement.style.opacity = "";
7529
8161
  clearReorderPreview();
7530
8162
  originalTransformRef.current = "";
8163
+ composeBaseRef.current = "";
7531
8164
  initialRectRef.current = { x: 0, y: 0, scaleX: 1, scaleY: 1 };
7532
8165
  const dragMode = dragOptionsRef.current.mode;
7533
8166
  dragOptionsRef.current = DEFAULT_DRAG_OPTIONS;
@@ -7556,7 +8189,13 @@ function useMove({ onMoveComplete }) {
7556
8189
  const deltaX = (current.ghostPosition.x - rect.left) / scaleX;
7557
8190
  const deltaY = (current.ghostPosition.y - rect.top) / scaleY;
7558
8191
  if ((Math.abs(deltaX) > 0.5 || Math.abs(deltaY) > 0.5) && originalParent) {
7559
- moveInfo = { originalParent, originalPreviousSibling, originalNextSibling, mode: "position", positionDelta: { x: deltaX, y: deltaY } };
8192
+ moveInfo = {
8193
+ originalParent,
8194
+ originalPreviousSibling,
8195
+ originalNextSibling,
8196
+ mode: "position",
8197
+ positionDelta: { x: deltaX, y: deltaY }
8198
+ };
7560
8199
  }
7561
8200
  }
7562
8201
  } else if (target && tryReparent(draggedElement, target, originalParent, originalNextSibling)) {
@@ -7582,13 +8221,21 @@ function useMove({ onMoveComplete }) {
7582
8221
  const previousSibling = element.previousElementSibling;
7583
8222
  const nextSibling = element.nextElementSibling;
7584
8223
  dragOptionsRef.current = normalizeStartDragOptions(options);
8224
+ const { scaleX, scaleY } = getElementScale(element);
7585
8225
  initialRectRef.current = {
7586
8226
  x: rect.left,
7587
8227
  y: rect.top,
7588
- scaleX: element.offsetWidth > 0 ? rect.width / element.offsetWidth : 1,
7589
- scaleY: element.offsetHeight > 0 ? rect.height / element.offsetHeight : 1
8228
+ scaleX,
8229
+ scaleY
7590
8230
  };
7591
- originalTransformRef.current = element.style.transform;
8231
+ const inlineTransform = element.style.transform;
8232
+ originalTransformRef.current = inlineTransform;
8233
+ if (inlineTransform) {
8234
+ composeBaseRef.current = inlineTransform;
8235
+ } else {
8236
+ const computed = getComputedStyle(element).transform;
8237
+ composeBaseRef.current = computed && computed !== "none" ? computed : "";
8238
+ }
7592
8239
  dragGuardRef.current.activate();
7593
8240
  setDragState({
7594
8241
  isDragging: true,
@@ -7621,7 +8268,8 @@ function useMove({ onMoveComplete }) {
7621
8268
  const { x, y, scaleX, scaleY } = initialRectRef.current;
7622
8269
  const dx = (e.clientX - dragOffset.x - x) / scaleX;
7623
8270
  const dy = (e.clientY - dragOffset.y - y) / scaleY;
7624
- draggedElement.style.transform = `translate(${dx}px, ${dy}px)`;
8271
+ const base = composeBaseRef.current;
8272
+ draggedElement.style.transform = base ? `translate(${dx}px, ${dy}px) ${base}` : `translate(${dx}px, ${dy}px)`;
7625
8273
  }
7626
8274
  if (dragOptionsRef.current.mode === "position") {
7627
8275
  let container2 = findLayoutContainerAtPoint(
@@ -7662,19 +8310,9 @@ function useMove({ onMoveComplete }) {
7662
8310
  }
7663
8311
  return;
7664
8312
  }
7665
- const container = dragOptionsRef.current.constrainToOriginalParent ? originalParent : findContainerAtPoint(
7666
- e.clientX,
7667
- e.clientY,
7668
- draggedElement,
7669
- originalParent
7670
- );
8313
+ const container = dragOptionsRef.current.constrainToOriginalParent ? originalParent : findContainerAtPoint(e.clientX, e.clientY, draggedElement, originalParent);
7671
8314
  if (container && draggedElement) {
7672
- const dropPos = calculateDropPosition(
7673
- container,
7674
- e.clientX,
7675
- e.clientY,
7676
- draggedElement
7677
- );
8315
+ const dropPos = calculateDropPosition(container, e.clientX, e.clientY, draggedElement);
7678
8316
  if (dropPos) {
7679
8317
  const nextTarget = {
7680
8318
  container,
@@ -8047,7 +8685,10 @@ function isSelectableElement(element) {
8047
8685
  if (!(element instanceof HTMLElement)) return false;
8048
8686
  if (!element.isConnected) return false;
8049
8687
  if (element === document.body || element === document.documentElement) return false;
8050
- if (element.matches("[data-direct-edit], [data-direct-edit-host], script, style, link, meta, noscript")) return false;
8688
+ if (element.matches(
8689
+ "[data-direct-edit], [data-direct-edit-host], script, style, link, meta, noscript"
8690
+ ))
8691
+ return false;
8051
8692
  const rect = element.getBoundingClientRect();
8052
8693
  if (rect.width <= 0 || rect.height <= 0) return false;
8053
8694
  const computed = window.getComputedStyle(element);
@@ -8065,7 +8706,9 @@ function compareDomOrder2(a, b) {
8065
8706
  }
8066
8707
  function collectMarqueeTargets(rect) {
8067
8708
  const hits = Array.from(document.querySelectorAll("*")).filter(isSelectableElement).filter((element) => rectsIntersect(rect, element.getBoundingClientRect()));
8068
- const deepestHits = hits.filter((element) => !hits.some((other) => other !== element && element.contains(other)));
8709
+ const deepestHits = hits.filter(
8710
+ (element) => !hits.some((other) => other !== element && element.contains(other))
8711
+ );
8069
8712
  deepestHits.sort(compareDomOrder2);
8070
8713
  return deepestHits;
8071
8714
  }
@@ -8488,6 +9131,7 @@ function SelectedCommentComposer({
8488
9131
  comment,
8489
9132
  attentionNonce,
8490
9133
  draftRef,
9134
+ onDraftTextChange,
8491
9135
  onSubmit,
8492
9136
  onCancel
8493
9137
  }) {
@@ -8533,7 +9177,8 @@ function SelectedCommentComposer({
8533
9177
  }, [attentionNonce]);
8534
9178
  React17.useEffect(() => {
8535
9179
  if (draftRef) draftRef.current = text;
8536
- }, [draftRef, text]);
9180
+ onDraftTextChange?.(text);
9181
+ }, [draftRef, onDraftTextChange, text]);
8537
9182
  const submit = React17.useCallback(() => {
8538
9183
  const nextText = text.trim();
8539
9184
  if (!nextText) return;
@@ -8592,161 +9237,89 @@ function SelectedCommentComposer({
8592
9237
  } else if (e.key === "Escape") {
8593
9238
  onCancel();
8594
9239
  }
8595
- }
8596
- }
8597
- ),
8598
- /* @__PURE__ */ jsx7(
8599
- Button,
8600
- {
8601
- type: "button",
8602
- variant: "ghost",
8603
- size: "icon",
8604
- className: cn(
8605
- "size-7 shrink-0 self-start",
8606
- text.trim() ? "bg-blue-500 text-white hover:bg-blue-600" : "bg-muted text-muted-foreground"
8607
- ),
8608
- disabled: !text.trim(),
8609
- onClick: submit,
8610
- children: /* @__PURE__ */ jsx7(ArrowUp, {})
8611
- }
8612
- )
8613
- ]
8614
- }
8615
- );
8616
- }
8617
-
8618
- // src/move-overlay.tsx
8619
- import { jsx as jsx8 } from "react/jsx-runtime";
8620
- var BLUE2 = "#0D99FF";
8621
- function MoveOverlay({ dropIndicator }) {
8622
- if (!dropIndicator) {
8623
- return null;
8624
- }
8625
- return /* @__PURE__ */ jsx8(
8626
- "svg",
8627
- {
8628
- "data-direct-edit": "move-overlay",
8629
- style: {
8630
- position: "fixed",
8631
- inset: 0,
8632
- width: "100vw",
8633
- height: "100vh",
8634
- pointerEvents: "none",
8635
- zIndex: 99997
8636
- },
8637
- children: /* @__PURE__ */ jsx8(
8638
- "rect",
8639
- {
8640
- x: dropIndicator.x,
8641
- y: dropIndicator.y,
8642
- width: dropIndicator.width,
8643
- height: dropIndicator.height,
8644
- fill: BLUE2
8645
- }
8646
- )
8647
- }
8648
- );
8649
- }
8650
-
8651
- // src/selection-overlay.tsx
8652
- import * as React19 from "react";
8653
- import { MessageSquare } from "lucide-react";
8654
-
8655
- // src/use-selection-resize.ts
8656
- import * as React18 from "react";
8657
-
8658
- // src/utils/resize-geometry.ts
8659
- function toFinite(value, fallback) {
8660
- if (!Number.isFinite(value)) return fallback;
8661
- return value;
8662
- }
8663
- function clampSize(value, minSize = 1) {
8664
- const safeMin = Math.max(1, toFinite(minSize, 1));
8665
- const safeValue = toFinite(value, safeMin);
8666
- return Math.max(safeMin, safeValue);
8667
- }
8668
- function computeEdgeSize({
8669
- handle,
8670
- startWidth,
8671
- startHeight,
8672
- dx,
8673
- dy,
8674
- minSize = 1
8675
- }) {
8676
- const baseWidth = clampSize(startWidth, minSize);
8677
- const baseHeight = clampSize(startHeight, minSize);
8678
- switch (handle) {
8679
- case "right":
8680
- return { width: clampSize(baseWidth + dx, minSize), height: baseHeight };
8681
- case "left":
8682
- return { width: clampSize(baseWidth - dx, minSize), height: baseHeight };
8683
- case "bottom":
8684
- return { width: baseWidth, height: clampSize(baseHeight + dy, minSize) };
8685
- case "top":
8686
- return { width: baseWidth, height: clampSize(baseHeight - dy, minSize) };
8687
- }
8688
- }
8689
- function computeCornerProportionalSize({
8690
- handle,
8691
- startWidth,
8692
- startHeight,
8693
- dx,
8694
- dy,
8695
- minSize = 1
8696
- }) {
8697
- const baseWidth = clampSize(startWidth, minSize);
8698
- const baseHeight = clampSize(startHeight, minSize);
8699
- const ratio = baseWidth > 0 && baseHeight > 0 ? baseWidth / baseHeight : 1;
8700
- const widthSign = handle === "top-left" || handle === "bottom-left" ? -1 : 1;
8701
- const heightSign = handle === "top-left" || handle === "top-right" ? -1 : 1;
8702
- const rawWidth = baseWidth + widthSign * dx;
8703
- const rawHeight = baseHeight + heightSign * dy;
8704
- const widthIntent = clampSize(rawWidth, minSize);
8705
- const heightIntent = clampSize(rawHeight, minSize);
8706
- const widthChange = Math.abs(widthIntent - baseWidth) / Math.max(baseWidth, 1);
8707
- const heightChange = Math.abs(heightIntent - baseHeight) / Math.max(baseHeight, 1);
8708
- if (widthChange >= heightChange) {
8709
- const width2 = clampSize(widthIntent, minSize);
8710
- const height2 = clampSize(width2 / Math.max(ratio, 1e-4), minSize);
8711
- return { width: width2, height: height2 };
8712
- }
8713
- const height = clampSize(heightIntent, minSize);
8714
- const width = clampSize(height * ratio, minSize);
8715
- return { width, height };
9240
+ }
9241
+ }
9242
+ ),
9243
+ /* @__PURE__ */ jsx7(
9244
+ Button,
9245
+ {
9246
+ type: "button",
9247
+ variant: "ghost",
9248
+ size: "icon",
9249
+ className: cn(
9250
+ "size-7 shrink-0 self-start",
9251
+ text.trim() ? "bg-blue-500 text-white hover:bg-blue-600" : "bg-muted text-muted-foreground"
9252
+ ),
9253
+ disabled: !text.trim(),
9254
+ onClick: submit,
9255
+ children: /* @__PURE__ */ jsx7(ArrowUp, {})
9256
+ }
9257
+ )
9258
+ ]
9259
+ }
9260
+ );
8716
9261
  }
8717
- function computeFillRenderedWidth(element) {
8718
- const parent = element.parentElement;
8719
- if (!parent) return null;
8720
- const parentComputed = window.getComputedStyle(parent);
8721
- const elementComputed = window.getComputedStyle(element);
8722
- const parentClientWidth = parent.clientWidth;
8723
- const parentPaddingLeft = parseFloat(parentComputed.paddingLeft) || 0;
8724
- const parentPaddingRight = parseFloat(parentComputed.paddingRight) || 0;
8725
- const parentContentWidth = parentClientWidth - parentPaddingLeft - parentPaddingRight;
8726
- if (!Number.isFinite(parentContentWidth) || parentContentWidth <= 0) {
9262
+
9263
+ // src/move-overlay.tsx
9264
+ import { jsx as jsx8 } from "react/jsx-runtime";
9265
+ var BLUE2 = "#0D99FF";
9266
+ function MoveOverlay({ dropIndicator }) {
9267
+ if (!dropIndicator) {
8727
9268
  return null;
8728
9269
  }
8729
- const elementPaddingLeft = parseFloat(elementComputed.paddingLeft) || 0;
8730
- const elementPaddingRight = parseFloat(elementComputed.paddingRight) || 0;
8731
- const elementBorderLeft = parseFloat(elementComputed.borderLeftWidth) || 0;
8732
- const elementBorderRight = parseFloat(elementComputed.borderRightWidth) || 0;
8733
- if (elementComputed.boxSizing === "border-box") {
8734
- return clampSize(parentContentWidth, 1);
8735
- }
8736
- return clampSize(
8737
- parentContentWidth + elementPaddingLeft + elementPaddingRight + elementBorderLeft + elementBorderRight,
8738
- 1
9270
+ return /* @__PURE__ */ jsx8(
9271
+ "svg",
9272
+ {
9273
+ "data-direct-edit": "move-overlay",
9274
+ style: {
9275
+ position: "fixed",
9276
+ inset: 0,
9277
+ width: "100vw",
9278
+ height: "100vh",
9279
+ pointerEvents: "none",
9280
+ zIndex: 99997
9281
+ },
9282
+ children: /* @__PURE__ */ jsx8(
9283
+ "rect",
9284
+ {
9285
+ x: dropIndicator.x,
9286
+ y: dropIndicator.y,
9287
+ width: dropIndicator.width,
9288
+ height: dropIndicator.height,
9289
+ fill: BLUE2
9290
+ }
9291
+ )
9292
+ }
8739
9293
  );
8740
9294
  }
8741
9295
 
9296
+ // src/selection-overlay.tsx
9297
+ import * as React19 from "react";
9298
+ import { MessageSquare } from "lucide-react";
9299
+
8742
9300
  // src/use-selection-resize.ts
9301
+ import * as React18 from "react";
8743
9302
  var MIN_SIZE_PX = 1;
8744
9303
  var SNAP_IN_PX = 2;
8745
9304
  var SNAP_OUT_PX = 6;
8746
9305
  var EPSILON = 1e-4;
8747
9306
  var EDGE_HANDLES = /* @__PURE__ */ new Set(["top", "right", "bottom", "left"]);
8748
- var WIDTH_HANDLES = /* @__PURE__ */ new Set(["left", "right", "top-left", "top-right", "bottom-left", "bottom-right"]);
8749
- var HEIGHT_HANDLES = /* @__PURE__ */ new Set(["top", "bottom", "top-left", "top-right", "bottom-left", "bottom-right"]);
9307
+ var WIDTH_HANDLES = /* @__PURE__ */ new Set([
9308
+ "left",
9309
+ "right",
9310
+ "top-left",
9311
+ "top-right",
9312
+ "bottom-left",
9313
+ "bottom-right"
9314
+ ]);
9315
+ var HEIGHT_HANDLES = /* @__PURE__ */ new Set([
9316
+ "top",
9317
+ "bottom",
9318
+ "top-left",
9319
+ "top-right",
9320
+ "bottom-left",
9321
+ "bottom-right"
9322
+ ]);
8750
9323
  function createSizingValue(mode, numericValue) {
8751
9324
  const rounded = Math.max(MIN_SIZE_PX, Math.round(clampSize(numericValue, MIN_SIZE_PX)));
8752
9325
  return {
@@ -8768,125 +9341,135 @@ function useSelectionResize({
8768
9341
  }) {
8769
9342
  const cleanupRef = React18.useRef(null);
8770
9343
  const txCounterRef = React18.useRef(0);
8771
- const emitSizingChange = React18.useCallback((changes, options) => {
8772
- onResizeSizingChange?.(changes, options);
8773
- }, [onResizeSizingChange]);
9344
+ const emitSizingChange = React18.useCallback(
9345
+ (changes, options) => {
9346
+ onResizeSizingChange?.(changes, options);
9347
+ },
9348
+ [onResizeSizingChange]
9349
+ );
8774
9350
  React18.useEffect(() => {
8775
9351
  return () => {
8776
9352
  cleanupRef.current?.();
8777
9353
  cleanupRef.current = null;
8778
9354
  };
8779
9355
  }, []);
8780
- const getResizeHandlePointerDown = React18.useCallback((handle) => {
8781
- return (e) => {
8782
- if (!enabled || !onResizeSizingChange) return;
8783
- if (e.button !== 0) return;
8784
- e.preventDefault();
8785
- e.stopPropagation();
8786
- cleanupRef.current?.();
8787
- const rect = selectedElement.getBoundingClientRect();
8788
- const offsetWidth = selectedElement.offsetWidth;
8789
- const offsetHeight = selectedElement.offsetHeight;
8790
- const startWidth = clampSize(offsetWidth > 0 ? offsetWidth : rect.width, MIN_SIZE_PX);
8791
- const startHeight = clampSize(offsetHeight > 0 ? offsetHeight : rect.height, MIN_SIZE_PX);
8792
- const scaleX = Math.max(EPSILON, offsetWidth > 0 ? rect.width / offsetWidth : 1);
8793
- const scaleY = Math.max(EPSILON, offsetHeight > 0 ? rect.height / offsetHeight : 1);
8794
- const transactionId = `resize-${Date.now()}-${txCounterRef.current++}`;
8795
- const state = {
8796
- transactionId,
8797
- handle,
8798
- startClientX: e.clientX,
8799
- startClientY: e.clientY,
8800
- startWidth,
8801
- startHeight,
8802
- scaleX,
8803
- scaleY,
8804
- fillTargetWidth: computeFillRenderedWidth(selectedElement),
8805
- fillLocked: detectSizingMode(selectedElement, "width") === "fill"
8806
- };
8807
- emitSizingChange({}, { transactionId: state.transactionId, phase: "start" });
8808
- const onPointerMove = (moveEvent) => {
8809
- const dx = (moveEvent.clientX - state.startClientX) / state.scaleX;
8810
- const dy = (moveEvent.clientY - state.startClientY) / state.scaleY;
8811
- const nextSize = isEdgeHandle(state.handle) ? computeEdgeSize({
8812
- handle: state.handle,
8813
- startWidth: state.startWidth,
8814
- startHeight: state.startHeight,
8815
- dx,
8816
- dy,
8817
- minSize: MIN_SIZE_PX
8818
- }) : computeCornerProportionalSize({
8819
- handle: state.handle,
8820
- startWidth: state.startWidth,
8821
- startHeight: state.startHeight,
8822
- dx,
8823
- dy,
8824
- minSize: MIN_SIZE_PX
8825
- });
8826
- const nextWidth = Math.max(MIN_SIZE_PX, Math.round(nextSize.width));
8827
- const nextHeight = Math.max(MIN_SIZE_PX, Math.round(nextSize.height));
8828
- const changes = {};
8829
- if (WIDTH_HANDLES.has(state.handle)) {
8830
- if (state.fillTargetWidth !== null) {
8831
- const distance = Math.abs(nextWidth - state.fillTargetWidth);
8832
- if (state.fillLocked) {
8833
- if (distance > SNAP_OUT_PX) {
8834
- state.fillLocked = false;
9356
+ const getResizeHandlePointerDown = React18.useCallback(
9357
+ (handle) => {
9358
+ return (e) => {
9359
+ if (!enabled || !onResizeSizingChange) return;
9360
+ if (e.button !== 0) return;
9361
+ e.preventDefault();
9362
+ e.stopPropagation();
9363
+ cleanupRef.current?.();
9364
+ const rect = selectedElement.getBoundingClientRect();
9365
+ const offsetWidth = selectedElement.offsetWidth;
9366
+ const offsetHeight = selectedElement.offsetHeight;
9367
+ const startWidth = clampSize(offsetWidth > 0 ? offsetWidth : rect.width, MIN_SIZE_PX);
9368
+ const startHeight = clampSize(offsetHeight > 0 ? offsetHeight : rect.height, MIN_SIZE_PX);
9369
+ const { scaleX: rawScaleX, scaleY: rawScaleY } = getElementScale(selectedElement);
9370
+ const scaleX = Math.max(EPSILON, rawScaleX);
9371
+ const scaleY = Math.max(EPSILON, rawScaleY);
9372
+ const transactionId = `resize-${Date.now()}-${txCounterRef.current++}`;
9373
+ const state = {
9374
+ transactionId,
9375
+ handle,
9376
+ startClientX: e.clientX,
9377
+ startClientY: e.clientY,
9378
+ startWidth,
9379
+ startHeight,
9380
+ scaleX,
9381
+ scaleY,
9382
+ fillTargetWidth: computeFillRenderedWidth(selectedElement),
9383
+ fillLocked: detectSizingMode(selectedElement, "width") === "fill"
9384
+ };
9385
+ emitSizingChange({}, { transactionId: state.transactionId, phase: "start" });
9386
+ const onPointerMove = (moveEvent) => {
9387
+ const dx = (moveEvent.clientX - state.startClientX) / state.scaleX;
9388
+ const dy = (moveEvent.clientY - state.startClientY) / state.scaleY;
9389
+ const nextSize = isEdgeHandle(state.handle) ? computeEdgeSize({
9390
+ handle: state.handle,
9391
+ startWidth: state.startWidth,
9392
+ startHeight: state.startHeight,
9393
+ dx,
9394
+ dy,
9395
+ minSize: MIN_SIZE_PX
9396
+ }) : computeCornerProportionalSize({
9397
+ handle: state.handle,
9398
+ startWidth: state.startWidth,
9399
+ startHeight: state.startHeight,
9400
+ dx,
9401
+ dy,
9402
+ minSize: MIN_SIZE_PX
9403
+ });
9404
+ const nextWidth = Math.max(MIN_SIZE_PX, Math.round(nextSize.width));
9405
+ const nextHeight = Math.max(MIN_SIZE_PX, Math.round(nextSize.height));
9406
+ const changes = {};
9407
+ if (WIDTH_HANDLES.has(state.handle)) {
9408
+ if (state.fillTargetWidth !== null) {
9409
+ const distance = Math.abs(nextWidth - state.fillTargetWidth);
9410
+ if (state.fillLocked) {
9411
+ if (distance > SNAP_OUT_PX) {
9412
+ state.fillLocked = false;
9413
+ }
9414
+ } else if (distance <= SNAP_IN_PX) {
9415
+ state.fillLocked = true;
8835
9416
  }
8836
- } else if (distance <= SNAP_IN_PX) {
8837
- state.fillLocked = true;
9417
+ } else {
9418
+ state.fillLocked = false;
9419
+ }
9420
+ if (state.fillLocked) {
9421
+ const fillWidth = state.fillTargetWidth ?? nextWidth;
9422
+ changes.width = createSizingValue("fill", fillWidth);
9423
+ } else {
9424
+ changes.width = createSizingValue("fixed", nextWidth);
8838
9425
  }
8839
- } else {
8840
- state.fillLocked = false;
8841
9426
  }
8842
- if (state.fillLocked) {
8843
- const fillWidth = state.fillTargetWidth ?? nextWidth;
8844
- changes.width = createSizingValue("fill", fillWidth);
8845
- } else {
8846
- changes.width = createSizingValue("fixed", nextWidth);
9427
+ if (HEIGHT_HANDLES.has(state.handle)) {
9428
+ changes.height = createSizingValue("fixed", nextHeight);
8847
9429
  }
8848
- }
8849
- if (HEIGHT_HANDLES.has(state.handle)) {
8850
- changes.height = createSizingValue("fixed", nextHeight);
8851
- }
8852
- if (Object.keys(changes).length === 0) return;
8853
- emitSizingChange(changes, { transactionId: state.transactionId, phase: "update" });
9430
+ if (Object.keys(changes).length === 0) return;
9431
+ emitSizingChange(changes, { transactionId: state.transactionId, phase: "update" });
9432
+ };
9433
+ const stop = () => {
9434
+ window.removeEventListener("pointermove", onPointerMove);
9435
+ window.removeEventListener("pointerup", stop);
9436
+ window.removeEventListener("pointercancel", stop);
9437
+ window.removeEventListener("blur", stop);
9438
+ cleanupRef.current = null;
9439
+ emitSizingChange({}, { transactionId: state.transactionId, phase: "end" });
9440
+ };
9441
+ cleanupRef.current = stop;
9442
+ window.addEventListener("pointermove", onPointerMove);
9443
+ window.addEventListener("pointerup", stop);
9444
+ window.addEventListener("pointercancel", stop);
9445
+ window.addEventListener("blur", stop);
8854
9446
  };
8855
- const stop = () => {
8856
- window.removeEventListener("pointermove", onPointerMove);
8857
- window.removeEventListener("pointerup", stop);
8858
- window.removeEventListener("pointercancel", stop);
8859
- window.removeEventListener("blur", stop);
8860
- cleanupRef.current = null;
8861
- emitSizingChange({}, { transactionId: state.transactionId, phase: "end" });
9447
+ },
9448
+ [emitSizingChange, enabled, onResizeSizingChange, selectedElement]
9449
+ );
9450
+ const getResizeHandleDoubleClick = React18.useCallback(
9451
+ (handle) => {
9452
+ return (e) => {
9453
+ if (!enabled || !onResizeSizingChange) return;
9454
+ if (!isEdgeHandle(handle)) return;
9455
+ const hasElementChildren = selectedElement.children.length > 0;
9456
+ const hasTextContent = Boolean(selectedElement.textContent?.trim());
9457
+ const isEligibleElement = hasElementChildren || hasTextContent;
9458
+ if (!isEligibleElement) return;
9459
+ e.preventDefault();
9460
+ e.stopPropagation();
9461
+ const rect = selectedElement.getBoundingClientRect();
9462
+ const width = Math.max(MIN_SIZE_PX, Math.round(rect.width));
9463
+ const height = Math.max(MIN_SIZE_PX, Math.round(rect.height));
9464
+ if (handle === "left" || handle === "right") {
9465
+ emitSizingChange({ width: createSizingValue("fit", width) });
9466
+ } else {
9467
+ emitSizingChange({ height: createSizingValue("fit", height) });
9468
+ }
8862
9469
  };
8863
- cleanupRef.current = stop;
8864
- window.addEventListener("pointermove", onPointerMove);
8865
- window.addEventListener("pointerup", stop);
8866
- window.addEventListener("pointercancel", stop);
8867
- window.addEventListener("blur", stop);
8868
- };
8869
- }, [emitSizingChange, enabled, onResizeSizingChange, selectedElement]);
8870
- const getResizeHandleDoubleClick = React18.useCallback((handle) => {
8871
- return (e) => {
8872
- if (!enabled || !onResizeSizingChange) return;
8873
- if (!isEdgeHandle(handle)) return;
8874
- const hasElementChildren = selectedElement.children.length > 0;
8875
- const hasTextContent = Boolean(selectedElement.textContent?.trim());
8876
- const isEligibleElement = hasElementChildren || hasTextContent;
8877
- if (!isEligibleElement) return;
8878
- e.preventDefault();
8879
- e.stopPropagation();
8880
- const rect = selectedElement.getBoundingClientRect();
8881
- const width = Math.max(MIN_SIZE_PX, Math.round(rect.width));
8882
- const height = Math.max(MIN_SIZE_PX, Math.round(rect.height));
8883
- if (handle === "left" || handle === "right") {
8884
- emitSizingChange({ width: createSizingValue("fit", width) });
8885
- } else {
8886
- emitSizingChange({ height: createSizingValue("fit", height) });
8887
- }
8888
- };
8889
- }, [emitSizingChange, enabled, onResizeSizingChange, selectedElement]);
9470
+ },
9471
+ [emitSizingChange, enabled, onResizeSizingChange, selectedElement]
9472
+ );
8890
9473
  return {
8891
9474
  getResizeHandlePointerDown,
8892
9475
  getResizeHandleDoubleClick
@@ -9511,17 +10094,20 @@ function getGroupBounds(rects) {
9511
10094
  if (rects.length === 0) {
9512
10095
  return { left: 0, top: 0, right: 0, bottom: 0 };
9513
10096
  }
9514
- return rects.reduce((bounds, rect) => ({
9515
- left: Math.min(bounds.left, rect.left),
9516
- top: Math.min(bounds.top, rect.top),
9517
- right: Math.max(bounds.right, rect.right),
9518
- bottom: Math.max(bounds.bottom, rect.bottom)
9519
- }), {
9520
- left: rects[0].left,
9521
- top: rects[0].top,
9522
- right: rects[0].right,
9523
- bottom: rects[0].bottom
9524
- });
10097
+ return rects.reduce(
10098
+ (bounds, rect) => ({
10099
+ left: Math.min(bounds.left, rect.left),
10100
+ top: Math.min(bounds.top, rect.top),
10101
+ right: Math.max(bounds.right, rect.right),
10102
+ bottom: Math.max(bounds.bottom, rect.bottom)
10103
+ }),
10104
+ {
10105
+ left: rects[0].left,
10106
+ top: rects[0].top,
10107
+ right: rects[0].right,
10108
+ bottom: rects[0].bottom
10109
+ }
10110
+ );
9525
10111
  }
9526
10112
  function MultiSelectionOverlay({ selectedElements }) {
9527
10113
  const elements = React20.useMemo(
@@ -9530,10 +10116,12 @@ function MultiSelectionOverlay({ selectedElements }) {
9530
10116
  );
9531
10117
  const [selectionRects, setSelectionRects] = React20.useState([]);
9532
10118
  const updateRects = React20.useCallback(() => {
9533
- setSelectionRects(elements.map((element) => ({
9534
- element,
9535
- rect: element.getBoundingClientRect()
9536
- })));
10119
+ setSelectionRects(
10120
+ elements.map((element) => ({
10121
+ element,
10122
+ rect: element.getBoundingClientRect()
10123
+ }))
10124
+ );
9537
10125
  }, [elements]);
9538
10126
  React20.useLayoutEffect(() => {
9539
10127
  updateRects();
@@ -11917,6 +12505,7 @@ function PanelFooter({
11917
12505
  onExportEdits,
11918
12506
  onSendToAgent,
11919
12507
  showSendButton = true,
12508
+ sendFailureReason,
11920
12509
  onPointerDown,
11921
12510
  onPointerMove,
11922
12511
  onPointerUp,
@@ -11925,6 +12514,13 @@ function PanelFooter({
11925
12514
  const [copied, setCopied] = React30.useState(false);
11926
12515
  const [copyError, setCopyError] = React30.useState(false);
11927
12516
  const [sendStatus, setSendStatus] = React30.useState("idle");
12517
+ const prevCanTriggerSendRef = React30.useRef(canTriggerSend);
12518
+ React30.useEffect(() => {
12519
+ if (prevCanTriggerSendRef.current !== canTriggerSend) {
12520
+ prevCanTriggerSendRef.current = canTriggerSend;
12521
+ setSendStatus("idle");
12522
+ }
12523
+ }, [canTriggerSend]);
11928
12524
  const handleCopy = async () => {
11929
12525
  if (!onExportEdits) return;
11930
12526
  const success = await onExportEdits();
@@ -11938,6 +12534,7 @@ function PanelFooter({
11938
12534
  setCopyError(true);
11939
12535
  setTimeout(() => setCopyError(false), 2e3);
11940
12536
  };
12537
+ const sendTooltipLabel = sendStatus === "offline" ? sendFailureReason === "unreachable" ? "Agent unreachable \u2014 click to retry" : "Agent rejected the edit \u2014 click to retry" : "Apply changes via agent";
11941
12538
  const handleSendToAgent = async () => {
11942
12539
  if (!onSendToAgent || sendStatus === "sending") return;
11943
12540
  setSendStatus("sending");
@@ -11947,7 +12544,6 @@ function PanelFooter({
11947
12544
  setTimeout(() => setSendStatus("idle"), 2e3);
11948
12545
  } else {
11949
12546
  setSendStatus("offline");
11950
- setTimeout(() => setSendStatus("idle"), 2e3);
11951
12547
  }
11952
12548
  };
11953
12549
  return /* @__PURE__ */ jsxs18(
@@ -11975,7 +12571,7 @@ function PanelFooter({
11975
12571
  children: copyError ? /* @__PURE__ */ jsx24(X3, { className: "text-red-500" }) : copied ? /* @__PURE__ */ jsx24(Check3, { className: "text-green-500" }) : /* @__PURE__ */ jsx24(Copy2, {})
11976
12572
  }
11977
12573
  ) }),
11978
- showSendButton && onSendToAgent && /* @__PURE__ */ jsx24("span", { className: !canTriggerSend || sendStatus === "sending" ? "cursor-not-allowed" : void 0, children: /* @__PURE__ */ jsx24(Tip, { label: "Apply changes via agent", children: /* @__PURE__ */ jsx24(
12574
+ showSendButton && onSendToAgent && /* @__PURE__ */ jsx24("span", { className: !canTriggerSend || sendStatus === "sending" ? "cursor-not-allowed" : void 0, children: /* @__PURE__ */ jsx24(Tip, { label: sendTooltipLabel, children: /* @__PURE__ */ jsx24(
11979
12575
  Button,
11980
12576
  {
11981
12577
  variant: "outline",
@@ -12692,6 +13288,7 @@ function DirectEditPanelInner({
12692
13288
  onSendToAgent,
12693
13289
  canSendToAgent = false,
12694
13290
  showSendButton = true,
13291
+ sendFailureReason,
12695
13292
  className,
12696
13293
  style,
12697
13294
  panelRef,
@@ -12754,89 +13351,91 @@ function DirectEditPanelInner({
12754
13351
  sectionRefs
12755
13352
  }
12756
13353
  ),
12757
- /* @__PURE__ */ jsxs23("div", { className: "flex-1 overflow-y-auto backdrop-blur-xl bg-background/85", ref: scrollRef, onWheelCapture: (e) => e.stopPropagation(), children: [
12758
- /* @__PURE__ */ jsx29(
12759
- LayoutSection,
12760
- {
12761
- elementInfo,
12762
- computedFlex,
12763
- computedSpacing,
12764
- computedSizing,
12765
- onToggleFlex,
12766
- onUpdateFlex,
12767
- onUpdateSpacing,
12768
- onUpdateSizing,
12769
- sectionRef: sectionRefs.layout
12770
- }
12771
- ),
12772
- /* @__PURE__ */ jsx29("div", { ref: sectionRefs.radius, children: /* @__PURE__ */ jsx29(CollapsibleSection, { title: "Radius", children: /* @__PURE__ */ jsx29(
12773
- BorderRadiusInputs,
12774
- {
12775
- values: {
12776
- topLeft: computedBorderRadius.borderTopLeftRadius,
12777
- topRight: computedBorderRadius.borderTopRightRadius,
12778
- bottomRight: computedBorderRadius.borderBottomRightRadius,
12779
- bottomLeft: computedBorderRadius.borderBottomLeftRadius
12780
- },
12781
- onChange: onUpdateBorderRadius
12782
- }
12783
- ) }) }),
12784
- computedColor && /* @__PURE__ */ jsx29("div", { ref: sectionRefs.fill, children: /* @__PURE__ */ jsx29(
12785
- BackgroundFillSection,
12786
- {
12787
- backgroundColor: computedColor.backgroundColor,
12788
- onSetCSS,
12789
- pendingStyles
12790
- }
12791
- ) }),
12792
- /* @__PURE__ */ jsx29("div", { ref: sectionRefs.border, children: /* @__PURE__ */ jsx29(
12793
- BorderSection,
12794
- {
12795
- border: computedBorder,
12796
- borderColor: computedColor?.borderColor,
12797
- outlineColor: computedColor?.outlineColor,
12798
- borderStyleControlPreference,
12799
- onChange: onUpdateBorder,
12800
- onBatchChange: onBatchUpdateBorder,
12801
- onBorderColorChange: (value) => onUpdateColor("borderColor", value),
12802
- onOutlineColorChange: (value) => onUpdateColor("outlineColor", value),
12803
- onSetCSS,
12804
- pendingStyles
12805
- }
12806
- ) }),
12807
- /* @__PURE__ */ jsx29("div", { ref: sectionRefs.shadow, children: /* @__PURE__ */ jsx29(
12808
- ShadowSection,
12809
- {
12810
- boxShadow: computedBoxShadow,
12811
- onSetCSS,
12812
- pendingStyles
12813
- }
12814
- ) }),
12815
- elementInfo.isTextElement && computedTypography && /* @__PURE__ */ jsx29("div", { ref: sectionRefs.text, children: /* @__PURE__ */ jsx29(CollapsibleSection, { title: "Text", children: /* @__PURE__ */ jsx29(
12816
- TypographyInputs,
12817
- {
12818
- typography: computedTypography,
12819
- onUpdate: onUpdateTypography
12820
- }
12821
- ) }) }),
12822
- computedColor && /* @__PURE__ */ jsx29("div", { ref: sectionRefs.colors, children: /* @__PURE__ */ jsx29(CollapsibleSection, { title: "Selection colors", children: /* @__PURE__ */ jsx29(
12823
- FillSection,
12824
- {
12825
- textColor: computedColor.color,
12826
- borderColor: computedColor.borderColor,
12827
- outlineColor: computedColor.outlineColor,
12828
- selectionColors,
12829
- onTextChange: (value) => onUpdateColor("color", value),
12830
- onBorderColorChange: (value) => onUpdateColor("borderColor", value),
12831
- onOutlineColorChange: (value) => onUpdateColor("outlineColor", value),
12832
- onSelectionColorChange: onReplaceSelectionColor,
12833
- onSelectionColorTarget: onSelectSelectionColorTarget,
12834
- hasTextContent: elementInfo.isTextElement,
12835
- showBorderColor: computedColor.borderColor.alpha > 0,
12836
- showOutlineColor: computedColor.outlineColor.alpha > 0
12837
- }
12838
- ) }) })
12839
- ] }),
13354
+ /* @__PURE__ */ jsxs23(
13355
+ "div",
13356
+ {
13357
+ className: "flex-1 overflow-y-auto backdrop-blur-xl bg-background/85",
13358
+ ref: scrollRef,
13359
+ onWheelCapture: (e) => e.stopPropagation(),
13360
+ children: [
13361
+ /* @__PURE__ */ jsx29(
13362
+ LayoutSection,
13363
+ {
13364
+ elementInfo,
13365
+ computedFlex,
13366
+ computedSpacing,
13367
+ computedSizing,
13368
+ onToggleFlex,
13369
+ onUpdateFlex,
13370
+ onUpdateSpacing,
13371
+ onUpdateSizing,
13372
+ sectionRef: sectionRefs.layout
13373
+ }
13374
+ ),
13375
+ /* @__PURE__ */ jsx29("div", { ref: sectionRefs.radius, children: /* @__PURE__ */ jsx29(CollapsibleSection, { title: "Radius", children: /* @__PURE__ */ jsx29(
13376
+ BorderRadiusInputs,
13377
+ {
13378
+ values: {
13379
+ topLeft: computedBorderRadius.borderTopLeftRadius,
13380
+ topRight: computedBorderRadius.borderTopRightRadius,
13381
+ bottomRight: computedBorderRadius.borderBottomRightRadius,
13382
+ bottomLeft: computedBorderRadius.borderBottomLeftRadius
13383
+ },
13384
+ onChange: onUpdateBorderRadius
13385
+ }
13386
+ ) }) }),
13387
+ computedColor && /* @__PURE__ */ jsx29("div", { ref: sectionRefs.fill, children: /* @__PURE__ */ jsx29(
13388
+ BackgroundFillSection,
13389
+ {
13390
+ backgroundColor: computedColor.backgroundColor,
13391
+ onSetCSS,
13392
+ pendingStyles
13393
+ }
13394
+ ) }),
13395
+ /* @__PURE__ */ jsx29("div", { ref: sectionRefs.border, children: /* @__PURE__ */ jsx29(
13396
+ BorderSection,
13397
+ {
13398
+ border: computedBorder,
13399
+ borderColor: computedColor?.borderColor,
13400
+ outlineColor: computedColor?.outlineColor,
13401
+ borderStyleControlPreference,
13402
+ onChange: onUpdateBorder,
13403
+ onBatchChange: onBatchUpdateBorder,
13404
+ onBorderColorChange: (value) => onUpdateColor("borderColor", value),
13405
+ onOutlineColorChange: (value) => onUpdateColor("outlineColor", value),
13406
+ onSetCSS,
13407
+ pendingStyles
13408
+ }
13409
+ ) }),
13410
+ /* @__PURE__ */ jsx29("div", { ref: sectionRefs.shadow, children: /* @__PURE__ */ jsx29(
13411
+ ShadowSection,
13412
+ {
13413
+ boxShadow: computedBoxShadow,
13414
+ onSetCSS,
13415
+ pendingStyles
13416
+ }
13417
+ ) }),
13418
+ elementInfo.isTextElement && computedTypography && /* @__PURE__ */ jsx29("div", { ref: sectionRefs.text, children: /* @__PURE__ */ jsx29(CollapsibleSection, { title: "Text", children: /* @__PURE__ */ jsx29(TypographyInputs, { typography: computedTypography, onUpdate: onUpdateTypography }) }) }),
13419
+ computedColor && /* @__PURE__ */ jsx29("div", { ref: sectionRefs.colors, children: /* @__PURE__ */ jsx29(CollapsibleSection, { title: "Selection colors", children: /* @__PURE__ */ jsx29(
13420
+ FillSection,
13421
+ {
13422
+ textColor: computedColor.color,
13423
+ borderColor: computedColor.borderColor,
13424
+ outlineColor: computedColor.outlineColor,
13425
+ selectionColors,
13426
+ onTextChange: (value) => onUpdateColor("color", value),
13427
+ onBorderColorChange: (value) => onUpdateColor("borderColor", value),
13428
+ onOutlineColorChange: (value) => onUpdateColor("outlineColor", value),
13429
+ onSelectionColorChange: onReplaceSelectionColor,
13430
+ onSelectionColorTarget: onSelectSelectionColorTarget,
13431
+ hasTextContent: elementInfo.isTextElement,
13432
+ showBorderColor: computedColor.borderColor.alpha > 0,
13433
+ showOutlineColor: computedColor.outlineColor.alpha > 0
13434
+ }
13435
+ ) }) })
13436
+ ]
13437
+ }
13438
+ ),
12840
13439
  (onExportEdits || showSendButton && onSendToAgent) && /* @__PURE__ */ jsx29(
12841
13440
  PanelFooter,
12842
13441
  {
@@ -12845,6 +13444,7 @@ function DirectEditPanelInner({
12845
13444
  onExportEdits,
12846
13445
  onSendToAgent,
12847
13446
  showSendButton,
13447
+ sendFailureReason,
12848
13448
  onPointerDown: onHeaderPointerDown,
12849
13449
  onPointerMove: onHeaderPointerMove,
12850
13450
  onPointerUp: onHeaderPointerUp,
@@ -12879,7 +13479,8 @@ function DirectEditPanelContent() {
12879
13479
  comments,
12880
13480
  activeCommentId,
12881
13481
  textEditingElement,
12882
- agentAvailable
13482
+ agentAvailable,
13483
+ lastSendFailure
12883
13484
  } = useDirectEditState();
12884
13485
  const {
12885
13486
  selectParent,
@@ -12907,11 +13508,15 @@ function DirectEditPanelContent() {
12907
13508
  addCommentReply,
12908
13509
  deleteComment,
12909
13510
  exportComment,
13511
+ exportEdits,
13512
+ sendEditToAgent: sendEditToAgent2,
12910
13513
  sendCommentToAgent: sendCommentToAgent2,
12911
13514
  setActiveCommentId,
12912
13515
  startTextEditing,
12913
13516
  toggleEditMode,
12914
- deleteSelection
13517
+ deleteSelection,
13518
+ setCommentDraftText,
13519
+ setCommentDraftBlockedHandler
12915
13520
  } = useDirectEditActions();
12916
13521
  const {
12917
13522
  position,
@@ -12933,46 +13538,67 @@ function DirectEditPanelContent() {
12933
13538
  });
12934
13539
  React34.useEffect(() => {
12935
13540
  commentDraftRef.current = "";
12936
- }, [activeCommentId]);
13541
+ setCommentDraftText("");
13542
+ }, [activeCommentId, setCommentDraftText]);
12937
13543
  const activeDraftComment = React34.useMemo(() => {
12938
13544
  if (!commentTargetElement || !activeCommentId) return null;
12939
13545
  const active = comments.find((comment) => comment.id === activeCommentId);
12940
- if (!active || active.text.trim().length > 0 || active.element !== commentTargetElement) return null;
13546
+ if (!active || active.text.trim().length > 0 || active.element !== commentTargetElement)
13547
+ return null;
12941
13548
  return active;
12942
13549
  }, [activeCommentId, commentTargetElement, comments]);
12943
- const { isActive: measurementActive, hoveredElement, measurements, mousePosition } = useMeasurement(
12944
- isOpen ? selectedElement : null
12945
- );
12946
13550
  const {
12947
- dragState,
12948
- dropIndicator,
12949
- startDrag
12950
- } = useMove({
13551
+ isActive: measurementActive,
13552
+ hoveredElement,
13553
+ measurements,
13554
+ mousePosition
13555
+ } = useMeasurement(isOpen ? selectedElement : null);
13556
+ const { dragState, dropIndicator, startDrag } = useMove({
12951
13557
  onMoveComplete: handleMoveComplete
12952
13558
  });
12953
13559
  const triggerCommentInputAttention = React34.useCallback((commentId) => {
12954
- setCommentInputAttention((prev) => prev?.commentId === commentId ? { commentId, nonce: prev.nonce + 1 } : { commentId, nonce: 1 });
13560
+ setCommentInputAttention(
13561
+ (prev) => prev?.commentId === commentId ? { commentId, nonce: prev.nonce + 1 } : { commentId, nonce: 1 }
13562
+ );
12955
13563
  }, []);
12956
- const hasPendingCommentDraft = React34.useCallback((nextCommentId = null) => {
12957
- if (!activeCommentId) return false;
12958
- if (nextCommentId && nextCommentId === activeCommentId) return false;
12959
- const active = comments.find((comment) => comment.id === activeCommentId);
12960
- if (!active) return false;
12961
- const hasUnsentDraft = active.text.trim().length === 0 && commentDraftRef.current.trim().length > 0;
12962
- if (!hasUnsentDraft) return false;
12963
- triggerCommentInputAttention(active.id);
12964
- return true;
12965
- }, [activeCommentId, comments, triggerCommentInputAttention]);
12966
- const handleSetActiveComment = React34.useCallback((id) => {
12967
- if (hasPendingCommentDraft(id)) return;
12968
- if (activeCommentId && activeCommentId !== id) {
13564
+ React34.useEffect(() => {
13565
+ if (!activeCommentId) {
13566
+ setCommentDraftBlockedHandler(null);
13567
+ return;
13568
+ }
13569
+ setCommentDraftBlockedHandler(() => {
13570
+ triggerCommentInputAttention(activeCommentId);
13571
+ });
13572
+ return () => {
13573
+ setCommentDraftBlockedHandler(null);
13574
+ };
13575
+ }, [activeCommentId, setCommentDraftBlockedHandler, triggerCommentInputAttention]);
13576
+ const hasPendingCommentDraft = React34.useCallback(
13577
+ (nextCommentId = null) => {
13578
+ if (!activeCommentId) return false;
13579
+ if (nextCommentId && nextCommentId === activeCommentId) return false;
12969
13580
  const active = comments.find((comment) => comment.id === activeCommentId);
12970
- if (active && active.text.trim().length === 0) {
12971
- deleteComment(active.id);
13581
+ if (!active) return false;
13582
+ const hasUnsentDraft = active.text.trim().length === 0 && commentDraftRef.current.trim().length > 0;
13583
+ if (!hasUnsentDraft) return false;
13584
+ triggerCommentInputAttention(active.id);
13585
+ return true;
13586
+ },
13587
+ [activeCommentId, comments, triggerCommentInputAttention]
13588
+ );
13589
+ const handleSetActiveComment = React34.useCallback(
13590
+ (id) => {
13591
+ if (hasPendingCommentDraft(id)) return;
13592
+ if (activeCommentId && activeCommentId !== id) {
13593
+ const active = comments.find((comment) => comment.id === activeCommentId);
13594
+ if (active && active.text.trim().length === 0) {
13595
+ deleteComment(active.id);
13596
+ }
12972
13597
  }
12973
- }
12974
- setActiveCommentId(id);
12975
- }, [activeCommentId, comments, hasPendingCommentDraft, deleteComment, setActiveCommentId]);
13598
+ setActiveCommentId(id);
13599
+ },
13600
+ [activeCommentId, comments, hasPendingCommentDraft, deleteComment, setActiveCommentId]
13601
+ );
12976
13602
  const handleCommentPillClick = React34.useCallback(() => {
12977
13603
  if (activeDraftComment) {
12978
13604
  handleSetActiveComment(null);
@@ -12980,13 +13606,23 @@ function DirectEditPanelContent() {
12980
13606
  }
12981
13607
  if (hasPendingCommentDraft()) return;
12982
13608
  if (!commentTargetElement) return;
12983
- const existingDraft = comments.find((comment) => comment.element === commentTargetElement && comment.text.trim().length === 0);
13609
+ const existingDraft = comments.find(
13610
+ (comment) => comment.element === commentTargetElement && comment.text.trim().length === 0
13611
+ );
12984
13612
  if (existingDraft) {
12985
13613
  setActiveCommentId(existingDraft.id);
12986
13614
  return;
12987
13615
  }
12988
13616
  addComment(commentTargetElement, getElementCommentAnchor(commentTargetElement));
12989
- }, [activeDraftComment, handleSetActiveComment, hasPendingCommentDraft, commentTargetElement, comments, setActiveCommentId, addComment]);
13617
+ }, [
13618
+ activeDraftComment,
13619
+ handleSetActiveComment,
13620
+ hasPendingCommentDraft,
13621
+ commentTargetElement,
13622
+ comments,
13623
+ setActiveCommentId,
13624
+ addComment
13625
+ ]);
12990
13626
  React34.useEffect(() => {
12991
13627
  const previous = previousCommentTriggerRef.current;
12992
13628
  previousCommentTriggerRef.current = { editModeActive, commentTargetElement };
@@ -13062,6 +13698,7 @@ function DirectEditPanelContent() {
13062
13698
  comment: activeDraftComment,
13063
13699
  attentionNonce: commentInputAttention?.commentId === activeDraftComment.id ? commentInputAttention.nonce : 0,
13064
13700
  draftRef: commentDraftRef,
13701
+ onDraftTextChange: setCommentDraftText,
13065
13702
  onSubmit: (text) => submitCommentDraft(activeDraftComment.id, text),
13066
13703
  onCancel: () => handleSetActiveComment(null)
13067
13704
  }
@@ -13082,58 +13719,81 @@ function DirectEditPanelContent() {
13082
13719
  if (pageTitle.length > 0) return pageTitle;
13083
13720
  return getElementDisplayName(pageFrameElement);
13084
13721
  }, [pageFrameElement]);
13085
- const handleSelectSelectionColorTarget = React34.useCallback((targetColor) => {
13086
- if (!selectedElement) return;
13087
- const toKey = (color) => `${color.hex.toUpperCase()}:${Math.round(color.alpha)}`;
13088
- const targetKey = toKey(targetColor);
13089
- const hasOwnText2 = (node) => Array.from(node.childNodes).some((child) => child.nodeType === Node.TEXT_NODE && (child.textContent ?? "").trim().length > 0);
13090
- const parseVisibleColor3 = (raw, fallbackCurrentColor) => {
13091
- const trimmed = raw.trim();
13092
- if (!trimmed || trimmed === "none" || trimmed === "transparent") return null;
13093
- const resolved = trimmed.toLowerCase() === "currentcolor" ? fallbackCurrentColor ?? trimmed : trimmed;
13094
- const parsed = parseColorValue(resolved);
13095
- return parsed.alpha > 0 ? parsed : null;
13096
- };
13097
- const hasMatchingColor = (node) => {
13098
- const computed = window.getComputedStyle(node);
13099
- const currentTextColor = computed.color;
13100
- const matches = (raw, fallback) => {
13101
- const parsed = parseVisibleColor3(raw, fallback);
13102
- return Boolean(parsed && toKey(parsed) === targetKey);
13722
+ const handleSelectSelectionColorTarget = React34.useCallback(
13723
+ (targetColor) => {
13724
+ if (!selectedElement) return;
13725
+ const toKey = (color) => `${color.hex.toUpperCase()}:${Math.round(color.alpha)}`;
13726
+ const targetKey = toKey(targetColor);
13727
+ const hasOwnText2 = (node) => Array.from(node.childNodes).some(
13728
+ (child) => child.nodeType === Node.TEXT_NODE && (child.textContent ?? "").trim().length > 0
13729
+ );
13730
+ const parseVisibleColor3 = (raw, fallbackCurrentColor) => {
13731
+ const trimmed = raw.trim();
13732
+ if (!trimmed || trimmed === "none" || trimmed === "transparent") return null;
13733
+ const resolved = trimmed.toLowerCase() === "currentcolor" ? fallbackCurrentColor ?? trimmed : trimmed;
13734
+ const parsed = parseColorValue(resolved);
13735
+ return parsed.alpha > 0 ? parsed : null;
13103
13736
  };
13104
- if (matches(computed.backgroundColor)) return true;
13105
- if (hasOwnText2(node) && matches(currentTextColor)) return true;
13106
- const borderSides = [
13107
- { style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
13108
- { style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
13109
- { style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
13110
- { style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
13111
- ];
13112
- for (const side of borderSides) {
13113
- if (side.style !== "none" && parseFloat(side.width) > 0 && matches(side.color, currentTextColor)) {
13737
+ const hasMatchingColor = (node) => {
13738
+ const computed = window.getComputedStyle(node);
13739
+ const currentTextColor = computed.color;
13740
+ const matches = (raw, fallback) => {
13741
+ const parsed = parseVisibleColor3(raw, fallback);
13742
+ return Boolean(parsed && toKey(parsed) === targetKey);
13743
+ };
13744
+ if (matches(computed.backgroundColor)) return true;
13745
+ if (hasOwnText2(node) && matches(currentTextColor)) return true;
13746
+ const borderSides = [
13747
+ {
13748
+ style: computed.borderTopStyle,
13749
+ width: computed.borderTopWidth,
13750
+ color: computed.borderTopColor
13751
+ },
13752
+ {
13753
+ style: computed.borderRightStyle,
13754
+ width: computed.borderRightWidth,
13755
+ color: computed.borderRightColor
13756
+ },
13757
+ {
13758
+ style: computed.borderBottomStyle,
13759
+ width: computed.borderBottomWidth,
13760
+ color: computed.borderBottomColor
13761
+ },
13762
+ {
13763
+ style: computed.borderLeftStyle,
13764
+ width: computed.borderLeftWidth,
13765
+ color: computed.borderLeftColor
13766
+ }
13767
+ ];
13768
+ for (const side of borderSides) {
13769
+ if (side.style !== "none" && parseFloat(side.width) > 0 && matches(side.color, currentTextColor)) {
13770
+ return true;
13771
+ }
13772
+ }
13773
+ if (computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0 && matches(computed.outlineColor, currentTextColor)) {
13114
13774
  return true;
13115
13775
  }
13776
+ if (node instanceof SVGGraphicsElement) {
13777
+ const fillMatch = matches(computed.getPropertyValue("fill"), currentTextColor) || matches(node.getAttribute("fill") ?? "", currentTextColor);
13778
+ const strokeMatch = matches(computed.getPropertyValue("stroke"), currentTextColor) || matches(node.getAttribute("stroke") ?? "", currentTextColor);
13779
+ if (fillMatch || strokeMatch) return true;
13780
+ }
13781
+ return false;
13782
+ };
13783
+ const descendants = Array.from(selectedElement.querySelectorAll("*"));
13784
+ const firstDescendantMatch = descendants.find(
13785
+ (node) => node instanceof HTMLElement && hasMatchingColor(node)
13786
+ );
13787
+ if (firstDescendantMatch) {
13788
+ selectElement(firstDescendantMatch);
13789
+ return;
13116
13790
  }
13117
- if (computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0 && matches(computed.outlineColor, currentTextColor)) {
13118
- return true;
13119
- }
13120
- if (node instanceof SVGGraphicsElement) {
13121
- const fillMatch = matches(computed.getPropertyValue("fill"), currentTextColor) || matches(node.getAttribute("fill") ?? "", currentTextColor);
13122
- const strokeMatch = matches(computed.getPropertyValue("stroke"), currentTextColor) || matches(node.getAttribute("stroke") ?? "", currentTextColor);
13123
- if (fillMatch || strokeMatch) return true;
13791
+ if (hasMatchingColor(selectedElement)) {
13792
+ selectElement(selectedElement);
13124
13793
  }
13125
- return false;
13126
- };
13127
- const descendants = Array.from(selectedElement.querySelectorAll("*"));
13128
- const firstDescendantMatch = descendants.find((node) => node instanceof HTMLElement && hasMatchingColor(node));
13129
- if (firstDescendantMatch) {
13130
- selectElement(firstDescendantMatch);
13131
- return;
13132
- }
13133
- if (hasMatchingColor(selectedElement)) {
13134
- selectElement(selectedElement);
13135
- }
13136
- }, [selectedElement, selectElement]);
13794
+ },
13795
+ [selectedElement, selectElement]
13796
+ );
13137
13797
  const handleMoveStart = (e, targetElement, options) => {
13138
13798
  const elementToDrag = targetElement ?? selectedElement;
13139
13799
  if (elementToDrag) {
@@ -13222,7 +13882,11 @@ function DirectEditPanelContent() {
13222
13882
  hoveredElement,
13223
13883
  measurements: [
13224
13884
  ...measurements,
13225
- ...calculateGuidelineMeasurements(selectedElement, getStoredGuidelines(), mousePosition)
13885
+ ...calculateGuidelineMeasurements(
13886
+ selectedElement,
13887
+ getStoredGuidelines(),
13888
+ mousePosition
13889
+ )
13226
13890
  ]
13227
13891
  }
13228
13892
  ),
@@ -13277,6 +13941,9 @@ function DirectEditPanelContent() {
13277
13941
  onSelectSelectionColorTarget: handleSelectSelectionColorTarget,
13278
13942
  onUpdateTypography: updateTypographyProperty,
13279
13943
  onReset: resetToOriginal,
13944
+ onExportEdits: exportEdits,
13945
+ onSendToAgent: agentAvailable ? sendEditToAgent2 : void 0,
13946
+ sendFailureReason: lastSendFailure?.reason ?? null,
13280
13947
  className: "fixed z-[99999]",
13281
13948
  style: {
13282
13949
  left: position.x,
@@ -14148,7 +14815,7 @@ function useToolbarDock(toolbarRef) {
14148
14815
  }
14149
14816
 
14150
14817
  // src/toolbar.tsx
14151
- import { MousePointer2, Command as Command2, Send as Send3, Check as Check8, X as X5 } from "lucide-react";
14818
+ import { MousePointer2, Command as Command2, Send as Send3, Check as Check8, X as X5, Square as Square2, Type as Type2 } from "lucide-react";
14152
14819
 
14153
14820
  // src/toolbar/edits-popover.tsx
14154
14821
  import * as React38 from "react";
@@ -14211,7 +14878,8 @@ function EditsPopover({
14211
14878
  onExportAllEdits,
14212
14879
  onClearSessionEdits,
14213
14880
  onRemoveSessionEdit,
14214
- onDeleteComment
14881
+ onDeleteComment,
14882
+ sendFailure
14215
14883
  }) {
14216
14884
  const [copied, setCopied] = React38.useState(false);
14217
14885
  const editsPopupRef = React38.useRef(null);
@@ -14224,6 +14892,7 @@ function EditsPopover({
14224
14892
  const visibleItems = React38.useMemo(() => {
14225
14893
  return editsSnapshot.filter((item) => {
14226
14894
  if (item.type === "comment") return true;
14895
+ if (item.edit.deleted) return true;
14227
14896
  if (!item.edit.move) return true;
14228
14897
  const moveIntent = getMoveIntentForEdit(item.edit, movePlanContext);
14229
14898
  const hasStyleOrText = Object.keys(item.edit.pendingStyles).length > 0 || item.edit.textEdit != null;
@@ -14328,12 +14997,15 @@ ${text}`);
14328
14997
  visibleItems.length === 0 && multiSelectContextItems.length === 0 ? /* @__PURE__ */ jsx32("div", { className: "px-3 pb-3 pt-1 text-xs text-muted-foreground", children: "No edits or comments yet." }) : /* @__PURE__ */ jsxs25("div", { className: "max-h-[240px] overflow-y-auto px-1 py-1", children: [
14329
14998
  visibleItems.map((item, i) => {
14330
14999
  const isEdit = item.type === "edit";
15000
+ const isDeleted = isEdit && Boolean(item.edit.deleted);
14331
15001
  const moveIntent = isEdit && item.edit.move ? getMoveIntentForEdit(item.edit, movePlanContext) : null;
14332
15002
  const isMoved = Boolean(moveIntent);
14333
15003
  const locator = isEdit ? item.edit.locator : item.comment.locator;
14334
15004
  const componentName = locator.reactStack[0]?.name ?? locator.tagName;
14335
15005
  let valueSummary = "";
14336
- if (isEdit) {
15006
+ if (isEdit && isDeleted) {
15007
+ valueSummary = locator.textPreview || locator.domSelector || locator.tagName;
15008
+ } else if (isEdit) {
14337
15009
  const entries = Object.entries(item.edit.pendingStyles);
14338
15010
  const editValues = [];
14339
15011
  for (const [prop, value] of entries) {
@@ -14354,6 +15026,7 @@ ${text}`);
14354
15026
  }
14355
15027
  valueSummary = commentValues.join(", ");
14356
15028
  }
15029
+ const failed = isEdit ? sendFailure?.failedEditElements.includes(item.edit.element) : sendFailure?.failedCommentIds.includes(item.comment.id);
14357
15030
  return /* @__PURE__ */ jsxs25(
14358
15031
  "div",
14359
15032
  {
@@ -14372,13 +15045,16 @@ ${text}`);
14372
15045
  },
14373
15046
  children: [
14374
15047
  /* @__PURE__ */ jsxs25("div", { className: "min-w-0 flex flex-1 flex-col items-start gap-[4px]", children: [
14375
- /* @__PURE__ */ jsxs25(Badge, { variant: "secondary", className: "h-6 shrink-0 px-1.5 text-xs", children: [
14376
- "@<",
14377
- componentName,
14378
- ">"
15048
+ /* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-1", children: [
15049
+ /* @__PURE__ */ jsxs25(Badge, { variant: "secondary", className: "h-6 shrink-0 px-1.5 text-xs", children: [
15050
+ "@<",
15051
+ componentName,
15052
+ ">"
15053
+ ] }),
15054
+ failed && /* @__PURE__ */ jsx32(Badge, { variant: "default", className: "h-6 shrink-0 px-1.5 text-xs bg-red-500 text-white border-transparent", children: "Failed" })
14379
15055
  ] }),
14380
15056
  /* @__PURE__ */ jsxs25("span", { className: "min-w-0 max-w-full truncate text-xs text-muted-foreground", children: [
14381
- isEdit ? isMoved ? "moved: " : "edit: " : "comment: ",
15057
+ isEdit ? isDeleted ? "deleted: " : isMoved ? "moved: " : "edit: " : "comment: ",
14382
15058
  truncateText(valueSummary, 128)
14383
15059
  ] })
14384
15060
  ] }),
@@ -14643,6 +15319,7 @@ function SettingsPopover({
14643
15319
  { label: "Undo", keys: isMac ? [/* @__PURE__ */ jsx33(Command, { className: "size-2.5" }, "cmd"), "Z"] : ["Ctrl", "Z"] },
14644
15320
  { label: "Group selection", keys: isMac ? [/* @__PURE__ */ jsx33(Command, { className: "size-2.5" }, "cmd"), "G"] : ["Ctrl", "G"] },
14645
15321
  { label: "Add frame", keys: ["F"] },
15322
+ { label: "Add text", keys: ["T"] },
14646
15323
  { label: "Add div", keys: ["D"] },
14647
15324
  { label: "Add to selection", keys: [/* @__PURE__ */ jsx33(ArrowBigUp, { className: "size-3" }, "shift"), "Click"] },
14648
15325
  { label: "Marquee select", keys: ["Drag"] },
@@ -14685,6 +15362,8 @@ function DirectEditToolbarInner({
14685
15362
  onExportAllEdits,
14686
15363
  onSendAllToAgents,
14687
15364
  agentAvailable = true,
15365
+ sendFailureReason,
15366
+ sendFailure,
14688
15367
  onClearSessionEdits,
14689
15368
  onRemoveSessionEdit,
14690
15369
  onDeleteComment,
@@ -14694,7 +15373,8 @@ function DirectEditToolbarInner({
14694
15373
  onToggleCanvas,
14695
15374
  onSetCanvasZoom,
14696
15375
  onZoomTo100,
14697
- onFitToViewport
15376
+ onFitToViewport,
15377
+ onInsertElement
14698
15378
  }) {
14699
15379
  const container = usePortalContainer();
14700
15380
  const toolbarRef = React40.useRef(null);
@@ -14703,7 +15383,8 @@ function DirectEditToolbarInner({
14703
15383
  const [activePopover, setActivePopover] = React40.useState(null);
14704
15384
  const [applyStatus, setApplyStatus] = React40.useState("idle");
14705
15385
  const applyTimerRef = React40.useRef(null);
14706
- const showApplyButton = agentAvailable && Boolean(onSendAllToAgents);
15386
+ const showApplyButton = (agentAvailable || applyStatus !== "idle") && Boolean(onSendAllToAgents);
15387
+ const showInsertButtons = Boolean(onInsertElement);
14707
15388
  const totalItemCount = sessionEditCount + multiSelectCount;
14708
15389
  const sizeCacheRef = React40.useRef({});
14709
15390
  React40.useEffect(() => {
@@ -14757,6 +15438,16 @@ function DirectEditToolbarInner({
14757
15438
  setApplyStatus("idle");
14758
15439
  }, 2e3);
14759
15440
  }, []);
15441
+ const prevTotalItemCountRef = React40.useRef(totalItemCount);
15442
+ React40.useEffect(() => {
15443
+ if (prevTotalItemCountRef.current !== totalItemCount) {
15444
+ prevTotalItemCountRef.current = totalItemCount;
15445
+ if (applyStatus === "offline") {
15446
+ setApplyStatus("idle");
15447
+ }
15448
+ }
15449
+ }, [totalItemCount, applyStatus]);
15450
+ const applyTooltipLabel = applyStatus === "offline" ? sendFailureReason === "unreachable" ? "Agent unreachable \u2014 click to retry" : "Agent rejected the edit \u2014 click to retry" : "Apply all changes via agent";
14760
15451
  const handleApplyAll = React40.useCallback(async () => {
14761
15452
  if (!onSendAllToAgents || totalItemCount === 0 || applyStatus === "sending") return;
14762
15453
  setApplyStatus("sending");
@@ -14766,8 +15457,12 @@ function DirectEditToolbarInner({
14766
15457
  } catch {
14767
15458
  success = false;
14768
15459
  }
14769
- setApplyStatus(success ? "sent" : "offline");
14770
- scheduleApplyReset();
15460
+ if (success) {
15461
+ setApplyStatus("sent");
15462
+ scheduleApplyReset();
15463
+ } else {
15464
+ setApplyStatus("offline");
15465
+ }
14771
15466
  }, [applyStatus, onSendAllToAgents, scheduleApplyReset, totalItemCount]);
14772
15467
  const dragHandlers = React40.useMemo(() => ({
14773
15468
  onPointerDown: handlePointerDown,
@@ -14848,6 +15543,38 @@ function DirectEditToolbarInner({
14848
15543
  },
14849
15544
  ...dragHandlers,
14850
15545
  children: [
15546
+ showInsertButtons && /* @__PURE__ */ jsxs27(Fragment8, { children: [
15547
+ /* @__PURE__ */ jsxs27(Tooltip, { children: [
15548
+ /* @__PURE__ */ jsx34(
15549
+ TooltipTrigger,
15550
+ {
15551
+ className: cn(toolbarBtnClass, "text-muted-foreground hover:bg-muted hover:text-foreground"),
15552
+ onPointerDown: (e) => e.stopPropagation(),
15553
+ onClick: () => onInsertElement?.("frame"),
15554
+ children: /* @__PURE__ */ jsx34(Square2, { className: "size-4" })
15555
+ }
15556
+ ),
15557
+ /* @__PURE__ */ jsxs27(TooltipContent, { side: tooltipSide, className: "inline-flex items-center gap-1.5", children: [
15558
+ /* @__PURE__ */ jsx34("span", { children: "Add frame" }),
15559
+ /* @__PURE__ */ jsx34("kbd", { className: kbdClass, children: "F" })
15560
+ ] })
15561
+ ] }),
15562
+ /* @__PURE__ */ jsxs27(Tooltip, { children: [
15563
+ /* @__PURE__ */ jsx34(
15564
+ TooltipTrigger,
15565
+ {
15566
+ className: cn(toolbarBtnClass, "text-muted-foreground hover:bg-muted hover:text-foreground"),
15567
+ onPointerDown: (e) => e.stopPropagation(),
15568
+ onClick: () => onInsertElement?.("text"),
15569
+ children: /* @__PURE__ */ jsx34(Type2, { className: "size-4" })
15570
+ }
15571
+ ),
15572
+ /* @__PURE__ */ jsxs27(TooltipContent, { side: tooltipSide, className: "inline-flex items-center gap-1.5", children: [
15573
+ /* @__PURE__ */ jsx34("span", { children: "Add text" }),
15574
+ /* @__PURE__ */ jsx34("kbd", { className: kbdClass, children: "T" })
15575
+ ] })
15576
+ ] })
15577
+ ] }),
14851
15578
  /* @__PURE__ */ jsx34(
14852
15579
  EditsPopover,
14853
15580
  {
@@ -14860,7 +15587,8 @@ function DirectEditToolbarInner({
14860
15587
  onExportAllEdits,
14861
15588
  onClearSessionEdits,
14862
15589
  onRemoveSessionEdit,
14863
- onDeleteComment
15590
+ onDeleteComment,
15591
+ sendFailure
14864
15592
  }
14865
15593
  ),
14866
15594
  showApplyButton && /* @__PURE__ */ jsxs27(Tooltip, { children: [
@@ -14884,7 +15612,7 @@ function DirectEditToolbarInner({
14884
15612
  ]
14885
15613
  }
14886
15614
  ),
14887
- /* @__PURE__ */ jsx34(TooltipContent, { side: tooltipSide, children: /* @__PURE__ */ jsx34("span", { children: "Apply all changes via agent" }) })
15615
+ /* @__PURE__ */ jsx34(TooltipContent, { side: tooltipSide, children: /* @__PURE__ */ jsx34("span", { children: applyTooltipLabel }) })
14888
15616
  ] }),
14889
15617
  /* @__PURE__ */ jsx34(
14890
15618
  "div",
@@ -14946,7 +15674,7 @@ function DirectEditToolbarInner({
14946
15674
  return toolbar;
14947
15675
  }
14948
15676
  function DirectEditToolbarContent() {
14949
- const { editModeActive, theme, sessionEditCount, multiSelectContextCount, selectedElements, canvas, agentAvailable } = useDirectEditState();
15677
+ const { editModeActive, theme, sessionEditCount, multiSelectContextCount, selectedElements, canvas, agentAvailable, lastSendFailure } = useDirectEditState();
14950
15678
  const {
14951
15679
  toggleEditMode,
14952
15680
  setTheme,
@@ -14956,6 +15684,7 @@ function DirectEditToolbarContent() {
14956
15684
  clearSessionEdits,
14957
15685
  removeSessionEdit,
14958
15686
  deleteComment,
15687
+ insertElement,
14959
15688
  toggleCanvas,
14960
15689
  setCanvasZoom,
14961
15690
  zoomCanvasTo100,
@@ -14978,6 +15707,8 @@ function DirectEditToolbarContent() {
14978
15707
  onExportAllEdits: exportAllEdits,
14979
15708
  onSendAllToAgents: sendAllSessionItemsToAgent,
14980
15709
  agentAvailable,
15710
+ sendFailureReason: lastSendFailure?.reason ?? null,
15711
+ sendFailure: lastSendFailure,
14981
15712
  onClearSessionEdits: clearSessionEdits,
14982
15713
  onRemoveSessionEdit: removeSessionEdit,
14983
15714
  onDeleteComment: deleteComment,
@@ -14986,7 +15717,8 @@ function DirectEditToolbarContent() {
14986
15717
  onToggleCanvas: toggleCanvas,
14987
15718
  onSetCanvasZoom: setCanvasZoom,
14988
15719
  onZoomTo100: zoomCanvasTo100,
14989
- onFitToViewport: fitCanvasToViewport
15720
+ onFitToViewport: fitCanvasToViewport,
15721
+ onInsertElement: insertElement
14990
15722
  }
14991
15723
  );
14992
15724
  }