@mhmo91/schmancy 0.5.41 → 0.5.42

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/badge.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./avatar-TAxgKH6w.cjs");Object.defineProperty(exports,"ScBadgeV2",{enumerable:!0,get:()=>e.ScBadgeV2}),Object.defineProperty(exports,"SchmancyBadgeV2",{enumerable:!0,get:()=>e.SchmancyBadgeV2});
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./avatar-DyRhI1cs.cjs");Object.defineProperty(exports,"ScBadgeV2",{enumerable:!0,get:()=>e.ScBadgeV2}),Object.defineProperty(exports,"SchmancyBadgeV2",{enumerable:!0,get:()=>e.SchmancyBadgeV2});
2
2
  //# sourceMappingURL=badge.cjs.map
package/dist/badge.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as e, S } from "./avatar-C70RL5gA.js";
1
+ import { a as e, S } from "./avatar-B1-VVeUn.js";
2
2
  export {
3
3
  e as ScBadgeV2,
4
4
  S as SchmancyBadgeV2
@@ -1,5 +1,5 @@
1
- import { fromEvent as l, race as k, merge as A } from "rxjs";
2
- import { takeUntil as x, filter as R, tap as b, take as P, map as f, switchMap as Y, finalize as D } from "rxjs/operators";
1
+ import { fromEvent as l, race as z, merge as A } from "rxjs";
2
+ import { takeUntil as x, filter as R, tap as b, take as P, map as f, switchMap as D, finalize as Y } from "rxjs/operators";
3
3
  import "lit/directives/class-map.js";
4
4
  import "lit/directives/style-map.js";
5
5
  import { property as y, state as g, customElement as I } from "lit/decorators.js";
@@ -7,9 +7,9 @@ import "./tailwind.mixin-Di9OJku4.js";
7
7
  import { $ as M } from "./litElement.mixin-CG9mrwt1.js";
8
8
  import { css as X, html as u } from "lit";
9
9
  import { createRef as $, ref as w } from "lit/directives/ref.js";
10
- var _ = Object.defineProperty, F = Object.getOwnPropertyDescriptor, d = (t, e, n, i) => {
11
- for (var s, o = i > 1 ? void 0 : i ? F(e, n) : e, a = t.length - 1; a >= 0; a--) (s = t[a]) && (o = (i ? s(e, n, o) : s(o)) || o);
12
- return i && o && _(e, n, o), o;
10
+ var _ = Object.defineProperty, F = Object.getOwnPropertyDescriptor, d = (t, e, s, i) => {
11
+ for (var n, o = i > 1 ? void 0 : i ? F(e, s) : e, a = t.length - 1; a >= 0; a--) (n = t[a]) && (o = (i ? n(e, s, o) : n(o)) || o);
12
+ return i && o && _(e, s, o), o;
13
13
  };
14
14
  let c = class extends M(X`
15
15
  :host {
@@ -62,22 +62,22 @@ let c = class extends M(X`
62
62
  async performTransition(t, e) {
63
63
  if (this.currentAnimation?.cancel(), !this.containerRef.value) return;
64
64
  e === "expanded" && (this.isContentVisible = !0);
65
- const n = this.createAnimations(t, e);
66
- n.container && (this.currentAnimation = n.container, await n.container.finished, e !== "expanded" && (this.isContentVisible = !1));
65
+ const s = this.createAnimations(t, e);
66
+ s.container && (this.currentAnimation = s.container, await s.container.finished, e !== "expanded" && (this.isContentVisible = !1));
67
67
  }
68
68
  createAnimations(t, e) {
69
- const n = this.containerRef.value, i = this.contentRef.value, s = this.iconRef.value, o = {};
70
- if (!n) return o;
69
+ const s = this.containerRef.value, i = this.contentRef.value, n = this.iconRef.value, o = {};
70
+ if (!s) return o;
71
71
  const a = this.ANIMATION_CONFIG, m = this.getStyleForState(t), h = this.getStyleForState(e);
72
- if (o.container = e === "expanded" ? n.animate([m, h], { duration: a.durations.expand, easing: a.easing.decelerate, fill: "forwards" }) : n.animate([m, h], { duration: e === "hidden" ? a.durations.hide : a.durations.minimize, easing: a.easing.accelerate, fill: "forwards" }), i && t === "expanded" && e === "minimized" ? i.animate([{ opacity: 1, transform: "translateY(0)" }, { opacity: 0, transform: "translateY(-8px)" }], { duration: 150, easing: a.easing.standard, fill: "forwards" }) : i && e === "expanded" && i.animate([{ opacity: 0, transform: "translateY(8px)" }, { opacity: 1, transform: "translateY(0)" }], { duration: a.durations.content, easing: a.easing.standard, fill: "forwards" }), s) {
72
+ if (o.container = e === "expanded" ? s.animate([m, h], { duration: a.durations.expand, easing: a.easing.decelerate, fill: "forwards" }) : s.animate([m, h], { duration: e === "hidden" ? a.durations.hide : a.durations.minimize, easing: a.easing.accelerate, fill: "forwards" }), i && t === "expanded" && e === "minimized" ? i.animate([{ opacity: 1, transform: "translateY(0)" }, { opacity: 0, transform: "translateY(-8px)" }], { duration: 150, easing: a.easing.standard, fill: "forwards" }) : i && e === "expanded" && i.animate([{ opacity: 0, transform: "translateY(8px)" }, { opacity: 1, transform: "translateY(0)" }], { duration: a.durations.content, easing: a.easing.standard, fill: "forwards" }), n) {
73
73
  const p = e === "expanded";
74
- (p || t === "expanded" && e === "minimized") && s.animate([{ transform: p ? "rotate(0deg)" : "rotate(180deg)" }, { transform: p ? "rotate(180deg)" : "rotate(0deg)" }], { duration: 250, easing: a.easing.emphasized, fill: "forwards" });
74
+ (p || t === "expanded" && e === "minimized") && n.animate([{ transform: p ? "rotate(0deg)" : "rotate(180deg)" }, { transform: p ? "rotate(180deg)" : "rotate(0deg)" }], { duration: 250, easing: a.easing.emphasized, fill: "forwards" });
75
75
  }
76
76
  return o;
77
77
  }
78
78
  getStyleForState(t) {
79
- const { shadows: e } = this.ANIMATION_CONFIG, n = { maxWidth: "300px", maxHeight: "auto", borderRadius: "16px" };
80
- return { hidden: { ...n, opacity: "0", pointerEvents: "none", boxShadow: "none", backdropFilter: "none" }, minimized: { ...n, opacity: "1", pointerEvents: "auto", boxShadow: this.isLowered ? e.fabLowered : e.fab, backdropFilter: "none" }, expanded: { opacity: "1", pointerEvents: "auto", width: this.getResponsiveWidth(), maxWidth: "100%", maxHeight: "80vh", boxShadow: e.expanded, borderRadius: "8px 8px 0 0", backdropFilter: "blur(12px)" } }[t];
79
+ const { shadows: e } = this.ANIMATION_CONFIG, s = { maxWidth: "300px", maxHeight: "auto", borderRadius: "16px" };
80
+ return { hidden: { ...s, opacity: "0", pointerEvents: "none", boxShadow: "none", backdropFilter: "none" }, minimized: { ...s, opacity: "1", pointerEvents: "auto", boxShadow: this.isLowered ? e.fabLowered : e.fab, backdropFilter: "none" }, expanded: { opacity: "1", pointerEvents: "auto", width: this.getResponsiveWidth(), maxWidth: "100%", maxHeight: "80vh", boxShadow: e.expanded, borderRadius: "8px 8px 0 0", backdropFilter: "blur(12px)" } }[t];
81
81
  }
82
82
  getResponsiveWidth() {
83
83
  if (typeof window > "u") return "40vw";
@@ -92,12 +92,12 @@ let c = class extends M(X`
92
92
  this.initializePosition(), this.applyInitialStyles(), this.updateContainerPosition(), this.setupDragPipeline(), this.querySelector('[slot="header"]') && !this.icon && this.label;
93
93
  }
94
94
  applyInitialStyles() {
95
- const t = this.containerRef.value, e = this.contentRef.value, n = this.iconRef.value;
95
+ const t = this.containerRef.value, e = this.contentRef.value, s = this.iconRef.value;
96
96
  if (t) {
97
97
  const i = this.getStyleForState(this.currentState);
98
98
  Object.assign(t.style, i), "webkitBackdropFilter" in t.style && (t.style.webkitBackdropFilter = i.backdropFilter);
99
99
  }
100
- e && (e.style.opacity = this.isContentVisible ? "1" : "0"), n && this.currentState === "expanded" && (n.style.transform = "rotate(180deg)");
100
+ e && (e.style.opacity = this.isContentVisible ? "1" : "0"), s && this.currentState === "expanded" && (s.style.transform = "rotate(180deg)");
101
101
  }
102
102
  toggleState() {
103
103
  const t = this.currentState === "minimized" ? "expanded" : "minimized";
@@ -107,23 +107,23 @@ let c = class extends M(X`
107
107
  this.animateToState("hidden");
108
108
  }
109
109
  closeAndAddToNav() {
110
- k(this.discover("schmancy-navigation-rail"), this.discover("schmancy-navigation-bar"), this.discover("schmancy-nav-drawer"), this.discover("app-navigation-rail"), this.discover("app-navigation-bar"), this.discover("app-nav-drawer")).pipe(P(1), b((t) => {
110
+ z(this.discover("schmancy-navigation-rail"), this.discover("schmancy-navigation-bar"), this.discover("schmancy-nav-drawer"), this.discover("app-navigation-rail"), this.discover("app-navigation-bar"), this.discover("app-nav-drawer")).pipe(P(1), b((t) => {
111
111
  if (t && typeof t.addBoatItem == "function") {
112
- const e = this.icon || (this.querySelector('[slot="header"]')?.querySelector("schmancy-icon")?.textContent?.trim() || "widgets"), n = this.label || (() => {
112
+ const e = this.icon || (this.querySelector('[slot="header"]')?.querySelector("schmancy-icon")?.textContent?.trim() || "widgets"), s = this.label || (() => {
113
113
  let o = this.querySelector('[slot="header"]')?.textContent?.trim() || "Boat";
114
114
  return o.includes(e) && (o = o.replace(e, "").trim()), o || this.id;
115
- })(), i = t.addBoatItem({ id: `boat-${this.id}`, title: n, icon: e });
115
+ })(), i = t.addBoatItem({ id: `boat-${this.id}`, title: s, icon: e });
116
116
  if (i) {
117
- const s = this.containerRef.value;
118
- s ? s.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 150, easing: "ease-out", fill: "forwards" }).finished.then(() => {
117
+ const n = this.containerRef.value;
118
+ n ? n.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 150, easing: "ease-out", fill: "forwards" }).finished.then(() => {
119
119
  this.currentState = "hidden", this.isContentVisible = !1;
120
120
  }) : (this.currentState = "hidden", this.isContentVisible = !1), l(i, "click").pipe(b(() => this.state = "expanded"), x(this.disconnecting)).subscribe();
121
121
  }
122
122
  } else this.close();
123
123
  })).subscribe();
124
124
  }
125
- calculateDragPosition(t, e, n, i, s) {
126
- const o = t - n, a = e - i, m = window.innerWidth, h = window.innerHeight, p = Math.max(0, Math.min(o, m - s.width)), v = Math.max(0, Math.min(a, h - s.height)), r = this.anchor.includes("right") ? m - (p + s.width) : p, S = this.anchor.includes("bottom") ? h - (v + s.height) : v;
125
+ calculateDragPosition(t, e, s, i, n) {
126
+ const o = t - s, a = e - i, m = window.innerWidth, h = window.innerHeight, p = Math.max(0, Math.min(o, m - n.width)), v = Math.max(0, Math.min(a, h - n.height)), r = this.anchor.includes("right") ? m - (p + n.width) : p, S = this.anchor.includes("bottom") ? h - (v + n.height) : v;
127
127
  return { x: Math.max(0, r), y: Math.max(0, S) };
128
128
  }
129
129
  savePosition() {
@@ -135,22 +135,22 @@ let c = class extends M(X`
135
135
  if (typeof window > "u") return;
136
136
  const t = this.headerRef.value, e = this.containerRef.value;
137
137
  if (!t || !e) return;
138
- let n = !1;
138
+ let s = !1;
139
139
  A(l(t, "mousedown").pipe(R((i) => i.button === 0), b((i) => {
140
140
  i.preventDefault(), i.stopPropagation();
141
- }), f((i) => ({ clientX: i.clientX, clientY: i.clientY, type: "mouse" }))), l(t, "touchstart").pipe(f((i) => ({ clientX: i.touches[0].clientX, clientY: i.touches[0].clientY, type: "touch" })))).pipe(f(({ clientX: i, clientY: s, type: o }) => {
141
+ }), f((i) => ({ clientX: i.clientX, clientY: i.clientY, type: "mouse" }))), l(t, "touchstart").pipe(f((i) => ({ clientX: i.touches[0].clientX, clientY: i.touches[0].clientY, type: "touch" })))).pipe(f(({ clientX: i, clientY: n, type: o }) => {
142
142
  const a = e.getBoundingClientRect();
143
- return n = !1, { startX: i, startY: s, offsetX: i - a.left, offsetY: s - a.top, initialRect: a, type: o };
144
- })).pipe(Y(({ startX: i, startY: s, offsetX: o, offsetY: a, initialRect: m, type: h }) => {
143
+ return s = !1, { startX: i, startY: n, offsetX: i - a.left, offsetY: n - a.top, initialRect: a, type: o };
144
+ })).pipe(D(({ startX: i, startY: n, offsetX: o, offsetY: a, initialRect: m, type: h }) => {
145
145
  const p = h === "mouse" ? l(window, "mousemove").pipe(f((r) => ({ clientX: r.clientX, clientY: r.clientY }))) : l(window, "touchmove").pipe(f((r) => ({ clientX: r.touches[0].clientX, clientY: r.touches[0].clientY }))), v = l(window, h === "mouse" ? "mouseup" : "touchend");
146
146
  return p.pipe(f(({ clientX: r, clientY: S }) => {
147
- const z = r - i, C = S - s;
148
- return Math.sqrt(z * z + C * C) > 5 && !n && (n = !0, this.isDragging = !0), n ? this.calculateDragPosition(r, S, o, a, m) : null;
147
+ const k = r - i, C = S - n;
148
+ return Math.sqrt(k * k + C * C) > 5 && !s && (s = !0, this.isDragging = !0), s ? this.calculateDragPosition(r, S, o, a, m) : null;
149
149
  }), R((r) => r !== null), b((r) => {
150
150
  r && (this.position = r, this.updateContainerPosition());
151
151
  }), x(v));
152
- }), D(() => {
153
- n ? (this.updateAnchor(), this.savePosition()) : this.toggleState(), this.isDragging = !1, n = !1;
152
+ }), Y(() => {
153
+ s ? (this.updateAnchor(), this.savePosition()) : this.toggleState(), this.isDragging = !1, s = !1;
154
154
  }), x(this.disconnecting)).subscribe();
155
155
  }
156
156
  updateContainerPosition() {
@@ -161,18 +161,18 @@ let c = class extends M(X`
161
161
  if (typeof window > "u") return;
162
162
  const t = this.containerRef.value;
163
163
  if (!t) return;
164
- const e = t.getBoundingClientRect(), n = window.innerWidth, i = window.innerHeight, s = e.left > n / 2, o = e.top > i / 2, a = `${o ? "bottom" : "top"}-${s ? "right" : "left"}`;
165
- a !== this.anchor && (this.position.x = s ? n - e.right : e.left, this.position.y = o ? i - e.bottom : e.top, this.anchor = a);
164
+ const e = t.getBoundingClientRect(), s = window.innerWidth, i = window.innerHeight, n = e.left > s / 2, o = e.top > i / 2, a = `${o ? "bottom" : "top"}-${n ? "right" : "left"}`;
165
+ a !== this.anchor && (this.position.x = n ? s - e.right : e.left, this.position.y = o ? i - e.bottom : e.top, this.anchor = a);
166
166
  }
167
167
  disconnectedCallback() {
168
168
  super.disconnectedCallback(), this.currentAnimation?.cancel();
169
169
  }
170
170
  render() {
171
- const t = this.currentState === "minimized" ? this.isLowered ? "1" : "3" : "4", e = this.currentState === "minimized", n = this.anchor.includes("bottom") ? this.anchor.includes("right") ? "bottom right" : "bottom left" : this.anchor.includes("right") ? "top right" : "top left", i = { "z-50": !0, fixed: !0, "overflow-y-auto": !0, flex: !0, "flex-col": !0, "select-none": !0, "will-change-transform": !0, "[contain:layout_style]": !0, "[transform:translate3d(0,0,0)]": !0, "[backface-visibility:hidden]": !0, "transition-shadow": !0, "opacity-95": this.isDragging, "shadow-[0_24px_48px_-8px_rgba(0,0,0,0.2),0_12px_24px_-4px_rgba(0,0,0,0.12)]": this.isDragging };
171
+ const t = this.currentState === "minimized" ? this.isLowered ? "1" : "3" : "4", e = this.currentState === "minimized", s = this.anchor.includes("bottom") ? this.anchor.includes("right") ? "bottom right" : "bottom left" : this.anchor.includes("right") ? "top right" : "top left", i = { "z-50": !0, fixed: !0, "overflow-y-auto": !0, flex: !0, "flex-col": !0, "select-none": !0, "will-change-transform": !0, "[contain:layout_style]": !0, "[transform:translate3d(0,0,0)]": !0, "[backface-visibility:hidden]": !0, "transition-shadow": !0, "opacity-95": this.isDragging, "shadow-[0_24px_48px_-8px_rgba(0,0,0,0.2),0_12px_24px_-4px_rgba(0,0,0,0.12)]": this.isDragging };
172
172
  return u`
173
173
  <div
174
174
  class=${this.classMap(i)}
175
- style="transform-origin: ${n}"
175
+ style="transform-origin: ${s}"
176
176
  ${w(this.containerRef)}
177
177
  >
178
178
  <!-- Header section -->
@@ -186,8 +186,8 @@ let c = class extends M(X`
186
186
  class="group sticky top-0 px-3 py-2 flex items-center justify-between gap-3 ${this.isDragging ? "cursor-grabbing" : "cursor-move"}"
187
187
  ${w(this.headerRef)}
188
188
  title="Drag to move, double-click to toggle"
189
- @dblclick=${(s) => {
190
- s.preventDefault(), s.stopPropagation(), this.toggleState();
189
+ @dblclick=${(n) => {
190
+ n.preventDefault(), n.stopPropagation(), this.toggleState();
191
191
  }}
192
192
  >
193
193
  <!-- Drag handle indicator -->
@@ -198,9 +198,16 @@ let c = class extends M(X`
198
198
  </div>
199
199
 
200
200
  <!-- Header content - use properties if provided, else fallback to slot -->
201
- <div class="flex-1 min-w-fit items-center flex justify-start">
201
+ <div
202
+ class="flex-1 min-w-fit items-center flex justify-start ${e ? "cursor-pointer" : ""}"
203
+
204
+ @dblclick=${(n) => {
205
+ e && (n.preventDefault(), n.stopPropagation(), this.state = "expanded");
206
+ }}
207
+ title="${e ? "Click to expand" : ""}"
208
+ >
202
209
  ${this.icon || this.label ? u`
203
- <div
210
+ <div
204
211
  class="flex gap-2 items-center">
205
212
  ${this.icon ? u`<schmancy-icon>${this.icon}</schmancy-icon>` : ""}
206
213
  ${this.label ? u`<schmancy-typography type="title" token="md">${this.label}</schmancy-typography>` : ""}
@@ -216,8 +223,8 @@ let c = class extends M(X`
216
223
  <schmancy-icon-button
217
224
  size="sm"
218
225
  variant="text"
219
- @click=${(s) => {
220
- s.stopPropagation(), this.state = "expanded";
226
+ @click=${(n) => {
227
+ n.stopPropagation(), this.state = "expanded";
221
228
  }}
222
229
  title="Expand"
223
230
  ${w(this.iconRef)}
@@ -229,8 +236,8 @@ let c = class extends M(X`
229
236
  <schmancy-icon-button
230
237
  size="sm"
231
238
  variant="filled tonal"
232
- @click=${(s) => {
233
- s.stopPropagation(), this.state = "minimized";
239
+ @click=${(n) => {
240
+ n.stopPropagation(), this.state = "minimized";
234
241
  }}
235
242
  title="Minimize"
236
243
  ${w(this.iconRef)}
@@ -242,8 +249,8 @@ let c = class extends M(X`
242
249
  <!-- Close button -->
243
250
  <schmancy-icon-button
244
251
  size="sm"
245
- @click=${(s) => {
246
- s.stopPropagation(), this.closeAndAddToNav();
252
+ @click=${(n) => {
253
+ n.stopPropagation(), this.closeAndAddToNav();
247
254
  }}
248
255
  title="Close and add to navigation"
249
256
  >
@@ -266,4 +273,4 @@ d([y({ type: String, reflect: !0 })], c.prototype, "state", 1), d([y({ type: Str
266
273
  export {
267
274
  c as S
268
275
  };
269
- //# sourceMappingURL=boat-BzsxPidL.js.map
276
+ //# sourceMappingURL=boat-BOeCFmGT.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"boat-BzsxPidL.js","sources":["../src/boat/boat.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { createRef, ref, Ref } from 'lit/directives/ref.js'\nimport { fromEvent, merge, race } from 'rxjs'\nimport { filter, finalize, map, switchMap, take, takeUntil, tap } from 'rxjs/operators'\n\ntype BoatState = 'hidden' | 'minimized' | 'expanded'\n\ninterface Position {\n\tx: number\n\ty: number\n}\n\ninterface SavedPosition {\n\tx: number\n\ty: number\n\tanchor: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'\n}\n\n@customElement('schmancy-boat')\nexport default class SchmancyBoat extends $LitElement(css`\n\t:host {\n\t\tdisplay: contents;\n\t}\n`) {\n\t@property({ type: String, reflect: true })\n\tget state(): BoatState {\n\t\treturn this.currentState\n\t}\n\tset state(value: BoatState) {\n\t\tif (this.isAnimating || value === this.currentState) return\n\t\tthis.animateToState(value)\n\t}\n\n\t@property({ type: String }) id: string = 'default'\n\n\t@property({ type: Boolean, reflect: true })\n\tget lowered(): boolean {\n\t\treturn this.isLowered\n\t}\n\tset lowered(value: boolean) {\n\t\tthis.isLowered = value\n\t\tthis.requestUpdate()\n\t}\n\n\t// New properties for simplified API\n\t@property({ type: String }) icon?: string\n\t@property({ type: String }) label?: string\n\t@property() badge?: string | number\n\n\t// Element references\n\tprivate containerRef: Ref<HTMLDivElement> = createRef()\n\tprivate contentRef: Ref<HTMLElement> = createRef()\n\tprivate iconRef: Ref<HTMLElement> = createRef()\n\tprivate headerRef: Ref<HTMLElement> = createRef()\n\n\t// Current animation reference\n\tprivate currentAnimation?: Animation\n\n\t// Animation configuration\n\tprivate readonly ANIMATION_CONFIG = {\n\t\tdurations: {\n\t\t\texpand: 350,\n\t\t\tminimize: 250,\n\t\t\thide: 200,\n\t\t\tcontent: 300,\n\t\t},\n\t\teasing: {\n\t\t\temphasized: 'cubic-bezier(0.2, 0.0, 0, 1.0)',\n\t\t\tdecelerate: 'cubic-bezier(0.05, 0.7, 0.1, 1.0)',\n\t\t\taccelerate: 'cubic-bezier(0.3, 0.0, 0.8, 0.15)',\n\t\t\tstandard: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\t\t},\n\t\tshadows: {\n\t\t\tfab: '0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12)',\n\t\t\tfabLowered:\n\t\t\t\t'0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12)',\n\t\t\texpanded: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n\t\t},\n\t}\n\n\t// Reactive state for template\n\t@state() private currentState: BoatState = 'minimized'\n\t@state() private isContentVisible: boolean = false\n\t@state() private isAnimating: boolean = false\n\t@state() private isLowered: boolean = false\n\t@state() private isDragging: boolean = false\n\t@state() private position: Position = { x: 16, y: 16 }\n\t@state() private anchor: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' = 'bottom-right'\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\tif (typeof window !== 'undefined') {\n\t\t\tfromEvent(window, 'resize')\n\t\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t\t.subscribe(() => {\n\t\t\t\t\tif (this.currentState === 'expanded') {\n\t\t\t\t\t\tthis.updateExpandedWidth()\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t// Keyboard shortcut - Escape key\n\t\t\tfromEvent<KeyboardEvent>(window, 'keydown')\n\t\t\t\t.pipe(\n\t\t\t\t\tfilter(e => e.key === 'Escape' && this.currentState !== 'hidden'),\n\t\t\t\t\ttap(e => e.preventDefault()),\n\t\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t\t)\n\t\t\t\t.subscribe(() => {\n\t\t\t\t\tif (this.currentState === 'expanded') {\n\t\t\t\t\t\tthis.toggleState() // Minimize on Esc if expanded\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.close() // Hide on Esc if minimized\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t}\n\t}\n\n\tprivate initializePosition() {\n\t\tif (typeof window === 'undefined') return\n\n\t\tconst saved = localStorage.getItem(`schmancy-boat-${this.id}`)\n\n\t\tif (saved) {\n\t\t\ttry {\n\t\t\t\tconst parsed: SavedPosition = JSON.parse(saved)\n\t\t\t\tthis.position = { x: parsed.x, y: parsed.y }\n\t\t\t\tthis.anchor = parsed.anchor\n\t\t\t\tconsole.log('📍 Loaded position:', this.id, parsed)\n\t\t\t} catch (e) {\n\t\t\t\t// Use default position on parse error\n\t\t\t}\n\t\t}\n\t\t// If no saved position, use default from @state initialization\n\t}\n\n\tprivate async animateToState(targetState: BoatState) {\n\t\tif (this.isAnimating || targetState === this.currentState) return\n\n\t\tconst previousState = this.currentState\n\t\tthis.isAnimating = true\n\n\t\ttry {\n\t\t\tawait this.performTransition(previousState, targetState)\n\t\t\tthis.currentState = targetState\n\t\t\tthis.isContentVisible = targetState === 'expanded'\n\n\t\t\t// Dispatch event\n\t\t\tthis.dispatchEvent(\n\t\t\t\tnew CustomEvent('toggle', {\n\t\t\t\t\tdetail: targetState,\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true,\n\t\t\t\t}),\n\t\t\t)\n\t\t} catch (err) {\n\t\t\tconsole.warn('Animation error:', err)\n\t\t\tthis.currentState = targetState\n\t\t\tthis.isContentVisible = targetState === 'expanded'\n\t\t} finally {\n\t\t\tthis.isAnimating = false\n\t\t}\n\t}\n\n\t// Simplified animation transition\n\tprivate async performTransition(fromState: BoatState, toState: BoatState): Promise<void> {\n\t\tthis.currentAnimation?.cancel()\n\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\t// Update content visibility before expand\n\t\tif (toState === 'expanded') {\n\t\t\tthis.isContentVisible = true\n\t\t}\n\n\t\t// Create animations\n\t\tconst animations = this.createAnimations(fromState, toState)\n\n\t\t// Wait for main animation to complete\n\t\tif (animations.container) {\n\t\t\tthis.currentAnimation = animations.container\n\t\t\tawait animations.container.finished\n\n\t\t\t// Hide content after minimize\n\t\t\tif (toState !== 'expanded') {\n\t\t\t\tthis.isContentVisible = false\n\t\t\t}\n\t\t}\n\t}\n\n\t// Create animations for state transition\n\tprivate createAnimations(fromState: BoatState, toState: BoatState) {\n\t\tconst container = this.containerRef.value\n\t\tconst content = this.contentRef.value\n\t\tconst icon = this.iconRef.value\n\t\tconst animations: { container?: Animation; content?: Animation; icon?: Animation } = {}\n\n\t\tif (!container) return animations\n\n\t\tconst config = this.ANIMATION_CONFIG\n\t\tconst fromStyles = this.getStyleForState(fromState)\n\t\tconst toStyles = this.getStyleForState(toState)\n\n\t\t// Container animation\n\t\tif (toState === 'expanded') {\n\t\t\t// Expand animation without transform\n\t\t\tanimations.container = container.animate([fromStyles, toStyles], {\n\t\t\t\tduration: config.durations.expand,\n\t\t\t\teasing: config.easing.decelerate,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t} else {\n\t\t\tanimations.container = container.animate([fromStyles, toStyles], {\n\t\t\t\tduration: toState === 'hidden' ? config.durations.hide : config.durations.minimize,\n\t\t\t\teasing: config.easing.accelerate,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\t// Content animation (only for expand/minimize transitions)\n\t\tif (content && fromState === 'expanded' && toState === 'minimized') {\n\t\t\t// Fade out content before minimizing\n\t\t\tcontent.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 1, transform: 'translateY(0)' },\n\t\t\t\t\t{ opacity: 0, transform: 'translateY(-8px)' },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 150,\n\t\t\t\t\teasing: config.easing.standard,\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t} else if (content && toState === 'expanded') {\n\t\t\t// Fade in content when expanding\n\t\t\tcontent.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 0, transform: 'translateY(8px)' },\n\t\t\t\t\t{ opacity: 1, transform: 'translateY(0)' },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: config.durations.content,\n\t\t\t\t\teasing: config.easing.standard,\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\n\t\t// Icon rotation animation\n\t\tif (icon) {\n\t\t\tconst isExpanding = toState === 'expanded'\n\t\t\tconst isCollapsing = fromState === 'expanded' && toState === 'minimized'\n\n\t\t\tif (isExpanding || isCollapsing) {\n\t\t\t\ticon.animate(\n\t\t\t\t\t[\n\t\t\t\t\t\t{ transform: isExpanding ? 'rotate(0deg)' : 'rotate(180deg)' },\n\t\t\t\t\t\t{ transform: isExpanding ? 'rotate(180deg)' : 'rotate(0deg)' },\n\t\t\t\t\t],\n\t\t\t\t\t{\n\t\t\t\t\t\tduration: 250,\n\t\t\t\t\t\teasing: config.easing.emphasized,\n\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\treturn animations\n\t}\n\n\t// Get styles for a specific state\n\tprivate getStyleForState(state: BoatState): Keyframe {\n\t\tconst { shadows } = this.ANIMATION_CONFIG\n\t\tconst baseStyles = {\n\t\t\tmaxWidth: '300px',\n\t\t\tmaxHeight: 'auto',\n\t\t\tborderRadius: '16px',\n\t\t}\n\n\t\tconst stateStyles: Record<BoatState, Keyframe> = {\n\t\t\thidden: {\n\t\t\t\t...baseStyles,\n\t\t\t\topacity: '0',\n\t\t\t\tpointerEvents: 'none',\n\t\t\t\tboxShadow: 'none',\n\t\t\t\tbackdropFilter: 'none',\n\t\t\t},\n\t\t\tminimized: {\n\t\t\t\t...baseStyles,\n\t\t\t\topacity: '1',\n\t\t\t\tpointerEvents: 'auto',\n\t\t\t\tboxShadow: this.isLowered ? shadows.fabLowered : shadows.fab,\n\t\t\t\tbackdropFilter: 'none',\n\t\t\t},\n\t\t\texpanded: {\n\t\t\t\topacity: '1',\n\t\t\t\tpointerEvents: 'auto',\n\t\t\t\twidth: this.getResponsiveWidth(),\n\t\t\t\tmaxWidth: '100%',\n\t\t\t\tmaxHeight: '80vh',\n\t\t\t\tboxShadow: shadows.expanded,\n\t\t\t\tborderRadius: '8px 8px 0 0',\n\t\t\t\tbackdropFilter: 'blur(12px)',\n\t\t\t},\n\t\t}\n\n\t\treturn stateStyles[state] as Keyframe\n\t}\n\n\t// Calculate responsive width based on viewport\n\tprivate getResponsiveWidth(): string {\n\t\tif (typeof window === 'undefined') return '40vw'\n\n\t\tconst vw = window.innerWidth\n\t\tif (vw < 768) return 'calc(100vw - 32px)'\n\t\tif (vw < 1024) return '70vw'\n\t\tif (vw < 1280) return '60vw'\n\t\treturn '40vw'\n\t}\n\n\t// Update expanded width on window resize\n\tprivate updateExpandedWidth() {\n\t\tconst container = this.containerRef.value\n\t\tif (container && this.currentState === 'expanded') {\n\t\t\tcontainer.style.width = this.getResponsiveWidth()\n\t\t}\n\t}\n\n\tfirstUpdated() {\n\t\tthis.initializePosition()\n\t\tthis.applyInitialStyles()\n\t\tthis.updateContainerPosition()\n\t\tthis.setupDragPipeline()\n\n\t\t// Check for deprecated header slot usage\n\t\tconst hasHeaderSlot = this.querySelector('[slot=\"header\"]')\n\t\tif (hasHeaderSlot && !this.icon && !this.label) {\n\t\t\tconsole.warn(\n\t\t\t\t'[schmancy-boat] Using slot=\"header\" is deprecated. ' +\n\t\t\t\t\t'Please use the icon, label, and badge properties instead. ' +\n\t\t\t\t\t'Example: <schmancy-boat icon=\"info\" label=\"Title\" badge=\"5\">',\n\t\t\t)\n\t\t}\n\t}\n\n\t// Apply initial styles to elements\n\tprivate applyInitialStyles() {\n\t\tconst container = this.containerRef.value\n\t\tconst content = this.contentRef.value\n\t\tconst icon = this.iconRef.value\n\n\t\tif (container) {\n\t\t\tconst initialStyle = this.getStyleForState(this.currentState)\n\t\t\tObject.assign(container.style, initialStyle)\n\n\t\t\t// Safari compatibility for backdrop filter\n\t\t\tif ('webkitBackdropFilter' in container.style) {\n\t\t\t\t;(container.style as any).webkitBackdropFilter = initialStyle.backdropFilter\n\t\t\t}\n\t\t}\n\n\t\t// Set initial content opacity\n\t\tif (content) {\n\t\t\tcontent.style.opacity = this.isContentVisible ? '1' : '0'\n\t\t}\n\n\t\t// Set initial icon rotation\n\t\tif (icon && this.currentState === 'expanded') {\n\t\t\ticon.style.transform = 'rotate(180deg)'\n\t\t}\n\t}\n\n\t// Public method to toggle between minimized and expanded\n\ttoggleState() {\n\t\tconst newState = this.currentState === 'minimized' ? 'expanded' : 'minimized'\n\t\tthis.animateToState(newState)\n\t}\n\n\t// Public method to close (hide) the boat\n\tclose() {\n\t\tthis.animateToState('hidden')\n\t}\n\n\tprivate closeAndAddToNav() {\n\t\trace(\n\t\t\tthis.discover<any>('schmancy-navigation-rail'),\n\t\t\tthis.discover<any>('schmancy-navigation-bar'),\n\t\t\tthis.discover<any>('schmancy-nav-drawer'),\n\t\t\tthis.discover<any>('app-navigation-rail'),\n\t\t\tthis.discover<any>('app-navigation-bar'),\n\t\t\tthis.discover<any>('app-nav-drawer'),\n\t\t)\n\t\t\t.pipe(\n\t\t\t\ttake(1),\n\t\t\t\ttap(navComponent => {\n\t\t\t\t\tif (navComponent && typeof navComponent.addBoatItem === 'function') {\n\t\t\t\t\t\t// Use properties first, fall back to slot parsing\n\t\t\t\t\t\tconst icon =\n\t\t\t\t\t\t\tthis.icon ||\n\t\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\t\tconst headerSlot = this.querySelector('[slot=\"header\"]')\n\t\t\t\t\t\t\t\tconst iconElement = headerSlot?.querySelector('schmancy-icon')\n\t\t\t\t\t\t\t\treturn iconElement?.textContent?.trim() || 'widgets'\n\t\t\t\t\t\t\t})()\n\n\t\t\t\t\t\tconst label =\n\t\t\t\t\t\t\tthis.label ||\n\t\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\t\tconst headerSlot = this.querySelector('[slot=\"header\"]')\n\t\t\t\t\t\t\t\tlet title = headerSlot?.textContent?.trim() || 'Boat'\n\t\t\t\t\t\t\t\tif (icon && title.includes(icon)) {\n\t\t\t\t\t\t\t\t\ttitle = title.replace(icon, '').trim()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn title || this.id\n\t\t\t\t\t\t\t})()\n\n\t\t\t\t\t\t// Add the boat to navigation\n\t\t\t\t\t\tconst navItem = navComponent.addBoatItem({\n\t\t\t\t\t\t\tid: `boat-${this.id}`,\n\t\t\t\t\t\t\ttitle: label,\n\t\t\t\t\t\t\ticon: icon,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tif (navItem) {\n\t\t\t\t\t\t\t// Simple fade out then hide\n\t\t\t\t\t\t\tconst container = this.containerRef.value\n\t\t\t\t\t\t\tif (container) {\n\t\t\t\t\t\t\t\tcontainer\n\t\t\t\t\t\t\t\t\t.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 150, easing: 'ease-out', fill: 'forwards' })\n\t\t\t\t\t\t\t\t\t.finished.then(() => {\n\t\t\t\t\t\t\t\t\t\tthis.currentState = 'hidden'\n\t\t\t\t\t\t\t\t\t\tthis.isContentVisible = false\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.currentState = 'hidden'\n\t\t\t\t\t\t\t\tthis.isContentVisible = false\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Set up click listener to reopen - using RxJS pattern\n\t\t\t\t\t\t\tfromEvent(navItem, 'click')\n\t\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\t\ttap(() => (this.state = 'expanded')),\n\t\t\t\t\t\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.subscribe()\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// No nav component found, just hide\n\t\t\t\t\t\tthis.close()\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tprivate calculateDragPosition(\n\t\tclientX: number,\n\t\tclientY: number,\n\t\toffsetX: number,\n\t\toffsetY: number,\n\t\tinitialRect: DOMRect,\n\t): Position {\n\t\tconst targetLeft = clientX - offsetX\n\t\tconst targetTop = clientY - offsetY\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\t\tconst clampedLeft = Math.max(0, Math.min(targetLeft, vw - initialRect.width))\n\t\tconst clampedTop = Math.max(0, Math.min(targetTop, vh - initialRect.height))\n\n\t\tconst newX = this.anchor.includes('right') ? vw - (clampedLeft + initialRect.width) : clampedLeft\n\n\t\tconst newY = this.anchor.includes('bottom') ? vh - (clampedTop + initialRect.height) : clampedTop\n\n\t\treturn { x: Math.max(0, newX), y: Math.max(0, newY) }\n\t}\n\n\tprivate savePosition() {\n\t\tif (typeof window === 'undefined') return\n\n\t\tconst toSave: SavedPosition = {\n\t\t\tx: this.position.x,\n\t\t\ty: this.position.y,\n\t\t\tanchor: this.anchor,\n\t\t}\n\t\tconst key = `schmancy-boat-${this.id}`\n\t\tlocalStorage.setItem(key, JSON.stringify(toSave))\n\t\tconsole.log('💾 Saved position:', key, toSave)\n\t}\n\n\tprivate setupDragPipeline() {\n\t\tif (typeof window === 'undefined') return\n\n\t\tconst header = this.headerRef.value\n\t\tconst container = this.containerRef.value\n\t\tif (!header || !container) return\n\n\t\tlet hasDragged = false\n\t\tconst DRAG_THRESHOLD = 5\n\n\t\t// Merge mouse and touch start events\n\t\tmerge(\n\t\t\tfromEvent<MouseEvent>(header, 'mousedown').pipe(\n\t\t\t\tfilter(e => e.button === 0),\n\t\t\t\ttap(e => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t}),\n\t\t\t\tmap(e => ({\n\t\t\t\t\tclientX: e.clientX,\n\t\t\t\t\tclientY: e.clientY,\n\t\t\t\t\ttype: 'mouse' as const,\n\t\t\t\t})),\n\t\t\t),\n\t\t\tfromEvent<TouchEvent>(header, 'touchstart').pipe(\n\t\t\t\tmap(e => ({\n\t\t\t\t\tclientX: e.touches[0].clientX,\n\t\t\t\t\tclientY: e.touches[0].clientY,\n\t\t\t\t\ttype: 'touch' as const,\n\t\t\t\t})),\n\t\t\t),\n\t\t)\n\t\t\t.pipe(\n\t\t\t\tmap(({ clientX, clientY, type }) => {\n\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\thasDragged = false\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstartX: clientX,\n\t\t\t\t\t\tstartY: clientY,\n\t\t\t\t\t\toffsetX: clientX - rect.left,\n\t\t\t\t\t\toffsetY: clientY - rect.top,\n\t\t\t\t\t\tinitialRect: rect,\n\t\t\t\t\t\ttype,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.pipe(\n\t\t\t\tswitchMap(({ startX, startY, offsetX, offsetY, initialRect, type }) => {\n\t\t\t\t\tconst move$ =\n\t\t\t\t\t\ttype === 'mouse'\n\t\t\t\t\t\t\t? fromEvent<MouseEvent>(window, 'mousemove').pipe(map(e => ({ clientX: e.clientX, clientY: e.clientY })))\n\t\t\t\t\t\t\t: fromEvent<TouchEvent>(window, 'touchmove').pipe(\n\t\t\t\t\t\t\t\t\tmap(e => ({ clientX: e.touches[0].clientX, clientY: e.touches[0].clientY })),\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\tconst end$ = type === 'mouse' ? fromEvent(window, 'mouseup') : fromEvent(window, 'touchend')\n\n\t\t\t\t\treturn move$.pipe(\n\t\t\t\t\t\tmap(({ clientX, clientY }) => {\n\t\t\t\t\t\t\tconst deltaX = clientX - startX\n\t\t\t\t\t\t\tconst deltaY = clientY - startY\n\t\t\t\t\t\t\tconst distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY)\n\n\t\t\t\t\t\t\tif (distance > DRAG_THRESHOLD && !hasDragged) {\n\t\t\t\t\t\t\t\thasDragged = true\n\t\t\t\t\t\t\t\tthis.isDragging = true\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!hasDragged) return null\n\n\t\t\t\t\t\t\treturn this.calculateDragPosition(clientX, clientY, offsetX, offsetY, initialRect)\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tfilter(position => position !== null),\n\t\t\t\t\t\ttap(position => {\n\t\t\t\t\t\t\tif (position) {\n\t\t\t\t\t\t\t\tthis.position = position\n\t\t\t\t\t\t\t\tthis.updateContainerPosition()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t\ttakeUntil(end$),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t\tfinalize(() => {\n\t\t\t\t\tif (hasDragged) {\n\t\t\t\t\t\tthis.updateAnchor()\n\t\t\t\t\t\tthis.savePosition()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.toggleState()\n\t\t\t\t\t}\n\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\thasDragged = false\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\t// Update container position based on anchor and position values\n\tprivate updateContainerPosition() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\t// Reset all position styles\n\t\tcontainer.style.removeProperty('left')\n\t\tcontainer.style.removeProperty('right')\n\t\tcontainer.style.removeProperty('top')\n\t\tcontainer.style.removeProperty('bottom')\n\n\t\t// Apply new position based on anchor\n\t\tif (this.anchor.includes('right')) {\n\t\t\tcontainer.style.right = `${this.position.x}px`\n\t\t} else {\n\t\t\tcontainer.style.left = `${this.position.x}px`\n\t\t}\n\n\t\tif (this.anchor.includes('bottom')) {\n\t\t\tcontainer.style.bottom = `${this.position.y}px`\n\t\t} else {\n\t\t\tcontainer.style.top = `${this.position.y}px`\n\t\t}\n\t}\n\n\t// Update anchor based on current position\n\tprivate updateAnchor() {\n\t\tif (typeof window === 'undefined') return\n\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\tconst rect = container.getBoundingClientRect()\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\n\t\tconst isRight = rect.left > vw / 2\n\t\tconst isBottom = rect.top > vh / 2\n\n\t\tconst newAnchor = `${isBottom ? 'bottom' : 'top'}-${isRight ? 'right' : 'left'}` as typeof this.anchor\n\n\t\tif (newAnchor !== this.anchor) {\n\t\t\t// Calculate new position values for the new anchor\n\t\t\tif (isRight) {\n\t\t\t\tthis.position.x = vw - rect.right\n\t\t\t} else {\n\t\t\t\tthis.position.x = rect.left\n\t\t\t}\n\n\t\t\tif (isBottom) {\n\t\t\t\tthis.position.y = vh - rect.bottom\n\t\t\t} else {\n\t\t\t\tthis.position.y = rect.top\n\t\t\t}\n\n\t\t\tthis.anchor = newAnchor\n\t\t}\n\t}\n\n\t// Cleanup on component disconnect\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis.currentAnimation?.cancel()\n\t}\n\n\tprotected render(): unknown {\n\t\tconst surfaceElevation = this.currentState === 'minimized' ? (this.isLowered ? '1' : '3') : '4'\n\t\tconst isMinimized = this.currentState === 'minimized'\n\n\t\t// Set transform origin based on anchor for proper expansion\n\t\tconst transformOrigin = this.anchor.includes('bottom')\n\t\t\t? this.anchor.includes('right')\n\t\t\t\t? 'bottom right'\n\t\t\t\t: 'bottom left'\n\t\t\t: this.anchor.includes('right')\n\t\t\t\t? 'top right'\n\t\t\t\t: 'top left'\n\n\t\tconst containerClasses = {\n\t\t\t'z-50': true,\n\t\t\tfixed: true,\n\t\t\t'overflow-y-auto': true,\n\t\t\tflex: true,\n\t\t\t'flex-col': true,\n\t\t\t'select-none': true,\n\t\t\t'will-change-transform': true,\n\t\t\t'[contain:layout_style]': true,\n\t\t\t'[transform:translate3d(0,0,0)]': true,\n\t\t\t'[backface-visibility:hidden]': true,\n\t\t\t'transition-shadow': true,\n\t\t\t'opacity-95': this.isDragging,\n\t\t\t'shadow-[0_24px_48px_-8px_rgba(0,0,0,0.2),0_12px_24px_-4px_rgba(0,0,0,0.12)]': this.isDragging,\n\t\t}\n\n\t\treturn html`\n\t\t\t<div\n\t\t\t\tclass=${this.classMap(containerClasses)}\n\t\t\t\tstyle=\"transform-origin: ${transformOrigin}\"\n\t\t\t\t${ref(this.containerRef)}\n\t\t\t>\n\t\t\t\t<!-- Header section -->\n\t\t\t\t<section class=\"sticky top-0\">\n\t\t\t\t\t<schmancy-surface\n\t\t\t\t\t\televation=\"${surfaceElevation}\"\n\t\t\t\t\t\trounded=\"${isMinimized ? 'none' : 'top'}\"\n\t\t\t\t\t\ttype=\"containerLowest\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclass=\"group sticky top-0 px-3 py-2 flex items-center justify-between gap-3 ${this.isDragging\n\t\t\t\t\t\t\t\t? 'cursor-grabbing'\n\t\t\t\t\t\t\t\t: 'cursor-move'}\"\n\t\t\t\t\t\t\t${ref(this.headerRef)}\n\t\t\t\t\t\t\ttitle=\"Drag to move, double-click to toggle\"\n\t\t\t\t\t\t\t@dblclick=${(e: Event) => {\n\t\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\tthis.toggleState()\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!-- Drag handle indicator -->\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"flex items-center text-surface-onVariant opacity-40 transition-opacity duration-200 group-hover:opacity-100\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<schmancy-icon style=\"font-size: 20px\">drag_indicator</schmancy-icon>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<!-- Header content - use properties if provided, else fallback to slot -->\n\t\t\t\t\t\t\t<div class=\"flex-1 min-w-fit items-center flex justify-start\">\n\t\t\t\t\t\t\t\t${this.icon || this.label\n\t\t\t\t\t\t\t\t\t? html`\n\t\t\t\t\t\t\t\t\t\t\t<div \n\t\t\t\t\t\t\t\t\t\t\tclass=\"flex gap-2 items-center\">\n\t\t\t\t\t\t\t\t\t\t\t\t${this.icon ? html`<schmancy-icon>${this.icon}</schmancy-icon>` : ''}\n\t\t\t\t\t\t\t\t\t\t\t\t${this.label\n\t\t\t\t\t\t\t\t\t\t\t\t\t? html`<schmancy-typography type=\"title\" token=\"md\">${this.label}</schmancy-typography>`\n\t\t\t\t\t\t\t\t\t\t\t\t\t: ''}\n\t\t\t\t\t\t\t\t\t\t\t\t${this.badge !== undefined && this.badge !== null && this.badge !== ''\n\t\t\t\t\t\t\t\t\t\t\t\t\t? html`<schmancy-badge>${this.badge}</schmancy-badge>`\n\t\t\t\t\t\t\t\t\t\t\t\t\t: ''}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t`\n\t\t\t\t\t\t\t\t\t: html`<slot name=\"header\"></slot>`}\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<!-- Control buttons -->\n\t\t\t\t\t\t\t<div class=\"flex items-center gap-1 flex-shrink-0\">\n\t\t\t\t\t\t\t\t${isMinimized\n\t\t\t\t\t\t\t\t\t? html`\n\t\t\t\t\t\t\t\t\t\t\t<!-- Expand button (when minimized) -->\n\t\t\t\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"text\"\n\t\t\t\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\t\t\t\tthis.state = 'expanded'\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"Expand\"\n\t\t\t\t\t\t\t\t\t\t\t\t${ref(this.iconRef)}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\tfullscreen\n\t\t\t\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t\t\t\t`\n\t\t\t\t\t\t\t\t\t: html`\n\t\t\t\t\t\t\t\t\t\t\t<!-- Minimize button (when expanded) -->\n\t\t\t\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"filled tonal\"\n\t\t\t\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\t\t\t\tthis.state = 'minimized'\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"Minimize\"\n\t\t\t\t\t\t\t\t\t\t\t\t${ref(this.iconRef)}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\tclose_fullscreen\n\t\t\t\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t\t\t\t`}\n\n\t\t\t\t\t\t\t\t<!-- Close button -->\n\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\tthis.closeAndAddToNav()\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\ttitle=\"Close and add to navigation\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tremove\n\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</schmancy-surface>\n\t\t\t\t</section>\n\n\t\t\t\t<!-- Content section -->\n\t\t\t\t<schmancy-surface .hidden=${!this.isContentVisible} type=\"containerLow\" class=\"flex-1\" ${ref(this.contentRef)}>\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</schmancy-surface>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-boat': SchmancyBoat\n\t}\n}\n"],"names":["SchmancyBoat","$LitElement","css","super","arguments","this","id","containerRef","createRef","contentRef","iconRef","headerRef","ANIMATION_CONFIG","durations","expand","minimize","hide","content","easing","emphasized","decelerate","accelerate","standard","shadows","fab","fabLowered","expanded","currentState","isContentVisible","isAnimating","isLowered","isDragging","position","x","y","anchor","state","value","animateToState","lowered","requestUpdate","connectedCallback","window","fromEvent","pipe","takeUntil","disconnecting","subscribe","updateExpandedWidth","filter","e","key","tap","preventDefault","toggleState","close","initializePosition","saved","localStorage","getItem","parsed","JSON","parse","targetState","previousState","performTransition","dispatchEvent","CustomEvent","detail","bubbles","composed","fromState","toState","currentAnimation","cancel","animations","createAnimations","container","finished","icon","config","fromStyles","getStyleForState","toStyles","animate","duration","fill","opacity","transform","isExpanding","baseStyles","maxWidth","maxHeight","borderRadius","hidden","pointerEvents","boxShadow","backdropFilter","minimized","width","getResponsiveWidth","vw","innerWidth","style","applyInitialStyles","updateContainerPosition","setupDragPipeline","querySelector","label","initialStyle","Object","assign","webkitBackdropFilter","newState","race","discover","take","navComponent","addBoatItem","textContent","trim","title","includes","replace","navItem","then","clientX","clientY","offsetX","offsetY","initialRect","targetLeft","targetTop","vh","innerHeight","clampedLeft","Math","max","min","clampedTop","height","newX","newY","toSave","setItem","stringify","header","hasDragged","merge","button","stopPropagation","map","type","touches","rect","getBoundingClientRect","startX","startY","left","top","switchMap","move$","end$","deltaX","deltaY","sqrt","calculateDragPosition","finalize","updateAnchor","savePosition","removeProperty","right","bottom","isRight","isBottom","newAnchor","disconnectedCallback","render","surfaceElevation","isMinimized","transformOrigin","containerClasses","fixed","flex","html","classMap","ref","badge","closeAndAddToNav","__decorateClass","property","String","reflect","prototype","Boolean","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"boat-BOeCFmGT.js","sources":["../src/boat/boat.ts"],"sourcesContent":["import { $LitElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { createRef, ref, Ref } from 'lit/directives/ref.js'\nimport { fromEvent, merge, race } from 'rxjs'\nimport { filter, finalize, map, switchMap, take, takeUntil, tap } from 'rxjs/operators'\n\ntype BoatState = 'hidden' | 'minimized' | 'expanded'\n\ninterface Position {\n\tx: number\n\ty: number\n}\n\ninterface SavedPosition {\n\tx: number\n\ty: number\n\tanchor: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'\n}\n\n@customElement('schmancy-boat')\nexport default class SchmancyBoat extends $LitElement(css`\n\t:host {\n\t\tdisplay: contents;\n\t}\n`) {\n\t@property({ type: String, reflect: true })\n\tget state(): BoatState {\n\t\treturn this.currentState\n\t}\n\tset state(value: BoatState) {\n\t\tif (this.isAnimating || value === this.currentState) return\n\t\tthis.animateToState(value)\n\t}\n\n\t@property({ type: String }) id: string = 'default'\n\n\t@property({ type: Boolean, reflect: true })\n\tget lowered(): boolean {\n\t\treturn this.isLowered\n\t}\n\tset lowered(value: boolean) {\n\t\tthis.isLowered = value\n\t\tthis.requestUpdate()\n\t}\n\n\t// New properties for simplified API\n\t@property({ type: String }) icon?: string\n\t@property({ type: String }) label?: string\n\t@property() badge?: string | number\n\n\t// Element references\n\tprivate containerRef: Ref<HTMLDivElement> = createRef()\n\tprivate contentRef: Ref<HTMLElement> = createRef()\n\tprivate iconRef: Ref<HTMLElement> = createRef()\n\tprivate headerRef: Ref<HTMLElement> = createRef()\n\n\t// Current animation reference\n\tprivate currentAnimation?: Animation\n\n\t// Animation configuration\n\tprivate readonly ANIMATION_CONFIG = {\n\t\tdurations: {\n\t\t\texpand: 350,\n\t\t\tminimize: 250,\n\t\t\thide: 200,\n\t\t\tcontent: 300,\n\t\t},\n\t\teasing: {\n\t\t\temphasized: 'cubic-bezier(0.2, 0.0, 0, 1.0)',\n\t\t\tdecelerate: 'cubic-bezier(0.05, 0.7, 0.1, 1.0)',\n\t\t\taccelerate: 'cubic-bezier(0.3, 0.0, 0.8, 0.15)',\n\t\t\tstandard: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\t\t},\n\t\tshadows: {\n\t\t\tfab: '0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12)',\n\t\t\tfabLowered:\n\t\t\t\t'0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12)',\n\t\t\texpanded: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n\t\t},\n\t}\n\n\t// Reactive state for template\n\t@state() private currentState: BoatState = 'minimized'\n\t@state() private isContentVisible: boolean = false\n\t@state() private isAnimating: boolean = false\n\t@state() private isLowered: boolean = false\n\t@state() private isDragging: boolean = false\n\t@state() private position: Position = { x: 16, y: 16 }\n\t@state() private anchor: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' = 'bottom-right'\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\tif (typeof window !== 'undefined') {\n\t\t\tfromEvent(window, 'resize')\n\t\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t\t.subscribe(() => {\n\t\t\t\t\tif (this.currentState === 'expanded') {\n\t\t\t\t\t\tthis.updateExpandedWidth()\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t// Keyboard shortcut - Escape key\n\t\t\tfromEvent<KeyboardEvent>(window, 'keydown')\n\t\t\t\t.pipe(\n\t\t\t\t\tfilter(e => e.key === 'Escape' && this.currentState !== 'hidden'),\n\t\t\t\t\ttap(e => e.preventDefault()),\n\t\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t\t)\n\t\t\t\t.subscribe(() => {\n\t\t\t\t\tif (this.currentState === 'expanded') {\n\t\t\t\t\t\tthis.toggleState() // Minimize on Esc if expanded\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.close() // Hide on Esc if minimized\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t}\n\t}\n\n\tprivate initializePosition() {\n\t\tif (typeof window === 'undefined') return\n\n\t\tconst saved = localStorage.getItem(`schmancy-boat-${this.id}`)\n\n\t\tif (saved) {\n\t\t\ttry {\n\t\t\t\tconst parsed: SavedPosition = JSON.parse(saved)\n\t\t\t\tthis.position = { x: parsed.x, y: parsed.y }\n\t\t\t\tthis.anchor = parsed.anchor\n\t\t\t\tconsole.log('📍 Loaded position:', this.id, parsed)\n\t\t\t} catch (e) {\n\t\t\t\t// Use default position on parse error\n\t\t\t}\n\t\t}\n\t\t// If no saved position, use default from @state initialization\n\t}\n\n\tprivate async animateToState(targetState: BoatState) {\n\t\tif (this.isAnimating || targetState === this.currentState) return\n\n\t\tconst previousState = this.currentState\n\t\tthis.isAnimating = true\n\n\t\ttry {\n\t\t\tawait this.performTransition(previousState, targetState)\n\t\t\tthis.currentState = targetState\n\t\t\tthis.isContentVisible = targetState === 'expanded'\n\n\t\t\t// Dispatch event\n\t\t\tthis.dispatchEvent(\n\t\t\t\tnew CustomEvent('toggle', {\n\t\t\t\t\tdetail: targetState,\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true,\n\t\t\t\t}),\n\t\t\t)\n\t\t} catch (err) {\n\t\t\tconsole.warn('Animation error:', err)\n\t\t\tthis.currentState = targetState\n\t\t\tthis.isContentVisible = targetState === 'expanded'\n\t\t} finally {\n\t\t\tthis.isAnimating = false\n\t\t}\n\t}\n\n\t// Simplified animation transition\n\tprivate async performTransition(fromState: BoatState, toState: BoatState): Promise<void> {\n\t\tthis.currentAnimation?.cancel()\n\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\t// Update content visibility before expand\n\t\tif (toState === 'expanded') {\n\t\t\tthis.isContentVisible = true\n\t\t}\n\n\t\t// Create animations\n\t\tconst animations = this.createAnimations(fromState, toState)\n\n\t\t// Wait for main animation to complete\n\t\tif (animations.container) {\n\t\t\tthis.currentAnimation = animations.container\n\t\t\tawait animations.container.finished\n\n\t\t\t// Hide content after minimize\n\t\t\tif (toState !== 'expanded') {\n\t\t\t\tthis.isContentVisible = false\n\t\t\t}\n\t\t}\n\t}\n\n\t// Create animations for state transition\n\tprivate createAnimations(fromState: BoatState, toState: BoatState) {\n\t\tconst container = this.containerRef.value\n\t\tconst content = this.contentRef.value\n\t\tconst icon = this.iconRef.value\n\t\tconst animations: { container?: Animation; content?: Animation; icon?: Animation } = {}\n\n\t\tif (!container) return animations\n\n\t\tconst config = this.ANIMATION_CONFIG\n\t\tconst fromStyles = this.getStyleForState(fromState)\n\t\tconst toStyles = this.getStyleForState(toState)\n\n\t\t// Container animation\n\t\tif (toState === 'expanded') {\n\t\t\t// Expand animation without transform\n\t\t\tanimations.container = container.animate([fromStyles, toStyles], {\n\t\t\t\tduration: config.durations.expand,\n\t\t\t\teasing: config.easing.decelerate,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t} else {\n\t\t\tanimations.container = container.animate([fromStyles, toStyles], {\n\t\t\t\tduration: toState === 'hidden' ? config.durations.hide : config.durations.minimize,\n\t\t\t\teasing: config.easing.accelerate,\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t}\n\n\t\t// Content animation (only for expand/minimize transitions)\n\t\tif (content && fromState === 'expanded' && toState === 'minimized') {\n\t\t\t// Fade out content before minimizing\n\t\t\tcontent.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 1, transform: 'translateY(0)' },\n\t\t\t\t\t{ opacity: 0, transform: 'translateY(-8px)' },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 150,\n\t\t\t\t\teasing: config.easing.standard,\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t} else if (content && toState === 'expanded') {\n\t\t\t// Fade in content when expanding\n\t\t\tcontent.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 0, transform: 'translateY(8px)' },\n\t\t\t\t\t{ opacity: 1, transform: 'translateY(0)' },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: config.durations.content,\n\t\t\t\t\teasing: config.easing.standard,\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\n\t\t// Icon rotation animation\n\t\tif (icon) {\n\t\t\tconst isExpanding = toState === 'expanded'\n\t\t\tconst isCollapsing = fromState === 'expanded' && toState === 'minimized'\n\n\t\t\tif (isExpanding || isCollapsing) {\n\t\t\t\ticon.animate(\n\t\t\t\t\t[\n\t\t\t\t\t\t{ transform: isExpanding ? 'rotate(0deg)' : 'rotate(180deg)' },\n\t\t\t\t\t\t{ transform: isExpanding ? 'rotate(180deg)' : 'rotate(0deg)' },\n\t\t\t\t\t],\n\t\t\t\t\t{\n\t\t\t\t\t\tduration: 250,\n\t\t\t\t\t\teasing: config.easing.emphasized,\n\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\treturn animations\n\t}\n\n\t// Get styles for a specific state\n\tprivate getStyleForState(state: BoatState): Keyframe {\n\t\tconst { shadows } = this.ANIMATION_CONFIG\n\t\tconst baseStyles = {\n\t\t\tmaxWidth: '300px',\n\t\t\tmaxHeight: 'auto',\n\t\t\tborderRadius: '16px',\n\t\t}\n\n\t\tconst stateStyles: Record<BoatState, Keyframe> = {\n\t\t\thidden: {\n\t\t\t\t...baseStyles,\n\t\t\t\topacity: '0',\n\t\t\t\tpointerEvents: 'none',\n\t\t\t\tboxShadow: 'none',\n\t\t\t\tbackdropFilter: 'none',\n\t\t\t},\n\t\t\tminimized: {\n\t\t\t\t...baseStyles,\n\t\t\t\topacity: '1',\n\t\t\t\tpointerEvents: 'auto',\n\t\t\t\tboxShadow: this.isLowered ? shadows.fabLowered : shadows.fab,\n\t\t\t\tbackdropFilter: 'none',\n\t\t\t},\n\t\t\texpanded: {\n\t\t\t\topacity: '1',\n\t\t\t\tpointerEvents: 'auto',\n\t\t\t\twidth: this.getResponsiveWidth(),\n\t\t\t\tmaxWidth: '100%',\n\t\t\t\tmaxHeight: '80vh',\n\t\t\t\tboxShadow: shadows.expanded,\n\t\t\t\tborderRadius: '8px 8px 0 0',\n\t\t\t\tbackdropFilter: 'blur(12px)',\n\t\t\t},\n\t\t}\n\n\t\treturn stateStyles[state] as Keyframe\n\t}\n\n\t// Calculate responsive width based on viewport\n\tprivate getResponsiveWidth(): string {\n\t\tif (typeof window === 'undefined') return '40vw'\n\n\t\tconst vw = window.innerWidth\n\t\tif (vw < 768) return 'calc(100vw - 32px)'\n\t\tif (vw < 1024) return '70vw'\n\t\tif (vw < 1280) return '60vw'\n\t\treturn '40vw'\n\t}\n\n\t// Update expanded width on window resize\n\tprivate updateExpandedWidth() {\n\t\tconst container = this.containerRef.value\n\t\tif (container && this.currentState === 'expanded') {\n\t\t\tcontainer.style.width = this.getResponsiveWidth()\n\t\t}\n\t}\n\n\tfirstUpdated() {\n\t\tthis.initializePosition()\n\t\tthis.applyInitialStyles()\n\t\tthis.updateContainerPosition()\n\t\tthis.setupDragPipeline()\n\n\t\t// Check for deprecated header slot usage\n\t\tconst hasHeaderSlot = this.querySelector('[slot=\"header\"]')\n\t\tif (hasHeaderSlot && !this.icon && !this.label) {\n\t\t\tconsole.warn(\n\t\t\t\t'[schmancy-boat] Using slot=\"header\" is deprecated. ' +\n\t\t\t\t\t'Please use the icon, label, and badge properties instead. ' +\n\t\t\t\t\t'Example: <schmancy-boat icon=\"info\" label=\"Title\" badge=\"5\">',\n\t\t\t)\n\t\t}\n\t}\n\n\t// Apply initial styles to elements\n\tprivate applyInitialStyles() {\n\t\tconst container = this.containerRef.value\n\t\tconst content = this.contentRef.value\n\t\tconst icon = this.iconRef.value\n\n\t\tif (container) {\n\t\t\tconst initialStyle = this.getStyleForState(this.currentState)\n\t\t\tObject.assign(container.style, initialStyle)\n\n\t\t\t// Safari compatibility for backdrop filter\n\t\t\tif ('webkitBackdropFilter' in container.style) {\n\t\t\t\t;(container.style as any).webkitBackdropFilter = initialStyle.backdropFilter\n\t\t\t}\n\t\t}\n\n\t\t// Set initial content opacity\n\t\tif (content) {\n\t\t\tcontent.style.opacity = this.isContentVisible ? '1' : '0'\n\t\t}\n\n\t\t// Set initial icon rotation\n\t\tif (icon && this.currentState === 'expanded') {\n\t\t\ticon.style.transform = 'rotate(180deg)'\n\t\t}\n\t}\n\n\t// Public method to toggle between minimized and expanded\n\ttoggleState() {\n\t\tconst newState = this.currentState === 'minimized' ? 'expanded' : 'minimized'\n\t\tthis.animateToState(newState)\n\t}\n\n\t// Public method to close (hide) the boat\n\tclose() {\n\t\tthis.animateToState('hidden')\n\t}\n\n\tprivate closeAndAddToNav() {\n\t\trace(\n\t\t\tthis.discover<any>('schmancy-navigation-rail'),\n\t\t\tthis.discover<any>('schmancy-navigation-bar'),\n\t\t\tthis.discover<any>('schmancy-nav-drawer'),\n\t\t\tthis.discover<any>('app-navigation-rail'),\n\t\t\tthis.discover<any>('app-navigation-bar'),\n\t\t\tthis.discover<any>('app-nav-drawer'),\n\t\t)\n\t\t\t.pipe(\n\t\t\t\ttake(1),\n\t\t\t\ttap(navComponent => {\n\t\t\t\t\tif (navComponent && typeof navComponent.addBoatItem === 'function') {\n\t\t\t\t\t\t// Use properties first, fall back to slot parsing\n\t\t\t\t\t\tconst icon =\n\t\t\t\t\t\t\tthis.icon ||\n\t\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\t\tconst headerSlot = this.querySelector('[slot=\"header\"]')\n\t\t\t\t\t\t\t\tconst iconElement = headerSlot?.querySelector('schmancy-icon')\n\t\t\t\t\t\t\t\treturn iconElement?.textContent?.trim() || 'widgets'\n\t\t\t\t\t\t\t})()\n\n\t\t\t\t\t\tconst label =\n\t\t\t\t\t\t\tthis.label ||\n\t\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\t\tconst headerSlot = this.querySelector('[slot=\"header\"]')\n\t\t\t\t\t\t\t\tlet title = headerSlot?.textContent?.trim() || 'Boat'\n\t\t\t\t\t\t\t\tif (icon && title.includes(icon)) {\n\t\t\t\t\t\t\t\t\ttitle = title.replace(icon, '').trim()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn title || this.id\n\t\t\t\t\t\t\t})()\n\n\t\t\t\t\t\t// Add the boat to navigation\n\t\t\t\t\t\tconst navItem = navComponent.addBoatItem({\n\t\t\t\t\t\t\tid: `boat-${this.id}`,\n\t\t\t\t\t\t\ttitle: label,\n\t\t\t\t\t\t\ticon: icon,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tif (navItem) {\n\t\t\t\t\t\t\t// Simple fade out then hide\n\t\t\t\t\t\t\tconst container = this.containerRef.value\n\t\t\t\t\t\t\tif (container) {\n\t\t\t\t\t\t\t\tcontainer\n\t\t\t\t\t\t\t\t\t.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 150, easing: 'ease-out', fill: 'forwards' })\n\t\t\t\t\t\t\t\t\t.finished.then(() => {\n\t\t\t\t\t\t\t\t\t\tthis.currentState = 'hidden'\n\t\t\t\t\t\t\t\t\t\tthis.isContentVisible = false\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.currentState = 'hidden'\n\t\t\t\t\t\t\t\tthis.isContentVisible = false\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Set up click listener to reopen - using RxJS pattern\n\t\t\t\t\t\t\tfromEvent(navItem, 'click')\n\t\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\t\ttap(() => (this.state = 'expanded')),\n\t\t\t\t\t\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.subscribe()\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// No nav component found, just hide\n\t\t\t\t\t\tthis.close()\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tprivate calculateDragPosition(\n\t\tclientX: number,\n\t\tclientY: number,\n\t\toffsetX: number,\n\t\toffsetY: number,\n\t\tinitialRect: DOMRect,\n\t): Position {\n\t\tconst targetLeft = clientX - offsetX\n\t\tconst targetTop = clientY - offsetY\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\t\tconst clampedLeft = Math.max(0, Math.min(targetLeft, vw - initialRect.width))\n\t\tconst clampedTop = Math.max(0, Math.min(targetTop, vh - initialRect.height))\n\n\t\tconst newX = this.anchor.includes('right') ? vw - (clampedLeft + initialRect.width) : clampedLeft\n\n\t\tconst newY = this.anchor.includes('bottom') ? vh - (clampedTop + initialRect.height) : clampedTop\n\n\t\treturn { x: Math.max(0, newX), y: Math.max(0, newY) }\n\t}\n\n\tprivate savePosition() {\n\t\tif (typeof window === 'undefined') return\n\n\t\tconst toSave: SavedPosition = {\n\t\t\tx: this.position.x,\n\t\t\ty: this.position.y,\n\t\t\tanchor: this.anchor,\n\t\t}\n\t\tconst key = `schmancy-boat-${this.id}`\n\t\tlocalStorage.setItem(key, JSON.stringify(toSave))\n\t\tconsole.log('💾 Saved position:', key, toSave)\n\t}\n\n\tprivate setupDragPipeline() {\n\t\tif (typeof window === 'undefined') return\n\n\t\tconst header = this.headerRef.value\n\t\tconst container = this.containerRef.value\n\t\tif (!header || !container) return\n\n\t\tlet hasDragged = false\n\t\tconst DRAG_THRESHOLD = 5\n\n\t\t// Merge mouse and touch start events\n\t\tmerge(\n\t\t\tfromEvent<MouseEvent>(header, 'mousedown').pipe(\n\t\t\t\tfilter(e => e.button === 0),\n\t\t\t\ttap(e => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t}),\n\t\t\t\tmap(e => ({\n\t\t\t\t\tclientX: e.clientX,\n\t\t\t\t\tclientY: e.clientY,\n\t\t\t\t\ttype: 'mouse' as const,\n\t\t\t\t})),\n\t\t\t),\n\t\t\tfromEvent<TouchEvent>(header, 'touchstart').pipe(\n\t\t\t\tmap(e => ({\n\t\t\t\t\tclientX: e.touches[0].clientX,\n\t\t\t\t\tclientY: e.touches[0].clientY,\n\t\t\t\t\ttype: 'touch' as const,\n\t\t\t\t})),\n\t\t\t),\n\t\t)\n\t\t\t.pipe(\n\t\t\t\tmap(({ clientX, clientY, type }) => {\n\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\thasDragged = false\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstartX: clientX,\n\t\t\t\t\t\tstartY: clientY,\n\t\t\t\t\t\toffsetX: clientX - rect.left,\n\t\t\t\t\t\toffsetY: clientY - rect.top,\n\t\t\t\t\t\tinitialRect: rect,\n\t\t\t\t\t\ttype,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.pipe(\n\t\t\t\tswitchMap(({ startX, startY, offsetX, offsetY, initialRect, type }) => {\n\t\t\t\t\tconst move$ =\n\t\t\t\t\t\ttype === 'mouse'\n\t\t\t\t\t\t\t? fromEvent<MouseEvent>(window, 'mousemove').pipe(map(e => ({ clientX: e.clientX, clientY: e.clientY })))\n\t\t\t\t\t\t\t: fromEvent<TouchEvent>(window, 'touchmove').pipe(\n\t\t\t\t\t\t\t\t\tmap(e => ({ clientX: e.touches[0].clientX, clientY: e.touches[0].clientY })),\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\tconst end$ = type === 'mouse' ? fromEvent(window, 'mouseup') : fromEvent(window, 'touchend')\n\n\t\t\t\t\treturn move$.pipe(\n\t\t\t\t\t\tmap(({ clientX, clientY }) => {\n\t\t\t\t\t\t\tconst deltaX = clientX - startX\n\t\t\t\t\t\t\tconst deltaY = clientY - startY\n\t\t\t\t\t\t\tconst distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY)\n\n\t\t\t\t\t\t\tif (distance > DRAG_THRESHOLD && !hasDragged) {\n\t\t\t\t\t\t\t\thasDragged = true\n\t\t\t\t\t\t\t\tthis.isDragging = true\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!hasDragged) return null\n\n\t\t\t\t\t\t\treturn this.calculateDragPosition(clientX, clientY, offsetX, offsetY, initialRect)\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tfilter(position => position !== null),\n\t\t\t\t\t\ttap(position => {\n\t\t\t\t\t\t\tif (position) {\n\t\t\t\t\t\t\t\tthis.position = position\n\t\t\t\t\t\t\t\tthis.updateContainerPosition()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t\ttakeUntil(end$),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t\tfinalize(() => {\n\t\t\t\t\tif (hasDragged) {\n\t\t\t\t\t\tthis.updateAnchor()\n\t\t\t\t\t\tthis.savePosition()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.toggleState()\n\t\t\t\t\t}\n\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\thasDragged = false\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\t// Update container position based on anchor and position values\n\tprivate updateContainerPosition() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\t// Reset all position styles\n\t\tcontainer.style.removeProperty('left')\n\t\tcontainer.style.removeProperty('right')\n\t\tcontainer.style.removeProperty('top')\n\t\tcontainer.style.removeProperty('bottom')\n\n\t\t// Apply new position based on anchor\n\t\tif (this.anchor.includes('right')) {\n\t\t\tcontainer.style.right = `${this.position.x}px`\n\t\t} else {\n\t\t\tcontainer.style.left = `${this.position.x}px`\n\t\t}\n\n\t\tif (this.anchor.includes('bottom')) {\n\t\t\tcontainer.style.bottom = `${this.position.y}px`\n\t\t} else {\n\t\t\tcontainer.style.top = `${this.position.y}px`\n\t\t}\n\t}\n\n\t// Update anchor based on current position\n\tprivate updateAnchor() {\n\t\tif (typeof window === 'undefined') return\n\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\tconst rect = container.getBoundingClientRect()\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\n\t\tconst isRight = rect.left > vw / 2\n\t\tconst isBottom = rect.top > vh / 2\n\n\t\tconst newAnchor = `${isBottom ? 'bottom' : 'top'}-${isRight ? 'right' : 'left'}` as typeof this.anchor\n\n\t\tif (newAnchor !== this.anchor) {\n\t\t\t// Calculate new position values for the new anchor\n\t\t\tif (isRight) {\n\t\t\t\tthis.position.x = vw - rect.right\n\t\t\t} else {\n\t\t\t\tthis.position.x = rect.left\n\t\t\t}\n\n\t\t\tif (isBottom) {\n\t\t\t\tthis.position.y = vh - rect.bottom\n\t\t\t} else {\n\t\t\t\tthis.position.y = rect.top\n\t\t\t}\n\n\t\t\tthis.anchor = newAnchor\n\t\t}\n\t}\n\n\t// Cleanup on component disconnect\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis.currentAnimation?.cancel()\n\t}\n\n\tprotected render(): unknown {\n\t\tconst surfaceElevation = this.currentState === 'minimized' ? (this.isLowered ? '1' : '3') : '4'\n\t\tconst isMinimized = this.currentState === 'minimized'\n\n\t\t// Set transform origin based on anchor for proper expansion\n\t\tconst transformOrigin = this.anchor.includes('bottom')\n\t\t\t? this.anchor.includes('right')\n\t\t\t\t? 'bottom right'\n\t\t\t\t: 'bottom left'\n\t\t\t: this.anchor.includes('right')\n\t\t\t\t? 'top right'\n\t\t\t\t: 'top left'\n\n\t\tconst containerClasses = {\n\t\t\t'z-50': true,\n\t\t\tfixed: true,\n\t\t\t'overflow-y-auto': true,\n\t\t\tflex: true,\n\t\t\t'flex-col': true,\n\t\t\t'select-none': true,\n\t\t\t'will-change-transform': true,\n\t\t\t'[contain:layout_style]': true,\n\t\t\t'[transform:translate3d(0,0,0)]': true,\n\t\t\t'[backface-visibility:hidden]': true,\n\t\t\t'transition-shadow': true,\n\t\t\t'opacity-95': this.isDragging,\n\t\t\t'shadow-[0_24px_48px_-8px_rgba(0,0,0,0.2),0_12px_24px_-4px_rgba(0,0,0,0.12)]': this.isDragging,\n\t\t}\n\n\t\treturn html`\n\t\t\t<div\n\t\t\t\tclass=${this.classMap(containerClasses)}\n\t\t\t\tstyle=\"transform-origin: ${transformOrigin}\"\n\t\t\t\t${ref(this.containerRef)}\n\t\t\t>\n\t\t\t\t<!-- Header section -->\n\t\t\t\t<section class=\"sticky top-0\">\n\t\t\t\t\t<schmancy-surface\n\t\t\t\t\t\televation=\"${surfaceElevation}\"\n\t\t\t\t\t\trounded=\"${isMinimized ? 'none' : 'top'}\"\n\t\t\t\t\t\ttype=\"containerLowest\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclass=\"group sticky top-0 px-3 py-2 flex items-center justify-between gap-3 ${this.isDragging\n\t\t\t\t\t\t\t\t? 'cursor-grabbing'\n\t\t\t\t\t\t\t\t: 'cursor-move'}\"\n\t\t\t\t\t\t\t${ref(this.headerRef)}\n\t\t\t\t\t\t\ttitle=\"Drag to move, double-click to toggle\"\n\t\t\t\t\t\t\t@dblclick=${(e: Event) => {\n\t\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\tthis.toggleState()\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!-- Drag handle indicator -->\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"flex items-center text-surface-onVariant opacity-40 transition-opacity duration-200 group-hover:opacity-100\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<schmancy-icon style=\"font-size: 20px\">drag_indicator</schmancy-icon>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<!-- Header content - use properties if provided, else fallback to slot -->\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"flex-1 min-w-fit items-center flex justify-start ${isMinimized ? 'cursor-pointer' : ''}\"\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t@dblclick=${(e: Event) => {\n\t\t\t\t\t\t\t\t\tif (isMinimized) {\n\t\t\t\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\tthis.state = 'expanded'\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\ttitle=\"${isMinimized ? 'Click to expand' : ''}\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t${this.icon || this.label\n\t\t\t\t\t\t\t\t\t? html`\n\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tclass=\"flex gap-2 items-center\">\n\t\t\t\t\t\t\t\t\t\t\t\t${this.icon ? html`<schmancy-icon>${this.icon}</schmancy-icon>` : ''}\n\t\t\t\t\t\t\t\t\t\t\t\t${this.label\n\t\t\t\t\t\t\t\t\t\t\t\t\t? html`<schmancy-typography type=\"title\" token=\"md\">${this.label}</schmancy-typography>`\n\t\t\t\t\t\t\t\t\t\t\t\t\t: ''}\n\t\t\t\t\t\t\t\t\t\t\t\t${this.badge !== undefined && this.badge !== null && this.badge !== ''\n\t\t\t\t\t\t\t\t\t\t\t\t\t? html`<schmancy-badge>${this.badge}</schmancy-badge>`\n\t\t\t\t\t\t\t\t\t\t\t\t\t: ''}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t`\n\t\t\t\t\t\t\t\t\t: html`<slot name=\"header\"></slot>`}\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<!-- Control buttons -->\n\t\t\t\t\t\t\t<div class=\"flex items-center gap-1 flex-shrink-0\">\n\t\t\t\t\t\t\t\t${isMinimized\n\t\t\t\t\t\t\t\t\t? html`\n\t\t\t\t\t\t\t\t\t\t\t<!-- Expand button (when minimized) -->\n\t\t\t\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"text\"\n\t\t\t\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\t\t\t\tthis.state = 'expanded'\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"Expand\"\n\t\t\t\t\t\t\t\t\t\t\t\t${ref(this.iconRef)}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\tfullscreen\n\t\t\t\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t\t\t\t`\n\t\t\t\t\t\t\t\t\t: html`\n\t\t\t\t\t\t\t\t\t\t\t<!-- Minimize button (when expanded) -->\n\t\t\t\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"filled tonal\"\n\t\t\t\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\t\t\t\tthis.state = 'minimized'\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"Minimize\"\n\t\t\t\t\t\t\t\t\t\t\t\t${ref(this.iconRef)}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\tclose_fullscreen\n\t\t\t\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t\t\t\t`}\n\n\t\t\t\t\t\t\t\t<!-- Close button -->\n\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\tthis.closeAndAddToNav()\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\ttitle=\"Close and add to navigation\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tremove\n\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</schmancy-surface>\n\t\t\t\t</section>\n\n\t\t\t\t<!-- Content section -->\n\t\t\t\t<schmancy-surface .hidden=${!this.isContentVisible} type=\"containerLow\" class=\"flex-1\" ${ref(this.contentRef)}>\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</schmancy-surface>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-boat': SchmancyBoat\n\t}\n}\n"],"names":["SchmancyBoat","$LitElement","css","super","arguments","this","id","containerRef","createRef","contentRef","iconRef","headerRef","ANIMATION_CONFIG","durations","expand","minimize","hide","content","easing","emphasized","decelerate","accelerate","standard","shadows","fab","fabLowered","expanded","currentState","isContentVisible","isAnimating","isLowered","isDragging","position","x","y","anchor","state","value","animateToState","lowered","requestUpdate","connectedCallback","window","fromEvent","pipe","takeUntil","disconnecting","subscribe","updateExpandedWidth","filter","e","key","tap","preventDefault","toggleState","close","initializePosition","saved","localStorage","getItem","parsed","JSON","parse","targetState","previousState","performTransition","dispatchEvent","CustomEvent","detail","bubbles","composed","fromState","toState","currentAnimation","cancel","animations","createAnimations","container","finished","icon","config","fromStyles","getStyleForState","toStyles","animate","duration","fill","opacity","transform","isExpanding","baseStyles","maxWidth","maxHeight","borderRadius","hidden","pointerEvents","boxShadow","backdropFilter","minimized","width","getResponsiveWidth","vw","innerWidth","style","applyInitialStyles","updateContainerPosition","setupDragPipeline","querySelector","label","initialStyle","Object","assign","webkitBackdropFilter","newState","race","discover","take","navComponent","addBoatItem","textContent","trim","title","includes","replace","navItem","then","clientX","clientY","offsetX","offsetY","initialRect","targetLeft","targetTop","vh","innerHeight","clampedLeft","Math","max","min","clampedTop","height","newX","newY","toSave","setItem","stringify","header","hasDragged","merge","button","stopPropagation","map","type","touches","rect","getBoundingClientRect","startX","startY","left","top","switchMap","move$","end$","deltaX","deltaY","sqrt","calculateDragPosition","finalize","updateAnchor","savePosition","removeProperty","right","bottom","isRight","isBottom","newAnchor","disconnectedCallback","render","surfaceElevation","isMinimized","transformOrigin","containerClasses","fixed","flex","html","classMap","ref","badge","closeAndAddToNav","__decorateClass","property","String","reflect","prototype","Boolean","customElement"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
- "use strict";const p=require("rxjs"),r=require("rxjs/operators");require("lit/directives/class-map.js"),require("lit/directives/style-map.js");const h=require("lit/decorators.js");require("./tailwind.mixin-DLCFOKfg.cjs");const w=require("./litElement.mixin-2hXm33ge.cjs"),l=require("lit"),u=require("lit/directives/ref.js");var S=Object.defineProperty,R=Object.getOwnPropertyDescriptor,d=(t,e,n,i)=>{for(var a,o=i>1?void 0:i?R(e,n):e,s=t.length-1;s>=0;s--)(a=t[s])&&(o=(i?a(e,n,o):a(o))||o);return i&&o&&S(e,n,o),o};exports.SchmancyBoat=class extends w.$LitElement(l.css`
1
+ "use strict";const p=require("rxjs"),r=require("rxjs/operators");require("lit/directives/class-map.js"),require("lit/directives/style-map.js");const h=require("lit/decorators.js");require("./tailwind.mixin-DLCFOKfg.cjs");const w=require("./litElement.mixin-2hXm33ge.cjs"),l=require("lit"),u=require("lit/directives/ref.js");var S=Object.defineProperty,$=Object.getOwnPropertyDescriptor,d=(t,e,a,i)=>{for(var n,o=i>1?void 0:i?$(e,a):e,s=t.length-1;s>=0;s--)(n=t[s])&&(o=(i?n(e,a,o):n(o))||o);return i&&o&&S(e,a,o),o};exports.SchmancyBoat=class extends w.$LitElement(l.css`
2
2
  :host {
3
3
  display: contents;
4
4
  }
5
- `){constructor(){super(...arguments),this.id="default",this.containerRef=u.createRef(),this.contentRef=u.createRef(),this.iconRef=u.createRef(),this.headerRef=u.createRef(),this.ANIMATION_CONFIG={durations:{expand:350,minimize:250,hide:200,content:300},easing:{emphasized:"cubic-bezier(0.2, 0.0, 0, 1.0)",decelerate:"cubic-bezier(0.05, 0.7, 0.1, 1.0)",accelerate:"cubic-bezier(0.3, 0.0, 0.8, 0.15)",standard:"cubic-bezier(0.4, 0.0, 0.2, 1)"},shadows:{fab:"0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12)",fabLowered:"0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12)",expanded:"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"}},this.currentState="minimized",this.isContentVisible=!1,this.isAnimating=!1,this.isLowered=!1,this.isDragging=!1,this.position={x:16,y:16},this.anchor="bottom-right"}get state(){return this.currentState}set state(t){this.isAnimating||t===this.currentState||this.animateToState(t)}get lowered(){return this.isLowered}set lowered(t){this.isLowered=t,this.requestUpdate()}connectedCallback(){super.connectedCallback(),typeof window<"u"&&(p.fromEvent(window,"resize").pipe(r.takeUntil(this.disconnecting)).subscribe(()=>{this.currentState==="expanded"&&this.updateExpandedWidth()}),p.fromEvent(window,"keydown").pipe(r.filter(t=>t.key==="Escape"&&this.currentState!=="hidden"),r.tap(t=>t.preventDefault()),r.takeUntil(this.disconnecting)).subscribe(()=>{this.currentState==="expanded"?this.toggleState():this.close()}))}initializePosition(){if(typeof window>"u")return;const t=localStorage.getItem(`schmancy-boat-${this.id}`);if(t)try{const e=JSON.parse(t);this.position={x:e.x,y:e.y},this.anchor=e.anchor}catch{}}async animateToState(t){if(this.isAnimating||t===this.currentState)return;const e=this.currentState;this.isAnimating=!0;try{await this.performTransition(e,t),this.currentState=t,this.isContentVisible=t==="expanded",this.dispatchEvent(new CustomEvent("toggle",{detail:t,bubbles:!0,composed:!0}))}catch{this.currentState=t,this.isContentVisible=t==="expanded"}finally{this.isAnimating=!1}}async performTransition(t,e){if(this.currentAnimation?.cancel(),!this.containerRef.value)return;e==="expanded"&&(this.isContentVisible=!0);const n=this.createAnimations(t,e);n.container&&(this.currentAnimation=n.container,await n.container.finished,e!=="expanded"&&(this.isContentVisible=!1))}createAnimations(t,e){const n=this.containerRef.value,i=this.contentRef.value,a=this.iconRef.value,o={};if(!n)return o;const s=this.ANIMATION_CONFIG,f=this.getStyleForState(t),m=this.getStyleForState(e);if(o.container=e==="expanded"?n.animate([f,m],{duration:s.durations.expand,easing:s.easing.decelerate,fill:"forwards"}):n.animate([f,m],{duration:e==="hidden"?s.durations.hide:s.durations.minimize,easing:s.easing.accelerate,fill:"forwards"}),i&&t==="expanded"&&e==="minimized"?i.animate([{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(-8px)"}],{duration:150,easing:s.easing.standard,fill:"forwards"}):i&&e==="expanded"&&i.animate([{opacity:0,transform:"translateY(8px)"},{opacity:1,transform:"translateY(0)"}],{duration:s.durations.content,easing:s.easing.standard,fill:"forwards"}),a){const y=e==="expanded";(y||t==="expanded"&&e==="minimized")&&a.animate([{transform:y?"rotate(0deg)":"rotate(180deg)"},{transform:y?"rotate(180deg)":"rotate(0deg)"}],{duration:250,easing:s.easing.emphasized,fill:"forwards"})}return o}getStyleForState(t){const{shadows:e}=this.ANIMATION_CONFIG,n={maxWidth:"300px",maxHeight:"auto",borderRadius:"16px"};return{hidden:{...n,opacity:"0",pointerEvents:"none",boxShadow:"none",backdropFilter:"none"},minimized:{...n,opacity:"1",pointerEvents:"auto",boxShadow:this.isLowered?e.fabLowered:e.fab,backdropFilter:"none"},expanded:{opacity:"1",pointerEvents:"auto",width:this.getResponsiveWidth(),maxWidth:"100%",maxHeight:"80vh",boxShadow:e.expanded,borderRadius:"8px 8px 0 0",backdropFilter:"blur(12px)"}}[t]}getResponsiveWidth(){if(typeof window>"u")return"40vw";const t=window.innerWidth;return t<768?"calc(100vw - 32px)":t<1024?"70vw":t<1280?"60vw":"40vw"}updateExpandedWidth(){const t=this.containerRef.value;t&&this.currentState==="expanded"&&(t.style.width=this.getResponsiveWidth())}firstUpdated(){this.initializePosition(),this.applyInitialStyles(),this.updateContainerPosition(),this.setupDragPipeline(),this.querySelector('[slot="header"]')&&!this.icon&&this.label}applyInitialStyles(){const t=this.containerRef.value,e=this.contentRef.value,n=this.iconRef.value;if(t){const i=this.getStyleForState(this.currentState);Object.assign(t.style,i),"webkitBackdropFilter"in t.style&&(t.style.webkitBackdropFilter=i.backdropFilter)}e&&(e.style.opacity=this.isContentVisible?"1":"0"),n&&this.currentState==="expanded"&&(n.style.transform="rotate(180deg)")}toggleState(){const t=this.currentState==="minimized"?"expanded":"minimized";this.animateToState(t)}close(){this.animateToState("hidden")}closeAndAddToNav(){p.race(this.discover("schmancy-navigation-rail"),this.discover("schmancy-navigation-bar"),this.discover("schmancy-nav-drawer"),this.discover("app-navigation-rail"),this.discover("app-navigation-bar"),this.discover("app-nav-drawer")).pipe(r.take(1),r.tap(t=>{if(t&&typeof t.addBoatItem=="function"){const e=this.icon||(this.querySelector('[slot="header"]')?.querySelector("schmancy-icon")?.textContent?.trim()||"widgets"),n=this.label||(()=>{let o=this.querySelector('[slot="header"]')?.textContent?.trim()||"Boat";return o.includes(e)&&(o=o.replace(e,"").trim()),o||this.id})(),i=t.addBoatItem({id:`boat-${this.id}`,title:n,icon:e});if(i){const a=this.containerRef.value;a?a.animate([{opacity:1},{opacity:0}],{duration:150,easing:"ease-out",fill:"forwards"}).finished.then(()=>{this.currentState="hidden",this.isContentVisible=!1}):(this.currentState="hidden",this.isContentVisible=!1),p.fromEvent(i,"click").pipe(r.tap(()=>this.state="expanded"),r.takeUntil(this.disconnecting)).subscribe()}}else this.close()})).subscribe()}calculateDragPosition(t,e,n,i,a){const o=t-n,s=e-i,f=window.innerWidth,m=window.innerHeight,y=Math.max(0,Math.min(o,f-a.width)),g=Math.max(0,Math.min(s,m-a.height)),c=this.anchor.includes("right")?f-(y+a.width):y,b=this.anchor.includes("bottom")?m-(g+a.height):g;return{x:Math.max(0,c),y:Math.max(0,b)}}savePosition(){if(typeof window>"u")return;const t={x:this.position.x,y:this.position.y,anchor:this.anchor},e=`schmancy-boat-${this.id}`;localStorage.setItem(e,JSON.stringify(t))}setupDragPipeline(){if(typeof window>"u")return;const t=this.headerRef.value,e=this.containerRef.value;if(!t||!e)return;let n=!1;p.merge(p.fromEvent(t,"mousedown").pipe(r.filter(i=>i.button===0),r.tap(i=>{i.preventDefault(),i.stopPropagation()}),r.map(i=>({clientX:i.clientX,clientY:i.clientY,type:"mouse"}))),p.fromEvent(t,"touchstart").pipe(r.map(i=>({clientX:i.touches[0].clientX,clientY:i.touches[0].clientY,type:"touch"})))).pipe(r.map(({clientX:i,clientY:a,type:o})=>{const s=e.getBoundingClientRect();return n=!1,{startX:i,startY:a,offsetX:i-s.left,offsetY:a-s.top,initialRect:s,type:o}})).pipe(r.switchMap(({startX:i,startY:a,offsetX:o,offsetY:s,initialRect:f,type:m})=>{const y=m==="mouse"?p.fromEvent(window,"mousemove").pipe(r.map(c=>({clientX:c.clientX,clientY:c.clientY}))):p.fromEvent(window,"touchmove").pipe(r.map(c=>({clientX:c.touches[0].clientX,clientY:c.touches[0].clientY}))),g=m==="mouse"?p.fromEvent(window,"mouseup"):p.fromEvent(window,"touchend");return y.pipe(r.map(({clientX:c,clientY:b})=>{const x=c-i,v=b-a;return Math.sqrt(x*x+v*v)>5&&!n&&(n=!0,this.isDragging=!0),n?this.calculateDragPosition(c,b,o,s,f):null}),r.filter(c=>c!==null),r.tap(c=>{c&&(this.position=c,this.updateContainerPosition())}),r.takeUntil(g))}),r.finalize(()=>{n?(this.updateAnchor(),this.savePosition()):this.toggleState(),this.isDragging=!1,n=!1}),r.takeUntil(this.disconnecting)).subscribe()}updateContainerPosition(){const t=this.containerRef.value;t&&(t.style.removeProperty("left"),t.style.removeProperty("right"),t.style.removeProperty("top"),t.style.removeProperty("bottom"),this.anchor.includes("right")?t.style.right=`${this.position.x}px`:t.style.left=`${this.position.x}px`,this.anchor.includes("bottom")?t.style.bottom=`${this.position.y}px`:t.style.top=`${this.position.y}px`)}updateAnchor(){if(typeof window>"u")return;const t=this.containerRef.value;if(!t)return;const e=t.getBoundingClientRect(),n=window.innerWidth,i=window.innerHeight,a=e.left>n/2,o=e.top>i/2,s=`${o?"bottom":"top"}-${a?"right":"left"}`;s!==this.anchor&&(this.position.x=a?n-e.right:e.left,this.position.y=o?i-e.bottom:e.top,this.anchor=s)}disconnectedCallback(){super.disconnectedCallback(),this.currentAnimation?.cancel()}render(){const t=this.currentState==="minimized"?this.isLowered?"1":"3":"4",e=this.currentState==="minimized",n=this.anchor.includes("bottom")?this.anchor.includes("right")?"bottom right":"bottom left":this.anchor.includes("right")?"top right":"top left",i={"z-50":!0,fixed:!0,"overflow-y-auto":!0,flex:!0,"flex-col":!0,"select-none":!0,"will-change-transform":!0,"[contain:layout_style]":!0,"[transform:translate3d(0,0,0)]":!0,"[backface-visibility:hidden]":!0,"transition-shadow":!0,"opacity-95":this.isDragging,"shadow-[0_24px_48px_-8px_rgba(0,0,0,0.2),0_12px_24px_-4px_rgba(0,0,0,0.12)]":this.isDragging};return l.html`
5
+ `){constructor(){super(...arguments),this.id="default",this.containerRef=u.createRef(),this.contentRef=u.createRef(),this.iconRef=u.createRef(),this.headerRef=u.createRef(),this.ANIMATION_CONFIG={durations:{expand:350,minimize:250,hide:200,content:300},easing:{emphasized:"cubic-bezier(0.2, 0.0, 0, 1.0)",decelerate:"cubic-bezier(0.05, 0.7, 0.1, 1.0)",accelerate:"cubic-bezier(0.3, 0.0, 0.8, 0.15)",standard:"cubic-bezier(0.4, 0.0, 0.2, 1)"},shadows:{fab:"0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12)",fabLowered:"0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12)",expanded:"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"}},this.currentState="minimized",this.isContentVisible=!1,this.isAnimating=!1,this.isLowered=!1,this.isDragging=!1,this.position={x:16,y:16},this.anchor="bottom-right"}get state(){return this.currentState}set state(t){this.isAnimating||t===this.currentState||this.animateToState(t)}get lowered(){return this.isLowered}set lowered(t){this.isLowered=t,this.requestUpdate()}connectedCallback(){super.connectedCallback(),typeof window<"u"&&(p.fromEvent(window,"resize").pipe(r.takeUntil(this.disconnecting)).subscribe(()=>{this.currentState==="expanded"&&this.updateExpandedWidth()}),p.fromEvent(window,"keydown").pipe(r.filter(t=>t.key==="Escape"&&this.currentState!=="hidden"),r.tap(t=>t.preventDefault()),r.takeUntil(this.disconnecting)).subscribe(()=>{this.currentState==="expanded"?this.toggleState():this.close()}))}initializePosition(){if(typeof window>"u")return;const t=localStorage.getItem(`schmancy-boat-${this.id}`);if(t)try{const e=JSON.parse(t);this.position={x:e.x,y:e.y},this.anchor=e.anchor}catch{}}async animateToState(t){if(this.isAnimating||t===this.currentState)return;const e=this.currentState;this.isAnimating=!0;try{await this.performTransition(e,t),this.currentState=t,this.isContentVisible=t==="expanded",this.dispatchEvent(new CustomEvent("toggle",{detail:t,bubbles:!0,composed:!0}))}catch{this.currentState=t,this.isContentVisible=t==="expanded"}finally{this.isAnimating=!1}}async performTransition(t,e){if(this.currentAnimation?.cancel(),!this.containerRef.value)return;e==="expanded"&&(this.isContentVisible=!0);const a=this.createAnimations(t,e);a.container&&(this.currentAnimation=a.container,await a.container.finished,e!=="expanded"&&(this.isContentVisible=!1))}createAnimations(t,e){const a=this.containerRef.value,i=this.contentRef.value,n=this.iconRef.value,o={};if(!a)return o;const s=this.ANIMATION_CONFIG,f=this.getStyleForState(t),m=this.getStyleForState(e);if(o.container=e==="expanded"?a.animate([f,m],{duration:s.durations.expand,easing:s.easing.decelerate,fill:"forwards"}):a.animate([f,m],{duration:e==="hidden"?s.durations.hide:s.durations.minimize,easing:s.easing.accelerate,fill:"forwards"}),i&&t==="expanded"&&e==="minimized"?i.animate([{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(-8px)"}],{duration:150,easing:s.easing.standard,fill:"forwards"}):i&&e==="expanded"&&i.animate([{opacity:0,transform:"translateY(8px)"},{opacity:1,transform:"translateY(0)"}],{duration:s.durations.content,easing:s.easing.standard,fill:"forwards"}),n){const y=e==="expanded";(y||t==="expanded"&&e==="minimized")&&n.animate([{transform:y?"rotate(0deg)":"rotate(180deg)"},{transform:y?"rotate(180deg)":"rotate(0deg)"}],{duration:250,easing:s.easing.emphasized,fill:"forwards"})}return o}getStyleForState(t){const{shadows:e}=this.ANIMATION_CONFIG,a={maxWidth:"300px",maxHeight:"auto",borderRadius:"16px"};return{hidden:{...a,opacity:"0",pointerEvents:"none",boxShadow:"none",backdropFilter:"none"},minimized:{...a,opacity:"1",pointerEvents:"auto",boxShadow:this.isLowered?e.fabLowered:e.fab,backdropFilter:"none"},expanded:{opacity:"1",pointerEvents:"auto",width:this.getResponsiveWidth(),maxWidth:"100%",maxHeight:"80vh",boxShadow:e.expanded,borderRadius:"8px 8px 0 0",backdropFilter:"blur(12px)"}}[t]}getResponsiveWidth(){if(typeof window>"u")return"40vw";const t=window.innerWidth;return t<768?"calc(100vw - 32px)":t<1024?"70vw":t<1280?"60vw":"40vw"}updateExpandedWidth(){const t=this.containerRef.value;t&&this.currentState==="expanded"&&(t.style.width=this.getResponsiveWidth())}firstUpdated(){this.initializePosition(),this.applyInitialStyles(),this.updateContainerPosition(),this.setupDragPipeline(),this.querySelector('[slot="header"]')&&!this.icon&&this.label}applyInitialStyles(){const t=this.containerRef.value,e=this.contentRef.value,a=this.iconRef.value;if(t){const i=this.getStyleForState(this.currentState);Object.assign(t.style,i),"webkitBackdropFilter"in t.style&&(t.style.webkitBackdropFilter=i.backdropFilter)}e&&(e.style.opacity=this.isContentVisible?"1":"0"),a&&this.currentState==="expanded"&&(a.style.transform="rotate(180deg)")}toggleState(){const t=this.currentState==="minimized"?"expanded":"minimized";this.animateToState(t)}close(){this.animateToState("hidden")}closeAndAddToNav(){p.race(this.discover("schmancy-navigation-rail"),this.discover("schmancy-navigation-bar"),this.discover("schmancy-nav-drawer"),this.discover("app-navigation-rail"),this.discover("app-navigation-bar"),this.discover("app-nav-drawer")).pipe(r.take(1),r.tap(t=>{if(t&&typeof t.addBoatItem=="function"){const e=this.icon||(this.querySelector('[slot="header"]')?.querySelector("schmancy-icon")?.textContent?.trim()||"widgets"),a=this.label||(()=>{let o=this.querySelector('[slot="header"]')?.textContent?.trim()||"Boat";return o.includes(e)&&(o=o.replace(e,"").trim()),o||this.id})(),i=t.addBoatItem({id:`boat-${this.id}`,title:a,icon:e});if(i){const n=this.containerRef.value;n?n.animate([{opacity:1},{opacity:0}],{duration:150,easing:"ease-out",fill:"forwards"}).finished.then(()=>{this.currentState="hidden",this.isContentVisible=!1}):(this.currentState="hidden",this.isContentVisible=!1),p.fromEvent(i,"click").pipe(r.tap(()=>this.state="expanded"),r.takeUntil(this.disconnecting)).subscribe()}}else this.close()})).subscribe()}calculateDragPosition(t,e,a,i,n){const o=t-a,s=e-i,f=window.innerWidth,m=window.innerHeight,y=Math.max(0,Math.min(o,f-n.width)),g=Math.max(0,Math.min(s,m-n.height)),c=this.anchor.includes("right")?f-(y+n.width):y,x=this.anchor.includes("bottom")?m-(g+n.height):g;return{x:Math.max(0,c),y:Math.max(0,x)}}savePosition(){if(typeof window>"u")return;const t={x:this.position.x,y:this.position.y,anchor:this.anchor},e=`schmancy-boat-${this.id}`;localStorage.setItem(e,JSON.stringify(t))}setupDragPipeline(){if(typeof window>"u")return;const t=this.headerRef.value,e=this.containerRef.value;if(!t||!e)return;let a=!1;p.merge(p.fromEvent(t,"mousedown").pipe(r.filter(i=>i.button===0),r.tap(i=>{i.preventDefault(),i.stopPropagation()}),r.map(i=>({clientX:i.clientX,clientY:i.clientY,type:"mouse"}))),p.fromEvent(t,"touchstart").pipe(r.map(i=>({clientX:i.touches[0].clientX,clientY:i.touches[0].clientY,type:"touch"})))).pipe(r.map(({clientX:i,clientY:n,type:o})=>{const s=e.getBoundingClientRect();return a=!1,{startX:i,startY:n,offsetX:i-s.left,offsetY:n-s.top,initialRect:s,type:o}})).pipe(r.switchMap(({startX:i,startY:n,offsetX:o,offsetY:s,initialRect:f,type:m})=>{const y=m==="mouse"?p.fromEvent(window,"mousemove").pipe(r.map(c=>({clientX:c.clientX,clientY:c.clientY}))):p.fromEvent(window,"touchmove").pipe(r.map(c=>({clientX:c.touches[0].clientX,clientY:c.touches[0].clientY}))),g=m==="mouse"?p.fromEvent(window,"mouseup"):p.fromEvent(window,"touchend");return y.pipe(r.map(({clientX:c,clientY:x})=>{const b=c-i,v=x-n;return Math.sqrt(b*b+v*v)>5&&!a&&(a=!0,this.isDragging=!0),a?this.calculateDragPosition(c,x,o,s,f):null}),r.filter(c=>c!==null),r.tap(c=>{c&&(this.position=c,this.updateContainerPosition())}),r.takeUntil(g))}),r.finalize(()=>{a?(this.updateAnchor(),this.savePosition()):this.toggleState(),this.isDragging=!1,a=!1}),r.takeUntil(this.disconnecting)).subscribe()}updateContainerPosition(){const t=this.containerRef.value;t&&(t.style.removeProperty("left"),t.style.removeProperty("right"),t.style.removeProperty("top"),t.style.removeProperty("bottom"),this.anchor.includes("right")?t.style.right=`${this.position.x}px`:t.style.left=`${this.position.x}px`,this.anchor.includes("bottom")?t.style.bottom=`${this.position.y}px`:t.style.top=`${this.position.y}px`)}updateAnchor(){if(typeof window>"u")return;const t=this.containerRef.value;if(!t)return;const e=t.getBoundingClientRect(),a=window.innerWidth,i=window.innerHeight,n=e.left>a/2,o=e.top>i/2,s=`${o?"bottom":"top"}-${n?"right":"left"}`;s!==this.anchor&&(this.position.x=n?a-e.right:e.left,this.position.y=o?i-e.bottom:e.top,this.anchor=s)}disconnectedCallback(){super.disconnectedCallback(),this.currentAnimation?.cancel()}render(){const t=this.currentState==="minimized"?this.isLowered?"1":"3":"4",e=this.currentState==="minimized",a=this.anchor.includes("bottom")?this.anchor.includes("right")?"bottom right":"bottom left":this.anchor.includes("right")?"top right":"top left",i={"z-50":!0,fixed:!0,"overflow-y-auto":!0,flex:!0,"flex-col":!0,"select-none":!0,"will-change-transform":!0,"[contain:layout_style]":!0,"[transform:translate3d(0,0,0)]":!0,"[backface-visibility:hidden]":!0,"transition-shadow":!0,"opacity-95":this.isDragging,"shadow-[0_24px_48px_-8px_rgba(0,0,0,0.2),0_12px_24px_-4px_rgba(0,0,0,0.12)]":this.isDragging};return l.html`
6
6
  <div
7
7
  class=${this.classMap(i)}
8
- style="transform-origin: ${n}"
8
+ style="transform-origin: ${a}"
9
9
  ${u.ref(this.containerRef)}
10
10
  >
11
11
  <!-- Header section -->
@@ -19,7 +19,7 @@
19
19
  class="group sticky top-0 px-3 py-2 flex items-center justify-between gap-3 ${this.isDragging?"cursor-grabbing":"cursor-move"}"
20
20
  ${u.ref(this.headerRef)}
21
21
  title="Drag to move, double-click to toggle"
22
- @dblclick=${a=>{a.preventDefault(),a.stopPropagation(),this.toggleState()}}
22
+ @dblclick=${n=>{n.preventDefault(),n.stopPropagation(),this.toggleState()}}
23
23
  >
24
24
  <!-- Drag handle indicator -->
25
25
  <div
@@ -29,9 +29,14 @@
29
29
  </div>
30
30
 
31
31
  <!-- Header content - use properties if provided, else fallback to slot -->
32
- <div class="flex-1 min-w-fit items-center flex justify-start">
32
+ <div
33
+ class="flex-1 min-w-fit items-center flex justify-start ${e?"cursor-pointer":""}"
34
+
35
+ @dblclick=${n=>{e&&(n.preventDefault(),n.stopPropagation(),this.state="expanded")}}
36
+ title="${e?"Click to expand":""}"
37
+ >
33
38
  ${this.icon||this.label?l.html`
34
- <div
39
+ <div
35
40
  class="flex gap-2 items-center">
36
41
  ${this.icon?l.html`<schmancy-icon>${this.icon}</schmancy-icon>`:""}
37
42
  ${this.label?l.html`<schmancy-typography type="title" token="md">${this.label}</schmancy-typography>`:""}
@@ -47,7 +52,7 @@
47
52
  <schmancy-icon-button
48
53
  size="sm"
49
54
  variant="text"
50
- @click=${a=>{a.stopPropagation(),this.state="expanded"}}
55
+ @click=${n=>{n.stopPropagation(),this.state="expanded"}}
51
56
  title="Expand"
52
57
  ${u.ref(this.iconRef)}
53
58
  >
@@ -58,7 +63,7 @@
58
63
  <schmancy-icon-button
59
64
  size="sm"
60
65
  variant="filled tonal"
61
- @click=${a=>{a.stopPropagation(),this.state="minimized"}}
66
+ @click=${n=>{n.stopPropagation(),this.state="minimized"}}
62
67
  title="Minimize"
63
68
  ${u.ref(this.iconRef)}
64
69
  >
@@ -69,7 +74,7 @@
69
74
  <!-- Close button -->
70
75
  <schmancy-icon-button
71
76
  size="sm"
72
- @click=${a=>{a.stopPropagation(),this.closeAndAddToNav()}}
77
+ @click=${n=>{n.stopPropagation(),this.closeAndAddToNav()}}
73
78
  title="Close and add to navigation"
74
79
  >
75
80
  remove
@@ -85,4 +90,4 @@
85
90
  </schmancy-surface>
86
91
  </div>
87
92
  `}},d([h.property({type:String,reflect:!0})],exports.SchmancyBoat.prototype,"state",1),d([h.property({type:String})],exports.SchmancyBoat.prototype,"id",2),d([h.property({type:Boolean,reflect:!0})],exports.SchmancyBoat.prototype,"lowered",1),d([h.property({type:String})],exports.SchmancyBoat.prototype,"icon",2),d([h.property({type:String})],exports.SchmancyBoat.prototype,"label",2),d([h.property()],exports.SchmancyBoat.prototype,"badge",2),d([h.state()],exports.SchmancyBoat.prototype,"currentState",2),d([h.state()],exports.SchmancyBoat.prototype,"isContentVisible",2),d([h.state()],exports.SchmancyBoat.prototype,"isAnimating",2),d([h.state()],exports.SchmancyBoat.prototype,"isLowered",2),d([h.state()],exports.SchmancyBoat.prototype,"isDragging",2),d([h.state()],exports.SchmancyBoat.prototype,"position",2),d([h.state()],exports.SchmancyBoat.prototype,"anchor",2),exports.SchmancyBoat=d([h.customElement("schmancy-boat")],exports.SchmancyBoat);
88
- //# sourceMappingURL=boat-DpHPXHCG.cjs.map
93
+ //# sourceMappingURL=boat-DsaSCYS-.cjs.map