@shift72/core-template 1.9.25 → 1.9.26
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/.nvmrc +1 -1
- package/CHANGELOG.md +34 -1
- package/kibble.json +4 -3
- package/package.json +16 -7
- package/rollup.config.js +10 -4
- package/site/ar_LB.all.json +7 -7
- package/site/ca_ES.all.json +2 -2
- package/site/da_DK.all.json +2 -2
- package/site/de_DE.all.json +3 -3
- package/site/el_EL.all.json +2 -2
- package/site/en_AU.all.json +2 -2
- package/site/es_ES.all.json +5 -5
- package/site/es_MX.all.json +5 -5
- package/site/et_ET.all.json +3 -3
- package/site/fi_FI.all.json +4 -4
- package/site/fr_FR.all.json +3 -3
- package/site/hr_HR.all.json +3 -3
- package/site/hu_HU.all.json +3 -3
- package/site/it_IT.all.json +7 -7
- package/site/ja_JP.all.json +7 -7
- package/site/lt_LT.all.json +2 -2
- package/site/nl_BE.all.json +3 -3
- package/site/no_NO.all.json +3 -3
- package/site/pl_PL.all.json +3 -3
- package/site/pt_BR.all.json +3 -3
- package/site/pt_PT.all.json +3 -3
- package/site/ru_RU.all.json +5 -5
- package/site/sr_SR.all.json +3 -3
- package/site/static/js/comments.js +9 -0
- package/site/static/js/detail-player/detail-player-iframe.component.js +24 -0
- package/site/static/js/detail-player/detail-player-placeholder.component.js +161 -0
- package/site/static/js/detail-player/detail-player.component.js +54 -0
- package/site/static/js/detail-player/icons.js +31 -0
- package/site/static/js/main.js +10 -0
- package/site/styles/_carousel.scss +10 -0
- package/site/styles/_collections.scss +7 -1
- package/site/styles/_detail-player.scss +182 -0
- package/site/styles/_forms.scss +3 -1
- package/site/styles/_globals.scss +11 -0
- package/site/styles/_legacy.scss +57 -55
- package/site/styles/_meta-detail-creator.scss +82 -0
- package/site/styles/_meta-detail.scss +19 -2
- package/site/styles/_meta-item-tagline.scss +7 -0
- package/site/styles/_meta-item-title.scss +1 -1
- package/site/styles/_meta-item.scss +3 -0
- package/site/styles/_nav.scss +1 -0
- package/site/styles/_poster.scss +29 -0
- package/site/styles/_search.scss +2 -0
- package/site/styles/_slider.scss +4 -4
- package/site/styles/_swiper.scss +17 -0
- package/site/styles/_typography.scss +6 -3
- package/site/styles/_variables.scss +33 -2
- package/site/styles/main.scss +2 -0
- package/site/templates/application/application.jet +8 -2
- package/site/templates/application/google.jet +3 -1
- package/site/templates/application/head/seo.jet +3 -0
- package/site/templates/application/pixel.jet +1 -1
- package/site/templates/collection/carousel/item/video.jet +3 -3
- package/site/templates/common/cta_buttons.jet +3 -1
- package/site/templates/film/item.jet +15 -3
- package/site/templates/film/title.jet +3 -3
- package/site/tr_TR.all.json +6 -6
- package/site/uk_UA.all.json +3 -3
- package/site/zh_TW.all.json +8 -8
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Component } from 's72.ui';
|
|
2
|
+
|
|
3
|
+
export class DetailPlayerIframe extends Component {
|
|
4
|
+
constructor(props, context) {
|
|
5
|
+
super(props, context);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
render(props) {
|
|
9
|
+
const {slug, onLoad} = props;
|
|
10
|
+
let startTime = new URLSearchParams(window.location.search).get('t');
|
|
11
|
+
let t = startTime ? startTime : 0;
|
|
12
|
+
return (
|
|
13
|
+
<iframe
|
|
14
|
+
id="detail-player"
|
|
15
|
+
src={`/play/#${slug}?tm=true&t=${t}&from=`}
|
|
16
|
+
width="100%"
|
|
17
|
+
height="100%"
|
|
18
|
+
frameborder={0}
|
|
19
|
+
allowFullScreen
|
|
20
|
+
onLoad={onLoad}
|
|
21
|
+
></iframe>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { i18n } from 's72';
|
|
2
|
+
import { AppComponent, classes } from 's72.ui';
|
|
3
|
+
import { LockOpenIcon, LockClosedIcon, PlayIcon } from './icons';
|
|
4
|
+
|
|
5
|
+
export class DetailPlayerPlaceholder extends AppComponent {
|
|
6
|
+
|
|
7
|
+
constructor(props, context) {
|
|
8
|
+
super(props, context);
|
|
9
|
+
this.state = {
|
|
10
|
+
bgLoaded: !!!props.bgImage,
|
|
11
|
+
titleLoaded: !!!props.titleImage,
|
|
12
|
+
availabilityLoaded: false,
|
|
13
|
+
canBeWatched: false,
|
|
14
|
+
wigglin: false,
|
|
15
|
+
playClicked: false,
|
|
16
|
+
purchaseCompleted: false,
|
|
17
|
+
unlockBegin: false,
|
|
18
|
+
unlockAnim: 0,
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async componentDidMount() {
|
|
23
|
+
this.app.messagebus.subscribe('shopping-session-completed', async () => {
|
|
24
|
+
if (await this.canBeWatched()) {
|
|
25
|
+
this.setState({ purchaseCompleted: true });
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
window.addEventListener('message', e => {
|
|
29
|
+
if (e.data.event == 's72-checkout:close' && this.state.purchaseCompleted) {
|
|
30
|
+
this.playUnlockAnimation();
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
this.setState({ availabilityLoaded: true, canBeWatched: await this.canBeWatched() });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
componentWillUnmount() {
|
|
37
|
+
this.app.messagebus.unsubscribe('shopping-session-completed');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
canBeWatched() {
|
|
41
|
+
return this.app.availabilityService.getAvailability(this.props.slug)
|
|
42
|
+
.then(a => a?.canBeWatched ?? false)
|
|
43
|
+
.catch(() => false);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
render(props, state) {
|
|
47
|
+
const {playerLoaded} = props;
|
|
48
|
+
const showPlaceholder = (state.availabilityLoaded && state.bgLoaded && state.titleLoaded) && !playerLoaded;
|
|
49
|
+
return (
|
|
50
|
+
<div
|
|
51
|
+
class={classes('detail-player-placeholder', {'detail-player-placeholder--visible': showPlaceholder})}
|
|
52
|
+
onClick={() => this.playWiggleAnimation()}
|
|
53
|
+
>
|
|
54
|
+
{this.placeholderBG()}
|
|
55
|
+
<div class="detail-player-placeholder-overlay">
|
|
56
|
+
{state.canBeWatched && this.playButton() }
|
|
57
|
+
{!state.canBeWatched && this.lockedMessage()}
|
|
58
|
+
<div class="detail-player-placeholder-gradient" />
|
|
59
|
+
{this.titleLogo()}
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
placeholderBG() {
|
|
66
|
+
return (
|
|
67
|
+
<ImageLoader
|
|
68
|
+
src={this.props.bgImage}
|
|
69
|
+
state={this.state.bgLoaded}
|
|
70
|
+
onLoad={() => this.setState({ bgLoaded: true })}
|
|
71
|
+
>
|
|
72
|
+
<div
|
|
73
|
+
class="detail-player-placeholder-bg"
|
|
74
|
+
style={`background-image: url(${this.props.bgImage})`}
|
|
75
|
+
/>
|
|
76
|
+
</ImageLoader>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
titleLogo() {
|
|
81
|
+
return (
|
|
82
|
+
<ImageLoader
|
|
83
|
+
src={this.props.titleImage}
|
|
84
|
+
state={this.state.titleLoaded}
|
|
85
|
+
onLoad={() => this.setState({ titleLoaded: true })}
|
|
86
|
+
>
|
|
87
|
+
<img
|
|
88
|
+
class="detail-player-placeholder-title"
|
|
89
|
+
src={this.props.titleImage}
|
|
90
|
+
/>
|
|
91
|
+
</ImageLoader>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
playWiggleAnimation() {
|
|
96
|
+
if (!this.state.wigglin && !this.state.unlockBegin) {
|
|
97
|
+
this.setState({ wigglin: true });
|
|
98
|
+
setTimeout(() => {
|
|
99
|
+
this.setState({ wigglin: false });
|
|
100
|
+
}, 900);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
lockedMessage() {
|
|
105
|
+
return (
|
|
106
|
+
<div class={classes('detail-player-locked-message', {'detail-player-locked-message--unlocked': this.state.unlockBegin})}>
|
|
107
|
+
<div class={classes('detail-player-lock-icon-wrapper', {
|
|
108
|
+
'detail-player-lock-icon-wrapper--wiggle': this.state.wigglin,
|
|
109
|
+
'detail-player-lock-icon-wrapper--large': this.state.unlockBegin
|
|
110
|
+
})}>
|
|
111
|
+
<div class={`detail-player-lock-icon detail-player-lock-icon--anim-${this.state.unlockAnim}`}>
|
|
112
|
+
{this.state.unlockAnim < 2 ? <LockClosedIcon /> : <LockOpenIcon />}
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
<span class={classes('detail-player-locked-message-text', { 'detail-player-locked-message-text--unlocked': this.state.unlockBegin })}>
|
|
116
|
+
{i18n('detail_player_subscribe')}
|
|
117
|
+
</span>
|
|
118
|
+
</div>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
playButton() {
|
|
123
|
+
return (
|
|
124
|
+
<div class={classes('detail-player-play-button', {'detail-player-play-button--clicked': this.state.playClicked})}
|
|
125
|
+
onClick={() => {
|
|
126
|
+
this.setState({ playClicked: true });
|
|
127
|
+
this.props.showPlayer();
|
|
128
|
+
}}
|
|
129
|
+
>
|
|
130
|
+
<PlayIcon />
|
|
131
|
+
</div>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
playUnlockAnimation() {
|
|
136
|
+
setTimeout(() => { this.setState({ unlockBegin: true }) }, 500);
|
|
137
|
+
setTimeout(() => { this.setState({ unlockAnim: 1 }); }, 1000);
|
|
138
|
+
setTimeout(() => { this.setState({ unlockAnim: 2 }); }, 1800);
|
|
139
|
+
setTimeout(() => { this.setState({ unlockAnim: 3 }); }, 1900);
|
|
140
|
+
setTimeout(() => { this.props.showPlayer() }, 2000);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function ImageLoader(props) {
|
|
146
|
+
const {src, state, onLoad, children} = props;
|
|
147
|
+
if (!src) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
return (
|
|
151
|
+
<div>
|
|
152
|
+
{!state && <img
|
|
153
|
+
class="detail-player-image-loader"
|
|
154
|
+
src={src}
|
|
155
|
+
onLoad={onLoad()}
|
|
156
|
+
onError={onLoad()}
|
|
157
|
+
/>}
|
|
158
|
+
{state && children}
|
|
159
|
+
</div>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { bindEachComponent, AppComponent, attrs, h, render } from 's72.ui';
|
|
2
|
+
import { DetailPlayerIframe } from './detail-player-iframe.component';
|
|
3
|
+
import { DetailPlayerPlaceholder } from './detail-player-placeholder.component';
|
|
4
|
+
|
|
5
|
+
export default class DetailPlayer extends AppComponent {
|
|
6
|
+
|
|
7
|
+
constructor(props, context) {
|
|
8
|
+
super(props, context);
|
|
9
|
+
this.state = {
|
|
10
|
+
playerLoaded: false,
|
|
11
|
+
playerVisible: false,
|
|
12
|
+
placeholderVisible: true,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
componentDidMount() {
|
|
17
|
+
window.addEventListener('message', e => {
|
|
18
|
+
const {event, value} = e.data;
|
|
19
|
+
if (event == 's72-player:theatre-mode-change') {
|
|
20
|
+
const container = document.querySelector('#main .detail-player-container');
|
|
21
|
+
container.querySelector('detail-player').scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
22
|
+
container.classList.toggle('detail-player-theatre-mode', value);
|
|
23
|
+
document.querySelector('.meta-detail-bg').classList.toggle('meta-detail-bg--lights-out', value);
|
|
24
|
+
document.querySelector('.poster-wrapper').classList.toggle('d-none', value);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
render(props, state) {
|
|
30
|
+
if (!props.slug) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
return (
|
|
34
|
+
<div class="detail-player-inner">
|
|
35
|
+
{state.playerVisible && <DetailPlayerIframe
|
|
36
|
+
slug={props.slug}
|
|
37
|
+
onLoad={() => {
|
|
38
|
+
this.setState({ playerLoaded: true });
|
|
39
|
+
setTimeout(() => this.setState({ placeholderVisible: false }), 1000);
|
|
40
|
+
}}
|
|
41
|
+
/>}
|
|
42
|
+
{state.placeholderVisible && <DetailPlayerPlaceholder
|
|
43
|
+
slug={props.slug}
|
|
44
|
+
bgImage={props.bgImage}
|
|
45
|
+
titleImage={props.titleImage}
|
|
46
|
+
showPlayer={() => setTimeout(() => this.setState({ playerVisible: true }), 500)}
|
|
47
|
+
playerLoaded={state.playerLoaded}
|
|
48
|
+
/>}
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
bindEachComponent('detail-player', e => render(h(DetailPlayer, attrs(e)), e));
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const LockClosedIcon = (props) => {
|
|
2
|
+
return (
|
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="1em" height="1em" viewBox="0 0 50 50">
|
|
4
|
+
<path d="M 25 3 C 18.364481 3 13 8.3644809 13 15 L 13 20 L 9 20 C 7.3545455 20 6 21.354545 6 23 L 6 47 C 6 48.645455 7.3545455 50 9 50 L 41 50 C 42.645455 50 44 48.645455 44 47 L 44 23 C 44 21.354545 42.645455 20 41 20 L 37 20 L 37 15 C 37 8.3644809 31.635519 3 25 3 z M 25 5 C 30.564481 5 35 9.4355191 35 15 L 35 20 L 15 20 L 15 15 C 15 9.4355191 19.435519 5 25 5 z M 9 22 L 13.832031 22 A 1.0001 1.0001 0 0 0 14.158203 22 L 35.832031 22 A 1.0001 1.0001 0 0 0 36.158203 22 L 41 22 C 41.554545 22 42 22.445455 42 23 L 42 47 C 42 47.554545 41.554545 48 41 48 L 9 48 C 8.4454545 48 8 47.554545 8 47 L 8 23 C 8 22.445455 8.4454545 22 9 22 z M 25 30 C 23.3 30 22 31.3 22 33 C 22 33.9 22.4 34.699219 23 35.199219 L 23 38 C 23 39.1 23.9 40 25 40 C 26.1 40 27 39.1 27 38 L 27 35.199219 C 27.6 34.699219 28 33.9 28 33 C 28 31.3 26.7 30 25 30 z"></path>
|
|
5
|
+
</svg>
|
|
6
|
+
);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const LockOpenIcon = (props) => {
|
|
10
|
+
return (
|
|
11
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="1em" height="1em" viewBox="0 0 50 50">
|
|
12
|
+
<path d="M 22.78125 0 C 21.605469 -0.00390625 20.40625 0.164063 19.21875 0.53125 C 12.902344 2.492188 9.289063 9.269531 11.25 15.59375 L 11.25 15.65625 C 11.507813 16.367188 12.199219 18.617188 12.625 20 L 9 20 C 7.355469 20 6 21.355469 6 23 L 6 47 C 6 48.644531 7.355469 50 9 50 L 41 50 C 42.644531 50 44 48.644531 44 47 L 44 23 C 44 21.355469 42.644531 20 41 20 L 14.75 20 C 14.441406 19.007813 13.511719 16.074219 13.125 15 L 13.15625 15 C 11.519531 9.722656 14.5 4.109375 19.78125 2.46875 C 25.050781 0.832031 30.695313 3.796875 32.34375 9.0625 C 32.34375 9.066406 32.34375 9.089844 32.34375 9.09375 C 32.570313 9.886719 33.65625 13.40625 33.65625 13.40625 C 33.746094 13.765625 34.027344 14.050781 34.386719 14.136719 C 34.75 14.226563 35.128906 14.109375 35.375 13.832031 C 35.621094 13.550781 35.695313 13.160156 35.5625 12.8125 C 35.5625 12.8125 34.433594 9.171875 34.25 8.53125 L 34.25 8.5 C 32.78125 3.761719 28.601563 0.542969 23.9375 0.0625 C 23.550781 0.0234375 23.171875 0 22.78125 0 Z M 9 22 L 41 22 C 41.554688 22 42 22.445313 42 23 L 42 47 C 42 47.554688 41.554688 48 41 48 L 9 48 C 8.445313 48 8 47.554688 8 47 L 8 23 C 8 22.445313 8.445313 22 9 22 Z M 25 30 C 23.300781 30 22 31.300781 22 33 C 22 33.898438 22.398438 34.6875 23 35.1875 L 23 38 C 23 39.101563 23.898438 40 25 40 C 26.101563 40 27 39.101563 27 38 L 27 35.1875 C 27.601563 34.6875 28 33.898438 28 33 C 28 31.300781 26.699219 30 25 30 Z"></path>
|
|
13
|
+
</svg>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const PlayIcon = () => {
|
|
18
|
+
return (
|
|
19
|
+
<svg className='detail-player-play-button-icon' fill="currentColor" height="1em" width="1em" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
|
20
|
+
<g>
|
|
21
|
+
<path d={`M46.0136986,31.1054993L25.1973,20.6973c-0.3096008-0.1532993-0.6777992-0.1387005-0.9727001,0.0438995
|
|
22
|
+
C23.9297009,20.9237995,23.75,21.2451,23.75,21.5918007v20.8163986c0,0.3467026,0.1797009,0.6679993,0.4745998,0.8506012
|
|
23
|
+
C24.3848,43.3583984,24.5674,43.4081993,24.75,43.4081993c0.1532993,0,0.3057003-0.035099,0.4473-0.1054001l20.8163986-10.4081993
|
|
24
|
+
c0.3388023-0.1699982,0.5527-0.5157013,0.5527-0.8945999C46.5663986,31.6210995,46.3525009,31.2754002,46.0136986,31.1054993z
|
|
25
|
+
M25.75,40.7901001v-17.580101L43.330101,32L25.75,40.7901001z`} />
|
|
26
|
+
<path d={`M32,0C14.3268995,0,0,14.3268995,0,32s14.3268995,32,32,32s32-14.3269005,32-32S49.6730995,0,32,0z M32,62
|
|
27
|
+
C15.4579,62,2,48.542099,2,32C2,15.4580002,15.4579,2,32,2c16.5419998,0,30,13.4580002,30,30C62,48.542099,48.5419998,62,32,62z`} />
|
|
28
|
+
</g>
|
|
29
|
+
</svg>
|
|
30
|
+
);
|
|
31
|
+
}
|
package/site/static/js/main.js
CHANGED
|
@@ -2,6 +2,8 @@ import './modernizr-custom.js';
|
|
|
2
2
|
import './can-be-watched-button.component.js';
|
|
3
3
|
import './external-purchase-button.component.js';
|
|
4
4
|
import './carousel-video-mute-button.component.js';
|
|
5
|
+
import './detail-player/detail-player.component.js';
|
|
6
|
+
import './comments.js';
|
|
5
7
|
|
|
6
8
|
/*global Swiper, Modernizr, s72*/
|
|
7
9
|
|
|
@@ -567,3 +569,11 @@ document.addEventListener('s72loaded', event => {
|
|
|
567
569
|
let app = event.detail.app;
|
|
568
570
|
documentReady(app);
|
|
569
571
|
});
|
|
572
|
+
|
|
573
|
+
window.addEventListener('message', e => {
|
|
574
|
+
const {event, url, type} = e.data;
|
|
575
|
+
if (event == 's72-player:navigate-to') {
|
|
576
|
+
console.log(`navigating to ${url}, reason: ${type}`);
|
|
577
|
+
window.location.href = `${url}`;
|
|
578
|
+
}
|
|
579
|
+
});
|
|
@@ -44,13 +44,23 @@ s72-carousel {
|
|
|
44
44
|
object-fit: cover;
|
|
45
45
|
object-position: var(--carousel-image-object-position);
|
|
46
46
|
width: 100%;
|
|
47
|
+
|
|
48
|
+
opacity: 0;
|
|
49
|
+
transition: opacity 0.25s ease;
|
|
50
|
+
|
|
47
51
|
z-index: -1;
|
|
52
|
+
|
|
48
53
|
@include media-breakpoint-up(sm) {
|
|
49
54
|
object-position: var(--carousel-image-object-position-sm);
|
|
50
55
|
}
|
|
51
56
|
@include media-breakpoint-up(lg) {
|
|
52
57
|
object-position: var(--carousel-image-object-position-lg);
|
|
53
58
|
}
|
|
59
|
+
|
|
60
|
+
&.s72-image--loaded {
|
|
61
|
+
opacity: 1;
|
|
62
|
+
}
|
|
63
|
+
|
|
54
64
|
&.focus-left {
|
|
55
65
|
object-position: left;
|
|
56
66
|
}
|
|
@@ -35,6 +35,11 @@
|
|
|
35
35
|
display: block;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
.page-collection-item {
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
}
|
|
42
|
+
|
|
38
43
|
/* stylelint-disable selector-max-compound-selectors, max-nesting-depth */
|
|
39
44
|
.page-collection-item,
|
|
40
45
|
.slider-item,
|
|
@@ -261,7 +266,8 @@
|
|
|
261
266
|
}
|
|
262
267
|
|
|
263
268
|
.caption {
|
|
264
|
-
padding:
|
|
269
|
+
padding: 0 0 8px;
|
|
270
|
+
margin-top: 4px;
|
|
265
271
|
|
|
266
272
|
.crumb {
|
|
267
273
|
@extend .d-flex;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
.detail-player {
|
|
2
|
+
&-inner {
|
|
3
|
+
background-color: var(--detail-player-fallback-color);
|
|
4
|
+
height: 100%;
|
|
5
|
+
position: relative;
|
|
6
|
+
width: 100%;
|
|
7
|
+
|
|
8
|
+
iframe {
|
|
9
|
+
border: 0;
|
|
10
|
+
height: 100%;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
position: absolute;
|
|
13
|
+
width: 100%;
|
|
14
|
+
z-index: 0;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
&-placeholder {
|
|
19
|
+
height: 100%;
|
|
20
|
+
opacity: 0;
|
|
21
|
+
position: absolute;
|
|
22
|
+
transition: 1s;
|
|
23
|
+
width: 100%;
|
|
24
|
+
z-index: 1;
|
|
25
|
+
|
|
26
|
+
&--visible {
|
|
27
|
+
opacity: 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&-image-loader {
|
|
31
|
+
display: none;
|
|
32
|
+
height: 0;
|
|
33
|
+
width: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&-bg {
|
|
37
|
+
background-position: 50% 50%;
|
|
38
|
+
background-repeat: no-repeat;
|
|
39
|
+
background-size: cover;
|
|
40
|
+
height: 100%;
|
|
41
|
+
position: absolute;
|
|
42
|
+
width: 100%;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
&-overlay {
|
|
46
|
+
align-items: center;
|
|
47
|
+
background-color: var(--detail-player-overlay-color);
|
|
48
|
+
display: flex;
|
|
49
|
+
height: 100%;
|
|
50
|
+
justify-content: center;
|
|
51
|
+
position: absolute;
|
|
52
|
+
width: 100%;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&-gradient {
|
|
56
|
+
@extend .bottom-gradient-bg;
|
|
57
|
+
width: 100%;
|
|
58
|
+
height: 30%;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&-title {
|
|
62
|
+
position: absolute;
|
|
63
|
+
bottom: 20px;
|
|
64
|
+
left: 20px;
|
|
65
|
+
max-width: 40%;
|
|
66
|
+
max-height: 50%;
|
|
67
|
+
z-index: 10;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&-locked-message {
|
|
72
|
+
align-items: center;
|
|
73
|
+
display: inline-flex;
|
|
74
|
+
justify-content: center;
|
|
75
|
+
user-select: none;
|
|
76
|
+
background-color: rgba(var(--detail-player-messsage-bg-color), 0.3);
|
|
77
|
+
padding: 15px 25px;
|
|
78
|
+
border-radius: 100px;
|
|
79
|
+
box-shadow: 3px 3px 3px #0005;
|
|
80
|
+
transition: 0.5s;
|
|
81
|
+
|
|
82
|
+
&--unlocked {
|
|
83
|
+
background-color: rgba(var(--detail-player-messsage-bg-color), 0);
|
|
84
|
+
box-shadow: 3px 3px 3px #0000;
|
|
85
|
+
backdrop-filter: blur(0);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
&-text {
|
|
89
|
+
color: var(--detail-player-messsage-font-color);
|
|
90
|
+
font-size: var(--detail-player-message-font-size);
|
|
91
|
+
opacity: 1;
|
|
92
|
+
flex-shrink: 1;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
transition: 0.5s;
|
|
95
|
+
white-space: nowrap;
|
|
96
|
+
width: auto;
|
|
97
|
+
max-width: 999px;
|
|
98
|
+
margin-top: 5px;
|
|
99
|
+
&--unlocked {
|
|
100
|
+
opacity: 0;
|
|
101
|
+
max-width: 0;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
&-lock-icon-wrapper {
|
|
107
|
+
color: var(--detail-player-lock-icon-color);
|
|
108
|
+
font-size: 45px;
|
|
109
|
+
margin-right: 12px;
|
|
110
|
+
transition: 0.5s;
|
|
111
|
+
|
|
112
|
+
svg {
|
|
113
|
+
display: block;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@keyframes wiggle {
|
|
117
|
+
0% {
|
|
118
|
+
transform: rotate(0deg);
|
|
119
|
+
}
|
|
120
|
+
20%,
|
|
121
|
+
40%,
|
|
122
|
+
60% {
|
|
123
|
+
transform: rotate(8deg);
|
|
124
|
+
}
|
|
125
|
+
30%,
|
|
126
|
+
50%,
|
|
127
|
+
70% {
|
|
128
|
+
transform: rotate(-8deg);
|
|
129
|
+
}
|
|
130
|
+
80% {
|
|
131
|
+
transform: rotate(4deg);
|
|
132
|
+
}
|
|
133
|
+
90% {
|
|
134
|
+
transform: rotate(-4deg);
|
|
135
|
+
}
|
|
136
|
+
100% {
|
|
137
|
+
transform: rotate(0deg);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
&--large {
|
|
141
|
+
filter: drop-shadow(5px 5px 3px #0008);
|
|
142
|
+
transform: scale(1.5);
|
|
143
|
+
}
|
|
144
|
+
&--wiggle {
|
|
145
|
+
animation: wiggle 0.9s;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
&-lock-icon {
|
|
150
|
+
transform-origin: 0% 80%;
|
|
151
|
+
&--anim-1 {
|
|
152
|
+
rotate: 12deg;
|
|
153
|
+
transition: 0.7s;
|
|
154
|
+
}
|
|
155
|
+
&--anim-2 {
|
|
156
|
+
rotate: -6deg;
|
|
157
|
+
transition: linear 0.1s;
|
|
158
|
+
}
|
|
159
|
+
&--anim-3 {
|
|
160
|
+
opacity: 0;
|
|
161
|
+
rotate: -12deg;
|
|
162
|
+
transition: linear 0.1s;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
&-play-button {
|
|
167
|
+
cursor: pointer;
|
|
168
|
+
transition: 0.3s;
|
|
169
|
+
&-icon {
|
|
170
|
+
color: var(--detail-player-play-icon-color);
|
|
171
|
+
font-size: 80px;
|
|
172
|
+
}
|
|
173
|
+
&:hover {
|
|
174
|
+
transform: scale(1.2);
|
|
175
|
+
}
|
|
176
|
+
&--clicked {
|
|
177
|
+
opacity: 0;
|
|
178
|
+
pointer-events: none;
|
|
179
|
+
transform: scale(1.6) !important;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
package/site/styles/_forms.scss
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@use "sass:math";
|
|
2
|
+
|
|
1
3
|
label {
|
|
2
4
|
@include subtitle-1-style;
|
|
3
5
|
margin-bottom: 0.25rem;
|
|
@@ -220,7 +222,7 @@ s72-confirm-delete-form,
|
|
|
220
222
|
.s72-btn-modal-cancel {
|
|
221
223
|
border-color: transparent;
|
|
222
224
|
color: var(--body-color);
|
|
223
|
-
margin-right: $grid-gutter-width
|
|
225
|
+
margin-right: math.div($grid-gutter-width, 3);
|
|
224
226
|
|
|
225
227
|
&:hover {
|
|
226
228
|
background-color: var(--hover-background);
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
body {
|
|
2
|
+
// Makes the fonts look a lot sharper on macOS. This is a pretty standard part
|
|
3
|
+
// of most CSS resets.
|
|
4
|
+
-webkit-font-smoothing: antialiased;
|
|
5
|
+
|
|
6
|
+
// prevents Safari (especially) from synthesizing bold or italic version of
|
|
7
|
+
// font faces (e.g. if you specify a font weight that isn't loaded). These
|
|
8
|
+
// look really bad.
|
|
9
|
+
font-synthesis: none;
|
|
10
|
+
}
|
|
11
|
+
|
|
1
12
|
small {
|
|
2
13
|
font-size: 85%;
|
|
3
14
|
}
|