slidecanvas 1.1.5 → 1.1.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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","#style-inject:#style-inject","../src/tailwind.css","../src/components/PptEditor.tsx","../src/components/Toolbar.tsx","../src/lib/utils.ts","../src/components/Sidebar.tsx","../src/components/EditorCanvas.tsx","../src/lib/pptx-exporter.ts","../src/lib/pptx-parser.ts","../src/components/PresenterMode.tsx","../src/components/RefineMenu.tsx","../src/components/SlashMenu.tsx","../src/components/Snackbar.tsx","../src/lib/PptxBlobExporter.ts"],"sourcesContent":["import './tailwind.css';\nexport * from './components/PptEditor';\nexport * from './lib/pptx-parser';\nexport * from './lib/pptx-exporter';\nexport * from './lib/PptxBlobExporter';\nexport * from './lib/types';\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\"@import\\\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Lato:wght@400;700&family=Open+Sans:wght@400;600;700&family=Poppins:wght@400;500;600;700&family=Roboto:wght@400;500;700&family=Roboto+Slab:wght@400;700&family=Playfair+Display:wght@400;700&family=Merriweather:wght@400;700&family=Nunito+Sans:wght@400;600;700&family=Montserrat:wght@400;600;700&family=Oswald:wght@400;500&family=Raleway:wght@400;600;700&family=Ubuntu:wght@400;500;700&family=Lora:wght@400;700&family=PT+Sans:wght@400;700&family=PT+Serif:wght@400;700&family=Play:wght@400;700&family=Arvo:wght@400;700&family=Kanit:wght@400;500;600&display=swap\\\";/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */@layer properties;@layer theme,base,components,utilities;@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-50: oklch(97.1% .013 17.38);--color-red-100: oklch(93.6% .032 17.717);--color-red-200: oklch(88.5% .062 18.334);--color-red-400: oklch(70.4% .191 22.216);--color-red-500: oklch(63.7% .237 25.331);--color-red-600: oklch(57.7% .245 27.325);--color-orange-50: oklch(98% .016 73.684);--color-orange-500: oklch(70.5% .213 47.604);--color-amber-500: oklch(76.9% .188 70.08);--color-green-500: oklch(72.3% .219 149.579);--color-emerald-50: oklch(97.9% .021 166.113);--color-emerald-100: oklch(95% .052 163.051);--color-emerald-400: oklch(76.5% .177 163.223);--color-emerald-500: oklch(69.6% .17 162.48);--color-emerald-600: oklch(59.6% .145 163.225);--color-emerald-700: oklch(50.8% .118 165.612);--color-teal-500: oklch(70.4% .14 182.503);--color-blue-50: oklch(97% .014 254.604);--color-blue-100: oklch(93.2% .032 255.585);--color-blue-400: oklch(70.7% .165 254.624);--color-blue-500: oklch(62.3% .214 259.815);--color-blue-600: oklch(54.6% .245 262.881);--color-blue-700: oklch(48.8% .243 264.376);--color-indigo-500: oklch(58.5% .233 277.117);--color-purple-50: oklch(97.7% .014 308.299);--color-purple-100: oklch(94.6% .033 307.174);--color-purple-300: oklch(82.7% .119 306.383);--color-purple-400: oklch(71.4% .203 305.504);--color-purple-500: oklch(62.7% .265 303.9);--color-purple-600: oklch(55.8% .288 302.321);--color-purple-700: oklch(49.6% .265 301.924);--color-pink-500: oklch(65.6% .241 354.308);--color-slate-50: oklch(98.4% .003 247.858);--color-slate-100: oklch(96.8% .007 247.896);--color-slate-200: oklch(92.9% .013 255.508);--color-slate-300: oklch(86.9% .022 252.894);--color-slate-400: oklch(70.4% .04 256.788);--color-slate-500: oklch(55.4% .046 257.417);--color-slate-600: oklch(44.6% .043 257.281);--color-slate-700: oklch(37.2% .044 257.287);--color-slate-800: oklch(27.9% .041 260.031);--color-slate-900: oklch(20.8% .042 265.755);--color-black: #000;--color-white: #fff;--spacing: .25rem;--container-2xl: 42rem;--text-xs: .75rem;--text-xs--line-height: calc(1 / .75);--text-sm: .875rem;--text-sm--line-height: calc(1.25 / .875);--text-base: 1rem;--text-base--line-height: 1.5 ;--text-lg: 1.125rem;--text-lg--line-height: calc(1.75 / 1.125);--text-xl: 1.25rem;--text-xl--line-height: calc(1.75 / 1.25);--text-2xl: 1.5rem;--text-2xl--line-height: calc(2 / 1.5);--text-4xl: 2.25rem;--text-4xl--line-height: calc(2.5 / 2.25);--font-weight-normal: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--font-weight-black: 900;--tracking-tighter: -.05em;--tracking-tight: -.025em;--tracking-wide: .025em;--tracking-wider: .05em;--tracking-widest: .1em;--leading-tight: 1.25;--leading-relaxed: 1.625;--radius-sm: .25rem;--radius-md: .375rem;--radius-lg: .5rem;--radius-xl: .75rem;--radius-2xl: 1rem;--radius-3xl: 1.5rem;--ease-out: cubic-bezier(0, 0, .2, 1);--animate-spin: spin 1s linear infinite;--blur-sm: 8px;--blur-md: 12px;--aspect-video: 16 / 9;--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)}}@layer base{*,:after,:before,::backdrop,::file-selector-button{box-sizing:border-box;margin:0;padding:0;border:0 solid}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;tab-size:4;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;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{font-size:75%;line-height:0;position:relative;vertical-align:baseline}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{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea,::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;border-radius:0;background-color:transparent;opacity:1}: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)){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,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-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]),::file-selector-button{appearance:button}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing) * 0)}.inset-x-0{inset-inline:calc(var(--spacing) * 0)}.top-0{top:calc(var(--spacing) * 0)}.top-1{top:calc(var(--spacing) * 1)}.top-1\\\\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-5{top:calc(var(--spacing) * 5)}.top-10{top:calc(var(--spacing) * 10)}.top-\\\\[24px\\\\]{top:24px}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-1{right:calc(var(--spacing) * 1)}.right-1\\\\.5{right:calc(var(--spacing) * 1.5)}.right-2{right:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.right-6{right:calc(var(--spacing) * 6)}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-1{bottom:calc(var(--spacing) * 1)}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-6{bottom:calc(var(--spacing) * 6)}.bottom-8{bottom:calc(var(--spacing) * 8)}.bottom-10{bottom:calc(var(--spacing) * 10)}.bottom-full{bottom:100%}.left-0{left:calc(var(--spacing) * 0)}.left-1{left:calc(var(--spacing) * 1)}.left-1\\\\.5{left:calc(var(--spacing) * 1.5)}.left-1\\\\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.left-4{left:calc(var(--spacing) * 4)}.z-10{z-index:10}.z-50{z-index:50}.z-\\\\[100\\\\]{z-index:100}.z-\\\\[1000\\\\]{z-index:1000}.z-\\\\[2000\\\\]{z-index:2000}.z-\\\\[2001\\\\]{z-index:2001}.z-\\\\[5000\\\\]{z-index:5000}.z-\\\\[9998\\\\]{z-index:9998}.z-\\\\[9999\\\\]{z-index:9999}.z-\\\\[10000\\\\]{z-index:10000}.z-\\\\[11000\\\\]{z-index:11000}.z-\\\\[99999\\\\]{z-index:99999}.col-span-1{grid-column:span 1 / span 1}.container{width:100%;@media(width>=40rem){max-width:40rem}@media(width>=48rem){max-width:48rem}@media(width>=64rem){max-width:64rem}@media(width>=80rem){max-width:80rem}@media(width>=96rem){max-width:96rem}}.mx-1{margin-inline:calc(var(--spacing) * 1)}.mx-1\\\\.5{margin-inline:calc(var(--spacing) * 1.5)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-3{margin-inline:calc(var(--spacing) * 3)}.my-1{margin-block:calc(var(--spacing) * 1)}.my-auto{margin-block:auto}.-mt-1{margin-top:calc(var(--spacing) * -1)}.mt-0{margin-top:calc(var(--spacing) * 0)}.mt-0\\\\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-auto{margin-top:auto}.mr-0{margin-right:calc(var(--spacing) * 0)}.mr-0\\\\.5{margin-right:calc(var(--spacing) * .5)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-0{margin-bottom:calc(var(--spacing) * 0)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.-ml-0{margin-left:calc(var(--spacing) * -0)}.-ml-0\\\\.5{margin-left:calc(var(--spacing) * -.5)}.ml-0{margin-left:calc(var(--spacing) * 0)}.ml-0\\\\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.table{display:table}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:var(--aspect-video)}.h-0{height:calc(var(--spacing) * 0)}.h-1{height:calc(var(--spacing) * 1)}.h-1\\\\.5{height:calc(var(--spacing) * 1.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-7\\\\.5{height:calc(var(--spacing) * 7.5)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-32{height:calc(var(--spacing) * 32)}.h-48{height:calc(var(--spacing) * 48)}.h-\\\\[1px\\\\]{height:1px}.h-\\\\[2\\\\.5px\\\\]{height:2.5px}.h-\\\\[4px\\\\]{height:4px}.h-\\\\[22px\\\\]{height:22px}.h-\\\\[28px\\\\]{height:28px}.h-full{height:100%}.h-screen{height:100vh}.max-h-\\\\[60vh\\\\]{max-height:60vh}.max-h-\\\\[90vh\\\\]{max-height:90vh}.max-h-\\\\[200px\\\\]{max-height:200px}.max-h-\\\\[250px\\\\]{max-height:250px}.max-h-\\\\[300px\\\\]{max-height:300px}.min-h-\\\\[56px\\\\]{min-height:56px}.min-h-\\\\[300px\\\\]{min-height:300px}.min-h-screen{min-height:100vh}.w-1{width:calc(var(--spacing) * 1)}.w-1\\\\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-2\\\\.5{width:calc(var(--spacing) * 2.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-15{width:calc(var(--spacing) * 15)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-32{width:calc(var(--spacing) * 32)}.w-36{width:calc(var(--spacing) * 36)}.w-40{width:calc(var(--spacing) * 40)}.w-44{width:calc(var(--spacing) * 44)}.w-48{width:calc(var(--spacing) * 48)}.w-56{width:calc(var(--spacing) * 56)}.w-60{width:calc(var(--spacing) * 60)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-96{width:calc(var(--spacing) * 96)}.w-\\\\[1px\\\\]{width:1px}.w-\\\\[15px\\\\]{width:15px}.w-\\\\[32px\\\\]{width:32px}.w-\\\\[480px\\\\]{width:480px}.w-\\\\[500px\\\\]{width:500px}.w-\\\\[600px\\\\]{width:600px}.w-full{width:100%}.w-screen{width:100vw}.max-w-2xl{max-width:var(--container-2xl)}.max-w-\\\\[90vw\\\\]{max-width:90vw}.max-w-\\\\[300px\\\\]{max-width:300px}.max-w-\\\\[400px\\\\]{max-width:400px}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\\\\[64px\\\\]{min-width:64px}.min-w-\\\\[72px\\\\]{min-width:72px}.min-w-\\\\[80px\\\\]{min-width:80px}.min-w-\\\\[180px\\\\]{min-width:180px}.min-w-\\\\[280px\\\\]{min-width:280px}.min-w-fit{min-width:fit-content}.flex-1{flex:1}.shrink-0{flex-shrink:0}.origin-bottom-left{transform-origin:0 100%}.origin-center{transform-origin:center}.origin-top-left{transform-origin:0 0}.-translate-x-1{--tw-translate-x: calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-1\\\\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1{--tw-translate-y: calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\\\\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\\\\[1px\\\\]{--tw-translate-y: 1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-75{--tw-scale-x: 75%;--tw-scale-y: 75%;--tw-scale-z: 75%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-105{--tw-scale-x: 105%;--tw-scale-y: 105%;--tw-scale-z: 105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-110{--tw-scale-x: 110%;--tw-scale-y: 110%;--tw-scale-z: 110%;scale:var(--tw-scale-x) var(--tw-scale-y)}.rotate-45{rotate:45deg}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.appearance-none{appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.justify-stretch{justify-content:stretch}.gap-0{gap:calc(var(--spacing) * 0)}.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-2\\\\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.space-y-2{:where(&>: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)))}}.space-y-4{:where(&>: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)))}}.space-y-6{:where(&>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}}.self-start{align-self:flex-start}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-3xl{border-radius:var(--radius-3xl)}.rounded-\\\\[2\\\\.5rem\\\\]{border-radius:2.5rem}.rounded-\\\\[3px\\\\]{border-radius:3px}.rounded-full{border-radius:calc(infinity * 1px)}.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-l-\\\\[3px\\\\]{border-top-left-radius:3px;border-bottom-left-radius:3px}.rounded-l-lg{border-top-left-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.rounded-l-md{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.rounded-r-\\\\[3px\\\\]{border-top-right-radius:3px;border-bottom-right-radius:3px}.rounded-r-lg{border-top-right-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.rounded-b-xl{border-bottom-right-radius:var(--radius-xl);border-bottom-left-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\\\\[1\\\\.5px\\\\]{border-style:var(--tw-border-style);border-width:1.5px}.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-none{--tw-border-style: none;border-style:none}.border-solid{--tw-border-style: solid;border-style:solid}.border-black{border-color:var(--color-black)}.border-blue-100{border-color:var(--color-blue-100)}.border-emerald-100{border-color:var(--color-emerald-100)}.border-emerald-100\\\\/50{border-color:color-mix(in srgb,oklch(95% .052 163.051) 50%,transparent);@supports (color: color-mix(in lab,red,red)){border-color:color-mix(in oklab,var(--color-emerald-100) 50%,transparent)}}.border-purple-100{border-color:var(--color-purple-100)}.border-red-200{border-color:var(--color-red-200)}.border-slate-50{border-color:var(--color-slate-50)}.border-slate-100{border-color:var(--color-slate-100)}.border-slate-100\\\\/50{border-color:color-mix(in srgb,oklch(96.8% .007 247.896) 50%,transparent);@supports (color: color-mix(in lab,red,red)){border-color:color-mix(in oklab,var(--color-slate-100) 50%,transparent)}}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-200\\\\/60{border-color:color-mix(in srgb,oklch(92.9% .013 255.508) 60%,transparent);@supports (color: color-mix(in lab,red,red)){border-color:color-mix(in oklab,var(--color-slate-200) 60%,transparent)}}.border-slate-300{border-color:var(--color-slate-300)}.border-transparent{border-color:transparent}.border-white{border-color:var(--color-white)}.border-white\\\\/10{border-color:color-mix(in srgb,#fff 10%,transparent);@supports (color: color-mix(in lab,red,red)){border-color:color-mix(in oklab,var(--color-white) 10%,transparent)}}.bg-\\\\[\\\\#0A0A0A\\\\]{background-color:#0a0a0a}.bg-black{background-color:var(--color-black)}.bg-black\\\\/20{background-color:color-mix(in srgb,#000 20%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-black) 20%,transparent)}}.bg-black\\\\/40{background-color:color-mix(in srgb,#000 40%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-black) 40%,transparent)}}.bg-black\\\\/60{background-color:color-mix(in srgb,#000 60%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-black) 60%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-50\\\\/50{background-color:color-mix(in srgb,oklch(97% .014 254.604) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-blue-50) 50%,transparent)}}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-100\\\\/50{background-color:color-mix(in srgb,oklch(93.2% .032 255.585) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-blue-100) 50%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-50\\\\/50{background-color:color-mix(in srgb,oklch(97.9% .021 166.113) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-emerald-50) 50%,transparent)}}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-emerald-600{background-color:var(--color-emerald-600)}.bg-orange-50{background-color:var(--color-orange-50)}.bg-purple-50{background-color:var(--color-purple-50)}.bg-purple-50\\\\/50{background-color:color-mix(in srgb,oklch(97.7% .014 308.299) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-purple-50) 50%,transparent)}}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-50\\\\/50{background-color:color-mix(in srgb,oklch(98.4% .003 247.858) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-slate-50) 50%,transparent)}}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-100\\\\/50{background-color:color-mix(in srgb,oklch(96.8% .007 247.896) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-slate-100) 50%,transparent)}}.bg-slate-200{background-color:var(--color-slate-200)}.bg-slate-200\\\\/50{background-color:color-mix(in srgb,oklch(92.9% .013 255.508) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-slate-200) 50%,transparent)}}.bg-slate-300{background-color:var(--color-slate-300)}.bg-slate-800{background-color:var(--color-slate-800)}.bg-slate-900{background-color:var(--color-slate-900)}.bg-slate-900\\\\/40{background-color:color-mix(in srgb,oklch(20.8% .042 265.755) 40%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-slate-900) 40%,transparent)}}.bg-transparent{background-color:transparent}.bg-white{background-color:var(--color-white)}.bg-white\\\\/10{background-color:color-mix(in srgb,#fff 10%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-white) 10%,transparent)}}.bg-white\\\\/50{background-color:color-mix(in srgb,#fff 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-white) 50%,transparent)}}.bg-white\\\\/80{background-color:color-mix(in srgb,#fff 80%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-white) 80%,transparent)}}.bg-gradient-to-b{--tw-gradient-position: to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-black{--tw-gradient-from: var(--color-black);--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-black\\\\/60{--tw-gradient-from: color-mix(in srgb, #000 60%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-gradient-from: color-mix(in oklab, var(--color-black) 60%, transparent)}--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to: transparent;--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.fill-purple-300{fill:var(--color-purple-300)}.fill-slate-700{fill:var(--color-slate-700)}.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-2\\\\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.p-10{padding:calc(var(--spacing) * 10)}.p-12{padding:calc(var(--spacing) * 12)}.px-0{padding-inline:calc(var(--spacing) * 0)}.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-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.px-10{padding-inline:calc(var(--spacing) * 10)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\\\\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\\\\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\\\\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\\\\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-0\\\\.5{padding-top:calc(var(--spacing) * .5)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\\\\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-8{padding-top:calc(var(--spacing) * 8)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-5{padding-right:calc(var(--spacing) * 5)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pr-12{padding-right:calc(var(--spacing) * 12)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-11{padding-left:calc(var(--spacing) * 11)}.pl-12{padding-left:calc(var(--spacing) * 12)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading, var(--text-2xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading, var(--text-4xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading, var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading, var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading, var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading, var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading, var(--text-xs--line-height))}.text-\\\\[6px\\\\]{font-size:6px}.text-\\\\[7px\\\\]{font-size:7px}.text-\\\\[9px\\\\]{font-size:9px}.text-\\\\[10px\\\\]{font-size:10px}.text-\\\\[11px\\\\]{font-size:11px}.text-\\\\[12\\\\.5px\\\\]{font-size:12.5px}.text-\\\\[12px\\\\]{font-size:12px}.text-\\\\[13px\\\\]{font-size:13px}.text-\\\\[14px\\\\]{font-size:14px}.text-\\\\[16px\\\\]{font-size:16px}.text-\\\\[17px\\\\]{font-size:17px}.leading-none{--tw-leading: 1;line-height:1}.leading-relaxed{--tw-leading: var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading: var(--leading-tight);line-height:var(--leading-tight)}.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-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)}.tracking-\\\\[0\\\\.2em\\\\]{--tw-tracking: .2em;letter-spacing:.2em}.tracking-\\\\[0\\\\.15em\\\\]{--tw-tracking: .15em;letter-spacing:.15em}.tracking-tight{--tw-tracking: var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-tighter{--tw-tracking: var(--tracking-tighter);letter-spacing:var(--tracking-tighter)}.tracking-wide{--tw-tracking: var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking: var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking: var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-500{color:var(--color-amber-500)}.text-black{color:var(--color-black)}.text-blue-400{color:var(--color-blue-400)}.text-blue-500{color:var(--color-blue-500)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-emerald-400{color:var(--color-emerald-400)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-600\\\\/70{color:color-mix(in srgb,oklch(59.6% .145 163.225) 70%,transparent);@supports (color: color-mix(in lab,red,red)){color:color-mix(in oklab,var(--color-emerald-600) 70%,transparent)}}.text-emerald-700{color:var(--color-emerald-700)}.text-green-500{color:var(--color-green-500)}.text-indigo-500{color:var(--color-indigo-500)}.text-orange-500{color:var(--color-orange-500)}.text-pink-500{color:var(--color-pink-500)}.text-purple-400{color:var(--color-purple-400)}.text-purple-500{color:var(--color-purple-500)}.text-purple-600{color:var(--color-purple-600)}.text-purple-700{color:var(--color-purple-700)}.text-red-400{color:var(--color-red-400)}.text-red-400\\\\/80{color:color-mix(in srgb,oklch(70.4% .191 22.216) 80%,transparent);@supports (color: color-mix(in lab,red,red)){color:color-mix(in oklab,var(--color-red-400) 80%,transparent)}}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-slate-200{color:var(--color-slate-200)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-slate-900{color:var(--color-slate-900)}.text-teal-500{color:var(--color-teal-500)}.text-white{color:var(--color-white)}.text-white\\\\/50{color:color-mix(in srgb,#fff 50%,transparent);@supports (color: color-mix(in lab,red,red)){color:color-mix(in oklab,var(--color-white) 50%,transparent)}}.text-white\\\\/80{color:color-mix(in srgb,#fff 80%,transparent);@supports (color: color-mix(in lab,red,red)){color:color-mix(in oklab,var(--color-white) 80%,transparent)}}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0%}.opacity-25{opacity:25%}.opacity-40{opacity:40%}.opacity-50{opacity:50%}.opacity-75{opacity:75%}.opacity-100{opacity:100%}.shadow-2xl{--tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, rgb(0 0 0 / .25));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_20px_50px_rgba\\\\(0\\\\,0\\\\,0\\\\,0\\\\.15\\\\)\\\\]{--tw-shadow: 0 20px 50px var(--tw-shadow-color, rgba(0,0,0,.15));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, rgb(0 0 0 / .05));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, rgb(0 0 0 / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / .1));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, rgb(0 0 0 / .1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / .1));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, rgb(0 0 0 / .1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--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)}.ring-4{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(4px + 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)}.shadow-black{--tw-shadow-color: #000;@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, var(--color-black) var(--tw-shadow-alpha), transparent)}}.shadow-black\\\\/80{--tw-shadow-color: color-mix(in srgb, #000 80%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-black) 80%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-blue-500{--tw-shadow-color: oklch(62.3% .214 259.815);@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, var(--color-blue-500) var(--tw-shadow-alpha), transparent)}}.shadow-blue-500\\\\/20{--tw-shadow-color: color-mix(in srgb, oklch(62.3% .214 259.815) 20%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-blue-500) 20%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-emerald-500{--tw-shadow-color: oklch(69.6% .17 162.48);@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, var(--color-emerald-500) var(--tw-shadow-alpha), transparent)}}.shadow-emerald-500\\\\/20{--tw-shadow-color: color-mix(in srgb, oklch(69.6% .17 162.48) 20%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-emerald-500) 20%, transparent) var(--tw-shadow-alpha), transparent)}}.ring-black{--tw-ring-color: var(--color-black)}.ring-black\\\\/5{--tw-ring-color: color-mix(in srgb, #000 5%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-ring-color: color-mix(in oklab, var(--color-black) 5%, transparent)}}.ring-purple-100{--tw-ring-color: var(--color-purple-100)}.ring-white{--tw-ring-color: var(--color-white)}.backdrop-blur-\\\\[1px\\\\]{--tw-backdrop-blur: blur(1px);-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,)}.backdrop-blur-\\\\[2px\\\\]{--tw-backdrop-blur: blur(2px);-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,)}.backdrop-blur-md{--tw-backdrop-blur: blur(var(--blur-md));-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,)}.backdrop-blur-sm{--tw-backdrop-blur: blur(var(--blur-sm));-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-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-opacity{transition-property:opacity;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}.duration-300{--tw-duration: .3s;transition-duration:.3s}.duration-500{--tw-duration: .5s;transition-duration:.5s}.duration-700{--tw-duration: .7s;transition-duration:.7s}.ease-out{--tw-ease: var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style: none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.group-focus-within\\\\:text-slate-600{&:is(:where(.group):focus-within *){color:var(--color-slate-600)}}.group-hover\\\\:scale-105{&:is(:where(.group):hover *){@media(hover:hover){--tw-scale-x: 105%;--tw-scale-y: 105%;--tw-scale-z: 105%;scale:var(--tw-scale-x) var(--tw-scale-y)}}}.group-hover\\\\:scale-110{&:is(:where(.group):hover *){@media(hover:hover){--tw-scale-x: 110%;--tw-scale-y: 110%;--tw-scale-z: 110%;scale:var(--tw-scale-x) var(--tw-scale-y)}}}.group-hover\\\\:bg-blue-50{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-blue-50)}}}.group-hover\\\\:bg-blue-100{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-blue-100)}}}.group-hover\\\\:bg-blue-600{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-blue-600)}}}.group-hover\\\\:bg-emerald-50{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-emerald-50)}}}.group-hover\\\\:bg-emerald-600{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-emerald-600)}}}.group-hover\\\\:bg-purple-600{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-purple-600)}}}.group-hover\\\\:bg-red-500{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-red-500)}}}.group-hover\\\\:bg-slate-200{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-slate-200)}}}.group-hover\\\\:fill-slate-900{&:is(:where(.group):hover *){@media(hover:hover){fill:var(--color-slate-900)}}}.group-hover\\\\:text-blue-600{&:is(:where(.group):hover *){@media(hover:hover){color:var(--color-blue-600)}}}.group-hover\\\\:text-slate-700{&:is(:where(.group):hover *){@media(hover:hover){color:var(--color-slate-700)}}}.group-hover\\\\:text-slate-900{&:is(:where(.group):hover *){@media(hover:hover){color:var(--color-slate-900)}}}.group-hover\\\\:text-white{&:is(:where(.group):hover *){@media(hover:hover){color:var(--color-white)}}}.group-hover\\\\:opacity-100{&:is(:where(.group):hover *){@media(hover:hover){opacity:100%}}}.group-hover\\\\:shadow-sm{&:is(:where(.group):hover *){@media(hover:hover){--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}}.placeholder\\\\:text-slate-400{&::placeholder{color:var(--color-slate-400)}}.hover\\\\:border-blue-400{&:hover{@media(hover:hover){border-color:var(--color-blue-400)}}}.hover\\\\:border-slate-100{&:hover{@media(hover:hover){border-color:var(--color-slate-100)}}}.hover\\\\:border-slate-200{&:hover{@media(hover:hover){border-color:var(--color-slate-200)}}}.hover\\\\:border-slate-300{&:hover{@media(hover:hover){border-color:var(--color-slate-300)}}}.hover\\\\:bg-black{&:hover{@media(hover:hover){background-color:var(--color-black)}}}.hover\\\\:bg-blue-50{&:hover{@media(hover:hover){background-color:var(--color-blue-50)}}}.hover\\\\:bg-blue-50\\\\/50{&:hover{@media(hover:hover){background-color:color-mix(in srgb,oklch(97% .014 254.604) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-blue-50) 50%,transparent)}}}}.hover\\\\:bg-blue-700{&:hover{@media(hover:hover){background-color:var(--color-blue-700)}}}.hover\\\\:bg-emerald-50{&:hover{@media(hover:hover){background-color:var(--color-emerald-50)}}}.hover\\\\:bg-emerald-700{&:hover{@media(hover:hover){background-color:var(--color-emerald-700)}}}.hover\\\\:bg-purple-50{&:hover{@media(hover:hover){background-color:var(--color-purple-50)}}}.hover\\\\:bg-red-50{&:hover{@media(hover:hover){background-color:var(--color-red-50)}}}.hover\\\\:bg-red-100{&:hover{@media(hover:hover){background-color:var(--color-red-100)}}}.hover\\\\:bg-slate-50{&:hover{@media(hover:hover){background-color:var(--color-slate-50)}}}.hover\\\\:bg-slate-100{&:hover{@media(hover:hover){background-color:var(--color-slate-100)}}}.hover\\\\:bg-slate-200{&:hover{@media(hover:hover){background-color:var(--color-slate-200)}}}.hover\\\\:bg-white{&:hover{@media(hover:hover){background-color:var(--color-white)}}}.hover\\\\:bg-white\\\\/20{&:hover{@media(hover:hover){background-color:color-mix(in srgb,#fff 20%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-white) 20%,transparent)}}}}.hover\\\\:text-blue-500{&:hover{@media(hover:hover){color:var(--color-blue-500)}}}.hover\\\\:text-blue-600{&:hover{@media(hover:hover){color:var(--color-blue-600)}}}.hover\\\\:text-blue-700{&:hover{@media(hover:hover){color:var(--color-blue-700)}}}.hover\\\\:text-emerald-700{&:hover{@media(hover:hover){color:var(--color-emerald-700)}}}.hover\\\\:text-purple-600{&:hover{@media(hover:hover){color:var(--color-purple-600)}}}.hover\\\\:text-purple-700{&:hover{@media(hover:hover){color:var(--color-purple-700)}}}.hover\\\\:text-red-500{&:hover{@media(hover:hover){color:var(--color-red-500)}}}.hover\\\\:text-slate-500{&:hover{@media(hover:hover){color:var(--color-slate-500)}}}.hover\\\\:text-slate-600{&:hover{@media(hover:hover){color:var(--color-slate-600)}}}.hover\\\\:text-slate-700{&:hover{@media(hover:hover){color:var(--color-slate-700)}}}.hover\\\\:text-white{&:hover{@media(hover:hover){color:var(--color-white)}}}.hover\\\\:opacity-100{&:hover{@media(hover:hover){opacity:100%}}}.hover\\\\:shadow-md{&:hover{@media(hover:hover){--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}}.focus\\\\:border-blue-500{&:focus{border-color:var(--color-blue-500)}}.focus\\\\:border-slate-400{&:focus{border-color:var(--color-slate-400)}}.focus\\\\:ring-2{&:focus{--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)}}.focus\\\\:ring-4{&:focus{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(4px + 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\\\\:ring-blue-500\\\\/10{&:focus{--tw-ring-color: color-mix(in srgb, oklch(62.3% .214 259.815) 10%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-ring-color: color-mix(in oklab, var(--color-blue-500) 10%, transparent)}}}.focus\\\\:ring-blue-500\\\\/20{&:focus{--tw-ring-color: color-mix(in srgb, oklch(62.3% .214 259.815) 20%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-ring-color: color-mix(in oklab, var(--color-blue-500) 20%, transparent)}}}.focus\\\\:ring-slate-400\\\\/5{&:focus{--tw-ring-color: color-mix(in srgb, oklch(70.4% .04 256.788) 5%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-ring-color: color-mix(in oklab, var(--color-slate-400) 5%, transparent)}}}.focus\\\\:outline-none{&:focus{--tw-outline-style: none;outline-style:none}}.active\\\\:scale-95{&:active{--tw-scale-x: 95%;--tw-scale-y: 95%;--tw-scale-z: 95%;scale:var(--tw-scale-x) var(--tw-scale-y)}}.active\\\\:scale-\\\\[0\\\\.98\\\\]{&:active{scale:.98}}.active\\\\:cursor-grabbing{&:active{cursor:grabbing}}.disabled\\\\:cursor-not-allowed{&:disabled{cursor:not-allowed}}.disabled\\\\:bg-slate-100{&:disabled{background-color:var(--color-slate-100)}}.disabled\\\\:bg-slate-300{&:disabled{background-color:var(--color-slate-300)}}.disabled\\\\:text-slate-400{&:disabled{color:var(--color-slate-400)}}.disabled\\\\:opacity-20{&:disabled{opacity:20%}}.disabled\\\\:opacity-40{&:disabled{opacity:40%}}.disabled\\\\:opacity-50{&:disabled{opacity:50%}}.disabled\\\\:active\\\\:scale-100{&:disabled{&:active{--tw-scale-x: 100%;--tw-scale-y: 100%;--tw-scale-z: 100%;scale:var(--tw-scale-x) var(--tw-scale-y)}}}.md\\\\:space-y-8{@media(width>=48rem){:where(&>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}}}.md\\\\:p-12{@media(width>=48rem){padding:calc(var(--spacing) * 12)}}}@keyframes blob{0%{transform:translate(0) scale(1)}33%{transform:translate(30px,-50px) scale(1.1)}66%{transform:translate(-20px,20px) scale(.9)}to{transform:translate(0) scale(1)}}.animate-blob{animation:blob 7s infinite}.animation-delay-2000{animation-delay:2s}.animation-delay-4000{animation-delay:4s}@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-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;}@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-gradient-position{syntax: \\\"*\\\"; inherits: false;}@property --tw-gradient-from{syntax: \\\"<color>\\\"; inherits: false; initial-value: #0000;}@property --tw-gradient-via{syntax: \\\"<color>\\\"; inherits: false; initial-value: #0000;}@property --tw-gradient-to{syntax: \\\"<color>\\\"; inherits: false; initial-value: #0000;}@property --tw-gradient-stops{syntax: \\\"*\\\"; inherits: false;}@property --tw-gradient-via-stops{syntax: \\\"*\\\"; inherits: false;}@property --tw-gradient-from-position{syntax: \\\"<length-percentage>\\\"; inherits: false; initial-value: 0%;}@property --tw-gradient-via-position{syntax: \\\"<length-percentage>\\\"; inherits: false; initial-value: 50%;}@property --tw-gradient-to-position{syntax: \\\"<length-percentage>\\\"; inherits: false; initial-value: 100%;}@property --tw-leading{syntax: \\\"*\\\"; inherits: false;}@property --tw-font-weight{syntax: \\\"*\\\"; inherits: false;}@property --tw-tracking{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: 0px;}@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-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;}@keyframes spin{to{transform:rotate(360deg)}}@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-scale-x: 1;--tw-scale-y: 1;--tw-scale-z: 1;--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-gradient-position: initial;--tw-gradient-from: #0000;--tw-gradient-via: #0000;--tw-gradient-to: #0000;--tw-gradient-stops: initial;--tw-gradient-via-stops: initial;--tw-gradient-from-position: 0%;--tw-gradient-via-position: 50%;--tw-gradient-to-position: 100%;--tw-leading: initial;--tw-font-weight: initial;--tw-tracking: 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-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}}}\\n\")","'use client';\n\nimport React, { useState, useCallback, useMemo, useEffect } from 'react';\nimport type { Presentation, Slide, SlideElement, PresentationSource, ShapeType } from '../lib/types';\nimport { Toolbar } from './Toolbar';\nimport { Sidebar } from './Sidebar';\nimport { EditorCanvas } from './EditorCanvas';\nimport { PptxExporter } from '../lib/pptx-exporter';\nimport { PptxParser } from '../lib/pptx-parser';\nimport { PresenterMode } from './PresenterMode';\nimport { GoogleGenerativeAI } from '@google/generative-ai';\nimport { RefineMenu } from './RefineMenu';\nimport { SlashMenu } from './SlashMenu';\nimport { Sparkles, Plus, RefreshCw, Check, Trash2, Image as ImageIcon, PieChart } from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport { Snackbar, SnackbarType } from './Snackbar';\n\ninterface PptEditorProps {\n initialPresentation?: Presentation;\n url?: string;\n appName?: string;\n onChange?: (presentation: Presentation) => void;\n geminiApiKey?: string;\n width: number | string;\n height: number | string;\n appBgColor?: string;\n showHomeOnEmpty?: boolean;\n initialSource?: PresentationSource;\n onSourceChange?: (source: PresentationSource, url?: string) => void;\n proxyUrl?: string;\n onGenerateImage?: (prompt: string) => Promise<string>;\n onGenerateInfographic?: (prompt: string) => Promise<string>;\n onAiRewrite?: (text: string) => Promise<string>;\n onAiGrammar?: (text: string) => Promise<string>;\n onAiShorten?: (text: string) => Promise<string>;\n onAiLengthen?: (text: string) => Promise<string>;\n onAiContinue?: (text: string) => Promise<string>;\n isTwoStepInfographicGeneration?: boolean;\n onRefineInfographicPrompt?: (text: string) => Promise<string>;\n}\n\nexport const PptEditor: React.FC<PptEditorProps> = ({\n initialPresentation, url, appName = 'My Studio', onChange, geminiApiKey = \"AIzaSyAcBfseKzoFZJMfuRzhRJjygQ-u2UKFxOw\",\n width, height, appBgColor = '#B7472A', showHomeOnEmpty = false,\n initialSource, onSourceChange, proxyUrl, onGenerateImage, onGenerateInfographic,\n onAiRewrite, onAiGrammar, onAiShorten, onAiLengthen, onAiContinue,\n isTwoStepInfographicGeneration, onRefineInfographicPrompt\n}) => {\n const [presentation, setPresentation] = useState<Presentation>(\n initialPresentation || { slides: [{ id: 'slide-1', elements: [] }], layout: { width: 12192000, height: 6858000 } }\n );\n\n const [history, setHistory] = useState<Presentation[]>([]);\n const [redoStack, setRedoStack] = useState<Presentation[]>([]);\n\n const [currentSlideIndex, setCurrentSlideIndex] = useState(0);\n const [selectedElementId, setSelectedElementId] = useState<string | null>(null);\n const [isPreviewMode, setIsPreviewMode] = useState(false);\n const [askAiResponse, setAskAiResponse] = useState<string | null>(null);\n const [refineResponse, setRefineResponse] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [source, setSource] = useState<PresentationSource | null>(initialSource || (url ? 'url' : null));\n const [showInitialLayout, setShowInitialLayout] = useState(showHomeOnEmpty && !initialPresentation && !url && !initialSource);\n const [urlInput, setUrlInput] = useState('');\n const [slashMenu, setSlashMenu] = useState<{\n visible: boolean,\n position: { x: number, y: number },\n mode: 'default' | 'textbox' | 'text-selection',\n context?: any\n }>({\n visible: false,\n position: { x: 0, y: 0 },\n mode: 'default'\n });\n const [isImageGenOpen, setIsImageGenOpen] = useState(false);\n const [imageGenPrompt, setImageGenPrompt] = useState('');\n const [isGeneratingImage, setIsGeneratingImage] = useState(false);\n const [pendingImage, setPendingImage] = useState<string | null>(null);\n const [imageError, setImageError] = useState(false);\n const [previewLoading, setPreviewLoading] = useState(false);\n const [isInfographicGenOpen, setIsInfographicGenOpen] = useState(false);\n const [infographicGenPrompt, setInfographicGenPrompt] = useState('');\n const [isGeneratingInfographic, setIsGeneratingInfographic] = useState(false);\n const [pendingInfographic, setPendingInfographic] = useState<string | null>(null);\n const [infographicError, setInfographicError] = useState(false);\n const [isRefiningInfographic, setIsRefiningInfographic] = useState(false);\n const [refinedInfographicPrompt, setRefinedInfographicPrompt] = useState<string | null>(null);\n\n // Snackbar State\n const [snackbar, setSnackbar] = useState<{ open: boolean; message: string; type: SnackbarType }>({\n open: false,\n message: '',\n type: 'info'\n });\n\n const showSnackbar = (message: string, type: SnackbarType = 'info') => {\n setSnackbar({ open: true, message, type });\n };\n\n useEffect(() => {\n if (pendingImage) {\n setImageError(false);\n setPreviewLoading(true);\n }\n }, [pendingImage]);\n\n useEffect(() => {\n if (pendingInfographic) {\n setInfographicError(false);\n setPreviewLoading(true);\n }\n }, [pendingInfographic]);\n\n useEffect(() => {\n if (url) {\n handleLoadPresentation(url);\n }\n }, [url]);\n const [isAiLoading, setIsAiLoading] = useState(false);\n const [lastAiPrompt, setLastAiPrompt] = useState<{ id: string, action: 'shorten' | 'reframe' | 'lengthen' } | null>(null);\n\n // Clear AI states when selection changes\n useEffect(() => {\n setAskAiResponse(null);\n setRefineResponse(null);\n setLastAiPrompt(null);\n setIsAiLoading(false);\n }, [selectedElementId]);\n\n // Calculate UI scale based on width/height\n const uiScale = useMemo(() => {\n const w = typeof width === 'number' ? width : parseInt(String(width));\n if (isNaN(w)) return 1;\n // Base width for 1x scale is 1600px\n // Range: 0.7 to 1.0 (never scale up beyond 1x)\n return Math.min(Math.max(w / 1600, 0.7), 1);\n }, [width]);\n\n const currentSlide = presentation.slides[currentSlideIndex];\n\n const selectedElement = useMemo(() => {\n return currentSlide.elements.find(el => el.id === selectedElementId) || null;\n }, [currentSlide, selectedElementId]);\n\n const saveToHistory = useCallback((state: Presentation) => {\n setHistory(prevHistory => [...prevHistory.slice(-19), presentation]);\n setRedoStack([]);\n setPresentation(state);\n onChange?.(state);\n }, [onChange, presentation]);\n\n const undo = () => {\n if (history.length === 0) return;\n const last = history[history.length - 1];\n setRedoStack(prev => [...prev, presentation]);\n setHistory(prev => prev.slice(0, -1));\n setPresentation(last);\n };\n\n const redo = () => {\n if (redoStack.length === 0) return;\n const next = redoStack[redoStack.length - 1];\n setHistory(prev => [...prev, presentation]);\n setRedoStack(prev => prev.slice(0, -1));\n setPresentation(next);\n };\n\n const handleUpdateSlide = useCallback((updates: Partial<Slide>) => {\n setPresentation(prev => {\n const newSlides = [...prev.slides];\n newSlides[currentSlideIndex] = { ...newSlides[currentSlideIndex], ...updates };\n const updated = { ...prev, slides: newSlides };\n\n // Note: We can't call saveToHistory inside here easily without dependency issues, \n // but we can move history logic here if needed or keep it simple for now.\n // For now, let's just make it stable.\n setHistory(h => [...h.slice(-19), prev]);\n setRedoStack([]);\n onChange?.(updated);\n return updated;\n });\n }, [currentSlideIndex, onChange]);\n\n const handleElementUpdate = useCallback((elementId: string, updates: Partial<SlideElement>) => {\n setPresentation(prev => {\n const slide = prev.slides[currentSlideIndex];\n const newElements = slide.elements.map(el =>\n el.id === elementId ? { ...el, ...updates } as SlideElement : el\n );\n const newSlides = [...prev.slides];\n newSlides[currentSlideIndex] = { ...slide, elements: newElements };\n const updated = { ...prev, slides: newSlides };\n onChange?.(updated);\n return updated;\n });\n }, [currentSlideIndex, onChange]);\n\n const handleFormatText = (updates: any) => {\n if (!selectedElementId) return;\n const el = currentSlide.elements.find(e => e.id === selectedElementId);\n if (el) {\n handleElementUpdate(selectedElementId, updates);\n // Explicitly save to history for discrete formatting actions\n const slide = presentation.slides[currentSlideIndex];\n const newElements = slide.elements.map(e => e.id === selectedElementId ? { ...e, ...updates } : e);\n const newSlides = [...presentation.slides];\n newSlides[currentSlideIndex] = { ...slide, elements: newElements };\n saveToHistory({ ...presentation, slides: newSlides });\n }\n };\n\n const handleDeleteElement = useCallback(() => {\n if (!selectedElementId) return;\n const slide = presentation.slides[currentSlideIndex];\n const newElements = slide.elements.filter(el => el.id !== selectedElementId);\n handleUpdateSlide({ elements: newElements });\n setSelectedElementId(null);\n }, [selectedElementId, currentSlideIndex, presentation, handleUpdateSlide]);\n\n const handleAddText = () => {\n const newElement: SlideElement = {\n id: `text-${Date.now()}`,\n type: 'text',\n content: 'New Text',\n x: 100,\n y: 100,\n width: 400,\n height: 100,\n fontSize: 48,\n fontFamily: 'Arial',\n color: '#000000',\n zIndex: currentSlide.elements.length\n };\n handleUpdateSlide({ elements: [...currentSlide.elements, newElement] });\n };\n\n const handleAddImage = useCallback(async (input: File | string) => {\n let src = '';\n if (typeof input === 'string') {\n src = input;\n } else {\n src = await new Promise((resolve) => {\n const reader = new FileReader();\n reader.onload = (e) => resolve(e.target?.result as string);\n reader.readAsDataURL(input);\n });\n }\n const id = `img-${Date.now()}`;\n const newElement: SlideElement = {\n id,\n type: 'image',\n src: src,\n x: 100,\n y: 100,\n width: 400,\n height: 250,\n zIndex: currentSlide.elements.length\n };\n handleUpdateSlide({ elements: [...currentSlide.elements, newElement] });\n setSelectedElementId(id);\n }, [currentSlide.elements, handleUpdateSlide, setSelectedElementId]);\n\n const handleAddShape = (shapeType: ShapeType) => {\n const newElement: SlideElement = {\n id: `shape-${Date.now()}`,\n type: 'shape',\n shapeType,\n fill: '#3b82f6',\n x: 200,\n y: 200,\n width: 200,\n height: 200,\n zIndex: currentSlide.elements.length\n };\n handleUpdateSlide({ elements: [...currentSlide.elements, newElement] });\n }\n\n const handleAddSlide = () => {\n const newSlide: Slide = { id: `slide-${Date.now()}`, elements: [] };\n saveToHistory({ ...presentation, slides: [...presentation.slides, newSlide] });\n setCurrentSlideIndex(presentation.slides.length);\n };\n\n const handleDeleteSlide = (index: number) => {\n if (presentation.slides.length <= 1) return;\n\n const newSlides = presentation.slides.filter((_, i) => i !== index);\n saveToHistory({ ...presentation, slides: newSlides });\n\n // Adjust current slide index if needed\n if (index <= currentSlideIndex) {\n setCurrentSlideIndex(Math.max(0, currentSlideIndex - 1));\n }\n };\n\n const handleDuplicateSlide = (index: number) => {\n const slideToClone = presentation.slides[index];\n const newSlide: Slide = {\n ...slideToClone,\n id: `slide-${Date.now()}`,\n elements: slideToClone.elements.map(el => ({\n ...el,\n id: `${el.type}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n }))\n };\n const newSlides = [...presentation.slides];\n newSlides.splice(index + 1, 0, newSlide);\n saveToHistory({ ...presentation, slides: newSlides });\n setCurrentSlideIndex(index + 1);\n };\n\n const handleReorderSlides = (oldIndex: number, newIndex: number) => {\n if (oldIndex === newIndex) return;\n const newSlides = [...presentation.slides];\n const [removed] = newSlides.splice(oldIndex, 1);\n newSlides.splice(newIndex, 0, removed);\n\n saveToHistory({ ...presentation, slides: newSlides });\n\n if (currentSlideIndex === oldIndex) {\n setCurrentSlideIndex(newIndex);\n } else if (currentSlideIndex > oldIndex && currentSlideIndex <= newIndex) {\n setCurrentSlideIndex(currentSlideIndex - 1);\n } else if (currentSlideIndex < oldIndex && currentSlideIndex >= newIndex) {\n setCurrentSlideIndex(currentSlideIndex + 1);\n }\n };\n\n const handleApplyLayout = (layoutType: 'title' | 'content' | 'split') => {\n let elements: SlideElement[] = [];\n const timestamp = Date.now();\n\n if (layoutType === 'title') {\n elements = [\n {\n id: `text-title-${timestamp}`,\n type: 'text',\n content: 'Presentation Title',\n x: 100,\n y: 200,\n width: 1000,\n height: 150,\n fontSize: 80,\n fontFamily: 'Inter',\n color: '#000000',\n textAlign: 'center',\n isBold: true,\n zIndex: 0\n },\n {\n id: `text-sub-${timestamp}`,\n type: 'text',\n content: 'Subtitle goes here',\n x: 200,\n y: 380,\n width: 800,\n height: 80,\n fontSize: 36,\n fontFamily: 'Inter',\n color: '#64748b',\n textAlign: 'center',\n zIndex: 1\n }\n ];\n } else if (layoutType === 'content') {\n elements = [\n {\n id: `text-title-${timestamp}`,\n type: 'text',\n content: 'Slide Title',\n x: 60,\n y: 40,\n width: 800,\n height: 80,\n fontSize: 48,\n fontFamily: 'Inter',\n color: '#000000',\n isBold: true,\n zIndex: 0\n },\n {\n id: `text-body-${timestamp}`,\n type: 'text',\n content: '• Add your points here\\n• Press Enter for new line\\n• Use the toolbar to format',\n x: 60,\n y: 150,\n width: 1080,\n height: 480,\n fontSize: 28,\n fontFamily: 'Inter',\n color: '#334155',\n zIndex: 1,\n isBulleted: true\n }\n ];\n } else if (layoutType === 'split') {\n elements = [\n {\n id: `text-title-${timestamp}`,\n type: 'text',\n content: 'Comparison Layout',\n x: 60,\n y: 40,\n width: 1080,\n height: 80,\n fontSize: 48,\n fontFamily: 'Inter',\n color: '#000000',\n isBold: true,\n textAlign: 'center',\n zIndex: 0\n },\n {\n id: `text-left-${timestamp}`,\n type: 'text',\n content: 'Left column content goes here.',\n x: 60,\n y: 180,\n width: 520,\n height: 400,\n fontSize: 24,\n fontFamily: 'Inter',\n color: '#334155',\n zIndex: 1\n },\n {\n id: `text-right-${timestamp}`,\n type: 'text',\n content: 'Right column content goes here.',\n x: 620,\n y: 180,\n width: 520,\n height: 400,\n fontSize: 24,\n fontFamily: 'Inter',\n color: '#334155',\n zIndex: 2\n }\n ];\n }\n\n handleUpdateSlide({ elements });\n };\n\n const handleAiAction = async (id: string, action: 'shorten' | 'reframe' | 'lengthen') => {\n const slide = presentation.slides[currentSlideIndex];\n const element = slide.elements.find(el => el.id === id);\n if (!element || element.type !== 'text') return;\n\n setIsAiLoading(true);\n setRefineResponse(null);\n setLastAiPrompt({ id, action });\n\n try {\n if (!geminiApiKey) {\n showSnackbar(\"Gemini API key is missing. Please provide it via the 'geminiApiKey' prop.\", 'error');\n setIsAiLoading(false);\n return;\n }\n const genAI = new GoogleGenerativeAI(geminiApiKey);\n const model = genAI.getGenerativeModel({\n model: \"gemini-flash-latest\",\n systemInstruction: \"You are a professional presentation assistant. Your task is to transform slide text according to specific user requests (shorten, reframe, or lengthen). \\n\\nCRITICAL RULES:\\n1. Return ONLY the transformed text. \\n2. Do NOT include any explanations, choices, or conversational fillers.\\n3. Do NOT use markdown formatting (like bolding or headers) unless specifically needed for bullet points.\\n4. If the input text is a title/headline, the output should be a professional title/headline.\\n5. If the input text is a bulleted list, the output MUST be a bulleted list using the same bullet style (e.g., '•').\\n6. Maintain the professional tone of the original presentation.\"\n });\n\n const elementContext = element.fontSize > 32 ? \"Title/Headline\" : \"Body Text/List\";\n const prompt = `Action: ${action.toUpperCase()}\\nText Role: ${elementContext}\\nOriginal Text: \"${element.content}\"\\n\\nTransformed Text:`;\n\n const result = await model.generateContent(prompt);\n const response = await result.response;\n setRefineResponse(response.text().trim());\n } catch (error) {\n console.error(\"Gemini AI Error:\", error);\n showSnackbar(\"Error generating response. Please check your API key or connection.\", 'error');\n } finally {\n setIsAiLoading(false);\n }\n };\n\n const handleAiTextEdit = async (action: 'rewrite' | 'grammar' | 'shorten' | 'lengthen' | 'continue') => {\n const slide = presentation.slides[currentSlideIndex];\n const element = slide.elements.find(el => el.id === selectedElementId);\n if (!element || element.type !== 'text') return;\n\n setIsAiLoading(true);\n setAskAiResponse(null);\n setLastAiPrompt({ id: selectedElementId!, action: action as any }); // Cast for now, might need to update type\n\n try {\n let resultText = '';\n\n // 1. Try Custom Props\n if (action === 'rewrite' && onAiRewrite) resultText = await onAiRewrite(element.content);\n else if (action === 'grammar' && onAiGrammar) resultText = await onAiGrammar(element.content);\n else if (action === 'shorten' && onAiShorten) resultText = await onAiShorten(element.content);\n else if (action === 'lengthen' && onAiLengthen) resultText = await onAiLengthen(element.content);\n else if (action === 'continue' && onAiContinue) resultText = await onAiContinue(element.content);\n\n // 2. Fallback to Gemini if no custom prop or if custom prop returned empty (optional behavior, assumed strictly prop OR gemini)\n if (!resultText) {\n if (!geminiApiKey) {\n showSnackbar(\"Gemini API key is missing and no custom AI route provided.\", 'error');\n setIsAiLoading(false);\n return;\n }\n\n const genAI = new GoogleGenerativeAI(geminiApiKey);\n const model = genAI.getGenerativeModel({ model: \"gemini-flash-latest\" });\n\n let systemPrompt = \"You are a professional editor. Return ONLY the edited text. No explanations.\";\n let userPrompt = `original text: \"${element.content}\"`;\n\n switch (action) {\n case 'rewrite': userPrompt = `Improve the writing of: \"${element.content}\"`; break;\n case 'grammar': userPrompt = `Fix grammar in: \"${element.content}\"`; break;\n case 'shorten': userPrompt = `Make this shorter: \"${element.content}\"`; break;\n case 'lengthen': userPrompt = `Make this longer: \"${element.content}\"`; break;\n case 'continue': userPrompt = `Continue writing from: \"${element.content}\"`; break;\n }\n\n const result = await model.generateContent(`${systemPrompt}\\n\\n${userPrompt}`);\n resultText = result.response.text().trim();\n }\n\n setAskAiResponse(resultText);\n } catch (error) {\n console.error(\"AI Text Edit Error:\", error);\n showSnackbar(\"AI editing failed. Please check configuration.\", 'error');\n } finally {\n setIsAiLoading(false);\n }\n };\n\n const handleAiResponseAction = (action: 'replace' | 'addBelow' | 'discard' | 'regenerate') => {\n if (!askAiResponse || !lastAiPrompt) return;\n\n if (action === 'regenerate') {\n handleAiTextEdit(lastAiPrompt.action as any);\n return;\n }\n\n const slide = presentation.slides[currentSlideIndex];\n const originalElement = slide.elements.find(el => el.id === lastAiPrompt.id);\n if (!originalElement || originalElement.type !== 'text') return;\n\n if (action === 'replace') {\n handleElementUpdate(lastAiPrompt.id, { content: askAiResponse });\n } else if (action === 'addBelow') {\n const newElement: SlideElement = {\n ...originalElement,\n id: `text-ai-${Date.now()}`,\n content: askAiResponse,\n y: originalElement.y + originalElement.height + 20,\n zIndex: slide.elements.length\n };\n handleUpdateSlide({ elements: [...slide.elements, newElement] });\n }\n\n setAskAiResponse(null);\n setLastAiPrompt(null);\n setSlashMenu(prev => ({ ...prev, visible: false }));\n };\n\n const handleRefineResponseAction = (action: 'replace' | 'addBelow' | 'discard' | 'regenerate') => {\n if (!refineResponse || !lastAiPrompt) return;\n\n if (action === 'discard') {\n setRefineResponse(null);\n return;\n }\n\n if (action === 'regenerate') {\n handleAiAction(lastAiPrompt.id, lastAiPrompt.action);\n return;\n }\n\n const slide = presentation.slides[currentSlideIndex];\n const originalElement = slide.elements.find(el => el.id === lastAiPrompt.id);\n if (!originalElement || originalElement.type !== 'text') return;\n\n if (action === 'replace') {\n handleElementUpdate(lastAiPrompt.id, { content: refineResponse });\n } else if (action === 'addBelow') {\n const newElement: SlideElement = {\n ...originalElement,\n id: `text-refine-${Date.now()}`,\n content: refineResponse,\n y: originalElement.y + originalElement.height + 20,\n zIndex: slide.elements.length\n };\n handleUpdateSlide({ elements: [...slide.elements, newElement] });\n }\n\n setRefineResponse(null);\n setLastAiPrompt(null);\n };\n\n const handleExport = async () => {\n const exporter = new PptxExporter();\n await exporter.export(presentation);\n };\n\n const handlePlay = () => {\n setIsPreviewMode(true);\n const elem = document.documentElement;\n if (elem.requestFullscreen) {\n elem.requestFullscreen();\n }\n };\n\n const handleClosePresenter = () => {\n setIsPreviewMode(false);\n if (document.fullscreenElement) {\n document.exitFullscreen();\n }\n };\n\n useEffect(() => {\n const handleFullscreenChange = () => {\n if (!document.fullscreenElement) {\n setIsPreviewMode(false);\n }\n };\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => document.removeEventListener('fullscreenchange', handleFullscreenChange);\n }, []);\n\n // Keyboard navigation\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Delete' || e.key === 'Backspace') {\n const activeElement = document.activeElement;\n if (activeElement?.tagName === 'INPUT' || activeElement?.tagName === 'TEXTAREA' || (activeElement as any)?.isContentEditable) return;\n handleDeleteElement();\n }\n if (e.key === 'Escape') {\n setSelectedElementId(null);\n setSlashMenu(prev => ({ ...prev, visible: false }));\n }\n if (e.ctrlKey || e.metaKey) {\n if (e.key === 'z') {\n e.preventDefault();\n if (e.shiftKey) redo(); else undo();\n }\n if (e.key === 'y') {\n e.preventDefault();\n redo();\n }\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [handleDeleteElement, undo, redo]);\n\n const updateSource = (newSource: PresentationSource, url?: string) => {\n setSource(newSource);\n onSourceChange?.(newSource, url);\n };\n\n const handleNewPresentation = () => {\n setPresentation({\n slides: [{ id: `slide-${Date.now()}`, elements: [] }],\n layout: { width: 12192000, height: 6858000 }\n });\n setCurrentSlideIndex(0);\n setSelectedElementId(null);\n updateSource('scratch');\n };\n\n const handleLoadPresentation = async (input: File | string) => {\n setIsLoading(true);\n try {\n const parser = new PptxParser();\n let prompt = input;\n if (typeof input === 'string') {\n const trimmedInput = input.trim();\n prompt = proxyUrl\n ? `${proxyUrl}${proxyUrl.includes('?') ? '&' : '?'}url=${encodeURIComponent(trimmedInput)}`\n : trimmedInput;\n updateSource('url', trimmedInput);\n } else {\n updateSource('uploaded');\n }\n const result = await parser.parse(prompt);\n setPresentation(result);\n setHistory([]);\n setRedoStack([]);\n setCurrentSlideIndex(0);\n setSelectedElementId(null);\n } catch (err) {\n console.error('Failed to load PPTX', err);\n showSnackbar('Failed to load presentation. Please ensure it is a valid .pptx.', 'error');\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleSlashAction = (actionId: string, payload?: any) => {\n if (actionId !== 'ai-text-edit') {\n setSlashMenu(prev => ({ ...prev, visible: false }));\n }\n\n switch (actionId) {\n case 'add-text': handleAddText(); break;\n case 'add-image': handleUploadImageClick(); break;\n case 'add-shape': handleAddShape(payload as ShapeType); break;\n case 'new-slide': handleAddSlide(); break;\n case 'ai-action': handleAiAction(selectedElementId || '', payload); break;\n case 'ai-text-edit': handleAiTextEdit(payload); break;\n case 'generate-image': setIsImageGenOpen(true); break;\n case 'generate-infographic': handleOpenInfographic(); break;\n case 'format': handleFormatText(payload); break;\n case 'delete': handleDeleteElement(); break;\n }\n };\n\n const handleGenerateImage = async () => {\n if (!imageGenPrompt.trim()) return;\n setIsGeneratingImage(true);\n try {\n let imageUrl = '';\n if (onGenerateImage) {\n imageUrl = await onGenerateImage(imageGenPrompt);\n } else if (geminiApiKey) {\n // Fallback to internal Gemini if key is provided (mocking for now as Gemini doesn't have a direct image gen API via this specific JS SDK easily without Vertex AI)\n // In a real scenario, this would call a known endpoint.\n throw new Error(\"Internal image generation requires onGenerateImage prop or specific endpoint configuration.\");\n } else {\n throw new Error(\"No image generation function or Gemini API key provided.\");\n }\n setPendingImage(imageUrl);\n setIsImageGenOpen(false);\n setImageGenPrompt('');\n } catch (error) {\n console.error(\"Image generation failed:\", error);\n showSnackbar(\"Image generation failed: \" + (error instanceof Error ? error.message : \"Unknown error\"), 'error');\n } finally {\n setIsGeneratingImage(false);\n }\n };\n\n const handleFinalizeImage = (action: 'insert' | 'replace' | 'discard') => {\n if (action === 'insert' && pendingImage) {\n handleAddImage(pendingImage);\n } else if (action === 'replace' && pendingImage && selectedElementId) {\n const el = presentation.slides[currentSlideIndex].elements.find(e => e.id === selectedElementId);\n if (el && el.type === 'image') {\n handleElementUpdate(selectedElementId, { src: pendingImage });\n } else {\n handleAddImage(pendingImage); // Fallback to insert if not an image\n }\n }\n setPendingImage(null);\n };\n\n const handleGenerateInfographic = async (customPrompt?: string) => {\n const promptToUse = customPrompt || infographicGenPrompt;\n if (!promptToUse.trim()) return;\n setIsGeneratingInfographic(true);\n try {\n let infographicUrl = '';\n if (onGenerateInfographic) {\n infographicUrl = await onGenerateInfographic(promptToUse);\n } else if (geminiApiKey) {\n // Fallback / Mock\n // throw new Error(\"Internal info gen...\");\n // For now, let's just mock it or throw if not provided, similar to image gen\n throw new Error(\"Internal infographic generation requires onGenerateInfographic prop or specific endpoint configuration.\");\n } else {\n throw new Error(\"No infographic generation function or Gemini API key provided.\");\n }\n setPendingInfographic(infographicUrl);\n setIsInfographicGenOpen(false);\n setInfographicGenPrompt('');\n } catch (error) {\n console.error(\"Infographic generation failed:\", error);\n showSnackbar(\"Infographic generation failed: \" + (error instanceof Error ? error.message : \"Unknown error\"), 'error');\n } finally {\n setIsGeneratingInfographic(false);\n }\n };\n\n const handleFinalizeInfographic = (action: 'insert' | 'replace' | 'discard') => {\n if (action === 'insert' && pendingInfographic) {\n handleAddImage(pendingInfographic); // Treat as image\n } else if (action === 'replace' && pendingInfographic && selectedElementId) {\n const el = presentation.slides[currentSlideIndex].elements.find(e => e.id === selectedElementId);\n if (el && el.type === 'image') {\n handleElementUpdate(selectedElementId, { src: pendingInfographic });\n } else {\n handleAddImage(pendingInfographic);\n }\n }\n setPendingInfographic(null);\n };\n\n const handleOpenInfographic = async () => {\n if (isTwoStepInfographicGeneration && onRefineInfographicPrompt) {\n const textToRefine = selectedElement?.type === 'text' ? selectedElement.content : '';\n if (textToRefine) {\n setIsRefiningInfographic(true);\n try {\n const refined = await onRefineInfographicPrompt(textToRefine);\n setRefinedInfographicPrompt(refined);\n } catch (error) {\n console.error(\"Prompt refinement failed:\", error);\n showSnackbar(\"Failed to refine infographic prompt.\", 'error');\n } finally {\n setIsRefiningInfographic(false);\n }\n return;\n }\n }\n setIsInfographicGenOpen(true);\n };\n\n const handleUploadImageClick = () => {\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = 'image/*';\n input.onchange = async (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (file) {\n const src = await new Promise<string>((resolve) => {\n const reader = new FileReader();\n reader.onload = (re) => resolve(re.target?.result as string);\n reader.readAsDataURL(file);\n });\n setPendingImage(src);\n }\n };\n input.click();\n };\n\n const getProxiedUrl = useCallback((url: string) => {\n if (!proxyUrl || !url || url.startsWith('data:')) return url;\n if (url.includes('localhost') || url.includes('127.0.0.1')) return url;\n return `${proxyUrl}?url=${encodeURIComponent(url)}`;\n }, [proxyUrl]);\n\n if (!width || !height) {\n return (\n <div className=\"flex items-center justify-center bg-red-50 text-red-600 p-8 rounded-xl border-2 border-red-200 font-bold\">\n Error: width and height props are compulsory for PptEditor.\n </div>\n );\n }\n\n return (\n <div\n className=\"flex flex-col bg-white relative\"\n style={{\n width: typeof width === 'number' ? `${width}px` : width,\n height: typeof height === 'number' ? `${height}px` : height,\n fontSize: `${16 * uiScale}px`\n }}\n >\n {showInitialLayout && (\n <div className=\"absolute inset-0 z-[2000] bg-white flex flex-col items-center justify-center p-6 md:p-12 overflow-y-auto\">\n <div className=\"max-w-2xl w-full text-center space-y-6 md:space-y-8 animate-in fade-in zoom-in-95 duration-500 my-auto\">\n <div className=\"flex justify-center\">\n {/* <div className=\"p-6 rounded-3xl\" style={{ backgroundColor: `${appBgColor}10` }}>\n <div className=\"p-4 rounded-2xl\" style={{ backgroundColor: appBgColor }}>\n <svg className=\"w-10 h-10 text-white\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7\" />\n </svg>\n </div>\n </div> */}\n </div>\n <div className=\"space-y-2\">\n <h2 className=\"text-4xl font-black tracking-tight text-slate-800\">{appName}</h2>\n <p className=\"text-slate-500 font-medium\">Create stunning presentations in seconds.</p>\n </div>\n <div className=\"grid grid-cols-2 gap-6\">\n <button\n onClick={() => { handleNewPresentation(); setShowInitialLayout(false); }}\n className=\"flex flex-col items-center justify-center gap-4 p-10 border-2 border-slate-100 rounded-[2.5rem] hover:border-slate-300 hover:bg-slate-50 transition-all group shadow-sm hover:shadow-md active:scale-[0.98]\"\n >\n <div className=\"p-5 bg-slate-100 rounded-2xl group-hover:bg-blue-50 transition-colors\">\n <svg className=\"w-10 h-10 text-blue-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2.5} d=\"M12 4v16m8-8H4\" />\n </svg>\n </div>\n <span className=\"text-sm font-black uppercase tracking-[0.15em] text-slate-600 group-hover:text-slate-900 transition-colors\">Start New Deck</span>\n </button>\n <label className=\"flex flex-col items-center justify-center gap-4 p-10 border-2 border-slate-100 rounded-[2.5rem] hover:border-slate-300 hover:bg-slate-50 transition-all group shadow-sm hover:shadow-md active:scale-[0.98] cursor-pointer\">\n <div className=\"p-5 bg-slate-100 rounded-2xl group-hover:bg-emerald-50 transition-colors\">\n <svg className=\"w-10 h-10 text-emerald-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2.5} d=\"M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1m-4-8l-4-4m0 0L8 8m4-4v12\" />\n </svg>\n </div>\n <span className=\"text-sm font-black uppercase tracking-[0.15em] text-slate-600 group-hover:text-slate-900 transition-colors\">Upload PPTX</span>\n <input\n type=\"file\"\n accept=\".pptx\"\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (file) {\n handleLoadPresentation(file);\n setShowInitialLayout(false);\n }\n }}\n />\n </label>\n </div>\n\n {/* URL Input */}\n <div className=\"space-y-4 pt-8 border-t border-slate-100\">\n <div className=\"flex gap-3 items-stretch\">\n <div className=\"flex-1 relative group\">\n {/* <svg className=\"absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-slate-400 group-focus-within:text-slate-600 transition-colors\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9h18\" />\n </svg> */}\n <input\n type=\"text\"\n placeholder=\"Paste presentation URL...\"\n value={urlInput}\n onChange={(e) => setUrlInput(e.target.value)}\n className=\"text-black w-full bg-slate-50 border border-slate-200 rounded-2xl pl-12 pr-5 py-4 focus:outline-none focus:border-slate-400 focus:ring-4 focus:ring-slate-400/5 text-base transition-all h-full\"\n />\n </div>\n <button\n onClick={() => {\n if (urlInput.trim()) {\n handleLoadPresentation(urlInput.trim());\n setShowInitialLayout(false);\n }\n }}\n disabled={!urlInput.trim() || isLoading}\n style={{ cursor: 'pointer' }}\n className=\"bg-slate-900 hover:bg-black disabled:bg-slate-100 disabled:text-slate-400 text-white font-black px-10 rounded-2xl transition-all shadow-sm text-sm shrink-0 whitespace-nowrap h-full min-h-[56px] flex items-center justify-center uppercase tracking-widest\"\n >\n {isLoading ? (\n <svg className=\"animate-spin h-5 w-5 text-white\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n ) : 'Load'}\n </button>\n </div>\n <p className=\"text-[10px] text-slate-400 font-bold uppercase tracking-[0.2em]\">\n Supports S3, public links, and versioned assets\n </p>\n </div>\n </div>\n </div>\n )}\n {isPreviewMode && (\n <PresenterMode\n presentation={presentation}\n initialSlideIndex={currentSlideIndex}\n onClose={handleClosePresenter}\n />\n )}\n <Toolbar\n onAddText={handleAddText}\n onAddImage={handleAddImage}\n onAddShape={handleAddShape}\n onAddSlide={handleAddSlide}\n onExport={handleExport}\n onFormatText={handleFormatText}\n onDeleteElement={handleDeleteElement}\n onGenerateImageClick={() => setIsImageGenOpen(true)}\n onGenerateInfographicClick={handleOpenInfographic}\n onUploadImageClick={handleUploadImageClick}\n onApplyLayout={handleApplyLayout}\n onPlay={() => setIsPreviewMode(true)}\n onAiAction={handleAiAction}\n onAiResponseAction={handleAiResponseAction}\n onNewPresentation={handleNewPresentation}\n onLoadPresentation={handleLoadPresentation}\n aiResponse={askAiResponse}\n isAiLoading={isAiLoading}\n selectedElement={selectedElement}\n refineResponse={refineResponse}\n onRefineAction={handleAiAction}\n appName={appName}\n appBgColor={appBgColor}\n uiScale={uiScale}\n source={source}\n />\n <div className=\"flex flex-1 overflow-hidden\">\n <Sidebar\n slides={presentation.slides}\n currentSlideIndex={currentSlideIndex}\n onSelectSlide={setCurrentSlideIndex}\n onDeleteSlide={handleDeleteSlide}\n onDuplicateSlide={handleDuplicateSlide}\n onReorderSlides={handleReorderSlides}\n uiScale={uiScale}\n appBgColor={appBgColor}\n />\n <div className=\"flex-1 flex items-center justify-center p-12 overflow-auto bg-white\">\n <EditorCanvas\n slide={currentSlide}\n onElementUpdate={handleElementUpdate}\n onSelect={setSelectedElementId}\n uiScale={uiScale}\n onSlashCommand={(position, mode, context) => setSlashMenu({\n visible: position.x !== 0,\n position,\n mode: mode || 'default',\n context\n })}\n selectedElementId={selectedElementId}\n onAiGenerateClick={() => setIsImageGenOpen(true)}\n onAiGenerateInfographicClick={handleOpenInfographic}\n onUploadImageClick={handleUploadImageClick}\n onDeleteElement={handleDeleteElement}\n />\n </div>\n </div>\n\n {slashMenu.visible && (\n <div\n className=\"fixed inset-0 z-[9998]\"\n onClick={() => setSlashMenu(prev => ({ ...prev, visible: false }))}\n >\n <SlashMenu\n position={slashMenu.position}\n onClose={() => setSlashMenu(prev => ({ ...prev, visible: false }))}\n onAction={handleSlashAction}\n canUseAi={!!geminiApiKey || !!proxyUrl}\n mode={slashMenu.mode}\n context={slashMenu.context}\n aiResult={askAiResponse}\n isAiLoading={isAiLoading}\n onAiResponseAction={handleAiResponseAction}\n />\n </div>\n )}\n\n {refineResponse && selectedElement && (\n <RefineMenu\n result={refineResponse}\n isLoading={isAiLoading}\n onAction={handleRefineResponseAction}\n onClose={() => setRefineResponse(null)}\n />\n )}\n\n {isImageGenOpen && (\n <div className=\"fixed inset-0 z-[9999] flex items-center justify-center bg-black/40 backdrop-blur-sm animate-in fade-in duration-200\">\n <div className=\"bg-white rounded-2xl shadow-2xl w-[500px] p-6 flex flex-col gap-4 animate-in zoom-in-95 duration-200\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-xl font-bold text-slate-800 flex items-center gap-2\">\n <Sparkles className=\"text-blue-600\" size={20} />\n Generate Image\n </h3>\n <button onClick={() => setIsImageGenOpen(false)} className=\"text-slate-400 hover:text-slate-600\">\n <Plus className=\"rotate-45\" size={24} />\n </button>\n </div>\n <p className=\"text-sm text-slate-500\">Describe the image you want to create for this slide.</p>\n <textarea\n autoFocus\n placeholder=\"A futuristic city in the style of cyberpunk with neon lights...\"\n className=\"text-black w-full h-32 p-4 bg-slate-50 border border-slate-200 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 text-sm font-medium resize-none\"\n value={imageGenPrompt}\n onChange={(e) => setImageGenPrompt(e.target.value)}\n />\n <div className=\"flex justify-end gap-3\">\n <button\n onClick={() => setIsImageGenOpen(false)}\n className=\"flex-1 px-5 py-3 cursor-pointer text-sm font-bold text-slate-600 hover:bg-slate-100 rounded-lg transition-colors\"\n >\n Cancel\n </button>\n <button\n onClick={handleGenerateImage}\n disabled={isGeneratingImage || !imageGenPrompt.trim()}\n className=\"flex-1 px-6 py-3 cursor-pointer text-sm font-bold text-white bg-blue-600 hover:bg-blue-700 rounded-lg shadow-lg shadow-blue-500/20 transition-all active:scale-95 disabled:opacity-50 disabled:active:scale-100 flex items-center gap-2\"\n >\n {isGeneratingImage ? (\n <>\n <RefreshCw className=\"animate-spin\" size={16} />\n Generating...\n </>\n ) : (\n 'Generate'\n )}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {pendingImage && (\n <div className=\"fixed inset-0 z-[10000] flex items-center justify-center bg-black/60 backdrop-blur-md animate-in fade-in duration-300\">\n <div className=\"bg-white rounded-2xl shadow-3xl max-w-[90vw] max-h-[90vh] overflow-hidden flex flex-col animate-in zoom-in-95 duration-300 border border-slate-200\">\n <div className=\"p-4 border-b border-slate-100 flex items-center justify-between bg-white\">\n <h3 className=\"text-lg font-bold text-slate-800\">Preview Image</h3>\n <button onClick={() => setPendingImage(null)} className=\"p-2 hover:bg-slate-100 rounded-full text-slate-400 transition-colors\">\n <Plus className=\"rotate-45\" size={20} />\n </button>\n </div>\n\n <div className=\"p-8 bg-slate-100 flex items-center justify-center overflow-auto min-h-[300px] relative\">\n {previewLoading && !imageError && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-slate-100/50 z-10\">\n <RefreshCw className=\"animate-spin text-slate-400\" size={32} />\n </div>\n )}\n <img\n src={getProxiedUrl(pendingImage)}\n alt=\"Generated\"\n className={cn(\n \"max-w-full max-h-[60vh] rounded-lg shadow-2xl ring-4 ring-white transition-opacity duration-300\",\n (imageError || previewLoading) ? \"opacity-0\" : \"opacity-100\"\n )}\n onLoad={() => setPreviewLoading(false)}\n onError={() => {\n setImageError(true);\n setPreviewLoading(false);\n }}\n />\n {imageError && (\n <div className=\"flex flex-col items-center gap-4 text-slate-400 p-12 text-center animate-in fade-in duration-500\">\n <div className=\"p-4 bg-slate-200/50 rounded-full\">\n <ImageIcon size={48} className=\"opacity-40\" />\n </div>\n <div>\n <p className=\"font-bold text-slate-600\">Failed to load preview</p>\n <p className=\"text-xs max-w-[300px] mt-1\">The URL might be invalid or restricted. Ensure it's a valid image format.</p>\n </div>\n <code className=\"text-[10px] bg-slate-200/50 px-2 py-1 rounded break-all max-w-[400px]\">\n {pendingImage}\n </code>\n </div>\n )}\n </div>\n\n <div className=\"p-6 bg-white border-t border-slate-100 flex flex-col gap-4\">\n <div className=\"flex gap-3 justify-center\">\n <button\n onClick={() => handleFinalizeImage('insert')}\n className=\"flex-1 px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white rounded-xl font-bold shadow-lg shadow-blue-500/20 transition-all flex items-center justify-center gap-2\"\n >\n <Check size={18} />\n Insert image\n </button>\n {selectedElementId && presentation.slides[currentSlideIndex].elements.find(e => e.id === selectedElementId)?.type === 'image' && (\n <button\n onClick={() => handleFinalizeImage('replace')}\n className=\"flex-1 px-6 py-3 bg-emerald-600 hover:bg-emerald-700 text-black rounded-xl font-bold shadow-lg shadow-emerald-500/20 transition-all flex items-center justify-center gap-2\"\n >\n <RefreshCw size={18} />\n Replace existing\n </button>\n )}\n </div>\n <button\n onClick={() => handleFinalizeImage('discard')}\n className=\"w-full px-6 py-3 bg-red-50 hover:bg-red-100 text-red-600 rounded-xl font-bold transition-all flex items-center justify-center gap-2\"\n >\n <Trash2 size={18} />\n Discard\n </button>\n </div>\n </div>\n </div>\n )}\n\n\n\n {isInfographicGenOpen && (\n <div className=\"fixed inset-0 z-[9999] flex items-center justify-center bg-black/40 backdrop-blur-sm animate-in fade-in duration-200\">\n <div className=\"bg-white rounded-2xl shadow-2xl w-[500px] p-6 flex flex-col gap-4 animate-in zoom-in-95 duration-200\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-xl font-bold text-slate-800 flex items-center gap-2\">\n <PieChart className=\"text-blue-600\" size={20} />\n Generate Infographic\n </h3>\n <button onClick={() => setIsInfographicGenOpen(false)} className=\"text-slate-400 hover:text-slate-600\">\n <Plus className=\"rotate-45\" size={24} />\n </button>\n </div>\n <p className=\"text-sm text-slate-500\">Describe the infographic you want to create for this slide.</p>\n <textarea\n autoFocus\n placeholder=\"A pie chart showing market share distribution...\"\n className=\"text-black w-full h-32 p-4 bg-slate-50 border border-slate-200 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 text-sm font-medium resize-none\"\n value={infographicGenPrompt}\n onChange={(e) => setInfographicGenPrompt(e.target.value)}\n />\n <div className=\"flex justify-end gap-3\">\n <button\n onClick={() => setIsInfographicGenOpen(false)}\n className=\"flex-1 px-5 py-3 cursor-pointer text-sm font-bold text-slate-600 hover:bg-slate-100 rounded-lg transition-colors\"\n >\n Cancel\n </button>\n <button\n onClick={() => handleGenerateInfographic()}\n disabled={isGeneratingInfographic || !infographicGenPrompt.trim()}\n className=\"flex-1 px-6 py-3 cursor-pointer text-sm font-bold text-white bg-blue-600 hover:bg-blue-700 rounded-lg shadow-lg shadow-blue-500/20 transition-all active:scale-95 disabled:opacity-50 disabled:active:scale-100 flex items-center gap-2\"\n >\n {isGeneratingInfographic ? (\n <>\n <RefreshCw className=\"animate-spin\" size={16} />\n Generating...\n </>\n ) : (\n 'Generate'\n )}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {isRefiningInfographic && (\n <div className=\"fixed inset-0 z-[11000] flex items-center justify-center bg-black/20 backdrop-blur-[2px] animate-in fade-in duration-200\">\n <div className=\"bg-white rounded-2xl shadow-2xl p-8 flex flex-col items-center gap-4 animate-in zoom-in-95 duration-200\">\n <RefreshCw className=\"animate-spin text-blue-600\" size={32} />\n <p className=\"text-sm font-bold text-slate-600\">Polishing your prompt with AI...</p>\n </div>\n </div>\n )}\n\n {refinedInfographicPrompt !== null && (\n <div className=\"fixed inset-0 z-[9999] flex items-center justify-center bg-black/40 backdrop-blur-sm animate-in fade-in duration-200\">\n <div className=\"bg-white rounded-2xl shadow-2xl w-[600px] p-6 flex flex-col gap-4 animate-in zoom-in-95 duration-200\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-xl font-bold text-slate-800 flex items-center gap-2\">\n <Sparkles className=\"text-blue-600\" size={20} />\n Step 1: AI Refinement\n </h3>\n <button onClick={() => setRefinedInfographicPrompt(null)} className=\"text-slate-400 hover:text-slate-600\">\n <Plus className=\"rotate-45\" size={24} />\n </button>\n </div>\n <p className=\"text-sm text-slate-500\">The AI has refined your selected text into a visual prompt. You can adjust it below.</p>\n <textarea\n autoFocus\n className=\"text-black w-full h-48 p-4 bg-slate-50 border border-slate-200 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 text-sm font-medium resize-none shadow-inner\"\n value={refinedInfographicPrompt}\n onChange={(e) => setRefinedInfographicPrompt(e.target.value)}\n />\n <div className=\"flex justify-end gap-3 mt-2\">\n <button\n onClick={() => setRefinedInfographicPrompt(null)}\n className=\"px-5 py-3 text-sm font-bold text-slate-600 hover:bg-slate-100 rounded-lg transition-colors\"\n >\n Discard\n </button>\n <button\n onClick={() => {\n const finalPrompt = refinedInfographicPrompt;\n setRefinedInfographicPrompt(null);\n handleGenerateInfographic(finalPrompt);\n }}\n className=\"px-6 py-3 text-sm font-bold text-white bg-blue-600 hover:bg-blue-700 rounded-xl shadow-lg shadow-blue-500/20 transition-all active:scale-95 flex items-center gap-2 uppercase tracking-wide\"\n >\n <PieChart size={18} />\n Generate Infographic\n </button>\n </div>\n </div>\n </div>\n )}\n\n {pendingInfographic && (\n <div className=\"fixed inset-0 z-[10000] flex items-center justify-center bg-black/60 backdrop-blur-md animate-in fade-in duration-300\">\n <div className=\"bg-white rounded-2xl shadow-3xl max-w-[90vw] max-h-[90vh] overflow-hidden flex flex-col animate-in zoom-in-95 duration-300 border border-slate-200\">\n <div className=\"p-4 border-b border-slate-100 flex items-center justify-between bg-white\">\n <h3 className=\"text-lg font-bold text-slate-800\">Preview Infographic</h3>\n <button onClick={() => setPendingInfographic(null)} className=\"p-2 hover:bg-slate-100 rounded-full text-slate-400 transition-colors\">\n <Plus className=\"rotate-45\" size={20} />\n </button>\n </div>\n\n <div className=\"p-8 bg-slate-100 flex items-center justify-center overflow-auto min-h-[300px] relative\">\n {previewLoading && !infographicError && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-slate-100/50 z-10\">\n <RefreshCw className=\"animate-spin text-slate-400\" size={32} />\n </div>\n )}\n <img\n src={getProxiedUrl(pendingInfographic)}\n alt=\"Generated Infographic\"\n className={cn(\n \"max-w-full max-h-[60vh] rounded-lg shadow-2xl ring-4 ring-white transition-opacity duration-300\",\n (infographicError || previewLoading) ? \"opacity-0\" : \"opacity-100\"\n )}\n onLoad={() => setPreviewLoading(false)}\n onError={() => {\n setInfographicError(true);\n setPreviewLoading(false);\n }}\n />\n {infographicError && (\n <div className=\"flex flex-col items-center gap-4 text-slate-400 p-12 text-center animate-in fade-in duration-500\">\n <div className=\"p-4 bg-slate-200/50 rounded-full\">\n <PieChart size={48} className=\"opacity-40\" />\n </div>\n <div>\n <p className=\"font-bold text-slate-600\">Failed to load preview</p>\n <p className=\"text-xs max-w-[300px] mt-1\">The URL might be invalid or restricted. Ensure it's a valid image format.</p>\n </div>\n <code className=\"text-[10px] bg-slate-200/50 px-2 py-1 rounded break-all max-w-[400px]\">\n {pendingInfographic}\n </code>\n </div>\n )}\n </div>\n\n <div className=\"p-6 bg-white border-t border-slate-100 flex flex-col gap-4\">\n <div className=\"flex gap-3 justify-center\">\n <button\n onClick={() => handleFinalizeInfographic('insert')}\n className=\"flex-1 px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white rounded-xl font-bold shadow-lg shadow-blue-500/20 transition-all flex items-center justify-center gap-2\"\n >\n <Check size={18} />\n Insert infographic\n </button>\n {selectedElementId && presentation.slides[currentSlideIndex].elements.find(e => e.id === selectedElementId)?.type === 'image' && (\n <button\n onClick={() => handleFinalizeInfographic('replace')}\n className=\"flex-1 px-6 py-3 bg-emerald-600 hover:bg-emerald-700 text-black rounded-xl font-bold shadow-lg shadow-emerald-500/20 transition-all flex items-center justify-center gap-2\"\n >\n <RefreshCw size={18} />\n Replace existing\n </button>\n )}\n </div>\n <button\n onClick={() => handleFinalizeInfographic('discard')}\n className=\"w-full px-6 py-3 bg-red-50 hover:bg-red-100 text-red-600 rounded-xl font-bold transition-all flex items-center justify-center gap-2\"\n >\n <Trash2 size={18} />\n Discard\n </button>\n </div>\n </div>\n </div>\n )}\n\n {isPreviewMode && (\n <PresenterMode\n presentation={presentation}\n initialSlideIndex={currentSlideIndex}\n onClose={handleClosePresenter}\n />\n )}\n\n <Snackbar\n isOpen={snackbar.open}\n message={snackbar.message}\n type={snackbar.type}\n onClose={() => setSnackbar(prev => ({ ...prev, open: false }))}\n />\n </div>\n );\n};\n","'use client';\n\nimport React, { useState } from 'react';\nimport {\n Type, Image as ImageIcon, MousePointer2,\n Square, Circle, Download, Plus, Trash2,\n Bold, Italic, Underline, AlignLeft, AlignCenter, AlignRight, AlignJustify,\n List, ListOrdered, Layout as LayoutIcon, Columns, FileText, Highlighter, Eraser,\n History, Share2, Play, Sparkles, RefreshCw, Check, ChevronUp, ChevronDown,\n Strikethrough, Type as TypeIcon\n} from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport { SlideElement, PresentationSource } from '../lib/types';\n\ninterface ToolbarProps {\n onAddText: () => void;\n onAddImage: (file: File) => void;\n onAddShape: (type: any) => void;\n onAddSlide: () => void;\n onExport: () => void;\n onFormatText: (updates: any) => void;\n onDeleteElement: () => void;\n onGenerateImageClick: () => void;\n onGenerateInfographicClick: () => void;\n onUploadImageClick: () => void;\n onApplyLayout: (type: 'title' | 'content' | 'split') => void;\n onPlay: () => void;\n selectedElement: SlideElement | null;\n appName: string;\n onAiAction: (id: string, action: 'shorten' | 'reframe' | 'lengthen') => void;\n onAiResponseAction: (action: 'replace' | 'addBelow' | 'regenerate') => void;\n aiResponse: string | null;\n isAiLoading: boolean;\n refineResponse?: string | null;\n onRefineAction: (actionId: string, actionType: 'shorten' | 'reframe' | 'lengthen') => void;\n onNewPresentation: () => void;\n onLoadPresentation: (input: File | string) => void;\n appBgColor?: string;\n uiScale: number;\n source: PresentationSource | null;\n}\n\nconst FONTS = [\n 'Inter', 'Lato', 'Open Sans', 'Poppins', 'Roboto', 'Roboto Slab',\n 'Georgia', 'Playfair Display', 'Merriweather', 'Nunito Sans',\n 'Montserrat', 'Oswald', 'Raleway', 'Ubuntu', 'Lora',\n 'PT Sans', 'PT Serif', 'Play', 'Arvo', 'Kanit', 'Times New Roman', 'Arial'\n];\nconst FONT_SIZES = [12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 64, 72, 96];\n\nconst SHAPE_CATEGORIES = [\n {\n name: 'Basic Shapes',\n shapes: ['rect', 'circle', 'triangle', 'rightTriangle', 'rhombus', 'parallelogram', 'trapezoid', 'pentagon', 'hexagon', 'heptagon', 'octagon', 'heart', 'smiley', 'sun', 'moon']\n },\n {\n name: 'Arrows',\n shapes: ['arrowRight', 'arrowLeft', 'arrowUp', 'arrowDown', 'arrowLeftRight', 'arrowUpDown']\n },\n {\n name: 'Stars & Symbols',\n shapes: ['star4', 'star5', 'star6', 'star8', 'cloud', 'lightning']\n },\n {\n name: 'Equation Shapes',\n shapes: ['plus', 'minus', 'multiply', 'divide', 'equal']\n }\n];\n\nconst ShapeIcon = ({ type, className }: { type: string, className?: string }) => {\n switch (type) {\n case 'rect': return <svg viewBox=\"0 0 24 24\" className={className}><rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" fill=\"currentColor\" /></svg>;\n case 'circle': return <svg viewBox=\"0 0 24 24\" className={className}><circle cx=\"12\" cy=\"12\" r=\"9\" fill=\"currentColor\" /></svg>;\n case 'triangle': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 4L20 18H4L12 4Z\" fill=\"currentColor\" /></svg>;\n case 'rightTriangle': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M4 4V20H20L4 4Z\" fill=\"currentColor\" /></svg>;\n case 'rhombus': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 4L20 12L12 20L4 12L12 4Z\" fill=\"currentColor\" /></svg>;\n case 'parallelogram': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M7 4H21L17 20H3L7 4Z\" fill=\"currentColor\" /></svg>;\n case 'trapezoid': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M6 4H18L21 20H3L6 4Z\" fill=\"currentColor\" /></svg>;\n case 'pentagon': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 3L21 9V19H3V9L12 3Z\" fill=\"currentColor\" /></svg>;\n case 'hexagon': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 3L20 7.5V16.5L12 21L4 16.5V7.5L12 3Z\" fill=\"currentColor\" /></svg>;\n case 'heptagon': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 3L18.5 6L21 13L16 20H8L3 13L5.5 6L12 3Z\" fill=\"currentColor\" /></svg>;\n case 'octagon': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M8.5 3H15.5L21 8.5V15.5L15.5 21H8.5L3 15.5V8.5L8.5 3Z\" fill=\"currentColor\" /></svg>;\n case 'heart': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\" /></svg>;\n case 'smiley': return <svg viewBox=\"0 0 24 24\" className={className}><circle cx=\"12\" cy=\"12\" r=\"9\" fill=\"currentColor\" fillOpacity=\"0.2\" stroke=\"currentColor\" strokeWidth=\"2\" /><circle cx=\"9\" cy=\"9\" r=\"1.5\" fill=\"currentColor\" /><circle cx=\"15\" cy=\"9\" r=\"1.5\" fill=\"currentColor\" /><path d=\"M8 15C8 15 9.5 17 12 17C14.5 17 16 15 16 15\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" /></svg>;\n case 'sun': return <svg viewBox=\"0 0 24 24\" className={className}><circle cx=\"12\" cy=\"12\" r=\"5\" fill=\"currentColor\" /><path d=\"M12 2V4M12 20V22M4 12H2M22 12H20M19.07 4.93L17.66 6.34M6.34 17.66L4.93 19.07M4.93 4.93L6.34 6.34M17.66 17.66L19.07 19.07\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" /></svg>;\n case 'moon': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 3a9 9 0 1 0 9 9 7 7 0 0 1-9-9\" fill=\"currentColor\" /></svg>;\n case 'arrowRight': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M4 11h11.5l-3.5-3.5 1.5-1.5 6 6-6 6-1.5-1.5 3.5-3.5H4z\" fill=\"currentColor\" /></svg>;\n case 'arrowLeft': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M20 11H8.5l3.5-3.5L10.5 6l-6 6 6 6 1.5-1.5-3.5-3.5H20z\" fill=\"currentColor\" /></svg>;\n case 'arrowUp': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M13 20V8.5l3.5 3.5 1.5-1.5-6-6-6 6 1.5 1.5 3.5-3.5V20z\" fill=\"currentColor\" /></svg>;\n case 'arrowDown': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M11 4v11.5l-3.5-3.5-1.5 1.5 6 6 6-6-1.5-1.5-3.5 3.5V4z\" fill=\"currentColor\" /></svg>;\n case 'arrowLeftRight': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M4 12l4-4v3h8V8l4 4-4 4v-3H8v3l-4-4z\" fill=\"currentColor\" /></svg>;\n case 'arrowUpDown': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 4l-4 4h3v8H8l4 4 4-4h-3V8h3l-4-4z\" fill=\"currentColor\" /></svg>;\n case 'star4': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 2l2 8 8 2-8 2-2 8-2-8-8-2 8-2 2-8z\" fill=\"currentColor\" /></svg>;\n case 'star5': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 2l2.5 7.5H22l-6 4.5 2.5 7.5-6.5-4.5-6.5 4.5 2.5-7.5-6-4.5h7.5L12 2z\" fill=\"currentColor\" /></svg>;\n case 'star6': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 2l3 5 6-1-4 4.5 2 6.5-7-3-7 3 2-6.5-4-4.5 6 1 3-5z\" fill=\"currentColor\" /></svg>;\n case 'star8': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 2l2 4 4-2-2 4 4 2-4 2 2 4-4-2-2 4-2-4-4 2 2-4-4-2 4-2-2-4 4 2 2-4z\" fill=\"currentColor\" /></svg>;\n case 'cloud': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M17.5 19c-3 0-5.5-2.5-5.5-5.5 0-.2 0-.4.1-.6-2-.8-3.6-2.5-4.1-4.7C6.5 7.4 5 6 3 6c-1.7 0-3 1.3-3 3s1.3 3 3 3c.4 0 .8-.1 1.2-.2C4.1 13 5 14.5 6.5 15.5c.3 1.8 1.4 3.4 3 4.3.4.2.8.3 1.2.4 1.2.4 2.5.6 3.8.6 4.4 0 8-3.6 8-8s-3.6-8-8-8c-.4 0-.8 0-1.2.1-1.2.2-2.3.7-3.2 1.5C11 4.2 12.4 3.5 14 3.5c4.1 0 7.5 3.4 7.5 7.5s-1.8 7.5-4 8z\" fill=\"currentColor\" transform=\"scale(0.8) translate(3,3)\" /></svg>;\n case 'lightning': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M13 2L3 14h9v8l10-12h-9l3-8z\" fill=\"currentColor\" /></svg>;\n case 'plus': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" fill=\"currentColor\" /></svg>;\n case 'minus': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M19 13H5v-2h14v2z\" fill=\"currentColor\" /></svg>;\n case 'multiply': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z\" fill=\"currentColor\" /></svg>;\n case 'divide': return <svg viewBox=\"0 0 24 24\" className={className}><circle cx=\"12\" cy=\"7\" r=\"2\" fill=\"currentColor\" /><circle cx=\"12\" cy=\"17\" r=\"2\" fill=\"currentColor\" /><rect x=\"5\" y=\"11\" width=\"14\" height=\"2\" fill=\"currentColor\" /></svg>;\n case 'equal': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M19 10H5V8h14v2zm0 6H5v-2h14v2z\" fill=\"currentColor\" /></svg>;\n default: return <div className=\"w-6 h-6 bg-slate-200 rounded-sm\" />;\n }\n};\n\nconst ShapesDropdown = ({ onAddShape, uiScale }: { onAddShape: (type: string) => void, uiScale: number }) => {\n const [isOpen, setIsOpen] = useState(false);\n\n // Wire up the toggle to the window so the parent button can trigger it\n React.useEffect(() => {\n (window as any)._toggleShapesMenu = () => setIsOpen(!isOpen);\n return () => { (window as any)._toggleShapesMenu = undefined; };\n }, [isOpen]);\n\n if (!isOpen) return null;\n\n return (\n <div\n className=\"absolute top-full left-0 mt-2 bg-white border border-slate-200 rounded-2xl shadow-2xl p-4 overflow-y-auto z-[100] animate-in fade-in zoom-in-95 duration-200\"\n style={{\n width: `${320 * uiScale}px`,\n maxHeight: `${480 * uiScale}px`\n }}\n >\n <div className=\"flex flex-col gap-6\">\n {SHAPE_CATEGORIES.map(cat => (\n <div key={cat.name} className=\"flex flex-col gap-2\">\n <span className=\"text-[10px] font-black uppercase tracking-widest text-slate-400 px-1\" style={{ fontSize: `${10 * uiScale}px` }}>{cat.name}</span>\n <div className=\"grid grid-cols-5 gap-1\">\n {cat.shapes.map(s => (\n <button\n key={s}\n onClick={() => { onAddShape(s); setIsOpen(false); }}\n className=\"aspect-square hover:bg-slate-50 rounded-lg flex items-center justify-center border border-transparent hover:border-slate-100 transition-all group p-1\"\n title={s}\n >\n <div className=\"w-full h-full bg-slate-100 rounded-sm group-hover:bg-blue-100 group-hover:scale-110 transition-all flex items-center justify-center overflow-hidden p-1.5\">\n <ShapeIcon type={s} className=\"w-full h-full text-slate-400 group-hover:text-blue-600 transition-colors\" />\n </div>\n </button>\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport const Toolbar: React.FC<ToolbarProps> = ({\n onAddText, onAddImage, onAddShape, onAddSlide, onExport,\n onFormatText, onDeleteElement, onApplyLayout, onPlay, selectedElement,\n onNewPresentation, onLoadPresentation, appBgColor = '#B7472A', uiScale,\n source, onGenerateImageClick, onGenerateInfographicClick, onUploadImageClick,\n onRefineAction, refineResponse, isAiLoading\n}) => {\n const fileInputRef = React.useRef<HTMLInputElement>(null);\n const [activeTab, setActiveTab] = useState('Home');\n const [showLayouts, setShowLayouts] = useState(false);\n const [showAiMenu, setShowAiMenu] = useState(false); // For the new Refine dropdown\n const [showFileMenu, setShowFileMenu] = useState(false);\n const [showUploadModal, setShowUploadModal] = useState(false);\n const [uploadType, setUploadType] = useState<'file' | 'link'>('file');\n const [uploadUrl, setUploadUrl] = useState('');\n const [showChangeCaseMenu, setShowChangeCaseMenu] = useState(false);\n const [showCharSpacingMenu, setShowCharSpacingMenu] = useState(false);\n const [showBulletMenu, setShowBulletMenu] = useState(false);\n const [showNumberingMenu, setShowNumberingMenu] = useState(false);\n\n // Change case helper functions\n const applyChangeCase = (caseType: string) => {\n if (!isText || !selectedElement) return;\n const currentText = (selectedElement as any).content || '';\n let newText = currentText;\n switch (caseType) {\n case 'sentence':\n newText = currentText.charAt(0).toUpperCase() + currentText.slice(1).toLowerCase();\n break;\n case 'lowercase':\n newText = currentText.toLowerCase();\n break;\n case 'uppercase':\n newText = currentText.toUpperCase();\n break;\n case 'capitalize':\n newText = currentText.split(' ').map((word: string) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(' ');\n break;\n case 'toggle':\n newText = currentText.split('').map((char: string) => char === char.toUpperCase() ? char.toLowerCase() : char.toUpperCase()).join('');\n break;\n }\n onFormatText({ content: newText });\n setShowChangeCaseMenu(false);\n };\n\n const isText = selectedElement?.type === 'text';\n const isShape = selectedElement?.type === 'shape';\n const isImage = selectedElement?.type === 'image';\n\n const PPT_RED = '#B7472A';\n\n return (\n <div\n className=\"flex flex-col border-b border-slate-200 bg-white z-50 select-none\"\n style={{ fontSize: `${12 * uiScale}px` }}\n >\n {/* Main Toolbar Row */}\n <div\n className=\"bg-white flex items-center justify-stretch border-b border-slate-200/60 transition-all duration-300 relative z-[1000]\"\n style={{ height: `${120 * uiScale}px`, overflow: 'visible' }}\n >\n {/* Slides Group */}\n <div className={cn(\"flex flex-col items-center border-r border-slate-100 px-3 gap-1 h-full py-2\", uiScale < 0.84 ? \"min-w-0\" : \"min-w-fit\")}>\n <div className=\"flex items-center justify-center gap-1 my-auto\">\n <button\n onClick={onAddSlide}\n className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg group transition-all min-w-[64px]\"\n >\n <div className=\"bg-orange-50 p-1.5 rounded-lg group-hover:scale-110 transition-transform\">\n <Plus size={20} style={{ color: appBgColor }} />\n </div>\n <span className=\"text-[10px] font-bold text-slate-700\">New Slide</span>\n </button>\n\n <div className=\"w-[1px] h-10 bg-slate-100 mx-1\" />\n\n <div className=\"relative\">\n <button\n onClick={() => setShowLayouts(!showLayouts)}\n className={cn(\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg transition-all min-w-[64px]\", showLayouts && \"bg-slate-100\")}\n >\n <div className=\"p-1.5 rounded-lg\">\n <LayoutIcon size={20} className=\"text-slate-500\" />\n </div>\n <span className=\"text-[10px] font-medium text-slate-500\">Layout</span>\n </button>\n {showLayouts && (\n <div className=\"absolute top-full left-0 mt-2 bg-white border border-slate-200 rounded-2xl shadow-3xl p-2 w-60 flex flex-col gap-1 z-[100] animate-in fade-in zoom-in-95 duration-200 ring-4 ring-black/5\">\n <button\n onClick={() => { onApplyLayout('title'); setShowLayouts(false); }}\n className=\"flex items-center gap-3 px-4 py-3 hover:bg-slate-50 rounded-xl text-[13px] font-bold text-slate-700 transition-all border border-transparent hover:border-slate-100 group\"\n >\n <div className=\"p-2 bg-blue-50 text-blue-600 rounded-lg group-hover:bg-blue-600 group-hover:text-white transition-colors\">\n <FileText size={18} />\n </div>\n Title Slide\n </button>\n <button\n onClick={() => { onApplyLayout('content'); setShowLayouts(false); }}\n className=\"flex items-center gap-3 px-4 py-3 hover:bg-slate-50 rounded-xl text-[13px] font-bold text-slate-700 transition-all border border-transparent hover:border-slate-100 group\"\n >\n <div className=\"p-2 bg-emerald-50 text-emerald-600 rounded-lg group-hover:bg-emerald-600 group-hover:text-white transition-colors\">\n <List size={18} />\n </div>\n Title & Content\n </button>\n <button\n onClick={() => { onApplyLayout('split'); setShowLayouts(false); }}\n className=\"flex items-center gap-3 px-4 py-3 hover:bg-slate-50 rounded-xl text-[13px] font-bold text-slate-700 transition-all border border-transparent hover:border-slate-100 group\"\n >\n <div className=\"p-2 bg-purple-50 text-purple-600 rounded-lg group-hover:bg-purple-600 group-hover:text-white transition-colors\">\n <Columns size={18} />\n </div>\n Two Columns\n </button>\n </div>\n )}\n </div>\n </div>\n {uiScale >= 0.85 && <span className=\"text-[9px] uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">Slides</span>}\n </div>\n\n\n {/* Font Group */}\n <div className={cn(\"flex-1 flex items-center flex-col border-r border-slate-200 h-full py-2 relative\", uiScale < 0.85 ? \"px-2\" : \"px-4\")}>\n {/* Top Row: Font Family, Size, A^, Av, Clear */}\n <div className=\"flex items-center gap-4 mt-2 mb-3\">\n {/* Font Family Dropdown */}\n <div className=\"flex items-center bg-white border border-slate-300 rounded-[3px] h-[28px] overflow-hidden\">\n <select\n disabled={!isText}\n value={(selectedElement as any)?.fontFamily || 'Open Sans'}\n onChange={(e) => onFormatText({ fontFamily: e.target.value })}\n className={cn(\"h-full px-1.5 text-[13px] text-slate-800 font-normal bg-transparent outline-none disabled:opacity-50 appearance-none cursor-pointer\", uiScale < 0.85 ? \"w-20\" : \"w-32\")}\n >\n {FONTS.map(f => <option key={f} value={f}>{f}</option>)}\n </select>\n <ChevronDown size={13} className=\"text-slate-400 mr-1\" />\n </div>\n\n {/* Font Size Dropdown */}\n <div className=\"flex items-center bg-white border border-slate-300 rounded-[3px] h-[28px] overflow-hidden w-15\">\n <select\n disabled={!isText}\n value={(selectedElement as any)?.fontSize || 10}\n onChange={(e) => onFormatText({ fontSize: parseInt(e.target.value) })}\n className=\"h-full w-full px-1 text-[12.5px] text-slate-800 font-normal bg-transparent outline-none disabled:opacity-50 appearance-none cursor-pointer text-center\"\n >\n {FONT_SIZES.map(s => <option key={s} value={s}>{s}</option>)}\n </select>\n <ChevronDown size={13} className=\"text-slate-400 mr-0.5\" />\n </div>\n\n {/* Increase Font Size (A^) */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ fontSize: Math.min(200, ((selectedElement as any)?.fontSize || 24) + 2) })}\n className=\"w-9 h-[28px] flex items-center justify-center hover:bg-slate-100 rounded-[3px] transition-colors disabled:opacity-40\"\n title=\"Increase Font Size\"\n >\n <span className=\"text-[16px] font-semibold text-slate-700\">A</span>\n <span className=\"text-[10px] font-bold text-slate-700 -ml-0.5 -mt-1\">▲</span>\n </button>\n\n {/* Decrease Font Size (Av) */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ fontSize: Math.max(8, ((selectedElement as any)?.fontSize || 24) - 2) })}\n className=\"w-9 h-[28px] flex items-center justify-center hover:bg-slate-100 rounded-[3px] transition-colors disabled:opacity-40\"\n title=\"Decrease Font Size\"\n >\n <span className=\"text-[14px] font-semibold text-slate-700\">A</span>\n <span className=\"text-[10px] font-bold text-slate-700 -ml-0.5 mt-1\">▼</span>\n </button>\n\n {/* Clear Formatting (Ax) */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ isBold: false, isItalic: false, isUnderline: false, highlightColor: '', color: '#000000', isStrikethrough: false })}\n className=\"w-9 h-[28px] flex items-center justify-center hover:bg-slate-100 rounded-[3px] transition-colors disabled:opacity-40\"\n title=\"Clear All Formatting\"\n >\n <span className=\"text-[16px] font-semibold text-slate-700\">A</span>\n <Eraser size={11} className=\"text-pink-500 -ml-0.5\" />\n </button>\n </div>\n\n {/* Bottom Row: B I U S abc AV Aa | Highlighter A-color */}\n <div className=\"flex items-center gap-1.5 mb-1\">\n {/* Bold */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ isBold: !(selectedElement as any).isBold })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isBold ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Bold\"\n >\n <span className={`text-[17px] font-black ${(selectedElement as any)?.isBold ? 'text-slate-900' : 'text-slate-700'}`}>B</span>\n </button>\n\n {/* Italic */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ isItalic: !(selectedElement as any).isItalic })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isItalic ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Italic\"\n >\n <span className={`text-[17px] font-semibold italic ${(selectedElement as any)?.isItalic ? 'text-slate-900' : 'text-slate-700'}`} style={{ fontFamily: 'serif' }}>I</span>\n </button>\n\n {/* Underline */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ isUnderline: !(selectedElement as any).isUnderline })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isUnderline ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Underline\"\n >\n <span className={`text-[17px] font-semibold underline underline-offset-2 ${(selectedElement as any)?.isUnderline ? 'text-slate-900' : 'text-slate-700'}`}>U</span>\n </button>\n\n {/* abc strikethrough */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ isStrikethrough: !(selectedElement as any).isStrikethrough })}\n className={cn(\"h-8 px-1.5 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isStrikethrough ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Strikethrough\"\n >\n <span className={`text-[12px] font-medium line-through ${(selectedElement as any)?.isStrikethrough ? 'text-slate-900' : 'text-slate-600'}`}>abc</span>\n <ChevronDown size={12} className=\"text-slate-400 ml-0.5\" />\n </button>\n\n {/* Character Spacing (AV with arrows) */}\n <div className=\"relative\">\n <button\n disabled={!isText}\n onClick={() => setShowCharSpacingMenu(!showCharSpacingMenu)}\n className={cn(\"h-8 px-1.5 flex flex-col items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", showCharSpacingMenu ? \"bg-slate-100\" : \"hover:bg-slate-100\")}\n title=\"Character Spacing\"\n >\n <div className=\"flex items-center\">\n <span className=\"text-[12px] font-bold text-slate-700\">A</span>\n <span className=\"text-[12px] font-bold text-slate-700 -ml-0.5\">V</span>\n <ChevronDown size={11} className=\"text-slate-400 ml-0.5\" />\n </div>\n <div className=\"flex items-center gap-0\">\n <span className=\"text-[7px] text-blue-500\">◀</span>\n <div className=\"w-2.5 h-[1px] bg-blue-500\" />\n <span className=\"text-[7px] text-blue-500\">▶</span>\n </div>\n </button>\n {showCharSpacingMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl py-1 w-32 z-[100] animate-in fade-in zoom-in-95 duration-150\">\n <button onClick={() => { onFormatText({ charSpacing: -50 }); setShowCharSpacingMenu(false); }} className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n Very Tight\n {(selectedElement as any)?.charSpacing === -50 && <Check size={12} className=\"text-blue-600 ml-auto\" />}\n </button>\n <button onClick={() => { onFormatText({ charSpacing: -25 }); setShowCharSpacingMenu(false); }} className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n Tight\n {(selectedElement as any)?.charSpacing === -25 && <Check size={12} className=\"text-blue-600 ml-auto\" />}\n </button>\n <button onClick={() => { onFormatText({ charSpacing: 0 }); setShowCharSpacingMenu(false); }} className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n Normal\n {((selectedElement as any)?.charSpacing === 0 || !(selectedElement as any)?.charSpacing) && <Check size={12} className=\"text-blue-600 ml-auto\" />}\n </button>\n <button onClick={() => { onFormatText({ charSpacing: 25 }); setShowCharSpacingMenu(false); }} className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n Loose\n {(selectedElement as any)?.charSpacing === 25 && <Check size={12} className=\"text-blue-600 ml-auto\" />}\n </button>\n <button onClick={() => { onFormatText({ charSpacing: 50 }); setShowCharSpacingMenu(false); }} className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n Very Loose\n {(selectedElement as any)?.charSpacing === 50 && <Check size={12} className=\"text-blue-600 ml-auto\" />}\n </button>\n <div className=\"h-[1px] bg-slate-100 my-1\" />\n <button className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 disabled:opacity-50\">\n More Spacing...\n </button>\n </div>\n )}\n </div>\n\n {/* Change Case (Aa) */}\n <div className=\"relative\">\n <button\n disabled={!isText}\n onClick={() => setShowChangeCaseMenu(!showChangeCaseMenu)}\n className=\"h-8 px-1.5 flex items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all disabled:opacity-40\"\n title=\"Change Case\"\n >\n <span className=\"text-[14px] font-medium text-slate-700\">Aa</span>\n <ChevronDown size={11} className=\"text-slate-400 ml-0.5\" />\n </button>\n {showChangeCaseMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl py-1 w-44 z-[100] animate-in fade-in zoom-in-95 duration-150\">\n <button onClick={() => applyChangeCase('sentence')} className=\"w-full px-3 py-1.5 text-left text-[12px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n <span className=\"text-slate-400\">Aa</span> Sentence case.\n </button>\n <button onClick={() => applyChangeCase('lowercase')} className=\"w-full px-3 py-1.5 text-left text-[12px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n <span className=\"text-slate-400 underline\">l</span> lowercase\n </button>\n <button onClick={() => applyChangeCase('uppercase')} className=\"w-full px-3 py-1.5 text-left text-[12px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n <span className=\"text-slate-400 underline\">U</span> UPPERCASE\n </button>\n <button onClick={() => applyChangeCase('capitalize')} className=\"w-full px-3 py-1.5 text-left text-[12px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n <span className=\"text-slate-400 underline\">C</span> Capitalize Each Word\n </button>\n <button onClick={() => applyChangeCase('toggle')} className=\"w-full px-3 py-1.5 text-left text-[12px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n <span className=\"text-slate-400 underline\">t</span> tOGGLE cASE\n </button>\n </div>\n )}\n </div>\n\n <div className=\"w-[1px] h-5 bg-slate-200 mx-1.5\" />\n\n {/* Highlighter */}\n <div className=\"relative flex items-center\">\n <button\n disabled={!isText}\n className={cn(\"w-9 h-7.5 flex flex-col items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.highlightColor ? \"bg-slate-100\" : \"hover:bg-slate-100\")}\n title=\"Text Highlight Color\"\n >\n <Highlighter size={21} strokeWidth={2.5} className={(selectedElement as any)?.highlightColor ? \"text-slate-900\" : \"text-slate-500\"} />\n <div className=\"absolute top-[24px] left-1.5 right-1.5 h-1.5\" style={{ backgroundColor: (selectedElement as any)?.highlightColor || 'transparent' }} />\n </button>\n <input\n type=\"color\"\n disabled={!isText}\n className=\"absolute inset-0 opacity-0 cursor-pointer w-full h-full disabled:cursor-not-allowed\"\n value={(selectedElement as any)?.highlightColor || '#ffff00'}\n onChange={(e) => onFormatText({ highlightColor: e.target.value })}\n title=\"Choose Highlight Color\"\n />\n <ChevronDown size={11} className=\"text-slate-400 -ml-0.5\" />\n </div>\n\n {/* Font Color */}\n <div className=\"relative flex items-center\">\n <button\n className=\"w-9 h-7.5 flex flex-col items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all\"\n title=\"Font Color\"\n >\n <span className=\"text-[16px] font-black text-slate-800 leading-none\">A</span>\n <div className=\"w-6 h-[4px] rounded-sm mt-0.5\" style={{ backgroundColor: (selectedElement as any)?.color || '#ff0000' }} />\n <input\n type=\"color\"\n className=\"absolute inset-0 opacity-0 cursor-pointer w-full h-full\"\n value={(selectedElement as any)?.color || '#ff0000'}\n onChange={(e) => onFormatText({ color: e.target.value })}\n />\n </button>\n <ChevronDown size={11} className=\"text-slate-400 -ml-0.5\" />\n </div>\n </div>\n\n {/* Footer with Label and Expand Icon */}\n {/* <div className=\"mt-auto flex items-center justify-center relative pt-0.5 border-t border-slate-100\">\n <span className=\"text-[10px] text-slate-500 font-medium\">Font</span>\n <div className=\"absolute right-0 bottom-0\">\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" className=\"text-slate-400\">\n <path d=\"M1 7L7 1M7 1H3M7 1V5\" stroke=\"currentColor\" strokeWidth=\"1\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n </div> */}\n {uiScale >= 0.85 && <span className=\"text-[9px] text-center uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">Font</span>}\n </div>\n\n {/* Paragraph Group */}\n <div className={cn(\"flex flex-col border-r border-slate-200 h-full py-2 relative\", uiScale < 0.85 ? \"px-2\" : \"px-4\")}>\n {/* Top Row: Lists and Indents */}\n <div className=\"flex items-center gap-1.5 mt-2 mb-3\">\n {/* Bullet List */}\n <div className=\"relative flex items-center rounded-[3px] hover:bg-slate-100 transition-all\">\n <button\n disabled={!isText}\n onClick={() => {\n if ((selectedElement as any)?.isBulleted) {\n onFormatText({ isBulleted: false, isNumbered: false, listType: 'none' });\n } else {\n onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-disc' });\n }\n }}\n className={cn(\"w-[32px] h-8 flex items-center justify-center rounded-l-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isBulleted ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Bullets\"\n >\n <List size={19} className={(selectedElement as any)?.isBulleted ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n <button\n disabled={!isText}\n onClick={() => setShowBulletMenu(!showBulletMenu)}\n className={cn(\"w-[15px] h-8 flex items-center justify-center rounded-r-[3px] border-l border-transparent hover:border-slate-200 transition-all disabled:opacity-40\", showBulletMenu ? \"bg-slate-100\" : \"hover:bg-slate-200\")}\n title=\"Bullet Options\"\n >\n <ChevronDown size={13} className=\"text-slate-400\" />\n </button>\n\n {showBulletMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl p-2 z-[100] animate-in fade-in zoom-in-95 duration-150 w-64 grid grid-cols-4 gap-2\">\n <button onClick={() => { onFormatText({ isBulleted: false, listType: 'none' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1\">\n <span className=\"text-[10px] text-slate-500\">None</span>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-disc' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-circle' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-square' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-square-outlined' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-diamond' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black rotate-45 scale-75\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black rotate-45 scale-75\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black rotate-45 scale-75\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-arrow' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">➤</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">➤</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">➤</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-check' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">✓</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">✓</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">✓</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n </div>\n )}\n </div>\n\n {/* Numbered List */}\n <div className=\"relative flex items-center rounded-[3px] hover:bg-slate-100 transition-all\">\n <button\n disabled={!isText}\n onClick={() => {\n if ((selectedElement as any)?.isNumbered) {\n onFormatText({ isBulleted: false, isNumbered: false, listType: 'none' });\n } else {\n onFormatText({ isBulleted: false, isNumbered: true, listType: 'number-decimal' });\n }\n }}\n className={cn(\"w-[32px] h-8 flex items-center justify-center rounded-l-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isNumbered ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Numbering\"\n >\n <ListOrdered size={19} className={(selectedElement as any)?.isNumbered ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n <button\n disabled={!isText}\n onClick={() => setShowNumberingMenu(!showNumberingMenu)}\n className={cn(\"w-[15px] h-8 flex items-center justify-center rounded-r-[3px] border-l border-transparent hover:border-slate-200 transition-all disabled:opacity-40\", showNumberingMenu ? \"bg-slate-100\" : \"hover:bg-slate-200\")}\n title=\"Numbering Options\"\n >\n <ChevronDown size={13} className=\"text-slate-400\" />\n </button>\n\n {showNumberingMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl p-2 z-[100] animate-in fade-in zoom-in-95 duration-150 w-64 grid grid-cols-4 gap-2\">\n <button onClick={() => { onFormatText({ isNumbered: false, listType: 'none' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1\">\n <span className=\"text-[10px] text-slate-500\">None</span>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-decimal' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">1.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">2.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">3.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-decimal-paren' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">1)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">2)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">3)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-roman-upper' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">I.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">II.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">III.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-alpha-upper' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">A.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">B.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">C.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-alpha-lower-paren' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">a)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">b)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">c)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-alpha-lower' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">a.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">b.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">c.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-roman-lower' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">i.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">ii.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">iii.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n </div>\n )}\n </div>\n\n <div className=\"w-[1px] h-6 bg-slate-200 mx-1.5\" />\n\n {/* Decrease Indent */}\n <button\n disabled={!isText}\n className=\"w-8 h-8 flex items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all disabled:opacity-40\"\n title=\"Decrease List Level\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 14 14\" fill=\"none\" className=\"text-slate-600\">\n <path d=\"M2 3H12M6 7H12M6 11H12M2 7L4 9L2 11\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n\n {/* Increase Indent */}\n <button\n disabled={!isText}\n className=\"w-8 h-8 flex items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all disabled:opacity-40\"\n title=\"Increase List Level\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 14 14\" fill=\"none\" className=\"text-slate-600\">\n <path d=\"M2 3H12M6 7H12M6 11H12M4 7L2 9L4 11\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n {/* Bottom Row: Alignment */}\n <div className=\"flex items-center gap-1.5 mb-1\">\n <button\n disabled={!isText}\n onClick={() => onFormatText({ textAlign: 'left' })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.textAlign === 'left' ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Align Left\"\n >\n <AlignLeft size={19} className={(selectedElement as any)?.textAlign === 'left' ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n <button\n disabled={!isText}\n onClick={() => onFormatText({ textAlign: 'center' })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.textAlign === 'center' ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Center\"\n >\n <AlignCenter size={19} className={(selectedElement as any)?.textAlign === 'center' ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n <button\n disabled={!isText}\n onClick={() => onFormatText({ textAlign: 'right' })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.textAlign === 'right' ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Align Right\"\n >\n <AlignRight size={19} className={(selectedElement as any)?.textAlign === 'right' ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n <button\n disabled={!isText}\n onClick={() => onFormatText({ textAlign: 'justify' })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.textAlign === 'justify' ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Justify\"\n >\n <AlignJustify size={19} className={(selectedElement as any)?.textAlign === 'justify' ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n </div>\n\n {uiScale >= 0.85 && <span className=\"text-[9px] text-center uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">Paragraph</span>}\n {/* Footer with Label and Expand Icon */}\n {/* <div className=\"mt-auto flex items-center justify-center relative pt-0.5 border-t border-slate-100\">\n <span className=\"text-[10px] text-slate-500 font-medium\">Paragraph</span>\n <div className=\"absolute right-0 bottom-0\">\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" className=\"text-slate-400\">\n <path d=\"M1 7L7 1M7 1H3M7 1V5\" stroke=\"currentColor\" strokeWidth=\"1\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n\n </div> */}\n </div>\n\n {/* Drawing Group */}\n <div className=\"flex flex-col items-center border-r border-slate-100 px-2 gap-1 h-full py-1.5 shrink-0\">\n <div className=\"flex items-center justify-center gap-1 my-auto\">\n <div className=\"relative group/shapes flex justify-center\">\n <button\n className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg group transition-all min-w-[64px]\"\n onClick={() => (window as any)._toggleShapesMenu?.()}\n >\n <div className=\"bg-blue-50 p-1.5 rounded-lg group-hover:scale-105 transition-transform\">\n <Square size={20} className=\"text-blue-600\" />\n </div>\n <span className=\"text-[10px] font-bold text-slate-700\">Shapes</span>\n </button>\n <ShapesDropdown onAddShape={(s) => { onAddShape(s); }} uiScale={uiScale} />\n </div>\n\n <div className=\"w-[1px] h-10 bg-slate-100 mx-1\" />\n\n <button onClick={onAddText} className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg text-slate-600 transition-colors min-w-[64px]\" title=\"Text Box\">\n <div className=\"p-1.5\">\n <Type size={20} />\n </div>\n <span className=\"text-[10px] font-medium text-slate-500\">Text Box</span>\n </button>\n\n <div className=\"w-[1px] h-10 bg-slate-100 mx-1\" />\n\n <button onClick={() => fileInputRef.current?.click()} className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg text-slate-600 transition-colors min-w-[64px]\" title=\"Image\">\n <div className=\"p-1.5\">\n <ImageIcon size={20} />\n </div>\n <span className=\"text-[10px] font-medium text-slate-500\">Image</span>\n <input type=\"file\" ref={fileInputRef} className=\"hidden\" accept=\"image/*\" onChange={(e) => e.target.files?.[0] && onAddImage(e.target.files[0])} />\n </button>\n </div>\n {uiScale >= 0.85 && <span className=\"text-[9px] uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">Drawing</span>}\n </div>\n\n {/* AI Text Group */}\n <div className=\"flex flex-col items-center border-r border-slate-100 px-1 gap-1 h-full py-1.5 relative\">\n <div className=\"flex items-center justify-center gap-0.5 my-auto h-full relative\">\n <button\n disabled={!isText || isAiLoading}\n onClick={() => setShowAiMenu(!showAiMenu)}\n className={cn(\n \"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg text-slate-600 disabled:opacity-20 transition-all min-w-[72px]\",\n showAiMenu && \"bg-slate-100 text-slate-900\"\n )}\n >\n <div className=\"p-1.5 rounded-lg group-hover:scale-110 transition-transform\">\n <Sparkles size={20} className=\"text-purple-500\" />\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[10px] font-bold\">Refine</span>\n <ChevronDown size={10} className=\"text-slate-400\" />\n </div>\n </button>\n\n {showAiMenu && (\n <div className=\"absolute top-full left-0 mt-2 bg-white border border-slate-200 rounded-xl shadow-xl w-40 z-[100] animate-in fade-in zoom-in-95 duration-150 overflow-hidden\">\n <button\n onClick={() => { onRefineAction?.(selectedElement!.id, 'shorten'); setShowAiMenu(false); }}\n className=\"w-full px-4 py-2.5 text-left text-xs font-medium text-slate-700 hover:bg-purple-50 hover:text-purple-700 flex items-center gap-2 transition-colors border-b border-slate-50\"\n >\n <span className=\"text-purple-400\">abc</span>\n Shorten\n </button>\n <button\n onClick={() => { onRefineAction?.(selectedElement!.id, 'reframe'); setShowAiMenu(false); }}\n className=\"w-full px-4 py-2.5 text-left text-xs font-medium text-slate-700 hover:bg-blue-50 hover:text-blue-700 flex items-center gap-2 transition-colors border-b border-slate-50\"\n >\n <span className=\"text-blue-400\">↻</span>\n Reframe\n </button>\n <button\n onClick={() => { onRefineAction?.(selectedElement!.id, 'lengthen'); setShowAiMenu(false); }}\n className=\"w-full px-4 py-2.5 text-left text-xs font-medium text-slate-700 hover:bg-emerald-50 hover:text-emerald-700 flex items-center gap-2 transition-colors\"\n >\n <span className=\"text-emerald-400\">...</span>\n Lengthen\n </button>\n </div>\n )}\n </div>\n\n {/* AI Loading State */}\n {isAiLoading && (\n <div className=\"absolute inset-x-0 top-2 bottom-8 bg-white/80 flex items-center justify-center rounded-lg z-10 backdrop-blur-[1px]\">\n <RefreshCw size={16} className=\"text-blue-600 animate-spin\" />\n </div>\n )}\n {uiScale >= 0.85 && <span className=\"text-[9px] uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">AI Text</span>}\n </div>\n\n {/* Actions Group */}\n <div className=\"flex flex-col items-center pl-4 pr-3 gap-1 h-full py-2 relative\">\n <div className=\"flex items-center justify-center gap-1 my-auto h-full\">\n <button\n onClick={onPlay}\n className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg text-slate-700 transition-all min-w-[64px] group\"\n title=\"Present\"\n >\n <div className=\"p-1.5 rounded-lg group-hover:scale-110 transition-transform\">\n <Play size={20} className=\"fill-slate-700 group-hover:fill-slate-900\" />\n </div>\n <span className=\"text-[10px] font-bold\">Present</span>\n </button>\n\n <div className=\"w-[1px] h-10 bg-slate-100 mx-1\" />\n\n <button\n onClick={onExport}\n className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg text-slate-700 transition-all min-w-[64px] group\"\n title=\"Export\"\n >\n <div className=\"p-1.5 rounded-lg group-hover:scale-110 transition-transform\">\n <Download size={20} className=\"text-emerald-600\" />\n </div>\n <span className=\"text-[10px] font-bold\">Export</span>\n </button>\n\n {selectedElement && (\n <>\n <div className=\"w-[1px] h-10 bg-slate-100 mx-1\" />\n <button\n onClick={onDeleteElement}\n className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-red-50 rounded-lg text-red-600 transition-all min-w-[64px] group\"\n title=\"Delete\"\n >\n <div className=\"p-1.5 rounded-lg group-hover:scale-110 transition-transform\">\n <Trash2 size={20} />\n </div>\n <span className=\"text-[10px] font-bold\">Delete</span>\n </button>\n </>\n )}\n </div>\n\n <div className=\"absolute bottom-2 right-3 flex items-center gap-1 px-1.5 py-0.5 bg-emerald-50/50 rounded-md border border-emerald-100/50\">\n <Check size={9} className=\"text-emerald-500\" />\n <span className=\"text-[7px] font-black text-emerald-600/70 tracking-tighter uppercase\">Saved</span>\n </div>\n\n {uiScale >= 0.85 && <span className=\"text-[9px] uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">Actions</span>}\n </div>\n </div>\n\n {/* Upload Modal */}\n {showUploadModal && (\n <>\n <div className=\"fixed inset-0 bg-slate-900/40 backdrop-blur-sm z-[2000]\" onClick={() => setShowUploadModal(false)} />\n <div className=\"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[480px] bg-white rounded-3xl shadow-2xl z-[2001] border border-slate-200 p-8 animate-in fade-in zoom-in-95 duration-200\">\n <div className=\"flex justify-between items-center mb-6\">\n <h3 className=\"text-lg font-black text-slate-800 tracking-tight flex items-center gap-3\">\n <div className=\"p-2 bg-blue-50 text-blue-600 rounded-xl\">\n <Download size={20} />\n </div>\n Upload Presentation\n </h3>\n <button onClick={() => setShowUploadModal(false)} className=\"text-slate-400 hover:text-slate-600 transition-colors\">\n <RefreshCw size={20} className=\"rotate-45\" />\n </button>\n </div>\n\n <div className=\"flex gap-2 p-1 bg-slate-50 rounded-2xl mb-8\">\n <button\n onClick={() => setUploadType('file')}\n className={cn(\n \"flex-1 py-3 text-xs font-black rounded-xl transition-all\",\n uploadType === 'file' ? \"bg-white text-blue-600 shadow-sm\" : \"text-slate-500 hover:text-slate-700\"\n )}\n >\n FILE UPLOAD\n </button>\n <button\n onClick={() => setUploadType('link')}\n className={cn(\n \"flex-1 py-3 text-xs font-black rounded-xl transition-all\",\n uploadType === 'link' ? \"bg-white text-blue-600 shadow-sm\" : \"text-slate-500 hover:text-slate-700\"\n )}\n >\n LINK UPLOAD\n </button>\n </div>\n\n {uploadType === 'file' ? (\n <label className=\"flex flex-col items-center justify-center gap-4 py-12 border-2 border-dashed border-slate-200 rounded-3xl hover:border-blue-400 hover:bg-blue-50/50 transition-all cursor-pointer group\">\n <div className=\"p-4 bg-white rounded-2xl shadow-sm border border-slate-100 group-hover:scale-110 transition-transform\">\n <Plus size={24} className=\"text-blue-500\" />\n </div>\n <div className=\"text-center\">\n <p className=\"text-sm font-bold text-slate-700\">Choose a PPTX file</p>\n <p className=\"text-xs text-slate-400 mt-1\">Maximum file size: 50MB</p>\n </div>\n <input\n type=\"file\"\n accept=\".pptx\"\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (file) {\n onLoadPresentation(file);\n setShowUploadModal(false);\n }\n }}\n />\n </label>\n ) : (\n <div className=\"space-y-4\">\n <div className=\"relative\">\n <input\n type=\"text\"\n placeholder=\"Paste S3 or public URL\"\n value={uploadUrl}\n onChange={(e) => setUploadUrl(e.target.value)}\n className=\"w-full bg-slate-50 border border-slate-200 rounded-2xl px-5 py-4 focus:outline-none focus:ring-4 focus:ring-blue-500/10 focus:border-blue-500 text-sm placeholder:text-slate-400 text-black\"\n />\n </div>\n <button\n onClick={() => {\n if (uploadUrl.trim()) {\n onLoadPresentation(uploadUrl.trim());\n setShowUploadModal(false);\n }\n }}\n disabled={!uploadUrl.trim()}\n className=\"w-full bg-blue-600 hover:bg-blue-700 disabled:bg-slate-300 text-white font-black py-4 rounded-2xl transition-all shadow-lg shadow-blue-500/20\"\n >\n LOAD PRESENTATION\n </button>\n <p className=\"text-[10px] text-slate-400 text-center uppercase tracking-widest font-black\">\n Supports S3, Dropbox, and public URLS\n </p>\n </div>\n )}\n </div>\n </>\n )}\n </div>\n );\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","'use client';\n\nimport React from 'react';\nimport type { Slide } from '../lib/types';\nimport { cn } from '@/lib/utils';\nimport { Trash2, Copy, GripVertical } from 'lucide-react';\n\nconst SHAPE_PATHS: Record<string, string> = {\n triangle: 'M 12,4 L 20,18 H 4 L 12,4 Z',\n rightTriangle: 'M 4,4 V 20 H 20 L 4,4 Z',\n rhombus: 'M 12,4 L 20,12 L 12,20 L 4,12 L 12,4 Z',\n parallelogram: 'M 7,4 H 21 L 17,20 H 3 L 7,4 Z',\n trapezoid: 'M 6,4 H 18 L 21,20 H 3 L 6,4 Z',\n pentagon: 'M 12,3 L 21,9 V 19 H 3 V 9 L 12,3 Z',\n hexagon: 'M 12,3 L 20,7.5 V 16.5 L 12,21 L 4,16.5 V 7.5 L 12,3 Z',\n heptagon: 'M 12,3 L 18.5,6 L 21,13 L 16,20 H 8 L 3,13 L 5.5,6 L 12,3 Z',\n octagon: 'M 8.5,3 H 15.5 L 21,8.5 V 15.5 L 15.5,21 H 8.5 L 3,15.5 V 8.5 L 8.5,3 Z',\n heart: 'M 12,21.35 L 10.55,20.03 C 5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3 C 9.24,3 10.91,3.81 12,5.09 C 13.09,3.81 14.76,3 16.5,3 C 19.58,3 22,5.42 22,8.5 C 22,12.28 18.6,15.36 13.45,20.04 L 12,21.35 Z',\n smiley: 'M 12,3 A 9,9 0 1,0 12,21 A 9,9 0 1,0 12,3 M 9,9 A 1.5,1.5 0 1,1 9,10.5 A 1.5,1.5 0 1,1 9,9 M 15,9 A 1.5,1.5 0 1,1 15,10.5 A 1.5,1.5 0 1,1 15,9 M 8,15 C 8,15 9.5,17 12,17 C 14.5,17 16,15 16,15',\n sun: 'M 12,7 A 5,5 0 1,1 12,17 A 5,5 0 1,1 12,7 M 12,2 V 4 M 12,20 V 22 M 4,12 H 2 M 22,12 H 20 M 19.07,4.93 L 17.66,6.34 M 6.34,17.66 L 4.93,19.07 M 4.93,4.93 L 6.34,6.34 M 17.66,17.66 L 19.07,19.07',\n moon: 'M 12,3 A 9,9 0 1,0 12,21 A 7,7 0 0,1 12,3 Z',\n circle: 'M 12,3 A 9,9 0 1,1 12,21 A 9,9 0 1,1 12,3 Z',\n arrowRight: 'M 4,11 H 15.5 L 12,7.5 L 13.5,6 L 19.5,12 L 13.5,18 L 12,16.5 L 15.5,13 H 4 Z',\n arrowLeft: 'M 20,11 H 8.5 L 12,7.5 L 10.5,6 L 4.5,12 L 10.5,18 L 12,16.5 L 8.5,13 H 20 Z',\n arrowUp: 'M 13,20 V 8.5 L 16.5,12 L 18,10.5 L 12,4.5 L 6,10.5 L 7.5,12 L 11,8.5 V 20 Z',\n arrowDown: 'M 11,4 V 15.5 L 7.5,12 L 6,13.5 L 12,19.5 L 18,13.5 L 16.5,12 L 13,15.5 V 4 Z',\n arrowLeftRight: 'M 4,12 L 8,8 V 11 H 16 V 8 L 20,12 L 16,16 V 13 H 8 V 16 L 4,12 Z',\n arrowUpDown: 'M 12,4 L 8,8 H 11 V 16 H 8 L 12,20 L 16,16 H 13 V 8 H 16 L 12,4 Z',\n star4: 'M 12,2 L 14,10 L 22,12 L 14,14 L 12,22 L 10,14 L 2,12 L 10,10 L 12,2 Z',\n star5: 'M 12,2 L 14.5,9.5 H 22 L 16,14 L 18.5,21.5 L 12,17 L 5.5,21.5 L 8,14 L 2,9.5 H 9.5 L 12,2 Z',\n star6: 'M 12,2 L 15,7 L 21,6 L 17,10.5 L 19,17 L 12,14 L 5,17 L 7,10.5 L 3,6 L 9,7 L 12,2 Z',\n star8: 'M 12,2 L 14,6 L 18,4 L 16,8 L 20,10 L 16,12 L 18,16 L 14,14 L 12,18 L 10,14 L 6,16 L 8,12 L 4,10 L 8,8 L 6,4 L 10,6 L 12,2 Z',\n cloud: 'M 17,19 C 14.8,19 13.1,17.7 12.3,15.8 C 11.4,16 10.5,16.2 9.6,16.2 C 7,16.2 4.7,14.6 3.7,12.3 C 1.5,11.8 0,9.9 0,7.6 C 0,5 2.1,2.9 4.7,2.9 C 5.3,2.9 5.8,3 6.3,3.1 C 7.6,1.4 9.6,0.3 11.9,0.3 C 12.5,0.3 13.1,0.4 13.7,0.5 C 15,1.9 15.9,3.7 16,5.7 C 18.2,6.1 20,8.1 20,10.5 C 20,13.2 17.8,15.4 15.1,15.4 C 14.8,15.4 14.5,15.4 14.2,15.3 C 14.2,15.4 14.2,15.4 14.2,15.5 C 14.2,17.4 15.5,19 17,19 Z',\n lightning: 'M 13,2 L 3,14 H 12 V 22 L 22,10 H 13 L 16,2 Z',\n plus: 'M 19,13 H 13 V 19 H 11 V 13 H 5 V 11 H 11 V 5 H 13 V 11 H 19 V 13 Z',\n minus: 'M 19,13 H 5 V 11 H 19 V 13 Z',\n multiply: 'M 19,6.41 L 17.59,5 L 12,10.59 L 6.41,5 L 5,6.41 L 10.59,12 L 5,17.59 L 6.41,19 L 12,13.41 L 17.59,19 L 19,17.59 L 13.41,12 L 19,6.41 Z',\n divide: 'M 12,7 A 2,2 0 1,1 12,11 A 2,2 0 1,1 12,7 M 12,17 A 2,2 0 1,1 12,21 A 2,2 0 1,1 12,17 M 5,11 H 19 V 13 H 5 V 11 Z',\n equal: 'M 19,10 H 5 V 8 H 19 V 10 M 19,16 H 5 V 14 H 19 V 16 Z'\n};\nimport {\n DndContext,\n closestCenter,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n DragEndEvent\n} from '@dnd-kit/core';\nimport {\n arrayMove,\n SortableContext,\n sortableKeyboardCoordinates,\n verticalListSortingStrategy,\n useSortable\n} from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\n\ninterface SidebarProps {\n slides: Slide[];\n currentSlideIndex: number;\n onSelectSlide: (index: number) => void;\n onDeleteSlide: (index: number) => void;\n onDuplicateSlide: (index: number) => void;\n onReorderSlides: (oldIndex: number, newIndex: number) => void;\n uiScale: number;\n appBgColor?: string;\n}\n\nconst SortableSlide = ({\n slide,\n index,\n isActive,\n onSelect,\n onDelete,\n onDuplicate,\n showDelete,\n uiScale,\n appBgColor\n}: {\n slide: Slide,\n index: number,\n isActive: boolean,\n onSelect: () => void,\n onDelete: () => void,\n onDuplicate: () => void,\n showDelete: boolean,\n uiScale: number,\n appBgColor: string\n}) => {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging\n } = useSortable({ id: slide.id });\n\n const style = {\n transform: CSS.Transform.toString(transform),\n transition,\n zIndex: isDragging ? 2 : 1,\n opacity: isDragging ? 0.5 : 1\n };\n\n return (\n <div\n ref={setNodeRef}\n onClick={onSelect}\n className={cn(\n \"cursor-pointer border-[1.5px] border-solid p-2 transition-all duration-300 group relative select-none\",\n isActive\n ? \"bg-white\"\n : \"border hover:border-slate-200 bg-white/50 hover:bg-white\"\n )}\n style={{\n ...style,\n border: isActive ? `1px solid ${appBgColor}` : \"1px solid transparent\"\n }}\n >\n <div\n className={cn(\"text-[10px] font-bold mb-1 flex items-center justify-between transition-colors\", !isActive && \"text-slate-400\")}\n style={{ color: isActive ? appBgColor : undefined }}\n >\n <div className=\"flex items-center gap-1\">\n <div {...attributes} {...listeners} className=\"cursor-grab active:cursor-grabbing p-0.5 hover:bg-slate-100 text-slate-300 hover:text-slate-500\">\n <GripVertical size={10} />\n </div>\n <span>SLIDE {index + 1}</span>\n </div>\n <div className=\"flex items-center gap-1\">\n {isActive && <span className=\"h-1.5 w-1.5\" style={{ backgroundColor: appBgColor }} />}\n <div className=\"flex items-center opacity-0 group-hover:opacity-100 transition-opacity\">\n <button\n onClick={(e) => { e.stopPropagation(); onDuplicate(); }}\n className=\"p-1 hover:bg-blue-50 text-slate-400 hover:text-blue-500 transition-all\"\n title=\"Duplicate Slide\"\n >\n <Copy size={12} />\n </button>\n {showDelete && (\n <button\n onClick={(e) => { e.stopPropagation(); onDelete(); }}\n className=\"p-1 hover:bg-red-50 text-red-400 hover:text-red-500 transition-all\"\n title=\"Delete Slide\"\n >\n <Trash2 size={12} />\n </button>\n )}\n </div>\n </div>\n </div>\n <div className=\"aspect-video bg-white flex items-center justify-center border border-slate-200 overflow-hidden relative group-hover:shadow-sm transition-shadow\">\n {/* Scaled Preview of Slide Content */}\n <div\n className=\"origin-center pointer-events-none select-none shrink-0\"\n style={{\n width: '1200px',\n height: '675px',\n transform: `scale(${(170 * uiScale) / 1200})`, // Perfectly fit within available width\n backgroundColor: '#ffffff'\n }}\n >\n {slide.elements.sort((a, b) => (a.zIndex || 0) - (b.zIndex || 0)).map((el) => {\n const style: React.CSSProperties = {\n position: 'absolute',\n left: el.x,\n top: el.y,\n width: el.width,\n height: el.height,\n opacity: el.opacity ?? 1,\n };\n\n if (el.type === 'text') {\n return (\n <div\n key={el.id}\n style={{\n ...style,\n fontSize: el.fontSize,\n fontFamily: el.fontFamily,\n color: el.color,\n textAlign: el.textAlign || 'left',\n fontWeight: el.isBold ? 'bold' : 'normal',\n fontStyle: el.isItalic ? 'italic' : 'normal',\n lineHeight: 1.2,\n overflow: 'hidden',\n wordBreak: 'break-word',\n whiteSpace: 'pre-wrap'\n }}\n >\n {el.content}\n </div>\n );\n } else if (el.type === 'shape') {\n const pathData = SHAPE_PATHS[el.shapeType] || (el.shapeType === 'ellipse' ? SHAPE_PATHS.circle : null);\n if (pathData) {\n return (\n <svg\n key={el.id}\n viewBox=\"0 0 24 24\"\n style={{\n ...style,\n fill: el.fill\n }}\n preserveAspectRatio=\"none\"\n >\n <path d={pathData} />\n </svg>\n );\n }\n return (\n <div\n key={el.id}\n style={{\n ...style,\n backgroundColor: el.fill,\n borderRadius: el.shapeType === 'ellipse' ? '50%' : '0'\n }}\n />\n );\n } else if (el.type === 'image') {\n return (\n <img\n key={el.id}\n src={el.src}\n alt=\"\"\n style={{\n ...style,\n objectFit: 'contain'\n }}\n />\n );\n }\n return null;\n })}\n </div>\n </div>\n </div>\n );\n};\n\nexport const Sidebar: React.FC<SidebarProps> = ({\n slides,\n currentSlideIndex,\n onSelectSlide,\n onDeleteSlide,\n onDuplicateSlide,\n onReorderSlides,\n uiScale,\n appBgColor = '#B7472A'\n}) => {\n const sensors = useSensors(\n useSensor(PointerSensor, {\n activationConstraint: {\n distance: 5,\n },\n }),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n })\n );\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { active, over } = event;\n if (active.id !== over?.id) {\n const oldIndex = slides.findIndex((s) => s.id === active.id);\n const newIndex = slides.findIndex((s) => s.id === over?.id);\n onReorderSlides(oldIndex, newIndex);\n }\n };\n\n return (\n <div\n className=\"bg-white border-r border-slate-100 overflow-y-auto p-4 flex flex-col gap-4\"\n style={{ width: `${256 * uiScale}px` }}\n >\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <SortableContext\n items={slides.map(s => s.id)}\n strategy={verticalListSortingStrategy}\n >\n {slides.map((slide, index) => (\n <SortableSlide\n key={slide.id}\n slide={slide}\n index={index}\n isActive={index === currentSlideIndex}\n onSelect={() => onSelectSlide(index)}\n onDelete={() => onDeleteSlide(index)}\n onDuplicate={() => onDuplicateSlide(index)}\n showDelete={slides.length > 1}\n uiScale={uiScale}\n appBgColor={appBgColor}\n />\n ))}\n </SortableContext>\n </DndContext>\n </div>\n );\n};\n","'use client';\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport * as fabric from 'fabric';\nimport type { Slide, SlideElement, ShapeType } from '../lib/types';\nimport { Sparkles, Image as ImageIcon, Trash2, Plus, PieChart } from 'lucide-react';\nimport { cn } from '../lib/utils';\n\nconst SHAPE_PATHS: Record<string, string> = {\n triangle: 'M 12,4 L 20,18 H 4 L 12,4 Z',\n rightTriangle: 'M 4,4 V 20 H 20 L 4,4 Z',\n rhombus: 'M 12,4 L 20,12 L 12,20 L 4,12 L 12,4 Z',\n parallelogram: 'M 7,4 H 21 L 17,20 H 3 L 7,4 Z',\n trapezoid: 'M 6,4 H 18 L 21,20 H 3 L 6,4 Z',\n pentagon: 'M 12,3 L 21,9 V 19 H 3 V 9 L 12,3 Z',\n hexagon: 'M 12,3 L 20,7.5 V 16.5 L 12,21 L 4,16.5 V 7.5 L 12,3 Z',\n heptagon: 'M 12,3 L 18.5,6 L 21,13 L 16,20 H 8 L 3,13 L 5.5,6 L 12,3 Z',\n octagon: 'M 8.5,3 H 15.5 L 21,8.5 V 15.5 L 15.5,21 H 8.5 L 3,15.5 V 8.5 L 8.5,3 Z',\n heart: 'M 12,21.35 L 10.55,20.03 C 5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3 C 9.24,3 10.91,3.81 12,5.09 C 13.09,3.81 14.76,3 16.5,3 C 19.58,3 22,5.42 22,8.5 C 22,12.28 18.6,15.36 13.45,20.04 L 12,21.35 Z',\n smiley: 'M 12,3 A 9,9 0 1,0 12,21 A 9,9 0 1,0 12,3 M 9,9 A 1.5,1.5 0 1,1 9,10.5 A 1.5,1.5 0 1,1 9,9 M 15,9 A 1.5,1.5 0 1,1 15,10.5 A 1.5,1.5 0 1,1 15,9 M 8,15 C 8,15 9.5,17 12,17 C 14.5,17 16,15 16,15',\n sun: 'M 12,7 A 5,5 0 1,1 12,17 A 5,5 0 1,1 12,7 M 12,2 V 4 M 12,20 V 22 M 4,12 H 2 M 22,12 H 20 M 19.07,4.93 L 17.66,6.34 M 6.34,17.66 L 4.93,19.07 M 4.93,4.93 L 6.34,6.34 M 17.66,17.66 L 19.07,19.07',\n moon: 'M 12,3 A 9,9 0 1,0 12,21 A 7,7 0 0,1 12,3 Z',\n circle: 'M 12,3 A 9,9 0 1,1 12,21 A 9,9 0 1,1 12,3 Z',\n arrowRight: 'M 4,11 H 15.5 L 12,7.5 L 13.5,6 L 19.5,12 L 13.5,18 L 12,16.5 L 15.5,13 H 4 Z',\n arrowLeft: 'M 20,11 H 8.5 L 12,7.5 L 10.5,6 L 4.5,12 L 10.5,18 L 12,16.5 L 8.5,13 H 20 Z',\n arrowUp: 'M 13,20 V 8.5 L 16.5,12 L 18,10.5 L 12,4.5 L 6,10.5 L 7.5,12 L 11,8.5 V 20 Z',\n arrowDown: 'M 11,4 V 15.5 L 7.5,12 L 6,13.5 L 12,19.5 L 18,13.5 L 16.5,12 L 13,15.5 V 4 Z',\n arrowLeftRight: 'M 4,12 L 8,8 V 11 H 16 V 8 L 20,12 L 16,16 V 13 H 8 V 16 L 4,12 Z',\n arrowUpDown: 'M 12,4 L 8,8 H 11 V 16 H 8 L 12,20 L 16,16 H 13 V 8 H 16 L 12,4 Z',\n star4: 'M 12,2 L 14,10 L 22,12 L 14,14 L 12,22 L 10,14 L 2,12 L 10,10 L 12,2 Z',\n star5: 'M 12,2 L 14.5,9.5 H 22 L 16,14 L 18.5,21.5 L 12,17 L 5.5,21.5 L 8,14 L 2,9.5 H 9.5 L 12,2 Z',\n star6: 'M 12,2 L 15,7 L 21,6 L 17,10.5 L 19,17 L 12,14 L 5,17 L 7,10.5 L 3,6 L 9,7 L 12,2 Z',\n star8: 'M 12,2 L 14,6 L 18,4 L 16,8 L 20,10 L 16,12 L 18,16 L 14,14 L 12,18 L 10,14 L 6,16 L 8,12 L 4,10 L 8,8 L 6,4 L 10,6 L 12,2 Z',\n cloud: 'M 17,19 C 14.8,19 13.1,17.7 12.3,15.8 C 11.4,16 10.5,16.2 9.6,16.2 C 7,16.2 4.7,14.6 3.7,12.3 C 1.5,11.8 0,9.9 0,7.6 C 0,5 2.1,2.9 4.7,2.9 C 5.3,2.9 5.8,3 6.3,3.1 C 7.6,1.4 9.6,0.3 11.9,0.3 C 12.5,0.3 13.1,0.4 13.7,0.5 C 15,1.9 15.9,3.7 16,5.7 C 18.2,6.1 20,8.1 20,10.5 C 20,13.2 17.8,15.4 15.1,15.4 C 14.8,15.4 14.5,15.4 14.2,15.3 C 14.2,15.4 14.2,15.4 14.2,15.5 C 14.2,17.4 15.5,19 17,19 Z',\n lightning: 'M 13,2 L 3,14 H 12 V 22 L 22,10 H 13 L 16,2 Z',\n plus: 'M 19,13 H 13 V 19 H 11 V 13 H 5 V 11 H 11 V 5 H 13 V 11 H 19 V 13 Z',\n minus: 'M 19,13 H 5 V 11 H 19 V 13 Z',\n multiply: 'M 19,6.41 L 17.59,5 L 12,10.59 L 6.41,5 L 5,6.41 L 10.59,12 L 5,17.59 L 6.41,19 L 12,13.41 L 17.59,19 L 19,17.59 L 13.41,12 L 19,6.41 Z',\n divide: 'M 12,7 A 2,2 0 1,1 12,11 A 2,2 0 1,1 12,7 M 12,17 A 2,2 0 1,1 12,21 A 2,2 0 1,1 12,17 M 5,11 H 19 V 13 H 5 V 11 Z',\n equal: 'M 19,10 H 5 V 8 H 19 V 10 M 19,16 H 5 V 14 H 19 V 16 Z'\n};\n\nconst getBulletContent = (listType: string | undefined, isBulleted: boolean | undefined, isNumbered: boolean | undefined, index: number): string => {\n if (isBulleted) {\n switch (listType) {\n case 'bullet-disc': return '•';\n case 'bullet-circle': return '○';\n case 'bullet-square': return '■';\n case 'bullet-square-outlined': return '□';\n case 'bullet-diamond': return '◆';\n case 'bullet-arrow': return '➤';\n case 'bullet-check': return '✓';\n case 'none': return '';\n default: return '•'; // Default to disc\n }\n } else if (isNumbered) {\n const n = index + 1;\n switch (listType) {\n case 'number-decimal': return `${n}.`;\n case 'number-decimal-paren': return `${n})`;\n case 'number-roman-upper': return toRoman(n) + '.';\n case 'number-roman-lower': return toRoman(n).toLowerCase() + '.';\n case 'number-alpha-upper': return toAlpha(n) + '.';\n case 'number-alpha-lower': return toAlpha(n).toLowerCase() + '.';\n case 'number-alpha-lower-paren': return toAlpha(n).toLowerCase() + ')';\n case 'none': return '';\n default: return `${n}.`; // Default to decimal\n }\n }\n return '';\n};\n\nconst toRoman = (num: number): string => {\n const lookup: { [key: string]: number } = { M: 1000, CM: 900, D: 500, CD: 400, C: 100, XC: 90, L: 50, XL: 40, X: 10, IX: 9, V: 5, IV: 4, I: 1 };\n let roman = '';\n for (const i in lookup) {\n while (num >= lookup[i]) {\n roman += i;\n num -= lookup[i];\n }\n }\n return roman;\n};\n\nconst toAlpha = (num: number): string => {\n return String.fromCharCode(64 + num);\n};\n\nclass CustomTextbox extends fabric.Textbox {\n listType?: string;\n isBulleted?: boolean;\n isNumbered?: boolean;\n\n _renderTextLine(method: any, ctx: any, line: string[], left: number, top: number, lineIndex: number) {\n super._renderTextLine(method, ctx, line, left, top, lineIndex);\n\n if ((this.isBulleted || this.isNumbered) && this.listType !== 'none') {\n const bulletText = getBulletContent(this.listType, this.isBulleted, this.isNumbered, lineIndex);\n if (bulletText) {\n ctx.save();\n const fontSize = this.fontSize || 22;\n // Reduce gap: -1.0em instead of -1.5em for tighter alignment\n const xOffset = -fontSize * 1.0;\n\n // Reduce bullet size to 60% of text size\n const bulletSize = fontSize * 0.6;\n ctx.font = `${this.fontStyle} ${this.fontWeight} ${bulletSize}px ${this.fontFamily}`;\n ctx.fillStyle = this.fill;\n\n // Move bullet up to vertically center it (adjusted for smaller bullet size)\n // User requested \"further up\" from 0.20, so trying 0.35 to hit the visual center\n ctx.fillText(bulletText, left + xOffset, top - (fontSize * 0.35));\n ctx.restore();\n }\n }\n }\n}\n\ninterface CanvasProps {\n slide: Slide;\n onElementUpdate: (elementId: string, updates: Partial<SlideElement>) => void;\n onSelect: (id: string | null) => void;\n uiScale: number;\n onSlashCommand: (\n position: { x: number; y: number },\n mode?: 'default' | 'textbox' | 'text-selection',\n context?: {\n fontFamily?: string;\n fontSize?: number;\n isBold?: boolean;\n isItalic?: boolean;\n isBulleted?: boolean;\n textAlign?: 'left' | 'center' | 'right' | 'justify';\n color?: string;\n }\n ) => void;\n selectedElementId: string | null;\n onAiGenerateClick: () => void;\n onAiGenerateInfographicClick: () => void;\n onUploadImageClick: () => void;\n onDeleteElement: () => void;\n}\n\nexport const EditorCanvas: React.FC<CanvasProps> = ({\n slide, onElementUpdate, onSelect, uiScale, onSlashCommand,\n selectedElementId, onAiGenerateClick, onAiGenerateInfographicClick, onUploadImageClick, onDeleteElement\n}) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const fabricCanvas = useRef<fabric.Canvas | null>(null);\n const isInternalUpdate = useRef(false);\n\n const onElementUpdateRef = useRef(onElementUpdate);\n const onSelectRef = useRef(onSelect);\n const containerRef = useRef<HTMLDivElement>(null);\n const [dynamicScale, setDynamicScale] = useState(1);\n const [canvasReady, setCanvasReady] = useState(false);\n const mousePos = useRef({ x: 0, y: 0 });\n\n // Dynamic Scaling Logic\n useEffect(() => {\n if (!containerRef.current) return;\n\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry) {\n const { width: cw, height: ch } = entry.contentRect;\n // Base dimensions for the slide are 1200x675\n const scaleX = cw / 1200;\n const scaleY = ch / 675;\n // We use the limiting factor (min) and subtract a bit of margin (0.9)\n const scale = Math.min(scaleX, scaleY) * 0.95;\n setDynamicScale(scale);\n }\n });\n\n observer.observe(containerRef.current);\n return () => observer.disconnect();\n }, []);\n\n useEffect(() => {\n onElementUpdateRef.current = onElementUpdate;\n onSelectRef.current = onSelect;\n }, [onElementUpdate, onSelect]);\n\n useEffect(() => {\n if (canvasRef.current && !fabricCanvas.current) {\n const canvas = new fabric.Canvas(canvasRef.current, {\n width: 1200,\n height: 675,\n backgroundColor: 'white',\n selection: true,\n preserveObjectStacking: true\n });\n\n fabricCanvas.current = canvas;\n setCanvasReady(true);\n\n const clamp = (obj: fabric.Object) => {\n if (obj.left! < 0) obj.set('left', 0);\n if (obj.top! < 0) obj.set('top', 0);\n const bound = obj.getBoundingRect();\n if (bound.left + bound.width > (canvas.width || 1200)) obj.set('left', (canvas.width || 1200) - bound.width);\n if (bound.top + bound.height > (canvas.height || 675)) obj.set('top', (canvas.height || 675) - bound.height);\n };\n\n canvas.on('object:moving', (e) => clamp(e.target!));\n canvas.on('object:scaling', (e) => clamp(e.target!));\n\n const handleUpdate = (e: any) => {\n if (isInternalUpdate.current) return;\n const obj = e.target as any;\n const elementId = obj.get('data')?.id;\n if (obj && elementId) {\n onElementUpdateRef.current(elementId, {\n x: obj.left,\n y: obj.top,\n width: obj.getScaledWidth(),\n height: obj.getScaledHeight(),\n ...(obj.isType('textbox') ? {\n content: (obj as fabric.Textbox).text,\n textAlign: (obj as fabric.Textbox).textAlign as any,\n fontSize: obj.fontSize,\n fontFamily: obj.fontFamily,\n color: obj.fill as string\n } : {\n fill: obj.fill as string\n })\n });\n }\n };\n\n canvas.on('object:modified', handleUpdate);\n canvas.on('text:changed', handleUpdate);\n\n const getContext = (obj: any) => {\n if (!obj || !obj.isType('textbox')) return undefined;\n return {\n fontFamily: obj.fontFamily,\n fontSize: obj.fontSize,\n isBold: obj.fontWeight === 'bold',\n isItalic: obj.fontStyle === 'italic',\n isUnderline: obj.underline,\n textAlign: obj.textAlign as any,\n color: obj.fill as string,\n highlightColor: obj.textBackgroundColor as string,\n // Check if it's bulleted (this might depend on how it's stored in fabric)\n isBulleted: !!(obj as any).isBulleted,\n isNumbered: !!(obj as any).isNumbered\n };\n };\n\n const triggerSlashMenu = (obj: any, isTextSelection = false) => {\n try {\n const rect = canvasRef.current?.getBoundingClientRect();\n if (!rect || !obj) return;\n\n let x = 0, y = 0;\n\n const hasMethod = (o: any, m: string) => typeof o === 'object' && o !== null && typeof o[m] === 'function';\n const isTextbox = hasMethod(obj, 'isType') && obj.isType('textbox');\n const isEditing = isTextbox && obj.isEditing;\n\n if (isEditing) {\n const getCoords = (o: any) => {\n try {\n const charIndex = o.selectionStart || 0;\n if (hasMethod(o, 'getCursorCoords')) return o.getCursorCoords(charIndex);\n if (hasMethod(o, '_getCursorCoords')) return o._getCursorCoords(charIndex);\n } catch (e) { }\n return null;\n };\n\n const coords = getCoords(obj);\n if (coords) {\n const canvasCoords = fabric.util.transformPoint(\n new fabric.Point(coords.left, coords.top),\n hasMethod(obj, 'calcTransformMatrix') ? obj.calcTransformMatrix() : [1, 0, 0, 1, 0, 0]\n );\n const vpt = canvas.viewportTransform || [1, 0, 0, 1, 0, 0];\n const viewportCoords = fabric.util.transformPoint(canvasCoords, vpt);\n x = rect.left + viewportCoords.x * dynamicScale;\n y = rect.top + viewportCoords.y * dynamicScale;\n } else {\n const bound = hasMethod(obj, 'getBoundingRect') ? obj.getBoundingRect() : { left: 0, top: 0, width: 0, height: 0 };\n x = rect.left + (bound.left + bound.width / 2) * dynamicScale;\n y = rect.top + bound.top * dynamicScale;\n }\n } else {\n const bound = hasMethod(obj, 'getBoundingRect') ? obj.getBoundingRect() : { left: mousePos.current.x, top: mousePos.current.y, width: 0, height: 0 };\n x = rect.left + (bound.left + bound.width / 2) * dynamicScale;\n y = rect.top + bound.top * dynamicScale;\n }\n\n if (x && y) {\n const mode = isTextSelection ? 'text-selection' : (isTextbox ? 'textbox' : 'default');\n let finalX = x;\n let finalY = y;\n\n if (mode === 'default') {\n // Default command menu: position near the cursor/object without large centering offsets\n finalX = x + 5;\n finalY = y + 5;\n } else {\n // Horizontal toolbar: center above the text and offset upwards\n finalX = x - 220;\n finalY = y - 140;\n }\n\n onSlashCommand(\n { x: finalX, y: finalY },\n mode,\n getContext(obj)\n );\n }\n } catch (err) {\n console.error('Critical error in triggerSlashMenu:', err);\n }\n };\n\n const syncSelection = (e: any) => {\n const obj = e.selected?.[0] || e.target;\n if (obj) {\n const elementId = (obj as any).get('data')?.id;\n onSelectRef.current(elementId);\n\n // Show slash menu on selection if it's a textbox\n if (obj.isType('textbox') && !isInternalUpdate.current) {\n triggerSlashMenu(obj);\n }\n }\n };\n\n canvas.on('selection:created', syncSelection);\n canvas.on('selection:updated', syncSelection);\n canvas.on('selection:cleared', () => {\n onSelectRef.current(null);\n onSlashCommand({ x: 0, y: 0 }, 'default'); // Close menu or reset\n });\n\n // Handle text selection inside textbox\n canvas.on('text:selection:changed', (e: any) => {\n const obj = e.target;\n if (obj && obj.isType('textbox') && obj.selectionStart !== obj.selectionEnd) {\n triggerSlashMenu(obj, true);\n }\n });\n\n canvas.on('mouse:move', (e: any) => {\n if (e.pointer) {\n mousePos.current = { x: e.pointer.x, y: e.pointer.y };\n }\n });\n\n // Global keyboard navigation\n const handleGlobalKeyDown = (e: KeyboardEvent) => {\n const canvas = fabricCanvas.current;\n if (!canvas) return;\n const activeObj = canvas.getActiveObject();\n\n if (e.key === '/') {\n e.preventDefault();\n triggerSlashMenu(activeObj || { isType: () => false, getBoundingRect: () => ({ left: mousePos.current.x, top: mousePos.current.y, width: 0, height: 0 }) } as any);\n return;\n }\n\n // Don't move if editing text\n if (activeObj && activeObj.isType('textbox') && (activeObj as any).isEditing) return;\n\n if (!activeObj) return;\n\n const step = e.shiftKey ? 10 : 1;\n let moved = false;\n\n switch (e.key) {\n case 'ArrowLeft': activeObj.set('left', activeObj.left - step); moved = true; break;\n case 'ArrowRight': activeObj.set('left', activeObj.left + step); moved = true; break;\n case 'ArrowUp': activeObj.set('top', activeObj.top - step); moved = true; break;\n case 'ArrowDown': activeObj.set('top', activeObj.top + step); moved = true; break;\n }\n\n if (moved) {\n clamp(activeObj);\n canvas.requestRenderAll();\n handleUpdate({ target: activeObj });\n }\n };\n\n window.addEventListener('keydown', handleGlobalKeyDown);\n (canvas as any)._keyboardListener = handleGlobalKeyDown;\n }\n\n return () => {\n if (fabricCanvas.current) {\n const listener = (fabricCanvas.current as any)._keyboardListener;\n if (listener) window.removeEventListener('keydown', listener);\n fabricCanvas.current.dispose();\n fabricCanvas.current = null;\n }\n };\n }, []); // Empty dependency array means this only runs once!\n\n useEffect(() => {\n if (!fabricCanvas.current) return;\n const canvas = fabricCanvas.current;\n\n const syncElements = async () => {\n isInternalUpdate.current = true;\n\n const existingObjs = canvas.getObjects();\n const slideIds = new Set(slide.elements.map((e: SlideElement) => e.id));\n\n existingObjs.forEach(obj => {\n const id = (obj as any).get('data')?.id;\n if (id && !slideIds.has(id)) {\n canvas.remove(obj);\n }\n });\n\n const sorted = [...slide.elements].sort((a, b) => (a.zIndex || 0) - (b.zIndex || 0));\n\n for (const el of sorted) {\n let obj = existingObjs.find((o: fabric.Object) => (o as any).get('data')?.id === el.id) as any;\n\n // Upgrade legacy Textbox to CustomTextbox to ensure list rendering works\n if (obj && obj.type === 'textbox' && !(obj instanceof CustomTextbox)) {\n canvas.remove(obj);\n obj = null;\n }\n\n if (obj) {\n // CRITICAL: Skip syncing properties for the object currently being edited.\n // If we update properties (like 'text') while Fabric.js is in editing mode,\n // it resets the cursor position and can cause desync/focus loss.\n if (obj === canvas.getActiveObject() && obj.isType('textbox') && (obj as fabric.Textbox).isEditing) {\n continue;\n }\n\n const updates: any = {\n left: el.x,\n top: el.y,\n opacity: el.opacity !== undefined ? el.opacity : 1,\n zIndex: el.zIndex\n };\n\n if (el.type === 'text' && obj.isType('textbox')) {\n updates.text = el.content || ' ';\n updates.fontSize = el.fontSize || 22;\n updates.fill = el.color || '#000000';\n updates.textBackgroundColor = el.highlightColor || '';\n updates.textAlign = el.textAlign || 'left';\n updates.fontWeight = el.isBold ? 'bold' : 'normal';\n updates.fontStyle = el.isItalic ? 'italic' : 'normal';\n updates.underline = el.isUnderline || false;\n updates.linethrough = el.isStrikethrough || false;\n updates.charSpacing = el.charSpacing || 0;\n updates.fontFamily = el.fontFamily || 'Arial';\n (obj as any).isBulleted = el.isBulleted;\n (obj as any).isNumbered = el.isNumbered;\n (obj as any).listType = el.listType;\n updates.width = Math.max(el.width || 50, 10);\n } else if (el.type === 'shape') {\n updates.fill = (el as any).fill || '#cccccc';\n updates.scaleX = (el.width || 50) / (obj.width || 1);\n updates.scaleY = (el.height || 50) / (obj.height || 1);\n } else if (el.type === 'image') {\n updates.scaleX = (el.width || 100) / (obj.width || 1);\n updates.scaleY = (el.height || 100) / (obj.height || 1);\n }\n\n obj.set(updates);\n } else {\n let newObj: fabric.Object | null = null;\n const commonProps = {\n left: el.x,\n top: el.y,\n data: { id: el.id },\n originX: 'left' as const,\n originY: 'top' as const,\n opacity: el.opacity !== undefined ? el.opacity : 1\n };\n\n if (el.type === 'text') {\n newObj = new CustomTextbox(el.content || ' ', {\n ...commonProps,\n width: Math.max(el.width || 200, 10),\n fontSize: el.fontSize || 22,\n fill: el.color || '#000000',\n backgroundColor: el.highlightColor || '',\n fontFamily: el.fontFamily || 'Inter, Arial, sans-serif',\n textAlign: el.textAlign || 'left',\n fontWeight: el.isBold ? 'bold' : 'normal',\n fontStyle: el.isItalic ? 'italic' : 'normal',\n underline: el.isUnderline || false,\n linethrough: el.isStrikethrough || false,\n charSpacing: el.charSpacing || 0,\n splitByGrapheme: false,\n objectCaching: false, // Critical: customized _renderTextLine draws outside bounding box\n });\n (newObj as any).isBulleted = el.isBulleted;\n (newObj as any).isNumbered = el.isNumbered;\n (newObj as any).listType = el.listType;\n } else if (el.type === 'shape') {\n const shapeFill = (el as any).fill || '#3b82f6';\n if (el.shapeType === 'ellipse') {\n newObj = new fabric.Circle({\n ...commonProps,\n radius: (el.width || 100) / 2,\n scaleY: (el.height || 100) / (el.width || 100),\n fill: shapeFill,\n });\n } else if (el.shapeType === 'rect') {\n newObj = new fabric.Rect({\n ...commonProps,\n width: el.width || 100,\n height: el.height || 100,\n fill: shapeFill,\n });\n } else {\n const pathData = SHAPE_PATHS[el.shapeType];\n if (pathData) {\n newObj = new fabric.Path(pathData, {\n ...commonProps,\n fill: shapeFill,\n });\n // Scale the path to fit the requested dimensions\n // Paths in SHAPE_PATHS are roughly 24x24 based on viewbox\n const p = newObj as fabric.Path;\n p.set({\n scaleX: (el.width || 100) / (p.width || 1),\n scaleY: (el.height || 100) / (p.height || 1),\n });\n } else {\n // Default back to rect if path not found\n newObj = new fabric.Rect({\n ...commonProps,\n width: el.width || 100,\n height: el.height || 100,\n fill: shapeFill,\n });\n }\n }\n } else if (el.type === 'image') {\n try {\n const img = await fabric.FabricImage.fromURL(el.src);\n img.set({\n ...commonProps,\n scaleX: (el.width || 100) / (img.width || 1),\n scaleY: (el.height || 100) / (img.height || 1),\n } as any);\n newObj = img;\n } catch (err) { console.error(err); }\n }\n\n if (newObj) {\n canvas.add(newObj);\n }\n }\n }\n\n canvas.renderAll();\n isInternalUpdate.current = false;\n };\n\n syncElements();\n }, [slide, canvasReady]);\n\n const selectedElement = slide.elements.find(el => el.id === selectedElementId);\n\n return (\n <div ref={containerRef} className=\"w-full h-full flex items-center justify-center overflow-hidden relative\">\n <div\n className=\"border border-slate-200 overflow-hidden bg-white shadow-xl transition-all duration-300 ease-out shrink-0 relative\"\n style={{\n transform: `scale(${dynamicScale})`,\n transformOrigin: 'center center'\n }}\n >\n <canvas ref={canvasRef} />\n\n {/* Empty Slide Helper Overlay */}\n {slide.elements.length === 0 && (\n <div className=\"absolute inset-0 flex flex-col items-center justify-center pointer-events-none select-none animate-in fade-in duration-700\">\n <div className=\"flex flex-col items-center gap-4 text-slate-300\">\n {/* <div className=\"p-5 rounded-full bg-slate-50/50 border border-slate-100/50\">\n <Plus size={40} strokeWidth={1.5} className=\"opacity-50\" />\n </div> */}\n <div className=\"flex flex-col items-center gap-1 text-center\">\n {/* <h3 className=\"text-lg font-semibold text-slate-400\">Empty Slide</h3> */}\n <h1 className=\"text-2xl font-medium text-slate-400\">\n Click <span className=\"px-2 py-0.5 bg-slate-100 rounded-md text-slate-500 font-bold\">/</span> for options\n </h1>\n </div>\n </div>\n </div>\n )}\n\n {/* Image Context Toolbar (Floating vertical list matching SlashMenu style) */}\n {selectedElement && selectedElement.type === 'image' && (\n <div\n className=\"absolute z-[5000] flex flex-col w-96 bg-white border border-slate-200 shadow-2xl rounded-2xl overflow-hidden animate-in fade-in zoom-in duration-200\"\n style={{\n // Horizontal positioning: Left or Right of the image\n left: selectedElement.x + (selectedElement.width / 2) > 600\n ? `${selectedElement.x - 12}px`\n : `${selectedElement.x + selectedElement.width + 12}px`,\n top: `${selectedElement.y + (selectedElement.height / 2)}px`,\n transform: selectedElement.x + (selectedElement.width / 2) > 600\n ? 'translate(-100%, -50%)'\n : 'translate(0, -50%)',\n }}\n >\n <div className=\"px-5 py-3.5 text-sm uppercase tracking-wider font-bold text-slate-400 bg-slate-50/50 border-b border-slate-100\">\n Image Actions\n </div>\n\n <div className=\"p-2.5 flex flex-col gap-1\">\n {/* AI Generate */}\n <button\n onClick={(e) => { e.stopPropagation(); onAiGenerateClick(); }}\n className=\"w-full flex items-center gap-5 px-5 py-4 text-left transition-all duration-150 rounded-xl hover:bg-slate-50 group\"\n >\n <div className=\"p-3 rounded-xl bg-blue-50 text-blue-600 group-hover:bg-blue-600 group-hover:text-white transition-colors\">\n <Sparkles size={28} />\n </div>\n <div className=\"flex flex-col min-w-0\">\n <span className=\"text-lg font-bold text-slate-900\">AI Generate Image</span>\n <span className=\"text-sm text-slate-400 truncate leading-tight\">Create an image with AI prompt</span>\n </div>\n </button>\n\n {/* AI Generate Infographic */}\n <button\n onClick={(e) => { e.stopPropagation(); onAiGenerateInfographicClick(); }}\n className=\"w-full flex items-center gap-5 px-5 py-4 text-left transition-all duration-150 rounded-xl hover:bg-slate-50 group\"\n >\n <div className=\"p-3 rounded-xl bg-purple-50 text-purple-600 group-hover:bg-purple-600 group-hover:text-white transition-colors\">\n <PieChart size={28} />\n </div>\n <div className=\"flex flex-col min-w-0\">\n <span className=\"text-lg font-bold text-slate-900\">AI Infographic</span>\n <span className=\"text-sm text-slate-400 truncate leading-tight\">Generate chart or diagram</span>\n </div>\n </button>\n\n {/* Change Image */}\n <button\n onClick={(e) => { e.stopPropagation(); onUploadImageClick(); }}\n className=\"w-full flex items-center gap-5 px-5 py-4 text-left transition-all duration-150 rounded-xl hover:bg-slate-50 group\"\n >\n <div className=\"p-3 rounded-xl bg-slate-100 text-slate-500 group-hover:bg-slate-200 group-hover:text-slate-700 transition-colors\">\n <ImageIcon size={28} />\n </div>\n <div className=\"flex flex-col min-w-0\">\n <span className=\"text-lg font-bold text-slate-700\">Change Image</span>\n <span className=\"text-sm text-slate-400 truncate leading-tight\">Replace with local file</span>\n </div>\n </button>\n\n <div className=\"h-[1px] bg-slate-100 my-1 mx-3\" />\n\n {/* Delete */}\n <button\n onClick={(e) => { e.stopPropagation(); onDeleteElement(); }}\n className=\"w-full flex items-center gap-5 px-5 py-4 text-left transition-all duration-150 rounded-xl hover:bg-red-50 group\"\n >\n <div className=\"p-3 rounded-xl bg-red-50 text-red-500 group-hover:bg-red-500 group-hover:text-white transition-colors\">\n <Trash2 size={28} />\n </div>\n <div className=\"flex flex-col min-w-0\">\n <span className=\"text-lg font-bold text-red-600\">Delete Element</span>\n <span className=\"text-sm text-red-400/80 truncate leading-tight\">Remove from slide</span>\n </div>\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n};\n","import pptxgen from 'pptxgenjs';\nimport type { Presentation } from './types';\n\nexport class PptxExporter {\n async export(presentation: Presentation): Promise<void> {\n const pptx = new pptxgen();\n\n const emuWidth = presentation.layout?.width || 12192000;\n const emuHeight = presentation.layout?.height || 6858000;\n const canvasWidth = 1200;\n const canvasHeight = 675;\n\n const getInchesX = (px: number) => (px / canvasWidth) * (emuWidth / 914400);\n const getInchesY = (px: number) => (px / canvasHeight) * (emuHeight / 914400);\n\n presentation.slides.forEach(slide => {\n const pptxSlide = pptx.addSlide();\n\n // Sort by zIndex for export layering\n const sortedElements = [...slide.elements].sort((a, b) => a.zIndex - b.zIndex);\n\n sortedElements.forEach(el => {\n const transparency = el.opacity !== undefined ? (1 - el.opacity) * 100 : 0;\n const common = {\n x: getInchesX(el.x),\n y: getInchesY(el.y),\n w: getInchesX(el.width),\n h: getInchesY(el.height),\n };\n\n if (el.type === 'text') {\n pptxSlide.addText(el.content, {\n ...common,\n fontSize: (el.fontSize || 18) / 2, // Halve for export\n color: el.color?.replace('#', '') || '000000',\n fontFace: el.fontFamily || 'Arial'\n });\n } else if (el.type === 'image') {\n pptxSlide.addImage({\n ...common,\n path: el.src,\n transparency: transparency\n });\n } else if (el.type === 'shape') {\n const shapeType = el.shapeType === 'ellipse' ? pptx.ShapeType.ellipse : pptx.ShapeType.rect;\n pptxSlide.addShape(shapeType, {\n ...common,\n fill: {\n color: el.fill?.replace('#', '') || 'CCCCCC',\n transparency: transparency > 0 ? Math.min(transparency + 10, 100) : 0 // Slightly lighter as requested\n }\n });\n }\n });\n });\n\n await pptx.writeFile({ fileName: 'presentation.pptx' });\n }\n}\n","import JSZip from 'jszip';\nimport type { Presentation, Slide, SlideElement, ShapeType } from './types';\n\nexport class PptxParser {\n private slideWidth = 12192000;\n private slideHeight = 6858000;\n private readonly CANVAS_WIDTH = 1200;\n private readonly CANVAS_HEIGHT = 675;\n\n async parse(input: File | Blob | ArrayBuffer | string): Promise<Presentation> {\n let data: any = input;\n if (typeof input === 'string') {\n const response = await fetch(input);\n if (!response.ok) {\n const status = response.status;\n const statusText = response.statusText;\n\n let detail = '';\n try {\n const errorJson = await response.json();\n detail = errorJson.details || errorJson.error || '';\n } catch (e) {\n // Ignore if not JSON\n }\n\n throw new Error(`Failed to fetch PPTX from ${input}: ${status} ${statusText} ${detail ? `(${detail})` : ''}`);\n }\n data = await response.arrayBuffer();\n }\n const zip = await JSZip.loadAsync(data);\n const presentationXml = await zip.file('ppt/presentation.xml')?.async('string');\n if (!presentationXml) throw new Error('Invalid PPTX');\n\n const parser = new DOMParser();\n const presentationDoc = parser.parseFromString(presentationXml, 'text/xml');\n\n const sldSz = this.findFirstByLocalName(presentationDoc, 'sldSz');\n if (sldSz) {\n this.slideWidth = parseInt(this.getAttr(sldSz, 'cx') || '12192000');\n this.slideHeight = parseInt(this.getAttr(sldSz, 'cy') || '6858000');\n }\n\n const sldIdList = Array.from(presentationDoc.getElementsByTagNameNS('*', 'sldId'));\n const slides: Slide[] = [];\n\n for (let i = 0; i < sldIdList.length; i++) {\n const slideNum = i + 1;\n const slidePath = `ppt/slides/slide${slideNum}.xml`;\n const slideXml = await zip.file(slidePath)?.async('string');\n if (slideXml) {\n const slide = await this.parseSlide(slideXml, slideNum, zip);\n slides.push(slide);\n }\n }\n\n return {\n slides,\n layout: { width: this.slideWidth, height: this.slideHeight }\n };\n }\n\n private getAttr(el: Element, name: string): string | null {\n return el.getAttribute(name) || el.getAttribute(`a:${name}`) || el.getAttribute(`p:${name}`) || el.getAttribute(`r:${name}`);\n }\n\n private findFirstByLocalName(parent: Document | Element, name: string): Element | null {\n const elements = parent.getElementsByTagNameNS('*', name);\n return elements.length > 0 ? elements[0] : null;\n }\n\n private findAllByLocalName(parent: Document | Element, name: string): Element[] {\n return Array.from(parent.getElementsByTagNameNS('*', name));\n }\n\n private scaleX(emu: number): number {\n return (emu / this.slideWidth) * this.CANVAS_WIDTH;\n }\n\n private scaleY(emu: number): number {\n return (emu / this.slideHeight) * this.CANVAS_HEIGHT;\n }\n\n private parseColor(el: Element): { color: string, opacity: number } {\n const srgbClr = this.findFirstByLocalName(el, 'srgbClr');\n if (srgbClr) {\n const hex = `#${this.getAttr(srgbClr, 'val')}`;\n const alphaNode = this.findFirstByLocalName(srgbClr, 'alpha');\n const opacity = alphaNode ? parseInt(this.getAttr(alphaNode, 'val') || '100000') / 100000 : 1;\n return { color: hex, opacity };\n }\n const schemeClr = this.findFirstByLocalName(el, 'schemeClr');\n if (schemeClr) {\n const alphaNode = this.findFirstByLocalName(schemeClr, 'alpha');\n const opacity = alphaNode ? parseInt(this.getAttr(alphaNode, 'val') || '100000') / 100000 : 1;\n return { color: '#000000', opacity }; // Themes usually default to dark if not specified\n }\n return { color: '#000000', opacity: 1 };\n }\n\n private async resolveImage(relId: string, slideIndex: number, zip: JSZip): Promise<Blob | null> {\n const relsXml = await zip.file(`ppt/slides/_rels/slide${slideIndex}.xml.rels`)?.async('string');\n if (!relsXml) return null;\n\n const parser = new DOMParser();\n const relsDoc = parser.parseFromString(relsXml, 'text/xml');\n const relationship = Array.from(relsDoc.getElementsByTagName('Relationship'))\n .find(r => r.getAttribute('Id') === relId);\n\n const target = relationship?.getAttribute('Target');\n if (target) {\n const mediaPath = (target.startsWith('../') ? `ppt/${target.substring(3)}` : `ppt/slides/${target}`).replace('ppt/slides/../', 'ppt/');\n return await zip.file(mediaPath)?.async('blob') || null;\n }\n return null;\n }\n\n private async parseSlide(xml: string, slideIndex: number, zip: JSZip): Promise<Slide> {\n const parser = new DOMParser();\n const doc = parser.parseFromString(xml, 'text/xml');\n const elements: SlideElement[] = [];\n let zIndex = 0;\n\n // Check for Background Image\n const bg = this.findFirstByLocalName(doc, 'bg');\n if (bg) {\n const blip = this.findFirstByLocalName(bg, 'blip');\n const relId = blip?.getAttributeNS('http://schemas.openxmlformats.org/officeDocument/2006/relationships', 'embed') ||\n blip?.getAttribute('r:embed');\n if (relId) {\n const mediaFile = await this.resolveImage(relId, slideIndex, zip);\n if (mediaFile) {\n elements.push({\n id: `bg-${slideIndex}`,\n type: 'image',\n src: URL.createObjectURL(mediaFile),\n x: 0,\n y: 0,\n width: this.CANVAS_WIDTH,\n height: this.CANVAS_HEIGHT,\n zIndex: zIndex++,\n opacity: 1\n });\n }\n }\n }\n\n const spTree = this.findFirstByLocalName(doc, 'spTree');\n if (!spTree) return { id: `slide-${slideIndex}`, elements };\n\n const children = Array.from(spTree.children);\n for (const child of children) {\n const localName = child.localName;\n\n if (localName === 'sp') {\n const txBody = this.findFirstByLocalName(child, 'txBody');\n const nvSpPr = this.findFirstByLocalName(child, 'nvSpPr');\n const nvPr = nvSpPr ? this.findFirstByLocalName(nvSpPr, 'nvPr') : null;\n const ph = nvPr ? this.findFirstByLocalName(nvPr, 'ph') : null;\n const phType = ph ? this.getAttr(ph, 'type') : null;\n const isBodyPlaceholder = ph && (!phType || phType === 'body');\n const xfrm = this.findFirstByLocalName(child, 'xfrm');\n const off = xfrm ? this.findFirstByLocalName(xfrm, 'off') : null;\n const ext = xfrm ? this.findFirstByLocalName(xfrm, 'ext') : null;\n\n if (txBody && off && ext) {\n const paragraphs = this.findAllByLocalName(txBody, 'p');\n let content = '';\n let fontSize = 18;\n let color = '#000000';\n let opacity = 1;\n let isBulleted = false;\n let isNumbered = false;\n\n for (const p of paragraphs) {\n const pPr = this.findFirstByLocalName(p, 'pPr');\n const buNone = pPr ? this.findFirstByLocalName(pPr, 'buNone') : null;\n let paragraphContent = '';\n\n // Parse paragraph properties\n if (pPr && !buNone) {\n if (this.findFirstByLocalName(pPr, 'buAutoNum')) {\n isNumbered = true;\n } else if (this.findFirstByLocalName(pPr, 'buChar')) {\n isBulleted = true;\n } else {\n // Heuristic 1: Hanging indent\n const indent = parseInt(this.getAttr(pPr, 'indent') || '0');\n if (indent < 0) {\n isBulleted = true;\n }\n // Heuristic 2: Body placeholder inheritance\n else if (isBodyPlaceholder) {\n isBulleted = true;\n }\n }\n } else if (!pPr && isBodyPlaceholder) {\n isBulleted = true;\n }\n\n const runs = this.findAllByLocalName(p, 'r');\n for (const r of runs) {\n const t = this.findFirstByLocalName(r, 't');\n if (t) paragraphContent += t.textContent;\n\n const rPr = this.findFirstByLocalName(r, 'rPr');\n if (rPr) {\n const sz = this.getAttr(rPr, 'sz');\n if (sz) fontSize = (parseInt(sz) / 100) * 2;\n const style = this.parseColor(rPr);\n color = style.color;\n opacity = style.opacity;\n }\n }\n\n // Heuristic 3: Baked-in text bullets\n // Check if text starts with a bullet character (•, etc)\n const bulletRegex = /^\\s*([•\\u2022\\u2023\\u25E6\\u2043\\u2219])\\s+/;\n const match = paragraphContent.match(bulletRegex);\n if (match) {\n isBulleted = true;\n // Remove the bullet char and trim leading whitespace\n paragraphContent = paragraphContent.replace(bulletRegex, '');\n }\n\n content += paragraphContent + '\\n';\n }\n\n if (content.trim()) {\n elements.push({\n id: `el-${slideIndex}-${Date.now()}-${zIndex}`,\n type: 'text',\n content: content.trim(),\n x: this.scaleX(parseInt(this.getAttr(off, 'x') || '0')),\n y: this.scaleY(parseInt(this.getAttr(off, 'y') || '0')),\n width: this.scaleX(parseInt(this.getAttr(ext, 'cx') || '0')),\n height: this.scaleY(parseInt(this.getAttr(ext, 'cy') || '0')),\n fontSize,\n color,\n fontFamily: 'Arial',\n zIndex: zIndex++,\n isBulleted,\n isNumbered,\n listType: isNumbered ? 'number-decimal' : (isBulleted ? 'bullet-disc' : 'none'),\n opacity\n });\n continue;\n }\n }\n\n const prstGeom = this.findFirstByLocalName(child, 'prstGeom');\n if (prstGeom && off && ext) {\n const prst = this.getAttr(prstGeom, 'prst') || 'rect';\n const spPr = this.findFirstByLocalName(child, 'spPr');\n const style = spPr ? this.parseColor(spPr) : { color: '#cccccc', opacity: 1 };\n\n // Mapping PPTX preset names to our internal shape types\n const mapping: Record<string, ShapeType> = {\n 'rect': 'rect',\n 'roundRect': 'rect',\n 'ellipse': 'ellipse',\n 'circle': 'ellipse',\n 'triangle': 'triangle',\n 'rtTriangle': 'rightTriangle',\n 'diamond': 'rhombus',\n 'parallelogram': 'parallelogram',\n 'trapezoid': 'trapezoid',\n 'pentagon': 'pentagon',\n 'hexagon': 'hexagon',\n 'heptagon': 'heptagon',\n 'octagon': 'octagon',\n 'heart': 'heart',\n 'smileyFace': 'smiley',\n 'sun': 'sun',\n 'moon': 'moon',\n 'rightArrow': 'arrowRight',\n 'leftArrow': 'arrowLeft',\n 'upArrow': 'arrowUp',\n 'downArrow': 'arrowDown',\n 'leftRightArrow': 'arrowLeftRight',\n 'upDownArrow': 'arrowUpDown',\n 'star4': 'star4',\n 'star5': 'star5',\n 'star6': 'star6',\n 'star8': 'star8',\n 'cloud': 'cloud',\n 'lightningBolt': 'lightning',\n 'plus': 'plus',\n 'minus': 'minus',\n 'multiply': 'multiply',\n 'divide': 'divide',\n 'equal': 'equal'\n };\n\n elements.push({\n id: `el-${slideIndex}-${Date.now()}-${zIndex}`,\n type: 'shape',\n shapeType: (mapping[prst] || 'rect'),\n fill: style.color,\n opacity: style.opacity,\n x: this.scaleX(parseInt(this.getAttr(off, 'x') || '0')),\n y: this.scaleY(parseInt(this.getAttr(off, 'y') || '0')),\n width: this.scaleX(parseInt(this.getAttr(ext, 'cx') || '0')),\n height: this.scaleY(parseInt(this.getAttr(ext, 'cy') || '0')),\n zIndex: zIndex++\n });\n }\n }\n\n if (localName === 'pic') {\n const blip = this.findFirstByLocalName(child, 'blip');\n const relId = blip?.getAttributeNS('http://schemas.openxmlformats.org/officeDocument/2006/relationships', 'embed') ||\n blip?.getAttribute('r:embed');\n\n const xfrm = this.findFirstByLocalName(child, 'xfrm');\n const off = xfrm ? this.findFirstByLocalName(xfrm, 'off') : null;\n const ext = xfrm ? this.findFirstByLocalName(xfrm, 'ext') : null;\n\n if (relId && off && ext) {\n const mediaFile = await this.resolveImage(relId, slideIndex, zip);\n if (mediaFile) {\n elements.push({\n id: `el-${slideIndex}-${Date.now()}-${zIndex}`,\n type: 'image',\n src: URL.createObjectURL(mediaFile),\n x: this.scaleX(parseInt(this.getAttr(off, 'x') || '0')),\n y: this.scaleY(parseInt(this.getAttr(off, 'y') || '0')),\n width: this.scaleX(parseInt(this.getAttr(ext, 'cx') || '0')),\n height: this.scaleY(parseInt(this.getAttr(ext, 'cy') || '0')),\n zIndex: zIndex++,\n opacity: 1\n });\n }\n }\n }\n }\n\n return { id: `slide-${slideIndex}`, elements };\n }\n}\n","'use client';\n\nimport React, { useEffect, useState } from 'react';\nimport { ChevronLeft, ChevronRight, X } from 'lucide-react';\nimport type { Presentation, Slide } from '../lib/types';\nimport { EditorCanvas } from './EditorCanvas';\n\ninterface PresenterModeProps {\n presentation: Presentation;\n initialSlideIndex: number;\n onClose: () => void;\n}\n\nexport const PresenterMode: React.FC<PresenterModeProps> = ({\n presentation,\n initialSlideIndex,\n onClose\n}) => {\n const [currentIndex, setCurrentIndex] = useState(initialSlideIndex);\n const currentSlide = presentation.slides[currentIndex];\n\n const goToPrevious = () => {\n if (currentIndex > 0) setCurrentIndex(currentIndex - 1);\n };\n\n const goToNext = () => {\n if (currentIndex < presentation.slides.length - 1) setCurrentIndex(currentIndex + 1);\n };\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'ArrowRight' || e.key === ' ' || e.key === 'PageDown') {\n goToNext();\n } else if (e.key === 'ArrowLeft' || e.key === 'Backspace' || e.key === 'PageUp') {\n goToPrevious();\n } else if (e.key === 'Escape') {\n onClose();\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [currentIndex]);\n\n const [scale, setScale] = useState(1);\n\n useEffect(() => {\n const updateScale = () => {\n const padding = 40;\n const availableWidth = window.innerWidth - padding;\n const availableHeight = window.innerHeight - padding;\n const slideWidth = 1200;\n const slideHeight = 675;\n\n const scaleX = availableWidth / slideWidth;\n const scaleY = availableHeight / slideHeight;\n const newScale = Math.min(scaleX, scaleY);\n setScale(newScale);\n };\n\n updateScale();\n window.addEventListener('resize', updateScale);\n return () => window.removeEventListener('resize', updateScale);\n }, []);\n\n return (\n <div className=\"fixed inset-0 z-[99999] bg-[#0A0A0A] flex flex-col items-center justify-center overflow-hidden\">\n {/* Header / Controls */}\n <div className=\"absolute top-0 left-0 right-0 p-6 flex justify-between items-center opacity-0 hover:opacity-100 transition-opacity bg-gradient-to-b from-black/60 to-transparent z-[100] pointer-events-none\">\n <div className=\"text-white/80 font-bold ml-4 pointer-events-auto\">\n Slide {currentIndex + 1} of {presentation.slides.length}\n </div>\n <button\n onClick={onClose}\n className=\"p-3 bg-white/10 hover:bg-white/20 text-white rounded-full transition-all pointer-events-auto\"\n >\n <X size={24} />\n </button>\n </div>\n\n {/* Slide Container */}\n <div className=\"w-full h-full flex items-center justify-center\">\n <div\n className=\"relative shadow-2xl shadow-black/80 bg-white\"\n style={{\n width: '1200px',\n height: '675px',\n transform: `scale(${scale})`,\n transformOrigin: 'center center'\n }}\n >\n <EditorCanvas\n slide={currentSlide}\n onElementUpdate={() => { }} // No editing in presenter mode\n onSelect={() => { }} // No selection in presenter mode\n uiScale={0.75} // Base width of 1200px / 1600px\n onSlashCommand={() => { }} // No slash commands in presenter mode\n selectedElementId={null}\n onAiGenerateClick={() => { }}\n onAiGenerateInfographicClick={() => { }}\n onUploadImageClick={() => { }}\n onDeleteElement={() => { }}\n />\n </div>\n </div>\n\n {/* Navigation Controls */}\n <div className=\"absolute bottom-10 left-1/2 -translate-x-1/2 flex items-center gap-6 opacity-0 hover:opacity-100 transition-opacity bg-black/40 backdrop-blur-md px-6 py-3 rounded-full border border-white/10 pointer-events-auto\">\n <button\n disabled={currentIndex === 0}\n onClick={goToPrevious}\n className=\"p-2 text-white/50 hover:text-white disabled:opacity-20 transition-colors\"\n >\n <ChevronLeft size={32} />\n </button>\n <div className=\"h-6 w-[1px] bg-white/10\" />\n <button\n disabled={currentIndex === presentation.slides.length - 1}\n onClick={goToNext}\n className=\"p-2 text-white/50 hover:text-white disabled:opacity-20 transition-colors\"\n >\n <ChevronRight size={32} />\n </button>\n </div>\n </div>\n );\n};\n","\nimport React from 'react';\nimport { Check, ArrowRightFromLine, RefreshCw, Trash2, Sparkles, X } from 'lucide-react';\nimport { cn } from '../lib/utils';\n\ninterface RefineMenuProps {\n result: string;\n isLoading: boolean;\n onAction: (action: 'replace' | 'addBelow' | 'discard' | 'regenerate') => void;\n onClose: () => void;\n position?: { x: number; y: number }; // Made optional, as we default to center\n}\n\nexport const RefineMenu: React.FC<RefineMenuProps> = ({ result, isLoading, onAction, onClose, position }) => {\n return (\n <div\n className=\"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[2000] w-80 bg-white border border-slate-200 rounded-xl shadow-2xl animate-in fade-in zoom-in-95 duration-200 overflow-hidden text-left\"\n // We ignore custom position for now to ensure it's always visible/centered (responsive behavior requested)\n >\n <div className=\"px-3 py-2.5 bg-blue-50/50 border-b border-blue-100 flex items-center justify-between\">\n <span className=\"text-xs font-bold text-blue-700 uppercase tracking-wider flex items-center gap-2\">\n <Sparkles size={12} />\n Refined Text\n </span>\n <button onClick={onClose} className=\"text-slate-400 hover:text-slate-600\">\n <X size={14} />\n </button>\n </div>\n\n {isLoading ? (\n <div className=\"p-8 flex flex-col items-center justify-center gap-3 text-slate-400\">\n <RefreshCw size={24} className=\"animate-spin text-blue-500\" />\n <span className=\"text-xs font-medium\">Refining text...</span>\n </div>\n ) : (\n <div className=\"flex flex-col\">\n <div className=\"p-4 bg-slate-50/50 max-h-[300px] overflow-y-auto text-sm text-slate-700 leading-relaxed border-b border-slate-100\">\n {result}\n </div>\n <div className=\"p-1.5 flex flex-col gap-0.5\">\n <button\n onClick={() => onAction('replace')}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <Check size={14} className=\"text-slate-400\" />\n <span>Replace selection</span>\n </button>\n <button\n onClick={() => onAction('addBelow')}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <ArrowRightFromLine size={14} className=\"text-slate-400 rotate-90\" />\n <span>Insert below</span>\n </button>\n <button\n onClick={() => onAction('regenerate')}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-blue-600 hover:bg-blue-50 rounded-lg transition-colors text-left\"\n >\n <RefreshCw size={14} />\n <span>Try again</span>\n </button>\n <div className=\"h-[1px] bg-slate-100 my-1\" />\n <button\n onClick={() => onAction('discard')}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-red-600 hover:bg-red-50 rounded-lg transition-colors text-left\"\n >\n <Trash2 size={14} />\n <span>Discard</span>\n </button>\n </div>\n </div>\n )}\n </div>\n );\n};\n","import React, { useState, useEffect, useRef, useMemo } from 'react';\nimport {\n Type, Square, Circle, Image as ImageIcon, Sparkles,\n PlusCircle, Triangle, Star, Hexagon, ArrowRight,\n Search, Wand2, Type as FontIcon, Layout,\n Bold, Italic, Underline, AlignLeft, AlignCenter, AlignRight, AlignJustify,\n List, ListOrdered, Palette, Trash2, ArrowBigUp, ArrowBigDown,\n ChevronRight, CaseSensitive, MessageSquare, Highlighter, Eraser, ChevronDown, ALargeSmall, ChevronUp, PieChart,\n RefreshCw, Check, ArrowRightFromLine, MoveDown, SpellCheck\n} from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport { ShapeType } from '../lib/types';\n\ninterface SlashMenuItem {\n id: string;\n label: string;\n icon: React.ElementType;\n category: 'Basic' | 'Shapes' | 'AI' | 'Canvas' | 'Formatting' | 'Alignment' | 'List' | 'Actions';\n description?: string;\n action: () => void;\n currentValue?: any;\n}\n\ninterface SlashMenuProps {\n onClose: () => void;\n onAction: (actionId: string, payload?: any) => void;\n position: { x: number; y: number };\n canUseAi: boolean;\n mode?: 'default' | 'textbox' | 'text-selection';\n context?: {\n fontFamily?: string;\n fontSize?: number;\n isBold?: boolean;\n isItalic?: boolean;\n isUnderline?: boolean;\n isBulleted?: boolean;\n isNumbered?: boolean;\n textAlign?: 'left' | 'center' | 'right' | 'justify';\n color?: string;\n highlightColor?: string;\n };\n aiResult?: string | null;\n isAiLoading?: boolean;\n onAiResponseAction?: (action: 'replace' | 'addBelow' | 'discard' | 'regenerate') => void;\n}\n\nconst FONTS = [\n 'Inter', 'Arial', 'Lato', 'Open Sans', 'Poppins', 'Roboto', 'Georgia', 'Times New Roman'\n];\n\nconst FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 64, 72, 96];\n\nexport const SlashMenu: React.FC<SlashMenuProps> = ({ onClose, onAction, position, canUseAi, mode = 'default', context, aiResult, isAiLoading, onAiResponseAction }) => {\n const [search, setSearch] = useState('');\n const [selectedIndex, setSelectedIndex] = useState(0);\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n const [showFontDropdown, setShowFontDropdown] = useState(false);\n const [showSizeDropdown, setShowSizeDropdown] = useState(false);\n\n const [showBulletMenu, setShowBulletMenu] = useState(false);\n const [showNumberingMenu, setShowNumberingMenu] = useState(false);\n const [showAiMenu, setShowAiMenu] = useState(false);\n\n // Default vertical menu items\n const defaultItems = useMemo(() => [\n { id: 'generate-image', label: 'AI Generate Image', icon: Sparkles, category: 'AI', description: 'Create an image with AI prompt', action: () => onAction('generate-image') },\n { id: 'generate-infographic', label: 'AI Generate Infographic', icon: PieChart, category: 'AI', description: 'Create an infographic with AI prompt', action: () => onAction('generate-infographic') },\n { id: 'text', label: 'Text Box', icon: Type, category: 'Basic', description: 'Insert a new text element', action: () => onAction('add-text') },\n { id: 'image', label: 'Image', icon: ImageIcon, category: 'Basic', description: 'Upload and insert an image', action: () => onAction('add-image') },\n { id: 'new-slide', label: 'New Slide', icon: PlusCircle, category: 'Canvas', description: 'Add a fresh slide to deck', action: () => onAction('new-slide') },\n { id: 'rect', label: 'Rectangle', icon: Square, category: 'Shapes', action: () => onAction('add-shape', 'rect') },\n { id: 'circle', label: 'Circle', icon: Circle, category: 'Shapes', action: () => onAction('add-shape', 'circle') },\n { id: 'triangle', label: 'Triangle', icon: Triangle, category: 'Shapes', action: () => onAction('add-shape', 'triangle') },\n { id: 'star5', label: 'Star', icon: Star, category: 'Shapes', action: () => onAction('add-shape', 'star5') },\n { id: 'arrowRight', label: 'Arrow', icon: ArrowRight, category: 'Shapes', action: () => onAction('add-shape', 'arrowRight') },\n ], [onAction]);\n\n const filteredItems = useMemo(() => {\n return defaultItems.filter(item =>\n item.label.toLowerCase().includes(search.toLowerCase()) ||\n item.category.toLowerCase().includes(search.toLowerCase())\n );\n }, [defaultItems, search]);\n\n useEffect(() => {\n setSelectedIndex(0);\n }, [search]);\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (mode === 'default') {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setSelectedIndex(prev => (prev + 1) % filteredItems.length);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setSelectedIndex(prev => (prev - 1 + filteredItems.length) % filteredItems.length);\n } else if (e.key === 'Enter') {\n e.preventDefault();\n if (filteredItems[selectedIndex]) {\n filteredItems[selectedIndex].action();\n }\n }\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n onClose();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [filteredItems, selectedIndex, onClose, mode]);\n\n // Ensure selected item is visible in scroll container (only for default mode)\n useEffect(() => {\n if (mode === 'default' && scrollContainerRef.current) {\n const selectedElement = scrollContainerRef.current.children[selectedIndex] as HTMLElement;\n if (selectedElement) {\n selectedElement.scrollIntoView({ block: 'nearest' });\n }\n }\n }, [selectedIndex, mode]);\n\n if (mode === 'default' && filteredItems.length === 0 && search === '') return null;\n\n // Redesign for horizontal toolbar (PowerPoint style)\n if (mode === 'textbox' || mode === 'text-selection') {\n const activeFont = context?.fontFamily || 'Arial';\n const activeSize = context?.fontSize || 24;\n\n // Dynamic positioning ref\n const menuRef = useRef<HTMLDivElement>(null);\n const [adjustedPosition, setAdjustedPosition] = useState<{ x: number, y: number } | null>(null);\n\n React.useLayoutEffect(() => {\n if (menuRef.current) {\n const rect = menuRef.current.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n let x = position.x;\n let y = position.y;\n\n // Check horizontal overflow\n if (x + rect.width > viewportWidth - 100) {\n x = viewportWidth - rect.width - 100;\n }\n x = Math.max(10, x); // Keep at least 10px from left\n\n // Check vertical overflow\n if (y + rect.height > viewportHeight - 20) {\n y = viewportHeight - rect.height - 20; // Flip up or push up\n }\n\n setAdjustedPosition({ x, y });\n }\n }, [position.x, position.y]); // Re-run when target position changes\n\n // Use adjusted position if available, otherwise hide initially (opacity 0) to prevent flash\n const stylePosition = adjustedPosition || { x: position.x, y: position.y };\n const opacity = adjustedPosition ? 1 : 0;\n\n // Determine if dropdown should open upwards\n const openUpwards = stylePosition.y > window.innerHeight / 2;\n\n return (\n <div\n ref={menuRef}\n className=\"fixed z-[9999] bg-white rounded-xl shadow-[0_20px_50px_rgba(0,0,0,0.15)] border border-slate-200 p-2.5 flex flex-col gap-2.5 animate-in fade-in zoom-in-95 duration-200\"\n style={{\n left: `${stylePosition.x}px`,\n top: `${stylePosition.y}px`,\n width: 'auto',\n minWidth: '440px',\n maxWidth: '90vw',\n opacity: opacity\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Row 1: Font Selectors and Alignment */}\n <div className=\"flex items-center gap-1.5 h-9\">\n <div className=\"flex items-center bg-slate-50 border border-slate-200 rounded-lg h-full flex-1 shadow-sm\">\n <div className=\"relative flex-1\">\n <button\n onClick={() => { setShowFontDropdown(!showFontDropdown); setShowSizeDropdown(false); }}\n className=\"w-full flex items-center justify-between px-3 h-full text-xs font-bold text-slate-800 hover:bg-white transition-colors border-r border-slate-100 rounded-l-lg\"\n >\n <span className=\"truncate\">{activeFont}</span>\n <ChevronDown size={14} className=\"text-slate-400\" />\n </button>\n {showFontDropdown && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-2xl z-50 py-1 min-w-[180px] max-h-[250px] overflow-y-auto animate-in fade-in slide-in-from-top-2\">\n {FONTS.map(font => (\n <button\n key={font}\n onClick={() => { onAction('format', { fontFamily: font }); setShowFontDropdown(false); }}\n className={cn(\n \"w-full text-left px-4 py-2 text-xs hover:bg-blue-50 transition-colors\",\n activeFont === font ? \"text-blue-600 font-bold bg-blue-100/50\" : \"text-slate-700\"\n )}\n style={{ fontFamily: font }}\n >\n {font}\n </button>\n ))}\n </div>\n )}\n </div>\n\n <div className=\"relative w-16\">\n <button\n onClick={() => { setShowSizeDropdown(!showSizeDropdown); setShowFontDropdown(false); }}\n className=\"w-full flex items-center justify-between px-2 h-full text-xs font-black text-slate-900 hover:bg-white transition-colors rounded-r-lg\"\n >\n <span>{activeSize}</span>\n <ChevronDown size={14} className=\"text-slate-400\" />\n </button>\n {showSizeDropdown && (\n <div className=\"absolute top-full right-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-2xl z-50 py-1 min-w-[80px] max-h-[250px] overflow-y-auto animate-in fade-in slide-in-from-top-2\">\n {FONT_SIZES.map(size => (\n <button\n key={size}\n onClick={() => { onAction('format', { fontSize: size }); setShowSizeDropdown(false); }}\n className={cn(\n \"w-full text-center px-4 py-2 text-xs hover:bg-blue-50 transition-colors\",\n activeSize === size ? \"text-blue-600 font-bold bg-blue-100/50\" : \"text-slate-700\"\n )}\n >\n {size}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n <div className=\"flex items-center gap-1 px-1 bg-slate-50 border border-slate-200 rounded-lg h-full shadow-sm\">\n <button onClick={() => onAction('format', { fontSize: activeSize + 2 })} className=\"p-1 hover:bg-white hover:text-blue-600 rounded-md text-slate-500 transition-all active:scale-95 flex items-center justify-center\" title=\"Increase font size\">\n <span className=\"text-[13px] font-black leading-none translate-y-[1px]\">A</span>\n <ChevronUp size={10} strokeWidth={4} className=\"ml-0.5\" />\n </button>\n <button onClick={() => onAction('format', { fontSize: Math.max(1, activeSize - 2) })} className=\"p-1 hover:bg-white hover:text-blue-600 rounded-md text-slate-500 transition-all active:scale-95 flex items-center justify-center\" title=\"Decrease font size\">\n <span className=\"text-[11px] font-black leading-none translate-y-[1px]\">A</span>\n <ChevronDown size={10} strokeWidth={4} className=\"ml-0.5\" />\n </button>\n </div>\n\n\n </div>\n\n {/* Row 2: Tool Icons */}\n <div className=\"flex items-center gap-0.5 border-t border-slate-100 pt-2.5 flex-nowrap\">\n <button\n onClick={() => onAction('format', { isBold: !context?.isBold })}\n className={cn(\"p-1.5 rounded-md transition-all\", context?.isBold ? \"text-blue-600 bg-blue-50 shadow-sm\" : \"text-slate-200 hover:bg-slate-50 hover:text-slate-500\")}\n title=\"Bold\"\n >\n <Bold size={18} strokeWidth={2} />\n </button>\n <button\n onClick={() => onAction('format', { isItalic: !context?.isItalic })}\n className={cn(\"p-1.5 rounded-md transition-all\", context?.isItalic ? \"text-blue-600 bg-blue-50 shadow-sm\" : \"text-slate-200 hover:bg-slate-50 hover:text-slate-500\")}\n title=\"Italic\"\n >\n <Italic size={18} strokeWidth={2} />\n </button>\n <button\n onClick={() => onAction('format', { isUnderline: !context?.isUnderline })}\n className={cn(\"p-1.5 rounded-md transition-all\", context?.isUnderline ? \"text-blue-600 bg-blue-50 shadow-sm\" : \"text-slate-200 hover:bg-slate-50 hover:text-slate-500\")}\n title=\"Underline\"\n >\n <Underline size={18} strokeWidth={2} />\n </button>\n\n <div className=\"w-[1px] h-4 bg-slate-100 mx-1.5\" />\n\n {/* Ask AI - Dropdown */}\n <div className=\"relative\">\n <button\n onClick={() => setShowAiMenu(!showAiMenu)}\n className={cn(\n \"flex items-center gap-1.5 px-2 py-1 rounded-md transition-all text-sm font-bold whitespace-nowrap\",\n showAiMenu\n ? \"bg-purple-50 text-purple-600 ring-1 ring-purple-100\"\n : \"text-slate-500 hover:bg-purple-50 hover:text-purple-600\"\n )}\n >\n <Sparkles size={14} className={showAiMenu ? \"fill-purple-300\" : \"\"} />\n <span>Ask AI</span>\n <ChevronDown size={12} className=\"opacity-50\" />\n </button>\n\n {showAiMenu && (\n <div className={cn(\n \"absolute left-0 w-80 bg-white border border-slate-200 rounded-xl shadow-2xl z-[1000] animate-in fade-in zoom-in-95 duration-200 overflow-hidden text-left flex flex-col max-h-[300px]\",\n openUpwards ? \"bottom-full mb-2 origin-bottom-left\" : \"top-full mt-2 origin-top-left\"\n )}>\n <div className=\"px-3 py-2.5 bg-purple-50/50 border-b border-purple-100 flex items-center justify-between\">\n <span className=\"text-xs font-bold text-purple-700 uppercase tracking-wider flex items-center gap-2\">\n <Sparkles size={12} />\n Ask AI\n </span>\n </div>\n\n {isAiLoading ? (\n <div className=\"p-8 flex flex-col items-center justify-center gap-3 text-slate-400\">\n <RefreshCw size={24} className=\"animate-spin text-purple-500\" />\n <span className=\"text-xs font-medium\">AI is thinking...</span>\n </div>\n ) : aiResult ? (\n <div className=\"flex flex-col overflow-y-auto max-h-[200px]\">\n <div className=\"p-4 bg-slate-50/50 text-sm text-slate-700 leading-relaxed border-b border-slate-100\">\n {aiResult}\n </div>\n <div className=\"p-1.5 flex flex-col gap-0.5\">\n <button\n onClick={() => { onAiResponseAction?.('replace'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-1 py-1 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <Check size={14} className=\"text-slate-400\" />\n <span>Replace selection</span>\n </button>\n <button\n onClick={() => { onAiResponseAction?.('addBelow'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <ArrowRightFromLine size={14} className=\"text-slate-400 rotate-90\" />\n <span>Insert below</span>\n </button>\n <button\n onClick={() => { onAiResponseAction?.('regenerate'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-blue-600 hover:bg-blue-50 rounded-lg transition-colors text-left\"\n >\n <RefreshCw size={14} />\n <span>Try again</span>\n </button>\n <div className=\"h-[1px] bg-slate-100 my-1\" />\n <button\n onClick={() => { onAiResponseAction?.('discard'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-red-600 hover:bg-red-50 rounded-lg transition-colors text-left\"\n >\n <Trash2 size={14} />\n <span>Discard</span>\n </button>\n </div>\n </div>\n ) : (\n <div className=\"p-1.5 flex flex-col gap-0.5 overflow-y-auto max-h-[200px]\">\n <div className=\"px-2 py-1 text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1\">Edit Selection</div>\n <button\n onClick={() => { onAction('ai-text-edit', 'rewrite'); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <RefreshCw size={14} className=\"text-blue-500\" />\n <span>Improve writing</span>\n </button>\n <button\n onClick={() => { onAction('ai-text-edit', 'grammar'); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <SpellCheck size={14} className=\"text-green-500\" />\n <span>Fix grammar</span>\n </button>\n <button\n onClick={() => { onAction('ai-text-edit', 'shorten'); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <ALargeSmall size={14} className=\"text-orange-500\" />\n <span>Make shorter</span>\n </button>\n <button\n onClick={() => { onAction('ai-text-edit', 'lengthen'); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <ArrowRightFromLine size={14} className=\"text-purple-500\" />\n <span>Make longer</span>\n </button>\n\n <div className=\"h-[1px] bg-slate-100 my-1\" />\n\n <div className=\"px-2 py-1 text-[10px] font-bold text-slate-400 uppercase tracking-widest\">Generate</div>\n <button\n onClick={() => { onAction('generate-image'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <ImageIcon size={14} className=\"text-pink-500\" />\n <span>Generate Image</span>\n </button>\n <button\n onClick={() => { onAction('generate-infographic'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <PieChart size={14} className=\"text-indigo-500\" />\n <span>Generate Infographic</span>\n </button>\n\n <div className=\"h-[1px] bg-slate-100 my-1\" />\n\n <div className=\"px-2 py-1 text-[10px] font-bold text-slate-400 uppercase tracking-widest\">More</div>\n <button\n onClick={() => { onAction('ai-text-edit', 'continue'); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <MoveDown size={14} className=\"text-teal-500\" />\n <span>Continue writing</span>\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n <div className=\"w-[1px] h-4 bg-slate-100 mx-1.5\" />\n\n {/* Bullet List Split Button */}\n <div className=\"relative flex items-center rounded-md transition-all\">\n <button\n onClick={() => onAction('format', { isBulleted: !context?.isBulleted, isNumbered: false, listType: !context?.isBulleted ? 'bullet-disc' : 'none' })}\n className={cn(\"p-1.5 rounded-l-md transition-all\", context?.isBulleted ? \"text-blue-600 bg-blue-50\" : \"text-slate-500 hover:bg-slate-50\")} title=\"Bullets\"\n >\n <List size={18} strokeWidth={2.5} />\n </button>\n <button\n onClick={() => setShowBulletMenu(!showBulletMenu)}\n className={cn(\"p-0.5 rounded-r-md border-l border-transparent hover:border-slate-200 transition-all\", showBulletMenu ? \"bg-slate-100\" : \"hover:bg-slate-50\")}\n >\n <ChevronDown size={10} className=\"text-slate-400\" />\n </button>\n {showBulletMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl p-2 z-[100] animate-in fade-in zoom-in-95 duration-150 w-64 grid grid-cols-4 gap-2\">\n <button onClick={() => { onAction('format', { isBulleted: false, listType: 'none' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1\">\n <span className=\"text-[10px] text-slate-500\">None</span>\n </button>\n <button onClick={() => { onAction('format', { isBulleted: true, isNumbered: false, listType: 'bullet-disc' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n <button onClick={() => { onAction('format', { isBulleted: true, isNumbered: false, listType: 'bullet-circle' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n <button onClick={() => { onAction('format', { isBulleted: true, isNumbered: false, listType: 'bullet-square' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n <button onClick={() => { onAction('format', { isBulleted: true, isNumbered: false, listType: 'bullet-check' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">✓</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">✓</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n </div>\n )}\n </div>\n\n {/* Numbered List Split Button */}\n <div className=\"relative text-black flex items-center rounded-md transition-all\">\n <button\n onClick={() => onAction('format', { isNumbered: !context?.isNumbered, isBulleted: false, listType: !context?.isNumbered ? 'number-decimal' : 'none' })}\n className={cn(\"p-1.5 rounded-l-md transition-all\", context?.isNumbered ? \"text-blue-600 bg-blue-50\" : \"text-slate-500 hover:bg-slate-50\")} title=\"Numbering\"\n >\n <ListOrdered size={18} strokeWidth={2.5} />\n </button>\n <button\n onClick={() => setShowNumberingMenu(!showNumberingMenu)}\n className={cn(\"p-0.5 rounded-r-md border-l border-transparent hover:border-slate-200 transition-all\", showNumberingMenu ? \"bg-slate-100\" : \"hover:bg-slate-50\")}\n >\n <ChevronDown size={10} className=\"text-slate-400\" />\n </button>\n {showNumberingMenu && (\n <div className=\"absolute text-black top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl p-2 z-[100] animate-in fade-in zoom-in-95 duration-150 w-64 grid grid-cols-4 gap-2\">\n <button onClick={() => { onAction('format', { isNumbered: false, listType: 'none' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1\">\n <span className=\"text-[10px] text-slate-500\">None</span>\n </button>\n <button onClick={() => { onAction('format', { isNumbered: true, isBulleted: false, listType: 'number-decimal' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">1.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">2.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n <button onClick={() => { onAction('format', { isNumbered: true, isBulleted: false, listType: 'number-decimal-paren' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">1)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">2)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n <button onClick={() => { onAction('format', { isNumbered: true, isBulleted: false, listType: 'number-roman-lower' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">i.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">ii.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n </div>\n )}\n </div>\n\n <div className=\"w-[1px] h-4 bg-slate-100 mx-1.5\" />\n\n <div className=\"relative flex items-center\">\n <button\n className=\"w-7 h-[22px] flex flex-col items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all relative\"\n title=\"Font Color\"\n >\n <span className=\"text-[13px] font-black text-slate-800 leading-none\">A</span>\n <div className=\"w-4 h-[2.5px] rounded-sm mt-0.5\" style={{ backgroundColor: context?.color || '#000000' }} />\n <input\n type=\"color\"\n className=\"absolute inset-0 opacity-0 cursor-pointer w-full h-full\"\n value={context?.color || '#000000'}\n onChange={(e) => onAction('format', { color: e.target.value })}\n />\n </button>\n <ChevronDown size={8} className=\"text-slate-400 -ml-0.5\" />\n </div>\n\n <div className=\"relative flex items-center\">\n <button\n className=\"w-7 h-[22px] flex flex-col items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all relative\"\n title=\"Highlight Color\"\n >\n <Highlighter size={14} strokeWidth={2.5} className={context?.highlightColor ? \"text-slate-900\" : \"text-slate-500\"} />\n <div className=\"w-4 h-[2.5px] rounded-sm mt-0.5\" style={{ backgroundColor: context?.highlightColor || 'transparent' }} />\n <input\n type=\"color\"\n className=\"absolute inset-0 opacity-0 cursor-pointer w-full h-full\"\n value={context?.highlightColor || '#ffff00'}\n onChange={(e) => onAction('format', { highlightColor: e.target.value })}\n />\n </button>\n <ChevronDown size={8} className=\"text-slate-400 -ml-0.5\" />\n </div>\n\n <button\n onClick={() => onAction('format', { isBold: false, isItalic: false, isUnderline: false, highlightColor: '', color: '#000000' })}\n className=\"p-1.5 rounded-md text-slate-400 hover:bg-slate-50 hover:text-slate-600 transition-all\"\n title=\"Clear Formatting\"\n >\n <Eraser size={18} strokeWidth={2.5} />\n </button>\n\n {/* Alignment 2x2 Grid */}\n <div className=\"gap-0.5 ml-auto\">\n <button onClick={() => onAction('format', { textAlign: 'left' })} className={cn(\"p-1 rounded-[3px] transition-all\", context?.textAlign === 'left' ? \"bg-blue-100 text-blue-600\" : \"hover:bg-slate-100 text-slate-500\")}><AlignLeft size={12} strokeWidth={2.5} /></button>\n <button onClick={() => onAction('format', { textAlign: 'center' })} className={cn(\"p-1 rounded-[3px] transition-all\", context?.textAlign === 'center' ? \"bg-blue-100 text-blue-600\" : \"hover:bg-slate-100 text-slate-500\")}><AlignCenter size={12} strokeWidth={2.5} /></button>\n <button onClick={() => onAction('format', { textAlign: 'right' })} className={cn(\"p-1 rounded-[3px] transition-all\", context?.textAlign === 'right' ? \"bg-blue-100 text-blue-600\" : \"hover:bg-slate-100 text-slate-500\")}><AlignRight size={12} strokeWidth={2.5} /></button>\n <button onClick={() => onAction('format', { textAlign: 'justify' })} className={cn(\"p-1 rounded-[3px] transition-all\", context?.textAlign === 'justify' ? \"bg-blue-100 text-blue-600\" : \"hover:bg-slate-100 text-slate-500\")}><AlignJustify size={12} strokeWidth={2.5} /></button>\n </div>\n\n {/* <div className=\"ml-auto flex items-center gap-1\">\n <button\n onClick={onClose}\n className=\"p-1.5 hover:bg-slate-100 text-slate-400 rounded-md transition-colors\"\n >\n <ChevronRight size={18} />\n </button>\n </div> */}\n </div>\n </div>\n );\n }\n\n const safeXVertical = Math.max(10, Math.min(position.x, window.innerWidth - 300));\n const safeYVertical = Math.max(10, Math.min(position.y, window.innerHeight - 450));\n\n return (\n <div\n className=\"fixed z-[9999] w-72 bg-white rounded-xl shadow-2xl border border-slate-200 overflow-hidden flex flex-col animate-in fade-in zoom-in duration-200\"\n style={{\n left: `${safeXVertical}px`,\n top: `${safeYVertical}px`,\n maxHeight: '400px'\n }}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"p-3 border-b border-slate-100 flex items-center gap-2 bg-slate-50/50\">\n <Search size={14} className=\"text-slate-400\" />\n <input\n autoFocus\n type=\"text\"\n placeholder=\"Type a command...\"\n className=\"bg-transparent border-none outline-none text-sm w-full font-medium text-slate-700 placeholder:text-slate-400\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n\n <div\n ref={scrollContainerRef}\n className=\"overflow-y-auto py-2 px-1 custom-scrollbar\"\n >\n {filteredItems.length > 0 ? (\n filteredItems.map((item, index) => {\n const isSelected = index === selectedIndex;\n const showsCategory = index === 0 || filteredItems[index - 1].category !== item.category;\n\n return (\n <React.Fragment key={item.id}>\n {showsCategory && (\n <div className=\"px-3 py-1.5 text-[10px] uppercase tracking-wider font-bold text-slate-400\">\n {item.category}\n </div>\n )}\n <button\n className={cn(\n \"w-full flex items-center gap-3 px-3 py-2 text-left transition-all duration-150 rounded-lg group\",\n isSelected ? \"bg-slate-100\" : \"hover:bg-slate-50\"\n )}\n onClick={() => item.action()}\n onMouseEnter={() => setSelectedIndex(index)}\n >\n <div className={cn(\n \"p-1.5 rounded-md transition-colors flex items-center justify-center relative\",\n isSelected ? \"bg-white shadow-sm text-blue-600\" : \"bg-slate-100 text-slate-500 group-hover:text-slate-700\"\n )}>\n <item.icon size={16} />\n </div>\n <div className=\"flex flex-col min-w-0\">\n <span className={cn(\n \"text-sm font-semibold truncate\",\n isSelected ? \"text-slate-900\" : \"text-slate-700\"\n )}>\n {item.label}\n </span>\n {item.description && (\n <span className=\"text-[11px] text-slate-400 truncate leading-tight\">\n {item.description}\n </span>\n )}\n </div>\n {isSelected && (\n <div className=\"ml-auto text-[10px] font-mono font-bold text-slate-400 flex items-center gap-1 border border-slate-200 rounded px-1 bg-white\">\n <span>↵</span>\n </div>\n )}\n </button>\n </React.Fragment>\n );\n })\n ) : (\n <div className=\"px-3 py-8 text-center flex flex-col items-center gap-2\">\n <div className=\"p-3 bg-slate-50 rounded-full\">\n <Search size={20} className=\"text-slate-300\" />\n </div>\n <span className=\"text-sm text-slate-400 font-medium whitespace-nowrap\">No commands found for \"{search}\"</span>\n </div>\n )}\n </div>\n\n <div className=\"px-3 py-2 border-t border-slate-100 bg-slate-50/50 flex items-center justify-between\">\n <div className=\"flex items-center gap-1 text-[10px] font-medium text-slate-400\">\n <span className=\"border border-slate-200 rounded px-1 bg-white\">↑↓</span>\n <span>to navigate</span>\n </div>\n <div className=\"flex items-center gap-1 text-[10px] font-medium text-slate-400\">\n <span className=\"border border-slate-200 rounded px-1 bg-white\">Esc</span>\n <span>to close</span>\n </div>\n </div>\n </div>\n );\n};\n","import React, { useEffect } from 'react';\nimport { X, AlertCircle, CheckCircle, Info } from 'lucide-react';\nimport { cn } from '../lib/utils';\n\nexport type SnackbarType = 'error' | 'success' | 'info';\n\ninterface SnackbarProps {\n message: string;\n type?: SnackbarType;\n isOpen: boolean;\n onClose: () => void;\n autoHideDuration?: number;\n}\n\nexport const Snackbar: React.FC<SnackbarProps> = ({\n message,\n type = 'info',\n isOpen,\n onClose,\n autoHideDuration = 4000\n}) => {\n useEffect(() => {\n if (isOpen && autoHideDuration > 0) {\n const timer = setTimeout(() => {\n onClose();\n }, autoHideDuration);\n return () => clearTimeout(timer);\n }\n }, [isOpen, autoHideDuration, onClose]);\n\n if (!isOpen) return null;\n\n const icons = {\n error: <AlertCircle size={20} className=\"text-white\" />,\n success: <CheckCircle size={20} className=\"text-white\" />,\n info: <Info size={20} className=\"text-white\" />\n };\n\n const bgColors = {\n error: 'bg-red-500',\n success: 'bg-emerald-500',\n info: 'bg-slate-800'\n };\n\n return (\n <div className={cn(\n \"fixed bottom-6 right-6 z-[10000] flex items-center gap-3 px-4 py-2 rounded-md shadow-lg animate-in fade-in slide-in-from-bottom-2 duration-300 min-w-[280px] max-w-[400px]\",\n bgColors[type]\n )}>\n {icons[type]}\n <span className=\"text-white text-sm font-medium flex-1\">{message}</span>\n <button\n onClick={onClose}\n className=\"p-1 hover:bg-white/20 rounded-full transition-colors ml-1\"\n >\n <X size={14} className=\"text-white\" />\n </button>\n </div>\n );\n};\n","import pptxgen from 'pptxgenjs';\nimport type { Presentation } from './types';\n\n/**\n * A standalone service to convert a Presentation object into a .pptx Blob.\n * Use this for background processing, S3 uploads, or other non-UI tasks.\n * \n * This replicates the logic from PptxExporter but returns a Blob instead of\n * triggering a browser download.\n */\nexport class PptxBlobExporter {\n /**\n * Converts a Presentation object into a .pptx Blob.\n * @param presentation The presentation data to export.\n * @returns A Promise that resolves to a Blob containing the .pptx file.\n */\n async exportToBlob(presentation: Presentation): Promise<Blob> {\n const pptx = new pptxgen();\n\n const emuWidth = presentation.layout?.width || 12192000;\n const emuHeight = presentation.layout?.height || 6858000;\n const canvasWidth = 1200;\n const canvasHeight = 675;\n\n const getInchesX = (px: number) => (px / canvasWidth) * (emuWidth / 914400);\n const getInchesY = (px: number) => (px / canvasHeight) * (emuHeight / 914400);\n\n presentation.slides.forEach(slide => {\n const pptxSlide = pptx.addSlide();\n\n // Sort by zIndex for export layering\n const sortedElements = [...slide.elements].sort((a, b) => a.zIndex - b.zIndex);\n\n sortedElements.forEach(el => {\n const transparency = el.opacity !== undefined ? (1 - el.opacity) * 100 : 0;\n const common = {\n x: getInchesX(el.x),\n y: getInchesY(el.y),\n w: getInchesX(el.width),\n h: getInchesY(el.height),\n };\n\n if (el.type === 'text') {\n pptxSlide.addText(el.content, {\n ...common,\n fontSize: (el.fontSize || 18) / 2, // Halve for export to match canvas scale\n color: el.color?.replace('#', '') || '000000',\n fontFace: el.fontFamily || 'Arial'\n });\n } else if (el.type === 'image') {\n pptxSlide.addImage({\n ...common,\n path: el.src,\n transparency: transparency\n });\n } else if (el.type === 'shape') {\n // Map basic shapes to pptxgen types\n const shapeType = el.shapeType === 'ellipse' ? pptx.ShapeType.ellipse : pptx.ShapeType.rect;\n pptxSlide.addShape(shapeType, {\n ...common,\n fill: {\n color: el.fill?.replace('#', '') || 'CCCCCC',\n transparency: transparency > 0 ? Math.min(transparency + 10, 100) : 0\n }\n });\n }\n });\n });\n\n // Generate the blob using 'blob' output type\n const output = await pptx.write({ outputType: 'blob' });\n return output as Blob;\n }\n}\n"],"mappings":"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","names":["index_exports","__export","PptEditor","PptxBlobExporter","PptxExporter","PptxParser","__toCommonJS","styleInject","css","insertAt","head","style","styleInject","import_react","import_react","import_lucide_react","import_clsx","import_tailwind_merge","cn","inputs","import_jsx_runtime","FONTS","FONT_SIZES","SHAPE_CATEGORIES","ShapeIcon","type","className","ShapesDropdown","onAddShape","uiScale","isOpen","setIsOpen","React","cat","Toolbar","onAddText","onAddImage","onAddSlide","onExport","onFormatText","onDeleteElement","onApplyLayout","onPlay","selectedElement","onNewPresentation","onLoadPresentation","appBgColor","source","onGenerateImageClick","onGenerateInfographicClick","onUploadImageClick","onRefineAction","refineResponse","isAiLoading","fileInputRef","activeTab","setActiveTab","showLayouts","setShowLayouts","showAiMenu","setShowAiMenu","showFileMenu","setShowFileMenu","showUploadModal","setShowUploadModal","uploadType","setUploadType","uploadUrl","setUploadUrl","showChangeCaseMenu","setShowChangeCaseMenu","showCharSpacingMenu","setShowCharSpacingMenu","showBulletMenu","setShowBulletMenu","showNumberingMenu","setShowNumberingMenu","applyChangeCase","caseType","isText","currentText","newText","word","char","isShape","isImage","PPT_RED","cn","LayoutIcon","e","f","s","_a","ImageIcon","file","import_lucide_react","import_core","import_sortable","import_utilities","import_jsx_runtime","SHAPE_PATHS","SortableSlide","slide","index","isActive","onSelect","onDelete","onDuplicate","showDelete","uiScale","appBgColor","attributes","listeners","setNodeRef","transform","transition","isDragging","style","cn","__spreadProps","__spreadValues","e","a","b","el","_a","pathData","Sidebar","slides","currentSlideIndex","onSelectSlide","onDeleteSlide","onDuplicateSlide","onReorderSlides","sensors","handleDragEnd","event","active","over","oldIndex","s","newIndex","import_react","fabric","import_lucide_react","import_jsx_runtime","SHAPE_PATHS","getBulletContent","listType","isBulleted","isNumbered","index","n","toRoman","toAlpha","num","lookup","roman","i","CustomTextbox","method","ctx","line","left","top","lineIndex","bulletText","fontSize","xOffset","bulletSize","EditorCanvas","slide","onElementUpdate","onSelect","uiScale","onSlashCommand","selectedElementId","onAiGenerateClick","onAiGenerateInfographicClick","onUploadImageClick","onDeleteElement","canvasRef","fabricCanvas","isInternalUpdate","onElementUpdateRef","onSelectRef","containerRef","dynamicScale","setDynamicScale","canvasReady","setCanvasReady","mousePos","observer","entries","entry","cw","ch","scaleX","scaleY","scale","canvas","clamp","obj","bound","e","handleUpdate","_a","elementId","__spreadValues","getContext","triggerSlashMenu","isTextSelection","rect","x","y","hasMethod","o","m","isTextbox","coords","charIndex","canvasCoords","vpt","viewportCoords","mode","finalX","finalY","err","syncSelection","_b","handleGlobalKeyDown","activeObj","step","moved","listener","existingObjs","slideIds","id","sorted","a","b","el","updates","newObj","commonProps","__spreadProps","shapeFill","pathData","p","img","selectedElement","ImageIcon","import_pptxgenjs","PptxExporter","presentation","_a","_b","pptx","pptxgen","emuWidth","emuHeight","canvasWidth","canvasHeight","getInchesX","px","getInchesY","slide","pptxSlide","a","b","el","transparency","common","__spreadProps","__spreadValues","shapeType","import_jszip","PptxParser","input","_a","_b","data","response","status","statusText","detail","errorJson","e","zip","JSZip","presentationXml","presentationDoc","sldSz","sldIdList","slides","i","slideNum","slidePath","slideXml","slide","el","name","parent","elements","emu","srgbClr","hex","alphaNode","opacity","schemeClr","relId","slideIndex","relsXml","relsDoc","relationship","r","target","mediaPath","xml","doc","zIndex","bg","blip","mediaFile","spTree","children","child","localName","txBody","nvSpPr","nvPr","ph","phType","isBodyPlaceholder","xfrm","off","ext","paragraphs","content","fontSize","color","isBulleted","isNumbered","p","pPr","buNone","paragraphContent","runs","t","rPr","sz","style","bulletRegex","prstGeom","prst","spPr","mapping","import_react","import_lucide_react","import_jsx_runtime","PresenterMode","presentation","initialSlideIndex","onClose","currentIndex","setCurrentIndex","currentSlide","goToPrevious","goToNext","handleKeyDown","e","scale","setScale","updateScale","availableWidth","availableHeight","slideWidth","slideHeight","scaleX","scaleY","newScale","EditorCanvas","import_generative_ai","import_lucide_react","import_jsx_runtime","RefineMenu","result","isLoading","onAction","onClose","position","import_react","import_lucide_react","import_jsx_runtime","FONTS","FONT_SIZES","SlashMenu","onClose","onAction","position","canUseAi","mode","context","aiResult","isAiLoading","onAiResponseAction","search","setSearch","selectedIndex","setSelectedIndex","scrollContainerRef","showFontDropdown","setShowFontDropdown","showSizeDropdown","setShowSizeDropdown","showBulletMenu","setShowBulletMenu","showNumberingMenu","setShowNumberingMenu","showAiMenu","setShowAiMenu","defaultItems","ImageIcon","filteredItems","item","handleKeyDown","e","prev","selectedElement","activeFont","activeSize","menuRef","adjustedPosition","setAdjustedPosition","React","rect","viewportWidth","viewportHeight","x","y","stylePosition","opacity","openUpwards","font","cn","size","safeXVertical","safeYVertical","index","isSelected","showsCategory","import_lucide_react","import_react","import_lucide_react","import_jsx_runtime","Snackbar","message","type","isOpen","onClose","autoHideDuration","timer","icons","cn","import_jsx_runtime","PptEditor","initialPresentation","url","appName","onChange","geminiApiKey","width","height","appBgColor","showHomeOnEmpty","initialSource","onSourceChange","proxyUrl","onGenerateImage","onGenerateInfographic","onAiRewrite","onAiGrammar","onAiShorten","onAiLengthen","onAiContinue","isTwoStepInfographicGeneration","onRefineInfographicPrompt","_a","_b","presentation","setPresentation","history","setHistory","redoStack","setRedoStack","currentSlideIndex","setCurrentSlideIndex","selectedElementId","setSelectedElementId","isPreviewMode","setIsPreviewMode","askAiResponse","setAskAiResponse","refineResponse","setRefineResponse","isLoading","setIsLoading","source","setSource","showInitialLayout","setShowInitialLayout","urlInput","setUrlInput","slashMenu","setSlashMenu","isImageGenOpen","setIsImageGenOpen","imageGenPrompt","setImageGenPrompt","isGeneratingImage","setIsGeneratingImage","pendingImage","setPendingImage","imageError","setImageError","previewLoading","setPreviewLoading","isInfographicGenOpen","setIsInfographicGenOpen","infographicGenPrompt","setInfographicGenPrompt","isGeneratingInfographic","setIsGeneratingInfographic","pendingInfographic","setPendingInfographic","infographicError","setInfographicError","isRefiningInfographic","setIsRefiningInfographic","refinedInfographicPrompt","setRefinedInfographicPrompt","snackbar","setSnackbar","showSnackbar","message","type","handleLoadPresentation","isAiLoading","setIsAiLoading","lastAiPrompt","setLastAiPrompt","uiScale","w","currentSlide","selectedElement","el","saveToHistory","state","prevHistory","undo","last","prev","redo","next","handleUpdateSlide","updates","newSlides","__spreadValues","updated","__spreadProps","h","handleElementUpdate","elementId","slide","newElements","handleFormatText","e","handleDeleteElement","handleAddText","newElement","handleAddImage","input","src","resolve","reader","id","handleAddShape","shapeType","handleAddSlide","newSlide","handleDeleteSlide","index","_","i","handleDuplicateSlide","slideToClone","handleReorderSlides","oldIndex","newIndex","removed","handleApplyLayout","layoutType","elements","timestamp","handleAiAction","action","element","model","elementContext","prompt","response","error","handleAiTextEdit","resultText","systemPrompt","userPrompt","handleAiResponseAction","originalElement","handleRefineResponseAction","handleExport","PptxExporter","handlePlay","elem","handleClosePresenter","handleFullscreenChange","handleKeyDown","activeElement","updateSource","newSource","handleNewPresentation","parser","PptxParser","trimmedInput","result","err","handleSlashAction","actionId","payload","handleUploadImageClick","handleOpenInfographic","handleGenerateImage","imageUrl","handleFinalizeImage","handleGenerateInfographic","customPrompt","promptToUse","infographicUrl","handleFinalizeInfographic","textToRefine","refined","file","re","getProxiedUrl","PresenterMode","Toolbar","Sidebar","EditorCanvas","position","mode","context","SlashMenu","RefineMenu","cn","ImageIcon","finalPrompt","Snackbar","import_pptxgenjs","PptxBlobExporter","presentation","_a","_b","pptx","pptxgen","emuWidth","emuHeight","canvasWidth","canvasHeight","getInchesX","px","getInchesY","slide","pptxSlide","a","b","el","transparency","common","__spreadProps","__spreadValues","shapeType"]}
1
+ {"version":3,"sources":["../src/index.ts","#style-inject:#style-inject","../src/tailwind.css","../src/components/PptEditor.tsx","../src/components/Toolbar.tsx","../src/lib/utils.ts","../src/components/Sidebar.tsx","../src/components/EditorCanvas.tsx","../src/lib/pptx-exporter.ts","../src/lib/pptx-parser.ts","../src/components/PresenterMode.tsx","../src/components/RefineMenu.tsx","../src/components/SlashMenu.tsx","../src/components/Snackbar.tsx","../src/lib/PptxBlobExporter.ts"],"sourcesContent":["import './tailwind.css';\nexport * from './components/PptEditor';\nexport * from './lib/pptx-parser';\nexport * from './lib/pptx-exporter';\nexport * from './lib/PptxBlobExporter';\nexport * from './lib/types';\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\"@import\\\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Lato:wght@400;700&family=Open+Sans:wght@400;600;700&family=Poppins:wght@400;500;600;700&family=Roboto:wght@400;500;700&family=Roboto+Slab:wght@400;700&family=Playfair+Display:wght@400;700&family=Merriweather:wght@400;700&family=Nunito+Sans:wght@400;600;700&family=Montserrat:wght@400;600;700&family=Oswald:wght@400;500&family=Raleway:wght@400;600;700&family=Ubuntu:wght@400;500;700&family=Lora:wght@400;700&family=PT+Sans:wght@400;700&family=PT+Serif:wght@400;700&family=Play:wght@400;700&family=Arvo:wght@400;700&family=Kanit:wght@400;500;600&display=swap\\\";/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */@layer properties;@layer theme,base,components,utilities;@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-serif: ui-serif, Georgia, Cambria, \\\"Times New Roman\\\", Times, serif;--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \\\"Liberation Mono\\\", \\\"Courier New\\\", monospace;--color-red-50: oklch(97.1% .013 17.38);--color-red-100: oklch(93.6% .032 17.717);--color-red-200: oklch(88.5% .062 18.334);--color-red-400: oklch(70.4% .191 22.216);--color-red-500: oklch(63.7% .237 25.331);--color-red-600: oklch(57.7% .245 27.325);--color-orange-50: oklch(98% .016 73.684);--color-orange-500: oklch(70.5% .213 47.604);--color-amber-500: oklch(76.9% .188 70.08);--color-green-500: oklch(72.3% .219 149.579);--color-emerald-50: oklch(97.9% .021 166.113);--color-emerald-100: oklch(95% .052 163.051);--color-emerald-400: oklch(76.5% .177 163.223);--color-emerald-500: oklch(69.6% .17 162.48);--color-emerald-600: oklch(59.6% .145 163.225);--color-emerald-700: oklch(50.8% .118 165.612);--color-teal-500: oklch(70.4% .14 182.503);--color-blue-50: oklch(97% .014 254.604);--color-blue-100: oklch(93.2% .032 255.585);--color-blue-400: oklch(70.7% .165 254.624);--color-blue-500: oklch(62.3% .214 259.815);--color-blue-600: oklch(54.6% .245 262.881);--color-blue-700: oklch(48.8% .243 264.376);--color-indigo-500: oklch(58.5% .233 277.117);--color-purple-50: oklch(97.7% .014 308.299);--color-purple-100: oklch(94.6% .033 307.174);--color-purple-300: oklch(82.7% .119 306.383);--color-purple-400: oklch(71.4% .203 305.504);--color-purple-500: oklch(62.7% .265 303.9);--color-purple-600: oklch(55.8% .288 302.321);--color-purple-700: oklch(49.6% .265 301.924);--color-pink-500: oklch(65.6% .241 354.308);--color-slate-50: oklch(98.4% .003 247.858);--color-slate-100: oklch(96.8% .007 247.896);--color-slate-200: oklch(92.9% .013 255.508);--color-slate-300: oklch(86.9% .022 252.894);--color-slate-400: oklch(70.4% .04 256.788);--color-slate-500: oklch(55.4% .046 257.417);--color-slate-600: oklch(44.6% .043 257.281);--color-slate-700: oklch(37.2% .044 257.287);--color-slate-800: oklch(27.9% .041 260.031);--color-slate-900: oklch(20.8% .042 265.755);--color-black: #000;--color-white: #fff;--spacing: .25rem;--container-2xl: 42rem;--text-xs: .75rem;--text-xs--line-height: calc(1 / .75);--text-sm: .875rem;--text-sm--line-height: calc(1.25 / .875);--text-base: 1rem;--text-base--line-height: 1.5 ;--text-lg: 1.125rem;--text-lg--line-height: calc(1.75 / 1.125);--text-xl: 1.25rem;--text-xl--line-height: calc(1.75 / 1.25);--text-2xl: 1.5rem;--text-2xl--line-height: calc(2 / 1.5);--text-4xl: 2.25rem;--text-4xl--line-height: calc(2.5 / 2.25);--font-weight-normal: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--font-weight-black: 900;--tracking-tighter: -.05em;--tracking-tight: -.025em;--tracking-wide: .025em;--tracking-wider: .05em;--tracking-widest: .1em;--leading-tight: 1.25;--leading-relaxed: 1.625;--radius-sm: .25rem;--radius-md: .375rem;--radius-lg: .5rem;--radius-xl: .75rem;--radius-2xl: 1rem;--radius-3xl: 1.5rem;--ease-out: cubic-bezier(0, 0, .2, 1);--animate-spin: spin 1s linear infinite;--blur-sm: 8px;--blur-md: 12px;--aspect-video: 16 / 9;--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)}}@layer base{*,:after,:before,::backdrop,::file-selector-button{box-sizing:border-box;margin:0;padding:0;border:0 solid}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;tab-size:4;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;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{font-size:75%;line-height:0;position:relative;vertical-align:baseline}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{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea,::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;border-radius:0;background-color:transparent;opacity:1}: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)){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,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-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]),::file-selector-button{appearance:button}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing) * 0)}.inset-x-0{inset-inline:calc(var(--spacing) * 0)}.top-0{top:calc(var(--spacing) * 0)}.top-1{top:calc(var(--spacing) * 1)}.top-1\\\\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-5{top:calc(var(--spacing) * 5)}.top-10{top:calc(var(--spacing) * 10)}.top-\\\\[24px\\\\]{top:24px}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-1{right:calc(var(--spacing) * 1)}.right-2{right:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.right-6{right:calc(var(--spacing) * 6)}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-1{bottom:calc(var(--spacing) * 1)}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-6{bottom:calc(var(--spacing) * 6)}.bottom-8{bottom:calc(var(--spacing) * 8)}.bottom-10{bottom:calc(var(--spacing) * 10)}.bottom-full{bottom:100%}.left-0{left:calc(var(--spacing) * 0)}.left-1{left:calc(var(--spacing) * 1)}.left-1\\\\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.left-4{left:calc(var(--spacing) * 4)}.z-10{z-index:10}.z-50{z-index:50}.z-\\\\[100\\\\]{z-index:100}.z-\\\\[1000\\\\]{z-index:1000}.z-\\\\[2000\\\\]{z-index:2000}.z-\\\\[2001\\\\]{z-index:2001}.z-\\\\[5000\\\\]{z-index:5000}.z-\\\\[9998\\\\]{z-index:9998}.z-\\\\[9999\\\\]{z-index:9999}.z-\\\\[10000\\\\]{z-index:10000}.z-\\\\[11000\\\\]{z-index:11000}.z-\\\\[99999\\\\]{z-index:99999}.col-span-1{grid-column:span 1 / span 1}.container{width:100%;@media(width>=40rem){max-width:40rem}@media(width>=48rem){max-width:48rem}@media(width>=64rem){max-width:64rem}@media(width>=80rem){max-width:80rem}@media(width>=96rem){max-width:96rem}}.mx-1{margin-inline:calc(var(--spacing) * 1)}.mx-1\\\\.5{margin-inline:calc(var(--spacing) * 1.5)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-3{margin-inline:calc(var(--spacing) * 3)}.my-1{margin-block:calc(var(--spacing) * 1)}.my-auto{margin-block:auto}.-mt-1{margin-top:calc(var(--spacing) * -1)}.mt-0{margin-top:calc(var(--spacing) * 0)}.mt-0\\\\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-auto{margin-top:auto}.mr-0{margin-right:calc(var(--spacing) * 0)}.mr-0\\\\.5{margin-right:calc(var(--spacing) * .5)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-0{margin-bottom:calc(var(--spacing) * 0)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.-ml-0{margin-left:calc(var(--spacing) * -0)}.-ml-0\\\\.5{margin-left:calc(var(--spacing) * -.5)}.ml-0{margin-left:calc(var(--spacing) * 0)}.ml-0\\\\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.table{display:table}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:var(--aspect-video)}.h-0{height:calc(var(--spacing) * 0)}.h-0\\\\.5{height:calc(var(--spacing) * .5)}.h-1{height:calc(var(--spacing) * 1)}.h-1\\\\.5{height:calc(var(--spacing) * 1.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-7\\\\.5{height:calc(var(--spacing) * 7.5)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-32{height:calc(var(--spacing) * 32)}.h-48{height:calc(var(--spacing) * 48)}.h-\\\\[1px\\\\]{height:1px}.h-\\\\[2\\\\.5px\\\\]{height:2.5px}.h-\\\\[4px\\\\]{height:4px}.h-\\\\[22px\\\\]{height:22px}.h-\\\\[28px\\\\]{height:28px}.h-full{height:100%}.h-screen{height:100vh}.max-h-\\\\[60vh\\\\]{max-height:60vh}.max-h-\\\\[90vh\\\\]{max-height:90vh}.max-h-\\\\[200px\\\\]{max-height:200px}.max-h-\\\\[250px\\\\]{max-height:250px}.max-h-\\\\[300px\\\\]{max-height:300px}.min-h-\\\\[56px\\\\]{min-height:56px}.min-h-\\\\[300px\\\\]{min-height:300px}.min-h-screen{min-height:100vh}.w-1{width:calc(var(--spacing) * 1)}.w-1\\\\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-2\\\\.5{width:calc(var(--spacing) * 2.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-15{width:calc(var(--spacing) * 15)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-32{width:calc(var(--spacing) * 32)}.w-36{width:calc(var(--spacing) * 36)}.w-40{width:calc(var(--spacing) * 40)}.w-44{width:calc(var(--spacing) * 44)}.w-48{width:calc(var(--spacing) * 48)}.w-56{width:calc(var(--spacing) * 56)}.w-60{width:calc(var(--spacing) * 60)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-96{width:calc(var(--spacing) * 96)}.w-\\\\[1px\\\\]{width:1px}.w-\\\\[15px\\\\]{width:15px}.w-\\\\[32px\\\\]{width:32px}.w-\\\\[480px\\\\]{width:480px}.w-\\\\[500px\\\\]{width:500px}.w-\\\\[600px\\\\]{width:600px}.w-full{width:100%}.w-screen{width:100vw}.max-w-2xl{max-width:var(--container-2xl)}.max-w-\\\\[90vw\\\\]{max-width:90vw}.max-w-\\\\[300px\\\\]{max-width:300px}.max-w-\\\\[400px\\\\]{max-width:400px}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\\\\[40px\\\\]{min-width:40px}.min-w-\\\\[45px\\\\]{min-width:45px}.min-w-\\\\[50px\\\\]{min-width:50px}.min-w-\\\\[72px\\\\]{min-width:72px}.min-w-\\\\[80px\\\\]{min-width:80px}.min-w-\\\\[180px\\\\]{min-width:180px}.min-w-\\\\[280px\\\\]{min-width:280px}.min-w-fit{min-width:fit-content}.flex-1{flex:1}.shrink-0{flex-shrink:0}.origin-bottom-left{transform-origin:0 100%}.origin-center{transform-origin:center}.origin-top-left{transform-origin:0 0}.-translate-x-1{--tw-translate-x: calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-1\\\\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1{--tw-translate-y: calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\\\\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\\\\[1px\\\\]{--tw-translate-y: 1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-75{--tw-scale-x: 75%;--tw-scale-y: 75%;--tw-scale-z: 75%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-105{--tw-scale-x: 105%;--tw-scale-y: 105%;--tw-scale-z: 105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-110{--tw-scale-x: 110%;--tw-scale-y: 110%;--tw-scale-z: 110%;scale:var(--tw-scale-x) var(--tw-scale-y)}.rotate-45{rotate:45deg}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.appearance-none{appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.justify-stretch{justify-content:stretch}.gap-0{gap:calc(var(--spacing) * 0)}.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-2\\\\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.space-y-2{:where(&>: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)))}}.space-y-4{:where(&>: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)))}}.space-y-6{:where(&>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}}.self-start{align-self:flex-start}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-3xl{border-radius:var(--radius-3xl)}.rounded-\\\\[2\\\\.5rem\\\\]{border-radius:2.5rem}.rounded-\\\\[3px\\\\]{border-radius:3px}.rounded-full{border-radius:calc(infinity * 1px)}.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-l-\\\\[3px\\\\]{border-top-left-radius:3px;border-bottom-left-radius:3px}.rounded-l-lg{border-top-left-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.rounded-l-md{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.rounded-r-\\\\[3px\\\\]{border-top-right-radius:3px;border-bottom-right-radius:3px}.rounded-r-lg{border-top-right-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.rounded-b-xl{border-bottom-right-radius:var(--radius-xl);border-bottom-left-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\\\\[1\\\\.5px\\\\]{border-style:var(--tw-border-style);border-width:1.5px}.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-none{--tw-border-style: none;border-style:none}.border-solid{--tw-border-style: solid;border-style:solid}.border-black{border-color:var(--color-black)}.border-blue-100{border-color:var(--color-blue-100)}.border-emerald-100{border-color:var(--color-emerald-100)}.border-emerald-100\\\\/50{border-color:color-mix(in srgb,oklch(95% .052 163.051) 50%,transparent);@supports (color: color-mix(in lab,red,red)){border-color:color-mix(in oklab,var(--color-emerald-100) 50%,transparent)}}.border-purple-100{border-color:var(--color-purple-100)}.border-red-200{border-color:var(--color-red-200)}.border-slate-50{border-color:var(--color-slate-50)}.border-slate-100{border-color:var(--color-slate-100)}.border-slate-100\\\\/50{border-color:color-mix(in srgb,oklch(96.8% .007 247.896) 50%,transparent);@supports (color: color-mix(in lab,red,red)){border-color:color-mix(in oklab,var(--color-slate-100) 50%,transparent)}}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-200\\\\/60{border-color:color-mix(in srgb,oklch(92.9% .013 255.508) 60%,transparent);@supports (color: color-mix(in lab,red,red)){border-color:color-mix(in oklab,var(--color-slate-200) 60%,transparent)}}.border-slate-300{border-color:var(--color-slate-300)}.border-transparent{border-color:transparent}.border-white{border-color:var(--color-white)}.border-white\\\\/10{border-color:color-mix(in srgb,#fff 10%,transparent);@supports (color: color-mix(in lab,red,red)){border-color:color-mix(in oklab,var(--color-white) 10%,transparent)}}.bg-\\\\[\\\\#0A0A0A\\\\]{background-color:#0a0a0a}.bg-black{background-color:var(--color-black)}.bg-black\\\\/20{background-color:color-mix(in srgb,#000 20%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-black) 20%,transparent)}}.bg-black\\\\/40{background-color:color-mix(in srgb,#000 40%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-black) 40%,transparent)}}.bg-black\\\\/60{background-color:color-mix(in srgb,#000 60%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-black) 60%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-50\\\\/50{background-color:color-mix(in srgb,oklch(97% .014 254.604) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-blue-50) 50%,transparent)}}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-100\\\\/50{background-color:color-mix(in srgb,oklch(93.2% .032 255.585) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-blue-100) 50%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-50\\\\/50{background-color:color-mix(in srgb,oklch(97.9% .021 166.113) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-emerald-50) 50%,transparent)}}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-emerald-600{background-color:var(--color-emerald-600)}.bg-orange-50{background-color:var(--color-orange-50)}.bg-purple-50{background-color:var(--color-purple-50)}.bg-purple-50\\\\/50{background-color:color-mix(in srgb,oklch(97.7% .014 308.299) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-purple-50) 50%,transparent)}}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-50\\\\/50{background-color:color-mix(in srgb,oklch(98.4% .003 247.858) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-slate-50) 50%,transparent)}}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-100\\\\/50{background-color:color-mix(in srgb,oklch(96.8% .007 247.896) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-slate-100) 50%,transparent)}}.bg-slate-200{background-color:var(--color-slate-200)}.bg-slate-200\\\\/50{background-color:color-mix(in srgb,oklch(92.9% .013 255.508) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-slate-200) 50%,transparent)}}.bg-slate-300{background-color:var(--color-slate-300)}.bg-slate-800{background-color:var(--color-slate-800)}.bg-slate-900{background-color:var(--color-slate-900)}.bg-slate-900\\\\/40{background-color:color-mix(in srgb,oklch(20.8% .042 265.755) 40%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-slate-900) 40%,transparent)}}.bg-transparent{background-color:transparent}.bg-white{background-color:var(--color-white)}.bg-white\\\\/10{background-color:color-mix(in srgb,#fff 10%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-white) 10%,transparent)}}.bg-white\\\\/50{background-color:color-mix(in srgb,#fff 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-white) 50%,transparent)}}.bg-white\\\\/80{background-color:color-mix(in srgb,#fff 80%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-white) 80%,transparent)}}.bg-gradient-to-b{--tw-gradient-position: to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-black{--tw-gradient-from: var(--color-black);--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-black\\\\/60{--tw-gradient-from: color-mix(in srgb, #000 60%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-gradient-from: color-mix(in oklab, var(--color-black) 60%, transparent)}--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to: transparent;--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.fill-purple-300{fill:var(--color-purple-300)}.fill-slate-700{fill:var(--color-slate-700)}.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-2\\\\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.p-10{padding:calc(var(--spacing) * 10)}.p-12{padding:calc(var(--spacing) * 12)}.px-0{padding-inline:calc(var(--spacing) * 0)}.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-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.px-10{padding-inline:calc(var(--spacing) * 10)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\\\\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\\\\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\\\\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\\\\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-0\\\\.5{padding-top:calc(var(--spacing) * .5)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\\\\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-8{padding-top:calc(var(--spacing) * 8)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-5{padding-right:calc(var(--spacing) * 5)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pr-12{padding-right:calc(var(--spacing) * 12)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-11{padding-left:calc(var(--spacing) * 11)}.pl-12{padding-left:calc(var(--spacing) * 12)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading, var(--text-2xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading, var(--text-4xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading, var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading, var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading, var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading, var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading, var(--text-xs--line-height))}.text-\\\\[6px\\\\]{font-size:6px}.text-\\\\[7px\\\\]{font-size:7px}.text-\\\\[9px\\\\]{font-size:9px}.text-\\\\[10px\\\\]{font-size:10px}.text-\\\\[11px\\\\]{font-size:11px}.text-\\\\[12px\\\\]{font-size:12px}.text-\\\\[13px\\\\]{font-size:13px}.text-\\\\[14px\\\\]{font-size:14px}.text-\\\\[15px\\\\]{font-size:15px}.text-\\\\[16px\\\\]{font-size:16px}.leading-none{--tw-leading: 1;line-height:1}.leading-relaxed{--tw-leading: var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading: var(--leading-tight);line-height:var(--leading-tight)}.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-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)}.tracking-\\\\[0\\\\.2em\\\\]{--tw-tracking: .2em;letter-spacing:.2em}.tracking-\\\\[0\\\\.15em\\\\]{--tw-tracking: .15em;letter-spacing:.15em}.tracking-tight{--tw-tracking: var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-tighter{--tw-tracking: var(--tracking-tighter);letter-spacing:var(--tracking-tighter)}.tracking-wide{--tw-tracking: var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking: var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking: var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-500{color:var(--color-amber-500)}.text-black{color:var(--color-black)}.text-blue-400{color:var(--color-blue-400)}.text-blue-500{color:var(--color-blue-500)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-emerald-400{color:var(--color-emerald-400)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-600\\\\/70{color:color-mix(in srgb,oklch(59.6% .145 163.225) 70%,transparent);@supports (color: color-mix(in lab,red,red)){color:color-mix(in oklab,var(--color-emerald-600) 70%,transparent)}}.text-emerald-700{color:var(--color-emerald-700)}.text-green-500{color:var(--color-green-500)}.text-indigo-500{color:var(--color-indigo-500)}.text-orange-500{color:var(--color-orange-500)}.text-pink-500{color:var(--color-pink-500)}.text-purple-400{color:var(--color-purple-400)}.text-purple-500{color:var(--color-purple-500)}.text-purple-600{color:var(--color-purple-600)}.text-purple-700{color:var(--color-purple-700)}.text-red-400{color:var(--color-red-400)}.text-red-400\\\\/80{color:color-mix(in srgb,oklch(70.4% .191 22.216) 80%,transparent);@supports (color: color-mix(in lab,red,red)){color:color-mix(in oklab,var(--color-red-400) 80%,transparent)}}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-slate-200{color:var(--color-slate-200)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-slate-900{color:var(--color-slate-900)}.text-teal-500{color:var(--color-teal-500)}.text-white{color:var(--color-white)}.text-white\\\\/50{color:color-mix(in srgb,#fff 50%,transparent);@supports (color: color-mix(in lab,red,red)){color:color-mix(in oklab,var(--color-white) 50%,transparent)}}.text-white\\\\/80{color:color-mix(in srgb,#fff 80%,transparent);@supports (color: color-mix(in lab,red,red)){color:color-mix(in oklab,var(--color-white) 80%,transparent)}}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0%}.opacity-25{opacity:25%}.opacity-40{opacity:40%}.opacity-50{opacity:50%}.opacity-75{opacity:75%}.opacity-100{opacity:100%}.shadow-2xl{--tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, rgb(0 0 0 / .25));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_20px_50px_rgba\\\\(0\\\\,0\\\\,0\\\\,0\\\\.15\\\\)\\\\]{--tw-shadow: 0 20px 50px var(--tw-shadow-color, rgba(0,0,0,.15));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, rgb(0 0 0 / .05));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, rgb(0 0 0 / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / .1));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, rgb(0 0 0 / .1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / .1));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, rgb(0 0 0 / .1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--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)}.ring-4{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(4px + 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)}.shadow-black{--tw-shadow-color: #000;@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, var(--color-black) var(--tw-shadow-alpha), transparent)}}.shadow-black\\\\/80{--tw-shadow-color: color-mix(in srgb, #000 80%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-black) 80%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-blue-500{--tw-shadow-color: oklch(62.3% .214 259.815);@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, var(--color-blue-500) var(--tw-shadow-alpha), transparent)}}.shadow-blue-500\\\\/20{--tw-shadow-color: color-mix(in srgb, oklch(62.3% .214 259.815) 20%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-blue-500) 20%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-emerald-500{--tw-shadow-color: oklch(69.6% .17 162.48);@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, var(--color-emerald-500) var(--tw-shadow-alpha), transparent)}}.shadow-emerald-500\\\\/20{--tw-shadow-color: color-mix(in srgb, oklch(69.6% .17 162.48) 20%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-emerald-500) 20%, transparent) var(--tw-shadow-alpha), transparent)}}.ring-black{--tw-ring-color: var(--color-black)}.ring-black\\\\/5{--tw-ring-color: color-mix(in srgb, #000 5%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-ring-color: color-mix(in oklab, var(--color-black) 5%, transparent)}}.ring-purple-100{--tw-ring-color: var(--color-purple-100)}.ring-white{--tw-ring-color: var(--color-white)}.backdrop-blur-\\\\[1px\\\\]{--tw-backdrop-blur: blur(1px);-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,)}.backdrop-blur-\\\\[2px\\\\]{--tw-backdrop-blur: blur(2px);-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,)}.backdrop-blur-md{--tw-backdrop-blur: blur(var(--blur-md));-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,)}.backdrop-blur-sm{--tw-backdrop-blur: blur(var(--blur-sm));-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-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-opacity{transition-property:opacity;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}.duration-300{--tw-duration: .3s;transition-duration:.3s}.duration-500{--tw-duration: .5s;transition-duration:.5s}.duration-700{--tw-duration: .7s;transition-duration:.7s}.ease-out{--tw-ease: var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style: none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.group-focus-within\\\\:text-slate-600{&:is(:where(.group):focus-within *){color:var(--color-slate-600)}}.group-hover\\\\:scale-105{&:is(:where(.group):hover *){@media(hover:hover){--tw-scale-x: 105%;--tw-scale-y: 105%;--tw-scale-z: 105%;scale:var(--tw-scale-x) var(--tw-scale-y)}}}.group-hover\\\\:scale-110{&:is(:where(.group):hover *){@media(hover:hover){--tw-scale-x: 110%;--tw-scale-y: 110%;--tw-scale-z: 110%;scale:var(--tw-scale-x) var(--tw-scale-y)}}}.group-hover\\\\:bg-blue-50{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-blue-50)}}}.group-hover\\\\:bg-blue-100{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-blue-100)}}}.group-hover\\\\:bg-blue-600{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-blue-600)}}}.group-hover\\\\:bg-emerald-50{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-emerald-50)}}}.group-hover\\\\:bg-emerald-600{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-emerald-600)}}}.group-hover\\\\:bg-purple-600{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-purple-600)}}}.group-hover\\\\:bg-red-500{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-red-500)}}}.group-hover\\\\:bg-slate-200{&:is(:where(.group):hover *){@media(hover:hover){background-color:var(--color-slate-200)}}}.group-hover\\\\:fill-slate-900{&:is(:where(.group):hover *){@media(hover:hover){fill:var(--color-slate-900)}}}.group-hover\\\\:text-blue-600{&:is(:where(.group):hover *){@media(hover:hover){color:var(--color-blue-600)}}}.group-hover\\\\:text-slate-700{&:is(:where(.group):hover *){@media(hover:hover){color:var(--color-slate-700)}}}.group-hover\\\\:text-slate-900{&:is(:where(.group):hover *){@media(hover:hover){color:var(--color-slate-900)}}}.group-hover\\\\:text-white{&:is(:where(.group):hover *){@media(hover:hover){color:var(--color-white)}}}.group-hover\\\\:opacity-100{&:is(:where(.group):hover *){@media(hover:hover){opacity:100%}}}.group-hover\\\\:shadow-sm{&:is(:where(.group):hover *){@media(hover:hover){--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}}.placeholder\\\\:text-slate-400{&::placeholder{color:var(--color-slate-400)}}.hover\\\\:border-blue-400{&:hover{@media(hover:hover){border-color:var(--color-blue-400)}}}.hover\\\\:border-slate-100{&:hover{@media(hover:hover){border-color:var(--color-slate-100)}}}.hover\\\\:border-slate-200{&:hover{@media(hover:hover){border-color:var(--color-slate-200)}}}.hover\\\\:border-slate-300{&:hover{@media(hover:hover){border-color:var(--color-slate-300)}}}.hover\\\\:bg-black{&:hover{@media(hover:hover){background-color:var(--color-black)}}}.hover\\\\:bg-blue-50{&:hover{@media(hover:hover){background-color:var(--color-blue-50)}}}.hover\\\\:bg-blue-50\\\\/50{&:hover{@media(hover:hover){background-color:color-mix(in srgb,oklch(97% .014 254.604) 50%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-blue-50) 50%,transparent)}}}}.hover\\\\:bg-blue-700{&:hover{@media(hover:hover){background-color:var(--color-blue-700)}}}.hover\\\\:bg-emerald-50{&:hover{@media(hover:hover){background-color:var(--color-emerald-50)}}}.hover\\\\:bg-emerald-700{&:hover{@media(hover:hover){background-color:var(--color-emerald-700)}}}.hover\\\\:bg-purple-50{&:hover{@media(hover:hover){background-color:var(--color-purple-50)}}}.hover\\\\:bg-red-50{&:hover{@media(hover:hover){background-color:var(--color-red-50)}}}.hover\\\\:bg-red-100{&:hover{@media(hover:hover){background-color:var(--color-red-100)}}}.hover\\\\:bg-slate-50{&:hover{@media(hover:hover){background-color:var(--color-slate-50)}}}.hover\\\\:bg-slate-100{&:hover{@media(hover:hover){background-color:var(--color-slate-100)}}}.hover\\\\:bg-slate-200{&:hover{@media(hover:hover){background-color:var(--color-slate-200)}}}.hover\\\\:bg-white{&:hover{@media(hover:hover){background-color:var(--color-white)}}}.hover\\\\:bg-white\\\\/20{&:hover{@media(hover:hover){background-color:color-mix(in srgb,#fff 20%,transparent);@supports (color: color-mix(in lab,red,red)){background-color:color-mix(in oklab,var(--color-white) 20%,transparent)}}}}.hover\\\\:text-blue-500{&:hover{@media(hover:hover){color:var(--color-blue-500)}}}.hover\\\\:text-blue-600{&:hover{@media(hover:hover){color:var(--color-blue-600)}}}.hover\\\\:text-blue-700{&:hover{@media(hover:hover){color:var(--color-blue-700)}}}.hover\\\\:text-emerald-700{&:hover{@media(hover:hover){color:var(--color-emerald-700)}}}.hover\\\\:text-purple-600{&:hover{@media(hover:hover){color:var(--color-purple-600)}}}.hover\\\\:text-purple-700{&:hover{@media(hover:hover){color:var(--color-purple-700)}}}.hover\\\\:text-red-500{&:hover{@media(hover:hover){color:var(--color-red-500)}}}.hover\\\\:text-slate-500{&:hover{@media(hover:hover){color:var(--color-slate-500)}}}.hover\\\\:text-slate-600{&:hover{@media(hover:hover){color:var(--color-slate-600)}}}.hover\\\\:text-slate-700{&:hover{@media(hover:hover){color:var(--color-slate-700)}}}.hover\\\\:text-white{&:hover{@media(hover:hover){color:var(--color-white)}}}.hover\\\\:opacity-100{&:hover{@media(hover:hover){opacity:100%}}}.hover\\\\:shadow-md{&:hover{@media(hover:hover){--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}}.focus\\\\:border-blue-500{&:focus{border-color:var(--color-blue-500)}}.focus\\\\:border-slate-400{&:focus{border-color:var(--color-slate-400)}}.focus\\\\:ring-0{&:focus{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + 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\\\\:ring-2{&:focus{--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)}}.focus\\\\:ring-4{&:focus{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(4px + 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\\\\:ring-blue-500\\\\/10{&:focus{--tw-ring-color: color-mix(in srgb, oklch(62.3% .214 259.815) 10%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-ring-color: color-mix(in oklab, var(--color-blue-500) 10%, transparent)}}}.focus\\\\:ring-blue-500\\\\/20{&:focus{--tw-ring-color: color-mix(in srgb, oklch(62.3% .214 259.815) 20%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-ring-color: color-mix(in oklab, var(--color-blue-500) 20%, transparent)}}}.focus\\\\:ring-slate-400\\\\/5{&:focus{--tw-ring-color: color-mix(in srgb, oklch(70.4% .04 256.788) 5%, transparent);@supports (color: color-mix(in lab,red,red)){--tw-ring-color: color-mix(in oklab, var(--color-slate-400) 5%, transparent)}}}.focus\\\\:outline-none{&:focus{--tw-outline-style: none;outline-style:none}}.active\\\\:scale-95{&:active{--tw-scale-x: 95%;--tw-scale-y: 95%;--tw-scale-z: 95%;scale:var(--tw-scale-x) var(--tw-scale-y)}}.active\\\\:scale-\\\\[0\\\\.98\\\\]{&:active{scale:.98}}.active\\\\:cursor-grabbing{&:active{cursor:grabbing}}.disabled\\\\:cursor-not-allowed{&:disabled{cursor:not-allowed}}.disabled\\\\:bg-slate-100{&:disabled{background-color:var(--color-slate-100)}}.disabled\\\\:bg-slate-300{&:disabled{background-color:var(--color-slate-300)}}.disabled\\\\:text-slate-400{&:disabled{color:var(--color-slate-400)}}.disabled\\\\:opacity-20{&:disabled{opacity:20%}}.disabled\\\\:opacity-40{&:disabled{opacity:40%}}.disabled\\\\:opacity-50{&:disabled{opacity:50%}}.disabled\\\\:active\\\\:scale-100{&:disabled{&:active{--tw-scale-x: 100%;--tw-scale-y: 100%;--tw-scale-z: 100%;scale:var(--tw-scale-x) var(--tw-scale-y)}}}.md\\\\:space-y-8{@media(width>=48rem){:where(&>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}}}.md\\\\:p-12{@media(width>=48rem){padding:calc(var(--spacing) * 12)}}}@keyframes blob{0%{transform:translate(0) scale(1)}33%{transform:translate(30px,-50px) scale(1.1)}66%{transform:translate(-20px,20px) scale(.9)}to{transform:translate(0) scale(1)}}.animate-blob{animation:blob 7s infinite}.animation-delay-2000{animation-delay:2s}.animation-delay-4000{animation-delay:4s}@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-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;}@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-gradient-position{syntax: \\\"*\\\"; inherits: false;}@property --tw-gradient-from{syntax: \\\"<color>\\\"; inherits: false; initial-value: #0000;}@property --tw-gradient-via{syntax: \\\"<color>\\\"; inherits: false; initial-value: #0000;}@property --tw-gradient-to{syntax: \\\"<color>\\\"; inherits: false; initial-value: #0000;}@property --tw-gradient-stops{syntax: \\\"*\\\"; inherits: false;}@property --tw-gradient-via-stops{syntax: \\\"*\\\"; inherits: false;}@property --tw-gradient-from-position{syntax: \\\"<length-percentage>\\\"; inherits: false; initial-value: 0%;}@property --tw-gradient-via-position{syntax: \\\"<length-percentage>\\\"; inherits: false; initial-value: 50%;}@property --tw-gradient-to-position{syntax: \\\"<length-percentage>\\\"; inherits: false; initial-value: 100%;}@property --tw-leading{syntax: \\\"*\\\"; inherits: false;}@property --tw-font-weight{syntax: \\\"*\\\"; inherits: false;}@property --tw-tracking{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: 0px;}@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-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;}@keyframes spin{to{transform:rotate(360deg)}}@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-scale-x: 1;--tw-scale-y: 1;--tw-scale-z: 1;--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-gradient-position: initial;--tw-gradient-from: #0000;--tw-gradient-via: #0000;--tw-gradient-to: #0000;--tw-gradient-stops: initial;--tw-gradient-via-stops: initial;--tw-gradient-from-position: 0%;--tw-gradient-via-position: 50%;--tw-gradient-to-position: 100%;--tw-leading: initial;--tw-font-weight: initial;--tw-tracking: 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-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}}}\\n\")","'use client';\n\nimport React, { useState, useCallback, useMemo, useEffect } from 'react';\nimport type { Presentation, Slide, SlideElement, PresentationSource, ShapeType } from '../lib/types';\nimport { Toolbar } from './Toolbar';\nimport { Sidebar } from './Sidebar';\nimport { EditorCanvas } from './EditorCanvas';\nimport { PptxExporter } from '../lib/pptx-exporter';\nimport { PptxParser } from '../lib/pptx-parser';\nimport { PresenterMode } from './PresenterMode';\nimport { GoogleGenerativeAI } from '@google/generative-ai';\nimport { RefineMenu } from './RefineMenu';\nimport { SlashMenu } from './SlashMenu';\nimport { Sparkles, Plus, RefreshCw, Check, Trash2, Image as ImageIcon, PieChart } from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport { Snackbar, SnackbarType } from './Snackbar';\n\ninterface PptEditorProps {\n initialPresentation?: Presentation;\n url?: string;\n appName?: string;\n onChange?: (presentation: Presentation) => void;\n geminiApiKey?: string;\n width: number | string;\n height: number | string;\n appBgColor?: string;\n showHomeOnEmpty?: boolean;\n initialSource?: PresentationSource;\n onSourceChange?: (source: PresentationSource, url?: string) => void;\n proxyUrl?: string;\n onGenerateImage?: (prompt: string) => Promise<string>;\n onGenerateInfographic?: (prompt: string) => Promise<string>;\n onAiRewrite?: (text: string) => Promise<string>;\n onAiGrammar?: (text: string) => Promise<string>;\n onAiShorten?: (text: string) => Promise<string>;\n onAiLengthen?: (text: string) => Promise<string>;\n onAiContinue?: (text: string) => Promise<string>;\n isTwoStepInfographicGeneration?: boolean;\n onRefineInfographicPrompt?: (text: string) => Promise<string>;\n}\n\nexport const PptEditor: React.FC<PptEditorProps> = ({\n initialPresentation, url, appName = 'My Studio', onChange, geminiApiKey = \"AIzaSyAcBfseKzoFZJMfuRzhRJjygQ-u2UKFxOw\",\n width, height, appBgColor = '#B7472A', showHomeOnEmpty = false,\n initialSource, onSourceChange, proxyUrl, onGenerateImage, onGenerateInfographic,\n onAiRewrite, onAiGrammar, onAiShorten, onAiLengthen, onAiContinue,\n isTwoStepInfographicGeneration, onRefineInfographicPrompt\n}) => {\n const [presentation, setPresentation] = useState<Presentation>(\n initialPresentation || { slides: [{ id: 'slide-1', elements: [] }], layout: { width: 12192000, height: 6858000 } }\n );\n\n const [history, setHistory] = useState<Presentation[]>([]);\n const [redoStack, setRedoStack] = useState<Presentation[]>([]);\n\n const [currentSlideIndex, setCurrentSlideIndex] = useState(0);\n const [selectedElementId, setSelectedElementId] = useState<string | null>(null);\n const [isPreviewMode, setIsPreviewMode] = useState(false);\n const [askAiResponse, setAskAiResponse] = useState<string | null>(null);\n const [refineResponse, setRefineResponse] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [source, setSource] = useState<PresentationSource | null>(initialSource || (url ? 'url' : null));\n const [showInitialLayout, setShowInitialLayout] = useState(showHomeOnEmpty && !initialPresentation && !url && !initialSource);\n const [urlInput, setUrlInput] = useState('');\n const [slashMenu, setSlashMenu] = useState<{\n visible: boolean,\n position: { x: number, y: number },\n mode: 'default' | 'textbox' | 'text-selection',\n context?: any\n }>({\n visible: false,\n position: { x: 0, y: 0 },\n mode: 'default'\n });\n const [isImageGenOpen, setIsImageGenOpen] = useState(false);\n const [imageGenPrompt, setImageGenPrompt] = useState('');\n const [isGeneratingImage, setIsGeneratingImage] = useState(false);\n const [pendingImage, setPendingImage] = useState<string | null>(null);\n const [imageError, setImageError] = useState(false);\n const [previewLoading, setPreviewLoading] = useState(false);\n const [isInfographicGenOpen, setIsInfographicGenOpen] = useState(false);\n const [infographicGenPrompt, setInfographicGenPrompt] = useState('');\n const [isGeneratingInfographic, setIsGeneratingInfographic] = useState(false);\n const [pendingInfographic, setPendingInfographic] = useState<string | null>(null);\n const [infographicError, setInfographicError] = useState(false);\n const [isRefiningInfographic, setIsRefiningInfographic] = useState(false);\n const [refinedInfographicPrompt, setRefinedInfographicPrompt] = useState<string | null>(null);\n const [showInfographicPreview, setShowInfographicPreview] = useState(false);\n\n // Snackbar State\n const [snackbar, setSnackbar] = useState<{ open: boolean; message: string; type: SnackbarType }>({\n open: false,\n message: '',\n type: 'info'\n });\n\n const showSnackbar = (message: string, type: SnackbarType = 'info') => {\n setSnackbar({ open: true, message, type });\n };\n\n useEffect(() => {\n if (pendingImage) {\n setImageError(false);\n setPreviewLoading(true);\n }\n }, [pendingImage]);\n\n useEffect(() => {\n if (pendingInfographic) {\n setInfographicError(false);\n setPreviewLoading(true);\n }\n }, [pendingInfographic]);\n\n useEffect(() => {\n if (url) {\n handleLoadPresentation(url);\n }\n }, [url]);\n const [isAiLoading, setIsAiLoading] = useState(false);\n const [lastAiPrompt, setLastAiPrompt] = useState<{ id: string, action: 'shorten' | 'reframe' | 'lengthen' } | null>(null);\n\n // Clear AI states when selection changes\n useEffect(() => {\n setAskAiResponse(null);\n setRefineResponse(null);\n setLastAiPrompt(null);\n setIsAiLoading(false);\n }, [selectedElementId]);\n\n // Calculate UI scale based on width/height\n const uiScale = useMemo(() => {\n const w = typeof width === 'number' ? width : parseInt(String(width));\n if (isNaN(w)) return 1;\n // Base width for 1x scale is 1600px\n // Range: 0.4 to 1.0 (never scale up beyond 1x)\n return Math.min(Math.max(w / 1600, 0.4), 1);\n }, [width]);\n\n const currentSlide = presentation.slides[currentSlideIndex];\n\n const selectedElement = useMemo(() => {\n return currentSlide.elements.find(el => el.id === selectedElementId) || null;\n }, [currentSlide, selectedElementId]);\n\n const saveToHistory = useCallback((state: Presentation) => {\n setHistory(prevHistory => [...prevHistory.slice(-19), presentation]);\n setRedoStack([]);\n setPresentation(state);\n onChange?.(state);\n }, [onChange, presentation]);\n\n const undo = () => {\n if (history.length === 0) return;\n const last = history[history.length - 1];\n setRedoStack(prev => [...prev, presentation]);\n setHistory(prev => prev.slice(0, -1));\n setPresentation(last);\n };\n\n const redo = () => {\n if (redoStack.length === 0) return;\n const next = redoStack[redoStack.length - 1];\n setHistory(prev => [...prev, presentation]);\n setRedoStack(prev => prev.slice(0, -1));\n setPresentation(next);\n };\n\n const handleUpdateSlide = useCallback((updates: Partial<Slide>) => {\n setPresentation(prev => {\n const newSlides = [...prev.slides];\n newSlides[currentSlideIndex] = { ...newSlides[currentSlideIndex], ...updates };\n const updated = { ...prev, slides: newSlides };\n\n // Note: We can't call saveToHistory inside here easily without dependency issues, \n // but we can move history logic here if needed or keep it simple for now.\n // For now, let's just make it stable.\n setHistory(h => [...h.slice(-19), prev]);\n setRedoStack([]);\n onChange?.(updated);\n return updated;\n });\n }, [currentSlideIndex, onChange]);\n\n const handleElementUpdate = useCallback((elementId: string, updates: Partial<SlideElement>) => {\n setPresentation(prev => {\n const slide = prev.slides[currentSlideIndex];\n const newElements = slide.elements.map(el =>\n el.id === elementId ? { ...el, ...updates } as SlideElement : el\n );\n const newSlides = [...prev.slides];\n newSlides[currentSlideIndex] = { ...slide, elements: newElements };\n const updated = { ...prev, slides: newSlides };\n onChange?.(updated);\n return updated;\n });\n }, [currentSlideIndex, onChange]);\n\n const handleFormatText = (updates: any) => {\n if (!selectedElementId) return;\n const el = currentSlide.elements.find(e => e.id === selectedElementId);\n if (el) {\n handleElementUpdate(selectedElementId, updates);\n // Explicitly save to history for discrete formatting actions\n const slide = presentation.slides[currentSlideIndex];\n const newElements = slide.elements.map(e => e.id === selectedElementId ? { ...e, ...updates } : e);\n const newSlides = [...presentation.slides];\n newSlides[currentSlideIndex] = { ...slide, elements: newElements };\n saveToHistory({ ...presentation, slides: newSlides });\n }\n };\n\n const handleDeleteElement = useCallback(() => {\n if (!selectedElementId) return;\n const slide = presentation.slides[currentSlideIndex];\n const newElements = slide.elements.filter(el => el.id !== selectedElementId);\n handleUpdateSlide({ elements: newElements });\n setSelectedElementId(null);\n }, [selectedElementId, currentSlideIndex, presentation, handleUpdateSlide]);\n\n const handleAddText = () => {\n const newElement: SlideElement = {\n id: `text-${Date.now()}`,\n type: 'text',\n content: 'New Text',\n x: 100,\n y: 100,\n width: 400,\n height: 100,\n fontSize: 48,\n fontFamily: 'Arial',\n color: '#000000',\n zIndex: currentSlide.elements.length\n };\n handleUpdateSlide({ elements: [...currentSlide.elements, newElement] });\n };\n\n const handleAddImage = useCallback(async (input: File | string) => {\n let src = '';\n if (typeof input === 'string') {\n src = input;\n } else {\n src = await new Promise((resolve) => {\n const reader = new FileReader();\n reader.onload = (e) => resolve(e.target?.result as string);\n reader.readAsDataURL(input);\n });\n }\n const id = `img-${Date.now()}`;\n const newElement: SlideElement = {\n id,\n type: 'image',\n src: src,\n x: 100,\n y: 100,\n width: 400,\n height: 250,\n zIndex: currentSlide.elements.length\n };\n handleUpdateSlide({ elements: [...currentSlide.elements, newElement] });\n setSelectedElementId(id);\n }, [currentSlide.elements, handleUpdateSlide, setSelectedElementId]);\n\n const handleAddShape = (shapeType: ShapeType) => {\n const newElement: SlideElement = {\n id: `shape-${Date.now()}`,\n type: 'shape',\n shapeType,\n fill: '#3b82f6',\n x: 200,\n y: 200,\n width: 200,\n height: 200,\n zIndex: currentSlide.elements.length\n };\n handleUpdateSlide({ elements: [...currentSlide.elements, newElement] });\n }\n\n const handleAddSlide = () => {\n const newSlide: Slide = { id: `slide-${Date.now()}`, elements: [] };\n saveToHistory({ ...presentation, slides: [...presentation.slides, newSlide] });\n setCurrentSlideIndex(presentation.slides.length);\n };\n\n const handleDeleteSlide = (index: number) => {\n if (presentation.slides.length <= 1) return;\n\n const newSlides = presentation.slides.filter((_, i) => i !== index);\n saveToHistory({ ...presentation, slides: newSlides });\n\n // Adjust current slide index if needed\n if (index <= currentSlideIndex) {\n setCurrentSlideIndex(Math.max(0, currentSlideIndex - 1));\n }\n };\n\n const handleDuplicateSlide = (index: number) => {\n const slideToClone = presentation.slides[index];\n const newSlide: Slide = {\n ...slideToClone,\n id: `slide-${Date.now()}`,\n elements: slideToClone.elements.map(el => ({\n ...el,\n id: `${el.type}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n }))\n };\n const newSlides = [...presentation.slides];\n newSlides.splice(index + 1, 0, newSlide);\n saveToHistory({ ...presentation, slides: newSlides });\n setCurrentSlideIndex(index + 1);\n };\n\n const handleReorderSlides = (oldIndex: number, newIndex: number) => {\n if (oldIndex === newIndex) return;\n const newSlides = [...presentation.slides];\n const [removed] = newSlides.splice(oldIndex, 1);\n newSlides.splice(newIndex, 0, removed);\n\n saveToHistory({ ...presentation, slides: newSlides });\n\n if (currentSlideIndex === oldIndex) {\n setCurrentSlideIndex(newIndex);\n } else if (currentSlideIndex > oldIndex && currentSlideIndex <= newIndex) {\n setCurrentSlideIndex(currentSlideIndex - 1);\n } else if (currentSlideIndex < oldIndex && currentSlideIndex >= newIndex) {\n setCurrentSlideIndex(currentSlideIndex + 1);\n }\n };\n\n const handleApplyLayout = (layoutType: 'title' | 'content' | 'split') => {\n let elements: SlideElement[] = [];\n const timestamp = Date.now();\n\n if (layoutType === 'title') {\n elements = [\n {\n id: `text-title-${timestamp}`,\n type: 'text',\n content: 'Presentation Title',\n x: 100,\n y: 200,\n width: 1000,\n height: 150,\n fontSize: 80,\n fontFamily: 'Inter',\n color: '#000000',\n textAlign: 'center',\n isBold: true,\n zIndex: 0\n },\n {\n id: `text-sub-${timestamp}`,\n type: 'text',\n content: 'Subtitle goes here',\n x: 200,\n y: 380,\n width: 800,\n height: 80,\n fontSize: 36,\n fontFamily: 'Inter',\n color: '#64748b',\n textAlign: 'center',\n zIndex: 1\n }\n ];\n } else if (layoutType === 'content') {\n elements = [\n {\n id: `text-title-${timestamp}`,\n type: 'text',\n content: 'Slide Title',\n x: 60,\n y: 40,\n width: 800,\n height: 80,\n fontSize: 48,\n fontFamily: 'Inter',\n color: '#000000',\n isBold: true,\n zIndex: 0\n },\n {\n id: `text-body-${timestamp}`,\n type: 'text',\n content: '• Add your points here\\n• Press Enter for new line\\n• Use the toolbar to format',\n x: 60,\n y: 150,\n width: 1080,\n height: 480,\n fontSize: 28,\n fontFamily: 'Inter',\n color: '#334155',\n zIndex: 1,\n isBulleted: true\n }\n ];\n } else if (layoutType === 'split') {\n elements = [\n {\n id: `text-title-${timestamp}`,\n type: 'text',\n content: 'Comparison Layout',\n x: 60,\n y: 40,\n width: 1080,\n height: 80,\n fontSize: 48,\n fontFamily: 'Inter',\n color: '#000000',\n isBold: true,\n textAlign: 'center',\n zIndex: 0\n },\n {\n id: `text-left-${timestamp}`,\n type: 'text',\n content: 'Left column content goes here.',\n x: 60,\n y: 180,\n width: 520,\n height: 400,\n fontSize: 24,\n fontFamily: 'Inter',\n color: '#334155',\n zIndex: 1\n },\n {\n id: `text-right-${timestamp}`,\n type: 'text',\n content: 'Right column content goes here.',\n x: 620,\n y: 180,\n width: 520,\n height: 400,\n fontSize: 24,\n fontFamily: 'Inter',\n color: '#334155',\n zIndex: 2\n }\n ];\n }\n\n handleUpdateSlide({ elements });\n };\n\n const handleAiAction = async (id: string, action: 'shorten' | 'reframe' | 'lengthen') => {\n const slide = presentation.slides[currentSlideIndex];\n const element = slide.elements.find(el => el.id === id);\n if (!element || element.type !== 'text') return;\n\n setIsAiLoading(true);\n setRefineResponse(null);\n setLastAiPrompt({ id, action });\n\n try {\n if (!geminiApiKey) {\n showSnackbar(\"Gemini API key is missing. Please provide it via the 'geminiApiKey' prop.\", 'error');\n setIsAiLoading(false);\n return;\n }\n const genAI = new GoogleGenerativeAI(geminiApiKey);\n const model = genAI.getGenerativeModel({\n model: \"gemini-flash-latest\",\n systemInstruction: \"You are a professional presentation assistant. Your task is to transform slide text according to specific user requests (shorten, reframe, or lengthen). \\n\\nCRITICAL RULES:\\n1. Return ONLY the transformed text. \\n2. Do NOT include any explanations, choices, or conversational fillers.\\n3. Do NOT use markdown formatting (like bolding or headers) unless specifically needed for bullet points.\\n4. If the input text is a title/headline, the output should be a professional title/headline.\\n5. If the input text is a bulleted list, the output MUST be a bulleted list using the same bullet style (e.g., '•').\\n6. Maintain the professional tone of the original presentation.\"\n });\n\n const elementContext = element.fontSize > 32 ? \"Title/Headline\" : \"Body Text/List\";\n const prompt = `Action: ${action.toUpperCase()}\\nText Role: ${elementContext}\\nOriginal Text: \"${element.content}\"\\n\\nTransformed Text:`;\n\n const result = await model.generateContent(prompt);\n const response = await result.response;\n setRefineResponse(response.text().trim());\n } catch (error) {\n console.error(\"Gemini AI Error:\", error);\n showSnackbar(\"Error generating response. Please check your API key or connection.\", 'error');\n } finally {\n setIsAiLoading(false);\n }\n };\n\n const handleAiTextEdit = async (action: 'rewrite' | 'grammar' | 'shorten' | 'lengthen' | 'continue') => {\n const slide = presentation.slides[currentSlideIndex];\n const element = slide.elements.find(el => el.id === selectedElementId);\n if (!element || element.type !== 'text') return;\n\n setIsAiLoading(true);\n setAskAiResponse(null);\n setLastAiPrompt({ id: selectedElementId!, action: action as any }); // Cast for now, might need to update type\n\n try {\n let resultText = '';\n\n // 1. Try Custom Props\n if (action === 'rewrite' && onAiRewrite) resultText = await onAiRewrite(element.content);\n else if (action === 'grammar' && onAiGrammar) resultText = await onAiGrammar(element.content);\n else if (action === 'shorten' && onAiShorten) resultText = await onAiShorten(element.content);\n else if (action === 'lengthen' && onAiLengthen) resultText = await onAiLengthen(element.content);\n else if (action === 'continue' && onAiContinue) resultText = await onAiContinue(element.content);\n\n // 2. Fallback to Gemini if no custom prop or if custom prop returned empty (optional behavior, assumed strictly prop OR gemini)\n if (!resultText) {\n if (!geminiApiKey) {\n showSnackbar(\"Gemini API key is missing and no custom AI route provided.\", 'error');\n setIsAiLoading(false);\n return;\n }\n\n const genAI = new GoogleGenerativeAI(geminiApiKey);\n const model = genAI.getGenerativeModel({ model: \"gemini-flash-latest\" });\n\n let systemPrompt = \"You are a professional editor. Return ONLY the edited text. No explanations.\";\n let userPrompt = `original text: \"${element.content}\"`;\n\n switch (action) {\n case 'rewrite': userPrompt = `Improve the writing of: \"${element.content}\"`; break;\n case 'grammar': userPrompt = `Fix grammar in: \"${element.content}\"`; break;\n case 'shorten': userPrompt = `Make this shorter: \"${element.content}\"`; break;\n case 'lengthen': userPrompt = `Make this longer: \"${element.content}\"`; break;\n case 'continue': userPrompt = `Continue writing from: \"${element.content}\"`; break;\n }\n\n const result = await model.generateContent(`${systemPrompt}\\n\\n${userPrompt}`);\n resultText = result.response.text().trim();\n }\n\n setAskAiResponse(resultText);\n } catch (error) {\n console.error(\"AI Text Edit Error:\", error);\n showSnackbar(\"AI editing failed. Please check configuration.\", 'error');\n } finally {\n setIsAiLoading(false);\n }\n };\n\n const handleAiResponseAction = (action: 'replace' | 'addBelow' | 'discard' | 'regenerate') => {\n if (!askAiResponse || !lastAiPrompt) return;\n\n if (action === 'regenerate') {\n handleAiTextEdit(lastAiPrompt.action as any);\n return;\n }\n\n const slide = presentation.slides[currentSlideIndex];\n const originalElement = slide.elements.find(el => el.id === lastAiPrompt.id);\n if (!originalElement || originalElement.type !== 'text') return;\n\n if (action === 'replace') {\n handleElementUpdate(lastAiPrompt.id, { content: askAiResponse });\n } else if (action === 'addBelow') {\n const newElement: SlideElement = {\n ...originalElement,\n id: `text-ai-${Date.now()}`,\n content: askAiResponse,\n y: originalElement.y + originalElement.height + 20,\n zIndex: slide.elements.length\n };\n handleUpdateSlide({ elements: [...slide.elements, newElement] });\n }\n\n setAskAiResponse(null);\n setLastAiPrompt(null);\n setSlashMenu(prev => ({ ...prev, visible: false }));\n };\n\n const handleRefineResponseAction = (action: 'replace' | 'addBelow' | 'discard' | 'regenerate') => {\n if (!refineResponse || !lastAiPrompt) return;\n\n if (action === 'discard') {\n setRefineResponse(null);\n return;\n }\n\n if (action === 'regenerate') {\n handleAiAction(lastAiPrompt.id, lastAiPrompt.action);\n return;\n }\n\n const slide = presentation.slides[currentSlideIndex];\n const originalElement = slide.elements.find(el => el.id === lastAiPrompt.id);\n if (!originalElement || originalElement.type !== 'text') return;\n\n if (action === 'replace') {\n handleElementUpdate(lastAiPrompt.id, { content: refineResponse });\n } else if (action === 'addBelow') {\n const newElement: SlideElement = {\n ...originalElement,\n id: `text-refine-${Date.now()}`,\n content: refineResponse,\n y: originalElement.y + originalElement.height + 20,\n zIndex: slide.elements.length\n };\n handleUpdateSlide({ elements: [...slide.elements, newElement] });\n }\n\n setRefineResponse(null);\n setLastAiPrompt(null);\n };\n\n const handleExport = async () => {\n const exporter = new PptxExporter();\n await exporter.export(presentation);\n };\n\n const handlePlay = () => {\n setIsPreviewMode(true);\n const elem = document.documentElement;\n if (elem.requestFullscreen) {\n elem.requestFullscreen();\n }\n };\n\n const handleClosePresenter = () => {\n setIsPreviewMode(false);\n if (document.fullscreenElement) {\n document.exitFullscreen();\n }\n };\n\n useEffect(() => {\n const handleFullscreenChange = () => {\n if (!document.fullscreenElement) {\n setIsPreviewMode(false);\n }\n };\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => document.removeEventListener('fullscreenchange', handleFullscreenChange);\n }, []);\n\n // Keyboard navigation\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Delete' || e.key === 'Backspace') {\n const activeElement = document.activeElement;\n if (activeElement?.tagName === 'INPUT' || activeElement?.tagName === 'TEXTAREA' || (activeElement as any)?.isContentEditable) return;\n handleDeleteElement();\n }\n if (e.key === 'Escape') {\n setSelectedElementId(null);\n setSlashMenu(prev => ({ ...prev, visible: false }));\n }\n if (e.ctrlKey || e.metaKey) {\n if (e.key === 'z') {\n e.preventDefault();\n if (e.shiftKey) redo(); else undo();\n }\n if (e.key === 'y') {\n e.preventDefault();\n redo();\n }\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [handleDeleteElement, undo, redo]);\n\n const updateSource = (newSource: PresentationSource, url?: string) => {\n setSource(newSource);\n onSourceChange?.(newSource, url);\n };\n\n const handleNewPresentation = () => {\n setPresentation({\n slides: [{ id: `slide-${Date.now()}`, elements: [] }],\n layout: { width: 12192000, height: 6858000 }\n });\n setCurrentSlideIndex(0);\n setSelectedElementId(null);\n updateSource('scratch');\n };\n\n const handleLoadPresentation = async (input: File | string) => {\n setIsLoading(true);\n try {\n const parser = new PptxParser();\n let prompt = input;\n if (typeof input === 'string') {\n const trimmedInput = input.trim();\n prompt = proxyUrl\n ? `${proxyUrl}${proxyUrl.includes('?') ? '&' : '?'}url=${encodeURIComponent(trimmedInput)}`\n : trimmedInput;\n updateSource('url', trimmedInput);\n } else {\n updateSource('uploaded');\n }\n const result = await parser.parse(prompt);\n setPresentation(result);\n setHistory([]);\n setRedoStack([]);\n setCurrentSlideIndex(0);\n setSelectedElementId(null);\n } catch (err) {\n console.error('Failed to load PPTX', err);\n showSnackbar('Failed to load presentation. Please ensure it is a valid .pptx.', 'error');\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleSlashAction = (actionId: string, payload?: any) => {\n if (actionId !== 'ai-text-edit') {\n setSlashMenu(prev => ({ ...prev, visible: false }));\n }\n\n switch (actionId) {\n case 'add-text': handleAddText(); break;\n case 'add-image': handleUploadImageClick(); break;\n case 'add-shape': handleAddShape(payload as ShapeType); break;\n case 'new-slide': handleAddSlide(); break;\n case 'ai-action': handleAiAction(selectedElementId || '', payload); break;\n case 'ai-text-edit': handleAiTextEdit(payload); break;\n case 'generate-image': setIsImageGenOpen(true); break;\n case 'generate-infographic': handleOpenInfographic(); break;\n case 'format': handleFormatText(payload); break;\n case 'delete': handleDeleteElement(); break;\n }\n };\n\n const handleGenerateImage = async () => {\n if (!imageGenPrompt.trim()) return;\n setIsGeneratingImage(true);\n try {\n let imageUrl = '';\n if (onGenerateImage) {\n imageUrl = await onGenerateImage(imageGenPrompt);\n } else if (geminiApiKey) {\n // Fallback to internal Gemini if key is provided (mocking for now as Gemini doesn't have a direct image gen API via this specific JS SDK easily without Vertex AI)\n // In a real scenario, this would call a known endpoint.\n throw new Error(\"Internal image generation requires onGenerateImage prop or specific endpoint configuration.\");\n } else {\n throw new Error(\"No image generation function or Gemini API key provided.\");\n }\n setPendingImage(imageUrl);\n setIsImageGenOpen(false);\n setImageGenPrompt('');\n } catch (error) {\n console.error(\"Image generation failed:\", error);\n showSnackbar(\"Image generation failed: \" + (error instanceof Error ? error.message : \"Unknown error\"), 'error');\n } finally {\n setIsGeneratingImage(false);\n }\n };\n\n const handleFinalizeImage = (action: 'insert' | 'replace' | 'discard') => {\n if (action === 'insert' && pendingImage) {\n handleAddImage(pendingImage);\n } else if (action === 'replace' && pendingImage && selectedElementId) {\n const el = presentation.slides[currentSlideIndex].elements.find(e => e.id === selectedElementId);\n if (el && el.type === 'image') {\n handleElementUpdate(selectedElementId, { src: pendingImage });\n } else {\n handleAddImage(pendingImage); // Fallback to insert if not an image\n }\n }\n setPendingImage(null);\n };\n\n const handleGenerateInfographic = async (customPrompt?: string) => {\n const promptToUse = customPrompt || infographicGenPrompt;\n if (!promptToUse.trim()) return;\n setIsGeneratingInfographic(true);\n setShowInfographicPreview(false);\n setPendingInfographic(null);\n try {\n let infographicUrl = '';\n if (onGenerateInfographic) {\n infographicUrl = await onGenerateInfographic(promptToUse);\n } else if (geminiApiKey) {\n // Fallback / Mock\n // throw new Error(\"Internal info gen...\");\n // For now, let's just mock it or throw if not provided, similar to image gen\n throw new Error(\"Internal infographic generation requires onGenerateInfographic prop or specific endpoint configuration.\");\n } else {\n throw new Error(\"No infographic generation function or Gemini API key provided.\");\n }\n setPendingInfographic(infographicUrl);\n\n // Preload image to ensure loading modal covers the image loading time\n const img = new Image();\n img.src = proxyUrl ? `${proxyUrl}${encodeURIComponent(infographicUrl)}` : infographicUrl;\n\n await new Promise((resolve, reject) => {\n img.onload = resolve;\n img.onerror = () => {\n // Even if it fails, we proceed to show the preview modal (which handles errors)\n // or we could throw here. Let's proceed to allow the preview modal's UI to specific error.\n console.log(\"Image preload failed, proceeding to preview\");\n resolve(null);\n };\n });\n\n setShowInfographicPreview(true);\n setIsInfographicGenOpen(false);\n setInfographicGenPrompt('');\n } catch (error) {\n console.error(\"Infographic generation failed:\", error);\n showSnackbar(\"Infographic generation failed: \" + (error instanceof Error ? error.message : \"Unknown error\"), 'error');\n } finally {\n setIsGeneratingInfographic(false);\n }\n };\n\n const handleFinalizeInfographic = (action: 'insert' | 'replace' | 'discard') => {\n if (action === 'insert' && pendingInfographic) {\n handleAddImage(pendingInfographic); // Treat as image\n } else if (action === 'replace' && pendingInfographic && selectedElementId) {\n const el = presentation.slides[currentSlideIndex].elements.find(e => e.id === selectedElementId);\n if (el && el.type === 'image') {\n handleElementUpdate(selectedElementId, { src: pendingInfographic });\n } else {\n handleAddImage(pendingInfographic);\n }\n }\n setPendingInfographic(null);\n };\n\n const handleOpenInfographic = async () => {\n if (isTwoStepInfographicGeneration && onRefineInfographicPrompt) {\n const textToRefine = selectedElement?.type === 'text' ? selectedElement.content : '';\n if (textToRefine) {\n setIsRefiningInfographic(true);\n try {\n const refined = await onRefineInfographicPrompt(textToRefine);\n setRefinedInfographicPrompt(refined);\n } catch (error) {\n console.error(\"Prompt refinement failed:\", error);\n showSnackbar(\"Failed to refine infographic prompt.\", 'error');\n } finally {\n setIsRefiningInfographic(false);\n }\n return;\n }\n }\n setIsInfographicGenOpen(true);\n };\n\n const handleUploadImageClick = () => {\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = 'image/*';\n input.onchange = async (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (file) {\n const src = await new Promise<string>((resolve) => {\n const reader = new FileReader();\n reader.onload = (re) => resolve(re.target?.result as string);\n reader.readAsDataURL(file);\n });\n setPendingImage(src);\n }\n };\n input.click();\n };\n\n const getProxiedUrl = useCallback((url: string) => {\n if (!proxyUrl || !url || url.startsWith('data:')) return url;\n if (url.includes('localhost') || url.includes('127.0.0.1')) return url;\n return `${proxyUrl}?url=${encodeURIComponent(url)}`;\n }, [proxyUrl]);\n\n if (!width || !height) {\n return (\n <div className=\"flex items-center justify-center bg-red-50 text-red-600 p-8 rounded-xl border-2 border-red-200 font-bold\">\n Error: width and height props are compulsory for PptEditor.\n </div>\n );\n }\n\n return (\n <div\n className=\"flex flex-col bg-white relative\"\n style={{\n width: typeof width === 'number' ? `${width}px` : width,\n height: typeof height === 'number' ? `${height}px` : height,\n fontSize: `${16 * uiScale}px`\n }}\n >\n {showInitialLayout && (\n <div className=\"absolute inset-0 z-[2000] bg-white flex flex-col items-center justify-center p-6 md:p-12 overflow-y-auto\">\n <div className=\"max-w-2xl w-full text-center space-y-6 md:space-y-8 animate-in fade-in zoom-in-95 duration-500 my-auto\">\n <div className=\"flex justify-center\">\n {/* <div className=\"p-6 rounded-3xl\" style={{ backgroundColor: `${appBgColor}10` }}>\n <div className=\"p-4 rounded-2xl\" style={{ backgroundColor: appBgColor }}>\n <svg className=\"w-10 h-10 text-white\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7\" />\n </svg>\n </div>\n </div> */}\n </div>\n <div className=\"space-y-2\">\n <h2 className=\"text-4xl font-black tracking-tight text-slate-800\">{appName}</h2>\n <p className=\"text-slate-500 font-medium\">Create stunning presentations in seconds.</p>\n </div>\n <div className=\"grid grid-cols-2 gap-6\">\n <button\n onClick={() => { handleNewPresentation(); setShowInitialLayout(false); }}\n className=\"flex flex-col items-center justify-center gap-4 p-10 border-2 border-slate-100 rounded-[2.5rem] hover:border-slate-300 hover:bg-slate-50 transition-all group shadow-sm hover:shadow-md active:scale-[0.98]\"\n >\n <div className=\"p-5 bg-slate-100 rounded-2xl group-hover:bg-blue-50 transition-colors\">\n <svg className=\"w-10 h-10 text-blue-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2.5} d=\"M12 4v16m8-8H4\" />\n </svg>\n </div>\n <span className=\"text-sm font-black uppercase tracking-[0.15em] text-slate-600 group-hover:text-slate-900 transition-colors\">Start New Deck</span>\n </button>\n <label className=\"flex flex-col items-center justify-center gap-4 p-10 border-2 border-slate-100 rounded-[2.5rem] hover:border-slate-300 hover:bg-slate-50 transition-all group shadow-sm hover:shadow-md active:scale-[0.98] cursor-pointer\">\n <div className=\"p-5 bg-slate-100 rounded-2xl group-hover:bg-emerald-50 transition-colors\">\n <svg className=\"w-10 h-10 text-emerald-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2.5} d=\"M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1m-4-8l-4-4m0 0L8 8m4-4v12\" />\n </svg>\n </div>\n <span className=\"text-sm font-black uppercase tracking-[0.15em] text-slate-600 group-hover:text-slate-900 transition-colors\">Upload PPTX</span>\n <input\n type=\"file\"\n accept=\".pptx\"\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (file) {\n handleLoadPresentation(file);\n setShowInitialLayout(false);\n }\n }}\n />\n </label>\n </div>\n\n {/* URL Input */}\n <div className=\"space-y-4 pt-8 border-t border-slate-100\">\n <div className=\"flex gap-3 items-stretch\">\n <div className=\"flex-1 relative group\">\n {/* <svg className=\"absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-slate-400 group-focus-within:text-slate-600 transition-colors\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9h18\" />\n </svg> */}\n <input\n type=\"text\"\n placeholder=\"Paste presentation URL...\"\n value={urlInput}\n onChange={(e) => setUrlInput(e.target.value)}\n className=\"text-black w-full bg-slate-50 border border-slate-200 rounded-2xl pl-12 pr-5 py-4 focus:outline-none focus:border-slate-400 focus:ring-4 focus:ring-slate-400/5 text-base transition-all h-full\"\n />\n </div>\n <button\n onClick={() => {\n if (urlInput.trim()) {\n handleLoadPresentation(urlInput.trim());\n setShowInitialLayout(false);\n }\n }}\n disabled={!urlInput.trim() || isLoading}\n style={{ cursor: 'pointer' }}\n className=\"bg-slate-900 hover:bg-black disabled:bg-slate-100 disabled:text-slate-400 text-white font-black px-10 rounded-2xl transition-all shadow-sm text-sm shrink-0 whitespace-nowrap h-full min-h-[56px] flex items-center justify-center uppercase tracking-widest\"\n >\n {isLoading ? (\n <svg className=\"animate-spin h-5 w-5 text-white\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n ) : 'Load'}\n </button>\n </div>\n <p className=\"text-[10px] text-slate-400 font-bold uppercase tracking-[0.2em]\">\n Supports S3, public links, and versioned assets\n </p>\n </div>\n </div>\n </div>\n )}\n {isPreviewMode && (\n <PresenterMode\n presentation={presentation}\n initialSlideIndex={currentSlideIndex}\n onClose={handleClosePresenter}\n />\n )}\n <Toolbar\n onAddText={handleAddText}\n onAddImage={handleAddImage}\n onAddShape={handleAddShape}\n onAddSlide={handleAddSlide}\n onExport={handleExport}\n onFormatText={handleFormatText}\n onDeleteElement={handleDeleteElement}\n onGenerateImageClick={() => setIsImageGenOpen(true)}\n onGenerateInfographicClick={handleOpenInfographic}\n onUploadImageClick={handleUploadImageClick}\n onApplyLayout={handleApplyLayout}\n onPlay={() => setIsPreviewMode(true)}\n onAiAction={handleAiAction}\n onAiResponseAction={handleAiResponseAction}\n onNewPresentation={handleNewPresentation}\n onLoadPresentation={handleLoadPresentation}\n aiResponse={askAiResponse}\n isAiLoading={isAiLoading}\n selectedElement={selectedElement}\n refineResponse={refineResponse}\n onRefineAction={handleAiAction}\n appName={appName}\n appBgColor={appBgColor}\n uiScale={uiScale}\n source={source}\n />\n <div className=\"flex flex-1 overflow-hidden\">\n <Sidebar\n slides={presentation.slides}\n currentSlideIndex={currentSlideIndex}\n onSelectSlide={setCurrentSlideIndex}\n onDeleteSlide={handleDeleteSlide}\n onDuplicateSlide={handleDuplicateSlide}\n onReorderSlides={handleReorderSlides}\n uiScale={uiScale}\n appBgColor={appBgColor}\n />\n <div className=\"flex-1 flex items-center justify-center p-12 overflow-auto bg-white\">\n <EditorCanvas\n slide={currentSlide}\n onElementUpdate={handleElementUpdate}\n onSelect={setSelectedElementId}\n uiScale={uiScale}\n onSlashCommand={(position, mode, context) => setSlashMenu({\n visible: position.x !== 0,\n position,\n mode: mode || 'default',\n context\n })}\n selectedElementId={selectedElementId}\n onAiGenerateClick={() => setIsImageGenOpen(true)}\n onAiGenerateInfographicClick={handleOpenInfographic}\n onUploadImageClick={handleUploadImageClick}\n onDeleteElement={handleDeleteElement}\n />\n </div>\n </div>\n\n {slashMenu.visible && (\n <div\n className=\"fixed inset-0 z-[9998]\"\n onClick={() => setSlashMenu(prev => ({ ...prev, visible: false }))}\n >\n <SlashMenu\n position={slashMenu.position}\n onClose={() => setSlashMenu(prev => ({ ...prev, visible: false }))}\n onAction={handleSlashAction}\n canUseAi={!!geminiApiKey || !!proxyUrl}\n mode={slashMenu.mode}\n context={slashMenu.context}\n aiResult={askAiResponse}\n isAiLoading={isAiLoading}\n onAiResponseAction={handleAiResponseAction}\n />\n </div>\n )}\n\n {refineResponse && selectedElement && (\n <RefineMenu\n result={refineResponse}\n isLoading={isAiLoading}\n onAction={handleRefineResponseAction}\n onClose={() => setRefineResponse(null)}\n />\n )}\n\n {isImageGenOpen && (\n <div className=\"fixed inset-0 z-[9999] flex items-center justify-center bg-black/40 backdrop-blur-sm animate-in fade-in duration-200\">\n <div className=\"bg-white rounded-2xl shadow-2xl w-[500px] p-6 flex flex-col gap-4 animate-in zoom-in-95 duration-200\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-xl font-bold text-slate-800 flex items-center gap-2\">\n <Sparkles className=\"text-blue-600\" size={20} />\n Generate Image\n </h3>\n <button onClick={() => setIsImageGenOpen(false)} className=\"text-slate-400 hover:text-slate-600\">\n <Plus className=\"rotate-45\" size={24} />\n </button>\n </div>\n <p className=\"text-sm text-slate-500\">Describe the image you want to create for this slide.</p>\n <textarea\n autoFocus\n placeholder=\"A futuristic city in the style of cyberpunk with neon lights...\"\n className=\"text-black w-full h-32 p-4 bg-slate-50 border border-slate-200 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 text-sm font-medium resize-none\"\n value={imageGenPrompt}\n onChange={(e) => setImageGenPrompt(e.target.value)}\n />\n <div className=\"flex justify-end gap-3\">\n <button\n onClick={() => setIsImageGenOpen(false)}\n className=\"flex-1 px-5 py-3 cursor-pointer text-sm font-bold text-slate-600 hover:bg-slate-100 rounded-lg transition-colors flex items-center justify-center\"\n >\n Cancel\n </button>\n <button\n onClick={handleGenerateImage}\n disabled={isGeneratingImage || !imageGenPrompt.trim()}\n className=\"flex-1 px-6 py-3 cursor-pointer text-sm font-bold text-white bg-blue-600 hover:bg-blue-700 rounded-lg shadow-lg shadow-blue-500/20 transition-all active:scale-95 disabled:opacity-50 disabled:active:scale-100 flex items-center justify-center gap-2\"\n >\n {isGeneratingImage ? (\n <>\n <RefreshCw className=\"animate-spin\" size={16} />\n Generating...\n </>\n ) : (\n 'Generate'\n )}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {pendingImage && (\n <div className=\"fixed inset-0 z-[10000] flex items-center justify-center bg-black/60 backdrop-blur-md animate-in fade-in duration-300\">\n <div className=\"bg-white rounded-2xl shadow-3xl max-w-[90vw] max-h-[90vh] overflow-hidden flex flex-col animate-in zoom-in-95 duration-300 border border-slate-200\">\n <div className=\"p-4 border-b border-slate-100 flex items-center justify-between bg-white\">\n <h3 className=\"text-lg font-bold text-slate-800\">Preview Image</h3>\n <button onClick={() => setPendingImage(null)} className=\"p-2 hover:bg-slate-100 rounded-full text-slate-400 transition-colors\">\n <Plus className=\"rotate-45\" size={20} />\n </button>\n </div>\n\n <div className=\"p-8 bg-slate-100 flex items-center justify-center overflow-auto min-h-[300px] relative\">\n {previewLoading && !imageError && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-slate-100/50 z-10\">\n <RefreshCw className=\"animate-spin text-slate-400\" size={32} />\n </div>\n )}\n <img\n src={getProxiedUrl(pendingImage)}\n alt=\"Generated\"\n className={cn(\n \"max-w-full max-h-[60vh] rounded-lg shadow-2xl ring-4 ring-white transition-opacity duration-300\",\n (imageError || previewLoading) ? \"opacity-0\" : \"opacity-100\"\n )}\n onLoad={() => setPreviewLoading(false)}\n onError={() => {\n setImageError(true);\n setPreviewLoading(false);\n }}\n />\n {imageError && (\n <div className=\"flex flex-col items-center gap-4 text-slate-400 p-12 text-center animate-in fade-in duration-500\">\n <div className=\"p-4 bg-slate-200/50 rounded-full\">\n <ImageIcon size={48} className=\"opacity-40\" />\n </div>\n <div>\n <p className=\"font-bold text-slate-600\">Failed to load preview</p>\n <p className=\"text-xs max-w-[300px] mt-1\">The URL might be invalid or restricted. Ensure it's a valid image format.</p>\n </div>\n <code className=\"text-[10px] bg-slate-200/50 px-2 py-1 rounded break-all max-w-[400px]\">\n {pendingImage}\n </code>\n </div>\n )}\n </div>\n\n <div className=\"p-6 bg-white border-t border-slate-100 flex flex-col gap-4\">\n <div className=\"flex gap-3 justify-center\">\n <button\n onClick={() => handleFinalizeImage('insert')}\n className=\"flex-1 px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white rounded-xl font-bold shadow-lg shadow-blue-500/20 transition-all flex items-center justify-center gap-2\"\n >\n <Check size={18} />\n Insert image\n </button>\n {selectedElementId && presentation.slides[currentSlideIndex].elements.find(e => e.id === selectedElementId)?.type === 'image' && (\n <button\n onClick={() => handleFinalizeImage('replace')}\n className=\"flex-1 px-6 py-3 bg-emerald-600 hover:bg-emerald-700 text-black rounded-xl font-bold shadow-lg shadow-emerald-500/20 transition-all flex items-center justify-center gap-2\"\n >\n <RefreshCw size={18} />\n Replace existing\n </button>\n )}\n </div>\n <button\n onClick={() => handleFinalizeImage('discard')}\n className=\"w-full px-6 py-3 bg-red-50 hover:bg-red-100 text-red-600 rounded-xl font-bold transition-all flex items-center justify-center gap-2\"\n >\n <Trash2 size={18} />\n Discard\n </button>\n </div>\n </div>\n </div>\n )}\n\n\n\n {isInfographicGenOpen && (\n <div className=\"fixed inset-0 z-[9999] flex items-center justify-center bg-black/40 backdrop-blur-sm animate-in fade-in duration-200\">\n <div className=\"bg-white rounded-2xl shadow-2xl w-[500px] p-6 flex flex-col gap-4 animate-in zoom-in-95 duration-200\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-xl font-bold text-slate-800 flex items-center gap-2\">\n <PieChart className=\"text-blue-600\" size={20} />\n Generate Infographic\n </h3>\n <button onClick={() => setIsInfographicGenOpen(false)} className=\"text-slate-400 hover:text-slate-600\">\n <Plus className=\"rotate-45\" size={24} />\n </button>\n </div>\n <p className=\"text-sm text-slate-500\">Describe the infographic you want to create for this slide.</p>\n <textarea\n autoFocus\n placeholder=\"A pie chart showing market share distribution...\"\n className=\"text-black w-full h-32 p-4 bg-slate-50 border border-slate-200 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 text-sm font-medium resize-none\"\n value={infographicGenPrompt}\n onChange={(e) => setInfographicGenPrompt(e.target.value)}\n />\n <div className=\"flex justify-end gap-3\">\n <button\n onClick={() => setIsInfographicGenOpen(false)}\n className=\"flex-1 px-5 py-3 cursor-pointer text-sm font-bold text-slate-600 hover:bg-slate-100 rounded-lg transition-colors flex items-center justify-center\"\n >\n Cancel\n </button>\n <button\n onClick={() => handleGenerateInfographic()}\n disabled={isGeneratingInfographic || !infographicGenPrompt.trim()}\n className=\"flex-1 px-6 py-3 cursor-pointer text-sm font-bold text-white bg-blue-600 hover:bg-blue-700 rounded-lg shadow-lg shadow-blue-500/20 transition-all active:scale-95 disabled:opacity-50 disabled:active:scale-100 flex items-center justify-center gap-2\"\n >\n {isGeneratingInfographic ? (\n <>\n <RefreshCw className=\"animate-spin\" size={16} />\n Generating...\n </>\n ) : (\n 'Generate'\n )}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {(isGeneratingInfographic) && (\n <div className=\"fixed inset-0 z-[11000] flex items-center justify-center bg-black/20 backdrop-blur-[2px] animate-in fade-in duration-200\">\n <div className=\"bg-white rounded-2xl shadow-2xl p-8 flex flex-col items-center gap-4 animate-in zoom-in-95 duration-200\">\n <RefreshCw className=\"animate-spin text-blue-600\" size={32} />\n <p className=\"text-sm font-bold text-slate-600\">Generating Infographic...</p>\n </div>\n </div>\n )}\n\n {isRefiningInfographic && (\n <div className=\"fixed inset-0 z-[11000] flex items-center justify-center bg-black/20 backdrop-blur-[2px] animate-in fade-in duration-200\">\n <div className=\"bg-white rounded-2xl shadow-2xl p-8 flex flex-col items-center gap-4 animate-in zoom-in-95 duration-200\">\n <RefreshCw className=\"animate-spin text-blue-600\" size={32} />\n <p className=\"text-sm font-bold text-slate-600\">Polishing your prompt with AI...</p>\n </div>\n </div>\n )}\n\n {refinedInfographicPrompt !== null && (\n <div className=\"fixed inset-0 z-[9999] flex items-center justify-center bg-black/40 backdrop-blur-sm animate-in fade-in duration-200\">\n <div className=\"bg-white rounded-2xl shadow-2xl w-[600px] p-6 flex flex-col gap-4 animate-in zoom-in-95 duration-200\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-xl font-bold text-slate-800 flex items-center gap-2\">\n <Sparkles className=\"text-blue-600\" size={20} />\n Step 1: AI Refinement\n </h3>\n <button onClick={() => setRefinedInfographicPrompt(null)} className=\"text-slate-400 hover:text-slate-600\">\n <Plus className=\"rotate-45\" size={24} />\n </button>\n </div>\n <p className=\"text-sm text-slate-500\">The AI has refined your selected text into a visual prompt. You can adjust it below.</p>\n <textarea\n autoFocus\n className=\"text-black w-full h-48 p-4 bg-slate-50 border border-slate-200 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 text-sm font-medium resize-none shadow-inner\"\n value={refinedInfographicPrompt}\n onChange={(e) => setRefinedInfographicPrompt(e.target.value)}\n />\n <div className=\"flex justify-end gap-3 mt-2\">\n <button\n onClick={() => setRefinedInfographicPrompt(null)}\n className=\"flex-1 flex items-center justify-center px-5 py-3 text-sm font-bold text-slate-600 hover:bg-slate-100 rounded-lg transition-colors\"\n >\n Discard\n </button>\n <button\n onClick={() => {\n const finalPrompt = refinedInfographicPrompt;\n setRefinedInfographicPrompt(null);\n handleGenerateInfographic(finalPrompt);\n }}\n className=\"px-6 py-3 text-sm font-bold text-white bg-blue-600 hover:bg-blue-700 rounded-xl shadow-lg shadow-blue-500/20 transition-all active:scale-95 flex-1 flex items-center justify-center gap-2 uppercase tracking-wide\"\n >\n <PieChart size={18} />\n Generate Infographic\n </button>\n </div>\n </div>\n </div>\n )}\n\n {(showInfographicPreview && pendingInfographic) && (\n <div className=\"fixed inset-0 z-[10000] flex items-center justify-center bg-black/60 backdrop-blur-md animate-in fade-in duration-300\">\n <div className=\"bg-white rounded-2xl shadow-3xl max-w-[90vw] max-h-[90vh] overflow-hidden flex flex-col animate-in zoom-in-95 duration-300 border border-slate-200\">\n <div className=\"p-4 border-b border-slate-100 flex items-center justify-between bg-white\">\n <h3 className=\"text-lg font-bold text-slate-800\">Preview Infographic</h3>\n <button onClick={() => setPendingInfographic(null)} className=\"p-2 hover:bg-slate-100 rounded-full text-slate-400 transition-colors\">\n <Plus className=\"rotate-45\" size={20} />\n </button>\n </div>\n\n <div className=\"p-8 bg-slate-100 flex items-center justify-center overflow-auto min-h-[300px] relative\">\n {previewLoading && !infographicError && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-slate-100/50 z-10\">\n <RefreshCw className=\"animate-spin text-slate-400\" size={32} />\n </div>\n )}\n <img\n src={getProxiedUrl(pendingInfographic)}\n alt=\"Generated Infographic\"\n className={cn(\n \"max-w-full max-h-[60vh] rounded-lg shadow-2xl ring-4 ring-white transition-opacity duration-300\",\n (infographicError || previewLoading) ? \"opacity-0\" : \"opacity-100\"\n )}\n onLoad={() => setPreviewLoading(false)}\n onError={() => {\n setInfographicError(true);\n setPreviewLoading(false);\n }}\n />\n {infographicError && (\n <div className=\"flex flex-col items-center gap-4 text-slate-400 p-12 text-center animate-in fade-in duration-500\">\n <div className=\"p-4 bg-slate-200/50 rounded-full\">\n <PieChart size={48} className=\"opacity-40\" />\n </div>\n <div>\n <p className=\"font-bold text-slate-600\">Failed to load preview</p>\n <p className=\"text-xs max-w-[300px] mt-1\">The URL might be invalid or restricted. Ensure it's a valid image format.</p>\n </div>\n <code className=\"text-[10px] bg-slate-200/50 px-2 py-1 rounded break-all max-w-[400px]\">\n {pendingInfographic}\n </code>\n </div>\n )}\n </div>\n\n <div className=\"p-6 bg-white border-t border-slate-100 flex flex-col gap-4\">\n <div className=\"flex gap-3 justify-center\">\n <button\n onClick={() => handleFinalizeInfographic('insert')}\n className=\"flex-1 px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white rounded-xl font-bold shadow-lg shadow-blue-500/20 transition-all flex items-center justify-center gap-2\"\n >\n <Check size={18} />\n Insert infographic\n </button>\n {selectedElementId && presentation.slides[currentSlideIndex].elements.find(e => e.id === selectedElementId)?.type === 'image' && (\n <button\n onClick={() => handleFinalizeInfographic('replace')}\n className=\"flex-1 px-6 py-3 bg-emerald-600 hover:bg-emerald-700 text-black rounded-xl font-bold shadow-lg shadow-emerald-500/20 transition-all flex items-center justify-center gap-2\"\n >\n <RefreshCw size={18} />\n Replace existing\n </button>\n )}\n </div>\n <button\n onClick={() => handleFinalizeInfographic('discard')}\n className=\"w-full px-6 py-3 bg-red-50 hover:bg-red-100 text-red-600 rounded-xl font-bold transition-all flex items-center justify-center gap-2\"\n >\n <Trash2 size={18} />\n Discard\n </button>\n </div>\n </div>\n </div>\n )}\n\n {isPreviewMode && (\n <PresenterMode\n presentation={presentation}\n initialSlideIndex={currentSlideIndex}\n onClose={handleClosePresenter}\n />\n )}\n\n <Snackbar\n isOpen={snackbar.open}\n message={snackbar.message}\n type={snackbar.type}\n onClose={() => setSnackbar(prev => ({ ...prev, open: false }))}\n />\n </div>\n );\n};\n","'use client';\n\nimport React, { useState } from 'react';\nimport {\n Type, Image as ImageIcon, MousePointer2,\n Square, Circle, Download, Plus, Trash2,\n Bold, Italic, Underline, AlignLeft, AlignCenter, AlignRight, AlignJustify,\n List, ListOrdered, Layout as LayoutIcon, Columns, FileText, Highlighter, Eraser,\n History, Share2, Play, Sparkles, RefreshCw, Check, ChevronUp, ChevronDown,\n Strikethrough, Type as TypeIcon,\n FilePen\n} from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport { SlideElement, PresentationSource } from '../lib/types';\n\ninterface ToolbarProps {\n onAddText: () => void;\n onAddImage: (file: File) => void;\n onAddShape: (type: any) => void;\n onAddSlide: () => void;\n onExport: () => void;\n onFormatText: (updates: any) => void;\n onDeleteElement: () => void;\n onGenerateImageClick: () => void;\n onGenerateInfographicClick: () => void;\n onUploadImageClick: () => void;\n onApplyLayout: (type: 'title' | 'content' | 'split') => void;\n onPlay: () => void;\n selectedElement: SlideElement | null;\n appName: string;\n onAiAction: (id: string, action: 'shorten' | 'reframe' | 'lengthen') => void;\n onAiResponseAction: (action: 'replace' | 'addBelow' | 'regenerate') => void;\n aiResponse: string | null;\n isAiLoading: boolean;\n refineResponse?: string | null;\n onRefineAction: (actionId: string, actionType: 'shorten' | 'reframe' | 'lengthen') => void;\n onNewPresentation: () => void;\n onLoadPresentation: (input: File | string) => void;\n appBgColor?: string;\n uiScale: number;\n source: PresentationSource | null;\n}\n\nconst FONTS = [\n 'Inter', 'Lato', 'Open Sans', 'Poppins', 'Roboto', 'Roboto Slab',\n 'Georgia', 'Playfair Display', 'Merriweather', 'Nunito Sans',\n 'Montserrat', 'Oswald', 'Raleway', 'Ubuntu', 'Lora',\n 'PT Sans', 'PT Serif', 'Play', 'Arvo', 'Kanit', 'Times New Roman', 'Arial'\n];\nconst FONT_SIZES = [12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 64, 72, 96];\n\nconst SHAPE_CATEGORIES = [\n {\n name: 'Basic Shapes',\n shapes: ['rect', 'circle', 'triangle', 'rightTriangle', 'rhombus', 'parallelogram', 'trapezoid', 'pentagon', 'hexagon', 'heptagon', 'octagon', 'heart', 'smiley', 'sun', 'moon']\n },\n {\n name: 'Arrows',\n shapes: ['arrowRight', 'arrowLeft', 'arrowUp', 'arrowDown', 'arrowLeftRight', 'arrowUpDown']\n },\n {\n name: 'Stars & Symbols',\n shapes: ['star4', 'star5', 'star6', 'star8', 'cloud', 'lightning']\n },\n {\n name: 'Equation Shapes',\n shapes: ['plus', 'minus', 'multiply', 'divide', 'equal']\n }\n];\n\nconst ShapeIcon = ({ type, className }: { type: string, className?: string }) => {\n switch (type) {\n case 'rect': return <svg viewBox=\"0 0 24 24\" className={className}><rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" fill=\"currentColor\" /></svg>;\n case 'circle': return <svg viewBox=\"0 0 24 24\" className={className}><circle cx=\"12\" cy=\"12\" r=\"9\" fill=\"currentColor\" /></svg>;\n case 'triangle': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 4L20 18H4L12 4Z\" fill=\"currentColor\" /></svg>;\n case 'rightTriangle': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M4 4V20H20L4 4Z\" fill=\"currentColor\" /></svg>;\n case 'rhombus': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 4L20 12L12 20L4 12L12 4Z\" fill=\"currentColor\" /></svg>;\n case 'parallelogram': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M7 4H21L17 20H3L7 4Z\" fill=\"currentColor\" /></svg>;\n case 'trapezoid': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M6 4H18L21 20H3L6 4Z\" fill=\"currentColor\" /></svg>;\n case 'pentagon': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 3L21 9V19H3V9L12 3Z\" fill=\"currentColor\" /></svg>;\n case 'hexagon': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 3L20 7.5V16.5L12 21L4 16.5V7.5L12 3Z\" fill=\"currentColor\" /></svg>;\n case 'heptagon': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 3L18.5 6L21 13L16 20H8L3 13L5.5 6L12 3Z\" fill=\"currentColor\" /></svg>;\n case 'octagon': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M8.5 3H15.5L21 8.5V15.5L15.5 21H8.5L3 15.5V8.5L8.5 3Z\" fill=\"currentColor\" /></svg>;\n case 'heart': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\" /></svg>;\n case 'smiley': return <svg viewBox=\"0 0 24 24\" className={className}><circle cx=\"12\" cy=\"12\" r=\"9\" fill=\"currentColor\" fillOpacity=\"0.2\" stroke=\"currentColor\" strokeWidth=\"2\" /><circle cx=\"9\" cy=\"9\" r=\"1.5\" fill=\"currentColor\" /><circle cx=\"15\" cy=\"9\" r=\"1.5\" fill=\"currentColor\" /><path d=\"M8 15C8 15 9.5 17 12 17C14.5 17 16 15 16 15\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" /></svg>;\n case 'sun': return <svg viewBox=\"0 0 24 24\" className={className}><circle cx=\"12\" cy=\"12\" r=\"5\" fill=\"currentColor\" /><path d=\"M12 2V4M12 20V22M4 12H2M22 12H20M19.07 4.93L17.66 6.34M6.34 17.66L4.93 19.07M4.93 4.93L6.34 6.34M17.66 17.66L19.07 19.07\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" /></svg>;\n case 'moon': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 3a9 9 0 1 0 9 9 7 7 0 0 1-9-9\" fill=\"currentColor\" /></svg>;\n case 'arrowRight': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M4 11h11.5l-3.5-3.5 1.5-1.5 6 6-6 6-1.5-1.5 3.5-3.5H4z\" fill=\"currentColor\" /></svg>;\n case 'arrowLeft': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M20 11H8.5l3.5-3.5L10.5 6l-6 6 6 6 1.5-1.5-3.5-3.5H20z\" fill=\"currentColor\" /></svg>;\n case 'arrowUp': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M13 20V8.5l3.5 3.5 1.5-1.5-6-6-6 6 1.5 1.5 3.5-3.5V20z\" fill=\"currentColor\" /></svg>;\n case 'arrowDown': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M11 4v11.5l-3.5-3.5-1.5 1.5 6 6 6-6-1.5-1.5-3.5 3.5V4z\" fill=\"currentColor\" /></svg>;\n case 'arrowLeftRight': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M4 12l4-4v3h8V8l4 4-4 4v-3H8v3l-4-4z\" fill=\"currentColor\" /></svg>;\n case 'arrowUpDown': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 4l-4 4h3v8H8l4 4 4-4h-3V8h3l-4-4z\" fill=\"currentColor\" /></svg>;\n case 'star4': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 2l2 8 8 2-8 2-2 8-2-8-8-2 8-2 2-8z\" fill=\"currentColor\" /></svg>;\n case 'star5': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 2l2.5 7.5H22l-6 4.5 2.5 7.5-6.5-4.5-6.5 4.5 2.5-7.5-6-4.5h7.5L12 2z\" fill=\"currentColor\" /></svg>;\n case 'star6': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 2l3 5 6-1-4 4.5 2 6.5-7-3-7 3 2-6.5-4-4.5 6 1 3-5z\" fill=\"currentColor\" /></svg>;\n case 'star8': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M12 2l2 4 4-2-2 4 4 2-4 2 2 4-4-2-2 4-2-4-4 2 2-4-4-2 4-2-2-4 4 2 2-4z\" fill=\"currentColor\" /></svg>;\n case 'cloud': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M17.5 19c-3 0-5.5-2.5-5.5-5.5 0-.2 0-.4.1-.6-2-.8-3.6-2.5-4.1-4.7C6.5 7.4 5 6 3 6c-1.7 0-3 1.3-3 3s1.3 3 3 3c.4 0 .8-.1 1.2-.2C4.1 13 5 14.5 6.5 15.5c.3 1.8 1.4 3.4 3 4.3.4.2.8.3 1.2.4 1.2.4 2.5.6 3.8.6 4.4 0 8-3.6 8-8s-3.6-8-8-8c-.4 0-.8 0-1.2.1-1.2.2-2.3.7-3.2 1.5C11 4.2 12.4 3.5 14 3.5c4.1 0 7.5 3.4 7.5 7.5s-1.8 7.5-4 8z\" fill=\"currentColor\" transform=\"scale(0.8) translate(3,3)\" /></svg>;\n case 'lightning': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M13 2L3 14h9v8l10-12h-9l3-8z\" fill=\"currentColor\" /></svg>;\n case 'plus': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" fill=\"currentColor\" /></svg>;\n case 'minus': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M19 13H5v-2h14v2z\" fill=\"currentColor\" /></svg>;\n case 'multiply': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z\" fill=\"currentColor\" /></svg>;\n case 'divide': return <svg viewBox=\"0 0 24 24\" className={className}><circle cx=\"12\" cy=\"7\" r=\"2\" fill=\"currentColor\" /><circle cx=\"12\" cy=\"17\" r=\"2\" fill=\"currentColor\" /><rect x=\"5\" y=\"11\" width=\"14\" height=\"2\" fill=\"currentColor\" /></svg>;\n case 'equal': return <svg viewBox=\"0 0 24 24\" className={className}><path d=\"M19 10H5V8h14v2zm0 6H5v-2h14v2z\" fill=\"currentColor\" /></svg>;\n default: return <div className=\"w-6 h-6 bg-slate-200 rounded-sm\" />;\n }\n};\n\nconst ShapesDropdown = ({ onAddShape, uiScale }: { onAddShape: (type: string) => void, uiScale: number }) => {\n const [isOpen, setIsOpen] = useState(false);\n\n // Wire up the toggle to the window so the parent button can trigger it\n React.useEffect(() => {\n (window as any)._toggleShapesMenu = () => setIsOpen(!isOpen);\n return () => { (window as any)._toggleShapesMenu = undefined; };\n }, [isOpen]);\n\n if (!isOpen) return null;\n\n return (\n <div\n className=\"absolute top-full left-0 mt-2 bg-white border border-slate-200 rounded-2xl shadow-2xl p-4 overflow-y-auto z-[100] animate-in fade-in zoom-in-95 duration-200\"\n style={{\n width: `${320 * uiScale}px`,\n maxHeight: `${480 * uiScale}px`\n }}\n >\n <div className=\"flex flex-col gap-6\">\n {SHAPE_CATEGORIES.map(cat => (\n <div key={cat.name} className=\"flex flex-col gap-2\">\n <span className=\"text-[10px] font-black uppercase tracking-widest text-slate-400 px-1\" style={{ fontSize: `${10 * uiScale}px` }}>{cat.name}</span>\n <div className=\"grid grid-cols-5 gap-1\">\n {cat.shapes.map(s => (\n <button\n key={s}\n onClick={() => { onAddShape(s); setIsOpen(false); }}\n className=\"aspect-square hover:bg-slate-50 rounded-lg flex items-center justify-center border border-transparent hover:border-slate-100 transition-all group p-1\"\n title={s}\n >\n <div className=\"w-full h-full bg-slate-100 rounded-sm group-hover:bg-blue-100 group-hover:scale-110 transition-all flex items-center justify-center overflow-hidden p-1.5\">\n <ShapeIcon type={s} className=\"w-full h-full text-slate-400 group-hover:text-blue-600 transition-colors\" />\n </div>\n </button>\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport const Toolbar: React.FC<ToolbarProps> = ({\n onAddText, onAddImage, onAddShape, onAddSlide, onExport,\n onFormatText, onDeleteElement, onApplyLayout, onPlay, selectedElement,\n onNewPresentation, onLoadPresentation, appBgColor = '#B7472A', uiScale,\n source, onGenerateImageClick, onGenerateInfographicClick, onUploadImageClick,\n onRefineAction, refineResponse, isAiLoading\n}) => {\n const fileInputRef = React.useRef<HTMLInputElement>(null);\n const [activeTab, setActiveTab] = useState('Home');\n const [showLayouts, setShowLayouts] = useState(false);\n const [showAiMenu, setShowAiMenu] = useState(false); // For the new Refine dropdown\n const [showFileMenu, setShowFileMenu] = useState(false);\n const [showUploadModal, setShowUploadModal] = useState(false);\n const [uploadType, setUploadType] = useState<'file' | 'link'>('file');\n const [uploadUrl, setUploadUrl] = useState('');\n const [showChangeCaseMenu, setShowChangeCaseMenu] = useState(false);\n const [showCharSpacingMenu, setShowCharSpacingMenu] = useState(false);\n const [showBulletMenu, setShowBulletMenu] = useState(false);\n const [showNumberingMenu, setShowNumberingMenu] = useState(false);\n\n // Change case helper functions\n const applyChangeCase = (caseType: string) => {\n if (!isText || !selectedElement) return;\n const currentText = (selectedElement as any).content || '';\n let newText = currentText;\n switch (caseType) {\n case 'sentence':\n newText = currentText.charAt(0).toUpperCase() + currentText.slice(1).toLowerCase();\n break;\n case 'lowercase':\n newText = currentText.toLowerCase();\n break;\n case 'uppercase':\n newText = currentText.toUpperCase();\n break;\n case 'capitalize':\n newText = currentText.split(' ').map((word: string) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(' ');\n break;\n case 'toggle':\n newText = currentText.split('').map((char: string) => char === char.toUpperCase() ? char.toLowerCase() : char.toUpperCase()).join('');\n break;\n }\n onFormatText({ content: newText });\n setShowChangeCaseMenu(false);\n };\n\n const isText = selectedElement?.type === 'text';\n const isShape = selectedElement?.type === 'shape';\n const isImage = selectedElement?.type === 'image';\n\n const PPT_RED = '#B7472A';\n\n return (\n <div\n className=\"flex flex-col border-b border-slate-200 bg-white z-50 select-none\"\n style={{ fontSize: `${12 * uiScale}px` }}\n >\n {/* Main Toolbar Row */}\n <div\n className=\"bg-white flex items-center justify-center border-b border-slate-200/60 transition-all duration-300 relative z-[1000]\"\n style={{ minHeight: `${120 * uiScale}px`, overflow: 'visible' }}\n >\n {/* Slides Group */}\n <div className={cn(\"flex flex-col items-center border-r border-slate-100 px-3 gap-1 h-full py-2\", uiScale < 0.84 ? \"min-w-0\" : \"min-w-fit\")}>\n <div className=\"flex items-center justify-center gap-1 my-auto\">\n {/*<button\n onClick={onAddSlide}\n className=\"flex flex-col items-right gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg group transition-all min-w-[45px]\"\n >\n <div className=\"bg-orange-50 p-1.5 rounded-lg group-hover:scale-110 transition-transform\">\n <Plus size={Math.max(14, 20 * uiScale)} style={{ color: appBgColor }} />\n </div>\n <span className=\"text-[10px] font-bold text-slate-700\">New Slide</span>\n </button>\n\n <div className=\"w-[1px] h-10 bg-slate-100 mx-1\" /> */}\n\n <div className=\"relative\">\n <button\n onClick={() => setShowLayouts(!showLayouts)}\n className={cn(\"flex flex-col items-left gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg transition-all min-w-[45px]\", showLayouts && \"bg-slate-100\")}\n >\n <div className=\"bg-orange-50 p-1.5 rounded-lg group-hover:scale-110 transition-transform\">\n {/* <LayoutIcon size={Math.max(14, 20 * uiScale)} className=\"text-slate-500\" /> */}\n <Plus size={Math.max(14, 20 * uiScale)} style={{ color: appBgColor }} />\n </div>\n <span className=\"text-[10px] font-medium text-slate-500 whitespace-nowrap\">Slides</span>\n </button>\n {showLayouts && (\n <div className=\"absolute top-full left-0 mt-2 bg-white border border-slate-200 rounded-2xl shadow-3xl p-2 w-60 flex flex-col gap-1 z-[100] animate-in fade-in zoom-in-95 duration-200 ring-4 ring-black/5\">\n <button\n onClick={onAddSlide}\n className=\"flex items-center gap-3 px-4 py-3 hover:bg-slate-50 rounded-xl text-[13px] font-bold text-slate-700 transition-all border border-transparent hover:border-slate-100 group\"\n >\n <div className=\"p-2 bg-blue-50 text-blue-600 rounded-lg group-hover:bg-blue-600 group-hover:text-white transition-colors\">\n <FilePen size={18} />\n </div>\n Blank Slide\n </button>\n <button\n onClick={() => { onApplyLayout('title'); setShowLayouts(false); }}\n className=\"flex items-center gap-3 px-4 py-3 hover:bg-slate-50 rounded-xl text-[13px] font-bold text-slate-700 transition-all border border-transparent hover:border-slate-100 group\"\n >\n <div className=\"p-2 bg-blue-50 text-blue-600 rounded-lg group-hover:bg-blue-600 group-hover:text-white transition-colors\">\n <FileText size={18} />\n </div>\n Title Slide\n </button>\n <button\n onClick={() => { onApplyLayout('content'); setShowLayouts(false); }}\n className=\"flex items-center gap-3 px-4 py-3 hover:bg-slate-50 rounded-xl text-[13px] font-bold text-slate-700 transition-all border border-transparent hover:border-slate-100 group\"\n >\n <div className=\"p-2 bg-emerald-50 text-emerald-600 rounded-lg group-hover:bg-emerald-600 group-hover:text-white transition-colors\">\n <List size={18} />\n </div>\n Title & Content\n </button>\n <button\n onClick={() => { onApplyLayout('split'); setShowLayouts(false); }}\n className=\"flex items-center gap-3 px-4 py-3 hover:bg-slate-50 rounded-xl text-[13px] font-bold text-slate-700 transition-all border border-transparent hover:border-slate-100 group\"\n >\n <div className=\"p-2 bg-purple-50 text-purple-600 rounded-lg group-hover:bg-purple-600 group-hover:text-white transition-colors\">\n <Columns size={18} />\n </div>\n Two Columns\n </button>\n </div>\n )}\n </div>\n </div>\n {uiScale >= 0.45 && <span className=\"text-[9px] uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">Slides</span>}\n </div>\n\n\n {/* Font Group */}\n <div className={cn(\"flex items-center flex-col border-r border-slate-200 h-full py-2 relative justify-center gap-2\", uiScale < 0.85 ? \"px-1\" : \"px-4\")}>\n {/* Top Row: Font Family, Size, A^, Av, Clear */}\n <div className=\"flex items-center gap-3\">\n {/* Font Family Dropdown */}\n <div className=\"flex items-center bg-white border border-slate-300 rounded-[3px] h-[28px] overflow-hidden\">\n <select\n disabled={!isText}\n value={(selectedElement as any)?.fontFamily || 'Open Sans'}\n onChange={(e) => onFormatText({ fontFamily: e.target.value })}\n className={cn(\"h-full px-1.5 text-slate-800 font-normal bg-transparent outline-none disabled:opacity-50 appearance-none cursor-pointer\", uiScale < 0.85 ? \"w-20\" : \"w-32\")}\n style={{ fontSize: `${Math.max(10, 12 * uiScale)}px` }}\n >\n {FONTS.map(f => <option key={f} value={f}>{f}</option>)}\n </select>\n <ChevronDown size={13} className=\"text-slate-400 mr-1\" />\n </div>\n\n {/* Font Size Dropdown */}\n <div className=\"flex items-center bg-white border border-slate-300 rounded-[3px] h-[28px] overflow-hidden w-15\">\n <select\n disabled={!isText}\n value={(selectedElement as any)?.fontSize || 10}\n onChange={(e) => onFormatText({ fontSize: parseInt(e.target.value) })}\n className=\"h-full w-full px-1 text-slate-800 font-normal bg-transparent outline-none disabled:opacity-50 appearance-none cursor-pointer text-center\"\n style={{ fontSize: `${Math.max(10, 12 * uiScale)}px` }}\n >\n {FONT_SIZES.map(s => <option key={s} value={s}>{s}</option>)}\n </select>\n <ChevronDown size={13} className=\"text-slate-400 mr-0.5\" />\n </div>\n\n {/* Increase Font Size (A^) */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ fontSize: Math.min(200, ((selectedElement as any)?.fontSize || 24) + 2) })}\n className=\"w-9 h-[28px] flex items-center justify-center hover:bg-slate-100 rounded-[3px] transition-colors disabled:opacity-40\"\n title=\"Increase Font Size\"\n >\n <span className=\"text-[16px] font-medium text-slate-600\">A</span><ChevronUp size={10} color={'black'} />\n </button>\n\n {/* Decrease Font Size (Av) */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ fontSize: Math.max(8, ((selectedElement as any)?.fontSize || 24) - 2) })}\n className=\"w-9 h-[28px] flex items-center justify-center hover:bg-slate-100 rounded-[3px] transition-colors disabled:opacity-40\"\n title=\"Decrease Font Size\"\n >\n <span className=\"text-[14px] font-medium text-slate-600\">A</span><ChevronDown size={10} color={'black'} />\n </button>\n\n {/* Character Spacing (AV with arrows) */}\n <div className=\"relative\">\n <button\n disabled={!isText}\n onClick={() => setShowCharSpacingMenu(!showCharSpacingMenu)}\n className={cn(\"h-8 px-1.5 flex flex-col items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", showCharSpacingMenu ? \"bg-slate-100\" : \"hover:bg-slate-100\")}\n title=\"Character Spacing\"\n >\n <div className=\"flex items-center\">\n <span className=\"text-[12px] font-bold text-slate-700\">A</span>\n <span className=\"text-[12px] font-bold text-slate-700 -ml-0.5\">V</span>\n <ChevronDown size={11} className=\"text-slate-400 ml-0.5\" />\n </div>\n <div className=\"flex items-center gap-0\">\n <span className=\"text-[7px] text-blue-500\">◀</span>\n <div className=\"w-2.5 h-[1px] bg-blue-500\" />\n <span className=\"text-[7px] text-blue-500\">▶</span>\n </div>\n </button>\n {showCharSpacingMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl py-1 w-32 z-[100] animate-in fade-in zoom-in-95 duration-150\">\n <button onClick={() => { onFormatText({ charSpacing: -50 }); setShowCharSpacingMenu(false); }} className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n Very Tight\n {(selectedElement as any)?.charSpacing === -50 && <Check size={12} className=\"text-blue-600 ml-auto\" />}\n </button>\n <button onClick={() => { onFormatText({ charSpacing: -25 }); setShowCharSpacingMenu(false); }} className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n Tight\n {(selectedElement as any)?.charSpacing === -25 && <Check size={12} className=\"text-blue-600 ml-auto\" />}\n </button>\n <button onClick={() => { onFormatText({ charSpacing: 0 }); setShowCharSpacingMenu(false); }} className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n Normal\n {((selectedElement as any)?.charSpacing === 0 || !(selectedElement as any)?.charSpacing) && <Check size={12} className=\"text-blue-600 ml-auto\" />}\n </button>\n <button onClick={() => { onFormatText({ charSpacing: 25 }); setShowCharSpacingMenu(false); }} className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n Loose\n {(selectedElement as any)?.charSpacing === 25 && <Check size={12} className=\"text-blue-600 ml-auto\" />}\n </button>\n <button onClick={() => { onFormatText({ charSpacing: 50 }); setShowCharSpacingMenu(false); }} className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n Very Loose\n {(selectedElement as any)?.charSpacing === 50 && <Check size={12} className=\"text-blue-600 ml-auto\" />}\n </button>\n <div className=\"h-[1px] bg-slate-100 my-1\" />\n <button className=\"w-full px-3 py-1.5 text-left text-[11px] text-slate-700 hover:bg-slate-50 disabled:opacity-50\">\n More Spacing...\n </button>\n </div>\n )}\n </div>\n </div>\n\n {/* Bottom Row: B I U S abc AV Aa | Highlighter A-color */}\n <div className=\"flex items-center gap-1.5\">\n {/* Bold */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ isBold: !(selectedElement as any).isBold })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isBold ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Bold\"\n >\n <span className={`text-[15px] font-bold ${(selectedElement as any)?.isBold ? 'text-slate-900' : 'text-slate-600'}`}>B</span>\n </button>\n\n {/* Italic */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ isItalic: !(selectedElement as any).isItalic })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isItalic ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Italic\"\n >\n <span className={`text-[15px] italic font-serif ${(selectedElement as any)?.isItalic ? 'text-slate-900' : 'text-slate-600'}`}>I</span>\n </button>\n\n {/* Underline */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ isUnderline: !(selectedElement as any).isUnderline })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isUnderline ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Underline\"\n >\n <span className={`text-[15px] underline underline-offset-2 ${(selectedElement as any)?.isUnderline ? 'text-slate-900' : 'text-slate-600'}`}>U</span>\n </button>\n\n {/* abc strikethrough */}\n <button\n disabled={!isText}\n onClick={() => onFormatText({ isStrikethrough: !(selectedElement as any).isStrikethrough })}\n className={cn(\"h-8 px-1.5 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isStrikethrough ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Strikethrough\"\n >\n <span className={`text-[12px] font-medium line-through ${(selectedElement as any)?.isStrikethrough ? 'text-slate-900' : 'text-slate-600'}`}>abc</span>\n <ChevronDown size={12} className=\"text-slate-400 ml-0.5\" />\n </button>\n\n\n {/* Change Case (Aa) */}\n <div className=\"relative\">\n <button\n disabled={!isText}\n onClick={() => setShowChangeCaseMenu(!showChangeCaseMenu)}\n className=\"h-8 px-1.5 flex items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all disabled:opacity-40\"\n title=\"Change Case\"\n >\n <span className=\"text-[14px] font-medium text-slate-700\">Aa</span>\n <ChevronDown size={11} className=\"text-slate-400 ml-0.5\" />\n </button>\n {showChangeCaseMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl py-1 w-44 z-[100] animate-in fade-in zoom-in-95 duration-150\">\n <button onClick={() => applyChangeCase('sentence')} className=\"w-full px-3 py-1.5 text-left text-[12px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n <span className=\"text-slate-400\">Aa</span> Sentence case.\n </button>\n <button onClick={() => applyChangeCase('lowercase')} className=\"w-full px-3 py-1.5 text-left text-[12px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n <span className=\"text-slate-400 underline\">l</span> lowercase\n </button>\n <button onClick={() => applyChangeCase('uppercase')} className=\"w-full px-3 py-1.5 text-left text-[12px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n <span className=\"text-slate-400 underline\">U</span> UPPERCASE\n </button>\n <button onClick={() => applyChangeCase('capitalize')} className=\"w-full px-3 py-1.5 text-left text-[12px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n <span className=\"text-slate-400 underline\">C</span> Capitalize Each Word\n </button>\n <button onClick={() => applyChangeCase('toggle')} className=\"w-full px-3 py-1.5 text-left text-[12px] text-slate-700 hover:bg-slate-50 flex items-center gap-2\">\n <span className=\"text-slate-400 underline\">t</span> tOGGLE cASE\n </button>\n </div>\n )}\n </div>\n\n <div className=\"w-[1px] h-5 bg-slate-200 mx-1.5\" />\n\n {/* Clear Formatting (Ax) */}\n <div className=\"relative\">\n <button\n disabled={!isText}\n onClick={() => onFormatText({ isBold: false, isItalic: false, isUnderline: false, highlightColor: '', color: '#000000', isStrikethrough: false })}\n className=\"w-9 h-[28px] flex items-center justify-center hover:bg-slate-100 rounded-[3px] transition-colors disabled:opacity-40\"\n title=\"Clear All Formatting\"\n >\n <span className=\"text-[16px] font-medium text-slate-600\">A</span>\n <Eraser size={Math.max(8, 11 * uiScale)} className=\"text-pink-500 -ml-0.5\" />\n </button>\n </div>\n\n {/* Highlighter */}\n <div className=\"relative flex items-center\">\n <button\n disabled={!isText}\n className={cn(\"w-9 h-7.5 flex flex-col items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.highlightColor ? \"bg-slate-100\" : \"hover:bg-slate-100\")}\n title=\"Text Highlight Color\"\n >\n <Highlighter size={18} strokeWidth={1.5} className={(selectedElement as any)?.highlightColor ? \"text-slate-900\" : \"text-slate-500\"} />\n <div className=\"absolute top-[24px] left-1 right-3 h-0.5\" style={{ backgroundColor: (selectedElement as any)?.highlightColor || 'transparent' }} />\n </button>\n <input\n type=\"color\"\n disabled={!isText}\n className=\"absolute inset-0 opacity-0 cursor-pointer w-full h-full disabled:cursor-not-allowed\"\n value={(selectedElement as any)?.highlightColor || '#ffff00'}\n onChange={(e) => onFormatText({ highlightColor: e.target.value })}\n title=\"Choose Highlight Color\"\n />\n <ChevronDown size={11} className=\"text-slate-400 -ml-0.5\" />\n </div>\n\n {/* Font Color */}\n <div className=\"relative flex items-center\">\n <button\n className=\"w-9 h-7.5 flex flex-col items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all\"\n title=\"Font Color\"\n >\n <span className=\"text-[15px] font-medium text-slate-600 leading-none\">A</span>\n <div className=\"w-6 h-[4px] rounded-sm mt-0.5\" style={{ backgroundColor: (selectedElement as any)?.color || '#ff0000' }} />\n <input\n type=\"color\"\n className=\"absolute inset-0 opacity-0 cursor-pointer w-full h-full\"\n value={(selectedElement as any)?.color || '#ff0000'}\n onChange={(e) => onFormatText({ color: e.target.value })}\n />\n </button>\n <ChevronDown size={11} className=\"text-slate-400 -ml-0.5\" />\n </div>\n </div>\n\n {/* Footer with Label and Expand Icon */}\n {/* <div className=\"mt-auto flex items-center justify-center relative pt-0.5 border-t border-slate-100\">\n <span className=\"text-[10px] text-slate-500 font-medium\">Font</span>\n <div className=\"absolute right-0 bottom-0\">\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" className=\"text-slate-400\">\n <path d=\"M1 7L7 1M7 1H3M7 1V5\" stroke=\"currentColor\" strokeWidth=\"1\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n </div> */}\n {uiScale >= 0.45 && <span className=\"text-[9px] text-center uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">Font</span>}\n </div>\n\n {/* Paragraph Group */}\n <div className={cn(\"flex flex-col border-r border-slate-200 h-full py-2 relative justify-center gap-2\", uiScale < 0.85 ? \"px-2\" : \"px-4\")}>\n {/* Top Row: Lists and Indents */}\n <div className=\"flex items-center gap-1.5\">\n {/* Bullet List */}\n <div className=\"relative flex items-center rounded-[3px] hover:bg-slate-100 transition-all\">\n <button\n disabled={!isText}\n onClick={() => {\n if ((selectedElement as any)?.isBulleted) {\n onFormatText({ isBulleted: false, isNumbered: false, listType: 'none' });\n } else {\n onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-disc' });\n }\n }}\n className={cn(\"w-[32px] h-8 flex items-center justify-center rounded-l-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isBulleted ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Bullets\"\n >\n <List size={Math.max(13, 19 * uiScale)} className={(selectedElement as any)?.isBulleted ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n <button\n disabled={!isText}\n onClick={() => setShowBulletMenu(!showBulletMenu)}\n className={cn(\"w-[15px] h-8 flex items-center justify-center rounded-r-[3px] border-l border-transparent hover:border-slate-200 transition-all disabled:opacity-40\", showBulletMenu ? \"bg-slate-100\" : \"hover:bg-slate-200\")}\n title=\"Bullet Options\"\n >\n <ChevronDown size={13} className=\"text-slate-400\" />\n </button>\n\n {showBulletMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl p-2 z-[100] animate-in fade-in zoom-in-95 duration-150 w-64 grid grid-cols-4 gap-2\">\n <button onClick={() => { onFormatText({ isBulleted: false, listType: 'none' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1\">\n <span className=\"text-[10px] text-slate-500\">None</span>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-disc' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-circle' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-square' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-square-outlined' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-diamond' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black rotate-45 scale-75\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black rotate-45 scale-75\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black rotate-45 scale-75\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-arrow' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">➤</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">➤</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">➤</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isBulleted: true, isNumbered: false, listType: 'bullet-check' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">✓</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">✓</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] leading-none\">✓</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n </div>\n )}\n </div>\n\n {/* Numbered List */}\n <div className=\"relative flex items-center rounded-[3px] hover:bg-slate-100 transition-all\">\n <button\n disabled={!isText}\n onClick={() => {\n if ((selectedElement as any)?.isNumbered) {\n onFormatText({ isBulleted: false, isNumbered: false, listType: 'none' });\n } else {\n onFormatText({ isBulleted: false, isNumbered: true, listType: 'number-decimal' });\n }\n }}\n className={cn(\"w-[32px] h-8 flex items-center justify-center rounded-l-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.isNumbered ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Numbering\"\n >\n <ListOrdered size={Math.max(13, 19 * uiScale)} className={(selectedElement as any)?.isNumbered ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n <button\n disabled={!isText}\n onClick={() => setShowNumberingMenu(!showNumberingMenu)}\n className={cn(\"w-[15px] h-8 flex items-center justify-center rounded-r-[3px] border-l border-transparent hover:border-slate-200 transition-all disabled:opacity-40\", showNumberingMenu ? \"bg-slate-100\" : \"hover:bg-slate-200\")}\n title=\"Numbering Options\"\n >\n <ChevronDown size={13} className=\"text-slate-400\" />\n </button>\n\n {showNumberingMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl p-2 z-[100] animate-in fade-in zoom-in-95 duration-150 w-64 grid grid-cols-4 gap-2\">\n <button onClick={() => { onFormatText({ isNumbered: false, listType: 'none' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1\">\n <span className=\"text-[10px] text-slate-500\">None</span>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-decimal' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">1.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">2.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">3.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-decimal-paren' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">1)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">2)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">3)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-roman-upper' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">I.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">II.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">III.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-alpha-upper' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">A.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">B.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">C.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-alpha-lower-paren' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">a)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">b)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">c)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-alpha-lower' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">a.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">b.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">c.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n <button onClick={() => { onFormatText({ isNumbered: true, isBulleted: false, listType: 'number-roman-lower' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\">\n <div className=\"flex flex-col gap-1 items-start w-full px-1\">\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">i.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">ii.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n <div className=\"flex items-center gap-1\"><span className=\"text-[6px] font-bold\">iii.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div>\n </div>\n </button>\n </div>\n )}\n </div>\n\n <div className=\"w-[1px] h-6 bg-slate-200 mx-1.5\" />\n\n {/* Decrease Indent */}\n <button\n disabled={!isText}\n className=\"w-7 h-7 flex items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all disabled:opacity-40\"\n title=\"Decrease List Level\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 14 14\" fill=\"none\" className=\"text-slate-600\">\n <path d=\"M2 3H12M6 7H12M6 11H12M2 7L4 9L2 11\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n\n {/* Increase Indent */}\n <button\n disabled={!isText}\n className=\"w-8 h-8 flex items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all disabled:opacity-40\"\n title=\"Increase List Level\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 14 14\" fill=\"none\" className=\"text-slate-600\">\n <path d=\"M2 3H12M6 7H12M6 11H12M4 7L2 9L4 11\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n {/* Bottom Row: Alignment */}\n <div className=\"flex items-center gap-0.5\">\n <button\n disabled={!isText}\n onClick={() => onFormatText({ textAlign: 'left' })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.textAlign === 'left' ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Align Left\"\n >\n <AlignLeft size={Math.max(13, 19 * uiScale)} className={(selectedElement as any)?.textAlign === 'left' ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n <button\n disabled={!isText}\n onClick={() => onFormatText({ textAlign: 'center' })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.textAlign === 'center' ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Center\"\n >\n <AlignCenter size={Math.max(13, 19 * uiScale)} className={(selectedElement as any)?.textAlign === 'center' ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n <button\n disabled={!isText}\n onClick={() => onFormatText({ textAlign: 'right' })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.textAlign === 'right' ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Align Right\"\n >\n <AlignRight size={Math.max(13, 19 * uiScale)} className={(selectedElement as any)?.textAlign === 'right' ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n <button\n disabled={!isText}\n onClick={() => onFormatText({ textAlign: 'justify' })}\n className={cn(\"w-8 h-8 flex items-center justify-center rounded-[3px] transition-all disabled:opacity-40\", (selectedElement as any)?.textAlign === 'justify' ? \"bg-blue-100\" : \"hover:bg-slate-100\")}\n title=\"Justify\"\n >\n <AlignJustify size={Math.max(13, 19 * uiScale)} className={(selectedElement as any)?.textAlign === 'justify' ? \"text-slate-900\" : \"text-slate-600\"} />\n </button>\n </div>\n\n {uiScale >= 0.45 && <span className=\"text-[9px] text-center uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">Paragraph</span>}\n {/* Footer with Label and Expand Icon */}\n {/* <div className=\"mt-auto flex items-center justify-center relative pt-0.5 border-t border-slate-100\">\n <span className=\"text-[10px] text-slate-500 font-medium\">Paragraph</span>\n <div className=\"absolute right-0 bottom-0\">\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" className=\"text-slate-400\">\n <path d=\"M1 7L7 1M7 1H3M7 1V5\" stroke=\"currentColor\" strokeWidth=\"1\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n\n </div> */}\n </div>\n\n {/* Drawing Group */}\n <div className=\"flex flex-col items-center border-r border-slate-100 px-2 gap-1 h-full py-1.5 shrink-0\">\n <div className=\"flex items-center justify-center gap-1 my-auto\">\n <div className=\"relative group/shapes flex justify-center\">\n <button\n className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg group transition-all min-w-[50px]\"\n onClick={() => (window as any)._toggleShapesMenu?.()}\n >\n <div className=\"bg-blue-50 p-1.5 rounded-lg group-hover:scale-105 transition-transform\">\n <Square size={Math.max(14, 20 * uiScale)} className=\"text-blue-600\" />\n </div>\n <span className=\"text-[10px] font-bold text-slate-700\">Shapes</span>\n </button>\n <ShapesDropdown onAddShape={(s) => { onAddShape(s); }} uiScale={uiScale} />\n </div>\n\n <div className=\"w-[1px] h-10 bg-slate-100 mx-1\" />\n\n <button onClick={onAddText} className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg text-slate-600 transition-colors min-w-[50px]\" title=\"Text Box\">\n <div className=\"p-1.5\">\n <Type size={Math.max(14, 20 * uiScale)} />\n </div>\n <span className=\"text-[10px] font-medium text-slate-500\">Text Box</span>\n </button>\n\n <div className=\"w-[1px] h-10 bg-slate-100 mx-1\" />\n\n <button onClick={() => fileInputRef.current?.click()} className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg text-slate-600 transition-colors min-w-[50px]\" title=\"Image\">\n <div className=\"p-1.5\">\n <ImageIcon size={Math.max(14, 20 * uiScale)} />\n </div>\n <span className=\"text-[10px] font-medium text-slate-500\">Image</span>\n <input type=\"file\" ref={fileInputRef} className=\"hidden\" accept=\"image/*\" onChange={(e) => e.target.files?.[0] && onAddImage(e.target.files[0])} />\n </button>\n </div>\n {uiScale >= 0.45 && <span className=\"text-[9px] uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">Drawing</span>}\n </div>\n\n {/* AI Text Group */}\n <div className=\"flex flex-col items-center border-r border-slate-100 px-1 gap-1 h-full py-1.5 relative\">\n <div className=\"flex items-center justify-center gap-0.5 my-auto h-full relative\">\n <button\n disabled={!isText || isAiLoading}\n onClick={() => setShowAiMenu(!showAiMenu)}\n className={cn(\n \"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg text-slate-600 disabled:opacity-20 transition-all min-w-[72px] outline-none focus:outline-none focus:ring-0 border-none\",\n showAiMenu && \"bg-slate-100 text-slate-900\"\n )}\n >\n <div className=\"p-1.5 rounded-lg group-hover:scale-110 transition-transform\">\n <Sparkles size={Math.max(14, 20 * uiScale)} className=\"text-purple-500\" />\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[10px] font-bold\">Refine</span>\n <ChevronDown size={10} className=\"text-slate-400\" />\n </div>\n </button>\n\n {showAiMenu && (\n <div className=\"absolute top-full right-0 mt-2 bg-white border border-slate-200 rounded-xl shadow-xl w-48 z-[100] animate-in fade-in zoom-in-95 duration-150 overflow-hidden\">\n <button\n onClick={() => { onRefineAction?.(selectedElement!.id, 'shorten'); setShowAiMenu(false); }}\n className=\"w-full px-5 py-4 text-left text-xs font-medium text-slate-700 hover:bg-purple-50 hover:text-purple-700 flex items-center gap-3 transition-colors border-b border-slate-50\"\n >\n <span className=\"text-purple-400\">abc</span>\n Shorten\n </button>\n <button\n onClick={() => { onRefineAction?.(selectedElement!.id, 'reframe'); setShowAiMenu(false); }}\n className=\"w-full px-5 py-4 text-left text-xs font-medium text-slate-700 hover:bg-blue-50 hover:text-blue-700 flex items-center gap-3 transition-colors border-b border-slate-50\"\n >\n <span className=\"text-blue-400\">↻</span>\n Reframe\n </button>\n <button\n onClick={() => { onRefineAction?.(selectedElement!.id, 'lengthen'); setShowAiMenu(false); }}\n className=\"w-full px-5 py-4 text-left text-xs font-medium text-slate-700 hover:bg-emerald-50 hover:text-emerald-700 flex items-center gap-3 transition-colors\"\n >\n <span className=\"text-emerald-400\">...</span>\n Lengthen\n </button>\n </div>\n )}\n </div>\n\n {/* AI Loading State */}\n {isAiLoading && (\n <div className=\"absolute inset-x-0 top-2 bottom-8 bg-white/80 flex items-center justify-center rounded-lg z-10 backdrop-blur-[1px]\">\n <RefreshCw size={16} className=\"text-blue-600 animate-spin\" />\n </div>\n )}\n {uiScale >= 0.45 && <span className=\"text-[9px] uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">AI Text</span>}\n </div>\n\n {/* Actions Group */}\n <div className=\"flex flex-col items-center pl-3 pr-3 gap-1 h-full py-2 relative\">\n <div className=\"flex items-center justify-center gap-1 my-auto h-full\">\n <button\n onClick={onPlay}\n className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg text-slate-700 transition-all min-w-[40px] group\"\n title=\"Present\"\n >\n <div className=\"p-1.5 rounded-lg group-hover:scale-110 transition-transform\">\n <Play size={Math.max(14, 20 * uiScale)} className=\"fill-slate-700 group-hover:fill-slate-900\" />\n </div>\n <span className=\"text-[10px] font-bold\">Present</span>\n </button>\n\n <div className=\"w-[1px] h-10 bg-slate-100 mx-1\" />\n\n <button\n onClick={onExport}\n className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-slate-50 rounded-lg text-slate-700 transition-all min-w-[50px] group\"\n title=\"Export\"\n >\n <div className=\"p-1.5 rounded-lg group-hover:scale-110 transition-transform\">\n <Download size={Math.max(14, 20 * uiScale)} className=\"text-emerald-600\" />\n </div>\n <span className=\"text-[10px] font-bold\">Export</span>\n </button>\n\n {selectedElement && (\n <>\n <div className=\"w-[1px] h-10 bg-slate-100 mx-1\" />\n <button\n onClick={onDeleteElement}\n className=\"flex flex-col items-center justify-center gap-1.5 px-3 py-1.5 hover:bg-red-50 rounded-lg text-red-600 transition-all min-w-[50px] group\"\n title=\"Delete\"\n >\n <div className=\"p-1.5 rounded-lg group-hover:scale-110 transition-transform\">\n <Trash2 size={Math.max(14, 20 * uiScale)} />\n </div>\n <span className=\"text-[10px] font-bold\">Delete</span>\n </button>\n </>\n )}\n </div>\n\n <div className=\"absolute top-2 right-3 flex items-center gap-1 px-1.5 py-0.5 bg-emerald-50/50 rounded-md border border-emerald-100/50\">\n <Check size={9} className=\"text-emerald-500\" />\n <span className=\"text-[7px] font-black text-emerald-600/70 tracking-tighter uppercase\">Saved</span>\n </div>\n\n {uiScale >= 0.45 && <span className=\"text-[9px] uppercase tracking-[0.2em] font-black text-slate-300 mt-auto\">Actions</span>}\n </div>\n </div>\n\n {/* Upload Modal */}\n {showUploadModal && (\n <>\n <div className=\"fixed inset-0 bg-slate-900/40 backdrop-blur-sm z-[2000]\" onClick={() => setShowUploadModal(false)} />\n <div className=\"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[480px] bg-white rounded-3xl shadow-2xl z-[2001] border border-slate-200 p-8 animate-in fade-in zoom-in-95 duration-200\">\n <div className=\"flex justify-between items-center mb-6\">\n <h3 className=\"text-lg font-black text-slate-800 tracking-tight flex items-center gap-3\">\n <div className=\"p-2 bg-blue-50 text-blue-600 rounded-xl\">\n <Download size={20} />\n </div>\n Upload Presentation\n </h3>\n <button onClick={() => setShowUploadModal(false)} className=\"text-slate-400 hover:text-slate-600 transition-colors\">\n <RefreshCw size={20} className=\"rotate-45\" />\n </button>\n </div>\n\n <div className=\"flex gap-2 p-1 bg-slate-50 rounded-2xl mb-8\">\n <button\n onClick={() => setUploadType('file')}\n className={cn(\n \"flex-1 py-3 text-xs font-black rounded-xl transition-all\",\n uploadType === 'file' ? \"bg-white text-blue-600 shadow-sm\" : \"text-slate-500 hover:text-slate-700\"\n )}\n >\n FILE UPLOAD\n </button>\n <button\n onClick={() => setUploadType('link')}\n className={cn(\n \"flex-1 py-3 text-xs font-black rounded-xl transition-all\",\n uploadType === 'link' ? \"bg-white text-blue-600 shadow-sm\" : \"text-slate-500 hover:text-slate-700\"\n )}\n >\n LINK UPLOAD\n </button>\n </div>\n\n {uploadType === 'file' ? (\n <label className=\"flex flex-col items-center justify-center gap-4 py-12 border-2 border-dashed border-slate-200 rounded-3xl hover:border-blue-400 hover:bg-blue-50/50 transition-all cursor-pointer group\">\n <div className=\"p-4 bg-white rounded-2xl shadow-sm border border-slate-100 group-hover:scale-110 transition-transform\">\n <Plus size={24} className=\"text-blue-500\" />\n </div>\n <div className=\"text-center\">\n <p className=\"text-sm font-bold text-slate-700\">Choose a PPTX file</p>\n <p className=\"text-xs text-slate-400 mt-1\">Maximum file size: 50MB</p>\n </div>\n <input\n type=\"file\"\n accept=\".pptx\"\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (file) {\n onLoadPresentation(file);\n setShowUploadModal(false);\n }\n }}\n />\n </label>\n ) : (\n <div className=\"space-y-4\">\n <div className=\"relative\">\n <input\n type=\"text\"\n placeholder=\"Paste S3 or public URL\"\n value={uploadUrl}\n onChange={(e) => setUploadUrl(e.target.value)}\n className=\"w-full bg-slate-50 border border-slate-200 rounded-2xl px-5 py-4 focus:outline-none focus:ring-4 focus:ring-blue-500/10 focus:border-blue-500 text-sm placeholder:text-slate-400 text-black\"\n />\n </div>\n <button\n onClick={() => {\n if (uploadUrl.trim()) {\n onLoadPresentation(uploadUrl.trim());\n setShowUploadModal(false);\n }\n }}\n disabled={!uploadUrl.trim()}\n className=\"w-full bg-blue-600 hover:bg-blue-700 disabled:bg-slate-300 text-white font-black py-4 rounded-2xl transition-all shadow-lg shadow-blue-500/20\"\n >\n LOAD PRESENTATION\n </button>\n <p className=\"text-[10px] text-slate-400 text-center uppercase tracking-widest font-black\">\n Supports S3, Dropbox, and public URLS\n </p>\n </div>\n )}\n </div>\n </>\n )}\n </div>\n );\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","'use client';\n\nimport React from 'react';\nimport type { Slide } from '../lib/types';\nimport { cn } from '@/lib/utils';\nimport { Trash2, Copy, GripVertical } from 'lucide-react';\n\nconst SHAPE_PATHS: Record<string, string> = {\n triangle: 'M 12,4 L 20,18 H 4 L 12,4 Z',\n rightTriangle: 'M 4,4 V 20 H 20 L 4,4 Z',\n rhombus: 'M 12,4 L 20,12 L 12,20 L 4,12 L 12,4 Z',\n parallelogram: 'M 7,4 H 21 L 17,20 H 3 L 7,4 Z',\n trapezoid: 'M 6,4 H 18 L 21,20 H 3 L 6,4 Z',\n pentagon: 'M 12,3 L 21,9 V 19 H 3 V 9 L 12,3 Z',\n hexagon: 'M 12,3 L 20,7.5 V 16.5 L 12,21 L 4,16.5 V 7.5 L 12,3 Z',\n heptagon: 'M 12,3 L 18.5,6 L 21,13 L 16,20 H 8 L 3,13 L 5.5,6 L 12,3 Z',\n octagon: 'M 8.5,3 H 15.5 L 21,8.5 V 15.5 L 15.5,21 H 8.5 L 3,15.5 V 8.5 L 8.5,3 Z',\n heart: 'M 12,21.35 L 10.55,20.03 C 5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3 C 9.24,3 10.91,3.81 12,5.09 C 13.09,3.81 14.76,3 16.5,3 C 19.58,3 22,5.42 22,8.5 C 22,12.28 18.6,15.36 13.45,20.04 L 12,21.35 Z',\n smiley: 'M 12,3 A 9,9 0 1,0 12,21 A 9,9 0 1,0 12,3 M 9,9 A 1.5,1.5 0 1,1 9,10.5 A 1.5,1.5 0 1,1 9,9 M 15,9 A 1.5,1.5 0 1,1 15,10.5 A 1.5,1.5 0 1,1 15,9 M 8,15 C 8,15 9.5,17 12,17 C 14.5,17 16,15 16,15',\n sun: 'M 12,7 A 5,5 0 1,1 12,17 A 5,5 0 1,1 12,7 M 12,2 V 4 M 12,20 V 22 M 4,12 H 2 M 22,12 H 20 M 19.07,4.93 L 17.66,6.34 M 6.34,17.66 L 4.93,19.07 M 4.93,4.93 L 6.34,6.34 M 17.66,17.66 L 19.07,19.07',\n moon: 'M 12,3 A 9,9 0 1,0 12,21 A 7,7 0 0,1 12,3 Z',\n circle: 'M 12,3 A 9,9 0 1,1 12,21 A 9,9 0 1,1 12,3 Z',\n arrowRight: 'M 4,11 H 15.5 L 12,7.5 L 13.5,6 L 19.5,12 L 13.5,18 L 12,16.5 L 15.5,13 H 4 Z',\n arrowLeft: 'M 20,11 H 8.5 L 12,7.5 L 10.5,6 L 4.5,12 L 10.5,18 L 12,16.5 L 8.5,13 H 20 Z',\n arrowUp: 'M 13,20 V 8.5 L 16.5,12 L 18,10.5 L 12,4.5 L 6,10.5 L 7.5,12 L 11,8.5 V 20 Z',\n arrowDown: 'M 11,4 V 15.5 L 7.5,12 L 6,13.5 L 12,19.5 L 18,13.5 L 16.5,12 L 13,15.5 V 4 Z',\n arrowLeftRight: 'M 4,12 L 8,8 V 11 H 16 V 8 L 20,12 L 16,16 V 13 H 8 V 16 L 4,12 Z',\n arrowUpDown: 'M 12,4 L 8,8 H 11 V 16 H 8 L 12,20 L 16,16 H 13 V 8 H 16 L 12,4 Z',\n star4: 'M 12,2 L 14,10 L 22,12 L 14,14 L 12,22 L 10,14 L 2,12 L 10,10 L 12,2 Z',\n star5: 'M 12,2 L 14.5,9.5 H 22 L 16,14 L 18.5,21.5 L 12,17 L 5.5,21.5 L 8,14 L 2,9.5 H 9.5 L 12,2 Z',\n star6: 'M 12,2 L 15,7 L 21,6 L 17,10.5 L 19,17 L 12,14 L 5,17 L 7,10.5 L 3,6 L 9,7 L 12,2 Z',\n star8: 'M 12,2 L 14,6 L 18,4 L 16,8 L 20,10 L 16,12 L 18,16 L 14,14 L 12,18 L 10,14 L 6,16 L 8,12 L 4,10 L 8,8 L 6,4 L 10,6 L 12,2 Z',\n cloud: 'M 17,19 C 14.8,19 13.1,17.7 12.3,15.8 C 11.4,16 10.5,16.2 9.6,16.2 C 7,16.2 4.7,14.6 3.7,12.3 C 1.5,11.8 0,9.9 0,7.6 C 0,5 2.1,2.9 4.7,2.9 C 5.3,2.9 5.8,3 6.3,3.1 C 7.6,1.4 9.6,0.3 11.9,0.3 C 12.5,0.3 13.1,0.4 13.7,0.5 C 15,1.9 15.9,3.7 16,5.7 C 18.2,6.1 20,8.1 20,10.5 C 20,13.2 17.8,15.4 15.1,15.4 C 14.8,15.4 14.5,15.4 14.2,15.3 C 14.2,15.4 14.2,15.4 14.2,15.5 C 14.2,17.4 15.5,19 17,19 Z',\n lightning: 'M 13,2 L 3,14 H 12 V 22 L 22,10 H 13 L 16,2 Z',\n plus: 'M 19,13 H 13 V 19 H 11 V 13 H 5 V 11 H 11 V 5 H 13 V 11 H 19 V 13 Z',\n minus: 'M 19,13 H 5 V 11 H 19 V 13 Z',\n multiply: 'M 19,6.41 L 17.59,5 L 12,10.59 L 6.41,5 L 5,6.41 L 10.59,12 L 5,17.59 L 6.41,19 L 12,13.41 L 17.59,19 L 19,17.59 L 13.41,12 L 19,6.41 Z',\n divide: 'M 12,7 A 2,2 0 1,1 12,11 A 2,2 0 1,1 12,7 M 12,17 A 2,2 0 1,1 12,21 A 2,2 0 1,1 12,17 M 5,11 H 19 V 13 H 5 V 11 Z',\n equal: 'M 19,10 H 5 V 8 H 19 V 10 M 19,16 H 5 V 14 H 19 V 16 Z'\n};\nimport {\n DndContext,\n closestCenter,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n DragEndEvent\n} from '@dnd-kit/core';\nimport {\n arrayMove,\n SortableContext,\n sortableKeyboardCoordinates,\n verticalListSortingStrategy,\n useSortable\n} from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\n\ninterface SidebarProps {\n slides: Slide[];\n currentSlideIndex: number;\n onSelectSlide: (index: number) => void;\n onDeleteSlide: (index: number) => void;\n onDuplicateSlide: (index: number) => void;\n onReorderSlides: (oldIndex: number, newIndex: number) => void;\n uiScale: number;\n appBgColor?: string;\n}\n\nconst SortableSlide = ({\n slide,\n index,\n isActive,\n onSelect,\n onDelete,\n onDuplicate,\n showDelete,\n uiScale,\n appBgColor\n}: {\n slide: Slide,\n index: number,\n isActive: boolean,\n onSelect: () => void,\n onDelete: () => void,\n onDuplicate: () => void,\n showDelete: boolean,\n uiScale: number,\n appBgColor: string\n}) => {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging\n } = useSortable({ id: slide.id });\n\n const style = {\n transform: CSS.Transform.toString(transform),\n transition,\n zIndex: isDragging ? 2 : 1,\n opacity: isDragging ? 0.5 : 1\n };\n\n return (\n <div\n ref={setNodeRef}\n onClick={onSelect}\n className={cn(\n \"cursor-pointer border-[1.5px] border-solid p-2 transition-all duration-300 group relative select-none\",\n isActive\n ? \"bg-white\"\n : \"border hover:border-slate-200 bg-white/50 hover:bg-white\"\n )}\n style={{\n ...style,\n border: isActive ? `1px solid ${appBgColor}` : \"1px solid transparent\"\n }}\n >\n <div\n className={cn(\"text-[10px] font-bold mb-1 flex items-center justify-between transition-colors\", !isActive && \"text-slate-400\")}\n style={{ color: isActive ? appBgColor : undefined }}\n >\n <div className=\"flex items-center gap-1\">\n <div {...attributes} {...listeners} className=\"cursor-grab active:cursor-grabbing p-0.5 hover:bg-slate-100 text-slate-300 hover:text-slate-500\">\n <GripVertical size={10} />\n </div>\n <span>SLIDE {index + 1}</span>\n </div>\n <div className=\"flex items-center gap-1\">\n {isActive && <span className=\"h-1.5 w-1.5\" style={{ backgroundColor: appBgColor }} />}\n <div className=\"flex items-center opacity-0 group-hover:opacity-100 transition-opacity\">\n <button\n onClick={(e) => { e.stopPropagation(); onDuplicate(); }}\n className=\"p-1 hover:bg-blue-50 text-slate-400 hover:text-blue-500 transition-all\"\n title=\"Duplicate Slide\"\n >\n <Copy size={12} />\n </button>\n {showDelete && (\n <button\n onClick={(e) => { e.stopPropagation(); onDelete(); }}\n className=\"p-1 hover:bg-red-50 text-red-400 hover:text-red-500 transition-all\"\n title=\"Delete Slide\"\n >\n <Trash2 size={12} />\n </button>\n )}\n </div>\n </div>\n </div>\n <div className=\"aspect-video bg-white flex items-center justify-center border border-slate-200 overflow-hidden relative group-hover:shadow-sm transition-shadow\">\n {/* Scaled Preview of Slide Content */}\n <div\n className=\"origin-center pointer-events-none select-none shrink-0\"\n style={{\n width: '1200px',\n height: '675px',\n transform: `scale(${(170 * uiScale) / 1200})`, // Perfectly fit within available width\n backgroundColor: '#ffffff'\n }}\n >\n {slide.elements.sort((a, b) => (a.zIndex || 0) - (b.zIndex || 0)).map((el) => {\n const style: React.CSSProperties = {\n position: 'absolute',\n left: el.x,\n top: el.y,\n width: el.width,\n height: el.height,\n opacity: el.opacity ?? 1,\n };\n\n if (el.type === 'text') {\n return (\n <div\n key={el.id}\n style={{\n ...style,\n fontSize: el.fontSize,\n fontFamily: el.fontFamily,\n color: el.color,\n textAlign: el.textAlign || 'left',\n fontWeight: el.isBold ? 'bold' : 'normal',\n fontStyle: el.isItalic ? 'italic' : 'normal',\n lineHeight: 1.2,\n overflow: 'hidden',\n wordBreak: 'break-word',\n whiteSpace: 'pre-wrap'\n }}\n >\n {el.content}\n </div>\n );\n } else if (el.type === 'shape') {\n const pathData = SHAPE_PATHS[el.shapeType] || (el.shapeType === 'ellipse' ? SHAPE_PATHS.circle : null);\n if (pathData) {\n return (\n <svg\n key={el.id}\n viewBox=\"0 0 24 24\"\n style={{\n ...style,\n fill: el.fill\n }}\n preserveAspectRatio=\"none\"\n >\n <path d={pathData} />\n </svg>\n );\n }\n return (\n <div\n key={el.id}\n style={{\n ...style,\n backgroundColor: el.fill,\n borderRadius: el.shapeType === 'ellipse' ? '50%' : '0'\n }}\n />\n );\n } else if (el.type === 'image') {\n return (\n <img\n key={el.id}\n src={el.src}\n alt=\"\"\n style={{\n ...style,\n objectFit: 'contain'\n }}\n />\n );\n }\n return null;\n })}\n </div>\n </div>\n </div>\n );\n};\n\nexport const Sidebar: React.FC<SidebarProps> = ({\n slides,\n currentSlideIndex,\n onSelectSlide,\n onDeleteSlide,\n onDuplicateSlide,\n onReorderSlides,\n uiScale,\n appBgColor = '#B7472A'\n}) => {\n const sensors = useSensors(\n useSensor(PointerSensor, {\n activationConstraint: {\n distance: 5,\n },\n }),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n })\n );\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { active, over } = event;\n if (active.id !== over?.id) {\n const oldIndex = slides.findIndex((s) => s.id === active.id);\n const newIndex = slides.findIndex((s) => s.id === over?.id);\n onReorderSlides(oldIndex, newIndex);\n }\n };\n\n return (\n <div\n className=\"bg-white border-r border-slate-100 overflow-y-auto p-4 flex flex-col gap-4\"\n style={{ width: `${Math.max(220, 256 * uiScale)}px` }}\n >\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <SortableContext\n items={slides.map(s => s.id)}\n strategy={verticalListSortingStrategy}\n >\n {slides.map((slide, index) => (\n <SortableSlide\n key={slide.id}\n slide={slide}\n index={index}\n isActive={index === currentSlideIndex}\n onSelect={() => onSelectSlide(index)}\n onDelete={() => onDeleteSlide(index)}\n onDuplicate={() => onDuplicateSlide(index)}\n showDelete={slides.length > 1}\n uiScale={uiScale}\n appBgColor={appBgColor}\n />\n ))}\n </SortableContext>\n </DndContext>\n </div>\n );\n};\n","'use client';\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport * as fabric from 'fabric';\nimport type { Slide, SlideElement, ShapeType } from '../lib/types';\nimport { Sparkles, Image as ImageIcon, Trash2, Plus, PieChart } from 'lucide-react';\nimport { cn } from '../lib/utils';\n\nconst SHAPE_PATHS: Record<string, string> = {\n triangle: 'M 12,4 L 20,18 H 4 L 12,4 Z',\n rightTriangle: 'M 4,4 V 20 H 20 L 4,4 Z',\n rhombus: 'M 12,4 L 20,12 L 12,20 L 4,12 L 12,4 Z',\n parallelogram: 'M 7,4 H 21 L 17,20 H 3 L 7,4 Z',\n trapezoid: 'M 6,4 H 18 L 21,20 H 3 L 6,4 Z',\n pentagon: 'M 12,3 L 21,9 V 19 H 3 V 9 L 12,3 Z',\n hexagon: 'M 12,3 L 20,7.5 V 16.5 L 12,21 L 4,16.5 V 7.5 L 12,3 Z',\n heptagon: 'M 12,3 L 18.5,6 L 21,13 L 16,20 H 8 L 3,13 L 5.5,6 L 12,3 Z',\n octagon: 'M 8.5,3 H 15.5 L 21,8.5 V 15.5 L 15.5,21 H 8.5 L 3,15.5 V 8.5 L 8.5,3 Z',\n heart: 'M 12,21.35 L 10.55,20.03 C 5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3 C 9.24,3 10.91,3.81 12,5.09 C 13.09,3.81 14.76,3 16.5,3 C 19.58,3 22,5.42 22,8.5 C 22,12.28 18.6,15.36 13.45,20.04 L 12,21.35 Z',\n smiley: 'M 12,3 A 9,9 0 1,0 12,21 A 9,9 0 1,0 12,3 M 9,9 A 1.5,1.5 0 1,1 9,10.5 A 1.5,1.5 0 1,1 9,9 M 15,9 A 1.5,1.5 0 1,1 15,10.5 A 1.5,1.5 0 1,1 15,9 M 8,15 C 8,15 9.5,17 12,17 C 14.5,17 16,15 16,15',\n sun: 'M 12,7 A 5,5 0 1,1 12,17 A 5,5 0 1,1 12,7 M 12,2 V 4 M 12,20 V 22 M 4,12 H 2 M 22,12 H 20 M 19.07,4.93 L 17.66,6.34 M 6.34,17.66 L 4.93,19.07 M 4.93,4.93 L 6.34,6.34 M 17.66,17.66 L 19.07,19.07',\n moon: 'M 12,3 A 9,9 0 1,0 12,21 A 7,7 0 0,1 12,3 Z',\n circle: 'M 12,3 A 9,9 0 1,1 12,21 A 9,9 0 1,1 12,3 Z',\n arrowRight: 'M 4,11 H 15.5 L 12,7.5 L 13.5,6 L 19.5,12 L 13.5,18 L 12,16.5 L 15.5,13 H 4 Z',\n arrowLeft: 'M 20,11 H 8.5 L 12,7.5 L 10.5,6 L 4.5,12 L 10.5,18 L 12,16.5 L 8.5,13 H 20 Z',\n arrowUp: 'M 13,20 V 8.5 L 16.5,12 L 18,10.5 L 12,4.5 L 6,10.5 L 7.5,12 L 11,8.5 V 20 Z',\n arrowDown: 'M 11,4 V 15.5 L 7.5,12 L 6,13.5 L 12,19.5 L 18,13.5 L 16.5,12 L 13,15.5 V 4 Z',\n arrowLeftRight: 'M 4,12 L 8,8 V 11 H 16 V 8 L 20,12 L 16,16 V 13 H 8 V 16 L 4,12 Z',\n arrowUpDown: 'M 12,4 L 8,8 H 11 V 16 H 8 L 12,20 L 16,16 H 13 V 8 H 16 L 12,4 Z',\n star4: 'M 12,2 L 14,10 L 22,12 L 14,14 L 12,22 L 10,14 L 2,12 L 10,10 L 12,2 Z',\n star5: 'M 12,2 L 14.5,9.5 H 22 L 16,14 L 18.5,21.5 L 12,17 L 5.5,21.5 L 8,14 L 2,9.5 H 9.5 L 12,2 Z',\n star6: 'M 12,2 L 15,7 L 21,6 L 17,10.5 L 19,17 L 12,14 L 5,17 L 7,10.5 L 3,6 L 9,7 L 12,2 Z',\n star8: 'M 12,2 L 14,6 L 18,4 L 16,8 L 20,10 L 16,12 L 18,16 L 14,14 L 12,18 L 10,14 L 6,16 L 8,12 L 4,10 L 8,8 L 6,4 L 10,6 L 12,2 Z',\n cloud: 'M 17,19 C 14.8,19 13.1,17.7 12.3,15.8 C 11.4,16 10.5,16.2 9.6,16.2 C 7,16.2 4.7,14.6 3.7,12.3 C 1.5,11.8 0,9.9 0,7.6 C 0,5 2.1,2.9 4.7,2.9 C 5.3,2.9 5.8,3 6.3,3.1 C 7.6,1.4 9.6,0.3 11.9,0.3 C 12.5,0.3 13.1,0.4 13.7,0.5 C 15,1.9 15.9,3.7 16,5.7 C 18.2,6.1 20,8.1 20,10.5 C 20,13.2 17.8,15.4 15.1,15.4 C 14.8,15.4 14.5,15.4 14.2,15.3 C 14.2,15.4 14.2,15.4 14.2,15.5 C 14.2,17.4 15.5,19 17,19 Z',\n lightning: 'M 13,2 L 3,14 H 12 V 22 L 22,10 H 13 L 16,2 Z',\n plus: 'M 19,13 H 13 V 19 H 11 V 13 H 5 V 11 H 11 V 5 H 13 V 11 H 19 V 13 Z',\n minus: 'M 19,13 H 5 V 11 H 19 V 13 Z',\n multiply: 'M 19,6.41 L 17.59,5 L 12,10.59 L 6.41,5 L 5,6.41 L 10.59,12 L 5,17.59 L 6.41,19 L 12,13.41 L 17.59,19 L 19,17.59 L 13.41,12 L 19,6.41 Z',\n divide: 'M 12,7 A 2,2 0 1,1 12,11 A 2,2 0 1,1 12,7 M 12,17 A 2,2 0 1,1 12,21 A 2,2 0 1,1 12,17 M 5,11 H 19 V 13 H 5 V 11 Z',\n equal: 'M 19,10 H 5 V 8 H 19 V 10 M 19,16 H 5 V 14 H 19 V 16 Z'\n};\n\nconst getBulletContent = (listType: string | undefined, isBulleted: boolean | undefined, isNumbered: boolean | undefined, index: number): string => {\n if (isBulleted) {\n switch (listType) {\n case 'bullet-disc': return '•';\n case 'bullet-circle': return '○';\n case 'bullet-square': return '■';\n case 'bullet-square-outlined': return '□';\n case 'bullet-diamond': return '◆';\n case 'bullet-arrow': return '➤';\n case 'bullet-check': return '✓';\n case 'none': return '';\n default: return '•'; // Default to disc\n }\n } else if (isNumbered) {\n const n = index + 1;\n switch (listType) {\n case 'number-decimal': return `${n}.`;\n case 'number-decimal-paren': return `${n})`;\n case 'number-roman-upper': return toRoman(n) + '.';\n case 'number-roman-lower': return toRoman(n).toLowerCase() + '.';\n case 'number-alpha-upper': return toAlpha(n) + '.';\n case 'number-alpha-lower': return toAlpha(n).toLowerCase() + '.';\n case 'number-alpha-lower-paren': return toAlpha(n).toLowerCase() + ')';\n case 'none': return '';\n default: return `${n}.`; // Default to decimal\n }\n }\n return '';\n};\n\nconst toRoman = (num: number): string => {\n const lookup: { [key: string]: number } = { M: 1000, CM: 900, D: 500, CD: 400, C: 100, XC: 90, L: 50, XL: 40, X: 10, IX: 9, V: 5, IV: 4, I: 1 };\n let roman = '';\n for (const i in lookup) {\n while (num >= lookup[i]) {\n roman += i;\n num -= lookup[i];\n }\n }\n return roman;\n};\n\nconst toAlpha = (num: number): string => {\n return String.fromCharCode(64 + num);\n};\n\nclass CustomTextbox extends fabric.Textbox {\n listType?: string;\n isBulleted?: boolean;\n isNumbered?: boolean;\n\n _renderTextLine(method: any, ctx: any, line: string[], left: number, top: number, lineIndex: number) {\n super._renderTextLine(method, ctx, line, left, top, lineIndex);\n\n if ((this.isBulleted || this.isNumbered) && this.listType !== 'none') {\n const bulletText = getBulletContent(this.listType, this.isBulleted, this.isNumbered, lineIndex);\n if (bulletText) {\n ctx.save();\n const fontSize = this.fontSize || 22;\n // Reduce gap: -1.0em instead of -1.5em for tighter alignment\n const xOffset = -fontSize * 1.0;\n\n // Reduce bullet size to 60% of text size\n const bulletSize = fontSize * 0.6;\n ctx.font = `${this.fontStyle} ${this.fontWeight} ${bulletSize}px ${this.fontFamily}`;\n ctx.fillStyle = this.fill;\n\n // Move bullet up to vertically center it (adjusted for smaller bullet size)\n // User requested \"further up\" from 0.20, so trying 0.35 to hit the visual center\n ctx.fillText(bulletText, left + xOffset, top - (fontSize * 0.35));\n ctx.restore();\n }\n }\n }\n}\n\ninterface CanvasProps {\n slide: Slide;\n onElementUpdate: (elementId: string, updates: Partial<SlideElement>) => void;\n onSelect: (id: string | null) => void;\n uiScale: number;\n onSlashCommand: (\n position: { x: number; y: number },\n mode?: 'default' | 'textbox' | 'text-selection',\n context?: {\n fontFamily?: string;\n fontSize?: number;\n isBold?: boolean;\n isItalic?: boolean;\n isBulleted?: boolean;\n textAlign?: 'left' | 'center' | 'right' | 'justify';\n color?: string;\n }\n ) => void;\n selectedElementId: string | null;\n onAiGenerateClick: () => void;\n onAiGenerateInfographicClick: () => void;\n onUploadImageClick: () => void;\n onDeleteElement: () => void;\n}\n\nexport const EditorCanvas: React.FC<CanvasProps> = ({\n slide, onElementUpdate, onSelect, uiScale, onSlashCommand,\n selectedElementId, onAiGenerateClick, onAiGenerateInfographicClick, onUploadImageClick, onDeleteElement\n}) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const fabricCanvas = useRef<fabric.Canvas | null>(null);\n const isInternalUpdate = useRef(false);\n\n const onElementUpdateRef = useRef(onElementUpdate);\n const onSelectRef = useRef(onSelect);\n const containerRef = useRef<HTMLDivElement>(null);\n const [dynamicScale, setDynamicScale] = useState(1);\n const [canvasReady, setCanvasReady] = useState(false);\n const mousePos = useRef({ x: 0, y: 0 });\n\n // Dynamic Scaling Logic\n useEffect(() => {\n if (!containerRef.current) return;\n\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry) {\n const { width: cw, height: ch } = entry.contentRect;\n // Base dimensions for the slide are 1200x675\n const scaleX = cw / 1200;\n const scaleY = ch / 675;\n // We use the limiting factor (min) and subtract a bit of margin (0.9)\n const scale = Math.min(scaleX, scaleY) * 0.95;\n setDynamicScale(scale);\n }\n });\n\n observer.observe(containerRef.current);\n return () => observer.disconnect();\n }, []);\n\n useEffect(() => {\n onElementUpdateRef.current = onElementUpdate;\n onSelectRef.current = onSelect;\n }, [onElementUpdate, onSelect]);\n\n useEffect(() => {\n if (canvasRef.current && !fabricCanvas.current) {\n const canvas = new fabric.Canvas(canvasRef.current, {\n width: 1200,\n height: 675,\n backgroundColor: 'white',\n selection: true,\n preserveObjectStacking: true\n });\n\n fabricCanvas.current = canvas;\n setCanvasReady(true);\n\n const clamp = (obj: fabric.Object) => {\n if (obj.left! < 0) obj.set('left', 0);\n if (obj.top! < 0) obj.set('top', 0);\n const bound = obj.getBoundingRect();\n if (bound.left + bound.width > (canvas.width || 1200)) obj.set('left', (canvas.width || 1200) - bound.width);\n if (bound.top + bound.height > (canvas.height || 675)) obj.set('top', (canvas.height || 675) - bound.height);\n };\n\n canvas.on('object:moving', (e) => clamp(e.target!));\n canvas.on('object:scaling', (e) => clamp(e.target!));\n\n const handleUpdate = (e: any) => {\n if (isInternalUpdate.current) return;\n const obj = e.target as any;\n const elementId = obj.get('data')?.id;\n if (obj && elementId) {\n onElementUpdateRef.current(elementId, {\n x: obj.left,\n y: obj.top,\n width: obj.getScaledWidth(),\n height: obj.getScaledHeight(),\n ...(obj.isType('textbox') ? {\n content: (obj as fabric.Textbox).text,\n textAlign: (obj as fabric.Textbox).textAlign as any,\n fontSize: obj.fontSize,\n fontFamily: obj.fontFamily,\n color: obj.fill as string\n } : {\n fill: obj.fill as string\n })\n });\n }\n };\n\n canvas.on('object:modified', handleUpdate);\n canvas.on('text:changed', handleUpdate);\n\n const getContext = (obj: any) => {\n if (!obj || !obj.isType('textbox')) return undefined;\n return {\n fontFamily: obj.fontFamily,\n fontSize: obj.fontSize,\n isBold: obj.fontWeight === 'bold',\n isItalic: obj.fontStyle === 'italic',\n isUnderline: obj.underline,\n textAlign: obj.textAlign as any,\n color: obj.fill as string,\n highlightColor: obj.textBackgroundColor as string,\n // Check if it's bulleted (this might depend on how it's stored in fabric)\n isBulleted: !!(obj as any).isBulleted,\n isNumbered: !!(obj as any).isNumbered\n };\n };\n\n const triggerSlashMenu = (obj: any, isTextSelection = false) => {\n try {\n const rect = canvasRef.current?.getBoundingClientRect();\n if (!rect || !obj) return;\n\n let x = 0, y = 0;\n\n const hasMethod = (o: any, m: string) => typeof o === 'object' && o !== null && typeof o[m] === 'function';\n const isTextbox = hasMethod(obj, 'isType') && obj.isType('textbox');\n const isEditing = isTextbox && obj.isEditing;\n\n if (isEditing) {\n const getCoords = (o: any) => {\n try {\n const charIndex = o.selectionStart || 0;\n if (hasMethod(o, 'getCursorCoords')) return o.getCursorCoords(charIndex);\n if (hasMethod(o, '_getCursorCoords')) return o._getCursorCoords(charIndex);\n } catch (e) { }\n return null;\n };\n\n const coords = getCoords(obj);\n if (coords) {\n const canvasCoords = fabric.util.transformPoint(\n new fabric.Point(coords.left, coords.top),\n hasMethod(obj, 'calcTransformMatrix') ? obj.calcTransformMatrix() : [1, 0, 0, 1, 0, 0]\n );\n const vpt = canvas.viewportTransform || [1, 0, 0, 1, 0, 0];\n const viewportCoords = fabric.util.transformPoint(canvasCoords, vpt);\n x = rect.left + viewportCoords.x * dynamicScale;\n y = rect.top + viewportCoords.y * dynamicScale;\n } else {\n const bound = hasMethod(obj, 'getBoundingRect') ? obj.getBoundingRect() : { left: 0, top: 0, width: 0, height: 0 };\n x = rect.left + (bound.left + bound.width / 2) * dynamicScale;\n y = rect.top + bound.top * dynamicScale;\n }\n } else {\n const bound = hasMethod(obj, 'getBoundingRect') ? obj.getBoundingRect() : { left: mousePos.current.x, top: mousePos.current.y, width: 0, height: 0 };\n x = rect.left + (bound.left + bound.width / 2) * dynamicScale;\n y = rect.top + bound.top * dynamicScale;\n }\n\n if (x && y) {\n const mode = isTextSelection ? 'text-selection' : (isTextbox ? 'textbox' : 'default');\n let finalX = x;\n let finalY = y;\n\n if (mode === 'default') {\n // Default command menu: position near the cursor/object without large centering offsets\n finalX = x + 5;\n finalY = y + 5;\n } else {\n // Horizontal toolbar: center above the text and offset upwards\n finalX = x - 220;\n finalY = y - 140;\n }\n\n onSlashCommand(\n { x: finalX, y: finalY },\n mode,\n getContext(obj)\n );\n }\n } catch (err) {\n console.error('Critical error in triggerSlashMenu:', err);\n }\n };\n\n const syncSelection = (e: any) => {\n const obj = e.selected?.[0] || e.target;\n if (obj) {\n const elementId = (obj as any).get('data')?.id;\n onSelectRef.current(elementId);\n\n // Show slash menu on selection if it's a textbox\n if (obj.isType('textbox') && !isInternalUpdate.current) {\n triggerSlashMenu(obj);\n }\n }\n };\n\n canvas.on('selection:created', syncSelection);\n canvas.on('selection:updated', syncSelection);\n canvas.on('selection:cleared', () => {\n onSelectRef.current(null);\n onSlashCommand({ x: 0, y: 0 }, 'default'); // Close menu or reset\n });\n\n // Handle text selection inside textbox\n canvas.on('text:selection:changed', (e: any) => {\n const obj = e.target;\n if (obj && obj.isType('textbox') && obj.selectionStart !== obj.selectionEnd) {\n triggerSlashMenu(obj, true);\n }\n });\n\n canvas.on('mouse:move', (e: any) => {\n if (e.pointer) {\n mousePos.current = { x: e.pointer.x, y: e.pointer.y };\n }\n });\n\n // Global keyboard navigation\n const handleGlobalKeyDown = (e: KeyboardEvent) => {\n const canvas = fabricCanvas.current;\n if (!canvas) return;\n const activeObj = canvas.getActiveObject();\n\n if (e.key === '/') {\n e.preventDefault();\n triggerSlashMenu(activeObj || { isType: () => false, getBoundingRect: () => ({ left: mousePos.current.x, top: mousePos.current.y, width: 0, height: 0 }) } as any);\n return;\n }\n\n // Don't move if editing text\n if (activeObj && activeObj.isType('textbox') && (activeObj as any).isEditing) return;\n\n if (!activeObj) return;\n\n const step = e.shiftKey ? 10 : 1;\n let moved = false;\n\n switch (e.key) {\n case 'ArrowLeft': activeObj.set('left', activeObj.left - step); moved = true; break;\n case 'ArrowRight': activeObj.set('left', activeObj.left + step); moved = true; break;\n case 'ArrowUp': activeObj.set('top', activeObj.top - step); moved = true; break;\n case 'ArrowDown': activeObj.set('top', activeObj.top + step); moved = true; break;\n }\n\n if (moved) {\n clamp(activeObj);\n canvas.requestRenderAll();\n handleUpdate({ target: activeObj });\n }\n };\n\n window.addEventListener('keydown', handleGlobalKeyDown);\n (canvas as any)._keyboardListener = handleGlobalKeyDown;\n }\n\n return () => {\n if (fabricCanvas.current) {\n const listener = (fabricCanvas.current as any)._keyboardListener;\n if (listener) window.removeEventListener('keydown', listener);\n fabricCanvas.current.dispose();\n fabricCanvas.current = null;\n }\n };\n }, []); // Empty dependency array means this only runs once!\n\n useEffect(() => {\n if (!fabricCanvas.current) return;\n const canvas = fabricCanvas.current;\n\n const syncElements = async () => {\n isInternalUpdate.current = true;\n\n const existingObjs = canvas.getObjects();\n const slideIds = new Set(slide.elements.map((e: SlideElement) => e.id));\n\n existingObjs.forEach(obj => {\n const id = (obj as any).get('data')?.id;\n if (id && !slideIds.has(id)) {\n canvas.remove(obj);\n }\n });\n\n const sorted = [...slide.elements].sort((a, b) => (a.zIndex || 0) - (b.zIndex || 0));\n\n for (const el of sorted) {\n let obj = existingObjs.find((o: fabric.Object) => (o as any).get('data')?.id === el.id) as any;\n\n // Upgrade legacy Textbox to CustomTextbox to ensure list rendering works\n if (obj && obj.type === 'textbox' && !(obj instanceof CustomTextbox)) {\n canvas.remove(obj);\n obj = null;\n }\n\n if (obj) {\n // CRITICAL: Skip syncing properties for the object currently being edited.\n // If we update properties (like 'text') while Fabric.js is in editing mode,\n // it resets the cursor position and can cause desync/focus loss.\n if (obj === canvas.getActiveObject() && obj.isType('textbox') && (obj as fabric.Textbox).isEditing) {\n continue;\n }\n\n const updates: any = {\n left: el.x,\n top: el.y,\n opacity: el.opacity !== undefined ? el.opacity : 1,\n zIndex: el.zIndex\n };\n\n if (el.type === 'text' && obj.isType('textbox')) {\n updates.text = el.content || ' ';\n updates.fontSize = el.fontSize || 22;\n updates.fill = el.color || '#000000';\n updates.textBackgroundColor = el.highlightColor || '';\n updates.textAlign = el.textAlign || 'left';\n updates.fontWeight = el.isBold ? 'bold' : 'normal';\n updates.fontStyle = el.isItalic ? 'italic' : 'normal';\n updates.underline = el.isUnderline || false;\n updates.linethrough = el.isStrikethrough || false;\n updates.charSpacing = el.charSpacing || 0;\n updates.fontFamily = el.fontFamily || 'Arial';\n (obj as any).isBulleted = el.isBulleted;\n (obj as any).isNumbered = el.isNumbered;\n (obj as any).listType = el.listType;\n updates.width = Math.max(el.width || 50, 10);\n } else if (el.type === 'shape') {\n updates.fill = (el as any).fill || '#cccccc';\n updates.scaleX = (el.width || 50) / (obj.width || 1);\n updates.scaleY = (el.height || 50) / (obj.height || 1);\n } else if (el.type === 'image') {\n updates.scaleX = (el.width || 100) / (obj.width || 1);\n updates.scaleY = (el.height || 100) / (obj.height || 1);\n }\n\n obj.set(updates);\n } else {\n let newObj: fabric.Object | null = null;\n const commonProps = {\n left: el.x,\n top: el.y,\n data: { id: el.id },\n originX: 'left' as const,\n originY: 'top' as const,\n opacity: el.opacity !== undefined ? el.opacity : 1\n };\n\n if (el.type === 'text') {\n newObj = new CustomTextbox(el.content || ' ', {\n ...commonProps,\n width: Math.max(el.width || 200, 10),\n fontSize: el.fontSize || 22,\n fill: el.color || '#000000',\n backgroundColor: el.highlightColor || '',\n fontFamily: el.fontFamily || 'Inter, Arial, sans-serif',\n textAlign: el.textAlign || 'left',\n fontWeight: el.isBold ? 'bold' : 'normal',\n fontStyle: el.isItalic ? 'italic' : 'normal',\n underline: el.isUnderline || false,\n linethrough: el.isStrikethrough || false,\n charSpacing: el.charSpacing || 0,\n splitByGrapheme: false,\n objectCaching: false, // Critical: customized _renderTextLine draws outside bounding box\n });\n (newObj as any).isBulleted = el.isBulleted;\n (newObj as any).isNumbered = el.isNumbered;\n (newObj as any).listType = el.listType;\n } else if (el.type === 'shape') {\n const shapeFill = (el as any).fill || '#3b82f6';\n if (el.shapeType === 'ellipse') {\n newObj = new fabric.Circle({\n ...commonProps,\n radius: (el.width || 100) / 2,\n scaleY: (el.height || 100) / (el.width || 100),\n fill: shapeFill,\n });\n } else if (el.shapeType === 'rect') {\n newObj = new fabric.Rect({\n ...commonProps,\n width: el.width || 100,\n height: el.height || 100,\n fill: shapeFill,\n });\n } else {\n const pathData = SHAPE_PATHS[el.shapeType];\n if (pathData) {\n newObj = new fabric.Path(pathData, {\n ...commonProps,\n fill: shapeFill,\n });\n // Scale the path to fit the requested dimensions\n // Paths in SHAPE_PATHS are roughly 24x24 based on viewbox\n const p = newObj as fabric.Path;\n p.set({\n scaleX: (el.width || 100) / (p.width || 1),\n scaleY: (el.height || 100) / (p.height || 1),\n });\n } else {\n // Default back to rect if path not found\n newObj = new fabric.Rect({\n ...commonProps,\n width: el.width || 100,\n height: el.height || 100,\n fill: shapeFill,\n });\n }\n }\n } else if (el.type === 'image') {\n try {\n const img = await fabric.FabricImage.fromURL(el.src);\n img.set({\n ...commonProps,\n scaleX: (el.width || 100) / (img.width || 1),\n scaleY: (el.height || 100) / (img.height || 1),\n } as any);\n newObj = img;\n } catch (err) { console.error(err); }\n }\n\n if (newObj) {\n canvas.add(newObj);\n }\n }\n }\n\n canvas.renderAll();\n isInternalUpdate.current = false;\n };\n\n syncElements();\n }, [slide, canvasReady]);\n\n const selectedElement = slide.elements.find(el => el.id === selectedElementId);\n\n return (\n <div ref={containerRef} className=\"w-full h-full flex items-center justify-center overflow-hidden relative\">\n <div\n className=\"border border-slate-200 overflow-hidden bg-white shadow-xl transition-all duration-300 ease-out shrink-0 relative\"\n style={{\n transform: `scale(${dynamicScale})`,\n transformOrigin: 'center center'\n }}\n >\n <canvas ref={canvasRef} />\n\n {/* Empty Slide Helper Overlay */}\n {slide.elements.length === 0 && (\n <div className=\"absolute inset-0 flex flex-col items-center justify-center pointer-events-none select-none animate-in fade-in duration-700\">\n <div className=\"flex flex-col items-center gap-4 text-slate-300\">\n {/* <div className=\"p-5 rounded-full bg-slate-50/50 border border-slate-100/50\">\n <Plus size={40} strokeWidth={1.5} className=\"opacity-50\" />\n </div> */}\n <div className=\"flex flex-col items-center gap-1 text-center\">\n {/* <h3 className=\"text-lg font-semibold text-slate-400\">Empty Slide</h3> */}\n <h1 className=\"text-2xl font-medium text-slate-400\">\n Click <span className=\"px-2 py-0.5 bg-slate-100 rounded-md text-slate-500 font-bold\">/</span> for options\n </h1>\n </div>\n </div>\n </div>\n )}\n\n {/* Image Context Toolbar (Floating vertical list matching SlashMenu style) */}\n {selectedElement && selectedElement.type === 'image' && (\n <div\n className=\"absolute z-[5000] flex flex-col w-96 bg-white border border-slate-200 shadow-2xl rounded-2xl overflow-hidden animate-in fade-in zoom-in duration-200\"\n style={{\n // Horizontal positioning: Left or Right of the image\n left: selectedElement.x + (selectedElement.width / 2) > 600\n ? `${selectedElement.x - 12}px`\n : `${selectedElement.x + selectedElement.width + 12}px`,\n top: `${selectedElement.y + (selectedElement.height / 2)}px`,\n transform: selectedElement.x + (selectedElement.width / 2) > 600\n ? 'translate(-100%, -50%)'\n : 'translate(0, -50%)',\n }}\n >\n <div className=\"px-5 py-3.5 text-sm uppercase tracking-wider font-bold text-slate-400 bg-slate-50/50 border-b border-slate-100\">\n Image Actions\n </div>\n\n <div className=\"p-2.5 flex flex-col gap-1\">\n {/* AI Generate */}\n <button\n onClick={(e) => { e.stopPropagation(); onAiGenerateClick(); }}\n className=\"w-full flex items-center gap-5 px-5 py-4 text-left transition-all duration-150 rounded-xl hover:bg-slate-50 group\"\n >\n <div className=\"p-3 rounded-xl bg-blue-50 text-blue-600 group-hover:bg-blue-600 group-hover:text-white transition-colors\">\n <Sparkles size={28} />\n </div>\n <div className=\"flex flex-col min-w-0\">\n <span className=\"text-lg font-bold text-slate-900\">AI Generate Image</span>\n <span className=\"text-sm text-slate-400 truncate leading-tight\">Create an image with AI prompt</span>\n </div>\n </button>\n\n {/* AI Generate Infographic */}\n <button\n onClick={(e) => { e.stopPropagation(); onAiGenerateInfographicClick(); }}\n className=\"w-full flex items-center gap-5 px-5 py-4 text-left transition-all duration-150 rounded-xl hover:bg-slate-50 group\"\n >\n <div className=\"p-3 rounded-xl bg-purple-50 text-purple-600 group-hover:bg-purple-600 group-hover:text-white transition-colors\">\n <PieChart size={28} />\n </div>\n <div className=\"flex flex-col min-w-0\">\n <span className=\"text-lg font-bold text-slate-900\">AI Infographic</span>\n <span className=\"text-sm text-slate-400 truncate leading-tight\">Generate chart or diagram</span>\n </div>\n </button>\n\n {/* Change Image */}\n <button\n onClick={(e) => { e.stopPropagation(); onUploadImageClick(); }}\n className=\"w-full flex items-center gap-5 px-5 py-4 text-left transition-all duration-150 rounded-xl hover:bg-slate-50 group\"\n >\n <div className=\"p-3 rounded-xl bg-slate-100 text-slate-500 group-hover:bg-slate-200 group-hover:text-slate-700 transition-colors\">\n <ImageIcon size={28} />\n </div>\n <div className=\"flex flex-col min-w-0\">\n <span className=\"text-lg font-bold text-slate-700\">Change Image</span>\n <span className=\"text-sm text-slate-400 truncate leading-tight\">Replace with local file</span>\n </div>\n </button>\n\n <div className=\"h-[1px] bg-slate-100 my-1 mx-3\" />\n\n {/* Delete */}\n <button\n onClick={(e) => { e.stopPropagation(); onDeleteElement(); }}\n className=\"w-full flex items-center gap-5 px-5 py-4 text-left transition-all duration-150 rounded-xl hover:bg-red-50 group\"\n >\n <div className=\"p-3 rounded-xl bg-red-50 text-red-500 group-hover:bg-red-500 group-hover:text-white transition-colors\">\n <Trash2 size={28} />\n </div>\n <div className=\"flex flex-col min-w-0\">\n <span className=\"text-lg font-bold text-red-600\">Delete Element</span>\n <span className=\"text-sm text-red-400/80 truncate leading-tight\">Remove from slide</span>\n </div>\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n};\n","import pptxgen from 'pptxgenjs';\nimport type { Presentation } from './types';\n\nexport class PptxExporter {\n async export(presentation: Presentation): Promise<void> {\n const pptx = new pptxgen();\n\n const emuWidth = presentation.layout?.width || 12192000;\n const emuHeight = presentation.layout?.height || 6858000;\n const canvasWidth = 1200;\n const canvasHeight = 675;\n\n const getInchesX = (px: number) => (px / canvasWidth) * (emuWidth / 914400);\n const getInchesY = (px: number) => (px / canvasHeight) * (emuHeight / 914400);\n\n presentation.slides.forEach(slide => {\n const pptxSlide = pptx.addSlide();\n\n // Sort by zIndex for export layering\n const sortedElements = [...slide.elements].sort((a, b) => a.zIndex - b.zIndex);\n\n sortedElements.forEach(el => {\n const transparency = el.opacity !== undefined ? (1 - el.opacity) * 100 : 0;\n const common = {\n x: getInchesX(el.x),\n y: getInchesY(el.y),\n w: getInchesX(el.width),\n h: getInchesY(el.height),\n };\n\n if (el.type === 'text') {\n pptxSlide.addText(el.content, {\n ...common,\n fontSize: (el.fontSize || 18) / 2, // Halve for export\n color: el.color?.replace('#', '') || '000000',\n fontFace: el.fontFamily || 'Arial'\n });\n } else if (el.type === 'image') {\n pptxSlide.addImage({\n ...common,\n path: el.src,\n transparency: transparency\n });\n } else if (el.type === 'shape') {\n const shapeType = el.shapeType === 'ellipse' ? pptx.ShapeType.ellipse : pptx.ShapeType.rect;\n pptxSlide.addShape(shapeType, {\n ...common,\n fill: {\n color: el.fill?.replace('#', '') || 'CCCCCC',\n transparency: transparency > 0 ? Math.min(transparency + 10, 100) : 0 // Slightly lighter as requested\n }\n });\n }\n });\n });\n\n await pptx.writeFile({ fileName: 'presentation.pptx' });\n }\n}\n","import JSZip from 'jszip';\nimport type { Presentation, Slide, SlideElement, ShapeType } from './types';\n\nexport class PptxParser {\n private slideWidth = 12192000;\n private slideHeight = 6858000;\n private readonly CANVAS_WIDTH = 1200;\n private readonly CANVAS_HEIGHT = 675;\n\n async parse(input: File | Blob | ArrayBuffer | string): Promise<Presentation> {\n let data: any = input;\n if (typeof input === 'string') {\n const response = await fetch(input);\n if (!response.ok) {\n const status = response.status;\n const statusText = response.statusText;\n\n let detail = '';\n try {\n const errorJson = await response.json();\n detail = errorJson.details || errorJson.error || '';\n } catch (e) {\n // Ignore if not JSON\n }\n\n throw new Error(`Failed to fetch PPTX from ${input}: ${status} ${statusText} ${detail ? `(${detail})` : ''}`);\n }\n data = await response.arrayBuffer();\n }\n const zip = await JSZip.loadAsync(data);\n const presentationXml = await zip.file('ppt/presentation.xml')?.async('string');\n if (!presentationXml) throw new Error('Invalid PPTX');\n\n const parser = new DOMParser();\n const presentationDoc = parser.parseFromString(presentationXml, 'text/xml');\n\n const sldSz = this.findFirstByLocalName(presentationDoc, 'sldSz');\n if (sldSz) {\n this.slideWidth = parseInt(this.getAttr(sldSz, 'cx') || '12192000');\n this.slideHeight = parseInt(this.getAttr(sldSz, 'cy') || '6858000');\n }\n\n const sldIdList = Array.from(presentationDoc.getElementsByTagNameNS('*', 'sldId'));\n const slides: Slide[] = [];\n\n for (let i = 0; i < sldIdList.length; i++) {\n const slideNum = i + 1;\n const slidePath = `ppt/slides/slide${slideNum}.xml`;\n const slideXml = await zip.file(slidePath)?.async('string');\n if (slideXml) {\n const slide = await this.parseSlide(slideXml, slideNum, zip);\n slides.push(slide);\n }\n }\n\n return {\n slides,\n layout: { width: this.slideWidth, height: this.slideHeight }\n };\n }\n\n private getAttr(el: Element, name: string): string | null {\n return el.getAttribute(name) || el.getAttribute(`a:${name}`) || el.getAttribute(`p:${name}`) || el.getAttribute(`r:${name}`);\n }\n\n private findFirstByLocalName(parent: Document | Element, name: string): Element | null {\n const elements = parent.getElementsByTagNameNS('*', name);\n return elements.length > 0 ? elements[0] : null;\n }\n\n private findAllByLocalName(parent: Document | Element, name: string): Element[] {\n return Array.from(parent.getElementsByTagNameNS('*', name));\n }\n\n private scaleX(emu: number): number {\n return (emu / this.slideWidth) * this.CANVAS_WIDTH;\n }\n\n private scaleY(emu: number): number {\n return (emu / this.slideHeight) * this.CANVAS_HEIGHT;\n }\n\n private parseColor(el: Element): { color: string, opacity: number } {\n const srgbClr = this.findFirstByLocalName(el, 'srgbClr');\n if (srgbClr) {\n const hex = `#${this.getAttr(srgbClr, 'val')}`;\n const alphaNode = this.findFirstByLocalName(srgbClr, 'alpha');\n const opacity = alphaNode ? parseInt(this.getAttr(alphaNode, 'val') || '100000') / 100000 : 1;\n return { color: hex, opacity };\n }\n const schemeClr = this.findFirstByLocalName(el, 'schemeClr');\n if (schemeClr) {\n const alphaNode = this.findFirstByLocalName(schemeClr, 'alpha');\n const opacity = alphaNode ? parseInt(this.getAttr(alphaNode, 'val') || '100000') / 100000 : 1;\n return { color: '#000000', opacity }; // Themes usually default to dark if not specified\n }\n return { color: '#000000', opacity: 1 };\n }\n\n private async resolveImage(relId: string, slideIndex: number, zip: JSZip): Promise<Blob | null> {\n const relsXml = await zip.file(`ppt/slides/_rels/slide${slideIndex}.xml.rels`)?.async('string');\n if (!relsXml) return null;\n\n const parser = new DOMParser();\n const relsDoc = parser.parseFromString(relsXml, 'text/xml');\n const relationship = Array.from(relsDoc.getElementsByTagName('Relationship'))\n .find(r => r.getAttribute('Id') === relId);\n\n const target = relationship?.getAttribute('Target');\n if (target) {\n const mediaPath = (target.startsWith('../') ? `ppt/${target.substring(3)}` : `ppt/slides/${target}`).replace('ppt/slides/../', 'ppt/');\n return await zip.file(mediaPath)?.async('blob') || null;\n }\n return null;\n }\n\n private async parseSlide(xml: string, slideIndex: number, zip: JSZip): Promise<Slide> {\n const parser = new DOMParser();\n const doc = parser.parseFromString(xml, 'text/xml');\n const elements: SlideElement[] = [];\n let zIndex = 0;\n\n // Check for Background Image\n const bg = this.findFirstByLocalName(doc, 'bg');\n if (bg) {\n const blip = this.findFirstByLocalName(bg, 'blip');\n const relId = blip?.getAttributeNS('http://schemas.openxmlformats.org/officeDocument/2006/relationships', 'embed') ||\n blip?.getAttribute('r:embed');\n if (relId) {\n const mediaFile = await this.resolveImage(relId, slideIndex, zip);\n if (mediaFile) {\n elements.push({\n id: `bg-${slideIndex}`,\n type: 'image',\n src: URL.createObjectURL(mediaFile),\n x: 0,\n y: 0,\n width: this.CANVAS_WIDTH,\n height: this.CANVAS_HEIGHT,\n zIndex: zIndex++,\n opacity: 1\n });\n }\n }\n }\n\n const spTree = this.findFirstByLocalName(doc, 'spTree');\n if (!spTree) return { id: `slide-${slideIndex}`, elements };\n\n const children = Array.from(spTree.children);\n for (const child of children) {\n const localName = child.localName;\n\n if (localName === 'sp') {\n const txBody = this.findFirstByLocalName(child, 'txBody');\n const nvSpPr = this.findFirstByLocalName(child, 'nvSpPr');\n const nvPr = nvSpPr ? this.findFirstByLocalName(nvSpPr, 'nvPr') : null;\n const ph = nvPr ? this.findFirstByLocalName(nvPr, 'ph') : null;\n const phType = ph ? this.getAttr(ph, 'type') : null;\n const isBodyPlaceholder = ph && (!phType || phType === 'body');\n const xfrm = this.findFirstByLocalName(child, 'xfrm');\n const off = xfrm ? this.findFirstByLocalName(xfrm, 'off') : null;\n const ext = xfrm ? this.findFirstByLocalName(xfrm, 'ext') : null;\n\n if (txBody && off && ext) {\n const paragraphs = this.findAllByLocalName(txBody, 'p');\n let content = '';\n let fontSize = 18;\n let color = '#000000';\n let opacity = 1;\n let isBulleted = false;\n let isNumbered = false;\n\n for (const p of paragraphs) {\n const pPr = this.findFirstByLocalName(p, 'pPr');\n const buNone = pPr ? this.findFirstByLocalName(pPr, 'buNone') : null;\n let paragraphContent = '';\n\n // Parse paragraph properties\n if (pPr && !buNone) {\n if (this.findFirstByLocalName(pPr, 'buAutoNum')) {\n isNumbered = true;\n } else if (this.findFirstByLocalName(pPr, 'buChar')) {\n isBulleted = true;\n } else {\n // Heuristic 1: Hanging indent\n const indent = parseInt(this.getAttr(pPr, 'indent') || '0');\n if (indent < 0) {\n isBulleted = true;\n }\n // Heuristic 2: Body placeholder inheritance\n else if (isBodyPlaceholder) {\n isBulleted = true;\n }\n }\n } else if (!pPr && isBodyPlaceholder) {\n isBulleted = true;\n }\n\n const runs = this.findAllByLocalName(p, 'r');\n for (const r of runs) {\n const t = this.findFirstByLocalName(r, 't');\n if (t) paragraphContent += t.textContent;\n\n const rPr = this.findFirstByLocalName(r, 'rPr');\n if (rPr) {\n const sz = this.getAttr(rPr, 'sz');\n if (sz) fontSize = (parseInt(sz) / 100) * 2;\n const style = this.parseColor(rPr);\n color = style.color;\n opacity = style.opacity;\n }\n }\n\n // Heuristic 3: Baked-in text bullets\n // Check if text starts with a bullet character (•, etc)\n const bulletRegex = /^\\s*([•\\u2022\\u2023\\u25E6\\u2043\\u2219])\\s+/;\n const match = paragraphContent.match(bulletRegex);\n if (match) {\n isBulleted = true;\n // Remove the bullet char and trim leading whitespace\n paragraphContent = paragraphContent.replace(bulletRegex, '');\n }\n\n content += paragraphContent + '\\n';\n }\n\n if (content.trim()) {\n elements.push({\n id: `el-${slideIndex}-${Date.now()}-${zIndex}`,\n type: 'text',\n content: content.trim(),\n x: this.scaleX(parseInt(this.getAttr(off, 'x') || '0')),\n y: this.scaleY(parseInt(this.getAttr(off, 'y') || '0')),\n width: this.scaleX(parseInt(this.getAttr(ext, 'cx') || '0')),\n height: this.scaleY(parseInt(this.getAttr(ext, 'cy') || '0')),\n fontSize,\n color,\n fontFamily: 'Arial',\n zIndex: zIndex++,\n isBulleted,\n isNumbered,\n listType: isNumbered ? 'number-decimal' : (isBulleted ? 'bullet-disc' : 'none'),\n opacity\n });\n continue;\n }\n }\n\n const prstGeom = this.findFirstByLocalName(child, 'prstGeom');\n if (prstGeom && off && ext) {\n const prst = this.getAttr(prstGeom, 'prst') || 'rect';\n const spPr = this.findFirstByLocalName(child, 'spPr');\n const style = spPr ? this.parseColor(spPr) : { color: '#cccccc', opacity: 1 };\n\n // Mapping PPTX preset names to our internal shape types\n const mapping: Record<string, ShapeType> = {\n 'rect': 'rect',\n 'roundRect': 'rect',\n 'ellipse': 'ellipse',\n 'circle': 'ellipse',\n 'triangle': 'triangle',\n 'rtTriangle': 'rightTriangle',\n 'diamond': 'rhombus',\n 'parallelogram': 'parallelogram',\n 'trapezoid': 'trapezoid',\n 'pentagon': 'pentagon',\n 'hexagon': 'hexagon',\n 'heptagon': 'heptagon',\n 'octagon': 'octagon',\n 'heart': 'heart',\n 'smileyFace': 'smiley',\n 'sun': 'sun',\n 'moon': 'moon',\n 'rightArrow': 'arrowRight',\n 'leftArrow': 'arrowLeft',\n 'upArrow': 'arrowUp',\n 'downArrow': 'arrowDown',\n 'leftRightArrow': 'arrowLeftRight',\n 'upDownArrow': 'arrowUpDown',\n 'star4': 'star4',\n 'star5': 'star5',\n 'star6': 'star6',\n 'star8': 'star8',\n 'cloud': 'cloud',\n 'lightningBolt': 'lightning',\n 'plus': 'plus',\n 'minus': 'minus',\n 'multiply': 'multiply',\n 'divide': 'divide',\n 'equal': 'equal'\n };\n\n elements.push({\n id: `el-${slideIndex}-${Date.now()}-${zIndex}`,\n type: 'shape',\n shapeType: (mapping[prst] || 'rect'),\n fill: style.color,\n opacity: style.opacity,\n x: this.scaleX(parseInt(this.getAttr(off, 'x') || '0')),\n y: this.scaleY(parseInt(this.getAttr(off, 'y') || '0')),\n width: this.scaleX(parseInt(this.getAttr(ext, 'cx') || '0')),\n height: this.scaleY(parseInt(this.getAttr(ext, 'cy') || '0')),\n zIndex: zIndex++\n });\n }\n }\n\n if (localName === 'pic') {\n const blip = this.findFirstByLocalName(child, 'blip');\n const relId = blip?.getAttributeNS('http://schemas.openxmlformats.org/officeDocument/2006/relationships', 'embed') ||\n blip?.getAttribute('r:embed');\n\n const xfrm = this.findFirstByLocalName(child, 'xfrm');\n const off = xfrm ? this.findFirstByLocalName(xfrm, 'off') : null;\n const ext = xfrm ? this.findFirstByLocalName(xfrm, 'ext') : null;\n\n if (relId && off && ext) {\n const mediaFile = await this.resolveImage(relId, slideIndex, zip);\n if (mediaFile) {\n elements.push({\n id: `el-${slideIndex}-${Date.now()}-${zIndex}`,\n type: 'image',\n src: URL.createObjectURL(mediaFile),\n x: this.scaleX(parseInt(this.getAttr(off, 'x') || '0')),\n y: this.scaleY(parseInt(this.getAttr(off, 'y') || '0')),\n width: this.scaleX(parseInt(this.getAttr(ext, 'cx') || '0')),\n height: this.scaleY(parseInt(this.getAttr(ext, 'cy') || '0')),\n zIndex: zIndex++,\n opacity: 1\n });\n }\n }\n }\n }\n\n return { id: `slide-${slideIndex}`, elements };\n }\n}\n","'use client';\n\nimport React, { useEffect, useState } from 'react';\nimport { ChevronLeft, ChevronRight, X } from 'lucide-react';\nimport type { Presentation, Slide } from '../lib/types';\nimport { EditorCanvas } from './EditorCanvas';\n\ninterface PresenterModeProps {\n presentation: Presentation;\n initialSlideIndex: number;\n onClose: () => void;\n}\n\nexport const PresenterMode: React.FC<PresenterModeProps> = ({\n presentation,\n initialSlideIndex,\n onClose\n}) => {\n const [currentIndex, setCurrentIndex] = useState(initialSlideIndex);\n const currentSlide = presentation.slides[currentIndex];\n\n const goToPrevious = () => {\n if (currentIndex > 0) setCurrentIndex(currentIndex - 1);\n };\n\n const goToNext = () => {\n if (currentIndex < presentation.slides.length - 1) setCurrentIndex(currentIndex + 1);\n };\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'ArrowRight' || e.key === ' ' || e.key === 'PageDown') {\n goToNext();\n } else if (e.key === 'ArrowLeft' || e.key === 'Backspace' || e.key === 'PageUp') {\n goToPrevious();\n } else if (e.key === 'Escape') {\n onClose();\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [currentIndex]);\n\n const [scale, setScale] = useState(1);\n\n useEffect(() => {\n const updateScale = () => {\n const padding = 40;\n const availableWidth = window.innerWidth - padding;\n const availableHeight = window.innerHeight - padding;\n const slideWidth = 1200;\n const slideHeight = 675;\n\n const scaleX = availableWidth / slideWidth;\n const scaleY = availableHeight / slideHeight;\n const newScale = Math.min(scaleX, scaleY);\n setScale(newScale);\n };\n\n updateScale();\n window.addEventListener('resize', updateScale);\n return () => window.removeEventListener('resize', updateScale);\n }, []);\n\n return (\n <div className=\"fixed inset-0 z-[99999] bg-[#0A0A0A] flex flex-col items-center justify-center overflow-hidden\">\n {/* Header / Controls */}\n <div className=\"absolute top-0 left-0 right-0 p-6 flex justify-between items-center opacity-0 hover:opacity-100 transition-opacity bg-gradient-to-b from-black/60 to-transparent z-[100] pointer-events-none\">\n <div className=\"text-white/80 font-bold ml-4 pointer-events-auto\">\n Slide {currentIndex + 1} of {presentation.slides.length}\n </div>\n <button\n onClick={onClose}\n className=\"p-3 bg-white/10 hover:bg-white/20 text-white rounded-full transition-all pointer-events-auto\"\n >\n <X size={24} />\n </button>\n </div>\n\n {/* Slide Container */}\n <div className=\"w-full h-full flex items-center justify-center\">\n <div\n className=\"relative shadow-2xl shadow-black/80 bg-white\"\n style={{\n width: '1200px',\n height: '675px',\n transform: `scale(${scale})`,\n transformOrigin: 'center center'\n }}\n >\n <EditorCanvas\n slide={currentSlide}\n onElementUpdate={() => { }} // No editing in presenter mode\n onSelect={() => { }} // No selection in presenter mode\n uiScale={0.75} // Base width of 1200px / 1600px\n onSlashCommand={() => { }} // No slash commands in presenter mode\n selectedElementId={null}\n onAiGenerateClick={() => { }}\n onAiGenerateInfographicClick={() => { }}\n onUploadImageClick={() => { }}\n onDeleteElement={() => { }}\n />\n </div>\n </div>\n\n {/* Navigation Controls */}\n <div className=\"absolute bottom-10 left-1/2 -translate-x-1/2 flex items-center gap-6 opacity-0 hover:opacity-100 transition-opacity bg-black/40 backdrop-blur-md px-6 py-3 rounded-full border border-white/10 pointer-events-auto\">\n <button\n disabled={currentIndex === 0}\n onClick={goToPrevious}\n className=\"p-2 text-white/50 hover:text-white disabled:opacity-20 transition-colors\"\n >\n <ChevronLeft size={32} />\n </button>\n <div className=\"h-6 w-[1px] bg-white/10\" />\n <button\n disabled={currentIndex === presentation.slides.length - 1}\n onClick={goToNext}\n className=\"p-2 text-white/50 hover:text-white disabled:opacity-20 transition-colors\"\n >\n <ChevronRight size={32} />\n </button>\n </div>\n </div>\n );\n};\n","\nimport React from 'react';\nimport { Check, ArrowRightFromLine, RefreshCw, Trash2, Sparkles, X } from 'lucide-react';\nimport { cn } from '../lib/utils';\n\ninterface RefineMenuProps {\n result: string;\n isLoading: boolean;\n onAction: (action: 'replace' | 'addBelow' | 'discard' | 'regenerate') => void;\n onClose: () => void;\n position?: { x: number; y: number }; // Made optional, as we default to center\n}\n\nexport const RefineMenu: React.FC<RefineMenuProps> = ({ result, isLoading, onAction, onClose, position }) => {\n return (\n <div\n className=\"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[2000] w-80 bg-white border border-slate-200 rounded-xl shadow-2xl animate-in fade-in zoom-in-95 duration-200 overflow-hidden text-left\"\n // We ignore custom position for now to ensure it's always visible/centered (responsive behavior requested)\n >\n <div className=\"px-3 py-2.5 bg-blue-50/50 border-b border-blue-100 flex items-center justify-between\">\n <span className=\"text-xs font-bold text-blue-700 uppercase tracking-wider flex items-center gap-2\">\n <Sparkles size={12} />\n Refined Text\n </span>\n <button onClick={onClose} className=\"text-slate-400 hover:text-slate-600\">\n <X size={14} />\n </button>\n </div>\n\n {isLoading ? (\n <div className=\"p-8 flex flex-col items-center justify-center gap-3 text-slate-400\">\n <RefreshCw size={24} className=\"animate-spin text-blue-500\" />\n <span className=\"text-xs font-medium\">Refining text...</span>\n </div>\n ) : (\n <div className=\"flex flex-col\">\n <div className=\"p-4 bg-slate-50/50 max-h-[300px] overflow-y-auto text-sm text-slate-700 leading-relaxed border-b border-slate-100\">\n {result}\n </div>\n <div className=\"p-1.5 flex flex-col gap-0.5\">\n <button\n onClick={() => onAction('replace')}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <Check size={14} className=\"text-slate-400\" />\n <span>Replace selection</span>\n </button>\n <button\n onClick={() => onAction('addBelow')}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <ArrowRightFromLine size={14} className=\"text-slate-400 rotate-90\" />\n <span>Insert below</span>\n </button>\n <button\n onClick={() => onAction('regenerate')}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-blue-600 hover:bg-blue-50 rounded-lg transition-colors text-left\"\n >\n <RefreshCw size={14} />\n <span>Try again</span>\n </button>\n <div className=\"h-[1px] bg-slate-100 my-1\" />\n <button\n onClick={() => onAction('discard')}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-red-600 hover:bg-red-50 rounded-lg transition-colors text-left\"\n >\n <Trash2 size={14} />\n <span>Discard</span>\n </button>\n </div>\n </div>\n )}\n </div>\n );\n};\n","import React, { useState, useEffect, useRef, useMemo } from 'react';\nimport {\n Type, Square, Circle, Image as ImageIcon, Sparkles,\n PlusCircle, Triangle, Star, Hexagon, ArrowRight,\n Search, Wand2, Type as FontIcon, Layout,\n Bold, Italic, Underline, AlignLeft, AlignCenter, AlignRight, AlignJustify,\n List, ListOrdered, Palette, Trash2, ArrowBigUp, ArrowBigDown,\n ChevronRight, CaseSensitive, MessageSquare, Highlighter, Eraser, ChevronDown, ALargeSmall, ChevronUp, PieChart,\n RefreshCw, Check, ArrowRightFromLine, MoveDown, SpellCheck\n} from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport { ShapeType } from '../lib/types';\n\ninterface SlashMenuItem {\n id: string;\n label: string;\n icon: React.ElementType;\n category: 'Basic' | 'Shapes' | 'AI' | 'Canvas' | 'Formatting' | 'Alignment' | 'List' | 'Actions';\n description?: string;\n action: () => void;\n currentValue?: any;\n}\n\ninterface SlashMenuProps {\n onClose: () => void;\n onAction: (actionId: string, payload?: any) => void;\n position: { x: number; y: number };\n canUseAi: boolean;\n mode?: 'default' | 'textbox' | 'text-selection';\n context?: {\n fontFamily?: string;\n fontSize?: number;\n isBold?: boolean;\n isItalic?: boolean;\n isUnderline?: boolean;\n isBulleted?: boolean;\n isNumbered?: boolean;\n textAlign?: 'left' | 'center' | 'right' | 'justify';\n color?: string;\n highlightColor?: string;\n };\n aiResult?: string | null;\n isAiLoading?: boolean;\n onAiResponseAction?: (action: 'replace' | 'addBelow' | 'discard' | 'regenerate') => void;\n}\n\nconst FONTS = [\n 'Inter', 'Arial', 'Lato', 'Open Sans', 'Poppins', 'Roboto', 'Georgia', 'Times New Roman'\n];\n\nconst FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 64, 72, 96];\n\nexport const SlashMenu: React.FC<SlashMenuProps> = ({ onClose, onAction, position, canUseAi, mode = 'default', context, aiResult, isAiLoading, onAiResponseAction }) => {\n const [search, setSearch] = useState('');\n const [selectedIndex, setSelectedIndex] = useState(0);\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n const [showFontDropdown, setShowFontDropdown] = useState(false);\n const [showSizeDropdown, setShowSizeDropdown] = useState(false);\n\n const [showBulletMenu, setShowBulletMenu] = useState(false);\n const [showNumberingMenu, setShowNumberingMenu] = useState(false);\n const [showAiMenu, setShowAiMenu] = useState(false);\n\n // Default vertical menu items\n const defaultItems = useMemo(() => [\n { id: 'generate-image', label: 'AI Generate Image', icon: Sparkles, category: 'AI', description: 'Create an image with AI prompt', action: () => onAction('generate-image') },\n { id: 'generate-infographic', label: 'AI Generate Infographic', icon: PieChart, category: 'AI', description: 'Create an infographic with AI prompt', action: () => onAction('generate-infographic') },\n { id: 'text', label: 'Text Box', icon: Type, category: 'Basic', description: 'Insert a new text element', action: () => onAction('add-text') },\n { id: 'image', label: 'Image', icon: ImageIcon, category: 'Basic', description: 'Upload and insert an image', action: () => onAction('add-image') },\n { id: 'new-slide', label: 'New Slide', icon: PlusCircle, category: 'Canvas', description: 'Add a fresh slide to deck', action: () => onAction('new-slide') },\n { id: 'rect', label: 'Rectangle', icon: Square, category: 'Shapes', action: () => onAction('add-shape', 'rect') },\n { id: 'circle', label: 'Circle', icon: Circle, category: 'Shapes', action: () => onAction('add-shape', 'circle') },\n { id: 'triangle', label: 'Triangle', icon: Triangle, category: 'Shapes', action: () => onAction('add-shape', 'triangle') },\n { id: 'star5', label: 'Star', icon: Star, category: 'Shapes', action: () => onAction('add-shape', 'star5') },\n { id: 'arrowRight', label: 'Arrow', icon: ArrowRight, category: 'Shapes', action: () => onAction('add-shape', 'arrowRight') },\n ], [onAction]);\n\n const filteredItems = useMemo(() => {\n return defaultItems.filter(item =>\n item.label.toLowerCase().includes(search.toLowerCase()) ||\n item.category.toLowerCase().includes(search.toLowerCase())\n );\n }, [defaultItems, search]);\n\n useEffect(() => {\n setSelectedIndex(0);\n }, [search]);\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (mode === 'default') {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setSelectedIndex(prev => (prev + 1) % filteredItems.length);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setSelectedIndex(prev => (prev - 1 + filteredItems.length) % filteredItems.length);\n } else if (e.key === 'Enter') {\n e.preventDefault();\n if (filteredItems[selectedIndex]) {\n filteredItems[selectedIndex].action();\n }\n }\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n onClose();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [filteredItems, selectedIndex, onClose, mode]);\n\n // Ensure selected item is visible in scroll container (only for default mode)\n useEffect(() => {\n if (mode === 'default' && scrollContainerRef.current) {\n const selectedElement = scrollContainerRef.current.children[selectedIndex] as HTMLElement;\n if (selectedElement) {\n selectedElement.scrollIntoView({ block: 'nearest' });\n }\n }\n }, [selectedIndex, mode]);\n\n if (mode === 'default' && filteredItems.length === 0 && search === '') return null;\n\n // Redesign for horizontal toolbar (PowerPoint style)\n if (mode === 'textbox' || mode === 'text-selection') {\n const activeFont = context?.fontFamily || 'Arial';\n const activeSize = context?.fontSize || 24;\n\n // Dynamic positioning ref\n const menuRef = useRef<HTMLDivElement>(null);\n const [adjustedPosition, setAdjustedPosition] = useState<{ x: number, y: number } | null>(null);\n\n React.useLayoutEffect(() => {\n if (menuRef.current) {\n const rect = menuRef.current.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n let x = position.x;\n let y = position.y;\n\n // Check horizontal overflow\n if (x + rect.width > viewportWidth - 100) {\n x = viewportWidth - rect.width - 100;\n }\n x = Math.max(10, x); // Keep at least 10px from left\n\n // Check vertical overflow\n if (y + rect.height > viewportHeight - 20) {\n y = viewportHeight - rect.height - 20; // Flip up or push up\n }\n\n setAdjustedPosition({ x, y });\n }\n }, [position.x, position.y]); // Re-run when target position changes\n\n // Use adjusted position if available, otherwise hide initially (opacity 0) to prevent flash\n const stylePosition = adjustedPosition || { x: position.x, y: position.y };\n const opacity = adjustedPosition ? 1 : 0;\n\n // Determine if dropdown should open upwards\n const openUpwards = stylePosition.y > window.innerHeight / 2;\n\n return (\n <div\n ref={menuRef}\n className=\"fixed z-[9999] bg-white rounded-xl shadow-[0_20px_50px_rgba(0,0,0,0.15)] border border-slate-200 p-2.5 flex flex-col gap-2.5 animate-in fade-in zoom-in-95 duration-200\"\n style={{\n left: `${stylePosition.x}px`,\n top: `${stylePosition.y}px`,\n width: 'auto',\n minWidth: '440px',\n maxWidth: '90vw',\n opacity: opacity\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Row 1: Font Selectors and Alignment */}\n <div className=\"flex items-center gap-1.5 h-9\">\n <div className=\"flex items-center bg-slate-50 border border-slate-200 rounded-lg h-full flex-1 shadow-sm\">\n <div className=\"relative flex-1\">\n <button\n onClick={() => { setShowFontDropdown(!showFontDropdown); setShowSizeDropdown(false); }}\n className=\"w-full flex items-center justify-between px-3 h-full text-xs font-bold text-slate-800 hover:bg-white transition-colors border-r border-slate-100 rounded-l-lg\"\n >\n <span className=\"truncate\">{activeFont}</span>\n <ChevronDown size={14} className=\"text-slate-400\" />\n </button>\n {showFontDropdown && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-2xl z-50 py-1 min-w-[180px] max-h-[250px] overflow-y-auto animate-in fade-in slide-in-from-top-2\">\n {FONTS.map(font => (\n <button\n key={font}\n onClick={() => { onAction('format', { fontFamily: font }); setShowFontDropdown(false); }}\n className={cn(\n \"w-full text-left px-4 py-2 text-xs hover:bg-blue-50 transition-colors\",\n activeFont === font ? \"text-blue-600 font-bold bg-blue-100/50\" : \"text-slate-700\"\n )}\n style={{ fontFamily: font }}\n >\n {font}\n </button>\n ))}\n </div>\n )}\n </div>\n\n <div className=\"relative w-16\">\n <button\n onClick={() => { setShowSizeDropdown(!showSizeDropdown); setShowFontDropdown(false); }}\n className=\"w-full flex items-center justify-between px-2 h-full text-xs font-black text-slate-900 hover:bg-white transition-colors rounded-r-lg\"\n >\n <span>{activeSize}</span>\n <ChevronDown size={14} className=\"text-slate-400\" />\n </button>\n {showSizeDropdown && (\n <div className=\"absolute top-full right-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-2xl z-50 py-1 min-w-[80px] max-h-[250px] overflow-y-auto animate-in fade-in slide-in-from-top-2\">\n {FONT_SIZES.map(size => (\n <button\n key={size}\n onClick={() => { onAction('format', { fontSize: size }); setShowSizeDropdown(false); }}\n className={cn(\n \"w-full text-center px-4 py-2 text-xs hover:bg-blue-50 transition-colors\",\n activeSize === size ? \"text-blue-600 font-bold bg-blue-100/50\" : \"text-slate-700\"\n )}\n >\n {size}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n <div className=\"flex items-center gap-1 px-1 bg-slate-50 border border-slate-200 rounded-lg h-full shadow-sm\">\n <button onClick={() => onAction('format', { fontSize: activeSize + 2 })} className=\"p-1 hover:bg-white hover:text-blue-600 rounded-md text-slate-500 transition-all active:scale-95 flex items-center justify-center\" title=\"Increase font size\">\n <span className=\"text-[13px] font-black leading-none translate-y-[1px]\">A</span>\n <ChevronUp size={10} strokeWidth={4} className=\"ml-0.5\" />\n </button>\n <button onClick={() => onAction('format', { fontSize: Math.max(1, activeSize - 2) })} className=\"p-1 hover:bg-white hover:text-blue-600 rounded-md text-slate-500 transition-all active:scale-95 flex items-center justify-center\" title=\"Decrease font size\">\n <span className=\"text-[11px] font-black leading-none translate-y-[1px]\">A</span>\n <ChevronDown size={10} strokeWidth={4} className=\"ml-0.5\" />\n </button>\n </div>\n\n\n </div>\n\n {/* Row 2: Tool Icons */}\n <div className=\"flex items-center gap-0.5 border-t border-slate-100 pt-2.5 flex-nowrap\">\n <button\n onClick={() => onAction('format', { isBold: !context?.isBold })}\n className={cn(\"p-1 rounded-[3px] transition-all\", context?.isBold ? \"text-blue-600 bg-blue-50 shadow-sm\" : \"text-slate-200 hover:bg-slate-50 hover:text-slate-500\")}\n title=\"Bold\"\n >\n <Bold size={14} strokeWidth={2.5} />\n </button>\n <button\n onClick={() => onAction('format', { isItalic: !context?.isItalic })}\n className={cn(\"p-1 rounded-[3px] transition-all\", context?.isItalic ? \"text-blue-600 bg-blue-50 shadow-sm\" : \"text-slate-200 hover:bg-slate-50 hover:text-slate-500\")}\n title=\"Italic\"\n >\n <Italic size={14} strokeWidth={2.5} />\n </button>\n <button\n onClick={() => onAction('format', { isUnderline: !context?.isUnderline })}\n className={cn(\"p-1 rounded-[3px] transition-all\", context?.isUnderline ? \"text-blue-600 bg-blue-50 shadow-sm\" : \"text-slate-200 hover:bg-slate-50 hover:text-slate-500\")}\n title=\"Underline\"\n >\n <Underline size={14} strokeWidth={2.5} />\n </button>\n\n <div className=\"w-[1px] h-4 bg-slate-100 mx-1.5\" />\n\n {/* Ask AI - Dropdown */}\n <div className=\"relative\">\n <button\n onClick={() => setShowAiMenu(!showAiMenu)}\n className={cn(\n \"flex items-center gap-1 px-1.5 py-0.5 rounded-[3px] transition-all text-xs font-bold whitespace-nowrap border border-transparent\",\n showAiMenu\n ? \"bg-purple-50 text-purple-600 border-purple-100\"\n : \"text-slate-500 hover:bg-purple-50 hover:text-purple-600\"\n )}\n >\n <Sparkles size={12} className={showAiMenu ? \"fill-purple-300\" : \"\"} />\n <span>Ask AI</span>\n <ChevronDown size={10} className=\"opacity-50\" />\n </button>\n\n {showAiMenu && (\n <div className={cn(\n \"absolute left-0 w-80 bg-white border border-slate-200 rounded-xl shadow-2xl z-[1000] animate-in fade-in zoom-in-95 duration-200 overflow-hidden text-left flex flex-col max-h-[300px]\",\n openUpwards ? \"bottom-full mb-2 origin-bottom-left\" : \"top-full mt-2 origin-top-left\"\n )}>\n <div className=\"px-3 py-2.5 bg-purple-50/50 border-b border-purple-100 flex items-center justify-between\">\n <span className=\"text-xs font-bold text-purple-700 uppercase tracking-wider flex items-center gap-2\">\n <Sparkles size={12} />\n Ask AI\n </span>\n </div>\n\n {isAiLoading ? (\n <div className=\"p-8 flex flex-col items-center justify-center gap-3 text-slate-400\">\n <RefreshCw size={24} className=\"animate-spin text-purple-500\" />\n <span className=\"text-xs font-medium\">AI is thinking...</span>\n </div>\n ) : aiResult ? (\n <div className=\"flex flex-col overflow-y-auto max-h-[200px]\">\n <div className=\"p-4 bg-slate-50/50 text-sm text-slate-700 leading-relaxed border-b border-slate-100\">\n {aiResult}\n </div>\n <div className=\"p-1.5 flex flex-col gap-0.5\">\n <button\n onClick={() => { onAiResponseAction?.('replace'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-1 py-1 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <Check size={14} className=\"text-slate-400\" />\n <span>Replace selection</span>\n </button>\n <button\n onClick={() => { onAiResponseAction?.('addBelow'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <ArrowRightFromLine size={14} className=\"text-slate-400 rotate-90\" />\n <span>Insert below</span>\n </button>\n <button\n onClick={() => { onAiResponseAction?.('regenerate'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-blue-600 hover:bg-blue-50 rounded-lg transition-colors text-left\"\n >\n <RefreshCw size={14} />\n <span>Try again</span>\n </button>\n <div className=\"h-[1px] bg-slate-100 my-1\" />\n <button\n onClick={() => { onAiResponseAction?.('discard'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-red-600 hover:bg-red-50 rounded-lg transition-colors text-left\"\n >\n <Trash2 size={14} />\n <span>Discard</span>\n </button>\n </div>\n </div>\n ) : (\n <div className=\"p-1.5 flex flex-col gap-0.5 overflow-y-auto max-h-[200px]\">\n <div className=\"px-2 py-1 text-[10px] font-bold text-slate-400 uppercase tracking-widest mt-1\">Edit Selection</div>\n <button\n onClick={() => { onAction('ai-text-edit', 'rewrite'); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <RefreshCw size={14} className=\"text-blue-500\" />\n <span>Improve writing</span>\n </button>\n <button\n onClick={() => { onAction('ai-text-edit', 'grammar'); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <SpellCheck size={14} className=\"text-green-500\" />\n <span>Fix grammar</span>\n </button>\n <button\n onClick={() => { onAction('ai-text-edit', 'shorten'); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <ALargeSmall size={14} className=\"text-orange-500\" />\n <span>Make shorter</span>\n </button>\n <button\n onClick={() => { onAction('ai-text-edit', 'lengthen'); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <ArrowRightFromLine size={14} className=\"text-purple-500\" />\n <span>Make longer</span>\n </button>\n\n <div className=\"h-[1px] bg-slate-100 my-1\" />\n\n <div className=\"px-2 py-1 text-[10px] font-bold text-slate-400 uppercase tracking-widest\">Generate</div>\n <button\n onClick={() => { onAction('generate-image'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <ImageIcon size={14} className=\"text-pink-500\" />\n <span>Generate Image</span>\n </button>\n <button\n onClick={() => { onAction('generate-infographic'); setShowAiMenu(false); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <PieChart size={14} className=\"text-indigo-500\" />\n <span>Generate Infographic</span>\n </button>\n\n <div className=\"h-[1px] bg-slate-100 my-1\" />\n\n <div className=\"px-2 py-1 text-[10px] font-bold text-slate-400 uppercase tracking-widest\">More</div>\n <button\n onClick={() => { onAction('ai-text-edit', 'continue'); }}\n className=\"flex items-center gap-2 px-2 py-2 text-sm text-slate-700 hover:bg-slate-50 rounded-lg transition-colors text-left\"\n >\n <MoveDown size={14} className=\"text-teal-500\" />\n <span>Continue writing</span>\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n <div className=\"w-[1px] h-4 bg-slate-100 mx-1.5\" />\n\n {/* Bullet List Split Button */}\n <div className=\"relative flex items-center rounded-md transition-all\">\n <button\n onClick={() => onAction('format', { isBulleted: !context?.isBulleted, isNumbered: false, listType: !context?.isBulleted ? 'bullet-disc' : 'none' })}\n className={cn(\"p-1 rounded-l-[3px] transition-all\", context?.isBulleted ? \"text-blue-600 bg-blue-50\" : \"text-slate-500 hover:bg-slate-50\")} title=\"Bullets\"\n >\n <List size={14} strokeWidth={2.5} />\n </button>\n <button\n onClick={() => setShowBulletMenu(!showBulletMenu)}\n className={cn(\"p-0.5 rounded-r-md border-l border-transparent hover:border-slate-200 transition-all\", showBulletMenu ? \"bg-slate-100\" : \"hover:bg-slate-50\")}\n >\n <ChevronDown size={10} className=\"text-slate-400\" />\n </button>\n {showBulletMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl p-2 z-[100] animate-in fade-in zoom-in-95 duration-150 w-64 grid grid-cols-4 gap-2\">\n <button onClick={() => { onAction('format', { isBulleted: false, listType: 'none' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1\">\n <span className=\"text-[10px] text-slate-500\">None</span>\n </button>\n <button onClick={() => { onAction('format', { isBulleted: true, isNumbered: false, listType: 'bullet-disc' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n <button onClick={() => { onAction('format', { isBulleted: true, isNumbered: false, listType: 'bullet-circle' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 rounded-full border border-black bg-transparent\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n <button onClick={() => { onAction('format', { isBulleted: true, isNumbered: false, listType: 'bullet-square' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><div className=\"w-1 h-1 bg-black\"></div><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n <button onClick={() => { onAction('format', { isBulleted: true, isNumbered: false, listType: 'bullet-check' }); setShowBulletMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">✓</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">✓</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n </div>\n )}\n </div>\n\n {/* Numbered List Split Button */}\n <div className=\"relative text-black flex items-center rounded-md transition-all\">\n <button\n onClick={() => onAction('format', { isNumbered: !context?.isNumbered, isBulleted: false, listType: !context?.isNumbered ? 'number-decimal' : 'none' })}\n className={cn(\"p-1 rounded-l-[3px] transition-all\", context?.isNumbered ? \"text-blue-600 bg-blue-50\" : \"text-slate-500 hover:bg-slate-50\")} title=\"Numbering\"\n >\n <ListOrdered size={14} strokeWidth={2.5} />\n </button>\n <button\n onClick={() => setShowNumberingMenu(!showNumberingMenu)}\n className={cn(\"p-0.5 rounded-r-md border-l border-transparent hover:border-slate-200 transition-all\", showNumberingMenu ? \"bg-slate-100\" : \"hover:bg-slate-50\")}\n >\n <ChevronDown size={10} className=\"text-slate-400\" />\n </button>\n {showNumberingMenu && (\n <div className=\"absolute text-black top-full left-0 mt-1 bg-white border border-slate-200 rounded-lg shadow-xl p-2 z-[100] animate-in fade-in zoom-in-95 duration-150 w-64 grid grid-cols-4 gap-2\">\n <button onClick={() => { onAction('format', { isNumbered: false, listType: 'none' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1\">\n <span className=\"text-[10px] text-slate-500\">None</span>\n </button>\n <button onClick={() => { onAction('format', { isNumbered: true, isBulleted: false, listType: 'number-decimal' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">1.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">2.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n <button onClick={() => { onAction('format', { isNumbered: true, isBulleted: false, listType: 'number-decimal-paren' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">1)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">2)</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n <button onClick={() => { onAction('format', { isNumbered: true, isBulleted: false, listType: 'number-roman-lower' }); setShowNumberingMenu(false); }} className=\"col-span-1 aspect-square flex flex-col items-center justify-center hover:bg-slate-50 border border-slate-200 rounded p-1 gap-1\"><div className=\"flex flex-col gap-1 items-start w-full px-1\"><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">i.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div><div className=\"flex items-center gap-1\"><span className=\"text-[6px]\">ii.</span><div className=\"w-6 h-[1px] bg-slate-300\"></div></div></div></button>\n </div>\n )}\n </div>\n\n <div className=\"w-[1px] h-4 bg-slate-100 mx-1.5\" />\n\n <div className=\"relative flex items-center\">\n <button\n className=\"w-7 h-[22px] flex flex-col items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all relative\"\n title=\"Font Color\"\n >\n <span className=\"text-[13px] font-black text-slate-800 leading-none\">A</span>\n <div className=\"w-4 h-[2.5px] rounded-sm mt-0.5\" style={{ backgroundColor: context?.color || '#000000' }} />\n <input\n type=\"color\"\n className=\"absolute inset-0 opacity-0 cursor-pointer w-full h-full\"\n value={context?.color || '#000000'}\n onChange={(e) => onAction('format', { color: e.target.value })}\n />\n </button>\n <ChevronDown size={8} className=\"text-slate-400 -ml-0.5\" />\n </div>\n\n <div className=\"relative flex items-center\">\n <button\n className=\"w-7 h-[22px] flex flex-col items-center justify-center rounded-[3px] hover:bg-slate-100 transition-all relative\"\n title=\"Highlight Color\"\n >\n <Highlighter size={14} strokeWidth={2.5} className={context?.highlightColor ? \"text-slate-900\" : \"text-slate-500\"} />\n <div className=\"w-4 h-[2.5px] rounded-sm mt-0.5\" style={{ backgroundColor: context?.highlightColor || 'transparent' }} />\n <input\n type=\"color\"\n className=\"absolute inset-0 opacity-0 cursor-pointer w-full h-full\"\n value={context?.highlightColor || '#ffff00'}\n onChange={(e) => onAction('format', { highlightColor: e.target.value })}\n />\n </button>\n <ChevronDown size={8} className=\"text-slate-400 -ml-0.5\" />\n </div>\n\n <button\n onClick={() => onAction('format', { isBold: false, isItalic: false, isUnderline: false, highlightColor: '', color: '#000000' })}\n className=\"p-1 rounded-[3px] text-slate-400 hover:bg-slate-50 hover:text-slate-600 transition-all\"\n title=\"Clear Formatting\"\n >\n <Eraser size={14} strokeWidth={2.5} />\n </button>\n\n {/* Alignment 2x2 Grid */}\n <div className=\"gap-0.5 ml-auto\">\n <button onClick={() => onAction('format', { textAlign: 'left' })} className={cn(\"p-1 rounded-[3px] transition-all\", context?.textAlign === 'left' ? \"bg-blue-100 text-blue-600\" : \"hover:bg-slate-100 text-slate-500\")}><AlignLeft size={12} strokeWidth={2.5} /></button>\n <button onClick={() => onAction('format', { textAlign: 'center' })} className={cn(\"p-1 rounded-[3px] transition-all\", context?.textAlign === 'center' ? \"bg-blue-100 text-blue-600\" : \"hover:bg-slate-100 text-slate-500\")}><AlignCenter size={12} strokeWidth={2.5} /></button>\n <button onClick={() => onAction('format', { textAlign: 'right' })} className={cn(\"p-1 rounded-[3px] transition-all\", context?.textAlign === 'right' ? \"bg-blue-100 text-blue-600\" : \"hover:bg-slate-100 text-slate-500\")}><AlignRight size={12} strokeWidth={2.5} /></button>\n <button onClick={() => onAction('format', { textAlign: 'justify' })} className={cn(\"p-1 rounded-[3px] transition-all\", context?.textAlign === 'justify' ? \"bg-blue-100 text-blue-600\" : \"hover:bg-slate-100 text-slate-500\")}><AlignJustify size={12} strokeWidth={2.5} /></button>\n </div>\n\n {/* <div className=\"ml-auto flex items-center gap-1\">\n <button\n onClick={onClose}\n className=\"p-1.5 hover:bg-slate-100 text-slate-400 rounded-md transition-colors\"\n >\n <ChevronRight size={18} />\n </button>\n </div> */}\n </div>\n </div>\n );\n }\n\n const safeXVertical = Math.max(10, Math.min(position.x, window.innerWidth - 300));\n const safeYVertical = Math.max(10, Math.min(position.y, window.innerHeight - 450));\n\n return (\n <div\n className=\"fixed z-[9999] w-72 bg-white rounded-xl shadow-2xl border border-slate-200 overflow-hidden flex flex-col animate-in fade-in zoom-in duration-200\"\n style={{\n left: `${safeXVertical}px`,\n top: `${safeYVertical}px`,\n maxHeight: '400px'\n }}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"p-3 border-b border-slate-100 flex items-center gap-2 bg-slate-50/50\">\n <Search size={14} className=\"text-slate-400\" />\n <input\n autoFocus\n type=\"text\"\n placeholder=\"Type a command...\"\n className=\"bg-transparent border-none outline-none text-sm w-full font-medium text-slate-700 placeholder:text-slate-400\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n </div>\n\n <div\n ref={scrollContainerRef}\n className=\"overflow-y-auto py-2 px-1 custom-scrollbar\"\n >\n {filteredItems.length > 0 ? (\n filteredItems.map((item, index) => {\n const isSelected = index === selectedIndex;\n const showsCategory = index === 0 || filteredItems[index - 1].category !== item.category;\n\n return (\n <React.Fragment key={item.id}>\n {showsCategory && (\n <div className=\"px-3 py-1.5 text-[10px] uppercase tracking-wider font-bold text-slate-400\">\n {item.category}\n </div>\n )}\n <button\n className={cn(\n \"w-full flex items-center gap-3 px-3 py-2 text-left transition-all duration-150 rounded-lg group\",\n isSelected ? \"bg-slate-100\" : \"hover:bg-slate-50\"\n )}\n onClick={() => item.action()}\n onMouseEnter={() => setSelectedIndex(index)}\n >\n <div className={cn(\n \"p-1.5 rounded-md transition-colors flex items-center justify-center relative\",\n isSelected ? \"bg-white shadow-sm text-blue-600\" : \"bg-slate-100 text-slate-500 group-hover:text-slate-700\"\n )}>\n <item.icon size={16} />\n </div>\n <div className=\"flex flex-col min-w-0\">\n <span className={cn(\n \"text-sm font-semibold truncate\",\n isSelected ? \"text-slate-900\" : \"text-slate-700\"\n )}>\n {item.label}\n </span>\n {item.description && (\n <span className=\"text-[11px] text-slate-400 truncate leading-tight\">\n {item.description}\n </span>\n )}\n </div>\n {isSelected && (\n <div className=\"ml-auto text-[10px] font-mono font-bold text-slate-400 flex items-center gap-1 border border-slate-200 rounded px-1 bg-white\">\n <span>↵</span>\n </div>\n )}\n </button>\n </React.Fragment>\n );\n })\n ) : (\n <div className=\"px-3 py-8 text-center flex flex-col items-center gap-2\">\n <div className=\"p-3 bg-slate-50 rounded-full\">\n <Search size={20} className=\"text-slate-300\" />\n </div>\n <span className=\"text-sm text-slate-400 font-medium whitespace-nowrap\">No commands found for \"{search}\"</span>\n </div>\n )}\n </div>\n\n <div className=\"px-3 py-2 border-t border-slate-100 bg-slate-50/50 flex items-center justify-between\">\n <div className=\"flex items-center gap-1 text-[10px] font-medium text-slate-400\">\n <span className=\"border border-slate-200 rounded px-1 bg-white\">↑↓</span>\n <span>to navigate</span>\n </div>\n <div className=\"flex items-center gap-1 text-[10px] font-medium text-slate-400\">\n <span className=\"border border-slate-200 rounded px-1 bg-white\">Esc</span>\n <span>to close</span>\n </div>\n </div>\n </div>\n );\n};\n","import React, { useEffect } from 'react';\nimport { X, AlertCircle, CheckCircle, Info } from 'lucide-react';\nimport { cn } from '../lib/utils';\n\nexport type SnackbarType = 'error' | 'success' | 'info';\n\ninterface SnackbarProps {\n message: string;\n type?: SnackbarType;\n isOpen: boolean;\n onClose: () => void;\n autoHideDuration?: number;\n}\n\nexport const Snackbar: React.FC<SnackbarProps> = ({\n message,\n type = 'info',\n isOpen,\n onClose,\n autoHideDuration = 4000\n}) => {\n useEffect(() => {\n if (isOpen && autoHideDuration > 0) {\n const timer = setTimeout(() => {\n onClose();\n }, autoHideDuration);\n return () => clearTimeout(timer);\n }\n }, [isOpen, autoHideDuration, onClose]);\n\n if (!isOpen) return null;\n\n const icons = {\n error: <AlertCircle size={20} className=\"text-white\" />,\n success: <CheckCircle size={20} className=\"text-white\" />,\n info: <Info size={20} className=\"text-white\" />\n };\n\n const bgColors = {\n error: 'bg-red-500',\n success: 'bg-emerald-500',\n info: 'bg-slate-800'\n };\n\n return (\n <div className={cn(\n \"fixed bottom-6 right-6 z-[10000] flex items-center gap-3 px-4 py-2 rounded-md shadow-lg animate-in fade-in slide-in-from-bottom-2 duration-300 min-w-[280px] max-w-[400px]\",\n bgColors[type]\n )}>\n {icons[type]}\n <span className=\"text-white text-sm font-medium flex-1\">{message}</span>\n <button\n onClick={onClose}\n className=\"p-1 hover:bg-white/20 rounded-full transition-colors ml-1\"\n >\n <X size={14} className=\"text-white\" />\n </button>\n </div>\n );\n};\n","import pptxgen from 'pptxgenjs';\nimport type { Presentation } from './types';\n\n/**\n * A standalone service to convert a Presentation object into a .pptx Blob.\n * Use this for background processing, S3 uploads, or other non-UI tasks.\n * \n * This replicates the logic from PptxExporter but returns a Blob instead of\n * triggering a browser download.\n */\nexport class PptxBlobExporter {\n /**\n * Converts a Presentation object into a .pptx Blob.\n * @param presentation The presentation data to export.\n * @returns A Promise that resolves to a Blob containing the .pptx file.\n */\n async exportToBlob(presentation: Presentation): Promise<Blob> {\n const pptx = new pptxgen();\n\n const emuWidth = presentation.layout?.width || 12192000;\n const emuHeight = presentation.layout?.height || 6858000;\n const canvasWidth = 1200;\n const canvasHeight = 675;\n\n const getInchesX = (px: number) => (px / canvasWidth) * (emuWidth / 914400);\n const getInchesY = (px: number) => (px / canvasHeight) * (emuHeight / 914400);\n\n presentation.slides.forEach(slide => {\n const pptxSlide = pptx.addSlide();\n\n // Sort by zIndex for export layering\n const sortedElements = [...slide.elements].sort((a, b) => a.zIndex - b.zIndex);\n\n sortedElements.forEach(el => {\n const transparency = el.opacity !== undefined ? (1 - el.opacity) * 100 : 0;\n const common = {\n x: getInchesX(el.x),\n y: getInchesY(el.y),\n w: getInchesX(el.width),\n h: getInchesY(el.height),\n };\n\n if (el.type === 'text') {\n pptxSlide.addText(el.content, {\n ...common,\n fontSize: (el.fontSize || 18) / 2, // Halve for export to match canvas scale\n color: el.color?.replace('#', '') || '000000',\n fontFace: el.fontFamily || 'Arial'\n });\n } else if (el.type === 'image') {\n pptxSlide.addImage({\n ...common,\n path: el.src,\n transparency: transparency\n });\n } else if (el.type === 'shape') {\n // Map basic shapes to pptxgen types\n const shapeType = el.shapeType === 'ellipse' ? pptx.ShapeType.ellipse : pptx.ShapeType.rect;\n pptxSlide.addShape(shapeType, {\n ...common,\n fill: {\n color: el.fill?.replace('#', '') || 'CCCCCC',\n transparency: transparency > 0 ? Math.min(transparency + 10, 100) : 0\n }\n });\n }\n });\n });\n\n // Generate the blob using 'blob' output type\n const output = await pptx.write({ outputType: 'blob' });\n return output as Blob;\n }\n}\n"],"mappings":"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","names":["index_exports","__export","PptEditor","PptxBlobExporter","PptxExporter","PptxParser","__toCommonJS","styleInject","css","insertAt","head","style","styleInject","import_react","import_react","import_lucide_react","import_clsx","import_tailwind_merge","cn","inputs","import_jsx_runtime","FONTS","FONT_SIZES","SHAPE_CATEGORIES","ShapeIcon","type","className","ShapesDropdown","onAddShape","uiScale","isOpen","setIsOpen","React","cat","Toolbar","onAddText","onAddImage","onAddSlide","onExport","onFormatText","onDeleteElement","onApplyLayout","onPlay","selectedElement","onNewPresentation","onLoadPresentation","appBgColor","source","onGenerateImageClick","onGenerateInfographicClick","onUploadImageClick","onRefineAction","refineResponse","isAiLoading","fileInputRef","activeTab","setActiveTab","showLayouts","setShowLayouts","showAiMenu","setShowAiMenu","showFileMenu","setShowFileMenu","showUploadModal","setShowUploadModal","uploadType","setUploadType","uploadUrl","setUploadUrl","showChangeCaseMenu","setShowChangeCaseMenu","showCharSpacingMenu","setShowCharSpacingMenu","showBulletMenu","setShowBulletMenu","showNumberingMenu","setShowNumberingMenu","applyChangeCase","caseType","isText","currentText","newText","word","char","isShape","isImage","PPT_RED","cn","e","f","s","_a","ImageIcon","file","import_lucide_react","import_core","import_sortable","import_utilities","import_jsx_runtime","SHAPE_PATHS","SortableSlide","slide","index","isActive","onSelect","onDelete","onDuplicate","showDelete","uiScale","appBgColor","attributes","listeners","setNodeRef","transform","transition","isDragging","style","cn","__spreadProps","__spreadValues","e","a","b","el","_a","pathData","Sidebar","slides","currentSlideIndex","onSelectSlide","onDeleteSlide","onDuplicateSlide","onReorderSlides","sensors","handleDragEnd","event","active","over","oldIndex","s","newIndex","import_react","fabric","import_lucide_react","import_jsx_runtime","SHAPE_PATHS","getBulletContent","listType","isBulleted","isNumbered","index","n","toRoman","toAlpha","num","lookup","roman","i","CustomTextbox","method","ctx","line","left","top","lineIndex","bulletText","fontSize","xOffset","bulletSize","EditorCanvas","slide","onElementUpdate","onSelect","uiScale","onSlashCommand","selectedElementId","onAiGenerateClick","onAiGenerateInfographicClick","onUploadImageClick","onDeleteElement","canvasRef","fabricCanvas","isInternalUpdate","onElementUpdateRef","onSelectRef","containerRef","dynamicScale","setDynamicScale","canvasReady","setCanvasReady","mousePos","observer","entries","entry","cw","ch","scaleX","scaleY","scale","canvas","clamp","obj","bound","e","handleUpdate","_a","elementId","__spreadValues","getContext","triggerSlashMenu","isTextSelection","rect","x","y","hasMethod","o","m","isTextbox","coords","charIndex","canvasCoords","vpt","viewportCoords","mode","finalX","finalY","err","syncSelection","_b","handleGlobalKeyDown","activeObj","step","moved","listener","existingObjs","slideIds","id","sorted","a","b","el","updates","newObj","commonProps","__spreadProps","shapeFill","pathData","p","img","selectedElement","ImageIcon","import_pptxgenjs","PptxExporter","presentation","_a","_b","pptx","pptxgen","emuWidth","emuHeight","canvasWidth","canvasHeight","getInchesX","px","getInchesY","slide","pptxSlide","a","b","el","transparency","common","__spreadProps","__spreadValues","shapeType","import_jszip","PptxParser","input","_a","_b","data","response","status","statusText","detail","errorJson","e","zip","JSZip","presentationXml","presentationDoc","sldSz","sldIdList","slides","i","slideNum","slidePath","slideXml","slide","el","name","parent","elements","emu","srgbClr","hex","alphaNode","opacity","schemeClr","relId","slideIndex","relsXml","relsDoc","relationship","r","target","mediaPath","xml","doc","zIndex","bg","blip","mediaFile","spTree","children","child","localName","txBody","nvSpPr","nvPr","ph","phType","isBodyPlaceholder","xfrm","off","ext","paragraphs","content","fontSize","color","isBulleted","isNumbered","p","pPr","buNone","paragraphContent","runs","t","rPr","sz","style","bulletRegex","prstGeom","prst","spPr","mapping","import_react","import_lucide_react","import_jsx_runtime","PresenterMode","presentation","initialSlideIndex","onClose","currentIndex","setCurrentIndex","currentSlide","goToPrevious","goToNext","handleKeyDown","e","scale","setScale","updateScale","availableWidth","availableHeight","slideWidth","slideHeight","scaleX","scaleY","newScale","EditorCanvas","import_generative_ai","import_lucide_react","import_jsx_runtime","RefineMenu","result","isLoading","onAction","onClose","position","import_react","import_lucide_react","import_jsx_runtime","FONTS","FONT_SIZES","SlashMenu","onClose","onAction","position","canUseAi","mode","context","aiResult","isAiLoading","onAiResponseAction","search","setSearch","selectedIndex","setSelectedIndex","scrollContainerRef","showFontDropdown","setShowFontDropdown","showSizeDropdown","setShowSizeDropdown","showBulletMenu","setShowBulletMenu","showNumberingMenu","setShowNumberingMenu","showAiMenu","setShowAiMenu","defaultItems","ImageIcon","filteredItems","item","handleKeyDown","e","prev","selectedElement","activeFont","activeSize","menuRef","adjustedPosition","setAdjustedPosition","React","rect","viewportWidth","viewportHeight","x","y","stylePosition","opacity","openUpwards","font","cn","size","safeXVertical","safeYVertical","index","isSelected","showsCategory","import_lucide_react","import_react","import_lucide_react","import_jsx_runtime","Snackbar","message","type","isOpen","onClose","autoHideDuration","timer","icons","cn","import_jsx_runtime","PptEditor","initialPresentation","url","appName","onChange","geminiApiKey","width","height","appBgColor","showHomeOnEmpty","initialSource","onSourceChange","proxyUrl","onGenerateImage","onGenerateInfographic","onAiRewrite","onAiGrammar","onAiShorten","onAiLengthen","onAiContinue","isTwoStepInfographicGeneration","onRefineInfographicPrompt","_a","_b","presentation","setPresentation","history","setHistory","redoStack","setRedoStack","currentSlideIndex","setCurrentSlideIndex","selectedElementId","setSelectedElementId","isPreviewMode","setIsPreviewMode","askAiResponse","setAskAiResponse","refineResponse","setRefineResponse","isLoading","setIsLoading","source","setSource","showInitialLayout","setShowInitialLayout","urlInput","setUrlInput","slashMenu","setSlashMenu","isImageGenOpen","setIsImageGenOpen","imageGenPrompt","setImageGenPrompt","isGeneratingImage","setIsGeneratingImage","pendingImage","setPendingImage","imageError","setImageError","previewLoading","setPreviewLoading","isInfographicGenOpen","setIsInfographicGenOpen","infographicGenPrompt","setInfographicGenPrompt","isGeneratingInfographic","setIsGeneratingInfographic","pendingInfographic","setPendingInfographic","infographicError","setInfographicError","isRefiningInfographic","setIsRefiningInfographic","refinedInfographicPrompt","setRefinedInfographicPrompt","showInfographicPreview","setShowInfographicPreview","snackbar","setSnackbar","showSnackbar","message","type","handleLoadPresentation","isAiLoading","setIsAiLoading","lastAiPrompt","setLastAiPrompt","uiScale","w","currentSlide","selectedElement","el","saveToHistory","state","prevHistory","undo","last","prev","redo","next","handleUpdateSlide","updates","newSlides","__spreadValues","updated","__spreadProps","h","handleElementUpdate","elementId","slide","newElements","handleFormatText","e","handleDeleteElement","handleAddText","newElement","handleAddImage","input","src","resolve","reader","id","handleAddShape","shapeType","handleAddSlide","newSlide","handleDeleteSlide","index","_","i","handleDuplicateSlide","slideToClone","handleReorderSlides","oldIndex","newIndex","removed","handleApplyLayout","layoutType","elements","timestamp","handleAiAction","action","element","model","elementContext","prompt","response","error","handleAiTextEdit","resultText","systemPrompt","userPrompt","handleAiResponseAction","originalElement","handleRefineResponseAction","handleExport","PptxExporter","handlePlay","elem","handleClosePresenter","handleFullscreenChange","handleKeyDown","activeElement","updateSource","newSource","handleNewPresentation","parser","PptxParser","trimmedInput","result","err","handleSlashAction","actionId","payload","handleUploadImageClick","handleOpenInfographic","handleGenerateImage","imageUrl","handleFinalizeImage","handleGenerateInfographic","customPrompt","promptToUse","infographicUrl","img","reject","handleFinalizeInfographic","textToRefine","refined","file","re","getProxiedUrl","PresenterMode","Toolbar","Sidebar","EditorCanvas","position","mode","context","SlashMenu","RefineMenu","cn","ImageIcon","finalPrompt","Snackbar","import_pptxgenjs","PptxBlobExporter","presentation","_a","_b","pptx","pptxgen","emuWidth","emuHeight","canvasWidth","canvasHeight","getInchesX","px","getInchesY","slide","pptxSlide","a","b","el","transparency","common","__spreadProps","__spreadValues","shapeType"]}