itube-specs 0.0.977 → 0.0.981
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/components/card/model.vue +3 -3
- package/components/card/video/actions.vue +3 -1
- package/components/card/video/index.vue +4 -9
- package/components/grid/models.vue +15 -6
- package/components/layout/language.vue +2 -2
- package/composables/use-client-country.ts +1 -1
- package/composables/use-test-model-images.ts +6 -4
- package/package.json +1 -1
- package/pages/playlists/index.vue +6 -0
|
@@ -93,11 +93,11 @@ const { generateLink } = useGenerateLink();
|
|
|
93
93
|
const { t } = useI18n();
|
|
94
94
|
|
|
95
95
|
/**
|
|
96
|
-
* Пороги — колоночная лестница `.grid-models` (2 → 3 с
|
|
97
|
-
*
|
|
96
|
+
* Пороги — колоночная лестница `.grid-models` (2 → 3 с 450px → … → 6 с 1160px), а не `$brkpnts`.
|
|
97
|
+
* До 1386px слот держится в 213px, дальше растёт до 249 — оттуда и правое значение.
|
|
98
98
|
* `auto` впереди — см. `UiImg`.
|
|
99
99
|
*/
|
|
100
|
-
const SIZES = 'auto, (max-width:
|
|
100
|
+
const SIZES = 'auto, (max-width: 449px) 50vw, (max-width: 1385px) 215px, 250px';
|
|
101
101
|
|
|
102
102
|
const fallbackImage = '/img/model-placeholder.webp';
|
|
103
103
|
const imageError = ref(false);
|
|
@@ -112,7 +112,9 @@ $action-size: 36px;
|
|
|
112
112
|
var(--transition) color;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
/* :focus-visible, а не :focus-within: после клика мышью фокус остаётся на кнопке, и она
|
|
116
|
+
продолжала висеть видимой, когда курсор уже ушёл с карточки. Клавиатурный обход не страдает. */
|
|
117
|
+
.card-video:is(:hover, :has(:focus-visible)) .card-video-actions__btn {
|
|
116
118
|
opacity: 1;
|
|
117
119
|
}
|
|
118
120
|
|
|
@@ -442,20 +442,16 @@ $dropdown-column: 18px;
|
|
|
442
442
|
--line-clamp: 2;
|
|
443
443
|
|
|
444
444
|
grid-row: 1;
|
|
445
|
+
font-weight: 500;
|
|
445
446
|
color: $video-card-text;
|
|
446
447
|
|
|
447
448
|
@include to-cq($layout-breakpoint) {
|
|
448
449
|
grid-column: 1;
|
|
449
450
|
}
|
|
450
451
|
|
|
451
|
-
@
|
|
452
|
-
transition: var(--transition) color;
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
.card-video:is(:hover, :focus-visible) .card-video__title {
|
|
457
|
-
@media (hover: hover) {
|
|
452
|
+
@include hover(color, opacity) {
|
|
458
453
|
color: $video-card-text--hover;
|
|
454
|
+
opacity: 0.9;
|
|
459
455
|
}
|
|
460
456
|
}
|
|
461
457
|
|
|
@@ -529,8 +525,7 @@ $dropdown-column: 18px;
|
|
|
529
525
|
}
|
|
530
526
|
|
|
531
527
|
.card-video__logo-wrapper[href],
|
|
532
|
-
.card-video__channel-wrapper[href]
|
|
533
|
-
.card-video__title {
|
|
528
|
+
.card-video__channel-wrapper[href] {
|
|
534
529
|
@include hover(opacity) {
|
|
535
530
|
opacity: 0.9;
|
|
536
531
|
}
|
|
@@ -26,26 +26,35 @@ defineProps<{
|
|
|
26
26
|
</script>
|
|
27
27
|
|
|
28
28
|
<style lang="scss">
|
|
29
|
-
/* Лестница
|
|
30
|
-
|
|
29
|
+
/* Лестница колонок: 2 → 3 (450px) → 4 (690px) → 5 (920px) → 6 (1160px). Больше шести в ряд
|
|
30
|
+
не даём — продуктовое требование.
|
|
31
|
+
|
|
32
|
+
Пороги — литералы, с тирами $brkpnts намеренно не совпадают: они подобраны так, чтобы слот
|
|
33
|
+
карточки держался в 213px. Это ширина исходника 640, делённая на 3 — предел плотности
|
|
34
|
+
современных телефонов. Считается как
|
|
35
|
+
(вьюпорт − 2×--container-padding-inline − 12×(колонок−1)) / колонок.
|
|
36
|
+
|
|
37
|
+
Единственное место, где 213 превышены — шесть колонок шире 1386px: там слот растёт до 249.
|
|
38
|
+
Это осознанно: при тройной плотности такому слоту нужно 746px, но десктопов с тройной
|
|
39
|
+
плотностью практически не бывает, а DPR2 просит 497 и укладывается в наши 640. */
|
|
31
40
|
.grid-models {
|
|
32
41
|
display: grid;
|
|
33
42
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
34
43
|
gap: 12px;
|
|
35
44
|
|
|
36
|
-
@include from-br(
|
|
45
|
+
@include from-br(450px) {
|
|
37
46
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
38
47
|
}
|
|
39
48
|
|
|
40
|
-
@include from-br(
|
|
49
|
+
@include from-br(690px) {
|
|
41
50
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
42
51
|
}
|
|
43
52
|
|
|
44
|
-
@include from-br(
|
|
53
|
+
@include from-br(920px) {
|
|
45
54
|
grid-template-columns: repeat(5, minmax(0, 1fr));
|
|
46
55
|
}
|
|
47
56
|
|
|
48
|
-
@include from-br(
|
|
57
|
+
@include from-br(1160px) {
|
|
49
58
|
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
50
59
|
}
|
|
51
60
|
}
|
|
@@ -215,9 +215,9 @@ function changeLocale(locale: string) {
|
|
|
215
215
|
|
|
216
216
|
async function changeCountry(item: ISelectItem) {
|
|
217
217
|
setCountry(item);
|
|
218
|
-
// куку пишет вотчер useCookie — ждём флаш, иначе
|
|
218
|
+
// куку пишет вотчер useCookie — ждём флаш, иначе перезагрузка может срезать запись
|
|
219
219
|
await nextTick();
|
|
220
|
-
window.location.
|
|
220
|
+
window.location.reload();
|
|
221
221
|
}
|
|
222
222
|
</script>
|
|
223
223
|
|
|
@@ -42,7 +42,7 @@ export const useClientCountry = () => {
|
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Ручной выбор страны в селекторе: наружу переживает перезагрузку только код. `place`
|
|
45
|
-
* пересчитает следующий SSR — layout/language.vue тут же
|
|
45
|
+
* пересчитает следующий SSR — layout/language.vue тут же перезагружает текущую страницу.
|
|
46
46
|
*/
|
|
47
47
|
const setCountry = (item: ISelectItem) => {
|
|
48
48
|
code.value = item.key || '';
|
|
@@ -24,6 +24,8 @@ const PORTRAIT_GUIDS = [
|
|
|
24
24
|
* Тестовые портреты моделей:
|
|
25
25
|
*
|
|
26
26
|
* - `?img=png` — исходники 1024×1536;
|
|
27
|
+
* - `?img=444` — наш avif в полной цветности 4:4:4 при том же качестве яркости, что у поставки
|
|
28
|
+
* нарезчика (она в 4:2:0). Сравнение стоит вести по цвету: губы, румянец, переходы кожи;
|
|
27
29
|
* - без параметра — нарезка по `DOCS/MODEL-IMAGES.md`: один 640w, avif через `<picture>`.
|
|
28
30
|
*
|
|
29
31
|
* Две ширины, выбирает их КОМПОНЕНТ, а не браузер: srcset мы не ставим. 640w — портрет в
|
|
@@ -43,12 +45,12 @@ const PORTRAIT_GUIDS = [
|
|
|
43
45
|
* по query. Для замера сети это и нужно: он честен только с чистого захода.
|
|
44
46
|
*/
|
|
45
47
|
export function useTestModelImages() {
|
|
46
|
-
const
|
|
48
|
+
const format = String(useRoute().query['img'] || '');
|
|
47
49
|
|
|
48
50
|
const portraits: ITestModelPortrait[] = PORTRAIT_GUIDS.map((guid) => {
|
|
49
51
|
const base = `/img/models/${guid}`;
|
|
50
52
|
|
|
51
|
-
if (
|
|
53
|
+
if (format === 'png') {
|
|
52
54
|
return { primaryImageUrl: `${base}.png`, thumbUrl: `${base}.png` };
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -56,8 +58,8 @@ export function useTestModelImages() {
|
|
|
56
58
|
primaryImageUrl: `${base}-640.webp`,
|
|
57
59
|
thumbUrl: `${base}-256.webp`,
|
|
58
60
|
primaryImageSmallUrl: `${base}-256.webp`,
|
|
59
|
-
primaryImageAvifUrl: `${base}-640.avif`,
|
|
60
|
-
primaryImageSmallAvifUrl: `${base}-256.avif`,
|
|
61
|
+
primaryImageAvifUrl: format === '444' ? `${base}-640-444.avif` : `${base}-640.avif`,
|
|
62
|
+
primaryImageSmallAvifUrl: format === '444' ? `${base}-256-444.avif` : `${base}-256.avif`,
|
|
61
63
|
};
|
|
62
64
|
});
|
|
63
65
|
|
package/package.json
CHANGED
|
@@ -141,4 +141,10 @@ const breadcrumbs = [
|
|
|
141
141
|
.playlists__navigation {
|
|
142
142
|
margin-bottom: 32px;
|
|
143
143
|
}
|
|
144
|
+
|
|
145
|
+
/* Два класса, а не `._pagination`: у `.ui-pagination` своя `margin: auto auto 0` той же
|
|
146
|
+
специфичности, и при заполненной странице отбивка сверху схлопывалась в ноль. */
|
|
147
|
+
.ui-pagination.playlists__pagination {
|
|
148
|
+
margin-top: 32px;
|
|
149
|
+
}
|
|
144
150
|
</style>
|