@redot-src/glare 1.2.1 → 1.4.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,20 +1,30 @@
1
1
  # Glare
2
2
 
3
- Modern, touch-enabled lightbox for the web. **Zero dependencies.** MIT licensed.
3
+ A lightbox for the web that opens anything: images, video, YouTube and Vimeo, maps, iframes, nodes from the page, fetched fragments, and plain HTML. Vanilla TypeScript, zero dependencies, MIT.
4
4
 
5
- Open images, HTML5 video, YouTube/Vimeo, maps, iframes, inline nodes, AJAX fragments, and custom HTML, with galleries, zoom, thumbnails, slideshow, fullscreen, deep links, and a polished toolbar.
5
+ **[Docs and live demo →](https://glare.redot.dev/)**
6
6
 
7
- ## Features
7
+ ## Why Glare
8
8
 
9
- - **Vanilla JS / TypeScript**, no jQuery, no framework lock-in
10
- - **Galleries** with loop, arrows, keyboard, mouse wheel, and swipe
11
- - **Content types**: image, video, responsive embed, iframe, inline, AJAX, HTML
12
- - **Media helpers** for YouTube, Vimeo, and Google Maps URLs
13
- - **Pinch-zoom and pan**, click-to-zoom, protect mode
14
- - **Thumbnails**, **slideshow**, **fullscreen**, **share**, **hash** deep links
15
- - **Accessible** dialog: focus trap, ARIA, Escape, restored focus
16
- - **Theming** via CSS custom properties
17
- - ESM + UMD builds, full type declarations
9
+ Most lightboxes were built for one job, images, and everything else got bolted on: a jQuery dependency here, a video plugin there, a second library for touch gestures. Glare starts from the other end. It is one small class with a single way to describe a slide, and the slide can be any kind of content.
10
+
11
+ - **One API for every content type.** Point it at a URL and it works out whether that is an image, a video, a YouTube watch page, or a PDF. Set `type` for the cases it cannot guess.
12
+ - **Touch-first.** Swipe to change slides, swipe down to close, pinch to zoom, drag to pan. Mouse and keyboard get the same behavior.
13
+ - **Accessible by default.** A real `role="dialog"`, focus trap, restored focus on close, slide announcements in a live region, translatable labels, and `prefers-reduced-motion` support.
14
+ - **Yours to style.** Colors, radius, blur, and fonts are CSS variables. State classes cover every mode. Every piece of markup is a template you can replace.
15
+ - **Small and dependency-free.** About 16 kB of JavaScript and 3 kB of CSS, gzipped. No jQuery, no framework, no peer dependencies.
16
+ - **Typed.** Written in TypeScript, shipped as ESM and UMD with declaration files.
17
+
18
+ ## What it does
19
+
20
+ | Feature | Details |
21
+ | ------------ | ---------------------------------------------------------------------------------------- |
22
+ | Galleries | Group links with `data-glare="name"`, or pass an array. Loop, arrows, counter, captions. |
23
+ | Content | `image`, `video`, `embed`, `iframe`, `inline`, `ajax`, `html`. Providers for YouTube, Vimeo, Google Maps. |
24
+ | Zoom | Click or pinch to zoom, drag to pan, mouse wheel to change slides. |
25
+ | Modules | Thumbnail strip, slideshow with progress bar, fullscreen, URL hash deep links. |
26
+ | Toolbar | Configurable buttons that collapse into a menu on small screens. |
27
+ | Events | Lifecycle and per-slide callbacks; `beforeClose` can cancel. |
18
28
 
19
29
  ## Quick start
20
30
 
@@ -30,53 +40,43 @@ Glare.bind('[data-glare]', { loop: true })
30
40
  ```
31
41
 
32
42
  ```html
33
- <a data-glare="gallery" href="photo-1.jpg" data-caption="Sunset">
34
- <img src="photo-1-thumb.jpg" alt="Sunset" />
43
+ <a data-glare="trip" href="lake.jpg" data-caption="Alpine lake at dusk">
44
+ <img src="lake-thumb.jpg" alt="Alpine lake at dusk" />
35
45
  </a>
36
- <a data-glare="gallery" href="photo-2.jpg">
37
- <img src="photo-2-thumb.jpg" alt="Trail" />
46
+ <a data-glare="trip" href="https://www.youtube.com/watch?v=XXXXXXXXXXX">
47
+ <img src="video-thumb.jpg" alt="Trip video" />
38
48
  </a>
39
49
  ```
40
50
 
41
- Or open programmatically:
51
+ Or from code:
42
52
 
43
53
  ```js
44
- Glare.open(
45
- [
46
- { src: 'a.jpg', caption: 'A' },
47
- { src: 'b.jpg', caption: 'B' },
48
- ],
49
- { loop: true },
50
- 0,
51
- )
54
+ Glare.open([{ src: 'lake.jpg', caption: 'Alpine lake at dusk' }, { src: 'dunes.jpg' }], { loop: true })
52
55
  ```
53
56
 
54
- ## CDN
57
+ No bundler? Load it from a CDN and use the global `Glare`:
55
58
 
56
59
  ```html
57
60
  <link rel="stylesheet" href="https://unpkg.com/@redot-src/glare/dist/glare.css" />
58
61
  <script src="https://unpkg.com/@redot-src/glare/dist/glare.js"></script>
59
- <script>
60
- Glare.bind('[data-glare]', { loop: true })
61
- </script>
62
62
  ```
63
63
 
64
- ## Demo & docs
64
+ The [Getting started](https://glare.redot.dev/guide/getting-started.html) guide continues from here.
65
+
66
+ ## Built by Redot
65
67
 
66
- - Docs: [redot-src.github.io/glare](https://redot-src.github.io/glare/)
67
- - Live demo: [redot-src.github.io/glare/demo](https://redot-src.github.io/glare/demo/)
68
+ Glare is created by [Redot](https://redot.dev). Building a Laravel app? Redot ships production-ready admin dashboards with auth, roles, CRUD, and datatables.
68
69
 
69
70
  ## Development
70
71
 
71
72
  ```bash
72
73
  npm install
73
- npm run dev # interactive demo with live reload
74
+ npm run dev # docs + interactive demo with live reload
74
75
  npm run build # typecheck + library build → dist/
75
- npm run docs:dev # VitePress documentation
76
- npm run pages:build # docs + demo, as deployed to GitHub Pages
76
+ npm run docs:build # static site, as deployed to GitHub Pages
77
77
  ```
78
78
 
79
- ### Project structure
79
+ Inside the docs, `@/` resolves to `src/`, so the demo imports the library the same way users do.
80
80
 
81
81
  ```
82
82
  src/
@@ -86,25 +86,19 @@ src/
86
86
  types.ts public types
87
87
  defaults.ts default options
88
88
  i18n.ts built-in strings
89
- icons.ts inline SVG icons
90
89
  templates.ts HTML templates for the dialog and buttons
91
- core/ the Glare class and its collaborators
92
- glare.ts lifecycle, navigation, public API
93
- dom.ts building and updating the dialog markup
94
- loaders.ts one loader per content type
95
- interactions.ts clicks, keyboard, focus trap
96
- animation.ts open animation and slide-transition settings
97
- zoom.ts image zoom and pan maths
98
- idle.ts idle timer that hides the controls
99
- options.ts merges defaults, mobile overrides, and module shorthands
100
- registry.ts stack of open instances
101
- bind.ts declarative `Glare.bind()` and hash restore
90
+ core/ the Glare class and its collaborators (lifecycle, DOM, loaders, zoom, bind)
102
91
  media/ URL type detection, providers (YouTube, Vimeo, Maps), item normalization
103
- modules/ optional features: fullscreen, gestures, hash, share, slideshow, thumbs, wheel
92
+ modules/ optional features: fullscreen, gestures, hash, slideshow, thumbs, wheel
104
93
  styles/ stylesheet split by concern; tokens.css holds the public CSS variables
105
94
  utils/ small DOM, object, environment, and template helpers
106
- demo/ Vite demo site (npm run dev)
107
- docs/ VitePress documentation
95
+ docs/
96
+ index.md the demo page: prose in markdown, interactive parts as components
97
+ guide/, api/ documentation
98
+ .vitepress/
99
+ config.ts site config and the `@` alias
100
+ theme/ restyled default theme; demo/ holds the demo data and components
101
+ public/demo/ static files the demo fetches
108
102
  ```
109
103
 
110
104
  ## License
@@ -1,7 +1,18 @@
1
1
  import type { ResolvedOptions, SlideItem } from '../types';
2
+ /**
3
+ * The motion actually in effect. An effect is off when it is disabled, its duration is zero,
4
+ * or the user prefers reduced motion; its duration is then zero too. Timers must wait on these
5
+ * values rather than the raw options, since a 0ms transition never fires `transitionend`.
6
+ */
7
+ export declare function resolveMotion(opts: ResolvedOptions): {
8
+ animationEffect: string | false;
9
+ animationDuration: number;
10
+ transitionEffect: string | false;
11
+ transitionDuration: number;
12
+ };
2
13
  /** Writes the effect and duration settings onto the container for the stylesheet to use. */
3
14
  export declare function applyMotionSettings(container: HTMLElement, opts: ResolvedOptions): void;
4
15
  /** Marks the container so slide-change keyframes apply from now on. */
5
16
  export declare function enableTransitions(container: HTMLElement, opts: ResolvedOptions): void;
6
- /** Flies the opened image in from its trigger element. */
17
+ /** Flies the opened image in from its anchor. */
7
18
  export declare function animateOpen(container: HTMLElement, item: SlideItem, opts: ResolvedOptions): void;
@@ -1,11 +1,25 @@
1
1
  import type { GlareRefs, I18nDict, ResolvedOptions, SlideItem } from '../types';
2
2
  export declare function buildContainer(opts: ResolvedOptions, dict: I18nDict, id: number, count: number): GlareRefs;
3
+ /**
4
+ * Lays out the caption: slides reserve its height through `--glare-caption-inset`, and it sits
5
+ * right under the media of the slide passed to `follow`. Until then it rests at the bottom.
6
+ */
7
+ export declare function trackCaption({ container, caption }: GlareRefs): {
8
+ follow(slide: HTMLElement): void;
9
+ destroy(): void;
10
+ };
3
11
  /** Creates a hidden slide with an empty content box and appends it to the stage. */
4
12
  export declare function mountSlide(stage: HTMLElement, item: SlideItem, opts: ResolvedOptions): HTMLElement;
5
- /** Makes a mounted slide the current one, fading it in unless `instant`. */
6
- export declare function revealSlide(slide: HTMLElement, instant: boolean): void;
13
+ /** Which way a slide change goes: 1 towards later slides, -1 towards earlier ones. */
14
+ export type Direction = 1 | -1;
15
+ /**
16
+ * Makes a mounted slide the current one, fading it in unless `opening`. The first slide is
17
+ * marked `--opening` and later ones `--in`, so open animations and slide-change effects each
18
+ * have their own target. Every slide carries the direction it arrived from, for effects to mirror.
19
+ */
20
+ export declare function revealSlide(slide: HTMLElement, opening: boolean, direction: Direction): void;
7
21
  /** Fades out every slide except `keep` and removes it after `delay`. */
8
- export declare function retireSlides(stage: HTMLElement, keep: HTMLElement, delay: number): void;
22
+ export declare function retireSlides(stage: HTMLElement, keep: HTMLElement, delay: number, direction: Direction): void;
9
23
  export declare function addSmallButton(slide: HTMLElement, opts: ResolvedOptions, dict: I18nDict): void;
10
24
  export declare function showSpinner(stage: HTMLElement, opts: ResolvedOptions, dict: I18nDict): void;
11
25
  export declare function hideSpinner(stage: HTMLElement): void;
@@ -1,6 +1,5 @@
1
1
  import type { BoundGroup, GlareInstance, GlareOptions, GlareRefs, I18nDict, ResolvedOptions, SlideItem, SlideSource } from '../types';
2
2
  import { Fullscreen } from '../modules/fullscreen';
3
- import { Share } from '../modules/share';
4
3
  import { Slideshow } from '../modules/slideshow';
5
4
  import { Thumbs } from '../modules/thumbs';
6
5
  import { type BindTarget } from './bind';
@@ -21,14 +20,15 @@ export declare class Glare implements GlareInstance {
21
20
  slideshow?: Slideshow;
22
21
  thumbs?: Thumbs;
23
22
  fullscreen?: Fullscreen;
24
- share?: Share;
25
23
  private readonly galleryName;
26
24
  private readonly idle;
27
25
  private hash;
28
26
  private gestures;
29
27
  private wheel;
30
28
  private cleanups;
29
+ private captionTracker;
31
30
  private previouslyFocused;
31
+ private direction;
32
32
  constructor(items: Array<SlideSource | string> | HTMLElement[], options?: GlareOptions, index?: number, galleryName?: string);
33
33
  open(index?: number): void;
34
34
  close(): void;
@@ -55,6 +55,8 @@ export declare class Glare implements GlareInstance {
55
55
  static defaults: ResolvedOptions;
56
56
  static open(items: Array<SlideSource | string> | HTMLElement[], options?: GlareOptions, index?: number): Glare;
57
57
  static bind(target: BindTarget, options?: GlareOptions): BoundGroup;
58
+ /** Builds the instance here, or in the `delegate` window when that window has Glare loaded. */
59
+ private static create;
58
60
  static close(all?: boolean): void;
59
61
  static getInstance(id?: number): Glare | null;
60
62
  static getInstances(): Glare[];
package/dist/glare.css CHANGED
@@ -1 +1 @@
1
- :root{--glare-z: 100000;--glare-font: system-ui, -apple-system, "Segoe UI", sans-serif;--glare-bg: rgba(12, 14, 18, .92);--glare-fg: #f4f6f8;--glare-muted: rgba(244, 246, 248, .62);--glare-surface: #11151c;--glare-border: rgba(255, 255, 255, .08);--glare-accent: #ff4d4d;--glare-accent-soft: rgba(255, 77, 77, .18);--glare-toolbar-bg: rgba(12, 14, 18, .55);--glare-toolbar-bg-hover: rgba(12, 14, 18, .8);--glare-button-bg: rgba(255, 255, 255, .08);--glare-button-hover: rgba(255, 255, 255, .16);--glare-button-size: 44px;--glare-caption-bg: linear-gradient(180deg, transparent, rgba(0, 0, 0, .72));--glare-radius: 14px;--glare-shadow: 0 24px 80px rgba(0, 0, 0, .45);--glare-backdrop: blur(14px);--glare-blur: blur(12px);--glare-ease: cubic-bezier(.22, 1, .36, 1);--glare-iframe-bg: #fff;--glare-iframe-radius: 5px;--glare-thumbs-size: 95px}.glare-lock{overflow:hidden!important}.glare-container{position:fixed;inset:0;z-index:var(--glare-z);color:var(--glare-fg);font-family:var(--glare-font);outline:none;visibility:hidden;transition:visibility var(--glare-duration);-webkit-tap-highlight-color:transparent}.glare-container.glare-is-open{visibility:visible}.glare-bg,.glare-inner{opacity:0;transition:opacity var(--glare-duration) var(--glare-ease);will-change:opacity}.glare-is-open .glare-bg,.glare-is-open .glare-inner{opacity:1}.glare-is-closing .glare-bg,.glare-is-closing .glare-inner,.glare-is-closing .glare-thumbs,.glare-is-closing .glare-share-overlay{opacity:0;pointer-events:none}.glare-bg{position:absolute;inset:0;background:var(--glare-bg);-webkit-backdrop-filter:var(--glare-backdrop);backdrop-filter:var(--glare-backdrop)}.glare-inner{position:relative;z-index:1;width:100%;height:100%}.glare-hidden{display:none!important}.glare-sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.glare-button{appearance:none;display:inline-flex;align-items:center;justify-content:center;width:var(--glare-button-size);height:var(--glare-button-size);margin:0;padding:0;border:0;border-radius:50%;background:var(--glare-button-bg);color:var(--glare-fg);cursor:pointer;text-decoration:none;transition:background .16s ease,color .16s ease,transform .16s ease}.glare-button svg{display:block;width:20px;height:20px}.glare-toolbar .glare-button{background:transparent}.glare-button:hover,.glare-button:focus-visible{background:var(--glare-button-hover);outline:none}.glare-button:focus-visible{box-shadow:0 0 0 2px var(--glare-accent)}.glare-button.glare-is-active{background:var(--glare-accent-soft);color:var(--glare-accent)}.glare-button.glare-is-disabled{opacity:.35;pointer-events:none}.glare-toolbar,.glare-infobar,.glare-button--prev,.glare-button--next,.glare-close-small{border:1px solid var(--glare-border);background:var(--glare-toolbar-bg);-webkit-backdrop-filter:var(--glare-blur);backdrop-filter:var(--glare-blur)}.glare-button--prev:hover,.glare-button--next:hover,.glare-close-small:hover,.glare-button--prev:focus-visible,.glare-button--next:focus-visible,.glare-close-small:focus-visible{background:var(--glare-toolbar-bg-hover)}.glare-toolbar,.glare-infobar{position:absolute;top:12px;z-index:5;border-radius:999px}.glare-toolbar{--glare-toolbar-gap: 6px;--glare-toolbar-padding: 5px;right:12px;display:flex;gap:var(--glare-toolbar-gap);padding:var(--glare-toolbar-padding)}.glare-toolbar-menu{display:contents}.glare-button--more{display:none}.glare-infobar{top:18px;left:18px;padding:8px 14px;color:var(--glare-muted);font-size:13px;font-variant-numeric:tabular-nums;letter-spacing:.02em}.glare-navigation{position:absolute;inset:0;z-index:4;pointer-events:none}.glare-button--prev,.glare-button--next{position:absolute;top:50%;width:52px;height:52px;transform:translateY(-50%);pointer-events:auto}.glare-button--prev{left:16px}.glare-button--next{right:16px}.glare-close-small{position:absolute;top:12px;right:12px;z-index:6}.glare-caption{position:absolute;inset:auto 0 0;z-index:5;padding:48px 24px 24px;background:var(--glare-caption-bg);font-size:15px;line-height:1.5;text-align:center;pointer-events:none}.glare-caption a{color:var(--glare-accent);pointer-events:auto}.glare-infobar,.glare-navigation,.glare-caption{transition:opacity .22s var(--glare-ease),visibility .22s}.glare-is-idle .glare-infobar,.glare-is-idle .glare-navigation,.glare-is-idle .glare-caption:not(:hover){opacity:0;visibility:hidden;pointer-events:none}.glare-progress{position:absolute;top:0;left:0;right:0;z-index:30;height:3px;background:var(--glare-accent);transform:scaleX(0);transform-origin:left center;transition:transform 0s linear;pointer-events:none}.glare-spinner{position:absolute;top:50%;left:50%;z-index:3;pointer-events:none;width:42px;height:42px;margin:-21px 0 0 -21px;border:3px solid rgba(255,255,255,.18);border-top-color:var(--glare-accent);border-radius:50%;animation:glare-spin .8s linear infinite}@keyframes glare-spin{to{transform:rotate(360deg)}}.glare-error{max-width:420px;padding:28px 32px;border:1px solid var(--glare-border);border-radius:var(--glare-radius);background:var(--glare-surface);color:var(--glare-muted);text-align:center}.glare-container{--glare-thumbs-inset: 0px;--glare-inset-top: 64px;--glare-inset-x: 72px;--glare-inset-bottom: max(88px, var(--glare-thumbs-inset))}.glare-show-thumbs.glare-thumbs-axis-x{--glare-thumbs-inset: calc(var(--glare-thumbs-size) + 16px)}.glare-show-thumbs.glare-thumbs-axis-y{--glare-inset-x: 110px}.glare-slide:where(:not(.glare-slide--image)){--glare-inset-top: 30px;--glare-inset-x: 30px;--glare-inset-bottom: max(30px, var(--glare-thumbs-inset))}.glare-stage{position:absolute;inset:0;overflow:hidden;touch-action:none;transition:transform .2s var(--glare-ease)}.glare-slide{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;box-sizing:border-box;padding:var(--glare-inset-top) var(--glare-inset-x) var(--glare-inset-bottom);opacity:0;transition:opacity var(--glare-transition-duration) var(--glare-ease),transform var(--glare-transition-duration) var(--glare-ease)}.glare-slide--current{z-index:2;opacity:1}.glare-slide--out{z-index:1;opacity:0;pointer-events:none}.glare-content{position:relative;display:flex;align-items:center;justify-content:center;max-width:100%;max-height:100%}.glare-image{display:block;width:auto;height:auto;max-width:calc(100vw - 2 * var(--glare-inset-x));max-height:calc(100vh - var(--glare-inset-top) - var(--glare-inset-bottom));max-height:calc(100dvh - var(--glare-inset-top) - var(--glare-inset-bottom));border-radius:8px;object-fit:contain;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;transform-origin:center;will-change:transform;transition:transform var(--glare-duration) var(--glare-ease),opacity var(--glare-duration) var(--glare-ease)}.glare-can-zoom-in .glare-image{cursor:zoom-in}.glare-can-zoom-out .glare-image{cursor:zoom-out}.glare-video{display:block;width:min(960px,100vw - 2 * var(--glare-inset-x));max-width:100%;max-height:calc(100vh - var(--glare-inset-top) - var(--glare-inset-bottom));max-height:calc(100dvh - var(--glare-inset-top) - var(--glare-inset-bottom));border-radius:var(--glare-iframe-radius);background:#000;box-shadow:var(--glare-shadow);object-fit:contain}.glare-content--embed{width:100%;height:auto;max-width:100%;max-height:100%;aspect-ratio:16 / 9}.glare-content--iframe{width:100%;height:100%}.glare-iframe-wrap{width:100%;height:100%;max-width:100%;max-height:100%;overflow:hidden;border-radius:var(--glare-iframe-radius);background:var(--glare-iframe-bg);box-shadow:var(--glare-shadow)}.glare-iframe{display:block;width:100%;height:100%;border:0}.glare-content--html,.glare-content--inline,.glare-content--ajax{display:block;box-sizing:border-box;max-width:min(720px,100%);padding:28px;overflow:auto;border:1px solid var(--glare-border);border-radius:var(--glare-radius);background:var(--glare-surface);box-shadow:var(--glare-shadow)}.glare-content--html>:first-child,.glare-content--inline>:first-child,.glare-content--ajax>:first-child{margin-top:0}.glare-content--html>:last-child,.glare-content--inline>:last-child,.glare-content--ajax>:last-child{margin-bottom:0}.glare-thumbs{position:absolute;z-index:6;opacity:0;pointer-events:none;transition:opacity .22s var(--glare-ease),transform .22s var(--glare-ease)}.glare-thumbs--x{left:0;right:0;bottom:0;height:var(--glare-thumbs-size);transform:translateY(8px)}.glare-thumbs--y{top:72px;right:12px;bottom:88px;width:88px;transform:translate(12px)}.glare-thumbs--active{opacity:1;pointer-events:auto;transform:none}.glare-thumbs-list{display:flex;gap:8px;height:100%;box-sizing:border-box;overflow:auto;scrollbar-width:thin;-webkit-backdrop-filter:var(--glare-blur);backdrop-filter:var(--glare-blur)}.glare-thumbs--x .glare-thumbs-list{padding:10px 10px 5px;background:#0000004d}.glare-thumbs--y .glare-thumbs-list{flex-direction:column;padding:8px;border:1px solid var(--glare-border);border-radius:16px;background:var(--glare-toolbar-bg)}.glare-thumbs-item{appearance:none;flex:0 0 auto;box-sizing:border-box;width:70px;height:70px;margin:0;padding:0;border:2px solid transparent;border-radius:10px;overflow:hidden;background:var(--glare-button-bg);color:var(--glare-muted);font-size:12px;cursor:pointer}.glare-thumbs--x .glare-thumbs-item:first-child{margin-inline-start:auto}.glare-thumbs--x .glare-thumbs-item:last-child{margin-inline-end:auto}.glare-thumbs-item img{display:block;width:100%;height:100%;object-fit:cover}.glare-thumbs-item.glare-is-active{border-color:var(--glare-accent)}.glare-thumbs-item:focus-visible{outline:2px solid var(--glare-accent);outline-offset:-2px}.glare-show-thumbs.glare-thumbs-axis-x .glare-caption{bottom:var(--glare-thumbs-size)}.glare-share-overlay{position:absolute;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;padding:24px;background:#0000008c}.glare-share{width:min(420px,100%);padding:24px;border:1px solid var(--glare-border);border-radius:var(--glare-radius);background:var(--glare-surface);box-shadow:var(--glare-shadow)}.glare-share-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}.glare-share-title{margin:0;font-size:18px}.glare-share-close{width:36px;height:36px}.glare-share p{margin:0 0 10px}.glare-share-row{display:flex;gap:8px}.glare-share-link,.glare-share-input,.glare-share-copy{display:block;box-sizing:border-box;padding:10px 12px;border-radius:10px;color:var(--glare-fg);font:inherit}.glare-share-link{width:100%;background:var(--glare-button-bg);text-decoration:none}.glare-share-link:hover,.glare-share-copy:hover{background:var(--glare-button-hover)}.glare-share-input{flex:1;min-width:0;border:1px solid var(--glare-border);background:#00000059}.glare-share-copy{flex:0 0 auto;border:0;background:var(--glare-button-bg);cursor:pointer}[data-transition=slide] .glare-slide--out{transform:translate3d(-40px,0,0)}[data-transition=circular] .glare-slide--current{animation:glare-circular var(--glare-transition-duration) var(--glare-ease)}[data-transition=tube] .glare-slide--current{animation:glare-tube var(--glare-transition-duration) var(--glare-ease)}[data-transition=rotate] .glare-slide--current{animation:glare-rotate var(--glare-transition-duration) var(--glare-ease)}[data-transition=zoom-in-out] .glare-slide--current{animation:glare-zoom-in-out var(--glare-transition-duration) var(--glare-ease)}@keyframes glare-circular{0%{transform:scale(.85) rotate(-8deg);opacity:0}}@keyframes glare-tube{0%{transform:scaleX(.2);opacity:0}}@keyframes glare-rotate{0%{transform:rotate(12deg) scale(.92);opacity:0}}@keyframes glare-zoom-in-out{0%{transform:scale(1.18);opacity:0}}@media(prefers-reduced-motion:reduce){.glare-container,.glare-container *{transition:none!important;animation:none!important}}@media(max-width:720px){.glare-container{--glare-button-size: 40px;--glare-inset-top: 56px;--glare-inset-x: 16px;--glare-inset-bottom: max(96px, var(--glare-thumbs-inset))}.glare-slide:where(:not(.glare-slide--image)){--glare-inset-top: 15px;--glare-inset-x: 15px;--glare-inset-bottom: max(15px, var(--glare-thumbs-inset))}.glare-toolbar{--glare-toolbar-gap: 4px;--glare-toolbar-padding: 3px;top:8px;right:8px}.glare-button--more{display:inline-flex}.glare-toolbar-menu{position:absolute;top:calc(100% + 8px);right:calc(var(--glare-button-size) + var(--glare-toolbar-gap) + var(--glare-toolbar-padding));display:flex;flex-direction:column;gap:4px;width:max-content;max-width:calc(100vw - 2 * var(--glare-inset-x));padding:6px;border:1px solid var(--glare-border);border-radius:16px;background:var(--glare-toolbar-bg);-webkit-backdrop-filter:var(--glare-blur);backdrop-filter:var(--glare-blur);opacity:0;visibility:hidden;transform:translateY(-8px) scale(.96);transform-origin:top right;pointer-events:none;transition:opacity .16s ease,transform .16s ease,visibility .16s}.glare-toolbar-menu .glare-button{justify-content:flex-start;width:100%;padding:0 12px;border-radius:10px;gap:10px}.glare-toolbar-menu .glare-button:after{content:attr(aria-label);overflow:hidden;font-size:13px;line-height:1;text-overflow:ellipsis;white-space:nowrap}.glare-toolbar--expanded .glare-toolbar-menu{opacity:1;visibility:visible;transform:translateY(0) scale(1);pointer-events:auto}.glare-close-small{top:8px;right:8px}.glare-infobar{top:12px;left:12px;font-size:12px}.glare-button--prev,.glare-button--next{width:44px;height:44px}.glare-button--prev{left:8px}.glare-button--next{right:8px}.glare-thumbs--y,.glare-thumbs-axis-y [data-glare-thumbs]{display:none}.glare-show-thumbs.glare-thumbs-axis-y{--glare-inset-x: 16px}}
1
+ :root{--glare-z: 100000;--glare-font: system-ui, -apple-system, "Segoe UI", sans-serif;--glare-bg: rgba(12, 14, 18, .92);--glare-fg: #f4f6f8;--glare-muted: rgba(244, 246, 248, .62);--glare-surface: #11151c;--glare-border: rgba(255, 255, 255, .08);--glare-accent: #ff4d4d;--glare-accent-soft: rgba(255, 77, 77, .18);--glare-toolbar-bg: rgba(12, 14, 18, .55);--glare-toolbar-bg-hover: rgba(12, 14, 18, .8);--glare-button-bg: rgba(255, 255, 255, .08);--glare-button-hover: rgba(255, 255, 255, .16);--glare-button-size: 44px;--glare-caption-bg: transparent;--glare-radius: 14px;--glare-shadow: 0 24px 80px rgba(0, 0, 0, .45);--glare-backdrop: blur(14px);--glare-blur: blur(12px);--glare-ease: cubic-bezier(.22, 1, .36, 1);--glare-iframe-bg: #fff;--glare-iframe-radius: 5px;--glare-thumbs-size: 95px}.glare-lock{overflow:hidden!important}.glare-container{position:fixed;inset:0;z-index:var(--glare-z);color:var(--glare-fg);font-family:var(--glare-font);outline:none;visibility:hidden;transition:visibility var(--glare-duration);-webkit-tap-highlight-color:transparent}.glare-container.glare-is-open{visibility:visible}.glare-bg,.glare-inner{opacity:0;transition:opacity var(--glare-duration) var(--glare-ease);will-change:opacity}.glare-is-open .glare-bg,.glare-is-open .glare-inner{opacity:1}.glare-is-closing .glare-bg,.glare-is-closing .glare-inner,.glare-is-closing .glare-thumbs{opacity:0;pointer-events:none}.glare-bg{position:absolute;inset:0;background:var(--glare-bg);-webkit-backdrop-filter:var(--glare-backdrop);backdrop-filter:var(--glare-backdrop)}.glare-inner{position:relative;z-index:1;width:100%;height:100%}.glare-hidden{display:none!important}.glare-sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.glare-button{appearance:none;display:inline-flex;align-items:center;justify-content:center;width:var(--glare-button-size);height:var(--glare-button-size);margin:0;padding:0;border:0;border-radius:50%;background:var(--glare-button-bg);color:var(--glare-fg);cursor:pointer;text-decoration:none;transition:background .16s ease,color .16s ease,transform .16s ease}.glare-button svg{display:block;width:20px;height:20px}.glare-toolbar .glare-button{background:transparent}.glare-button:hover,.glare-button:focus-visible{background:var(--glare-button-hover);outline:none}.glare-button:focus-visible{box-shadow:0 0 0 2px var(--glare-accent)}.glare-button.glare-is-active{background:var(--glare-accent-soft);color:var(--glare-accent)}.glare-button.glare-is-disabled{opacity:.35;pointer-events:none}.glare-toolbar,.glare-infobar,.glare-button--prev,.glare-button--next,.glare-close-small{border:1px solid var(--glare-border);background:var(--glare-toolbar-bg);-webkit-backdrop-filter:var(--glare-blur);backdrop-filter:var(--glare-blur)}.glare-button--prev:hover,.glare-button--next:hover,.glare-close-small:hover,.glare-button--prev:focus-visible,.glare-button--next:focus-visible,.glare-close-small:focus-visible{background:var(--glare-toolbar-bg-hover)}.glare-toolbar,.glare-infobar{position:absolute;top:12px;z-index:5;border-radius:999px}.glare-toolbar{--glare-toolbar-gap: 6px;--glare-toolbar-padding: 5px;right:12px;display:flex;gap:var(--glare-toolbar-gap);padding:var(--glare-toolbar-padding)}.glare-toolbar-menu{display:contents}.glare-button--more{display:none}.glare-infobar{top:18px;left:18px;padding:8px 14px;color:var(--glare-muted);font-size:13px;font-variant-numeric:tabular-nums;letter-spacing:.02em}.glare-navigation{position:absolute;inset:0;z-index:4;pointer-events:none}.glare-button--prev,.glare-button--next{position:absolute;top:50%;width:52px;height:52px;transform:translateY(-50%);pointer-events:auto}.glare-button--prev{left:16px}.glare-button--next{right:16px}.glare-close-small{position:absolute;top:12px;right:12px;z-index:6}.glare-caption{position:absolute;inset:auto 0 0;z-index:5;box-sizing:border-box;max-height:35vh;padding:12px max(24px,calc(50% - 440px)) 20px;overflow:hidden;background:var(--glare-caption-bg);font-size:15px;line-height:1.5;text-align:center;pointer-events:none}.glare-caption a{color:var(--glare-accent);pointer-events:auto}.glare-infobar,.glare-navigation,.glare-caption{transition:opacity .22s var(--glare-ease),visibility .22s}.glare-is-idle .glare-infobar,.glare-is-idle .glare-navigation,.glare-is-idle .glare-caption:not(:hover),.glare-can-zoom-out .glare-caption{opacity:0;visibility:hidden;pointer-events:none}.glare-progress{position:absolute;top:0;left:0;right:0;z-index:30;height:3px;background:var(--glare-accent);transform:scaleX(0);transform-origin:left center;transition:transform 0s linear;pointer-events:none}.glare-spinner{position:absolute;top:50%;left:50%;z-index:3;pointer-events:none;width:42px;height:42px;margin:-21px 0 0 -21px;border:3px solid rgba(255,255,255,.18);border-top-color:var(--glare-accent);border-radius:50%;animation:glare-spin .8s linear infinite}@keyframes glare-spin{to{transform:rotate(360deg)}}.glare-error{max-width:420px;padding:28px 32px;border:1px solid var(--glare-border);border-radius:var(--glare-radius);background:var(--glare-surface);color:var(--glare-muted);text-align:center}.glare-container{--glare-thumbs-inset: 0px;--glare-caption-inset: 0px;--glare-inset-top: 64px;--glare-inset-x: 72px;--glare-inset-bottom: max(88px, var(--glare-thumbs-inset) + var(--glare-caption-inset))}.glare-show-thumbs.glare-thumbs-axis-x{--glare-thumbs-inset: calc(var(--glare-thumbs-size) + 16px)}.glare-show-thumbs.glare-thumbs-axis-y{--glare-inset-x: 110px}.glare-slide:where(:not(.glare-slide--image)){--glare-inset-top: 30px;--glare-inset-x: 30px;--glare-inset-bottom: max(30px, var(--glare-thumbs-inset) + var(--glare-caption-inset))}.glare-stage{position:absolute;inset:0;overflow:hidden;touch-action:none;transition:transform .2s var(--glare-ease)}.glare-slide{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;box-sizing:border-box;padding:var(--glare-inset-top) var(--glare-inset-x) var(--glare-inset-bottom);opacity:0;transition:opacity var(--glare-transition-duration) var(--glare-ease),transform var(--glare-transition-duration) var(--glare-ease)}.glare-slide--current{z-index:2;opacity:1}.glare-slide--out{z-index:1;opacity:0;pointer-events:none}.glare-content{position:relative;display:flex;align-items:center;justify-content:center;max-width:100%;max-height:100%}.glare-image{display:block;width:auto;height:auto;max-width:calc(100vw - 2 * var(--glare-inset-x));max-height:calc(100vh - var(--glare-inset-top) - var(--glare-inset-bottom));max-height:calc(100dvh - var(--glare-inset-top) - var(--glare-inset-bottom));border-radius:8px;object-fit:contain;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;transform-origin:center;will-change:transform;transition:transform var(--glare-duration) var(--glare-ease),opacity var(--glare-duration) var(--glare-ease)}.glare-can-zoom-in .glare-image{cursor:zoom-in}.glare-can-zoom-out .glare-image{cursor:zoom-out}.glare-video{display:block;width:min(960px,100vw - 2 * var(--glare-inset-x));max-width:100%;max-height:calc(100vh - var(--glare-inset-top) - var(--glare-inset-bottom));max-height:calc(100dvh - var(--glare-inset-top) - var(--glare-inset-bottom));border-radius:var(--glare-iframe-radius);background:#000;box-shadow:var(--glare-shadow);object-fit:contain}.glare-content--embed{width:100%;height:auto;max-width:100%;max-height:100%;aspect-ratio:16 / 9}.glare-content--iframe{width:100%;height:100%}.glare-iframe-wrap{width:100%;height:100%;max-width:100%;max-height:100%;overflow:hidden;border-radius:var(--glare-iframe-radius);background:var(--glare-iframe-bg);box-shadow:var(--glare-shadow)}.glare-iframe{display:block;width:100%;height:100%;border:0}.glare-content--html,.glare-content--inline,.glare-content--ajax{display:block;box-sizing:border-box;max-width:min(720px,100%);padding:28px;overflow:auto;border:1px solid var(--glare-border);border-radius:var(--glare-radius);background:var(--glare-surface);box-shadow:var(--glare-shadow)}.glare-content--html>:first-child,.glare-content--inline>:first-child,.glare-content--ajax>:first-child{margin-top:0}.glare-content--html>:last-child,.glare-content--inline>:last-child,.glare-content--ajax>:last-child{margin-bottom:0}.glare-thumbs{position:absolute;z-index:6;opacity:0;pointer-events:none;transition:opacity .22s var(--glare-ease),transform .22s var(--glare-ease)}.glare-thumbs--x{left:0;right:0;bottom:0;height:var(--glare-thumbs-size);transform:translateY(8px)}.glare-thumbs--y{top:72px;right:12px;bottom:max(88px,var(--glare-caption-inset, 0px) + 16px);width:88px;transform:translate(12px)}.glare-thumbs--active{opacity:1;pointer-events:auto;transform:none}.glare-thumbs-list{display:flex;gap:8px;height:100%;box-sizing:border-box;overflow:auto;scrollbar-width:thin;-webkit-backdrop-filter:var(--glare-blur);backdrop-filter:var(--glare-blur)}.glare-thumbs--x .glare-thumbs-list{padding:10px 10px 5px;background:#0000004d}.glare-thumbs--y .glare-thumbs-list{flex-direction:column;padding:8px;border:1px solid var(--glare-border);border-radius:16px;background:var(--glare-toolbar-bg)}.glare-thumbs-item{appearance:none;flex:0 0 auto;box-sizing:border-box;width:70px;height:70px;margin:0;padding:0;border:2px solid transparent;border-radius:10px;overflow:hidden;background:var(--glare-button-bg);color:var(--glare-muted);font-size:12px;cursor:pointer}.glare-thumbs--x .glare-thumbs-item:first-child{margin-inline-start:auto}.glare-thumbs--x .glare-thumbs-item:last-child{margin-inline-end:auto}.glare-thumbs-item img{display:block;width:100%;height:100%;object-fit:var(--glare-thumbs-fit, cover)}.glare-thumbs-item--placeholder{display:grid;place-items:center}.glare-thumbs-item--placeholder svg{width:30px;height:30px;opacity:.72}.glare-thumbs-item.glare-is-active{border-color:var(--glare-accent)}.glare-thumbs-item:focus-visible{outline:2px solid var(--glare-accent);outline-offset:-2px}.glare-show-thumbs.glare-thumbs-axis-x .glare-caption{bottom:var(--glare-thumbs-size)}[data-transition=slide] .glare-slide--in{animation:glare-slide var(--glare-transition-duration) var(--glare-ease)}[data-transition=slide] .glare-slide--out{transform:translate3d(calc(var(--glare-direction, 1) * -40px),0,0)}[data-transition=circular] .glare-slide--in{animation:glare-circular var(--glare-transition-duration) var(--glare-ease)}[data-transition=tube] .glare-slide--in{transform-origin:calc(50% + var(--glare-direction, 1) * 50%) 50%;animation:glare-tube var(--glare-transition-duration) var(--glare-ease)}[data-transition=rotate] .glare-slide--in{animation:glare-rotate var(--glare-transition-duration) var(--glare-ease)}[data-transition=zoom-in-out] .glare-slide--in{animation:glare-zoom-in-out var(--glare-transition-duration) var(--glare-ease)}@keyframes glare-slide{0%{transform:translate3d(calc(var(--glare-direction, 1) * 40px),0,0);opacity:0}}@keyframes glare-circular{0%{transform:scale(.85) rotate(calc(var(--glare-direction, 1) * -8deg));opacity:0}}@keyframes glare-tube{0%{transform:scaleX(.2);opacity:0}}@keyframes glare-rotate{0%{transform:rotate(calc(var(--glare-direction, 1) * 12deg)) scale(.92);opacity:0}}@keyframes glare-zoom-in-out{0%{transform:scale(calc(1 + var(--glare-direction, 1) * .18));opacity:0}}@media(prefers-reduced-motion:reduce){.glare-container,.glare-container *{transition:none!important;animation:none!important}}@media(max-width:720px){.glare-container{--glare-button-size: 40px;--glare-inset-top: 56px;--glare-inset-x: 16px;--glare-inset-bottom: max(96px, var(--glare-thumbs-inset) + var(--glare-caption-inset))}.glare-slide:where(:not(.glare-slide--image)){--glare-inset-top: 15px;--glare-inset-x: 15px;--glare-inset-bottom: max(15px, var(--glare-thumbs-inset) + var(--glare-caption-inset))}.glare-toolbar{--glare-toolbar-gap: 4px;--glare-toolbar-padding: 3px;top:8px;right:8px}.glare-button--more{display:inline-flex}.glare-toolbar-menu{position:absolute;top:calc(100% + 8px);right:calc(var(--glare-button-size) + var(--glare-toolbar-gap) + var(--glare-toolbar-padding));display:flex;flex-direction:column;gap:4px;width:max-content;max-width:calc(100vw - 2 * var(--glare-inset-x));padding:6px;border:1px solid var(--glare-border);border-radius:16px;background:var(--glare-toolbar-bg);-webkit-backdrop-filter:var(--glare-blur);backdrop-filter:var(--glare-blur);opacity:0;visibility:hidden;transform:translateY(-8px) scale(.96);transform-origin:top right;pointer-events:none;transition:opacity .16s ease,transform .16s ease,visibility .16s}.glare-toolbar-menu .glare-button{justify-content:flex-start;width:100%;padding:0 12px;border-radius:10px;gap:10px}.glare-toolbar-menu .glare-button:after{content:attr(aria-label);overflow:hidden;font-size:13px;line-height:1;text-overflow:ellipsis;white-space:nowrap}.glare-toolbar--expanded .glare-toolbar-menu{opacity:1;visibility:visible;transform:translateY(0) scale(1);pointer-events:auto}.glare-close-small{top:8px;right:8px}.glare-infobar{top:12px;left:12px;font-size:12px}.glare-button--prev,.glare-button--next{width:44px;height:44px}.glare-button--prev{left:8px}.glare-button--next{right:8px}.glare-thumbs--y,.glare-thumbs-axis-y [data-glare-thumbs]{display:none}.glare-show-thumbs.glare-thumbs-axis-y{--glare-inset-x: 16px}}