@smartimpact-it/modern-video-embed 2.0.1
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 +1205 -0
- package/dist/components/VimeoEmbed.d.ts +143 -0
- package/dist/components/VimeoEmbed.d.ts.map +1 -0
- package/dist/components/VimeoEmbed.js +1176 -0
- package/dist/components/VimeoEmbed.js.map +1 -0
- package/dist/components/VimeoEmbed.min.js +1 -0
- package/dist/components/YouTubeEmbed.d.ts +225 -0
- package/dist/components/YouTubeEmbed.d.ts.map +1 -0
- package/dist/components/YouTubeEmbed.js +1354 -0
- package/dist/components/YouTubeEmbed.js.map +1 -0
- package/dist/components/YouTubeEmbed.min.js +1 -0
- package/dist/css/components.css +349 -0
- package/dist/css/components.css.map +1 -0
- package/dist/css/components.min.css +1 -0
- package/dist/css/main.css +12210 -0
- package/dist/css/main.css.map +1 -0
- package/dist/css/main.min.css +7 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/vimeo-only.d.ts +7 -0
- package/dist/vimeo-only.d.ts.map +1 -0
- package/dist/vimeo-only.js +8 -0
- package/dist/vimeo-only.js.map +1 -0
- package/dist/vimeo-only.min.js +1 -0
- package/dist/youtube-only.d.ts +7 -0
- package/dist/youtube-only.d.ts.map +1 -0
- package/dist/youtube-only.js +8 -0
- package/dist/youtube-only.js.map +1 -0
- package/dist/youtube-only.min.js +1 -0
- package/package.json +75 -0
- package/src/components/VimeoEmbed.ts +1340 -0
- package/src/components/YouTubeEmbed.ts +1568 -0
- package/src/index.ts +3 -0
- package/src/styles/README.md +56 -0
- package/src/styles/components.scss +7 -0
- package/src/styles/main.scss +10 -0
- package/src/styles/vimeo-embed.scss +255 -0
- package/src/styles/youtube-embed.scss +261 -0
- package/src/types/common.d.ts +198 -0
- package/src/types/index.ts +7 -0
- package/src/types/vimeo-embed.d.ts +80 -0
- package/src/types/youtube-embed.d.ts +83 -0
- package/src/vimeo-only.ts +9 -0
- package/src/youtube-only.ts +9 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# CSS Files
|
|
2
|
+
|
|
3
|
+
This directory contains the styles for the video embed components.
|
|
4
|
+
|
|
5
|
+
## For Production/Integration
|
|
6
|
+
|
|
7
|
+
Use `components.css` when integrating into your website:
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<!-- Minimal CSS - Components only -->
|
|
11
|
+
<link rel="stylesheet" href="path/to/dist/css/components.css" />
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
This file contains **only** the essential styles for:
|
|
15
|
+
|
|
16
|
+
- `youtube-embed` component
|
|
17
|
+
- `vimeo-embed` component
|
|
18
|
+
|
|
19
|
+
**Size:** ~15KB (much smaller, no Bootstrap)
|
|
20
|
+
|
|
21
|
+
## For Demos/Examples
|
|
22
|
+
|
|
23
|
+
Use `main.css` for demos and examples:
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<!-- Full CSS - Components + Bootstrap -->
|
|
27
|
+
<link rel="stylesheet" href="path/to/dist/css/main.css" />
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This file includes:
|
|
31
|
+
|
|
32
|
+
- Bootstrap framework (~200KB)
|
|
33
|
+
- Video embed component styles
|
|
34
|
+
|
|
35
|
+
**Size:** ~215KB (includes full Bootstrap)
|
|
36
|
+
|
|
37
|
+
## Source Files
|
|
38
|
+
|
|
39
|
+
- `components.scss` - Production build (components only)
|
|
40
|
+
- `main.scss` - Demo build (Bootstrap + components)
|
|
41
|
+
- `youtube-embed.scss` - YouTube component styles
|
|
42
|
+
- `vimeo-embed.scss` - Vimeo component styles
|
|
43
|
+
|
|
44
|
+
## Building
|
|
45
|
+
|
|
46
|
+
Both CSS files are automatically built when you run:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm run build
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or watch for changes:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm run watch
|
|
56
|
+
```
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Video Embed Components - Production Styles
|
|
2
|
+
// This file contains only the essential styles needed for the video embed components
|
|
3
|
+
// Use this when integrating into your website
|
|
4
|
+
|
|
5
|
+
// Import our custom video embed styles
|
|
6
|
+
@import "./youtube-embed.scss";
|
|
7
|
+
@import "./vimeo-embed.scss";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Video Embed Components - Demo Styles
|
|
2
|
+
// This file includes Bootstrap and component styles for demos and examples
|
|
3
|
+
// For production integration, use components.scss instead
|
|
4
|
+
|
|
5
|
+
// Import Bootstrap SCSS (only needed for demos)
|
|
6
|
+
@import "../../node_modules/bootstrap/scss/bootstrap";
|
|
7
|
+
|
|
8
|
+
// Import our custom video embed styles
|
|
9
|
+
@import "./youtube-embed.scss";
|
|
10
|
+
@import "./vimeo-embed.scss";
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG encoding functions (shared with YouTube embed)
|
|
3
|
+
*/
|
|
4
|
+
@function svg-str-replace($string, $search, $replace: "") {
|
|
5
|
+
$index: str-index($string, $search);
|
|
6
|
+
@if $index {
|
|
7
|
+
@return str-slice($string, 1, $index - 1) + $replace +
|
|
8
|
+
svg-str-replace(
|
|
9
|
+
str-slice($string, $index + str-length($search)),
|
|
10
|
+
$search,
|
|
11
|
+
$replace
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
@return $string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@function svg-url-encode($string) {
|
|
18
|
+
$map: (
|
|
19
|
+
"%": "%25",
|
|
20
|
+
"<": "%3C",
|
|
21
|
+
">": "%3E",
|
|
22
|
+
" ": "%20",
|
|
23
|
+
"!": "%21",
|
|
24
|
+
"*": "%2A",
|
|
25
|
+
"'": "%27",
|
|
26
|
+
'"': "%22",
|
|
27
|
+
"(": "%28",
|
|
28
|
+
")": "%29",
|
|
29
|
+
";": "%3B",
|
|
30
|
+
":": "%3A",
|
|
31
|
+
"@": "%40",
|
|
32
|
+
"&": "%26",
|
|
33
|
+
"=": "%3D",
|
|
34
|
+
"+": "%2B",
|
|
35
|
+
"$": "%24",
|
|
36
|
+
",": "%2C",
|
|
37
|
+
"/": "%2F",
|
|
38
|
+
"?": "%3F",
|
|
39
|
+
"#": "%23",
|
|
40
|
+
"[": "%5B",
|
|
41
|
+
"]": "%5D",
|
|
42
|
+
);
|
|
43
|
+
$new: $string;
|
|
44
|
+
@each $search, $replace in $map {
|
|
45
|
+
$new: #{svg-str-replace($new, $search, $replace)};
|
|
46
|
+
}
|
|
47
|
+
@return $new;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@function inline-svg($string) {
|
|
51
|
+
@return url("data:image/svg+xml;utf8,#{svg-url-encode($string)}");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
vimeo-embed {
|
|
55
|
+
// CSS Variables for customization
|
|
56
|
+
--video-aspect-ratio: 56.25%; // Default 16:9
|
|
57
|
+
--poster-object-fit: cover;
|
|
58
|
+
--video-object-fit: contain;
|
|
59
|
+
--control-button-size: 70px;
|
|
60
|
+
--control-button-color: #ffffff;
|
|
61
|
+
--overlay-background-color: rgba(0, 0, 0, 0.5);
|
|
62
|
+
|
|
63
|
+
display: block;
|
|
64
|
+
position: relative;
|
|
65
|
+
width: 100%;
|
|
66
|
+
padding-top: var(--video-aspect-ratio);
|
|
67
|
+
overflow: hidden;
|
|
68
|
+
background-color: #000;
|
|
69
|
+
|
|
70
|
+
iframe {
|
|
71
|
+
position: absolute;
|
|
72
|
+
top: 0;
|
|
73
|
+
left: 0;
|
|
74
|
+
width: 100%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
border: none;
|
|
77
|
+
object-fit: var(--video-object-fit);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Poster image
|
|
81
|
+
.vimeo-poster,
|
|
82
|
+
.video-poster {
|
|
83
|
+
position: absolute;
|
|
84
|
+
top: 0;
|
|
85
|
+
left: 0;
|
|
86
|
+
width: 100%;
|
|
87
|
+
height: 100%;
|
|
88
|
+
object-fit: var(--poster-object-fit);
|
|
89
|
+
display: block;
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Custom control overlay
|
|
94
|
+
.button-overlay {
|
|
95
|
+
background: var(--overlay-background-color);
|
|
96
|
+
cursor: pointer;
|
|
97
|
+
display: flex;
|
|
98
|
+
align-items: center;
|
|
99
|
+
justify-content: center;
|
|
100
|
+
position: absolute;
|
|
101
|
+
left: 0;
|
|
102
|
+
top: 0;
|
|
103
|
+
right: 0;
|
|
104
|
+
bottom: 0;
|
|
105
|
+
height: 100%;
|
|
106
|
+
width: 100%;
|
|
107
|
+
transition: opacity 0.3s ease;
|
|
108
|
+
z-index: 10;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&.is-playing .button-overlay {
|
|
112
|
+
opacity: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&.is-playing:hover .button-overlay {
|
|
116
|
+
opacity: 1;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.button-overlay .button {
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
display: flex;
|
|
122
|
+
align-items: center;
|
|
123
|
+
justify-content: center;
|
|
124
|
+
height: var(--control-button-size);
|
|
125
|
+
width: var(--control-button-size);
|
|
126
|
+
background-image: inline-svg(
|
|
127
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#ffffff" d="M8,5.14V19.14L19,12.14L8,5.14Z" /></svg>'
|
|
128
|
+
);
|
|
129
|
+
background-size: cover;
|
|
130
|
+
background-repeat: no-repeat;
|
|
131
|
+
background-position: center;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
&.is-playing .button-overlay .button {
|
|
135
|
+
background-image: inline-svg(
|
|
136
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#ffffff" d="M14,19H18V5H14M6,19H10V5H6V19Z" /></svg>'
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Background mode styles
|
|
141
|
+
&.is-background {
|
|
142
|
+
padding-top: 0;
|
|
143
|
+
position: absolute;
|
|
144
|
+
height: 100%;
|
|
145
|
+
width: 100%;
|
|
146
|
+
top: 0;
|
|
147
|
+
left: 0;
|
|
148
|
+
z-index: 0;
|
|
149
|
+
overflow: hidden;
|
|
150
|
+
background: #000;
|
|
151
|
+
|
|
152
|
+
iframe {
|
|
153
|
+
position: absolute;
|
|
154
|
+
top: 50%;
|
|
155
|
+
left: 50%;
|
|
156
|
+
transform: translate(-50%, -50%);
|
|
157
|
+
|
|
158
|
+
min-width: 100%;
|
|
159
|
+
min-height: 100%;
|
|
160
|
+
width: auto;
|
|
161
|
+
height: auto;
|
|
162
|
+
|
|
163
|
+
@supports (aspect-ratio: 16 / 9) {
|
|
164
|
+
aspect-ratio: 16 / 9;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
pointer-events: none;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.button-overlay {
|
|
171
|
+
display: none;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// When background controls are enabled
|
|
176
|
+
&.has-background-controls {
|
|
177
|
+
.button-overlay {
|
|
178
|
+
display: flex;
|
|
179
|
+
background: none;
|
|
180
|
+
justify-content: flex-end;
|
|
181
|
+
align-items: flex-end;
|
|
182
|
+
padding: 1rem;
|
|
183
|
+
|
|
184
|
+
.button {
|
|
185
|
+
--control-button-size: 40px;
|
|
186
|
+
opacity: 0.7;
|
|
187
|
+
transition: opacity 0.2s ease;
|
|
188
|
+
&:hover {
|
|
189
|
+
opacity: 1;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
&.is-playing .button-overlay {
|
|
195
|
+
opacity: 0;
|
|
196
|
+
&:hover {
|
|
197
|
+
opacity: 1;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Error message styling
|
|
203
|
+
.vimeo-error-message {
|
|
204
|
+
position: absolute;
|
|
205
|
+
top: 0;
|
|
206
|
+
left: 0;
|
|
207
|
+
width: 100%;
|
|
208
|
+
height: 100%;
|
|
209
|
+
display: flex;
|
|
210
|
+
align-items: center;
|
|
211
|
+
justify-content: center;
|
|
212
|
+
background: rgba(0, 0, 0, 0.9);
|
|
213
|
+
color: white;
|
|
214
|
+
z-index: 1000;
|
|
215
|
+
|
|
216
|
+
.error-content {
|
|
217
|
+
text-align: center;
|
|
218
|
+
padding: 2rem;
|
|
219
|
+
max-width: 400px;
|
|
220
|
+
|
|
221
|
+
svg {
|
|
222
|
+
color: #00adef;
|
|
223
|
+
margin-bottom: 1rem;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.error-message {
|
|
227
|
+
margin: 1rem 0;
|
|
228
|
+
font-size: 1rem;
|
|
229
|
+
line-height: 1.5;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.retry-button {
|
|
233
|
+
margin-top: 1rem;
|
|
234
|
+
padding: 0.75rem 1.5rem;
|
|
235
|
+
background: #00adef;
|
|
236
|
+
color: white;
|
|
237
|
+
border: none;
|
|
238
|
+
border-radius: 4px;
|
|
239
|
+
cursor: pointer;
|
|
240
|
+
font-size: 1rem;
|
|
241
|
+
font-weight: 600;
|
|
242
|
+
transition: background 0.2s ease;
|
|
243
|
+
|
|
244
|
+
&:hover {
|
|
245
|
+
background: #0088bf;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
&:focus {
|
|
249
|
+
outline: 2px solid white;
|
|
250
|
+
outline-offset: 2px;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG encoding functions
|
|
3
|
+
*/
|
|
4
|
+
@function svg-str-replace($string, $search, $replace: "") {
|
|
5
|
+
$index: str-index($string, $search);
|
|
6
|
+
@if $index {
|
|
7
|
+
@return str-slice($string, 1, $index - 1) + $replace +
|
|
8
|
+
svg-str-replace(
|
|
9
|
+
str-slice($string, $index + str-length($search)),
|
|
10
|
+
$search,
|
|
11
|
+
$replace
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
@return $string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@function svg-url-encode($string) {
|
|
18
|
+
$map: (
|
|
19
|
+
"%": "%25",
|
|
20
|
+
"<": "%3C",
|
|
21
|
+
">": "%3E",
|
|
22
|
+
" ": "%20",
|
|
23
|
+
"!": "%21",
|
|
24
|
+
"*": "%2A",
|
|
25
|
+
"'": "%27",
|
|
26
|
+
'"': "%22",
|
|
27
|
+
"(": "%28",
|
|
28
|
+
")": "%29",
|
|
29
|
+
";": "%3B",
|
|
30
|
+
":": "%3A",
|
|
31
|
+
"@": "%40",
|
|
32
|
+
"&": "%26",
|
|
33
|
+
"=": "%3D",
|
|
34
|
+
"+": "%2B",
|
|
35
|
+
"$": "%24",
|
|
36
|
+
",": "%2C",
|
|
37
|
+
"/": "%2F",
|
|
38
|
+
"?": "%3F",
|
|
39
|
+
"#": "%23",
|
|
40
|
+
"[": "%5B",
|
|
41
|
+
"]": "%5D",
|
|
42
|
+
);
|
|
43
|
+
$new: $string;
|
|
44
|
+
@each $search, $replace in $map {
|
|
45
|
+
$new: #{svg-str-replace($new, $search, $replace)};
|
|
46
|
+
}
|
|
47
|
+
@return $new;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@function inline-svg($string) {
|
|
51
|
+
@return url("data:image/svg+xml;utf8,#{svg-url-encode($string)}");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
youtube-embed {
|
|
55
|
+
// CSS Variables for customization
|
|
56
|
+
--video-aspect-ratio: 56.25%; // Default 16:9
|
|
57
|
+
--poster-object-fit: cover;
|
|
58
|
+
--video-object-fit: contain;
|
|
59
|
+
--control-button-size: 70px;
|
|
60
|
+
--control-button-color: #ffffff;
|
|
61
|
+
--overlay-background-color: rgba(0, 0, 0, 0.5);
|
|
62
|
+
|
|
63
|
+
display: block;
|
|
64
|
+
position: relative;
|
|
65
|
+
width: 100%;
|
|
66
|
+
padding-top: var(--video-aspect-ratio);
|
|
67
|
+
overflow: hidden;
|
|
68
|
+
background-color: #000;
|
|
69
|
+
|
|
70
|
+
iframe {
|
|
71
|
+
position: absolute;
|
|
72
|
+
top: 0;
|
|
73
|
+
left: 0;
|
|
74
|
+
width: 100%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
border: none;
|
|
77
|
+
object-fit: var(--video-object-fit);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Poster image (now appended directly to element)
|
|
81
|
+
.youtube-poster,
|
|
82
|
+
.video-poster {
|
|
83
|
+
position: absolute;
|
|
84
|
+
top: 0;
|
|
85
|
+
left: 0;
|
|
86
|
+
width: 100%;
|
|
87
|
+
height: 100%;
|
|
88
|
+
object-fit: var(--poster-object-fit);
|
|
89
|
+
display: block;
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Custom control overlay (when controls=false)
|
|
94
|
+
.button-overlay {
|
|
95
|
+
background: var(--overlay-background-color);
|
|
96
|
+
cursor: pointer;
|
|
97
|
+
display: flex;
|
|
98
|
+
align-items: center;
|
|
99
|
+
justify-content: center;
|
|
100
|
+
position: absolute;
|
|
101
|
+
left: 0;
|
|
102
|
+
top: 0;
|
|
103
|
+
right: 0;
|
|
104
|
+
bottom: 0;
|
|
105
|
+
height: 100%;
|
|
106
|
+
width: 100%;
|
|
107
|
+
transition: opacity 0.3s ease;
|
|
108
|
+
z-index: 10;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&.is-playing .button-overlay {
|
|
112
|
+
opacity: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&.is-playing:hover .button-overlay {
|
|
116
|
+
opacity: 1;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.button-overlay .button {
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
display: flex;
|
|
122
|
+
align-items: center;
|
|
123
|
+
justify-content: center;
|
|
124
|
+
height: var(--control-button-size);
|
|
125
|
+
width: var(--control-button-size);
|
|
126
|
+
background-image: inline-svg(
|
|
127
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#ffffff" d="M8,5.14V19.14L19,12.14L8,5.14Z" /></svg>'
|
|
128
|
+
);
|
|
129
|
+
background-size: cover;
|
|
130
|
+
background-repeat: no-repeat;
|
|
131
|
+
background-position: center;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
&.is-playing .button-overlay .button {
|
|
135
|
+
background-image: inline-svg(
|
|
136
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#ffffff" d="M14,19H18V5H14M6,19H10V5H6V19Z" /></svg>'
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Background mode styles
|
|
141
|
+
&.is-background {
|
|
142
|
+
padding-top: 0;
|
|
143
|
+
position: absolute;
|
|
144
|
+
height: 100%;
|
|
145
|
+
width: 100%;
|
|
146
|
+
top: 0;
|
|
147
|
+
left: 0;
|
|
148
|
+
z-index: 0;
|
|
149
|
+
overflow: hidden;
|
|
150
|
+
background: #000;
|
|
151
|
+
|
|
152
|
+
iframe {
|
|
153
|
+
position: absolute;
|
|
154
|
+
top: 50%;
|
|
155
|
+
left: 50%;
|
|
156
|
+
transform: translate(-50%, -50%);
|
|
157
|
+
|
|
158
|
+
// Using min-width and min-height with larger percentage to ensure coverage
|
|
159
|
+
// This technique makes the video always cover the container
|
|
160
|
+
min-width: 100%;
|
|
161
|
+
min-height: 100%;
|
|
162
|
+
width: auto;
|
|
163
|
+
height: auto;
|
|
164
|
+
|
|
165
|
+
// For 16:9 video: make it large enough to cover any aspect ratio container
|
|
166
|
+
@supports (aspect-ratio: 16 / 9) {
|
|
167
|
+
aspect-ratio: 16 / 9;
|
|
168
|
+
// If container is wider, video height = 100% and width expands
|
|
169
|
+
// If container is taller, video width = 100% and height expands
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
pointer-events: none;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.button-overlay {
|
|
176
|
+
display: none;
|
|
177
|
+
}
|
|
178
|
+
} // When background controls are enabled
|
|
179
|
+
&.has-background-controls {
|
|
180
|
+
.button-overlay {
|
|
181
|
+
display: flex;
|
|
182
|
+
background: none;
|
|
183
|
+
// Position controls in the bottom right
|
|
184
|
+
justify-content: flex-end;
|
|
185
|
+
align-items: flex-end;
|
|
186
|
+
padding: 1rem;
|
|
187
|
+
|
|
188
|
+
.button {
|
|
189
|
+
// Smaller, more discreet button
|
|
190
|
+
--control-button-size: 40px;
|
|
191
|
+
opacity: 0.7;
|
|
192
|
+
transition: opacity 0.2s ease;
|
|
193
|
+
&:hover {
|
|
194
|
+
opacity: 1;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Hide the button when playing, but show on hover
|
|
200
|
+
&.is-playing .button-overlay {
|
|
201
|
+
opacity: 0;
|
|
202
|
+
&:hover {
|
|
203
|
+
opacity: 1;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Error message styling
|
|
209
|
+
.youtube-error-message {
|
|
210
|
+
position: absolute;
|
|
211
|
+
top: 0;
|
|
212
|
+
left: 0;
|
|
213
|
+
width: 100%;
|
|
214
|
+
height: 100%;
|
|
215
|
+
display: flex;
|
|
216
|
+
align-items: center;
|
|
217
|
+
justify-content: center;
|
|
218
|
+
background: rgba(0, 0, 0, 0.9);
|
|
219
|
+
color: white;
|
|
220
|
+
z-index: 1000;
|
|
221
|
+
|
|
222
|
+
.error-content {
|
|
223
|
+
text-align: center;
|
|
224
|
+
padding: 2rem;
|
|
225
|
+
max-width: 400px;
|
|
226
|
+
|
|
227
|
+
svg {
|
|
228
|
+
color: #ff4444;
|
|
229
|
+
margin-bottom: 1rem;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.error-message {
|
|
233
|
+
margin: 1rem 0;
|
|
234
|
+
font-size: 1rem;
|
|
235
|
+
line-height: 1.5;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.retry-button {
|
|
239
|
+
margin-top: 1rem;
|
|
240
|
+
padding: 0.75rem 1.5rem;
|
|
241
|
+
background: #ff0000;
|
|
242
|
+
color: white;
|
|
243
|
+
border: none;
|
|
244
|
+
border-radius: 4px;
|
|
245
|
+
cursor: pointer;
|
|
246
|
+
font-size: 1rem;
|
|
247
|
+
font-weight: 600;
|
|
248
|
+
transition: background 0.2s ease;
|
|
249
|
+
|
|
250
|
+
&:hover {
|
|
251
|
+
background: #cc0000;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
&:focus {
|
|
255
|
+
outline: 2px solid white;
|
|
256
|
+
outline-offset: 2px;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|