fluxer/fluxer_app/src/components/channel/GifPicker.module.css
2026-01-01 21:05:54 +00:00

555 lines
10 KiB
CSS

/*
* Copyright (C) 2026 Fluxer Contributors
*
* This file is part of Fluxer.
*
* Fluxer is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Fluxer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
*/
.gifPickerContainer {
position: relative;
display: grid;
height: 100%;
grid-template-rows: 1fr;
overflow: hidden;
background-color: var(--background-primary);
--gif-picker-overlay-bg: oklab(0 0 0 / 0.75);
--gif-picker-overlay-hover-bg: oklab(0 0 0 / 0.8);
}
.gifPickerMain {
position: relative;
min-height: 0;
overflow: hidden;
background-color: var(--background-primary);
}
.autoSizerWrapper {
height: 100%;
width: 100%;
}
.autoSizerWrapper > div {
height: 100% !important;
width: 100% !important;
}
.virtualList {
scrollbar-color: var(--scrollbar-thumb-bg) transparent;
scrollbar-width: thin;
overflow-anchor: none;
background-color: var(--background-primary);
}
@media (max-width: 768px) {
.virtualList {
scrollbar-width: none;
}
.virtualList::-webkit-scrollbar {
display: none;
}
}
.virtualList::-webkit-scrollbar {
width: 8px;
}
.virtualList::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-thumb-bg);
background-clip: padding-box;
border: 2px solid transparent;
border-radius: 4px;
min-height: 48px;
}
.virtualList::-webkit-scrollbar-thumb:hover {
background-color: var(--scrollbar-thumb-bg-hover);
}
.virtualList::-webkit-scrollbar-track {
background-color: transparent;
}
.virtualRow {
display: flex;
gap: var(--spacing-3);
}
@media (max-width: 768px) {
.virtualRow {
gap: var(--spacing-2);
}
}
.searchBarContainer {
display: flex;
align-items: center;
gap: var(--spacing-3);
}
.mobileHeaderWrapper {
display: flex;
flex-direction: column;
gap: var(--spacing-3);
padding-block: var(--spacing-2);
padding-inline: var(--spacing-4);
}
.searchBarTitleWrapper {
display: flex;
align-items: center;
gap: 8px;
}
.searchBarBackButton {
cursor: pointer;
width: 24px;
height: 24px;
color: var(--text-primary-muted);
transition: color 0.1s ease-out;
}
.searchBarBackButton:hover {
color: var(--text-primary);
}
.searchBarTitle {
font-size: 1rem;
font-weight: 600;
color: var(--text-tertiary);
}
.grid {
display: flex;
flex-wrap: nowrap;
gap: var(--spacing-3);
padding: 0 10px 0 10px;
justify-content: flex-start;
}
.column {
display: flex;
flex-direction: column;
flex: 1;
gap: var(--spacing-3);
min-width: 227px;
}
@media (max-width: 768px) {
.grid {
gap: var(--spacing-2);
padding: 0 10px 0 10px;
}
.column {
gap: var(--spacing-2);
min-width: calc(50svw - 20px);
}
.gridItem {
border-radius: var(--radius-sm);
}
}
.gridItem {
position: relative;
border-radius: 0.375rem;
background-color: var(--background-secondary);
cursor: pointer;
width: 100%;
box-sizing: border-box;
border: 1px solid transparent;
transition: border-color 0.1s ease-out;
outline: none;
}
.gridItemFocused {
border-color: var(--brand-primary-light);
box-shadow: inset 0 0 0 2px var(--brand-primary-light);
}
.gridItemBackdrop {
position: absolute;
inset: 1px;
transition:
background-color 0.1s ease-out,
backdrop-filter 0.1s ease-out;
z-index: 2;
background-color: var(--gif-picker-overlay-bg);
border-radius: calc(0.375rem - 1px);
}
.gridItemCategory:hover {
border-color: var(--brand-primary-light);
box-shadow: inset 0 0 0 1px var(--brand-primary-light);
}
.gridItemCategory:hover .gridItemBackdrop {
backdrop-filter: blur(2px);
background-color: var(--gif-picker-overlay-hover-bg);
}
.gridItemGif .gridItemBackdrop {
display: none;
}
.gifMediaContainer {
position: absolute;
inset: 1px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
border-radius: calc(0.375rem - 1px);
transition: filter 0.1s ease-out;
}
.gridItemGif:hover {
border-color: var(--brand-primary-light);
box-shadow: inset 0 0 0 1px var(--brand-primary-light);
}
.gridItemGif:hover .gifMediaContainer {
filter: brightness(1.2);
}
.gridItemFavorites .gridItemBackdrop {
background-color: hsla(242, 67%, 55%, 0.6);
}
.gridItemFavorites:hover .gridItemBackdrop {
background-color: hsla(242, 67%, 55%, 0.8);
}
.gridItemCategoryTitle {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
z-index: 3;
pointer-events: none;
gap: 4px;
}
.gridItemIcon {
width: 20px;
height: 20px;
color: white;
}
.gridItemCategoryTitleText {
font-size: 1rem;
line-height: 16px;
font-weight: 600;
color: white;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.6);
}
.gif {
width: 100%;
height: 100%;
object-fit: cover;
background-color: transparent;
}
.gifVideoContainer {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.header {
display: flex;
align-items: center;
padding: 16px;
background-color: var(--background-primary);
}
.backButton {
margin-right: 16px;
cursor: pointer;
width: 24px;
height: 24px;
color: var(--text-primary-muted);
transition: color 0.1s ease-out;
}
.backButton:hover {
color: var(--text-primary);
}
.header h2 {
flex: 1;
margin: 0;
font-size: 1.25rem;
font-weight: 600;
color: var(--text-primary);
}
.skeletonContainer {
display: flex;
flex-wrap: wrap;
gap: 10px;
padding: 0 16px;
}
.skeletonItem {
background: linear-gradient(
90deg,
var(--background-secondary) 0%,
var(--background-tertiary) 50%,
var(--background-secondary) 100%
);
background-size: 200% 100%;
border-radius: 0.375rem;
animation: shimmer 2s ease-in-out infinite;
will-change: background-position;
}
@keyframes shimmer {
0% {
background-position: -200% center;
}
100% {
background-position: 200% center;
}
}
@media (max-width: 768px) {
.skeletonItem {
border-radius: 0.25rem;
}
}
.suggestionsContainer {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 16px 16px 0;
justify-content: center;
}
.suggestionTag {
padding: 8px 16px;
border: none;
border-radius: 16px;
background-color: var(--background-tertiary);
color: var(--text-primary);
font-size: 14px;
cursor: pointer;
transition: background-color 0.2s ease;
}
.suggestionTag:hover {
background-color: var(--background-modifier-hover);
}
.suggestionTag:active {
background-color: var(--background-modifier-selected);
}
.hoverActionButtons {
position: absolute;
top: 0.5rem;
right: 0.5rem;
z-index: 10;
display: flex;
gap: 0.25rem;
opacity: 0;
pointer-events: none;
transform: translateY(-4px);
}
.favoriteButton {
display: flex;
height: 2rem;
width: 2rem;
align-items: center;
justify-content: center;
border-radius: 0.375rem;
border: 1px solid var(--background-modifier-accent);
background-color: var(--background-primary);
box-shadow:
0 4px 6px -1px rgb(0 0 0 / 0.1),
0 2px 4px -2px rgb(0 0 0 / 0.1);
transition:
transform 0.15s,
border-color 0.15s,
background-color 0.15s;
cursor: pointer;
}
.favoriteButton:hover {
transform: scale(1.05);
}
.favoriteButton:hover:has([style*='status-danger']) {
background-color: var(--status-danger-hover);
}
.favoriteButton:active {
transform: scale(0.95);
}
.favoriteButtonActive {
border-color: var(--brand-primary);
background-color: var(--brand-primary);
}
.favoriteButtonIcon {
color: var(--text-primary);
height: 1rem;
width: 1rem;
}
.favoriteButtonActiveIcon {
color: white;
}
.centeredContent {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 64px;
}
.slate {
display: flex;
flex-direction: column;
width: 100%;
align-items: center;
justify-content: center;
padding: 0 1rem;
gap: 0.5rem;
}
.slateContent {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
}
.slateIcon {
height: 3.5rem;
width: 3.5rem;
color: var(--text-primary-muted);
}
.slateTextContainer {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
text-align: center;
}
.slateTitle {
font-size: 1.25rem;
font-weight: 600;
color: var(--text-primary);
}
.slateDescription {
font-size: 1rem;
color: var(--text-primary-muted);
}
:global(.theme-light) .gifPickerContainer {
background-color: var(--background-primary);
--gif-picker-overlay-bg: color-mix(in srgb, var(--background-primary) 80%, transparent);
--gif-picker-overlay-hover-bg: color-mix(in srgb, var(--background-primary) 90%, transparent);
}
:global(.theme-light) .gifPickerMain,
:global(.theme-light) .scrollArea {
background-color: var(--background-primary);
}
:global(.theme-light) .gridItem {
background-color: color-mix(in srgb, var(--background-primary) 90%, var(--background-secondary) 10%);
border-color: color-mix(in srgb, var(--background-modifier-accent) 60%, transparent);
}
:global(.theme-light) .gridItemCategoryTitleText {
color: var(--text-primary);
text-shadow: none;
}
:global(.theme-light) .gridItemIcon {
color: var(--text-primary);
}
:global(.theme-light) .gridItemFavorites .gridItemCategoryTitleText,
:global(.theme-light) .gridItemFavorites .gridItemIcon {
color: var(--text-on-brand-primary);
}
:global(.theme-light) .gridItemFavorites .gridItemCategoryTitleText {
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35);
}
:global(.theme-light) .suggestionTag {
background-color: var(--background-secondary);
}
:global(.theme-light) .gridItemFocused {
border-color: var(--brand-primary);
box-shadow: inset 0 0 0 2px var(--brand-primary);
}
.searchBarContent {
display: flex;
width: 100%;
flex-direction: column;
gap: var(--spacing-3);
}
.favoriteButtonSpinner {
width: 18px;
height: 18px;
border-radius: 999px;
box-sizing: border-box;
border: 2px solid color-mix(in srgb, var(--brand-primary-light) 20%, transparent);
border-top-color: var(--brand-primary-light);
border-right-color: var(--brand-primary-light);
animation: gifFavoriteSpinner 600ms linear infinite;
}
@keyframes gifFavoriteSpinner {
to {
transform: rotate(360deg);
}
}
.gridItemGif:hover .hoverActionButtons,
.gridItemGif:focus-visible .hoverActionButtons,
.gridItemGif:focus-within .hoverActionButtons,
.gridItemFavoritePending .hoverActionButtons,
.gridItemFocused .hoverActionButtons {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}