feat: галерея-слайдер, листалка в просмотрщике и TUI braille-спиннер
- case-media-slider: переиспользуемый слайдер (prev/next + точки, swipe, клавиатура, lazy) - image-viewer: листалка prev/next в тулбаре как пилюли, пагинация-точки в тулбаре слева, группа масштаба (slider + текст) с gap 0.25rem, текст масштаба --text-muted/400 - tui-spinner: переиспользуемый braille-спиннер (чистый CSS), лоадер просмотрщика - design-system.html: живой пример TUI braille-спиннера - fix: удалён мёртвый textContent='Загрузка...', убивавший .tui-spinner при повторном открытии
This commit is contained in:
1 parent
9b91ed165f
commit
95b4eaca93
14 files changed
+753
-34
No files matched your search
+318
-13
@@ -2162,11 +2162,18 @@ html[data-theme="dark"] {
|
||||
}
|
||||
|
||||
.case-image-viewer__zoom {
|
||||
min-width: 3.5rem;
|
||||
min-width: 2.5rem;
|
||||
text-align: center;
|
||||
font-size: 0.82rem;
|
||||
color: var(--text);
|
||||
font-weight: 600;
|
||||
color: var(--text-muted);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* Группа слайдер + текст масштаба с уменьшенным внутренним зазором */
|
||||
.case-image-viewer__scale-group {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.case-image-viewer__slider {
|
||||
@@ -2310,29 +2317,82 @@ html[data-theme="dark"] {
|
||||
opacity 0.16s ease;
|
||||
}
|
||||
|
||||
.case-image-viewer__loading {
|
||||
/* TUI braille-спиннер (переиспользуемый, чистый CSS) */
|
||||
.tui-spinner {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 1.1em;
|
||||
height: 1.1em;
|
||||
font-family: ui-monospace, "Cascadia Code", "Consolas", "Courier New", monospace;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.tui-spinner > span {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
animation: tui-spinner-step 0.9s steps(1, end) infinite;
|
||||
}
|
||||
|
||||
.tui-spinner > span:nth-child(1) { animation-delay: 0s; }
|
||||
.tui-spinner > span:nth-child(2) { animation-delay: 0.09s; }
|
||||
.tui-spinner > span:nth-child(3) { animation-delay: 0.18s; }
|
||||
.tui-spinner > span:nth-child(4) { animation-delay: 0.27s; }
|
||||
.tui-spinner > span:nth-child(5) { animation-delay: 0.36s; }
|
||||
.tui-spinner > span:nth-child(6) { animation-delay: 0.45s; }
|
||||
.tui-spinner > span:nth-child(7) { animation-delay: 0.54s; }
|
||||
.tui-spinner > span:nth-child(8) { animation-delay: 0.63s; }
|
||||
.tui-spinner > span:nth-child(9) { animation-delay: 0.72s; }
|
||||
.tui-spinner > span:nth-child(10) { animation-delay: 0.81s; }
|
||||
|
||||
@keyframes tui-spinner-step {
|
||||
0%, 9.999% { opacity: 1; }
|
||||
10%, 100% { opacity: 0; }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.tui-spinner > span { animation: none; opacity: 0; }
|
||||
.tui-spinner > span:nth-child(1) { opacity: 1; }
|
||||
}
|
||||
|
||||
/* Лоадер изображения в просмотрщике (обёртка вокруг .tui-spinner) */
|
||||
.case-image-viewer__loader {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
z-index: 2;
|
||||
transform: translate(-50%, -50%);
|
||||
min-width: 8.5rem;
|
||||
padding: 0.5rem 0.8rem;
|
||||
border-radius: 999px;
|
||||
text-align: center;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text);
|
||||
background: color-mix(in srgb, var(--surface) 86%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--line) 88%, transparent);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
text-shadow: 0 1px 6px hsla(0, 0%, 0%, 0.35);
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.14s ease;
|
||||
}
|
||||
|
||||
.case-image-viewer.is-loading .case-image-viewer__loading {
|
||||
.case-image-viewer.is-loading .case-image-viewer__loader {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.case-image-viewer__loader.is-error .tui-spinner {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.case-image-viewer__loader-msg {
|
||||
font-family: var(--font, inherit);
|
||||
font-size: 0.82rem;
|
||||
color: var(--text-muted);
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.case-image-viewer.is-loading .case-image-viewer__img {
|
||||
opacity: 0;
|
||||
}
|
||||
@@ -2347,6 +2407,80 @@ html[data-theme="dark"] {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* Кнопки пред/след в тулбаре: группа с отрицательным зазором и скруглением только снаружи */
|
||||
.case-image-viewer__nav-group {
|
||||
display: inline-flex;
|
||||
border-radius: 999px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.case-image-viewer__btn--nav {
|
||||
--imgv-nav-size: 2rem;
|
||||
width: var(--imgv-nav-size);
|
||||
height: var(--imgv-nav-size);
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Соседняя кнопка сдвигается на 1px, перекрывая разделительный бордер */
|
||||
.case-image-viewer__btn--nav + .case-image-viewer__btn--nav {
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
.case-image-viewer__btn--nav[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Скругления только на крайних кнопках группы (все 4 угла заданы явно) */
|
||||
.case-image-viewer__btn--nav:first-child {
|
||||
border-radius: 999px 0 0 999px;
|
||||
}
|
||||
|
||||
.case-image-viewer__btn--nav:last-child {
|
||||
border-radius: 0 999px 999px 0;
|
||||
}
|
||||
|
||||
/* У одиночной кнопки в группе — скругление со всех сторон */
|
||||
.case-image-viewer__btn--nav:only-child {
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
/* Точки-пагинация в тулбаре просмотрщика */
|
||||
.case-image-viewer__dots {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
padding: 0 0.15rem;
|
||||
}
|
||||
|
||||
.case-image-viewer__dots[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.case-image-viewer__dot {
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
background: color-mix(in srgb, var(--text-muted) 40%, transparent);
|
||||
cursor: pointer;
|
||||
transition: background 0.18s ease, transform 0.18s ease;
|
||||
}
|
||||
|
||||
.case-image-viewer__dot:hover,
|
||||
.case-image-viewer__dot:focus-visible {
|
||||
background: color-mix(in srgb, var(--text-muted) 65%, transparent);
|
||||
}
|
||||
|
||||
.case-image-viewer__dot.is-active {
|
||||
background: var(--accent);
|
||||
transform: scale(1.25);
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.case-link-card {
|
||||
grid-template-columns: 1fr;
|
||||
@@ -5194,3 +5328,174 @@ body.content-edit-shift-active.content-edit-mode-active .content-edit-fab-stack
|
||||
.sep--air-lg {
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
/* Слайдер изображений в лонгриде кейса: одна картинка + стрелки + точки */
|
||||
.case-media-slider {
|
||||
--slider-gap: 0;
|
||||
--slider-radius: var(--radius-card);
|
||||
--slider-ctrl-size: 2.5rem;
|
||||
--slider-ctrl-inset: 0.75rem;
|
||||
--slider-dot-size: 0.5rem;
|
||||
--slider-dot-gap: 0.5rem;
|
||||
position: relative;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
border-radius: var(--slider-radius);
|
||||
}
|
||||
|
||||
.case-media-slider__viewport {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
touch-action: pan-y;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.case-media-slider__viewport:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.case-media-slider__track {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
transition: transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1);
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.case-media-slider__slide {
|
||||
flex: 0 0 100%;
|
||||
min-width: 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.case-media-slider__slide img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-height: 80vh;
|
||||
object-fit: contain;
|
||||
border-radius: var(--slider-radius);
|
||||
}
|
||||
|
||||
/* Подпись под активным слайдом (как у case-media) */
|
||||
.case-media-slider__slide figcaption,
|
||||
.case-media-slider figcaption {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 0.6rem 0.9rem;
|
||||
font-size: 0.82rem;
|
||||
color: var(--text-muted);
|
||||
text-align: center;
|
||||
background: color-mix(in srgb, var(--surface) 78%, transparent);
|
||||
backdrop-filter: blur(6px);
|
||||
border-bottom-left-radius: var(--slider-radius);
|
||||
border-bottom-right-radius: var(--slider-radius);
|
||||
}
|
||||
|
||||
/* Стрелки */
|
||||
.case-media-slider__nav {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: var(--slider-ctrl-size);
|
||||
height: var(--slider-ctrl-size);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 50%;
|
||||
background: color-mix(in srgb, var(--surface) 86%, transparent);
|
||||
color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
z-index: 3;
|
||||
transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease,
|
||||
opacity 0.18s ease;
|
||||
}
|
||||
|
||||
.case-media-slider__nav--prev {
|
||||
left: var(--slider-ctrl-inset);
|
||||
}
|
||||
|
||||
.case-media-slider__nav--next {
|
||||
right: var(--slider-ctrl-inset);
|
||||
}
|
||||
|
||||
.case-media-slider__nav:hover:not(:disabled),
|
||||
.case-media-slider__nav:focus-visible:not(:disabled) {
|
||||
color: var(--accent-text);
|
||||
border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
|
||||
background: var(--accent-soft);
|
||||
}
|
||||
|
||||
.case-media-slider__nav:disabled {
|
||||
opacity: 0.35;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.case-media-slider__nav-ico {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
display: block;
|
||||
background: currentColor;
|
||||
mask-size: contain;
|
||||
-webkit-mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
-webkit-mask-position: center;
|
||||
}
|
||||
|
||||
.case-media-slider__nav-ico--left {
|
||||
mask-image: url("../assets/shared/icons/shevron-left.svg");
|
||||
-webkit-mask-image: url("../assets/shared/icons/shevron-left.svg");
|
||||
}
|
||||
|
||||
.case-media-slider__nav-ico--right {
|
||||
mask-image: url("../assets/shared/icons/shevron-right.svg");
|
||||
-webkit-mask-image: url("../assets/shared/icons/shevron-right.svg");
|
||||
}
|
||||
|
||||
/* Точки-пагинация */
|
||||
.case-media-slider__dots {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: var(--slider-dot-gap);
|
||||
margin-top: 0.9rem;
|
||||
}
|
||||
|
||||
.case-media-slider__dot {
|
||||
width: var(--slider-dot-size);
|
||||
height: var(--slider-dot-size);
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
background: color-mix(in srgb, var(--text-muted) 40%, transparent);
|
||||
cursor: pointer;
|
||||
transition: background 0.18s ease, transform 0.18s ease;
|
||||
}
|
||||
|
||||
.case-media-slider__dot:hover,
|
||||
.case-media-slider__dot:focus-visible {
|
||||
background: color-mix(in srgb, var(--text-muted) 65%, transparent);
|
||||
}
|
||||
|
||||
.case-media-slider__dot.is-active {
|
||||
background: var(--accent);
|
||||
transform: scale(1.25);
|
||||
}
|
||||
|
||||
/* Неактивные слайды скрыты от скринридеров и не ловят клики по viewer */
|
||||
.case-media-slider__slide:not(.is-active) {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.case-media-slider__track {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user