heroshot 0.0.6 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,33 +1,95 @@
1
1
  <p align="center">
2
- <img src="https://github.com/omachala/heroshot/blob/main/assets/icon-128.svg?raw=true" alt="heroshot logo" width="128" height="128">
2
+ <img src="https://github.com/omachala/heroshot/blob/main/assets/logo.svg?raw=true" alt="heroshot logo" height="80">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">heroshot</h1>
6
6
 
7
7
  <p align="center">
8
- <strong>Keep your product screenshots always up to date.</strong><br>
9
- No more stale images in docs, landing pages, or blog posts.
8
+ <strong>Screenshot automation for docs, landing pages, and more.</strong><br>
9
+ Point and click to define. One command to regenerate when your UI changes.
10
10
  </p>
11
11
 
12
- **How it works:**
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/heroshot"><img src="https://img.shields.io/npm/v/heroshot" alt="npm"></a>
14
+ <a href="https://heroshot.sh"><img src="https://img.shields.io/badge/docs-heroshot.sh-blue" alt="docs"></a>
15
+ </p>
16
+
17
+ <p align="center">
18
+ <img src="https://github.com/omachala/heroshot/blob/main/toolbar/tests/snapshots/manage-screenshots.test.ts/after-rename.png?raw=true" alt="heroshot toolbar demo" width="800">
19
+ </p>
20
+
21
+ ## Get Started
13
22
 
14
- 1. Run `npx heroshot` - opens a browser with a visual picker
23
+ ```bash
24
+ npx heroshot
25
+ ```
26
+
27
+ **First run** opens an interactive browser:
28
+
29
+ 1. Navigate to any URL
15
30
  2. Click on elements you want to screenshot
16
- 3. Close browser - screenshots are captured automatically
31
+ 3. Name your screenshots and adjust settings
32
+ 4. Close the browser when done
33
+
34
+ **Subsequent runs** regenerate all screenshots headlessly:
35
+
36
+ ```bash
37
+ npx heroshot
38
+ ```
39
+
40
+ **Reconfigure** anytime by running:
17
41
 
18
- **Why heroshot?**
42
+ ```bash
43
+ npx heroshot config
44
+ ```
45
+
46
+ ## Why heroshot?
19
47
 
20
48
  - **Visual picker** - Point and click to select elements, no DevTools needed
21
49
  - **Zero config** - No YAML to write, config is auto-generated
22
50
  - **Element-precise** - Capture specific UI components, not just full pages
23
51
  - **One command** - Regenerate all screenshots anytime your UI changes
52
+ - **CI ready** - Automate updates with encrypted session support
24
53
 
25
- ---
54
+ ## Automated Updates
55
+
56
+ Run heroshot in CI to keep screenshots always current. See the [full guide](https://heroshot.sh/guide/automated-updates).
57
+
58
+ **Quick setup:**
59
+
60
+ 1. Get your session key: `npx heroshot session-key`
61
+ 2. Add as GitHub secret: `gh secret set HEROSHOT_SESSION_KEY`
62
+ 3. Create workflow:
26
63
 
27
- [![npm](https://img.shields.io/npm/v/heroshot)](https://www.npmjs.com/package/heroshot)
64
+ ```yaml
65
+ # .github/workflows/heroshot.yaml
66
+ name: Heroshot
67
+
68
+ on:
69
+ workflow_dispatch:
70
+
71
+ jobs:
72
+ screenshots:
73
+ runs-on: ubuntu-latest
74
+ steps:
75
+ - uses: actions/checkout@v4
76
+ - uses: actions/setup-node@v4
77
+ with:
78
+ node-version: 20
79
+ - run: npx heroshot --session-key=${{ secrets.HEROSHOT_SESSION_KEY }}
80
+ - run: |
81
+ git config user.name "github-actions[bot]"
82
+ git config user.email "github-actions[bot]@users.noreply.github.com"
83
+ git add heroshots/
84
+ git diff --staged --quiet || git commit -m "chore: update screenshots" && git push
85
+ ```
86
+
87
+ ---
28
88
 
29
89
  **Status:** Early alpha. [See releases](https://github.com/omachala/heroshot/releases) for current version.
30
90
 
91
+ **Docs:** [heroshot.sh](https://heroshot.sh)
92
+
31
93
  ## License
32
94
 
33
95
  MIT
package/dist/cli.js CHANGED
@@ -46,7 +46,9 @@ var screenshotSchema = z.object({
46
46
  /** Padding to expand capture area beyond element bounds */
47
47
  padding: paddingSchema.optional(),
48
48
  /** Scroll position to restore when capturing */
49
- scroll: scrollPositionSchema.optional()
49
+ scroll: scrollPositionSchema.optional(),
50
+ /** Fill padding area with detected background color */
51
+ maskPadding: z.boolean().optional()
50
52
  });
51
53
  var browserSchema = z.object({
52
54
  viewport: viewportSchema.optional(),
@@ -102,7 +104,7 @@ To use heroshot in CI, add your session key as a secret:
102
104
  - run: npx heroshot --session-key=\${{ secrets.HEROSHOT_SESSION_KEY }}
103
105
  \`\`\`
104
106
 
105
- To get your session key, run: \`heroshot session-key\`
107
+ To get your session key, run: \`npx heroshot session-key\`
106
108
 
107
109
  Learn more: https://heroshot.sh/docs
108
110
  `;
@@ -371,9 +373,11 @@ async function setup() {
371
373
  // Use index as fallback createdAt for existing items (older items first)
372
374
  createdAt: index,
373
375
  ...screenshot.padding && { padding: screenshot.padding },
374
- ...screenshot.scroll && { scroll: screenshot.scroll }
376
+ ...screenshot.scroll && { scroll: screenshot.scroll },
377
+ ...screenshot.maskPadding && { maskPadding: screenshot.maskPadding }
375
378
  }));
376
379
  const newlyAddedIds = /* @__PURE__ */ new Set();
380
+ const deletedIds = /* @__PURE__ */ new Set();
377
381
  let pendingJob = null;
378
382
  let selectedId = null;
379
383
  let sidebarExpanded = false;
@@ -395,6 +399,16 @@ async function setup() {
395
399
  }
396
400
  break;
397
401
  }
402
+ case "screenshot-removed": {
403
+ const index = allScreenshots.findIndex((item) => item.id === event.id);
404
+ if (index !== -1) {
405
+ const [removed] = allScreenshots.splice(index, 1);
406
+ deletedIds.add(event.id);
407
+ newlyAddedIds.delete(event.id);
408
+ log.verbose(`Removed: ${removed?.name ?? event.id}`);
409
+ }
410
+ break;
411
+ }
398
412
  case "screenshot-selected": {
399
413
  const [currentPage] = context.pages();
400
414
  if (!currentPage) break;
@@ -475,7 +489,8 @@ async function setup() {
475
489
  selector: element.selector,
476
490
  filename,
477
491
  ...element.padding && { padding: element.padding },
478
- ...element.scroll && { scroll: element.scroll }
492
+ ...element.scroll && { scroll: element.scroll },
493
+ ...element.maskPadding && { maskPadding: element.maskPadding }
479
494
  };
480
495
  const existingIndex = latestConfig.screenshots.findIndex((item) => item.id === element.id);
481
496
  if (existingIndex === -1) {
@@ -486,13 +501,20 @@ async function setup() {
486
501
  log.verbose(`~ ${element.name} (updated)`);
487
502
  }
488
503
  }
504
+ for (const id of deletedIds) {
505
+ const index = latestConfig.screenshots.findIndex((item) => item.id === id);
506
+ if (index !== -1) {
507
+ const [removed] = latestConfig.screenshots.splice(index, 1);
508
+ log.verbose(`- ${removed?.name ?? id} (deleted)`);
509
+ }
510
+ }
489
511
  saveConfig(configPath, latestConfig);
490
512
  log.verbose(`Config saved: ${configPath}`);
491
513
  if (isNewKey) {
492
514
  log("");
493
515
  log("Session encrypted and saved to .heroshot/session.enc");
494
516
  log("");
495
- log("To print your session key, run: heroshot session-key");
517
+ log("To print your session key, run: npx heroshot session-key");
496
518
  log("");
497
519
  log("For CI, add HEROSHOT_SESSION_KEY as a repository secret.");
498
520
  }
@@ -502,6 +524,84 @@ async function setup() {
502
524
  // src/sync.ts
503
525
  import { existsSync as existsSync3, mkdirSync as mkdirSync3 } from "fs";
504
526
  import path4 from "path";
527
+ var GET_BACKGROUND_COLOR_SCRIPT = String.raw`
528
+ (element) => {
529
+ let current = element.parentElement;
530
+ while (current) {
531
+ const style = globalThis.getComputedStyle(current);
532
+ const bgColor = style.backgroundColor;
533
+ if (bgColor && bgColor !== 'transparent' && !bgColor.startsWith('rgba(0, 0, 0, 0)')) {
534
+ const rgbMatch = bgColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
535
+ if (rgbMatch && rgbMatch[1] && rgbMatch[2] && rgbMatch[3]) {
536
+ const red = parseInt(rgbMatch[1], 10);
537
+ const green = parseInt(rgbMatch[2], 10);
538
+ const blue = parseInt(rgbMatch[3], 10);
539
+ return '#' + red.toString(16).padStart(2, '0') + green.toString(16).padStart(2, '0') + blue.toString(16).padStart(2, '0');
540
+ }
541
+ return bgColor;
542
+ }
543
+ const root = current.getRootNode();
544
+ if (root instanceof ShadowRoot) {
545
+ current = root.host;
546
+ } else {
547
+ current = current.parentElement;
548
+ }
549
+ }
550
+ return '#ffffff';
551
+ }
552
+ `;
553
+ async function injectPaddingMask(page, element, padding, bgColor) {
554
+ const box = await element.boundingBox();
555
+ if (!box) return;
556
+ await page.evaluate(`
557
+ (() => {
558
+ const box = ${JSON.stringify(box)};
559
+ const padding = ${JSON.stringify(padding)};
560
+ const bgColor = ${JSON.stringify(bgColor)};
561
+ const maskId = 'heroshot-padding-mask';
562
+
563
+ // Remove any existing mask
564
+ document.querySelector('#' + maskId)?.remove();
565
+
566
+ const container = document.createElement('div');
567
+ container.id = maskId;
568
+ container.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:2147483646;';
569
+
570
+ // Top mask
571
+ if (padding.top > 0) {
572
+ const top = document.createElement('div');
573
+ top.style.cssText = 'position:absolute;top:' + (box.y - padding.top) + 'px;left:' + (box.x - padding.left) + 'px;width:' + (box.width + padding.left + padding.right) + 'px;height:' + padding.top + 'px;background:' + bgColor + ';';
574
+ container.append(top);
575
+ }
576
+
577
+ // Bottom mask
578
+ if (padding.bottom > 0) {
579
+ const bottom = document.createElement('div');
580
+ bottom.style.cssText = 'position:absolute;top:' + (box.y + box.height) + 'px;left:' + (box.x - padding.left) + 'px;width:' + (box.width + padding.left + padding.right) + 'px;height:' + padding.bottom + 'px;background:' + bgColor + ';';
581
+ container.append(bottom);
582
+ }
583
+
584
+ // Left mask
585
+ if (padding.left > 0) {
586
+ const left = document.createElement('div');
587
+ left.style.cssText = 'position:absolute;top:' + box.y + 'px;left:' + (box.x - padding.left) + 'px;width:' + padding.left + 'px;height:' + box.height + 'px;background:' + bgColor + ';';
588
+ container.append(left);
589
+ }
590
+
591
+ // Right mask
592
+ if (padding.right > 0) {
593
+ const right = document.createElement('div');
594
+ right.style.cssText = 'position:absolute;top:' + box.y + 'px;left:' + (box.x + box.width) + 'px;width:' + padding.right + 'px;height:' + box.height + 'px;background:' + bgColor + ';';
595
+ container.append(right);
596
+ }
597
+
598
+ document.body.append(container);
599
+ })()
600
+ `);
601
+ }
602
+ async function removePaddingMask(page) {
603
+ await page.evaluate(`document.querySelector('#heroshot-padding-mask')?.remove()`);
604
+ }
505
605
  async function findElement(page, selector, maxAttempts = 10, intervalMs = 500) {
506
606
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
507
607
  const handle = await page.evaluateHandle(`
@@ -562,7 +662,7 @@ async function takeScreenshot(target, outputPath, format, quality, clip) {
562
662
  }
563
663
  }
564
664
  async function captureScreenshot(page, screenshot, outputDirectory, captureOptions, filenameSuffix = "") {
565
- const { name, url, selector, filename, padding, scroll } = screenshot;
665
+ const { name, url, selector, filename, padding, scroll, maskPadding } = screenshot;
566
666
  const { format, quality } = captureOptions;
567
667
  const finalFilename = filenameSuffix ? addFilenameSuffix(filename, filenameSuffix) : filename;
568
668
  log.verbose(` ${name}${filenameSuffix}...`);
@@ -594,6 +694,11 @@ async function captureScreenshot(page, screenshot, outputDirectory, captureOptio
594
694
  if (!box) {
595
695
  return { success: false, error: "Could not get element bounding box" };
596
696
  }
697
+ if (maskPadding) {
698
+ const bgColorResult = await element.evaluate(GET_BACKGROUND_COLOR_SCRIPT);
699
+ const bgColor = typeof bgColorResult === "string" ? bgColorResult : "#ffffff";
700
+ await injectPaddingMask(page, element, padding, bgColor);
701
+ }
597
702
  const clip = {
598
703
  x: Math.max(0, box.x - padding.left),
599
704
  y: Math.max(0, box.y - padding.top),
@@ -601,6 +706,9 @@ async function captureScreenshot(page, screenshot, outputDirectory, captureOptio
601
706
  height: box.height + padding.top + padding.bottom
602
707
  };
603
708
  await takeScreenshot(page, outputPath, format, quality, clip);
709
+ if (maskPadding) {
710
+ await removePaddingMask(page);
711
+ }
604
712
  } else {
605
713
  await takeScreenshot(element, outputPath, format, quality);
606
714
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heroshot",
3
- "version": "0.0.6",
3
+ "version": "0.1.0",
4
4
  "description": "Define your screenshots once, update them forever with one command",
5
5
  "type": "module",
6
6
  "author": "Ondrej Machala",
@@ -85,6 +85,8 @@
85
85
  "knip": "knip",
86
86
  "check": "pnpm typecheck && pnpm format:check && pnpm lint && pnpm knip && pnpm test:run",
87
87
  "check:toolbar": "pnpm typecheck:toolbar && pnpm lint:toolbar && pnpm test:toolbar",
88
+ "docs:dev": "pnpm --dir docs run dev",
89
+ "docs:build": "pnpm --dir docs run build",
88
90
  "fix": "pnpm format && pnpm lint:fix",
89
91
  "changeset": "changeset"
90
92
  }
@@ -3605,10 +3605,10 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3605
3605
  if (typeof window !== "undefined") {
3606
3606
  ((_a = window.__svelte ?? (window.__svelte = {})).v ?? (_a.v = /* @__PURE__ */ new Set())).add(PUBLIC_VERSION);
3607
3607
  }
3608
- var root$8 = /* @__PURE__ */ from_svg(`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="3"></circle><line x1="12" y1="2" x2="12" y2="6"></line><line x1="12" y1="18" x2="12" y2="22"></line><line x1="2" y1="12" x2="6" y2="12"></line><line x1="18" y1="12" x2="22" y2="12"></line></svg>`);
3608
+ var root$9 = /* @__PURE__ */ from_svg(`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="3"></circle><line x1="12" y1="2" x2="12" y2="6"></line><line x1="12" y1="18" x2="12" y2="22"></line><line x1="2" y1="12" x2="6" y2="12"></line><line x1="18" y1="12" x2="22" y2="12"></line></svg>`);
3609
3609
  function PickerIcon($$anchor, $$props) {
3610
3610
  let size = prop($$props, "size", 3, 20), strokeWidth = prop($$props, "strokeWidth", 3, 2);
3611
- var svg = root$8();
3611
+ var svg = root$9();
3612
3612
  template_effect(() => {
3613
3613
  set_attribute(svg, "width", size());
3614
3614
  set_attribute(svg, "height", size());
@@ -3616,10 +3616,10 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3616
3616
  });
3617
3617
  append($$anchor, svg);
3618
3618
  }
3619
- var root$7 = /* @__PURE__ */ from_svg(`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>`);
3619
+ var root$8 = /* @__PURE__ */ from_svg(`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>`);
3620
3620
  function SettingsIcon($$anchor, $$props) {
3621
3621
  let size = prop($$props, "size", 3, 18), strokeWidth = prop($$props, "strokeWidth", 3, 2);
3622
- var svg = root$7();
3622
+ var svg = root$8();
3623
3623
  template_effect(() => {
3624
3624
  set_attribute(svg, "width", size());
3625
3625
  set_attribute(svg, "height", size());
@@ -3627,10 +3627,10 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3627
3627
  });
3628
3628
  append($$anchor, svg);
3629
3629
  }
3630
- var root$6 = /* @__PURE__ */ from_svg(`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="15" y1="3" x2="15" y2="21"></line></svg>`);
3630
+ var root$7 = /* @__PURE__ */ from_svg(`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="15" y1="3" x2="15" y2="21"></line></svg>`);
3631
3631
  function SidebarIcon($$anchor, $$props) {
3632
3632
  let size = prop($$props, "size", 3, 18), strokeWidth = prop($$props, "strokeWidth", 3, 2);
3633
- var svg = root$6();
3633
+ var svg = root$7();
3634
3634
  template_effect(() => {
3635
3635
  set_attribute(svg, "width", size());
3636
3636
  set_attribute(svg, "height", size());
@@ -3676,6 +3676,26 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3676
3676
  function generateUid() {
3677
3677
  return Math.random().toString(36).slice(2, 10);
3678
3678
  }
3679
+ function getBackgroundColor(element) {
3680
+ let current = element.parentElement;
3681
+ while (current) {
3682
+ const style = globalThis.getComputedStyle(current);
3683
+ const bgColor = style.backgroundColor;
3684
+ if (bgColor && bgColor !== "transparent" && !bgColor.startsWith("rgba(0, 0, 0, 0)")) {
3685
+ const rgbMatch = /rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(bgColor);
3686
+ if ((rgbMatch == null ? void 0 : rgbMatch[1]) && rgbMatch[2] && rgbMatch[3]) {
3687
+ const red = parseInt(rgbMatch[1], 10);
3688
+ const green = parseInt(rgbMatch[2], 10);
3689
+ const blue = parseInt(rgbMatch[3], 10);
3690
+ return `#${red.toString(16).padStart(2, "0")}${green.toString(16).padStart(2, "0")}${blue.toString(16).padStart(2, "0")}`;
3691
+ }
3692
+ return bgColor;
3693
+ }
3694
+ const root2 = current.getRootNode();
3695
+ current = root2 instanceof ShadowRoot ? root2.host : current.parentElement;
3696
+ }
3697
+ return "#ffffff";
3698
+ }
3679
3699
  function deepElementFromPoint(x, y) {
3680
3700
  let element = document.elementFromPoint(x, y);
3681
3701
  if (!element) return null;
@@ -3759,10 +3779,10 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3759
3779
  function findElementBySelector(selector) {
3760
3780
  return selector.includes(">>>") ? querySelectorPiercing(selector) : document.querySelector(selector);
3761
3781
  }
3762
- var root_4$1 = /* @__PURE__ */ from_html(`<div class="fixed bg-heroshot-primary/25 pointer-events-none flex items-center justify-center"><span class="text-xs font-mono font-bold" style="color:#22c55e;"> </span></div>`);
3763
- var root_5$1 = /* @__PURE__ */ from_html(`<div class="fixed bg-heroshot-primary/25 pointer-events-none flex items-center justify-center"><span class="text-xs font-mono font-bold" style="color:#22c55e;"> </span></div>`);
3764
- var root_6$1 = /* @__PURE__ */ from_html(`<div class="fixed bg-heroshot-primary/25 pointer-events-none flex items-center justify-center"><span class="text-xs font-mono font-bold" style="color:#22c55e;"> </span></div>`);
3765
- var root_7$1 = /* @__PURE__ */ from_html(`<div class="fixed bg-heroshot-primary/25 pointer-events-none flex items-center justify-center"><span class="text-xs font-mono font-bold" style="color:#22c55e;"> </span></div>`);
3782
+ var root_4$1 = /* @__PURE__ */ from_html(`<div class="fixed pointer-events-auto cursor-pointer"></div>`);
3783
+ var root_5$1 = /* @__PURE__ */ from_html(`<div class="fixed pointer-events-auto cursor-pointer"></div>`);
3784
+ var root_6$1 = /* @__PURE__ */ from_html(`<div class="fixed pointer-events-auto cursor-pointer"></div>`);
3785
+ var root_7$1 = /* @__PURE__ */ from_html(`<div class="fixed pointer-events-auto cursor-pointer"></div>`);
3766
3786
  var root_8$1 = /* @__PURE__ */ from_html(`<div class="fixed h-0.5 bg-heroshot-primary/50 pointer-events-none"></div>`);
3767
3787
  var root_9$1 = /* @__PURE__ */ from_html(`<div class="fixed h-0.5 bg-heroshot-primary/50 pointer-events-none"></div>`);
3768
3788
  var root_10$1 = /* @__PURE__ */ from_html(`<div class="fixed w-0.5 bg-heroshot-primary/50 pointer-events-none"></div>`);
@@ -3771,6 +3791,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3771
3791
  var root_2$1 = /* @__PURE__ */ from_html(`<!> <div></div> <div class="fixed bg-white rounded-sm pointer-events-auto -translate-x-1/2 -translate-y-1/2" role="button" tabindex="0"></div> <div class="fixed bg-white rounded-sm pointer-events-auto -translate-x-1/2 -translate-y-1/2" role="button" tabindex="0"></div> <div class="fixed bg-white rounded-sm pointer-events-auto -translate-x-1/2 -translate-y-1/2" role="button" tabindex="0"></div> <div class="fixed bg-white rounded-sm pointer-events-auto -translate-x-1/2 -translate-y-1/2" role="button" tabindex="0"></div> <div class="fixed bg-white rounded-sm pointer-events-auto -translate-x-1/2 -translate-y-1/2" role="button" tabindex="0"></div> <div class="fixed bg-white rounded-sm pointer-events-auto -translate-x-1/2 -translate-y-1/2" role="button" tabindex="0"></div> <div class="fixed bg-white rounded-sm pointer-events-auto -translate-x-1/2 -translate-y-1/2" role="button" tabindex="0"></div> <div class="fixed bg-white rounded-sm pointer-events-auto -translate-x-1/2 -translate-y-1/2" role="button" tabindex="0"></div>`, 1);
3772
3792
  var root_12 = /* @__PURE__ */ from_html(`<div class="fixed border-[3px] pointer-events-none box-border border-heroshot-primary bg-heroshot-primary/10"></div>`);
3773
3793
  var root_1$3 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 w-screen h-screen z-[2147483646] pointer-events-none"><div></div> <div></div> <div></div> <div></div> <!></div>`);
3794
+ var root_14 = /* @__PURE__ */ from_html(`<span style="color:#fbbf24;"> </span>`);
3795
+ var root_15 = /* @__PURE__ */ from_html(`<span style="color:#67e8f9;"> </span>`);
3796
+ var root_16 = /* @__PURE__ */ from_html(`<span style="color:#22c55e;"> </span>`);
3797
+ var root_13 = /* @__PURE__ */ from_html(`<div class="fixed z-[2147483647] pointer-events-none bg-black/85 text-xs font-mono px-2 py-1.5 rounded flex flex-col gap-0.5"><!> <!> <!></div>`);
3798
+ var root$6 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
3774
3799
  function ElementPicker($$anchor, $$props) {
3775
3800
  push($$props, true);
3776
3801
  const defaultPadding = { top: 0, right: 0, bottom: 0, left: 0 };
@@ -3797,6 +3822,15 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3797
3822
  false
3798
3823
  // True if this is a new pick (not editing existing)
3799
3824
  );
3825
+ let maskPadding = /* @__PURE__ */ state(
3826
+ false
3827
+ // Whether to fill padding with background color
3828
+ );
3829
+ let originalMaskPadding = /* @__PURE__ */ state(
3830
+ false
3831
+ // For revert on Esc
3832
+ );
3833
+ let detectedBgColor = /* @__PURE__ */ user_derived(() => get(selectedElement) ? getBackgroundColor(get(selectedElement)) : "#ffffff");
3800
3834
  let scrollY = /* @__PURE__ */ state(proxy(globalThis.scrollY ?? 0));
3801
3835
  let scrollX = /* @__PURE__ */ state(proxy(globalThis.scrollX ?? 0));
3802
3836
  let showOverlay = /* @__PURE__ */ user_derived(() => $$props.active && get(currentElement) !== null || get(selectedElement) !== null);
@@ -3804,11 +3838,27 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3804
3838
  user_effect(() => {
3805
3839
  document.body.style.cursor = $$props.active ? "crosshair" : "";
3806
3840
  });
3841
+ user_effect(() => {
3842
+ if (!$$props.active) {
3843
+ set(tooltipData, null);
3844
+ }
3845
+ });
3807
3846
  function handleMouseMove(event2) {
3808
3847
  if (!$$props.active) return;
3809
3848
  const element = deepElementFromPoint(event2.clientX, event2.clientY);
3810
3849
  if (element && !element.closest("#heroshot-root") && !element.closest("#heroshot-overlay")) {
3811
3850
  set(currentElement, element, true);
3851
+ const rect = element.getBoundingClientRect();
3852
+ set(
3853
+ tooltipData,
3854
+ {
3855
+ size: `${Math.round(rect.width)} x ${Math.round(rect.height)}`,
3856
+ path: getSelector(element)
3857
+ },
3858
+ true
3859
+ );
3860
+ set(tooltipX, event2.clientX, true);
3861
+ set(tooltipY, event2.clientY, true);
3812
3862
  }
3813
3863
  }
3814
3864
  function handleClick(event2) {
@@ -3827,7 +3877,14 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3827
3877
  set(selectedScroll, { x: globalThis.scrollX, y: globalThis.scrollY }, true);
3828
3878
  set(editingScreenshotId, null);
3829
3879
  set(isNewElement, true);
3880
+ set(maskPadding, false);
3881
+ set(originalMaskPadding, false);
3830
3882
  set(currentElement, null);
3883
+ set(
3884
+ tooltipData,
3885
+ null
3886
+ // Clear tooltip
3887
+ );
3831
3888
  $$props.onToggle();
3832
3889
  $$props.onNewElement(selector);
3833
3890
  }
@@ -3839,6 +3896,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3839
3896
  handleCancel();
3840
3897
  } else if (get(editingScreenshotId)) {
3841
3898
  $$props.onPaddingUpdate(get(editingScreenshotId), get(originalPadding));
3899
+ $$props.onMaskPaddingUpdate(get(editingScreenshotId), get(originalMaskPadding));
3842
3900
  clearSelection();
3843
3901
  }
3844
3902
  } else if ($$props.active) {
@@ -3864,6 +3922,8 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3864
3922
  set(selectedScroll, { ...defaultScroll }, true);
3865
3923
  set(editingScreenshotId, null);
3866
3924
  set(isNewElement, false);
3925
+ set(maskPadding, false);
3926
+ set(originalMaskPadding, false);
3867
3927
  set(currentElement, null);
3868
3928
  $$props.onCancel();
3869
3929
  }
@@ -3881,6 +3941,23 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3881
3941
  $$props.onPaddingUpdate(get(editingScreenshotId), newPadding);
3882
3942
  }
3883
3943
  }
3944
+ function handlePaddingClick(event2) {
3945
+ event2.preventDefault();
3946
+ event2.stopPropagation();
3947
+ set(maskPadding, !get(maskPadding));
3948
+ set(tooltipData, { padding: get(maskPadding) ? "masked" : "transparent" }, true);
3949
+ if (get(editingScreenshotId) && !get(isNewElement)) {
3950
+ $$props.onMaskPaddingUpdate(get(editingScreenshotId), get(maskPadding));
3951
+ }
3952
+ }
3953
+ function handlePaddingMouseMove(event2) {
3954
+ set(tooltipData, { padding: get(maskPadding) ? "masked" : "transparent" }, true);
3955
+ set(tooltipX, event2.clientX, true);
3956
+ set(tooltipY, event2.clientY, true);
3957
+ }
3958
+ function handlePaddingMouseLeave() {
3959
+ set(tooltipData, null);
3960
+ }
3884
3961
  function highlightElement(selector, screenshotId, attempt = 1) {
3885
3962
  const maxAttempts = 5;
3886
3963
  const element = findElementBySelector(selector);
@@ -3888,6 +3965,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3888
3965
  if (screenshotId) {
3889
3966
  const screenshot = $$props.screenshots.find((item) => item.id === screenshotId);
3890
3967
  const padding = (screenshot == null ? void 0 : screenshot.padding) ? { ...screenshot.padding } : { ...defaultPadding };
3968
+ const mask = (screenshot == null ? void 0 : screenshot.maskPadding) ?? false;
3891
3969
  if (screenshot == null ? void 0 : screenshot.scroll) {
3892
3970
  globalThis.scrollTo({
3893
3971
  left: screenshot.scroll.x,
@@ -3912,6 +3990,8 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3912
3990
  );
3913
3991
  set(editingScreenshotId, screenshotId, true);
3914
3992
  set(isNewElement, false);
3993
+ set(maskPadding, mask, true);
3994
+ set(originalMaskPadding, mask, true);
3915
3995
  set(currentElement, null);
3916
3996
  } else {
3917
3997
  element.scrollIntoView({ behavior: "smooth", block: "center" });
@@ -3931,6 +4011,8 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3931
4011
  set(selectedScroll, { ...defaultScroll }, true);
3932
4012
  set(editingScreenshotId, null);
3933
4013
  set(isNewElement, false);
4014
+ set(maskPadding, false);
4015
+ set(originalMaskPadding, false);
3934
4016
  set(currentElement, null);
3935
4017
  }
3936
4018
  function confirmDraft(screenshotId) {
@@ -3938,6 +4020,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3938
4020
  set(editingScreenshotId, screenshotId, true);
3939
4021
  set(isNewElement, false);
3940
4022
  set(originalPadding, { ...get(selectedPadding) }, true);
4023
+ set(originalMaskPadding, get(maskPadding), true);
3941
4024
  }
3942
4025
  }
3943
4026
  function getCurrentPadding() {
@@ -3949,6 +4032,9 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3949
4032
  function isEditingNewElement() {
3950
4033
  return get(isNewElement);
3951
4034
  }
4035
+ function getCurrentMaskPadding() {
4036
+ return get(maskPadding);
4037
+ }
3952
4038
  function getOverlayRects(element, _scrollX, _scrollY, padding) {
3953
4039
  if (!element) return null;
3954
4040
  const rect = element.getBoundingClientRect();
@@ -3993,6 +4079,9 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3993
4079
  let dragStartX = /* @__PURE__ */ state(0);
3994
4080
  let dragStartY = /* @__PURE__ */ state(0);
3995
4081
  let dragStartPadding = /* @__PURE__ */ state(proxy({ top: 0, right: 0, bottom: 0, left: 0 }));
4082
+ let tooltipData = /* @__PURE__ */ state(null);
4083
+ let tooltipX = /* @__PURE__ */ state(0);
4084
+ let tooltipY = /* @__PURE__ */ state(0);
3996
4085
  const cornerInset = 2;
3997
4086
  let expandedRect = /* @__PURE__ */ user_derived(() => get(overlayRects) ? {
3998
4087
  top: get(overlayRects).highlight.top - get(selectedPadding).top,
@@ -4013,44 +4102,83 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
4013
4102
  globalThis.addEventListener("mouseup", handleResizeMouseUp);
4014
4103
  }
4015
4104
  function handleResizeMouseMove(event2) {
4016
- if (!get(isDragging) || !get(dragHandle)) return;
4105
+ if (!get(isDragging) || !get(dragHandle) || !get(selectedElement)) return;
4017
4106
  const deltaX = event2.clientX - get(dragStartX);
4018
4107
  const deltaY = event2.clientY - get(dragStartY);
4019
4108
  const newPadding = { ...get(dragStartPadding) };
4109
+ let paddingString;
4110
+ const shiftHeld = event2.shiftKey;
4020
4111
  if (get(dragHandle).includes("-")) {
4021
4112
  const [vertical, horizontal] = get(dragHandle).split("-");
4022
- let expansion = 0;
4023
- if (vertical === "top") {
4024
- expansion = -deltaY;
4025
- } else if (vertical === "bottom") {
4026
- expansion = deltaY;
4027
- }
4028
- if (horizontal === "left") {
4029
- expansion = Math.max(expansion, -deltaX);
4030
- } else if (horizontal === "right") {
4031
- expansion = Math.max(expansion, deltaX);
4113
+ if (shiftHeld) {
4114
+ if (vertical === "top") {
4115
+ newPadding.top = Math.max(0, get(dragStartPadding).top - deltaY);
4116
+ } else if (vertical === "bottom") {
4117
+ newPadding.bottom = Math.max(0, get(dragStartPadding).bottom + deltaY);
4118
+ }
4119
+ if (horizontal === "left") {
4120
+ newPadding.left = Math.max(0, get(dragStartPadding).left - deltaX);
4121
+ } else if (horizontal === "right") {
4122
+ newPadding.right = Math.max(0, get(dragStartPadding).right + deltaX);
4123
+ }
4124
+ } else {
4125
+ let expansion = 0;
4126
+ if (vertical === "top") {
4127
+ expansion = -deltaY;
4128
+ } else if (vertical === "bottom") {
4129
+ expansion = deltaY;
4130
+ }
4131
+ if (horizontal === "left") {
4132
+ expansion = Math.max(expansion, -deltaX);
4133
+ } else if (horizontal === "right") {
4134
+ expansion = Math.max(expansion, deltaX);
4135
+ }
4136
+ newPadding.top = Math.max(0, get(dragStartPadding).top + expansion);
4137
+ newPadding.right = Math.max(0, get(dragStartPadding).right + expansion);
4138
+ newPadding.bottom = Math.max(0, get(dragStartPadding).bottom + expansion);
4139
+ newPadding.left = Math.max(0, get(dragStartPadding).left + expansion);
4032
4140
  }
4033
- newPadding.top = Math.max(0, get(dragStartPadding).top + expansion);
4034
- newPadding.right = Math.max(0, get(dragStartPadding).right + expansion);
4035
- newPadding.bottom = Math.max(0, get(dragStartPadding).bottom + expansion);
4036
- newPadding.left = Math.max(0, get(dragStartPadding).left + expansion);
4141
+ const allSame = newPadding.top === newPadding.right && newPadding.right === newPadding.bottom && newPadding.bottom === newPadding.left;
4142
+ paddingString = allSame ? `${newPadding.top}` : `${newPadding.top} ${newPadding.right} ${newPadding.bottom} ${newPadding.left}`;
4037
4143
  } else {
4038
4144
  const edgeDeltas = {
4039
- top: { key: "top", delta: -deltaY },
4040
- bottom: { key: "bottom", delta: deltaY },
4041
- left: { key: "left", delta: -deltaX },
4042
- right: { key: "right", delta: deltaX }
4145
+ top: { key: "top", opposite: "bottom", delta: -deltaY },
4146
+ bottom: { key: "bottom", opposite: "top", delta: deltaY },
4147
+ left: { key: "left", opposite: "right", delta: -deltaX },
4148
+ right: { key: "right", opposite: "left", delta: deltaX }
4043
4149
  };
4044
4150
  const edge = edgeDeltas[get(dragHandle)];
4045
4151
  if (edge) {
4046
4152
  newPadding[edge.key] = Math.max(0, get(dragStartPadding)[edge.key] + edge.delta);
4153
+ if (!shiftHeld) {
4154
+ newPadding[edge.opposite] = Math.max(0, get(dragStartPadding)[edge.opposite] + edge.delta);
4155
+ }
4047
4156
  }
4157
+ paddingString = `${newPadding[edge.key]}`;
4048
4158
  }
4159
+ const rect = get(selectedElement).getBoundingClientRect();
4160
+ const totalWidth = Math.round(rect.width + newPadding.left + newPadding.right);
4161
+ const totalHeight = Math.round(rect.height + newPadding.top + newPadding.bottom);
4162
+ set(
4163
+ tooltipData,
4164
+ {
4165
+ size: `${totalWidth} x ${totalHeight}`,
4166
+ padding: paddingString
4167
+ },
4168
+ true
4169
+ );
4170
+ set(tooltipX, event2.clientX, true);
4171
+ set(tooltipY, event2.clientY, true);
4049
4172
  handlePaddingChange(newPadding);
4050
4173
  }
4051
4174
  function handleResizeMouseUp() {
4052
4175
  set(isDragging, false);
4053
4176
  set(dragHandle, null);
4177
+ set(
4178
+ tooltipData,
4179
+ null
4180
+ // Clear tooltip
4181
+ );
4054
4182
  globalThis.removeEventListener("mousemove", handleResizeMouseMove);
4055
4183
  globalThis.removeEventListener("mouseup", handleResizeMouseUp);
4056
4184
  }
@@ -4074,9 +4202,10 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
4074
4202
  confirmDraft,
4075
4203
  getCurrentPadding,
4076
4204
  getCurrentScroll,
4077
- isEditingNewElement
4205
+ isEditingNewElement,
4206
+ getCurrentMaskPadding
4078
4207
  };
4079
- var fragment = comment();
4208
+ var fragment = root$6();
4080
4209
  event("scroll", $window, handleScroll);
4081
4210
  event("mousemove", $document, handleMouseMove);
4082
4211
  event("click", $document, handleClick);
@@ -4105,12 +4234,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
4105
4234
  {
4106
4235
  var consequent = ($$anchor5) => {
4107
4236
  var div_5 = root_4$1();
4108
- var span = child(div_5);
4109
- var text = child(span);
4110
- template_effect(() => {
4111
- set_style(div_5, `top:${get(expandedRect).top ?? ""}px;left:${get(expandedRect).left ?? ""}px;width:${get(expandedRect).width ?? ""}px;height:${get(selectedPadding).top ?? ""}px;`);
4112
- set_text(text, get(selectedPadding).top);
4113
- });
4237
+ div_5.__click = handlePaddingClick;
4238
+ div_5.__mousemove = handlePaddingMouseMove;
4239
+ template_effect(() => set_style(div_5, `top:${get(expandedRect).top ?? ""}px;left:${get(expandedRect).left ?? ""}px;width:${get(expandedRect).width ?? ""}px;height:${get(selectedPadding).top ?? ""}px;background:${(get(maskPadding) ? get(detectedBgColor) : "rgba(34, 197, 94, 0.25)") ?? ""};`));
4240
+ event("mouseenter", div_5, handlePaddingMouseMove);
4241
+ event("mouseleave", div_5, handlePaddingMouseLeave);
4114
4242
  append($$anchor5, div_5);
4115
4243
  };
4116
4244
  if_block(node_3, ($$render) => {
@@ -4121,12 +4249,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
4121
4249
  {
4122
4250
  var consequent_1 = ($$anchor5) => {
4123
4251
  var div_6 = root_5$1();
4124
- var span_1 = child(div_6);
4125
- var text_1 = child(span_1);
4126
- template_effect(() => {
4127
- set_style(div_6, `top:${get(overlayRects).highlight.top + get(overlayRects).highlight.height}px;left:${get(expandedRect).left ?? ""}px;width:${get(expandedRect).width ?? ""}px;height:${get(selectedPadding).bottom ?? ""}px;`);
4128
- set_text(text_1, get(selectedPadding).bottom);
4129
- });
4252
+ div_6.__click = handlePaddingClick;
4253
+ div_6.__mousemove = handlePaddingMouseMove;
4254
+ template_effect(() => set_style(div_6, `top:${get(overlayRects).highlight.top + get(overlayRects).highlight.height}px;left:${get(expandedRect).left ?? ""}px;width:${get(expandedRect).width ?? ""}px;height:${get(selectedPadding).bottom ?? ""}px;background:${(get(maskPadding) ? get(detectedBgColor) : "rgba(34, 197, 94, 0.25)") ?? ""};`));
4255
+ event("mouseenter", div_6, handlePaddingMouseMove);
4256
+ event("mouseleave", div_6, handlePaddingMouseLeave);
4130
4257
  append($$anchor5, div_6);
4131
4258
  };
4132
4259
  if_block(node_4, ($$render) => {
@@ -4137,12 +4264,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
4137
4264
  {
4138
4265
  var consequent_2 = ($$anchor5) => {
4139
4266
  var div_7 = root_6$1();
4140
- var span_2 = child(div_7);
4141
- var text_2 = child(span_2);
4142
- template_effect(() => {
4143
- set_style(div_7, `top:${get(overlayRects).highlight.top ?? ""}px;left:${get(expandedRect).left ?? ""}px;width:${get(selectedPadding).left ?? ""}px;height:${get(overlayRects).highlight.height ?? ""}px;`);
4144
- set_text(text_2, get(selectedPadding).left);
4145
- });
4267
+ div_7.__click = handlePaddingClick;
4268
+ div_7.__mousemove = handlePaddingMouseMove;
4269
+ template_effect(() => set_style(div_7, `top:${get(overlayRects).highlight.top ?? ""}px;left:${get(expandedRect).left ?? ""}px;width:${get(selectedPadding).left ?? ""}px;height:${get(overlayRects).highlight.height ?? ""}px;background:${(get(maskPadding) ? get(detectedBgColor) : "rgba(34, 197, 94, 0.25)") ?? ""};`));
4270
+ event("mouseenter", div_7, handlePaddingMouseMove);
4271
+ event("mouseleave", div_7, handlePaddingMouseLeave);
4146
4272
  append($$anchor5, div_7);
4147
4273
  };
4148
4274
  if_block(node_5, ($$render) => {
@@ -4153,12 +4279,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
4153
4279
  {
4154
4280
  var consequent_3 = ($$anchor5) => {
4155
4281
  var div_8 = root_7$1();
4156
- var span_3 = child(div_8);
4157
- var text_3 = child(span_3);
4158
- template_effect(() => {
4159
- set_style(div_8, `top:${get(overlayRects).highlight.top ?? ""}px;left:${get(overlayRects).highlight.left + get(overlayRects).highlight.width}px;width:${get(selectedPadding).right ?? ""}px;height:${get(overlayRects).highlight.height ?? ""}px;`);
4160
- set_text(text_3, get(selectedPadding).right);
4161
- });
4282
+ div_8.__click = handlePaddingClick;
4283
+ div_8.__mousemove = handlePaddingMouseMove;
4284
+ template_effect(() => set_style(div_8, `top:${get(overlayRects).highlight.top ?? ""}px;left:${get(overlayRects).highlight.left + get(overlayRects).highlight.width}px;width:${get(selectedPadding).right ?? ""}px;height:${get(overlayRects).highlight.height ?? ""}px;background:${(get(maskPadding) ? get(detectedBgColor) : "rgba(34, 197, 94, 0.25)") ?? ""};`));
4285
+ event("mouseenter", div_8, handlePaddingMouseMove);
4286
+ event("mouseleave", div_8, handlePaddingMouseLeave);
4162
4287
  append($$anchor5, div_8);
4163
4288
  };
4164
4289
  if_block(node_6, ($$render) => {
@@ -4285,10 +4410,57 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
4285
4410
  if (get(showOverlay) && get(overlayRects)) $$render(consequent_10);
4286
4411
  });
4287
4412
  }
4413
+ var node_11 = sibling(node, 2);
4414
+ {
4415
+ var consequent_14 = ($$anchor2) => {
4416
+ var div_23 = root_13();
4417
+ var node_12 = child(div_23);
4418
+ {
4419
+ var consequent_11 = ($$anchor3) => {
4420
+ var span = root_14();
4421
+ var text = child(span);
4422
+ template_effect(() => set_text(text, get(tooltipData).size));
4423
+ append($$anchor3, span);
4424
+ };
4425
+ if_block(node_12, ($$render) => {
4426
+ if (get(tooltipData).size) $$render(consequent_11);
4427
+ });
4428
+ }
4429
+ var node_13 = sibling(node_12, 2);
4430
+ {
4431
+ var consequent_12 = ($$anchor3) => {
4432
+ var span_1 = root_15();
4433
+ var text_1 = child(span_1);
4434
+ template_effect(() => set_text(text_1, get(tooltipData).path));
4435
+ append($$anchor3, span_1);
4436
+ };
4437
+ if_block(node_13, ($$render) => {
4438
+ if (get(tooltipData).path) $$render(consequent_12);
4439
+ });
4440
+ }
4441
+ var node_14 = sibling(node_13, 2);
4442
+ {
4443
+ var consequent_13 = ($$anchor3) => {
4444
+ var span_2 = root_16();
4445
+ var text_2 = child(span_2);
4446
+ template_effect(() => set_text(text_2, get(tooltipData).padding));
4447
+ append($$anchor3, span_2);
4448
+ };
4449
+ if_block(node_14, ($$render) => {
4450
+ if (get(tooltipData).padding) $$render(consequent_13);
4451
+ });
4452
+ }
4453
+ template_effect(() => set_style(div_23, `left:${get(tooltipX) ?? ""}px;top:${get(tooltipY) - 10}px;transform:translateX(-50%) translateY(-100%);`));
4454
+ append($$anchor2, div_23);
4455
+ };
4456
+ if_block(node_11, ($$render) => {
4457
+ if (get(tooltipData)) $$render(consequent_14);
4458
+ });
4459
+ }
4288
4460
  append($$anchor, fragment);
4289
4461
  return pop($$exports);
4290
4462
  }
4291
- delegate(["click", "mousedown"]);
4463
+ delegate(["click", "mousemove", "mousedown"]);
4292
4464
  var root_2 = /* @__PURE__ */ from_html(`<p class="text-xs text-slate-500 mt-2">Will capture two screenshots: -light and -dark variants</p>`);
4293
4465
  var root_1$2 = /* @__PURE__ */ from_html(`<div class="fixed inset-0 bg-black/50 z-[2147483647] flex items-center justify-center pointer-events-auto" role="button" tabindex="0"><div class="bg-slate-800 rounded-lg p-6 w-80 shadow-2xl" role="dialog" aria-modal="true" aria-label="Settings" tabindex="-1"><h2 class="text-lg font-semibold text-white mb-4">Settings</h2> <div class="mb-4"><span class="block text-sm text-slate-400 mb-2">Viewport Size</span> <div class="flex gap-2 items-center"><label class="sr-only" for="viewport-width">Width</label> <input id="viewport-width" type="number" class="w-20 px-2 py-1 bg-slate-700 text-white rounded border border-slate-600 focus:border-blue-500 focus:outline-none" min="320" max="3840"/> <span class="text-slate-400">x</span> <label class="sr-only" for="viewport-height">Height</label> <input id="viewport-height" type="number" class="w-20 px-2 py-1 bg-slate-700 text-white rounded border border-slate-600 focus:border-blue-500 focus:outline-none" min="200" max="2160"/> <span class="text-slate-500 text-sm">px</span></div></div> <div class="mb-4"><span class="block text-sm text-slate-400 mb-2">Scale (Retina)</span> <div class="flex gap-2"><button type="button">1x</button> <button type="button">2x</button> <button type="button">3x</button></div> <p class="text-xs text-slate-500 mt-2">Higher scale = sharper images, larger file size</p></div> <div class="mb-6"><span class="block text-sm text-slate-400 mb-2">Color Scheme</span> <div class="flex gap-2"><button type="button">Auto</button> <button type="button">Light</button> <button type="button">Dark</button> <button type="button" title="Capture both light and dark versions">Both</button></div> <!></div> <div class="flex justify-end gap-2"><button type="button" class="px-4 py-2 rounded bg-slate-700 text-white hover:bg-slate-600 transition-colors">Cancel</button> <button type="button" class="px-4 py-2 rounded bg-green-500 text-white hover:bg-green-600 transition-colors">Save</button></div></div></div>`);
4294
4466
  function SettingsModal($$anchor, $$props) {
@@ -4808,6 +4980,17 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
4808
4980
  emit({ type: "screenshot-updated", data: updated });
4809
4981
  }
4810
4982
  }
4983
+ function handleMaskPaddingUpdate(id, mask) {
4984
+ set(
4985
+ screenshots,
4986
+ get(screenshots).map((screenshot) => screenshot.id === id ? { ...screenshot, maskPadding: mask || void 0 } : screenshot),
4987
+ true
4988
+ );
4989
+ const updated = get(screenshots).find((screenshot) => screenshot.id === id);
4990
+ if (updated && id !== get(draftId)) {
4991
+ emit({ type: "screenshot-updated", data: updated });
4992
+ }
4993
+ }
4811
4994
  function handleElementCancel() {
4812
4995
  if (get(draftId)) {
4813
4996
  set(screenshots, get(screenshots).filter((screenshot) => screenshot.id !== get(draftId)), true);
@@ -4823,13 +5006,15 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
4823
5006
  if (id === get(draftId)) {
4824
5007
  const padding = elementPicker.getCurrentPadding();
4825
5008
  const scroll = elementPicker.getCurrentScroll();
5009
+ const mask = elementPicker.getCurrentMaskPadding();
4826
5010
  const hasPadding = padding.top > 0 || padding.right > 0 || padding.bottom > 0 || padding.left > 0;
4827
5011
  set(
4828
5012
  screenshots,
4829
5013
  get(screenshots).map((screenshot) => screenshot.id === id ? {
4830
5014
  ...screenshot,
4831
5015
  padding: hasPadding ? { ...padding } : void 0,
4832
- scroll: { ...scroll }
5016
+ scroll: { ...scroll },
5017
+ maskPadding: mask || void 0
4833
5018
  } : screenshot),
4834
5019
  true
4835
5020
  );
@@ -4922,6 +5107,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
4922
5107
  onNewElement: handleNewElement,
4923
5108
  onPaddingUpdate: handlePaddingUpdate,
4924
5109
  onScrollUpdate: handleScrollUpdate,
5110
+ onMaskPaddingUpdate: handleMaskPaddingUpdate,
4925
5111
  onCancel: handleElementCancel,
4926
5112
  onDeselect: handleDeselect
4927
5113
  }),
@@ -5004,10 +5190,12 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
5004
5190
  pop();
5005
5191
  }
5006
5192
  delegate(["click"]);
5007
- const styles = '/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */\n@layer properties {\n @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) {\n *, :before, :after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-rotate-x: initial;\n --tw-rotate-y: initial;\n --tw-rotate-z: initial;\n --tw-skew-x: initial;\n --tw-skew-y: initial;\n --tw-space-y-reverse: 0;\n --tw-border-style: solid;\n --tw-font-weight: initial;\n --tw-tracking: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-blur: initial;\n --tw-brightness: initial;\n --tw-contrast: initial;\n --tw-grayscale: initial;\n --tw-hue-rotate: initial;\n --tw-invert: initial;\n --tw-opacity: initial;\n --tw-saturate: initial;\n --tw-sepia: initial;\n --tw-drop-shadow: initial;\n --tw-drop-shadow-color: initial;\n --tw-drop-shadow-alpha: 100%;\n --tw-drop-shadow-size: initial;\n --tw-duration: initial;\n }\n }\n}\n\n@layer theme {\n :root, :host {\n --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;\n --color-red-500: oklch(63.7% .237 25.331);\n --color-green-400: oklch(79.2% .209 151.711);\n --color-green-500: oklch(72.3% .219 149.579);\n --color-green-600: oklch(62.7% .194 149.214);\n --color-green-700: oklch(52.7% .154 150.069);\n --color-blue-400: oklch(70.7% .165 254.624);\n --color-blue-500: oklch(62.3% .214 259.815);\n --color-blue-600: oklch(54.6% .245 262.881);\n --color-slate-300: oklch(86.9% .022 252.894);\n --color-slate-400: oklch(70.4% .04 256.788);\n --color-slate-500: oklch(55.4% .046 257.417);\n --color-slate-600: oklch(44.6% .043 257.281);\n --color-slate-700: oklch(37.2% .044 257.287);\n --color-slate-800: oklch(27.9% .041 260.031);\n --color-slate-900: oklch(20.8% .042 265.755);\n --color-black: #000;\n --color-white: #fff;\n --spacing: .25rem;\n --text-xs: .75rem;\n --text-xs--line-height: calc(1 / .75);\n --text-sm: .875rem;\n --text-sm--line-height: calc(1.25 / .875);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --tracking-wide: .025em;\n --radius-sm: .25rem;\n --radius-md: .375rem;\n --radius-lg: .5rem;\n --radius-xl: .75rem;\n --default-transition-duration: .15s;\n --default-transition-timing-function: cubic-bezier(.4, 0, .2, 1);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n --color-heroshot-primary: #22c55e;\n }\n}\n\n@layer base {\n *, :after, :before, ::backdrop {\n box-sizing: border-box;\n border: 0 solid;\n margin: 0;\n padding: 0;\n }\n\n ::file-selector-button {\n box-sizing: border-box;\n border: 0 solid;\n margin: 0;\n padding: 0;\n }\n\n html, :host {\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n line-height: 1.5;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n\n h1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n -webkit-text-decoration: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n\n b, strong {\n font-weight: bolder;\n }\n\n code, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n\n small {\n font-size: 80%;\n }\n\n sub, sup {\n vertical-align: baseline;\n font-size: 75%;\n line-height: 0;\n position: relative;\n }\n\n sub {\n bottom: -.25em;\n }\n\n sup {\n top: -.5em;\n }\n\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n\n :-moz-focusring {\n outline: auto;\n }\n\n progress {\n vertical-align: baseline;\n }\n\n summary {\n display: list-item;\n }\n\n ol, ul, menu {\n list-style: none;\n }\n\n img, svg, video, canvas, audio, iframe, embed, object {\n vertical-align: middle;\n display: block;\n }\n\n img, video {\n max-width: 100%;\n height: auto;\n }\n\n button, input, select, optgroup, textarea {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n opacity: 1;\n background-color: #0000;\n border-radius: 0;\n }\n\n ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n opacity: 1;\n background-color: #0000;\n border-radius: 0;\n }\n\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n\n ::placeholder {\n opacity: 1;\n }\n\n @supports (not ((-webkit-appearance: -apple-pay-button))) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentColor;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n ::placeholder {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n\n textarea {\n resize: vertical;\n }\n\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n\n ::-webkit-datetime-edit {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-year-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-month-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-day-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-hour-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-minute-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-second-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-millisecond-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n\n ::-webkit-calendar-picker-indicator {\n line-height: 1;\n }\n\n :-moz-ui-invalid {\n box-shadow: none;\n }\n\n button, input:where([type="button"], [type="reset"], [type="submit"]) {\n appearance: button;\n }\n\n ::file-selector-button {\n appearance: button;\n }\n\n ::-webkit-inner-spin-button {\n height: auto;\n }\n\n ::-webkit-outer-spin-button {\n height: auto;\n }\n\n [hidden]:where(:not([hidden="until-found"])) {\n display: none !important;\n }\n}\n\n@layer components;\n\n@layer utilities {\n .pointer-events-auto {\n pointer-events: auto;\n }\n\n .pointer-events-none {\n pointer-events: none;\n }\n\n .visible {\n visibility: visible;\n }\n\n .sr-only {\n clip-path: inset(50%);\n white-space: nowrap;\n border-width: 0;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n position: absolute;\n overflow: hidden;\n }\n\n .absolute {\n position: absolute;\n }\n\n .fixed {\n position: fixed;\n }\n\n .relative {\n position: relative;\n }\n\n .inset-0 {\n inset: calc(var(--spacing) * 0);\n }\n\n .-top-1 {\n top: calc(var(--spacing) * -1);\n }\n\n .top-4 {\n top: calc(var(--spacing) * 4);\n }\n\n .-right-1 {\n right: calc(var(--spacing) * -1);\n }\n\n .bottom-5 {\n bottom: calc(var(--spacing) * 5);\n }\n\n .left-1\\/2 {\n left: 50%;\n }\n\n .z-\\[2147483646\\] {\n z-index: 2147483646;\n }\n\n .z-\\[2147483647\\] {\n z-index: 2147483647;\n }\n\n .container {\n width: 100%;\n }\n\n @media (min-width: 40rem) {\n .container {\n max-width: 40rem;\n }\n }\n\n @media (min-width: 48rem) {\n .container {\n max-width: 48rem;\n }\n }\n\n @media (min-width: 64rem) {\n .container {\n max-width: 64rem;\n }\n }\n\n @media (min-width: 80rem) {\n .container {\n max-width: 80rem;\n }\n }\n\n @media (min-width: 96rem) {\n .container {\n max-width: 96rem;\n }\n }\n\n .-mx-1 {\n margin-inline: calc(var(--spacing) * -1);\n }\n\n .mt-2 {\n margin-top: calc(var(--spacing) * 2);\n }\n\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n\n .mb-4 {\n margin-bottom: calc(var(--spacing) * 4);\n }\n\n .mb-6 {\n margin-bottom: calc(var(--spacing) * 6);\n }\n\n .box-border {\n box-sizing: border-box;\n }\n\n .block {\n display: block;\n }\n\n .flex {\n display: flex;\n }\n\n .grid {\n display: grid;\n }\n\n .hidden {\n display: none;\n }\n\n .table {\n display: table;\n }\n\n .h-0\\.5 {\n height: calc(var(--spacing) * .5);\n }\n\n .h-5 {\n height: calc(var(--spacing) * 5);\n }\n\n .h-6 {\n height: calc(var(--spacing) * 6);\n }\n\n .h-9 {\n height: calc(var(--spacing) * 9);\n }\n\n .h-screen {\n height: 100vh;\n }\n\n .max-h-\\[calc\\(100vh-32px\\)\\] {\n max-height: calc(100vh - 32px);\n }\n\n .w-0\\.5 {\n width: calc(var(--spacing) * .5);\n }\n\n .w-5 {\n width: calc(var(--spacing) * 5);\n }\n\n .w-6 {\n width: calc(var(--spacing) * 6);\n }\n\n .w-9 {\n width: calc(var(--spacing) * 9);\n }\n\n .w-20 {\n width: calc(var(--spacing) * 20);\n }\n\n .w-64 {\n width: calc(var(--spacing) * 64);\n }\n\n .w-80 {\n width: calc(var(--spacing) * 80);\n }\n\n .w-full {\n width: 100%;\n }\n\n .w-screen {\n width: 100vw;\n }\n\n .max-w-full {\n max-width: 100%;\n }\n\n .min-w-0 {\n min-width: calc(var(--spacing) * 0);\n }\n\n .min-w-5 {\n min-width: calc(var(--spacing) * 5);\n }\n\n .flex-1 {\n flex: 1;\n }\n\n .flex-shrink-0 {\n flex-shrink: 0;\n }\n\n .border-collapse {\n border-collapse: collapse;\n }\n\n .-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n\n .-translate-y-1\\/2 {\n --tw-translate-y: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n\n .transform {\n transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, );\n }\n\n .cursor-pointer {\n cursor: pointer;\n }\n\n .cursor-text {\n cursor: text;\n }\n\n .resize {\n resize: both;\n }\n\n .flex-col {\n flex-direction: column;\n }\n\n .items-center {\n align-items: center;\n }\n\n .items-start {\n align-items: flex-start;\n }\n\n .justify-between {\n justify-content: space-between;\n }\n\n .justify-center {\n justify-content: center;\n }\n\n .justify-end {\n justify-content: flex-end;\n }\n\n .gap-0\\.5 {\n gap: calc(var(--spacing) * .5);\n }\n\n .gap-1\\.5 {\n gap: calc(var(--spacing) * 1.5);\n }\n\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n\n :where(.space-y-1 > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)));\n }\n\n .truncate {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n }\n\n .overflow-hidden {\n overflow: hidden;\n }\n\n .overflow-y-auto {\n overflow-y: auto;\n }\n\n .rounded {\n border-radius: .25rem;\n }\n\n .rounded-full {\n border-radius: 3.40282e38px;\n }\n\n .rounded-lg {\n border-radius: var(--radius-lg);\n }\n\n .rounded-md {\n border-radius: var(--radius-md);\n }\n\n .rounded-sm {\n border-radius: var(--radius-sm);\n }\n\n .rounded-xl {\n border-radius: var(--radius-xl);\n }\n\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n\n .border-\\[3px\\] {\n border-style: var(--tw-border-style);\n border-width: 3px;\n }\n\n .border-b {\n border-bottom-style: var(--tw-border-style);\n border-bottom-width: 1px;\n }\n\n .border-dashed {\n --tw-border-style: dashed;\n border-style: dashed;\n }\n\n .border-blue-500 {\n border-color: var(--color-blue-500);\n }\n\n .border-heroshot-primary {\n border-color: var(--color-heroshot-primary);\n }\n\n .border-slate-600 {\n border-color: var(--color-slate-600);\n }\n\n .border-slate-700 {\n border-color: var(--color-slate-700);\n }\n\n .bg-black\\/50 {\n background-color: #00000080;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-black\\/50 {\n background-color: color-mix(in oklab, var(--color-black) 50%, transparent);\n }\n }\n\n .bg-blue-600 {\n background-color: var(--color-blue-600);\n }\n\n .bg-green-500 {\n background-color: var(--color-green-500);\n }\n\n .bg-green-700 {\n background-color: var(--color-green-700);\n }\n\n .bg-heroshot-primary\\/10 {\n background-color: #22c55e1a;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-heroshot-primary\\/10 {\n background-color: color-mix(in oklab, var(--color-heroshot-primary) 10%, transparent);\n }\n }\n\n .bg-heroshot-primary\\/25 {\n background-color: #22c55e40;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-heroshot-primary\\/25 {\n background-color: color-mix(in oklab, var(--color-heroshot-primary) 25%, transparent);\n }\n }\n\n .bg-heroshot-primary\\/50 {\n background-color: #22c55e80;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-heroshot-primary\\/50 {\n background-color: color-mix(in oklab, var(--color-heroshot-primary) 50%, transparent);\n }\n }\n\n .bg-red-500 {\n background-color: var(--color-red-500);\n }\n\n .bg-slate-600 {\n background-color: var(--color-slate-600);\n }\n\n .bg-slate-700 {\n background-color: var(--color-slate-700);\n }\n\n .bg-slate-700\\/50 {\n background-color: #31415880;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-slate-700\\/50 {\n background-color: color-mix(in oklab, var(--color-slate-700) 50%, transparent);\n }\n }\n\n .bg-slate-800 {\n background-color: var(--color-slate-800);\n }\n\n .bg-slate-900 {\n background-color: var(--color-slate-900);\n }\n\n .bg-white {\n background-color: var(--color-white);\n }\n\n .p-1\\.5 {\n padding: calc(var(--spacing) * 1.5);\n }\n\n .p-2 {\n padding: calc(var(--spacing) * 2);\n }\n\n .p-6 {\n padding: calc(var(--spacing) * 6);\n }\n\n .px-1 {\n padding-inline: calc(var(--spacing) * 1);\n }\n\n .px-2 {\n padding-inline: calc(var(--spacing) * 2);\n }\n\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n\n .py-0\\.5 {\n padding-block: calc(var(--spacing) * .5);\n }\n\n .py-1 {\n padding-block: calc(var(--spacing) * 1);\n }\n\n .py-1\\.5 {\n padding-block: calc(var(--spacing) * 1.5);\n }\n\n .py-2 {\n padding-block: calc(var(--spacing) * 2);\n }\n\n .py-6 {\n padding-block: calc(var(--spacing) * 6);\n }\n\n .text-center {\n text-align: center;\n }\n\n .text-left {\n text-align: left;\n }\n\n .font-mono {\n font-family: var(--font-mono);\n }\n\n .font-sans {\n font-family: var(--font-sans);\n }\n\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n\n .text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n }\n\n .text-\\[10px\\] {\n font-size: 10px;\n }\n\n .font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n }\n\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n\n .tracking-wide {\n --tw-tracking: var(--tracking-wide);\n letter-spacing: var(--tracking-wide);\n }\n\n .text-slate-300 {\n color: var(--color-slate-300);\n }\n\n .text-slate-400 {\n color: var(--color-slate-400);\n }\n\n .text-slate-500 {\n color: var(--color-slate-500);\n }\n\n .text-white {\n color: var(--color-white);\n }\n\n .uppercase {\n text-transform: uppercase;\n }\n\n .opacity-0 {\n opacity: 0;\n }\n\n .shadow {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, #0000001a), 0 1px 2px -1px var(--tw-shadow-color, #0000001a);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n\n .shadow-2xl {\n --tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, #00000040);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n\n .shadow-xl {\n --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, #0000001a), 0 8px 10px -6px var(--tw-shadow-color, #0000001a);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n\n .ring {\n --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n\n .ring-2 {\n --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n\n .ring-blue-400 {\n --tw-ring-color: var(--color-blue-400);\n }\n\n .ring-green-400 {\n --tw-ring-color: var(--color-green-400);\n }\n\n .blur {\n --tw-blur: blur(8px);\n filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );\n }\n\n .filter {\n filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );\n }\n\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .transition-all {\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .transition-colors {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .duration-300 {\n --tw-duration: .3s;\n transition-duration: .3s;\n }\n\n .outline-none {\n --tw-outline-style: none;\n outline-style: none;\n }\n\n .select-none {\n -webkit-user-select: none;\n user-select: none;\n }\n\n @media (hover: hover) {\n .group-hover\\:opacity-100:is(:where(.group):hover *) {\n opacity: 1;\n }\n\n .hover\\:bg-green-600:hover {\n background-color: var(--color-green-600);\n }\n\n .hover\\:bg-red-500:hover {\n background-color: var(--color-red-500);\n }\n\n .hover\\:bg-slate-600:hover {\n background-color: var(--color-slate-600);\n }\n\n .hover\\:bg-slate-700:hover {\n background-color: var(--color-slate-700);\n }\n\n .hover\\:bg-white\\/10:hover {\n background-color: #ffffff1a;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .hover\\:bg-white\\/10:hover {\n background-color: color-mix(in oklab, var(--color-white) 10%, transparent);\n }\n }\n\n .hover\\:text-white:hover {\n color: var(--color-white);\n }\n }\n\n .focus\\:border-blue-500:focus {\n border-color: var(--color-blue-500);\n }\n\n .focus\\:outline-none:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n}\n\nbutton {\n cursor: pointer;\n}\n\n[data-theme="dark"] {\n --color-slate-50: #f8fafc;\n --color-slate-100: #f1f5f9;\n --color-slate-200: #e2e8f0;\n --color-slate-300: #cbd5e1;\n --color-slate-400: #94a3b8;\n --color-slate-500: #64748b;\n --color-slate-600: #475569;\n --color-slate-700: #334155;\n --color-slate-800: #1e293b;\n --color-slate-900: #0f172a;\n --color-slate-950: #020617;\n --theme-text: #fff;\n --theme-text-muted: #94a3b8;\n}\n\n[data-theme="light"] {\n --color-slate-50: #020617;\n --color-slate-100: #0f172a;\n --color-slate-200: #1e293b;\n --color-slate-300: #334155;\n --color-slate-400: #475569;\n --color-slate-500: #64748b;\n --color-slate-600: #94a3b8;\n --color-slate-700: #e2e8f0;\n --color-slate-800: #f1f5f9;\n --color-slate-900: #f8fafc;\n --color-slate-950: #fff;\n --theme-text: #0f172a;\n --theme-text-muted: #475569;\n}\n\n[data-theme="light"] .text-white {\n color: var(--theme-text);\n}\n\n@property --tw-translate-x {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-translate-y {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-translate-z {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-rotate-x {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-rotate-y {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-rotate-z {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-skew-x {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-skew-y {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-space-y-reverse {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-border-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n\n@property --tw-font-weight {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-tracking {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n\n@property --tw-shadow-color {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n\n@property --tw-inset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n\n@property --tw-inset-shadow-color {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-inset-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n\n@property --tw-ring-color {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n\n@property --tw-inset-ring-color {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-inset-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n\n@property --tw-ring-inset {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-ring-offset-width {\n syntax: "<length>";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-ring-offset-color {\n syntax: "*";\n inherits: false;\n initial-value: #fff;\n}\n\n@property --tw-ring-offset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n\n@property --tw-blur {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-brightness {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-contrast {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-grayscale {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-hue-rotate {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-invert {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-opacity {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-saturate {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-sepia {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-drop-shadow {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-drop-shadow-color {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-drop-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n\n@property --tw-drop-shadow-size {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-duration {\n syntax: "*";\n inherits: false\n}\n';
5193
+ const styles = '/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */\n@layer properties {\n @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) {\n *, :before, :after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-rotate-x: initial;\n --tw-rotate-y: initial;\n --tw-rotate-z: initial;\n --tw-skew-x: initial;\n --tw-skew-y: initial;\n --tw-space-y-reverse: 0;\n --tw-border-style: solid;\n --tw-font-weight: initial;\n --tw-tracking: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-blur: initial;\n --tw-brightness: initial;\n --tw-contrast: initial;\n --tw-grayscale: initial;\n --tw-hue-rotate: initial;\n --tw-invert: initial;\n --tw-opacity: initial;\n --tw-saturate: initial;\n --tw-sepia: initial;\n --tw-drop-shadow: initial;\n --tw-drop-shadow-color: initial;\n --tw-drop-shadow-alpha: 100%;\n --tw-drop-shadow-size: initial;\n --tw-duration: initial;\n }\n }\n}\n\n@layer theme {\n :root, :host {\n --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;\n --color-red-500: oklch(63.7% .237 25.331);\n --color-green-400: oklch(79.2% .209 151.711);\n --color-green-500: oklch(72.3% .219 149.579);\n --color-green-600: oklch(62.7% .194 149.214);\n --color-green-700: oklch(52.7% .154 150.069);\n --color-blue-400: oklch(70.7% .165 254.624);\n --color-blue-500: oklch(62.3% .214 259.815);\n --color-blue-600: oklch(54.6% .245 262.881);\n --color-slate-300: oklch(86.9% .022 252.894);\n --color-slate-400: oklch(70.4% .04 256.788);\n --color-slate-500: oklch(55.4% .046 257.417);\n --color-slate-600: oklch(44.6% .043 257.281);\n --color-slate-700: oklch(37.2% .044 257.287);\n --color-slate-800: oklch(27.9% .041 260.031);\n --color-slate-900: oklch(20.8% .042 265.755);\n --color-black: #000;\n --color-white: #fff;\n --spacing: .25rem;\n --text-xs: .75rem;\n --text-xs--line-height: calc(1 / .75);\n --text-sm: .875rem;\n --text-sm--line-height: calc(1.25 / .875);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --tracking-wide: .025em;\n --radius-sm: .25rem;\n --radius-md: .375rem;\n --radius-lg: .5rem;\n --radius-xl: .75rem;\n --default-transition-duration: .15s;\n --default-transition-timing-function: cubic-bezier(.4, 0, .2, 1);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n --color-heroshot-primary: #22c55e;\n }\n}\n\n@layer base {\n *, :after, :before, ::backdrop {\n box-sizing: border-box;\n border: 0 solid;\n margin: 0;\n padding: 0;\n }\n\n ::file-selector-button {\n box-sizing: border-box;\n border: 0 solid;\n margin: 0;\n padding: 0;\n }\n\n html, :host {\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n line-height: 1.5;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n\n h1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n -webkit-text-decoration: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n\n b, strong {\n font-weight: bolder;\n }\n\n code, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n\n small {\n font-size: 80%;\n }\n\n sub, sup {\n vertical-align: baseline;\n font-size: 75%;\n line-height: 0;\n position: relative;\n }\n\n sub {\n bottom: -.25em;\n }\n\n sup {\n top: -.5em;\n }\n\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n\n :-moz-focusring {\n outline: auto;\n }\n\n progress {\n vertical-align: baseline;\n }\n\n summary {\n display: list-item;\n }\n\n ol, ul, menu {\n list-style: none;\n }\n\n img, svg, video, canvas, audio, iframe, embed, object {\n vertical-align: middle;\n display: block;\n }\n\n img, video {\n max-width: 100%;\n height: auto;\n }\n\n button, input, select, optgroup, textarea {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n opacity: 1;\n background-color: #0000;\n border-radius: 0;\n }\n\n ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n opacity: 1;\n background-color: #0000;\n border-radius: 0;\n }\n\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n\n ::placeholder {\n opacity: 1;\n }\n\n @supports (not ((-webkit-appearance: -apple-pay-button))) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentColor;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n ::placeholder {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n\n textarea {\n resize: vertical;\n }\n\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n\n ::-webkit-datetime-edit {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-year-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-month-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-day-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-hour-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-minute-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-second-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-millisecond-field {\n padding-block: 0;\n }\n\n ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n\n ::-webkit-calendar-picker-indicator {\n line-height: 1;\n }\n\n :-moz-ui-invalid {\n box-shadow: none;\n }\n\n button, input:where([type="button"], [type="reset"], [type="submit"]) {\n appearance: button;\n }\n\n ::file-selector-button {\n appearance: button;\n }\n\n ::-webkit-inner-spin-button {\n height: auto;\n }\n\n ::-webkit-outer-spin-button {\n height: auto;\n }\n\n [hidden]:where(:not([hidden="until-found"])) {\n display: none !important;\n }\n}\n\n@layer components;\n\n@layer utilities {\n .pointer-events-auto {\n pointer-events: auto;\n }\n\n .pointer-events-none {\n pointer-events: none;\n }\n\n .visible {\n visibility: visible;\n }\n\n .sr-only {\n clip-path: inset(50%);\n white-space: nowrap;\n border-width: 0;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n position: absolute;\n overflow: hidden;\n }\n\n .absolute {\n position: absolute;\n }\n\n .fixed {\n position: fixed;\n }\n\n .relative {\n position: relative;\n }\n\n .inset-0 {\n inset: calc(var(--spacing) * 0);\n }\n\n .-top-1 {\n top: calc(var(--spacing) * -1);\n }\n\n .top-4 {\n top: calc(var(--spacing) * 4);\n }\n\n .-right-1 {\n right: calc(var(--spacing) * -1);\n }\n\n .bottom-5 {\n bottom: calc(var(--spacing) * 5);\n }\n\n .left-1\\/2 {\n left: 50%;\n }\n\n .z-\\[2147483646\\] {\n z-index: 2147483646;\n }\n\n .z-\\[2147483647\\] {\n z-index: 2147483647;\n }\n\n .container {\n width: 100%;\n }\n\n @media (min-width: 40rem) {\n .container {\n max-width: 40rem;\n }\n }\n\n @media (min-width: 48rem) {\n .container {\n max-width: 48rem;\n }\n }\n\n @media (min-width: 64rem) {\n .container {\n max-width: 64rem;\n }\n }\n\n @media (min-width: 80rem) {\n .container {\n max-width: 80rem;\n }\n }\n\n @media (min-width: 96rem) {\n .container {\n max-width: 96rem;\n }\n }\n\n .-mx-1 {\n margin-inline: calc(var(--spacing) * -1);\n }\n\n .mt-2 {\n margin-top: calc(var(--spacing) * 2);\n }\n\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n\n .mb-4 {\n margin-bottom: calc(var(--spacing) * 4);\n }\n\n .mb-6 {\n margin-bottom: calc(var(--spacing) * 6);\n }\n\n .box-border {\n box-sizing: border-box;\n }\n\n .block {\n display: block;\n }\n\n .flex {\n display: flex;\n }\n\n .grid {\n display: grid;\n }\n\n .hidden {\n display: none;\n }\n\n .table {\n display: table;\n }\n\n .h-0\\.5 {\n height: calc(var(--spacing) * .5);\n }\n\n .h-5 {\n height: calc(var(--spacing) * 5);\n }\n\n .h-6 {\n height: calc(var(--spacing) * 6);\n }\n\n .h-9 {\n height: calc(var(--spacing) * 9);\n }\n\n .h-screen {\n height: 100vh;\n }\n\n .max-h-\\[calc\\(100vh-32px\\)\\] {\n max-height: calc(100vh - 32px);\n }\n\n .w-0\\.5 {\n width: calc(var(--spacing) * .5);\n }\n\n .w-5 {\n width: calc(var(--spacing) * 5);\n }\n\n .w-6 {\n width: calc(var(--spacing) * 6);\n }\n\n .w-9 {\n width: calc(var(--spacing) * 9);\n }\n\n .w-20 {\n width: calc(var(--spacing) * 20);\n }\n\n .w-64 {\n width: calc(var(--spacing) * 64);\n }\n\n .w-80 {\n width: calc(var(--spacing) * 80);\n }\n\n .w-full {\n width: 100%;\n }\n\n .w-screen {\n width: 100vw;\n }\n\n .max-w-full {\n max-width: 100%;\n }\n\n .min-w-0 {\n min-width: calc(var(--spacing) * 0);\n }\n\n .min-w-5 {\n min-width: calc(var(--spacing) * 5);\n }\n\n .flex-1 {\n flex: 1;\n }\n\n .flex-shrink-0 {\n flex-shrink: 0;\n }\n\n .border-collapse {\n border-collapse: collapse;\n }\n\n .-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n\n .-translate-y-1\\/2 {\n --tw-translate-y: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n\n .transform {\n transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, );\n }\n\n .cursor-pointer {\n cursor: pointer;\n }\n\n .cursor-text {\n cursor: text;\n }\n\n .resize {\n resize: both;\n }\n\n .flex-col {\n flex-direction: column;\n }\n\n .items-center {\n align-items: center;\n }\n\n .items-start {\n align-items: flex-start;\n }\n\n .justify-between {\n justify-content: space-between;\n }\n\n .justify-center {\n justify-content: center;\n }\n\n .justify-end {\n justify-content: flex-end;\n }\n\n .gap-0\\.5 {\n gap: calc(var(--spacing) * .5);\n }\n\n .gap-1\\.5 {\n gap: calc(var(--spacing) * 1.5);\n }\n\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n\n :where(.space-y-1 > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)));\n }\n\n .truncate {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n }\n\n .overflow-hidden {\n overflow: hidden;\n }\n\n .overflow-y-auto {\n overflow-y: auto;\n }\n\n .rounded {\n border-radius: .25rem;\n }\n\n .rounded-full {\n border-radius: 3.40282e38px;\n }\n\n .rounded-lg {\n border-radius: var(--radius-lg);\n }\n\n .rounded-md {\n border-radius: var(--radius-md);\n }\n\n .rounded-sm {\n border-radius: var(--radius-sm);\n }\n\n .rounded-xl {\n border-radius: var(--radius-xl);\n }\n\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n\n .border-\\[3px\\] {\n border-style: var(--tw-border-style);\n border-width: 3px;\n }\n\n .border-b {\n border-bottom-style: var(--tw-border-style);\n border-bottom-width: 1px;\n }\n\n .border-dashed {\n --tw-border-style: dashed;\n border-style: dashed;\n }\n\n .border-blue-500 {\n border-color: var(--color-blue-500);\n }\n\n .border-heroshot-primary {\n border-color: var(--color-heroshot-primary);\n }\n\n .border-slate-600 {\n border-color: var(--color-slate-600);\n }\n\n .border-slate-700 {\n border-color: var(--color-slate-700);\n }\n\n .bg-black\\/50 {\n background-color: #00000080;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-black\\/50 {\n background-color: color-mix(in oklab, var(--color-black) 50%, transparent);\n }\n }\n\n .bg-black\\/85 {\n background-color: #000000d9;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-black\\/85 {\n background-color: color-mix(in oklab, var(--color-black) 85%, transparent);\n }\n }\n\n .bg-blue-600 {\n background-color: var(--color-blue-600);\n }\n\n .bg-green-500 {\n background-color: var(--color-green-500);\n }\n\n .bg-green-700 {\n background-color: var(--color-green-700);\n }\n\n .bg-heroshot-primary\\/10 {\n background-color: #22c55e1a;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-heroshot-primary\\/10 {\n background-color: color-mix(in oklab, var(--color-heroshot-primary) 10%, transparent);\n }\n }\n\n .bg-heroshot-primary\\/50 {\n background-color: #22c55e80;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-heroshot-primary\\/50 {\n background-color: color-mix(in oklab, var(--color-heroshot-primary) 50%, transparent);\n }\n }\n\n .bg-red-500 {\n background-color: var(--color-red-500);\n }\n\n .bg-slate-600 {\n background-color: var(--color-slate-600);\n }\n\n .bg-slate-700 {\n background-color: var(--color-slate-700);\n }\n\n .bg-slate-700\\/50 {\n background-color: #31415880;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-slate-700\\/50 {\n background-color: color-mix(in oklab, var(--color-slate-700) 50%, transparent);\n }\n }\n\n .bg-slate-800 {\n background-color: var(--color-slate-800);\n }\n\n .bg-slate-900 {\n background-color: var(--color-slate-900);\n }\n\n .bg-white {\n background-color: var(--color-white);\n }\n\n .p-1\\.5 {\n padding: calc(var(--spacing) * 1.5);\n }\n\n .p-2 {\n padding: calc(var(--spacing) * 2);\n }\n\n .p-6 {\n padding: calc(var(--spacing) * 6);\n }\n\n .px-1 {\n padding-inline: calc(var(--spacing) * 1);\n }\n\n .px-2 {\n padding-inline: calc(var(--spacing) * 2);\n }\n\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n\n .py-0\\.5 {\n padding-block: calc(var(--spacing) * .5);\n }\n\n .py-1 {\n padding-block: calc(var(--spacing) * 1);\n }\n\n .py-1\\.5 {\n padding-block: calc(var(--spacing) * 1.5);\n }\n\n .py-2 {\n padding-block: calc(var(--spacing) * 2);\n }\n\n .py-6 {\n padding-block: calc(var(--spacing) * 6);\n }\n\n .text-center {\n text-align: center;\n }\n\n .text-left {\n text-align: left;\n }\n\n .font-mono {\n font-family: var(--font-mono);\n }\n\n .font-sans {\n font-family: var(--font-sans);\n }\n\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n\n .text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n }\n\n .text-\\[10px\\] {\n font-size: 10px;\n }\n\n .font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n }\n\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n\n .tracking-wide {\n --tw-tracking: var(--tracking-wide);\n letter-spacing: var(--tracking-wide);\n }\n\n .text-slate-300 {\n color: var(--color-slate-300);\n }\n\n .text-slate-400 {\n color: var(--color-slate-400);\n }\n\n .text-slate-500 {\n color: var(--color-slate-500);\n }\n\n .text-white {\n color: var(--color-white);\n }\n\n .uppercase {\n text-transform: uppercase;\n }\n\n .opacity-0 {\n opacity: 0;\n }\n\n .shadow {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, #0000001a), 0 1px 2px -1px var(--tw-shadow-color, #0000001a);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n\n .shadow-2xl {\n --tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, #00000040);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n\n .shadow-xl {\n --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, #0000001a), 0 8px 10px -6px var(--tw-shadow-color, #0000001a);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n\n .ring {\n --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n\n .ring-2 {\n --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n\n .ring-blue-400 {\n --tw-ring-color: var(--color-blue-400);\n }\n\n .ring-green-400 {\n --tw-ring-color: var(--color-green-400);\n }\n\n .blur {\n --tw-blur: blur(8px);\n filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );\n }\n\n .filter {\n filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );\n }\n\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .transition-all {\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .transition-colors {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .duration-300 {\n --tw-duration: .3s;\n transition-duration: .3s;\n }\n\n .outline-none {\n --tw-outline-style: none;\n outline-style: none;\n }\n\n .select-none {\n -webkit-user-select: none;\n user-select: none;\n }\n\n @media (hover: hover) {\n .group-hover\\:opacity-100:is(:where(.group):hover *) {\n opacity: 1;\n }\n\n .hover\\:bg-green-600:hover {\n background-color: var(--color-green-600);\n }\n\n .hover\\:bg-red-500:hover {\n background-color: var(--color-red-500);\n }\n\n .hover\\:bg-slate-600:hover {\n background-color: var(--color-slate-600);\n }\n\n .hover\\:bg-slate-700:hover {\n background-color: var(--color-slate-700);\n }\n\n .hover\\:bg-white\\/10:hover {\n background-color: #ffffff1a;\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .hover\\:bg-white\\/10:hover {\n background-color: color-mix(in oklab, var(--color-white) 10%, transparent);\n }\n }\n\n .hover\\:text-white:hover {\n color: var(--color-white);\n }\n }\n\n .focus\\:border-blue-500:focus {\n border-color: var(--color-blue-500);\n }\n\n .focus\\:outline-none:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n}\n\nbutton {\n cursor: pointer;\n}\n\n[data-theme="dark"] {\n --color-slate-50: #f8fafc;\n --color-slate-100: #f1f5f9;\n --color-slate-200: #e2e8f0;\n --color-slate-300: #cbd5e1;\n --color-slate-400: #94a3b8;\n --color-slate-500: #64748b;\n --color-slate-600: #475569;\n --color-slate-700: #334155;\n --color-slate-800: #1e293b;\n --color-slate-900: #0f172a;\n --color-slate-950: #020617;\n --theme-text: #fff;\n --theme-text-muted: #94a3b8;\n}\n\n[data-theme="light"] {\n --color-slate-50: #020617;\n --color-slate-100: #0f172a;\n --color-slate-200: #1e293b;\n --color-slate-300: #334155;\n --color-slate-400: #475569;\n --color-slate-500: #64748b;\n --color-slate-600: #94a3b8;\n --color-slate-700: #e2e8f0;\n --color-slate-800: #f1f5f9;\n --color-slate-900: #f8fafc;\n --color-slate-950: #fff;\n --theme-text: #0f172a;\n --theme-text-muted: #475569;\n}\n\n[data-theme="light"] .text-white {\n color: var(--theme-text);\n}\n\n@property --tw-translate-x {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-translate-y {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-translate-z {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-rotate-x {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-rotate-y {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-rotate-z {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-skew-x {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-skew-y {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-space-y-reverse {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-border-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n\n@property --tw-font-weight {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-tracking {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n\n@property --tw-shadow-color {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n\n@property --tw-inset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n\n@property --tw-inset-shadow-color {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-inset-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n\n@property --tw-ring-color {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n\n@property --tw-inset-ring-color {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-inset-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n\n@property --tw-ring-inset {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-ring-offset-width {\n syntax: "<length>";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-ring-offset-color {\n syntax: "*";\n inherits: false;\n initial-value: #fff;\n}\n\n@property --tw-ring-offset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n\n@property --tw-blur {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-brightness {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-contrast {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-grayscale {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-hue-rotate {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-invert {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-opacity {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-saturate {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-sepia {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-drop-shadow {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-drop-shadow-color {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-drop-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n\n@property --tw-drop-shadow-size {\n syntax: "*";\n inherits: false\n}\n\n@property --tw-duration {\n syntax: "*";\n inherits: false\n}\n';
5008
5194
  function initToolbar() {
5009
5195
  var _a2;
5010
- if (!globalThis.__heroshot) {
5196
+ if (globalThis.__heroshot) {
5197
+ globalThis.__heroshot.utils = { getBackgroundColor };
5198
+ } else {
5011
5199
  globalThis.__heroshot = {
5012
5200
  initialized: false,
5013
5201
  screenshots: [],
@@ -5016,6 +5204,9 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
5016
5204
  selectedId: null,
5017
5205
  sidebarVisible: false,
5018
5206
  emit: () => {
5207
+ },
5208
+ utils: {
5209
+ getBackgroundColor
5019
5210
  }
5020
5211
  };
5021
5212
  }