made-refine 0.2.6 → 0.2.7

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.js CHANGED
@@ -53,6 +53,7 @@ __export(index_exports, {
53
53
  colorToTailwind: () => colorToTailwind,
54
54
  elementFromPointWithoutOverlays: () => elementFromPointWithoutOverlays,
55
55
  findContainerAtPoint: () => findContainerAtPoint,
56
+ findLayoutContainerAtPoint: () => findLayoutContainerAtPoint,
56
57
  formatColorValue: () => formatColorValue,
57
58
  formatPropertyValue: () => formatPropertyValue,
58
59
  getComputedBorderStyles: () => getComputedBorderStyles,
@@ -65,6 +66,7 @@ __export(index_exports, {
65
66
  getFlexDirection: () => getFlexDirection,
66
67
  getStoredGuidelines: () => getStoredGuidelines,
67
68
  isFlexContainer: () => isFlexContainer,
69
+ isLayoutContainer: () => isLayoutContainer,
68
70
  parseColorValue: () => parseColorValue,
69
71
  parsePropertyValue: () => parsePropertyValue,
70
72
  stylesToTailwind: () => stylesToTailwind,
@@ -85,7 +87,7 @@ var React8 = __toESM(require("react"));
85
87
  var React = __toESM(require("react"));
86
88
 
87
89
  // dist/styles.css
88
- 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-lg:.5rem;--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}.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-\\[30px\\]{width:30px}.w-\\[60px\\]{width:60px}.w-\\[68px\\]{width:68px}.w-\\[180px\\]{width:180px}.w-\\[200px\\]{width:200px}.w-\\[260px\\]{width:260px}.w-\\[280px\\]{width:280px}.w-\\[300px\\]{width:300px}.w-\\[340px\\]{width:340px}.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}.\\[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-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-\\[2px\\]{gap:2px}.gap-\\[4px\\]{gap:4px}:where(.space-y-1\\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}: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)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.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-lg{border-radius:var(--radius-lg)}.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-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\\.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-3{padding-left:calc(var(--spacing)*3)}.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}.text-\\[11px\\]{font-size:11px}.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)}.whitespace-nowrap{white-space:nowrap}.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-dashed{--tw-outline-style:dashed;outline-style:dashed}.outline-dotted{--tw-outline-style:dotted;outline-style:dotted}.outline-double{--tw-outline-style:double;outline-style:double}.outline-none{--tw-outline-style:none;outline-style:none}.outline-solid{--tw-outline-style:solid;outline-style:solid}.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}.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}.disabled\\:opacity-60:disabled{opacity:.6}.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-4 svg{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\\[\\&_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}}';
90
+ 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-lg:.5rem;--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-\\[30px\\]{width:30px}.w-\\[60px\\]{width:60px}.w-\\[68px\\]{width:68px}.w-\\[180px\\]{width:180px}.w-\\[200px\\]{width:200px}.w-\\[260px\\]{width:260px}.w-\\[280px\\]{width:280px}.w-\\[300px\\]{width:300px}.w-\\[340px\\]{width:340px}.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}.\\[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-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-\\[2px\\]{gap:2px}.gap-\\[4px\\]{gap:4px}:where(.space-y-1\\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}: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)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.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-lg{border-radius:var(--radius-lg)}.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-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\\.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-3{padding-left:calc(var(--spacing)*3)}.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}.text-\\[11px\\]{font-size:11px}.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)}.whitespace-nowrap{white-space:nowrap}.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-dashed{--tw-outline-style:dashed;outline-style:dashed}.outline-dotted{--tw-outline-style:dotted;outline-style:dotted}.outline-double{--tw-outline-style:double;outline-style:double}.outline-none{--tw-outline-style:none;outline-style:none}.outline-solid{--tw-outline-style:solid;outline-style:solid}.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}.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}.disabled\\:opacity-60:disabled{opacity:.6}.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-4 svg{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\\[\\&_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}}';
89
91
 
90
92
  // src/portal-container.tsx
91
93
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -1221,6 +1223,10 @@ function getFlexDirection(element) {
1221
1223
  const computed = window.getComputedStyle(element);
1222
1224
  return computed.flexDirection;
1223
1225
  }
1226
+ function isInFlowChild(el) {
1227
+ const cs = window.getComputedStyle(el);
1228
+ return cs.display !== "none" && cs.position !== "absolute" && cs.position !== "fixed";
1229
+ }
1224
1230
  function detectChildrenDirection(container, exclude) {
1225
1231
  const computed = window.getComputedStyle(container);
1226
1232
  if (computed.display === "flex" || computed.display === "inline-flex") {
@@ -1233,8 +1239,7 @@ function detectChildrenDirection(container, exclude) {
1233
1239
  const visible = [];
1234
1240
  for (const c of container.children) {
1235
1241
  if (!(c instanceof HTMLElement) || c === exclude) continue;
1236
- const cs = window.getComputedStyle(c);
1237
- if (cs.display === "none" || cs.position === "absolute" || cs.position === "fixed") continue;
1242
+ if (!isInFlowChild(c)) continue;
1238
1243
  visible.push(c);
1239
1244
  if (visible.length === 2) break;
1240
1245
  }
@@ -1247,6 +1252,29 @@ function detectChildrenDirection(container, exclude) {
1247
1252
  }
1248
1253
  return { axis: "vertical", reversed: second.bottom < first.top };
1249
1254
  }
1255
+ function computeIntendedIndex(parent, draggedElement) {
1256
+ const { axis } = detectChildrenDirection(parent, draggedElement);
1257
+ const isHorizontal = axis === "horizontal";
1258
+ const draggedRect = draggedElement.getBoundingClientRect();
1259
+ const intendedCenter = isHorizontal ? draggedRect.left + draggedRect.width / 2 : draggedRect.top + draggedRect.height / 2;
1260
+ const siblings = [];
1261
+ for (const c of parent.children) {
1262
+ if (!(c instanceof HTMLElement) || c === draggedElement) continue;
1263
+ if (!isInFlowChild(c)) continue;
1264
+ siblings.push(c);
1265
+ }
1266
+ if (siblings.length === 0) {
1267
+ return { index: 0, siblingBefore: null, siblingAfter: null };
1268
+ }
1269
+ for (let i = 0; i < siblings.length; i++) {
1270
+ const rect = siblings[i].getBoundingClientRect();
1271
+ const midpoint = isHorizontal ? rect.left + rect.width / 2 : rect.top + rect.height / 2;
1272
+ if (intendedCenter < midpoint) {
1273
+ return { index: i, siblingBefore: i > 0 ? siblings[i - 1] : null, siblingAfter: siblings[i] };
1274
+ }
1275
+ }
1276
+ return { index: siblings.length, siblingBefore: siblings[siblings.length - 1], siblingAfter: null };
1277
+ }
1250
1278
  function htmlChildren(el) {
1251
1279
  return Array.from(el.children).filter(
1252
1280
  (child) => child instanceof HTMLElement
@@ -1347,6 +1375,22 @@ function findContainerAtPoint(x, y, exclude, preferredParent) {
1347
1375
  }
1348
1376
  return findContainerViaTraversal(x, y, exclude);
1349
1377
  }
1378
+ function findLayoutContainerAtPoint(x, y, exclude, preferredParent) {
1379
+ const host = document.querySelector("[data-direct-edit-host]");
1380
+ if (host) host.style.display = "none";
1381
+ const elements = document.elementsFromPoint(x, y);
1382
+ if (host) host.style.display = "";
1383
+ for (const el of elements) {
1384
+ if (skipElement(el, exclude)) continue;
1385
+ if (isLayoutContainer(el)) return el;
1386
+ }
1387
+ if (preferredParent && isLayoutContainer(preferredParent)) {
1388
+ for (const el of elements) {
1389
+ if (el === preferredParent) return preferredParent;
1390
+ }
1391
+ }
1392
+ return null;
1393
+ }
1350
1394
  function calculateDropPosition(container, pointerX, pointerY, draggedElement) {
1351
1395
  const { axis, reversed: isReversed } = detectChildrenDirection(container, draggedElement);
1352
1396
  const isHorizontal = axis === "horizontal";
@@ -1741,7 +1785,11 @@ function getReactComponentStack(element) {
1741
1785
  return getRenderStack(fiber);
1742
1786
  }
1743
1787
  function getElementDisplayName(element) {
1744
- return element.tagName.toLowerCase();
1788
+ const tag = element.tagName.toLowerCase();
1789
+ if (element.id) return `${tag}#${element.id}`;
1790
+ const firstClass = Array.from(element.classList).find((c) => c && !c.startsWith("direct-edit"));
1791
+ if (firstClass) return `${tag}.${firstClass}`;
1792
+ return tag;
1745
1793
  }
1746
1794
  var STABLE_ATTRIBUTES = ["data-testid", "data-qa", "data-cy", "aria-label", "role"];
1747
1795
  var MAX_SELECTOR_DEPTH = 24;
@@ -2029,26 +2077,28 @@ function parseDomSource(element) {
2029
2077
  }
2030
2078
  return { file, line, column };
2031
2079
  }
2032
- function getElementLocator(element) {
2033
- const elementInfo = getElementInfo(element);
2034
- let domSource = parseDomSource(element);
2035
- if (!domSource) {
2036
- const seenFibers = /* @__PURE__ */ new Set();
2037
- let fiber = getFiberForElement(element);
2038
- while (fiber && !seenFibers.has(fiber)) {
2039
- seenFibers.add(fiber);
2040
- const fiberSource = getSourceFromFiber(fiber);
2041
- if (fiberSource?.fileName) {
2042
- domSource = {
2043
- file: fiberSource.fileName,
2044
- line: fiberSource.lineNumber,
2045
- column: fiberSource.columnNumber
2046
- };
2047
- break;
2048
- }
2049
- fiber = fiber._debugOwner ?? fiber.return ?? null;
2080
+ function getElementSource(element) {
2081
+ const domSource = parseDomSource(element);
2082
+ if (domSource) return domSource;
2083
+ const seenFibers = /* @__PURE__ */ new Set();
2084
+ let fiber = getFiberForElement(element);
2085
+ while (fiber && !seenFibers.has(fiber)) {
2086
+ seenFibers.add(fiber);
2087
+ const fiberSource = getSourceFromFiber(fiber);
2088
+ if (fiberSource?.fileName) {
2089
+ return {
2090
+ file: fiberSource.fileName,
2091
+ line: fiberSource.lineNumber,
2092
+ column: fiberSource.columnNumber
2093
+ };
2050
2094
  }
2095
+ fiber = fiber._debugOwner ?? fiber.return ?? null;
2051
2096
  }
2097
+ return null;
2098
+ }
2099
+ function getElementLocator(element) {
2100
+ const elementInfo = getElementInfo(element);
2101
+ const domSource = getElementSource(element);
2052
2102
  return {
2053
2103
  reactStack: getReactComponentStack(element),
2054
2104
  domSelector: buildDomSelector(element),
@@ -2067,7 +2117,7 @@ function getLocatorHeader(locator) {
2067
2117
  const formattedSource = locator.domSource?.file ? formatSourceLocation(locator.domSource.file, locator.domSource.line, locator.domSource.column) : primaryFrame?.file ? formatSourceLocation(primaryFrame.file, primaryFrame.line, primaryFrame.column) : null;
2068
2118
  return { componentLabel, formattedSource };
2069
2119
  }
2070
- function buildLocatorContextLines(locator) {
2120
+ function buildLocatorContextLines(locator, options) {
2071
2121
  const lines = [];
2072
2122
  const { componentLabel, formattedSource } = getLocatorHeader(locator);
2073
2123
  const target = (locator.targetHtml || locator.domContextHtml || "").trim();
@@ -2080,7 +2130,7 @@ function buildLocatorContextLines(locator) {
2080
2130
  lines.push("target:");
2081
2131
  lines.push(target);
2082
2132
  }
2083
- if (context && context !== target) {
2133
+ if (!options?.skipContext && context && context !== target) {
2084
2134
  lines.push("context:");
2085
2135
  lines.push(context);
2086
2136
  }
@@ -2234,6 +2284,29 @@ function buildEditExport(arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
2234
2284
  }
2235
2285
  return lines.join("\n");
2236
2286
  }
2287
+ function buildEditExportWithOptions(locator, pendingStyles, textEdit, options) {
2288
+ const changes = [];
2289
+ const collapsedStyles = collapseExportShorthands(pendingStyles);
2290
+ for (const [property, value] of Object.entries(collapsedStyles)) {
2291
+ const tailwindClass = stylesToTailwind({ [property]: value });
2292
+ changes.push({ property, value, tailwind: tailwindClass });
2293
+ }
2294
+ const lines = buildLocatorContextLines(locator, options);
2295
+ lines.push("");
2296
+ if (changes.length > 0) {
2297
+ lines.push("edits:");
2298
+ for (const change of changes) {
2299
+ const tailwind = change.tailwind ? ` (${change.tailwind})` : "";
2300
+ lines.push(`${change.property}: ${change.value}${tailwind}`);
2301
+ }
2302
+ }
2303
+ if (textEdit) {
2304
+ lines.push("text content changed:");
2305
+ lines.push(`from: "${textEdit.originalText}"`);
2306
+ lines.push(`to: "${textEdit.newText}"`);
2307
+ }
2308
+ return lines.join("\n");
2309
+ }
2237
2310
  function buildCommentExport(locator, commentText, replies) {
2238
2311
  const lines = buildLocatorContextLines(locator);
2239
2312
  lines.push("");
@@ -2245,55 +2318,545 @@ function buildCommentExport(locator, commentText, replies) {
2245
2318
  }
2246
2319
  return lines.join("\n");
2247
2320
  }
2248
- function formatPosition(siblingBefore, siblingAfter) {
2249
- if (siblingBefore && siblingAfter) return `after <${siblingBefore}>`;
2250
- if (siblingBefore && !siblingAfter) return `after <${siblingBefore}> (last)`;
2251
- if (!siblingBefore && siblingAfter) return `before <${siblingAfter}> (first)`;
2252
- return "(only child)";
2321
+ function normalizeSelector(selector) {
2322
+ const value = selector?.trim();
2323
+ return value && value.length > 0 ? value : null;
2253
2324
  }
2254
- function formatMoveSummary(move) {
2255
- const fromPosition = formatPosition(move.fromSiblingBefore, move.fromSiblingAfter);
2256
- const toPosition = formatPosition(move.toSiblingBefore, move.toSiblingAfter);
2257
- if (move.fromParentName === move.toParentName) {
2258
- return `in <${move.toParentName}>, from ${fromPosition} to ${toPosition}`;
2325
+ function normalizeName(name) {
2326
+ return name?.trim().toLowerCase() || "element";
2327
+ }
2328
+ function buildAnchorRef(name, selector, source) {
2329
+ return {
2330
+ name: name?.trim() || "element",
2331
+ selector: normalizeSelector(selector),
2332
+ source: source?.file ? source : null
2333
+ };
2334
+ }
2335
+ function anchorKey(anchor) {
2336
+ if (!anchor) return "none";
2337
+ const selector = normalizeSelector(anchor.selector);
2338
+ if (selector) return `selector:${selector}`;
2339
+ if (anchor.source?.file) {
2340
+ return `source:${anchor.source.file}:${anchor.source.line ?? 0}:${anchor.source.column ?? 0}`;
2341
+ }
2342
+ return `name:${normalizeName(anchor.name)}`;
2343
+ }
2344
+ function anchorsEqual(a, b) {
2345
+ if (!a && !b) return true;
2346
+ if (!a || !b) return false;
2347
+ const aSelector = normalizeSelector(a.selector);
2348
+ const bSelector = normalizeSelector(b.selector);
2349
+ if (aSelector && bSelector) return aSelector === bSelector;
2350
+ if (a.source?.file && b.source?.file) {
2351
+ return a.source.file === b.source.file && (a.source.line ?? null) === (b.source.line ?? null) && (a.source.column ?? null) === (b.source.column ?? null);
2352
+ }
2353
+ return normalizeName(a.name) === normalizeName(b.name);
2354
+ }
2355
+ function formatAnchorRef(anchor, fallback = "(none)") {
2356
+ if (!anchor) return fallback;
2357
+ const selector = normalizeSelector(anchor.selector);
2358
+ if (selector) return selector;
2359
+ if (anchor.source?.file) return `<${anchor.name}> @ ${formatSourceLocation(anchor.source.file, anchor.source.line, anchor.source.column)}`;
2360
+ return `<${anchor.name}>`;
2361
+ }
2362
+ function buildPlacementRef(before, after) {
2363
+ if (before && after) {
2364
+ return {
2365
+ before,
2366
+ after,
2367
+ description: `between after ${formatAnchorRef(before)} and before ${formatAnchorRef(after)}`
2368
+ };
2369
+ }
2370
+ if (before) {
2371
+ return {
2372
+ before,
2373
+ after: null,
2374
+ description: `after ${formatAnchorRef(before)}`
2375
+ };
2376
+ }
2377
+ if (after) {
2378
+ return {
2379
+ before: null,
2380
+ after,
2381
+ description: `before ${formatAnchorRef(after)}`
2382
+ };
2259
2383
  }
2260
- return `from <${move.fromParentName}> ${fromPosition} to <${move.toParentName}> ${toPosition}`;
2384
+ return {
2385
+ before: null,
2386
+ after: null,
2387
+ description: "as the only child"
2388
+ };
2261
2389
  }
2262
- function formatMoveSelector(selector, fallback) {
2263
- const normalized = selector?.trim();
2264
- return normalized ? normalized : fallback;
2390
+ function buildPlacementFromMove(beforeName, beforeSelector, beforeSource, afterName, afterSelector, afterSource) {
2391
+ const before = beforeName || beforeSelector || beforeSource?.file ? buildAnchorRef(beforeName, beforeSelector, beforeSource) : null;
2392
+ const after = afterName || afterSelector || afterSource?.file ? buildAnchorRef(afterName, afterSelector, afterSource) : null;
2393
+ return buildPlacementRef(before, after);
2394
+ }
2395
+ function toRoundedVisualDelta(move) {
2396
+ const delta = move.visualDelta ?? move.positionDelta;
2397
+ if (!delta) return void 0;
2398
+ const rounded = { x: Math.round(delta.x), y: Math.round(delta.y) };
2399
+ return rounded.x === 0 && rounded.y === 0 ? void 0 : rounded;
2400
+ }
2401
+ function hasVisualIntent(move) {
2402
+ return Boolean(toRoundedVisualDelta(move));
2403
+ }
2404
+ function hasStructuralChange(move) {
2405
+ const fromParent = buildAnchorRef(move.fromParentName, move.fromParentSelector, move.fromParentSource);
2406
+ const toParent = buildAnchorRef(move.toParentName, move.toParentSelector, move.toParentSource);
2407
+ const fromPlacement = buildPlacementFromMove(
2408
+ move.fromSiblingBefore,
2409
+ move.fromSiblingBeforeSelector,
2410
+ move.fromSiblingBeforeSource,
2411
+ move.fromSiblingAfter,
2412
+ move.fromSiblingAfterSelector,
2413
+ move.fromSiblingAfterSource
2414
+ );
2415
+ const toPlacement = buildPlacementFromMove(
2416
+ move.toSiblingBefore,
2417
+ move.toSiblingBeforeSelector,
2418
+ move.toSiblingBeforeSource,
2419
+ move.toSiblingAfter,
2420
+ move.toSiblingAfterSelector,
2421
+ move.toSiblingAfterSource
2422
+ );
2423
+ if (!anchorsEqual(fromParent, toParent)) return true;
2424
+ if (!anchorsEqual(fromPlacement.before, toPlacement.before)) return true;
2425
+ if (!anchorsEqual(fromPlacement.after, toPlacement.after)) return true;
2426
+ if (typeof move.fromIndex === "number" && typeof move.toIndex === "number" && move.fromIndex !== move.toIndex) return true;
2427
+ return false;
2265
2428
  }
2266
- function formatMoveSource(source, fallback) {
2267
- if (!source?.file) return fallback;
2268
- return formatSourceLocation(source.file, source.line, source.column);
2429
+ function isStructuredLayoutContainer(layout) {
2430
+ return layout === "flex" || layout === "grid";
2431
+ }
2432
+ function isExistingFlexWorkflow(move) {
2433
+ const structuralChange = hasStructuralChange(move);
2434
+ if (!structuralChange) return false;
2435
+ const fromParent = buildAnchorRef(move.fromParentName, move.fromParentSelector, move.fromParentSource);
2436
+ const toParent = buildAnchorRef(move.toParentName, move.toParentSelector, move.toParentSource);
2437
+ const sameParent = anchorsEqual(fromParent, toParent);
2438
+ const fromLayout = move.fromParentLayout;
2439
+ const toLayout = move.toParentLayout;
2440
+ if (sameParent) {
2441
+ return Boolean(move.mode === "reorder" && (isStructuredLayoutContainer(toLayout) || isStructuredLayoutContainer(fromLayout)));
2442
+ }
2443
+ return Boolean(isStructuredLayoutContainer(fromLayout) && isStructuredLayoutContainer(toLayout));
2444
+ }
2445
+ function classifyMove(move) {
2446
+ const structuralChange = hasStructuralChange(move);
2447
+ const visualIntent = hasVisualIntent(move);
2448
+ if (!structuralChange && !visualIntent) return "noop";
2449
+ if (isExistingFlexWorkflow(move)) return "existing_layout_move";
2450
+ if (move.mode === "free" || move.mode === "position") return "layout_refactor";
2451
+ if (!structuralChange && visualIntent) return "layout_refactor";
2452
+ return "layout_refactor";
2453
+ }
2454
+ function buildNumericClusters(values, tolerance) {
2455
+ if (values.length === 0) return [];
2456
+ const sorted = [...values].sort((a, b) => a - b);
2457
+ const clusters = [{ center: sorted[0], values: [sorted[0]] }];
2458
+ for (let i = 1; i < sorted.length; i++) {
2459
+ const value = sorted[i];
2460
+ const current = clusters[clusters.length - 1];
2461
+ if (Math.abs(value - current.center) <= tolerance) {
2462
+ current.values.push(value);
2463
+ current.center = current.values.reduce((sum, n) => sum + n, 0) / current.values.length;
2464
+ } else {
2465
+ clusters.push({ center: value, values: [value] });
2466
+ }
2467
+ }
2468
+ return clusters;
2269
2469
  }
2270
- function buildMoveExportLines(move) {
2271
- return [
2470
+ function inferFlexDirection(sameRowCount, sameColumnCount, visualDelta) {
2471
+ if (sameRowCount > sameColumnCount) {
2472
+ return { direction: "row", reason: "Subject aligns with neighboring anchors on the same row." };
2473
+ }
2474
+ if (sameColumnCount > sameRowCount) {
2475
+ return { direction: "column", reason: "Subject aligns with neighboring anchors on the same column." };
2476
+ }
2477
+ if (sameRowCount > 0) {
2478
+ return { direction: "row", reason: "Detected row alignment in final geometry." };
2479
+ }
2480
+ if (sameColumnCount > 0) {
2481
+ return { direction: "column", reason: "Detected column alignment in final geometry." };
2482
+ }
2483
+ const horizontalDominant = Math.abs(visualDelta?.x ?? 0) >= Math.abs(visualDelta?.y ?? 0);
2484
+ return {
2485
+ direction: horizontalDominant ? "row" : "column",
2486
+ reason: "Fell back to movement axis because anchor alignment was ambiguous."
2487
+ };
2488
+ }
2489
+ function inferLayoutPrescription(edit, operation, reasons) {
2490
+ const parent = edit.element.parentElement;
2491
+ if (!parent || !edit.element.isConnected) {
2492
+ return {
2493
+ recommendedSystem: "flex",
2494
+ intentPatterns: ["no_geometry_context"],
2495
+ refactorSteps: [
2496
+ `Reparent ${formatAnchorRef(operation.subject)} under ${formatAnchorRef(operation.to.parent)} at ${operation.to.placement.description}.`
2497
+ ],
2498
+ styleSteps: [
2499
+ `Convert ${formatAnchorRef(operation.to.parent)} to flex and set a clear primary axis for this relationship.`,
2500
+ "Use `gap` for spacing and keep positioning static."
2501
+ ],
2502
+ itemSteps: [
2503
+ "Remove any inline `left/top/transform` move artifacts from moved elements."
2504
+ ]
2505
+ };
2506
+ }
2507
+ const children = Array.from(parent.children).filter(
2508
+ (node) => node instanceof HTMLElement && isInFlowChild(node) && !node.hasAttribute("data-direct-edit")
2509
+ );
2510
+ const childSnapshots = children.map((child) => {
2511
+ const rect = child.getBoundingClientRect();
2512
+ const locator = getElementLocator(child);
2513
+ const anchor = buildAnchorRef(getElementDisplayName(child), locator.domSelector, locator.domSource);
2514
+ return {
2515
+ child,
2516
+ rect,
2517
+ centerX: rect.left + rect.width / 2,
2518
+ centerY: rect.top + rect.height / 2,
2519
+ anchor,
2520
+ anchorLabel: formatAnchorRef(anchor)
2521
+ };
2522
+ });
2523
+ const subjectSnapshot = childSnapshots.find((snapshot2) => snapshot2.child === edit.element);
2524
+ const subjectRect = edit.element.getBoundingClientRect();
2525
+ const subjectCenterX = subjectRect.left + subjectRect.width / 2;
2526
+ const subjectCenterY = subjectRect.top + subjectRect.height / 2;
2527
+ const rowTolerance = Math.max(8, subjectRect.height * 0.35);
2528
+ const colTolerance = Math.max(8, subjectRect.width * 0.35);
2529
+ const sameRowWith = [];
2530
+ const sameColumnWith = [];
2531
+ const sameRowNodes = [];
2532
+ let aboveAnchor = null;
2533
+ let belowAnchor = null;
2534
+ let bestAboveDistance = Number.POSITIVE_INFINITY;
2535
+ let bestBelowDistance = Number.POSITIVE_INFINITY;
2536
+ for (const node of childSnapshots) {
2537
+ if (node.child === edit.element) continue;
2538
+ if (Math.abs(node.centerY - subjectCenterY) <= rowTolerance) {
2539
+ sameRowWith.push(node.anchorLabel);
2540
+ sameRowNodes.push(node);
2541
+ }
2542
+ if (Math.abs(node.centerX - subjectCenterX) <= colTolerance) {
2543
+ sameColumnWith.push(node.anchorLabel);
2544
+ }
2545
+ const yDelta = node.centerY - subjectCenterY;
2546
+ if (yDelta < 0 && Math.abs(yDelta) < bestAboveDistance) {
2547
+ bestAboveDistance = Math.abs(yDelta);
2548
+ aboveAnchor = node.anchorLabel;
2549
+ }
2550
+ if (yDelta > 0 && yDelta < bestBelowDistance) {
2551
+ bestBelowDistance = yDelta;
2552
+ belowAnchor = node.anchorLabel;
2553
+ }
2554
+ }
2555
+ const rowCenters = childSnapshots.map(({ centerY }) => centerY);
2556
+ const colCenters = childSnapshots.map(({ centerX }) => centerX);
2557
+ const rowClusters = buildNumericClusters(rowCenters, rowTolerance);
2558
+ const colClusters = buildNumericClusters(colCenters, colTolerance);
2559
+ const denseRowClusters = rowClusters.filter((cluster) => cluster.values.length >= 2).length;
2560
+ const denseColClusters = colClusters.filter((cluster) => cluster.values.length >= 2).length;
2561
+ const isTwoDimensional = childSnapshots.length >= 4 && denseRowClusters >= 2 && denseColClusters >= 2;
2562
+ const recommendedSystem = isTwoDimensional ? "grid" : "flex";
2563
+ const intentPatterns = [];
2564
+ if (sameRowWith.length > 0) intentPatterns.push(`same_row_with:${sameRowWith.slice(0, 3).join(", ")}`);
2565
+ if (sameColumnWith.length > 0) intentPatterns.push(`same_column_with:${sameColumnWith.slice(0, 3).join(", ")}`);
2566
+ if (aboveAnchor) intentPatterns.push(`below:${aboveAnchor}`);
2567
+ if (belowAnchor) intentPatterns.push(`above:${belowAnchor}`);
2568
+ if (sameRowWith.length === 0 && sameColumnWith.length === 0) intentPatterns.push("separate_cluster");
2569
+ const visualDelta = operation.visualDelta;
2570
+ const flexDirectionInfo = inferFlexDirection(sameRowWith.length, sameColumnWith.length, visualDelta);
2571
+ const flexDirection = flexDirectionInfo.direction;
2572
+ if (recommendedSystem === "grid") {
2573
+ reasons.push("Detected multiple dense row and column clusters; a 2D layout system is likely intentional.");
2574
+ return {
2575
+ recommendedSystem: "grid",
2576
+ intentPatterns,
2577
+ refactorSteps: [
2578
+ `Create/ensure a shared container around ${formatAnchorRef(operation.subject)} and related anchors under ${formatAnchorRef(operation.to.parent)}.`,
2579
+ `Reorder/reparent elements to satisfy placement ${operation.to.placement.description}.`
2580
+ ],
2581
+ styleSteps: [
2582
+ `Set ${formatAnchorRef(operation.to.parent)} to grid with explicit template rows/columns for the final layout.`,
2583
+ "Use `gap` for consistent spacing and keep placement structural."
2584
+ ],
2585
+ itemSteps: [
2586
+ `Set item alignment on ${formatAnchorRef(operation.subject)} with grid self-alignment (\`justify-self\`/\`align-self\`).`
2587
+ ]
2588
+ };
2589
+ }
2590
+ reasons.push(`${flexDirectionInfo.reason} Use a 1D flex layout instead of literal drag replay.`);
2591
+ let hasStackedCluster = false;
2592
+ const stackedAnchorLabels = /* @__PURE__ */ new Set();
2593
+ if (flexDirection === "row" && subjectSnapshot) {
2594
+ for (const rowPeer of sameRowNodes) {
2595
+ for (const node of childSnapshots) {
2596
+ if (node.child === edit.element || node.child === rowPeer.child) continue;
2597
+ const sameColumnAsPeer = Math.abs(node.centerX - rowPeer.centerX) <= colTolerance;
2598
+ const verticallySeparated = Math.abs(node.centerY - rowPeer.centerY) > rowTolerance;
2599
+ if (sameColumnAsPeer && verticallySeparated) {
2600
+ hasStackedCluster = true;
2601
+ stackedAnchorLabels.add(rowPeer.anchorLabel);
2602
+ stackedAnchorLabels.add(node.anchorLabel);
2603
+ }
2604
+ }
2605
+ }
2606
+ }
2607
+ const hasBelowCluster = childSnapshots.some((node) => node.child !== edit.element && node.centerY - subjectCenterY > rowTolerance * 1.5 && Math.abs(node.centerY - subjectCenterY) > Math.abs(node.centerX - subjectCenterX));
2608
+ const refactorSteps = [
2609
+ `Ensure ${formatAnchorRef(operation.subject)} and referenced neighbors share a common container under ${formatAnchorRef(operation.to.parent)}.`,
2610
+ `Reparent/reorder nodes so ${formatAnchorRef(operation.subject)} lands ${operation.to.placement.description}.`
2611
+ ];
2612
+ if (flexDirection === "row" && hasStackedCluster) {
2613
+ const clusterSample = Array.from(stackedAnchorLabels).slice(0, 3).join(", ");
2614
+ refactorSteps.push(`Create a left-side content wrapper for vertically stacked items (${clusterSample}), and keep ${formatAnchorRef(operation.subject)} as the opposite-side sibling.`);
2615
+ }
2616
+ if (hasBelowCluster) {
2617
+ refactorSteps.push("Keep lower content sections in a separate block below the horizontal header row; do not force them into the same row.");
2618
+ }
2619
+ const styleSteps = [
2620
+ `Set ${formatAnchorRef(operation.to.parent)} to flex with direction ${flexDirection}.`,
2621
+ flexDirection === "row" ? "Use `justify-content: space-between` and `align-items: flex-start` when the moved element should sit on the opposite edge." : "Use `justify-content` / `align-items` to establish top-bottom alignment.",
2622
+ "Use `gap` for spacing between siblings."
2623
+ ];
2624
+ if (flexDirection === "row" && hasStackedCluster) {
2625
+ styleSteps.push("Set the content wrapper to `display: flex` with `flex-direction: column` and an appropriate vertical gap.");
2626
+ }
2627
+ return {
2628
+ recommendedSystem: "flex",
2629
+ intentPatterns,
2630
+ refactorSteps,
2631
+ styleSteps,
2632
+ itemSteps: [
2633
+ `Apply item-level alignment (\`align-self\` / flex-basis) only when needed for ${formatAnchorRef(operation.subject)}.`,
2634
+ "Do not use absolute positioning, top/left offsets, transforms, or margin hacks to simulate movement."
2635
+ ]
2636
+ };
2637
+ }
2638
+ function buildMoveEntries(edits) {
2639
+ const entries = [];
2640
+ let noopMoveCount = 0;
2641
+ for (const edit of edits) {
2642
+ const move = edit.move;
2643
+ if (!move) continue;
2644
+ const subject = buildAnchorRef(
2645
+ getElementDisplayName(edit.element) || edit.locator.tagName,
2646
+ edit.locator.domSelector,
2647
+ edit.locator.domSource
2648
+ );
2649
+ const fromParent = buildAnchorRef(move.fromParentName, move.fromParentSelector, move.fromParentSource);
2650
+ const toParent = buildAnchorRef(move.toParentName, move.toParentSelector, move.toParentSource);
2651
+ const fromPlacement = buildPlacementFromMove(
2652
+ move.fromSiblingBefore,
2653
+ move.fromSiblingBeforeSelector,
2654
+ move.fromSiblingBeforeSource,
2655
+ move.fromSiblingAfter,
2656
+ move.fromSiblingAfterSelector,
2657
+ move.fromSiblingAfterSource
2658
+ );
2659
+ const toPlacement = buildPlacementFromMove(
2660
+ move.toSiblingBefore,
2661
+ move.toSiblingBeforeSelector,
2662
+ move.toSiblingBeforeSource,
2663
+ move.toSiblingAfter,
2664
+ move.toSiblingAfterSelector,
2665
+ move.toSiblingAfterSource
2666
+ );
2667
+ const reasons = [];
2668
+ const classification = classifyMove(move);
2669
+ if (classification === "noop") {
2670
+ noopMoveCount++;
2671
+ continue;
2672
+ }
2673
+ const interactionMode = move.mode ?? "free";
2674
+ const visualDelta = toRoundedVisualDelta(move);
2675
+ if (visualDelta) {
2676
+ reasons.push(`Non-zero visual delta detected (${visualDelta.x}px, ${visualDelta.y}px).`);
2677
+ }
2678
+ const structuralChange = hasStructuralChange(move);
2679
+ if (structuralChange) reasons.push("Anchor placement changed between source and target.");
2680
+ else reasons.push("No anchor placement change; treating movement as layout intent translation.");
2681
+ const operationBase = {
2682
+ classification,
2683
+ interactionMode,
2684
+ subject,
2685
+ from: { parent: fromParent, placement: fromPlacement },
2686
+ to: { parent: toParent, placement: toPlacement },
2687
+ ...visualDelta ? { visualDelta } : {},
2688
+ confidence: classification === "existing_layout_move" ? "high" : structuralChange ? "medium" : "high",
2689
+ reasons
2690
+ };
2691
+ if (classification === "layout_refactor") {
2692
+ operationBase.layoutPrescription = inferLayoutPrescription(edit, operationBase, reasons);
2693
+ }
2694
+ const sortSource = subject.source?.file ? `${subject.source.file}:${subject.source.line ?? 0}:${subject.source.column ?? 0}` : "";
2695
+ const sortKey = [
2696
+ sortSource,
2697
+ anchorKey(subject),
2698
+ anchorKey(toParent),
2699
+ toPlacement.description
2700
+ ].join("|");
2701
+ entries.push({ edit, operation: operationBase, sortKey });
2702
+ }
2703
+ entries.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
2704
+ return { entries, noopMoveCount };
2705
+ }
2706
+ function buildMovePlanContext(edits, _domContext) {
2707
+ const { entries, noopMoveCount } = buildMoveEntries(edits);
2708
+ if (entries.length === 0) {
2709
+ return {
2710
+ movePlan: null,
2711
+ intentsByEdit: /* @__PURE__ */ new Map(),
2712
+ noopMoveCount
2713
+ };
2714
+ }
2715
+ const operations = [];
2716
+ const intentsByEdit = /* @__PURE__ */ new Map();
2717
+ for (let i = 0; i < entries.length; i++) {
2718
+ const operationId = `op-${i + 1}`;
2719
+ const operation = { operationId, ...entries[i].operation };
2720
+ operations.push(operation);
2721
+ intentsByEdit.set(entries[i].edit, operation);
2722
+ }
2723
+ const affectedContainerMap = /* @__PURE__ */ new Map();
2724
+ for (const operation of operations) {
2725
+ affectedContainerMap.set(anchorKey(operation.from.parent), operation.from.parent);
2726
+ affectedContainerMap.set(anchorKey(operation.to.parent), operation.to.parent);
2727
+ }
2728
+ const orderingConstraints = operations.filter((op) => op.classification === "existing_layout_move").map((op) => `${op.operationId}: place ${formatAnchorRef(op.subject)} ${op.to.placement.description} in ${formatAnchorRef(op.to.parent)}.`);
2729
+ const notes = [];
2730
+ if (noopMoveCount > 0) notes.push(`Excluded ${noopMoveCount} no-op move(s).`);
2731
+ if (operations.some((op) => op.classification === "layout_refactor")) {
2732
+ notes.push("Layout refactor operations include best-practice flex/grid prescriptions.");
2733
+ }
2734
+ return {
2735
+ movePlan: {
2736
+ operations,
2737
+ affectedContainers: Array.from(affectedContainerMap.values()),
2738
+ orderingConstraints,
2739
+ notes
2740
+ },
2741
+ intentsByEdit,
2742
+ noopMoveCount
2743
+ };
2744
+ }
2745
+ function getMoveIntentForEdit(edit, context) {
2746
+ if (!edit.move) return null;
2747
+ if (context?.intentsByEdit.has(edit)) return context.intentsByEdit.get(edit) ?? null;
2748
+ const singleContext = buildMovePlanContext([edit]);
2749
+ return singleContext.intentsByEdit.get(edit) ?? null;
2750
+ }
2751
+ function buildMoveInstructionFromIntent(intent) {
2752
+ if (intent.classification === "existing_layout_move") {
2753
+ return `Apply as a structural move in code: place ${formatAnchorRef(intent.subject)} ${intent.to.placement.description} in ${formatAnchorRef(intent.to.parent)}.`;
2754
+ }
2755
+ const system = intent.layoutPrescription?.recommendedSystem ?? "flex";
2756
+ return `Treat this as a ${system} layout refactor. Implement the listed structure/style steps in source code instead of drag replay.`;
2757
+ }
2758
+ function formatMoveType(classification) {
2759
+ return classification === "existing_layout_move" ? "structural_move" : "layout_refactor";
2760
+ }
2761
+ function buildMoveExportLines(intent) {
2762
+ const moveType = formatMoveType(intent.classification);
2763
+ const implementationSteps = [];
2764
+ if (intent.classification === "existing_layout_move") {
2765
+ implementationSteps.push(`Reorder/reparent ${formatAnchorRef(intent.subject)} to ${intent.to.placement.description} in ${formatAnchorRef(intent.to.parent)}.`);
2766
+ } else {
2767
+ const prescription = intent.layoutPrescription;
2768
+ if (prescription) {
2769
+ implementationSteps.push(...prescription.refactorSteps);
2770
+ implementationSteps.push(...prescription.styleSteps);
2771
+ implementationSteps.push(...prescription.itemSteps);
2772
+ }
2773
+ }
2774
+ const lines = [
2272
2775
  "moved:",
2273
- `summary: ${formatMoveSummary(move)}`,
2274
- `from_parent_selector: ${formatMoveSelector(move.fromParentSelector, "(unknown)")}`,
2275
- `from_before_selector: ${formatMoveSelector(move.fromSiblingBeforeSelector, "(none)")}`,
2276
- `from_after_selector: ${formatMoveSelector(move.fromSiblingAfterSelector, "(none)")}`,
2277
- `from_parent_source: ${formatMoveSource(move.fromParentSource, "(unknown)")}`,
2278
- `from_before_source: ${formatMoveSource(move.fromSiblingBeforeSource, "(none)")}`,
2279
- `from_after_source: ${formatMoveSource(move.fromSiblingAfterSource, "(none)")}`,
2280
- `to_parent_selector: ${formatMoveSelector(move.toParentSelector, "(unknown)")}`,
2281
- `to_before_selector: ${formatMoveSelector(move.toSiblingBeforeSelector, "(none)")}`,
2282
- `to_after_selector: ${formatMoveSelector(move.toSiblingAfterSelector, "(none)")}`,
2283
- `to_parent_source: ${formatMoveSource(move.toParentSource, "(unknown)")}`,
2284
- `to_before_source: ${formatMoveSource(move.toSiblingBeforeSource, "(none)")}`,
2285
- `to_after_source: ${formatMoveSource(move.toSiblingAfterSource, "(none)")}`
2776
+ `id: ${intent.operationId}`,
2777
+ `type: ${moveType}`,
2778
+ `subject: ${formatAnchorRef(intent.subject, "(unknown)")}`,
2779
+ `parent: ${formatAnchorRef(intent.to.parent, "(unknown)")}`,
2780
+ `current_anchor: ${intent.from.placement.description}`,
2781
+ `target_anchor: ${intent.to.placement.description}`,
2782
+ ...intent.visualDelta ? [`visual_hint: ${intent.visualDelta.x}px horizontal, ${intent.visualDelta.y}px vertical`] : []
2286
2783
  ];
2784
+ if (intent.layoutPrescription) {
2785
+ lines.push(`recommended_layout: ${intent.layoutPrescription.recommendedSystem}`);
2786
+ }
2787
+ lines.push("implementation_steps:");
2788
+ for (const step of implementationSteps) {
2789
+ lines.push(` - ${step}`);
2790
+ }
2791
+ lines.push("guardrails:");
2792
+ lines.push(" - Do not simulate movement with absolute positioning, left/top offsets, transform, or margin hacks.");
2793
+ lines.push(`instruction: ${buildMoveInstructionFromIntent(intent)}`);
2794
+ return lines;
2795
+ }
2796
+ function getExportContentProfile(edits, comments, movePlanOrContext) {
2797
+ const moveOpCount = movePlanOrContext ? "operations" in movePlanOrContext ? movePlanOrContext.operations.length : movePlanOrContext.movePlan?.operations.length ?? 0 : buildMovePlanContext(edits).movePlan?.operations.length ?? 0;
2798
+ return {
2799
+ hasCssEdits: edits.some((e) => Object.keys(e.pendingStyles).length > 0),
2800
+ hasTextEdits: edits.some((e) => e.textEdit != null),
2801
+ hasMoves: moveOpCount > 0,
2802
+ hasComments: comments.length > 0
2803
+ };
2804
+ }
2805
+ function buildExportInstruction(profile) {
2806
+ const { hasCssEdits, hasTextEdits, hasMoves, hasComments } = profile;
2807
+ if (!hasCssEdits && !hasTextEdits && !hasMoves && !hasComments) return "";
2808
+ if (!hasCssEdits && !hasTextEdits && !hasMoves) {
2809
+ return hasComments ? "Address this feedback on the UI. Use the provided source location and selector to find each element in the codebase." : "";
2810
+ }
2811
+ const parts = [];
2812
+ if (hasCssEdits) parts.push("Apply the CSS changes to the targeted elements using the project's existing styling approach (Tailwind, CSS modules, etc.).");
2813
+ if (hasTextEdits) parts.push("Update the text content as specified.");
2814
+ 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.");
2815
+ if (hasComments) parts.push("Address the comments on the relevant elements.");
2816
+ return `${parts.join(" ")} Use the provided source locations, selectors, and context HTML to locate each element in the codebase.`;
2287
2817
  }
2288
- function buildSessionExport(edits, comments = []) {
2818
+ function buildSessionExport(edits, comments = [], options) {
2289
2819
  const blocks = [];
2290
- for (const edit of edits) {
2291
- let block = buildEditExport(edit.locator, edit.pendingStyles, edit.textEdit);
2292
- if (edit.move) {
2293
- block += `
2294
- ${buildMoveExportLines(edit.move).join("\n")}`;
2820
+ const planContext = options?.movePlanContext ?? buildMovePlanContext(edits);
2821
+ const movePlan = planContext.movePlan;
2822
+ const includeMovePlanHeader = options?.includeMovePlanHeader !== false;
2823
+ if (includeMovePlanHeader && movePlan && movePlan.operations.length > 0) {
2824
+ const planLines = [
2825
+ "=== LAYOUT MOVE PLAN ===",
2826
+ `operations: ${movePlan.operations.length}`
2827
+ ];
2828
+ if (movePlan.affectedContainers.length > 0) {
2829
+ planLines.push("containers:");
2830
+ for (const container of movePlan.affectedContainers) {
2831
+ planLines.push(` - ${formatAnchorRef(container, "(unknown)")}`);
2832
+ }
2833
+ }
2834
+ if (movePlan.orderingConstraints.length > 0) {
2835
+ planLines.push("structural_constraints:");
2836
+ for (const constraint of movePlan.orderingConstraints) {
2837
+ planLines.push(` - ${constraint}`);
2838
+ }
2295
2839
  }
2296
- blocks.push(block);
2840
+ if (movePlan.notes.length > 0) {
2841
+ planLines.push("plan_notes:");
2842
+ for (const note of movePlan.notes) {
2843
+ planLines.push(` - ${note}`);
2844
+ }
2845
+ }
2846
+ blocks.push(planLines.join("\n"));
2847
+ }
2848
+ for (const edit of edits) {
2849
+ const moveIntent = getMoveIntentForEdit(edit, planContext);
2850
+ const hasMove = Boolean(moveIntent);
2851
+ const hasStyleOrText = Object.keys(edit.pendingStyles).length > 0 || edit.textEdit != null;
2852
+ if (!hasMove && !hasStyleOrText) continue;
2853
+ const block = hasMove ? buildEditExportWithOptions(edit.locator, edit.pendingStyles, edit.textEdit, { skipContext: true }) : buildEditExport(edit.locator, edit.pendingStyles, edit.textEdit);
2854
+ let moveBlock = "";
2855
+ if (moveIntent) {
2856
+ moveBlock = `
2857
+ ${buildMoveExportLines(moveIntent).join("\n")}`;
2858
+ }
2859
+ blocks.push(block + moveBlock);
2297
2860
  }
2298
2861
  for (const comment of comments) {
2299
2862
  blocks.push(buildCommentExport(comment.locator, comment.text, comment.replies));
@@ -2741,6 +3304,224 @@ function useStyleUpdaters({ stateRef, pushUndo, setState }) {
2741
3304
 
2742
3305
  // src/use-session-manager.ts
2743
3306
  var React3 = __toESM(require("react"));
3307
+
3308
+ // src/clipboard.ts
3309
+ function buildAgentClipboardText(markdown) {
3310
+ return `implement the visual edits
3311
+
3312
+ ${markdown}`;
3313
+ }
3314
+ function tryRestoreFocus(element) {
3315
+ if (!(element instanceof HTMLElement)) return;
3316
+ try {
3317
+ element.focus({ preventScroll: true });
3318
+ } catch {
3319
+ try {
3320
+ element.focus();
3321
+ } catch {
3322
+ }
3323
+ }
3324
+ }
3325
+ async function copyText(text) {
3326
+ const nav = globalThis.navigator;
3327
+ const clipboard = nav?.clipboard;
3328
+ const clipboardWrite = clipboard?.writeText;
3329
+ if (typeof clipboardWrite === "function") {
3330
+ try {
3331
+ await clipboardWrite.call(clipboard, text);
3332
+ return true;
3333
+ } catch {
3334
+ }
3335
+ }
3336
+ if (typeof document === "undefined") return false;
3337
+ if (typeof document.execCommand !== "function") return false;
3338
+ const body = document.body;
3339
+ if (!body) return false;
3340
+ const activeElement = document.activeElement;
3341
+ const selection = typeof window !== "undefined" ? window.getSelection() : null;
3342
+ const previousRange = selection && selection.rangeCount > 0 ? selection.getRangeAt(0).cloneRange() : null;
3343
+ const textarea = document.createElement("textarea");
3344
+ textarea.value = text;
3345
+ textarea.setAttribute("readonly", "");
3346
+ textarea.style.position = "fixed";
3347
+ textarea.style.top = "0";
3348
+ textarea.style.left = "0";
3349
+ textarea.style.width = "1px";
3350
+ textarea.style.height = "1px";
3351
+ textarea.style.opacity = "0";
3352
+ textarea.style.pointerEvents = "none";
3353
+ body.appendChild(textarea);
3354
+ let copied = false;
3355
+ try {
3356
+ try {
3357
+ textarea.focus({ preventScroll: true });
3358
+ } catch {
3359
+ textarea.focus();
3360
+ }
3361
+ textarea.select();
3362
+ textarea.setSelectionRange(0, textarea.value.length);
3363
+ copied = document.execCommand("copy");
3364
+ } catch {
3365
+ copied = false;
3366
+ } finally {
3367
+ textarea.remove();
3368
+ if (selection) {
3369
+ selection.removeAllRanges();
3370
+ if (previousRange) {
3371
+ selection.addRange(previousRange);
3372
+ }
3373
+ }
3374
+ tryRestoreFocus(activeElement);
3375
+ }
3376
+ return copied;
3377
+ }
3378
+
3379
+ // src/use-session-manager.ts
3380
+ function getLayoutFromDisplay(display) {
3381
+ if (display === "flex" || display === "inline-flex") return "flex";
3382
+ if (display === "grid" || display === "inline-grid") return "grid";
3383
+ if (display === "block" || display === "inline-block" || display === "flow-root" || display === "list-item") {
3384
+ return "block";
3385
+ }
3386
+ return "other";
3387
+ }
3388
+ function getParentLayoutMeta(parent) {
3389
+ if (!parent) return {};
3390
+ const computed = window.getComputedStyle(parent);
3391
+ const display = computed.display;
3392
+ const layout = getLayoutFromDisplay(display);
3393
+ const childCount = countInFlowChildren(parent);
3394
+ if (layout === "flex") {
3395
+ return {
3396
+ display,
3397
+ layout,
3398
+ childCount,
3399
+ flexDirection: computed.flexDirection,
3400
+ gap: computed.gap !== "normal" && computed.gap !== "0px" ? computed.gap : void 0
3401
+ };
3402
+ }
3403
+ if (layout === "grid") {
3404
+ return {
3405
+ display,
3406
+ layout,
3407
+ childCount,
3408
+ gap: computed.gap !== "normal" && computed.gap !== "0px" ? computed.gap : void 0
3409
+ };
3410
+ }
3411
+ return { display, layout, childCount };
3412
+ }
3413
+ function countInFlowChildren(parent) {
3414
+ let count = 0;
3415
+ for (const c of parent.children) {
3416
+ if (c instanceof HTMLElement && isInFlowChild(c)) count++;
3417
+ }
3418
+ return count;
3419
+ }
3420
+ function findChildIndex(parent, child) {
3421
+ if (!parent || !child) return void 0;
3422
+ const index = Array.from(parent.children).indexOf(child);
3423
+ return index >= 0 ? index : void 0;
3424
+ }
3425
+ function getOriginalMoveIndex(parent, previousSibling, nextSibling) {
3426
+ const previousIndex = findChildIndex(parent, previousSibling);
3427
+ if (previousIndex !== void 0) return previousIndex + 1;
3428
+ const nextIndex = findChildIndex(parent, nextSibling);
3429
+ if (nextIndex !== void 0) return nextIndex;
3430
+ return 0;
3431
+ }
3432
+ function applyPositionMoveCSS(element, delta) {
3433
+ const computed = window.getComputedStyle(element);
3434
+ const previousStyles = [];
3435
+ if (computed.position === "static") {
3436
+ previousStyles.push({ cssProperty: "position", previousValue: element.style.getPropertyValue("position") || null });
3437
+ element.style.setProperty("position", "relative");
3438
+ }
3439
+ const appliedLeft = `${(parseFloat(computed.left) || 0) + delta.x}px`;
3440
+ const appliedTop = `${(parseFloat(computed.top) || 0) + delta.y}px`;
3441
+ previousStyles.push({ cssProperty: "left", previousValue: element.style.getPropertyValue("left") || null });
3442
+ previousStyles.push({ cssProperty: "top", previousValue: element.style.getPropertyValue("top") || null });
3443
+ element.style.setProperty("left", appliedLeft);
3444
+ element.style.setProperty("top", appliedTop);
3445
+ return { previousStyles, appliedLeft, appliedTop };
3446
+ }
3447
+ function getAnchor(node) {
3448
+ if (!node) return { selector: null, source: null };
3449
+ const locator = getElementLocator(node);
3450
+ const selector = locator.domSelector.trim();
3451
+ return {
3452
+ selector: selector.length > 0 ? selector : null,
3453
+ source: locator.domSource ?? null
3454
+ };
3455
+ }
3456
+ function buildPositionMoveFields(element, moveInfo, appliedLeft, appliedTop, existingMove) {
3457
+ const parent = element.parentElement;
3458
+ const intended = computeIntendedIndex(parent, element);
3459
+ const parentMeta = getParentLayoutMeta(parent);
3460
+ const parentName = getElementDisplayName(parent);
3461
+ const parentAnchor = getAnchor(parent);
3462
+ const fromIndex = getOriginalMoveIndex(
3463
+ moveInfo.originalParent,
3464
+ moveInfo.originalPreviousSibling,
3465
+ moveInfo.originalNextSibling
3466
+ );
3467
+ const fromParentMeta = existingMove ? getParentLayoutMeta(moveInfo.originalParent) : parentMeta;
3468
+ const fromFields = existingMove ? {
3469
+ fromParentName: existingMove.fromParentName,
3470
+ fromSiblingBefore: existingMove.fromSiblingBefore,
3471
+ fromSiblingAfter: existingMove.fromSiblingAfter,
3472
+ fromParentSelector: existingMove.fromParentSelector ?? null,
3473
+ fromSiblingBeforeSelector: existingMove.fromSiblingBeforeSelector ?? null,
3474
+ fromSiblingAfterSelector: existingMove.fromSiblingAfterSelector ?? null,
3475
+ fromParentSource: existingMove.fromParentSource ?? null,
3476
+ fromSiblingBeforeSource: existingMove.fromSiblingBeforeSource ?? null,
3477
+ fromSiblingAfterSource: existingMove.fromSiblingAfterSource ?? null,
3478
+ fromParentDisplay: existingMove.fromParentDisplay ?? parentMeta.display,
3479
+ fromParentLayout: existingMove.fromParentLayout ?? parentMeta.layout,
3480
+ fromIndex: existingMove.fromIndex ?? fromIndex,
3481
+ fromFlexDirection: existingMove.fromFlexDirection ?? fromParentMeta.flexDirection,
3482
+ fromGap: existingMove.fromGap ?? fromParentMeta.gap,
3483
+ fromChildCount: existingMove.fromChildCount ?? fromParentMeta.childCount
3484
+ } : {
3485
+ fromParentName: parentName,
3486
+ fromSiblingBefore: moveInfo.originalPreviousSibling ? getElementDisplayName(moveInfo.originalPreviousSibling) : null,
3487
+ fromSiblingAfter: moveInfo.originalNextSibling ? getElementDisplayName(moveInfo.originalNextSibling) : null,
3488
+ fromParentSelector: parentAnchor.selector,
3489
+ fromSiblingBeforeSelector: getAnchor(moveInfo.originalPreviousSibling).selector,
3490
+ fromSiblingAfterSelector: getAnchor(moveInfo.originalNextSibling).selector,
3491
+ fromParentSource: parentAnchor.source,
3492
+ fromSiblingBeforeSource: getAnchor(moveInfo.originalPreviousSibling).source,
3493
+ fromSiblingAfterSource: getAnchor(moveInfo.originalNextSibling).source,
3494
+ fromParentDisplay: parentMeta.display,
3495
+ fromParentLayout: parentMeta.layout,
3496
+ fromIndex,
3497
+ fromFlexDirection: parentMeta.flexDirection,
3498
+ fromGap: parentMeta.gap,
3499
+ fromChildCount: parentMeta.childCount
3500
+ };
3501
+ return {
3502
+ ...fromFields,
3503
+ mode: "position",
3504
+ positionDelta: moveInfo.positionDelta,
3505
+ appliedLeft,
3506
+ appliedTop,
3507
+ visualDelta: moveInfo.positionDelta ? { x: Math.round(moveInfo.positionDelta.x), y: Math.round(moveInfo.positionDelta.y) } : void 0,
3508
+ toParentName: parentName,
3509
+ toSiblingBefore: intended.siblingBefore ? getElementDisplayName(intended.siblingBefore) : null,
3510
+ toSiblingAfter: intended.siblingAfter ? getElementDisplayName(intended.siblingAfter) : null,
3511
+ toParentSelector: parentAnchor.selector,
3512
+ toSiblingBeforeSelector: getAnchor(intended.siblingBefore).selector,
3513
+ toSiblingAfterSelector: getAnchor(intended.siblingAfter).selector,
3514
+ toParentSource: parentAnchor.source,
3515
+ toSiblingBeforeSource: getAnchor(intended.siblingBefore).source,
3516
+ toSiblingAfterSource: getAnchor(intended.siblingAfter).source,
3517
+ toParentDisplay: parentMeta.display,
3518
+ toParentLayout: parentMeta.layout,
3519
+ toIndex: intended.index,
3520
+ toFlexDirection: parentMeta.flexDirection,
3521
+ toGap: parentMeta.gap,
3522
+ toChildCount: parentMeta.childCount
3523
+ };
3524
+ }
2744
3525
  function useSessionManager({
2745
3526
  stateRef,
2746
3527
  sessionEditsRef,
@@ -2987,6 +3768,15 @@ function useSessionManager({
2987
3768
  }
2988
3769
  } catch {
2989
3770
  }
3771
+ if (entry.previousPositionStyles) {
3772
+ for (const { cssProperty, previousValue } of entry.previousPositionStyles) {
3773
+ if (previousValue) {
3774
+ entry.element.style.setProperty(cssProperty, previousValue);
3775
+ } else {
3776
+ entry.element.style.removeProperty(cssProperty);
3777
+ }
3778
+ }
3779
+ }
2990
3780
  const sessionEntry = sessionEditsRef.current.get(entry.element);
2991
3781
  if (sessionEntry) {
2992
3782
  const restoredMove = entry.previousSessionMove;
@@ -3058,77 +3848,137 @@ function useSessionManager({
3058
3848
  };
3059
3849
  };
3060
3850
  if (moveInfo) {
3061
- const getAnchor = (node) => {
3062
- if (!node) {
3063
- return { selector: null, source: null };
3851
+ if (moveInfo.mode === "position" && moveInfo.positionDelta) {
3852
+ const existing = sessionEditsRef.current.get(element);
3853
+ const styleState2 = getStyleStateForElement(existing);
3854
+ const { previousStyles, appliedLeft, appliedTop } = applyPositionMoveCSS(element, moveInfo.positionDelta);
3855
+ pushUndo({
3856
+ type: "move",
3857
+ element,
3858
+ originalParent: moveInfo.originalParent,
3859
+ originalNextSibling: moveInfo.originalNextSibling,
3860
+ previousSessionMove: existing?.move ?? null,
3861
+ previousPositionStyles: previousStyles
3862
+ });
3863
+ const locator = existing?.locator ?? getElementLocator(element);
3864
+ const pendingStyles = { ...styleState2.pendingStyles };
3865
+ delete pendingStyles["position"];
3866
+ delete pendingStyles["left"];
3867
+ delete pendingStyles["top"];
3868
+ const move = buildPositionMoveFields(element, moveInfo, appliedLeft, appliedTop, existing?.move ?? null);
3869
+ sessionEditsRef.current.set(element, {
3870
+ element,
3871
+ locator,
3872
+ originalStyles: styleState2.originalStyles,
3873
+ pendingStyles,
3874
+ textEdit: existing?.textEdit ?? null,
3875
+ move
3876
+ });
3877
+ syncSessionItemCount();
3878
+ } else {
3879
+ const existing = sessionEditsRef.current.get(element);
3880
+ const styleState2 = getStyleStateForElement(existing);
3881
+ const moveMode = moveInfo.mode ?? "free";
3882
+ let clearedPositionStyles;
3883
+ if (moveInfo.resetPositionOffsets) {
3884
+ clearedPositionStyles = [];
3885
+ for (const prop of ["position", "left", "top"]) {
3886
+ const prev = element.style.getPropertyValue(prop) || null;
3887
+ clearedPositionStyles.push({ cssProperty: prop, previousValue: prev });
3888
+ element.style.removeProperty(prop);
3889
+ }
3064
3890
  }
3065
- const locator2 = getElementLocator(node);
3066
- const selector = locator2.domSelector.trim();
3067
- return {
3068
- selector: selector.length > 0 ? selector : null,
3069
- source: locator2.domSource ?? null
3891
+ pushUndo({
3892
+ type: "move",
3893
+ element,
3894
+ originalParent: moveInfo.originalParent,
3895
+ originalNextSibling: moveInfo.originalNextSibling,
3896
+ previousSessionMove: existing?.move ?? null,
3897
+ previousPositionStyles: clearedPositionStyles
3898
+ });
3899
+ const locator = existing?.locator ?? getElementLocator(element);
3900
+ const newParent = element.parentElement;
3901
+ const nextPrevSibling = element.previousElementSibling;
3902
+ const nextSibling = element.nextElementSibling;
3903
+ const fromParentAnchor = getAnchor(moveInfo.originalParent);
3904
+ const fromBeforeAnchor = getAnchor(moveInfo.originalPreviousSibling);
3905
+ const fromAfterAnchor = getAnchor(moveInfo.originalNextSibling);
3906
+ const toParentAnchor = getAnchor(newParent);
3907
+ const toBeforeAnchor = getAnchor(nextPrevSibling);
3908
+ const toAfterAnchor = getAnchor(nextSibling);
3909
+ const fromParentMeta = getParentLayoutMeta(moveInfo.originalParent);
3910
+ const toParentMeta = getParentLayoutMeta(newParent);
3911
+ const fromIndex = getOriginalMoveIndex(
3912
+ moveInfo.originalParent,
3913
+ moveInfo.originalPreviousSibling,
3914
+ moveInfo.originalNextSibling
3915
+ );
3916
+ const toIndex = findChildIndex(newParent, element);
3917
+ const fromFields = existing?.move ? {
3918
+ fromParentName: existing.move.fromParentName,
3919
+ fromSiblingBefore: existing.move.fromSiblingBefore,
3920
+ fromSiblingAfter: existing.move.fromSiblingAfter,
3921
+ fromParentSelector: existing.move.fromParentSelector ?? null,
3922
+ fromSiblingBeforeSelector: existing.move.fromSiblingBeforeSelector ?? null,
3923
+ fromSiblingAfterSelector: existing.move.fromSiblingAfterSelector ?? null,
3924
+ fromParentSource: existing.move.fromParentSource ?? null,
3925
+ fromSiblingBeforeSource: existing.move.fromSiblingBeforeSource ?? null,
3926
+ fromSiblingAfterSource: existing.move.fromSiblingAfterSource ?? null,
3927
+ fromParentDisplay: existing.move.fromParentDisplay ?? fromParentMeta.display,
3928
+ fromParentLayout: existing.move.fromParentLayout ?? fromParentMeta.layout,
3929
+ fromIndex: existing.move.fromIndex ?? fromIndex,
3930
+ fromFlexDirection: existing.move.fromFlexDirection ?? fromParentMeta.flexDirection,
3931
+ fromGap: existing.move.fromGap ?? fromParentMeta.gap,
3932
+ fromChildCount: existing.move.fromChildCount ?? fromParentMeta.childCount
3933
+ } : {
3934
+ fromParentName: getElementDisplayName(moveInfo.originalParent),
3935
+ fromSiblingBefore: moveInfo.originalPreviousSibling ? getElementDisplayName(moveInfo.originalPreviousSibling) : null,
3936
+ fromSiblingAfter: moveInfo.originalNextSibling ? getElementDisplayName(moveInfo.originalNextSibling) : null,
3937
+ fromParentSelector: fromParentAnchor.selector,
3938
+ fromSiblingBeforeSelector: fromBeforeAnchor.selector,
3939
+ fromSiblingAfterSelector: fromAfterAnchor.selector,
3940
+ fromParentSource: fromParentAnchor.source,
3941
+ fromSiblingBeforeSource: fromBeforeAnchor.source,
3942
+ fromSiblingAfterSource: fromAfterAnchor.source,
3943
+ fromParentDisplay: fromParentMeta.display,
3944
+ fromParentLayout: fromParentMeta.layout,
3945
+ fromIndex,
3946
+ fromFlexDirection: fromParentMeta.flexDirection,
3947
+ fromGap: fromParentMeta.gap,
3948
+ fromChildCount: fromParentMeta.childCount
3070
3949
  };
3071
- };
3072
- const existing = sessionEditsRef.current.get(element);
3073
- const styleState2 = getStyleStateForElement(existing);
3074
- pushUndo({
3075
- type: "move",
3076
- element,
3077
- originalParent: moveInfo.originalParent,
3078
- originalNextSibling: moveInfo.originalNextSibling,
3079
- previousSessionMove: existing?.move ?? null
3080
- });
3081
- const locator = existing?.locator ?? getElementLocator(element);
3082
- const newParent = element.parentElement;
3083
- const nextPrevSibling = element.previousElementSibling;
3084
- const nextSibling = element.nextElementSibling;
3085
- const fromParentAnchor = getAnchor(moveInfo.originalParent);
3086
- const fromBeforeAnchor = getAnchor(moveInfo.originalPreviousSibling);
3087
- const fromAfterAnchor = getAnchor(moveInfo.originalNextSibling);
3088
- const toParentAnchor = getAnchor(newParent);
3089
- const toBeforeAnchor = getAnchor(nextPrevSibling);
3090
- const toAfterAnchor = getAnchor(nextSibling);
3091
- const fromFields = existing?.move ? {
3092
- fromParentName: existing.move.fromParentName,
3093
- fromSiblingBefore: existing.move.fromSiblingBefore,
3094
- fromSiblingAfter: existing.move.fromSiblingAfter,
3095
- fromParentSelector: existing.move.fromParentSelector ?? null,
3096
- fromSiblingBeforeSelector: existing.move.fromSiblingBeforeSelector ?? null,
3097
- fromSiblingAfterSelector: existing.move.fromSiblingAfterSelector ?? null,
3098
- fromParentSource: existing.move.fromParentSource ?? null,
3099
- fromSiblingBeforeSource: existing.move.fromSiblingBeforeSource ?? null,
3100
- fromSiblingAfterSource: existing.move.fromSiblingAfterSource ?? null
3101
- } : {
3102
- fromParentName: getElementDisplayName(moveInfo.originalParent),
3103
- fromSiblingBefore: moveInfo.originalPreviousSibling ? getElementDisplayName(moveInfo.originalPreviousSibling) : null,
3104
- fromSiblingAfter: moveInfo.originalNextSibling ? getElementDisplayName(moveInfo.originalNextSibling) : null,
3105
- fromParentSelector: fromParentAnchor.selector,
3106
- fromSiblingBeforeSelector: fromBeforeAnchor.selector,
3107
- fromSiblingAfterSelector: fromAfterAnchor.selector,
3108
- fromParentSource: fromParentAnchor.source,
3109
- fromSiblingBeforeSource: fromBeforeAnchor.source,
3110
- fromSiblingAfterSource: fromAfterAnchor.source
3111
- };
3112
- sessionEditsRef.current.set(element, {
3113
- element,
3114
- locator,
3115
- originalStyles: styleState2.originalStyles,
3116
- pendingStyles: styleState2.pendingStyles,
3117
- textEdit: existing?.textEdit ?? null,
3118
- move: newParent ? {
3119
- ...fromFields,
3120
- toParentName: getElementDisplayName(newParent),
3121
- toSiblingBefore: nextPrevSibling ? getElementDisplayName(nextPrevSibling) : null,
3122
- toSiblingAfter: nextSibling ? getElementDisplayName(nextSibling) : null,
3123
- toParentSelector: toParentAnchor.selector,
3124
- toSiblingBeforeSelector: toBeforeAnchor.selector,
3125
- toSiblingAfterSelector: toAfterAnchor.selector,
3126
- toParentSource: toParentAnchor.source,
3127
- toSiblingBeforeSource: toBeforeAnchor.source,
3128
- toSiblingAfterSource: toAfterAnchor.source
3129
- } : null
3130
- });
3131
- syncSessionItemCount();
3950
+ sessionEditsRef.current.set(element, {
3951
+ element,
3952
+ locator,
3953
+ originalStyles: styleState2.originalStyles,
3954
+ pendingStyles: styleState2.pendingStyles,
3955
+ textEdit: existing?.textEdit ?? null,
3956
+ move: newParent ? {
3957
+ ...fromFields,
3958
+ toParentName: getElementDisplayName(newParent),
3959
+ toSiblingBefore: nextPrevSibling ? getElementDisplayName(nextPrevSibling) : null,
3960
+ toSiblingAfter: nextSibling ? getElementDisplayName(nextSibling) : null,
3961
+ toParentSelector: toParentAnchor.selector,
3962
+ toSiblingBeforeSelector: toBeforeAnchor.selector,
3963
+ toSiblingAfterSelector: toAfterAnchor.selector,
3964
+ toParentSource: toParentAnchor.source,
3965
+ toSiblingBeforeSource: toBeforeAnchor.source,
3966
+ toSiblingAfterSource: toAfterAnchor.source,
3967
+ mode: moveMode,
3968
+ fromParentDisplay: fromFields.fromParentDisplay,
3969
+ fromParentLayout: fromFields.fromParentLayout,
3970
+ fromIndex: fromFields.fromIndex,
3971
+ toParentDisplay: toParentMeta.display,
3972
+ toParentLayout: toParentMeta.layout,
3973
+ toIndex,
3974
+ visualDelta: moveInfo.visualDelta,
3975
+ toFlexDirection: toParentMeta.flexDirection,
3976
+ toGap: toParentMeta.gap,
3977
+ toChildCount: toParentMeta.childCount
3978
+ } : null
3979
+ });
3980
+ syncSessionItemCount();
3981
+ }
3132
3982
  }
3133
3983
  const computed = getAllComputedStyles(element);
3134
3984
  const elementInfo = getElementInfo(element);
@@ -3182,15 +4032,12 @@ function useSessionManager({
3182
4032
  if (items.length === 0) return false;
3183
4033
  const edits = items.filter((item) => item.type === "edit").map((item) => item.edit);
3184
4034
  const comments = items.filter((item) => item.type === "comment").map((item) => item.comment);
3185
- const text = buildSessionExport(edits, comments);
3186
- try {
3187
- await navigator.clipboard.writeText(`implement the visual edits
4035
+ const movePlanContext = buildMovePlanContext(edits);
4036
+ const text = buildSessionExport(edits, comments, { movePlanContext });
4037
+ const instruction = buildExportInstruction(getExportContentProfile(edits, comments, movePlanContext));
4038
+ return copyText(`${instruction}
3188
4039
 
3189
4040
  ${text}`);
3190
- return true;
3191
- } catch {
3192
- return false;
3193
- }
3194
4041
  }, [getSessionItems]);
3195
4042
  const revertElementStyles = React3.useCallback((element, sessionEdit) => {
3196
4043
  for (const prop of Object.keys(sessionEdit.pendingStyles)) {
@@ -3265,22 +4112,27 @@ ${text}`);
3265
4112
  const sessionEdit = sessionEditsRef.current.get(current.selectedElement);
3266
4113
  const hasPendingStyles = Object.keys(current.pendingStyles).length > 0;
3267
4114
  const hasTextEdit = Boolean(sessionEdit?.textEdit);
3268
- const hasMove = Boolean(sessionEdit?.move);
3269
4115
  const locator = getElementLocator(current.selectedElement);
3270
- const exportMarkdown = hasPendingStyles || hasTextEdit || hasMove ? hasMove && sessionEdit ? buildSessionExport([{
4116
+ const editForExport = sessionEdit ? {
3271
4117
  ...sessionEdit,
3272
4118
  locator,
3273
4119
  pendingStyles: { ...current.pendingStyles },
3274
4120
  textEdit: sessionEdit.textEdit
3275
- }], []) : buildEditExport(locator, current.pendingStyles, sessionEdit?.textEdit) : buildElementContext(locator);
3276
- try {
3277
- await navigator.clipboard.writeText(`implement the visual edits
4121
+ } : null;
4122
+ const movePlanContext = editForExport?.move ? buildMovePlanContext([editForExport]) : null;
4123
+ const moveIntent = editForExport?.move ? getMoveIntentForEdit(editForExport, movePlanContext) : null;
4124
+ const hasMove = Boolean(moveIntent);
4125
+ const hasExportableEdit = hasPendingStyles || hasTextEdit || hasMove;
4126
+ const exportMarkdown = hasExportableEdit ? hasMove && editForExport ? buildSessionExport([editForExport], [], { movePlanContext }) : buildEditExport(locator, current.pendingStyles, sessionEdit?.textEdit) : buildElementContext(locator);
4127
+ const instruction = hasExportableEdit ? buildExportInstruction({
4128
+ hasCssEdits: hasPendingStyles,
4129
+ hasTextEdits: hasTextEdit,
4130
+ hasMoves: hasMove,
4131
+ hasComments: false
4132
+ }) : "Here is the element context for reference";
4133
+ return copyText(`${instruction}
3278
4134
 
3279
4135
  ${exportMarkdown}`);
3280
- return true;
3281
- } catch {
3282
- return false;
3283
- }
3284
4136
  }, []);
3285
4137
  return {
3286
4138
  syncSessionItemCount,
@@ -3304,6 +4156,10 @@ ${exportMarkdown}`);
3304
4156
 
3305
4157
  // src/use-text-and-comments.ts
3306
4158
  var React4 = __toESM(require("react"));
4159
+ function clampUnit(value) {
4160
+ if (!Number.isFinite(value)) return 0;
4161
+ return Math.max(0, Math.min(1, value));
4162
+ }
3307
4163
  function useTextAndComments({
3308
4164
  stateRef,
3309
4165
  sessionEditsRef,
@@ -3367,8 +4223,8 @@ function useTextAndComments({
3367
4223
  const locator = getElementLocator(element);
3368
4224
  const rect = element.getBoundingClientRect();
3369
4225
  const relativePosition = {
3370
- x: rect.width > 0 ? (clickPosition.x - rect.left) / rect.width : 0,
3371
- y: rect.height > 0 ? (clickPosition.y - rect.top) / rect.height : 0
4226
+ x: rect.width > 0 ? clampUnit((clickPosition.x - rect.left) / rect.width) : 0,
4227
+ y: rect.height > 0 ? clampUnit((clickPosition.y - rect.top) / rect.height) : 0
3372
4228
  };
3373
4229
  const id = `comment-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
3374
4230
  const comment = {
@@ -3415,14 +4271,15 @@ function useTextAndComments({
3415
4271
  const comment = stateRef.current.comments.find((c) => c.id === id);
3416
4272
  if (!comment) return false;
3417
4273
  const exportMarkdown = buildCommentExport(comment.locator, comment.text, comment.replies);
3418
- try {
3419
- await navigator.clipboard.writeText(`implement the visual edits
4274
+ const instruction = buildExportInstruction({
4275
+ hasCssEdits: false,
4276
+ hasTextEdits: false,
4277
+ hasMoves: false,
4278
+ hasComments: true
4279
+ });
4280
+ return copyText(`${instruction}
3420
4281
 
3421
4282
  ${exportMarkdown}`);
3422
- return true;
3423
- } catch {
3424
- return false;
3425
- }
3426
4283
  }, []);
3427
4284
  const setActiveCommentId = React4.useCallback((id) => {
3428
4285
  setState((prev) => {
@@ -3820,24 +4677,36 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems }) {
3820
4677
  const sessionEdit = sessionEditsRef.current.get(selectedElement);
3821
4678
  const hasPendingStyles = Object.keys(pendingStyles).length > 0;
3822
4679
  const hasTextEdit = Boolean(sessionEdit?.textEdit);
3823
- const hasMove = Boolean(sessionEdit?.move);
4680
+ const hasMove = Boolean(
4681
+ sessionEdit?.move && getMoveIntentForEdit(sessionEdit, buildMovePlanContext([sessionEdit]))
4682
+ );
3824
4683
  return hasPendingStyles || hasTextEdit || hasMove;
3825
4684
  }, []);
3826
- const sendSessionEditToAgent = React5.useCallback(async (sessionEdit) => {
4685
+ const sendSessionEditToAgent = React5.useCallback(async (sessionEdit, allEdits, movePlanContext, options) => {
3827
4686
  const locator = sessionEdit.locator;
3828
4687
  const pendingStyles = { ...sessionEdit.pendingStyles };
3829
- const exportMarkdown = sessionEdit.move ? buildSessionExport([{
3830
- ...sessionEdit,
3831
- locator,
3832
- pendingStyles,
3833
- textEdit: sessionEdit.textEdit
3834
- }], []) : buildEditExport(locator, pendingStyles, sessionEdit.textEdit);
4688
+ const editsForPlan = allEdits ?? [sessionEdit];
4689
+ const resolvedPlanContext = movePlanContext ?? buildMovePlanContext(editsForPlan);
4690
+ const includeBatchMoveEnvelope = Boolean(options?.includeBatchMoveEnvelope && sessionEdit.move);
4691
+ const isBatchSend = Boolean(allEdits && allEdits.length > 1);
4692
+ const exportMarkdown = sessionEdit.move ? buildSessionExport(
4693
+ includeBatchMoveEnvelope ? editsForPlan : [sessionEdit],
4694
+ [],
4695
+ {
4696
+ movePlanContext: resolvedPlanContext,
4697
+ includeMovePlanHeader: includeBatchMoveEnvelope || !isBatchSend
4698
+ }
4699
+ ) : buildEditExport(locator, pendingStyles, sessionEdit.textEdit);
3835
4700
  const collapsedStyles = collapseExportShorthands(pendingStyles);
3836
4701
  const changes = Object.entries(collapsedStyles).map(([cssProperty, cssValue]) => ({
3837
4702
  cssProperty,
3838
4703
  cssValue,
3839
4704
  tailwindClass: stylesToTailwind({ [cssProperty]: cssValue })
3840
4705
  }));
4706
+ const moveIntent = sessionEdit.move ? getMoveIntentForEdit(sessionEdit, resolvedPlanContext) : null;
4707
+ const movePlan = includeBatchMoveEnvelope ? resolvedPlanContext.movePlan : null;
4708
+ const hasMeaningfulPayload = changes.length > 0 || sessionEdit.textEdit != null || moveIntent != null;
4709
+ if (!hasMeaningfulPayload) return true;
3841
4710
  try {
3842
4711
  const result = await sendEditToAgent({
3843
4712
  element: {
@@ -3852,7 +4721,8 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems }) {
3852
4721
  reactStack: locator.reactStack,
3853
4722
  changes,
3854
4723
  textChange: sessionEdit.textEdit ?? null,
3855
- moveChange: sessionEdit.move ?? null,
4724
+ moveIntent,
4725
+ ...movePlan ? { movePlan } : {},
3856
4726
  exportMarkdown
3857
4727
  });
3858
4728
  return result.ok;
@@ -3911,9 +4781,25 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems }) {
3911
4781
  const sendAllSessionItemsToAgent = React5.useCallback(async () => {
3912
4782
  const items = getSessionItems();
3913
4783
  if (items.length === 0) return false;
4784
+ const allEdits = items.filter((i) => i.type === "edit").map((i) => i.edit);
4785
+ const movePlanContext = buildMovePlanContext(allEdits);
4786
+ let moveEnvelopeSent = false;
3914
4787
  let allSucceeded = true;
3915
4788
  for (const item of items) {
3916
- const succeeded = item.type === "edit" ? await sendSessionEditToAgent(item.edit) : await sendSessionCommentToAgent(item.comment);
4789
+ let succeeded;
4790
+ if (item.type === "edit") {
4791
+ const hasMoveIntent = Boolean(item.edit.move && getMoveIntentForEdit(item.edit, movePlanContext));
4792
+ const includeBatchMoveEnvelope = hasMoveIntent && !moveEnvelopeSent;
4793
+ succeeded = await sendSessionEditToAgent(
4794
+ item.edit,
4795
+ allEdits,
4796
+ movePlanContext,
4797
+ { includeBatchMoveEnvelope }
4798
+ );
4799
+ if (includeBatchMoveEnvelope) moveEnvelopeSent = true;
4800
+ } else {
4801
+ succeeded = await sendSessionCommentToAgent(item.comment);
4802
+ }
3917
4803
  if (!succeeded) {
3918
4804
  allSucceeded = false;
3919
4805
  }
@@ -4105,6 +4991,8 @@ var LINE_HEIGHT_PX = 40;
4105
4991
  var PAGE_HEIGHT_PX = 800;
4106
4992
  var CANVAS_MEASURE_NODE_BUDGET = 12e3;
4107
4993
  var CANVAS_PRIORITY_ROOT_SELECTORS = ["#root", "#app", "#__next", "main"];
4994
+ var FIXED_FRAME_CANVAS_MIN_VIEWPORT_COVERAGE = 0.6;
4995
+ var FIXED_FRAME_CANVAS_EDGE_TOLERANCE_PX = 1;
4108
4996
  function normalizeWheelDelta(e) {
4109
4997
  let { deltaX, deltaY } = e;
4110
4998
  if (e.deltaMode === 1) {
@@ -4116,6 +5004,46 @@ function normalizeWheelDelta(e) {
4116
5004
  }
4117
5005
  return { deltaX, deltaY };
4118
5006
  }
5007
+ function getVisibleAreaInViewport(rect) {
5008
+ const left = Math.max(0, rect.left);
5009
+ const top = Math.max(0, rect.top);
5010
+ const right = Math.min(window.innerWidth, rect.right);
5011
+ const bottom = Math.min(window.innerHeight, rect.bottom);
5012
+ const width = Math.max(0, right - left);
5013
+ const height = Math.max(0, bottom - top);
5014
+ return width * height;
5015
+ }
5016
+ function getFixedFrameCanvasDimensions() {
5017
+ const viewportWidth = window.innerWidth;
5018
+ const viewportHeight = window.innerHeight;
5019
+ const viewportArea = viewportWidth * viewportHeight;
5020
+ if (viewportArea <= 0) return null;
5021
+ let bestArea = 0;
5022
+ let bestRect = null;
5023
+ const canvases = document.querySelectorAll("canvas");
5024
+ for (const canvas of canvases) {
5025
+ if (canvas.closest("[data-direct-edit]") || canvas.closest("[data-direct-edit-host]")) continue;
5026
+ const style = getComputedStyle(canvas);
5027
+ if (style.display === "none" || style.visibility === "hidden") continue;
5028
+ const opacity = parseFloat(style.opacity);
5029
+ if ((Number.isFinite(opacity) ? opacity : 1) <= 0) continue;
5030
+ const rect = canvas.getBoundingClientRect();
5031
+ if (style.position !== "fixed") continue;
5032
+ if (Math.abs(rect.left) > FIXED_FRAME_CANVAS_EDGE_TOLERANCE_PX || Math.abs(rect.top) > FIXED_FRAME_CANVAS_EDGE_TOLERANCE_PX) {
5033
+ continue;
5034
+ }
5035
+ const visibleArea = getVisibleAreaInViewport(rect);
5036
+ if (visibleArea <= bestArea) continue;
5037
+ bestArea = visibleArea;
5038
+ bestRect = rect;
5039
+ }
5040
+ if (!bestRect) return null;
5041
+ if (bestArea / viewportArea < FIXED_FRAME_CANVAS_MIN_VIEWPORT_COVERAGE) return null;
5042
+ return {
5043
+ width: Math.max(viewportWidth, bestRect.width),
5044
+ height: Math.max(viewportHeight, bestRect.height)
5045
+ };
5046
+ }
4119
5047
  function getResolvedOverflowY(style) {
4120
5048
  return style.overflowY || style.overflow;
4121
5049
  }
@@ -4178,6 +5106,7 @@ function clampPan(zoom, panX, panY, bodyW, bodyH) {
4178
5106
  function useCanvas({ stateRef, setState }) {
4179
5107
  React7.useEffect(() => registerCanvasStoreOwner(), []);
4180
5108
  const canvasRef = React7.useRef({ active: false, zoom: 1, panX: 0, panY: 0 });
5109
+ const canvasStrategyRef = React7.useRef("body-transform");
4181
5110
  const savedScrollRef = React7.useRef({ x: 0, y: 0 });
4182
5111
  const savedBodyOverflowRef = React7.useRef("");
4183
5112
  const savedHtmlOverflowRef = React7.useRef("");
@@ -4198,6 +5127,9 @@ function useCanvas({ stateRef, setState }) {
4198
5127
  window.dispatchEvent(new Event("direct-edit-canvas-change"));
4199
5128
  }, []);
4200
5129
  const readBodyOffset = React7.useCallback(() => {
5130
+ if (canvasStrategyRef.current !== "body-transform") {
5131
+ return { x: 0, y: 0 };
5132
+ }
4201
5133
  const bodyStyle = getComputedStyle(document.body);
4202
5134
  return {
4203
5135
  x: parseFloat(bodyStyle.marginLeft) || 0,
@@ -4334,20 +5266,32 @@ function useCanvas({ stateRef, setState }) {
4334
5266
  savedHtmlOverflowRef.current = document.documentElement.style.overflow;
4335
5267
  savedHtmlBgColorRef.current = document.documentElement.style.backgroundColor;
4336
5268
  domStateSavedRef.current = true;
4337
- const existingTransform = document.body.style.transform;
4338
- if (existingTransform && existingTransform !== "none" && existingTransform !== "") {
4339
- console.warn("[made-refine] canvas mode: overriding existing body transform:", existingTransform);
5269
+ const fixedFrameDims = getFixedFrameCanvasDimensions();
5270
+ canvasStrategyRef.current = fixedFrameDims ? "fixed-frame" : "body-transform";
5271
+ if (canvasStrategyRef.current === "body-transform") {
5272
+ const existingTransform = document.body.style.transform;
5273
+ if (existingTransform && existingTransform !== "none" && existingTransform !== "") {
5274
+ console.warn("[made-refine] canvas mode: overriding existing body transform:", existingTransform);
5275
+ }
4340
5276
  }
4341
5277
  let entered = false;
4342
5278
  try {
4343
5279
  window.scrollTo(0, 0);
4344
- savedBodyDimensionsRef.current = expandScrollableRegionsAndMeasureBody();
4345
- updateBodyOffset();
5280
+ if (canvasStrategyRef.current === "body-transform") {
5281
+ savedBodyDimensionsRef.current = expandScrollableRegionsAndMeasureBody();
5282
+ updateBodyOffset();
5283
+ } else {
5284
+ savedBodyDimensionsRef.current = fixedFrameDims ?? {
5285
+ width: window.innerWidth,
5286
+ height: window.innerHeight
5287
+ };
5288
+ setBodyOffset({ x: 0, y: 0 });
5289
+ }
4346
5290
  document.body.style.overflow = "hidden";
4347
5291
  document.documentElement.style.overflow = "hidden";
4348
5292
  document.documentElement.style.backgroundColor = "#F5F5F5";
4349
- const initialPanX = -scrollX;
4350
- const initialPanY = -scrollY;
5293
+ const initialPanX = canvasStrategyRef.current === "body-transform" ? -scrollX : 0;
5294
+ const initialPanY = canvasStrategyRef.current === "body-transform" ? -scrollY : 0;
4351
5295
  applyTransform(1, initialPanX, initialPanY);
4352
5296
  canvasRef.current = { active: true, zoom: 1, panX: initialPanX, panY: initialPanY };
4353
5297
  setCanvasSnapshot(canvasRef.current);
@@ -4367,6 +5311,7 @@ function useCanvas({ stateRef, setState }) {
4367
5311
  document.documentElement.style.backgroundColor = savedHtmlBgColorRef.current;
4368
5312
  window.scrollTo(scrollX, scrollY);
4369
5313
  domStateSavedRef.current = false;
5314
+ canvasStrategyRef.current = "body-transform";
4370
5315
  }
4371
5316
  }
4372
5317
  }, [applyTransform, dispatchCanvasChange, setState, updateBodyOffset]);
@@ -4386,6 +5331,7 @@ function useCanvas({ stateRef, setState }) {
4386
5331
  }
4387
5332
  document.body.style.cursor = "";
4388
5333
  domStateSavedRef.current = false;
5334
+ canvasStrategyRef.current = "body-transform";
4389
5335
  setBodyOffset({ x: 0, y: 0 });
4390
5336
  canvasRef.current = { active: false, zoom: 1, panX: 0, panY: 0 };
4391
5337
  setCanvasSnapshot(canvasRef.current);
@@ -4455,6 +5401,14 @@ function useCanvas({ stateRef, setState }) {
4455
5401
  React7.useEffect(() => {
4456
5402
  function handleResize() {
4457
5403
  if (!canvasRef.current.active) return;
5404
+ if (canvasStrategyRef.current === "fixed-frame") {
5405
+ savedBodyDimensionsRef.current = getFixedFrameCanvasDimensions() ?? {
5406
+ width: window.innerWidth,
5407
+ height: window.innerHeight
5408
+ };
5409
+ dispatchCanvasChange();
5410
+ return;
5411
+ }
4458
5412
  if (updateBodyOffset()) {
4459
5413
  dispatchCanvasChange();
4460
5414
  }
@@ -4721,6 +5675,17 @@ function DirectEditProvider({ children }) {
4721
5675
  document.removeEventListener("mousedown", handleMouseDown, true);
4722
5676
  };
4723
5677
  }, [state.textEditingElement, commitTextEditing]);
5678
+ React8.useEffect(() => {
5679
+ if (!state.editModeActive || state.textEditingElement) return;
5680
+ function blockClick(e) {
5681
+ const host = document.querySelector("[data-direct-edit-host]");
5682
+ if (host && e.target === host) return;
5683
+ e.preventDefault();
5684
+ e.stopPropagation();
5685
+ }
5686
+ document.addEventListener("click", blockClick, true);
5687
+ return () => document.removeEventListener("click", blockClick, true);
5688
+ }, [state.editModeActive, state.textEditingElement]);
4724
5689
  const {
4725
5690
  canSendEditToAgent,
4726
5691
  sendEditToAgent: sendEditToAgent2,
@@ -5148,6 +6113,37 @@ var INITIAL_DRAG_STATE = {
5148
6113
  ghostPosition: { x: 0, y: 0 },
5149
6114
  dragOffset: { x: 0, y: 0 }
5150
6115
  };
6116
+ var DEFAULT_DRAG_OPTIONS = {
6117
+ constrainToOriginalParent: false,
6118
+ mode: "free"
6119
+ };
6120
+ function normalizeStartDragOptions(options) {
6121
+ const mode = options?.mode ?? (options?.constrainToOriginalParent ? "reorder" : "free");
6122
+ return {
6123
+ mode,
6124
+ constrainToOriginalParent: mode === "reorder" || Boolean(options?.constrainToOriginalParent)
6125
+ };
6126
+ }
6127
+ function resolveFlexDirection(container, draggedElement) {
6128
+ const { axis, reversed } = detectChildrenDirection(container, draggedElement);
6129
+ if (axis === "horizontal") return reversed ? "row-reverse" : "row";
6130
+ return reversed ? "column-reverse" : "column";
6131
+ }
6132
+ function tryReparent(draggedElement, target, originalParent, originalNextSibling) {
6133
+ const isSamePosition = target.container === originalParent && target.insertBefore === originalNextSibling;
6134
+ const isInvalidTarget = target.container === draggedElement || draggedElement.contains(target.container) || (target.insertBefore ? draggedElement.contains(target.insertBefore) : false);
6135
+ if (isSamePosition || isInvalidTarget) return false;
6136
+ try {
6137
+ if (target.insertBefore) {
6138
+ target.container.insertBefore(draggedElement, target.insertBefore);
6139
+ } else {
6140
+ target.container.appendChild(draggedElement);
6141
+ }
6142
+ return true;
6143
+ } catch {
6144
+ return false;
6145
+ }
6146
+ }
5151
6147
  function useMove({ onMoveComplete }) {
5152
6148
  const [dragState, setDragState] = React12.useState(INITIAL_DRAG_STATE);
5153
6149
  const [dropTarget, setDropTarget] = React12.useState(null);
@@ -5155,7 +6151,11 @@ function useMove({ onMoveComplete }) {
5155
6151
  const dragStateRef = React12.useRef(dragState);
5156
6152
  const dropTargetRef = React12.useRef(dropTarget);
5157
6153
  const onMoveCompleteRef = React12.useRef(onMoveComplete);
5158
- const dragOptionsRef = React12.useRef({});
6154
+ const dragOptionsRef = React12.useRef(DEFAULT_DRAG_OPTIONS);
6155
+ const initialRectRef = React12.useRef(
6156
+ { x: 0, y: 0, scaleX: 1, scaleY: 1 }
6157
+ );
6158
+ const originalTransformRef = React12.useRef("");
5159
6159
  React12.useEffect(() => {
5160
6160
  dragStateRef.current = dragState;
5161
6161
  dropTargetRef.current = dropTarget;
@@ -5165,8 +6165,11 @@ function useMove({ onMoveComplete }) {
5165
6165
  const current = dragStateRef.current;
5166
6166
  if (current.draggedElement) {
5167
6167
  current.draggedElement.style.opacity = "";
6168
+ current.draggedElement.style.transform = originalTransformRef.current;
5168
6169
  }
5169
- dragOptionsRef.current = {};
6170
+ originalTransformRef.current = "";
6171
+ initialRectRef.current = { x: 0, y: 0, scaleX: 1, scaleY: 1 };
6172
+ dragOptionsRef.current = DEFAULT_DRAG_OPTIONS;
5170
6173
  setDragState(INITIAL_DRAG_STATE);
5171
6174
  setDropTarget(null);
5172
6175
  setDropIndicator(null);
@@ -5179,31 +6182,43 @@ function useMove({ onMoveComplete }) {
5179
6182
  cancelDrag();
5180
6183
  return;
5181
6184
  }
6185
+ const initialPos = { x: initialRectRef.current.x, y: initialRectRef.current.y };
6186
+ const { scaleX, scaleY } = initialRectRef.current;
6187
+ draggedElement.style.transform = originalTransformRef.current;
5182
6188
  draggedElement.style.opacity = "";
5183
- dragOptionsRef.current = {};
5184
- let didMove = false;
5185
- if (target) {
5186
- const isSamePosition = target.container === originalParent && target.insertBefore === originalNextSibling;
5187
- const isInvalidTarget = target.container === draggedElement || draggedElement.contains(target.container) || (target.insertBefore ? draggedElement.contains(target.insertBefore) : false);
5188
- if (!isSamePosition && !isInvalidTarget) {
5189
- try {
5190
- if (target.insertBefore) {
5191
- target.container.insertBefore(draggedElement, target.insertBefore);
5192
- } else {
5193
- target.container.appendChild(draggedElement);
5194
- }
5195
- didMove = true;
5196
- } catch {
6189
+ originalTransformRef.current = "";
6190
+ initialRectRef.current = { x: 0, y: 0, scaleX: 1, scaleY: 1 };
6191
+ const dragMode = dragOptionsRef.current.mode;
6192
+ dragOptionsRef.current = DEFAULT_DRAG_OPTIONS;
6193
+ const vd = {
6194
+ x: Math.round(current.ghostPosition.x - initialPos.x),
6195
+ y: Math.round(current.ghostPosition.y - initialPos.y)
6196
+ };
6197
+ const hasVisualDelta = vd.x !== 0 || vd.y !== 0;
6198
+ let moveInfo = null;
6199
+ if (dragMode === "position") {
6200
+ if (target && tryReparent(draggedElement, target, originalParent, originalNextSibling)) {
6201
+ if (originalParent) {
6202
+ moveInfo = { originalParent, originalPreviousSibling, originalNextSibling, mode: "free", resetPositionOffsets: true, visualDelta: hasVisualDelta ? vd : void 0 };
5197
6203
  }
5198
6204
  }
6205
+ if (!moveInfo) {
6206
+ const rect = draggedElement.getBoundingClientRect();
6207
+ const deltaX = (current.ghostPosition.x - rect.left) / scaleX;
6208
+ const deltaY = (current.ghostPosition.y - rect.top) / scaleY;
6209
+ if ((Math.abs(deltaX) > 0.5 || Math.abs(deltaY) > 0.5) && originalParent) {
6210
+ moveInfo = { originalParent, originalPreviousSibling, originalNextSibling, mode: "position", positionDelta: { x: deltaX, y: deltaY } };
6211
+ }
6212
+ }
6213
+ } else if (target && tryReparent(draggedElement, target, originalParent, originalNextSibling)) {
6214
+ if (originalParent) {
6215
+ moveInfo = { originalParent, originalPreviousSibling, originalNextSibling, mode: dragMode, visualDelta: hasVisualDelta ? vd : void 0 };
6216
+ }
5199
6217
  }
5200
6218
  setDragState(INITIAL_DRAG_STATE);
5201
6219
  setDropTarget(null);
5202
6220
  setDropIndicator(null);
5203
- if (onMoveCompleteRef.current && draggedElement) {
5204
- const moveInfo = didMove && originalParent ? { originalParent, originalPreviousSibling, originalNextSibling } : null;
5205
- onMoveCompleteRef.current(draggedElement, moveInfo);
5206
- }
6221
+ onMoveCompleteRef.current?.(draggedElement, moveInfo);
5207
6222
  }, [cancelDrag]);
5208
6223
  const startDrag = React12.useCallback(
5209
6224
  (e, element, options) => {
@@ -5211,7 +6226,14 @@ function useMove({ onMoveComplete }) {
5211
6226
  const parent = element.parentElement;
5212
6227
  const previousSibling = element.previousElementSibling;
5213
6228
  const nextSibling = element.nextElementSibling;
5214
- dragOptionsRef.current = options ?? {};
6229
+ dragOptionsRef.current = normalizeStartDragOptions(options);
6230
+ initialRectRef.current = {
6231
+ x: rect.left,
6232
+ y: rect.top,
6233
+ scaleX: element.offsetWidth > 0 ? rect.width / element.offsetWidth : 1,
6234
+ scaleY: element.offsetHeight > 0 ? rect.height / element.offsetHeight : 1
6235
+ };
6236
+ originalTransformRef.current = element.style.transform;
5215
6237
  setDragState({
5216
6238
  isDragging: true,
5217
6239
  draggedElement: element,
@@ -5237,6 +6259,44 @@ function useMove({ onMoveComplete }) {
5237
6259
  y: e.clientY - dragOffset.y
5238
6260
  }
5239
6261
  }));
6262
+ if (draggedElement) {
6263
+ const { x, y, scaleX, scaleY } = initialRectRef.current;
6264
+ const dx = (e.clientX - dragOffset.x - x) / scaleX;
6265
+ const dy = (e.clientY - dragOffset.y - y) / scaleY;
6266
+ draggedElement.style.transform = `translate(${dx}px, ${dy}px)`;
6267
+ }
6268
+ if (dragOptionsRef.current.mode === "position") {
6269
+ let container2 = findLayoutContainerAtPoint(
6270
+ e.clientX,
6271
+ e.clientY,
6272
+ draggedElement,
6273
+ originalParent
6274
+ );
6275
+ if (!container2 && draggedElement && originalParent) {
6276
+ const parentRect = originalParent.getBoundingClientRect();
6277
+ const hasSize = parentRect.width > 0 || parentRect.height > 0;
6278
+ const isOutside = hasSize && (e.clientX < parentRect.left || e.clientX > parentRect.right || e.clientY < parentRect.top || e.clientY > parentRect.bottom);
6279
+ if (isOutside) {
6280
+ const found = findContainerAtPoint(e.clientX, e.clientY, draggedElement, null);
6281
+ if (found && found !== originalParent) container2 = found;
6282
+ }
6283
+ }
6284
+ if (container2 && draggedElement) {
6285
+ const dropPos = calculateDropPosition(container2, e.clientX, e.clientY, draggedElement);
6286
+ if (dropPos) {
6287
+ setDropTarget({
6288
+ container: container2,
6289
+ insertBefore: dropPos.insertBefore,
6290
+ flexDirection: resolveFlexDirection(container2, draggedElement)
6291
+ });
6292
+ setDropIndicator(dropPos.indicator);
6293
+ }
6294
+ } else {
6295
+ setDropTarget(null);
6296
+ setDropIndicator(null);
6297
+ }
6298
+ return;
6299
+ }
5240
6300
  const container = dragOptionsRef.current.constrainToOriginalParent ? originalParent : findContainerAtPoint(
5241
6301
  e.clientX,
5242
6302
  e.clientY,
@@ -5254,11 +6314,7 @@ function useMove({ onMoveComplete }) {
5254
6314
  setDropTarget({
5255
6315
  container,
5256
6316
  insertBefore: dropPos.insertBefore,
5257
- flexDirection: (() => {
5258
- const { axis, reversed } = detectChildrenDirection(container, draggedElement);
5259
- if (axis === "horizontal") return reversed ? "row-reverse" : "row";
5260
- return reversed ? "column-reverse" : "column";
5261
- })()
6317
+ flexDirection: resolveFlexDirection(container, draggedElement)
5262
6318
  });
5263
6319
  setDropIndicator(dropPos.indicator);
5264
6320
  }
@@ -5719,6 +6775,12 @@ var MAGENTA = "#E11BB6";
5719
6775
  var DRAG_THRESHOLD = 4;
5720
6776
  var DBLCLICK_DELAY = 300;
5721
6777
  var HANDLE_SIZE = 12;
6778
+ function isInLayoutContainer(element) {
6779
+ const parent = element.parentElement;
6780
+ if (!parent) return false;
6781
+ const display = window.getComputedStyle(parent).display;
6782
+ return display === "flex" || display === "inline-flex" || display === "grid" || display === "inline-grid";
6783
+ }
5722
6784
  function SelectionOverlay({
5723
6785
  selectedElement,
5724
6786
  draggedElement,
@@ -5737,8 +6799,16 @@ function SelectionOverlay({
5737
6799
  const [moveHandleRects, setMoveHandleRects] = React14.useState([]);
5738
6800
  const cleanupRef = React14.useRef(null);
5739
6801
  const clickThroughTimerRef = React14.useRef(null);
6802
+ const isDraggingRef = React14.useRef(isDragging);
6803
+ isDraggingRef.current = isDragging;
6804
+ React14.useLayoutEffect(() => {
6805
+ if (!isDragging) {
6806
+ setRect(rectElement.getBoundingClientRect());
6807
+ }
6808
+ }, [isDragging, rectElement]);
5740
6809
  React14.useEffect(() => {
5741
6810
  function updateRect() {
6811
+ if (isDraggingRef.current) return;
5742
6812
  setRect(rectElement.getBoundingClientRect());
5743
6813
  }
5744
6814
  updateRect();
@@ -5779,7 +6849,9 @@ function SelectionOverlay({
5779
6849
  const dy = moveEvent.clientY - origin.y;
5780
6850
  if (dx * dx + dy * dy >= DRAG_THRESHOLD * DRAG_THRESHOLD) {
5781
6851
  cleanup();
5782
- onMoveStart(savedEvent);
6852
+ onMoveStart(savedEvent, void 0, {
6853
+ mode: isInLayoutContainer(selectedElement) ? "free" : "position"
6854
+ });
5783
6855
  }
5784
6856
  };
5785
6857
  const onUp = (upEvent) => {
@@ -5836,7 +6908,7 @@ function SelectionOverlay({
5836
6908
  flexParent = flexParent.parentElement;
5837
6909
  }
5838
6910
  if (!flexParent) {
5839
- return [selectedElement];
6911
+ return [];
5840
6912
  }
5841
6913
  let target = selectedElement;
5842
6914
  while (target.parentElement && target.parentElement !== flexParent) {
@@ -5879,7 +6951,7 @@ function SelectionOverlay({
5879
6951
  clearTimeout(clickThroughTimerRef.current);
5880
6952
  clickThroughTimerRef.current = null;
5881
6953
  }
5882
- onMoveStart(e, target, { constrainToOriginalParent: true });
6954
+ onMoveStart(e, target, { constrainToOriginalParent: true, mode: "reorder" });
5883
6955
  };
5884
6956
  const displayX = isDragging && ghostPosition ? ghostPosition.x : rect.left;
5885
6957
  const displayY = isDragging && ghostPosition ? ghostPosition.y : rect.top;
@@ -5959,6 +7031,10 @@ function SelectionOverlay({
5959
7031
  var React15 = __toESM(require("react"));
5960
7032
  var import_lucide_react = require("lucide-react");
5961
7033
  var import_jsx_runtime8 = require("react/jsx-runtime");
7034
+ function clampUnit2(value) {
7035
+ if (!Number.isFinite(value)) return 0;
7036
+ return Math.max(0, Math.min(1, value));
7037
+ }
5962
7038
  function formatRelativeTime(timestamp) {
5963
7039
  const seconds = Math.floor((Date.now() - timestamp) / 1e3);
5964
7040
  if (seconds < 60) return "just now";
@@ -6041,9 +7117,11 @@ function CommentPin({
6041
7117
  function updatePosition() {
6042
7118
  if (!comment.element.isConnected) return;
6043
7119
  const rect = comment.element.getBoundingClientRect();
7120
+ const relativeX = clampUnit2(comment.relativePosition.x);
7121
+ const relativeY = clampUnit2(comment.relativePosition.y);
6044
7122
  setPosition({
6045
- x: rect.left + comment.relativePosition.x * rect.width,
6046
- y: rect.top + comment.relativePosition.y * rect.height
7123
+ x: rect.left + relativeX * rect.width,
7124
+ y: rect.top + relativeY * rect.height
6047
7125
  });
6048
7126
  setElementRect(rect);
6049
7127
  }
@@ -10261,6 +11339,11 @@ function truncateText(value, max = 64) {
10261
11339
  if (value.length <= max) return value;
10262
11340
  return `${value.slice(0, max)}...`;
10263
11341
  }
11342
+ function summarizeMoveForPreview(intent) {
11343
+ const system = intent.layoutPrescription?.recommendedSystem;
11344
+ const systemPart = system ? `, ${system}` : "";
11345
+ return `${intent.operationId}: ${intent.classification}${systemPart}`;
11346
+ }
10264
11347
  function EditsPopover({
10265
11348
  tooltipSide,
10266
11349
  sessionEditCount,
@@ -10278,6 +11361,19 @@ function EditsPopover({
10278
11361
  const editsPopupRef = React33.useRef(null);
10279
11362
  const editsTriggerRef = React33.useRef(null);
10280
11363
  const [editsSnapshot, setEditsSnapshot] = React33.useState([]);
11364
+ const movePlanContext = React33.useMemo(() => {
11365
+ const edits = editsSnapshot.filter((item) => item.type === "edit").map((item) => item.edit);
11366
+ return buildMovePlanContext(edits);
11367
+ }, [editsSnapshot]);
11368
+ const visibleItems = React33.useMemo(() => {
11369
+ return editsSnapshot.filter((item) => {
11370
+ if (item.type === "comment") return true;
11371
+ if (!item.edit.move) return true;
11372
+ const moveIntent = getMoveIntentForEdit(item.edit, movePlanContext);
11373
+ const hasStyleOrText = Object.keys(item.edit.pendingStyles).length > 0 || item.edit.textEdit != null;
11374
+ return Boolean(moveIntent || hasStyleOrText);
11375
+ });
11376
+ }, [editsSnapshot, movePlanContext]);
10281
11377
  React33.useEffect(() => {
10282
11378
  if (!isOpen) return;
10283
11379
  function handlePointerDown(e) {
@@ -10323,16 +11419,22 @@ function EditsPopover({
10323
11419
  window.setTimeout(() => setSendStatus("idle"), 2e3);
10324
11420
  }, [onSendAllToAgents, sendStatus]);
10325
11421
  const handleCopyItem = React33.useCallback(async (item) => {
10326
- const text = item.type === "edit" ? buildSessionExport([item.edit], []) : buildSessionExport([], [item.comment]);
10327
- try {
10328
- await navigator.clipboard.writeText(`implement the visual edits
11422
+ const text = item.type === "edit" ? buildSessionExport([item.edit], [], {
11423
+ movePlanContext,
11424
+ includeMovePlanHeader: false
11425
+ }) : buildSessionExport([], [item.comment]);
11426
+ const instruction = item.type === "edit" ? buildExportInstruction(getExportContentProfile(
11427
+ [item.edit],
11428
+ [],
11429
+ item.edit.move ? buildMovePlanContext([item.edit]) : null
11430
+ )) : buildExportInstruction({ hasCssEdits: false, hasTextEdits: false, hasMoves: false, hasComments: true });
11431
+ const success = await copyText(`${instruction}
10329
11432
 
10330
11433
  ${text}`);
10331
- setCopied(true);
10332
- window.setTimeout(() => setCopied(false), 2e3);
10333
- } catch {
10334
- }
10335
- }, []);
11434
+ if (!success) return;
11435
+ setCopied(true);
11436
+ window.setTimeout(() => setCopied(false), 2e3);
11437
+ }, [movePlanContext]);
10336
11438
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_popover2.Popover.Root, { open: isOpen, onOpenChange, children: [
10337
11439
  /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Tooltip, { disabled: isOpen, children: [
10338
11440
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipTrigger, { render: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_popover2.Popover.Trigger, { render: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
@@ -10363,7 +11465,7 @@ ${text}`);
10363
11465
  children: [
10364
11466
  /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between px-3 pb-1 pt-2.5", children: [
10365
11467
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-xs font-medium text-foreground", children: "Copy to AI agents" }),
10366
- editsSnapshot.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-1", children: [
11468
+ visibleItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-1", children: [
10367
11469
  /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
10368
11470
  import_button7.Button,
10369
11471
  {
@@ -10406,9 +11508,10 @@ ${text}`);
10406
11508
  ] })
10407
11509
  ] })
10408
11510
  ] }),
10409
- editsSnapshot.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "px-3 pb-3 pt-1 text-xs text-muted-foreground", children: "No edits or comments yet." }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "max-h-[240px] overflow-y-auto px-1 py-1", children: editsSnapshot.map((item, i) => {
11511
+ visibleItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "px-3 pb-3 pt-1 text-xs text-muted-foreground", children: "No edits or comments yet." }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "max-h-[240px] overflow-y-auto px-1 py-1", children: visibleItems.map((item, i) => {
10410
11512
  const isEdit = item.type === "edit";
10411
- const isMoved = isEdit && Boolean(item.edit.move);
11513
+ const moveIntent = isEdit && item.edit.move ? getMoveIntentForEdit(item.edit, movePlanContext) : null;
11514
+ const isMoved = Boolean(moveIntent);
10412
11515
  const locator = isEdit ? item.edit.locator : item.comment.locator;
10413
11516
  const componentName = locator.reactStack[0]?.name ?? locator.tagName;
10414
11517
  let valueSummary = "";
@@ -10421,8 +11524,8 @@ ${text}`);
10421
11524
  if (item.edit.textEdit) {
10422
11525
  editValues.push(`text: "${item.edit.textEdit.newText}"`);
10423
11526
  }
10424
- if (item.edit.move) {
10425
- editValues.push(`${item.edit.move.fromParentName} -> ${item.edit.move.toParentName}`);
11527
+ if (moveIntent) {
11528
+ editValues.push(summarizeMoveForPreview(moveIntent));
10426
11529
  }
10427
11530
  valueSummary = editValues.length > 0 ? editValues.join(", ") : "(no edits)";
10428
11531
  } else {
@@ -10473,7 +11576,15 @@ ${text}`);
10473
11576
  } else {
10474
11577
  onDeleteComment?.(item.comment.id);
10475
11578
  }
10476
- setEditsSnapshot((prev) => prev.filter((_, j) => j !== i));
11579
+ setEditsSnapshot((prev) => prev.filter((candidate) => {
11580
+ if (item.type === "edit" && candidate.type === "edit") {
11581
+ return candidate.edit.element !== item.edit.element;
11582
+ }
11583
+ if (item.type === "comment" && candidate.type === "comment") {
11584
+ return candidate.comment.id !== item.comment.id;
11585
+ }
11586
+ return true;
11587
+ }));
10477
11588
  },
10478
11589
  children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react13.X, { className: "size-3" })
10479
11590
  }
@@ -11286,12 +12397,7 @@ function DirectEditDemo() {
11286
12397
  const handleExportEdits = async () => {
11287
12398
  if (Object.keys(pendingStyles).length === 0) return false;
11288
12399
  const exportMarkdown = buildEditExport(DEMO_LOCATOR, pendingStyles);
11289
- try {
11290
- await navigator.clipboard.writeText(exportMarkdown);
11291
- return true;
11292
- } catch {
11293
- return false;
11294
- }
12400
+ return copyText(buildAgentClipboardText(exportMarkdown));
11295
12401
  };
11296
12402
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "min-h-screen p-8", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "mx-auto max-w-4xl", children: [
11297
12403
  /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h1", { className: "mb-2 text-2xl font-bold", children: "Direct Edit Panel" }),
@@ -11408,6 +12514,7 @@ function DirectEditDemo() {
11408
12514
  colorToTailwind,
11409
12515
  elementFromPointWithoutOverlays,
11410
12516
  findContainerAtPoint,
12517
+ findLayoutContainerAtPoint,
11411
12518
  formatColorValue,
11412
12519
  formatPropertyValue,
11413
12520
  getComputedBorderStyles,
@@ -11420,6 +12527,7 @@ function DirectEditDemo() {
11420
12527
  getFlexDirection,
11421
12528
  getStoredGuidelines,
11422
12529
  isFlexContainer,
12530
+ isLayoutContainer,
11423
12531
  parseColorValue,
11424
12532
  parsePropertyValue,
11425
12533
  stylesToTailwind,