Store per-user 5-star ratings with averages and surface them in the player. Refresh movie list layout to show ratings and details in a cleaner card layout.
394 lines
7.7 KiB
CSS
394 lines
7.7 KiB
CSS
footer {
|
||
margin-top: auto;
|
||
padding: 25px;
|
||
background-color: #f8f9fa;
|
||
text-align: center;
|
||
|
||
}
|
||
#footer-text {
|
||
margin: -5px;
|
||
font-family:monospace;
|
||
font-size: small;
|
||
}
|
||
|
||
#footer-copy {
|
||
margin: -5px;
|
||
font-family:monospace;
|
||
font-size: smaller;
|
||
padding-top: 10px;
|
||
}
|
||
|
||
#copy {
|
||
text-decoration: none;
|
||
}
|
||
|
||
/* Simple, clean loading indicator (no spinner spam) */
|
||
.loading-indicator {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
gap: 0.35rem;
|
||
padding: 2rem 0;
|
||
}
|
||
|
||
.loading-dots {
|
||
display: inline-flex;
|
||
gap: 0.15rem;
|
||
}
|
||
|
||
.loading-dots span {
|
||
display: inline-block;
|
||
opacity: 0.2;
|
||
transform: translateY(-1px);
|
||
animation: loading-dot 1.1s infinite ease-in-out;
|
||
}
|
||
|
||
.loading-dots span:nth-child(2) { animation-delay: 0.15s; }
|
||
.loading-dots span:nth-child(3) { animation-delay: 0.30s; }
|
||
|
||
@keyframes loading-dot {
|
||
0%, 80%, 100% { opacity: 0.2; }
|
||
40% { opacity: 1; }
|
||
}
|
||
|
||
/* Full-page loader overlay (blur + progress bar) */
|
||
body.page-loading {
|
||
overflow: hidden;
|
||
}
|
||
|
||
.page-loader-overlay {
|
||
position: fixed;
|
||
top: var(--page-loader-top, 0px);
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
z-index: 2000;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 24px;
|
||
background: rgba(255, 255, 255, 0.55);
|
||
backdrop-filter: blur(10px);
|
||
-webkit-backdrop-filter: blur(10px);
|
||
transition: opacity 200ms ease;
|
||
opacity: 1;
|
||
}
|
||
|
||
/* Avoid initial navbar "blur flash" before JS computes the exact height. */
|
||
body.page-loading .page-loader-overlay {
|
||
top: var(--page-loader-top, 72px);
|
||
}
|
||
|
||
/* Reserve space for username so it doesn't "pop" the layout. */
|
||
#user-name {
|
||
display: inline-block;
|
||
min-width: 8ch;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/*
|
||
Reserve space for the Admin button even when hidden.
|
||
This prevents a visible re-layout when we discover admin status from the token.
|
||
*/
|
||
@media (min-width: 992px) {
|
||
nav.navbar #admin-control-link.d-none {
|
||
display: inline-block !important;
|
||
visibility: hidden !important;
|
||
pointer-events: none;
|
||
}
|
||
}
|
||
|
||
.page-loader-overlay.page-loader-hide {
|
||
opacity: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.page-loader-card {
|
||
width: min(520px, 92vw);
|
||
background: rgba(255, 255, 255, 0.9);
|
||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||
border-radius: 16px;
|
||
padding: 18px 18px 14px;
|
||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
|
||
}
|
||
|
||
.page-loader-card.page-loader-card--baronly {
|
||
width: min(420px, 90vw);
|
||
padding: 14px;
|
||
}
|
||
|
||
.page-loader-title {
|
||
margin: 0 0 10px 0;
|
||
font-weight: 700;
|
||
font-size: 1rem;
|
||
color: #111;
|
||
}
|
||
|
||
.page-loader-subtitle {
|
||
margin: 0 0 12px 0;
|
||
font-size: 0.9rem;
|
||
color: rgba(0, 0, 0, 0.7);
|
||
}
|
||
|
||
.page-loader-progress {
|
||
height: 10px;
|
||
border-radius: 999px;
|
||
overflow: hidden;
|
||
background: rgba(0, 0, 0, 0.08);
|
||
}
|
||
|
||
.page-loader-bar {
|
||
height: 100%;
|
||
width: 0%;
|
||
border-radius: 999px;
|
||
background: #111;
|
||
transition: width 220ms ease;
|
||
}
|
||
|
||
.page-loader-actions {
|
||
margin-top: 12px;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
gap: 10px;
|
||
}
|
||
|
||
/* Admin → Version: keep history rows clean and readable */
|
||
.app-version-list .list-group-item {
|
||
border-left: 0;
|
||
border-right: 0;
|
||
}
|
||
|
||
.app-version-list .list-group-item:first-child {
|
||
border-top: 0;
|
||
}
|
||
|
||
.app-version-list .list-group-item:last-child {
|
||
border-bottom: 0;
|
||
}
|
||
|
||
/* Admin: compact "sub tabs" used inside panels */
|
||
.admin-subtabs {
|
||
gap: 0.5rem;
|
||
}
|
||
|
||
.admin-subtabs .nav-item {
|
||
margin: 0;
|
||
}
|
||
|
||
.admin-subtabs.nav-pills .nav-link {
|
||
border: 1px solid rgba(0, 0, 0, 0.12);
|
||
background: #fff;
|
||
color: #111;
|
||
font-weight: 600;
|
||
padding: 0.45rem 0.8rem;
|
||
border-radius: 10px;
|
||
}
|
||
|
||
.admin-subtabs.nav-pills .nav-link:hover {
|
||
background: rgba(0, 0, 0, 0.03);
|
||
}
|
||
|
||
.admin-subtabs.nav-pills .nav-link.active {
|
||
background: #111;
|
||
border-color: #111;
|
||
color: #fff;
|
||
}
|
||
|
||
/* Admin → Version preview: keep it compact */
|
||
.app-version-preview {
|
||
white-space: pre-wrap;
|
||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||
font-size: 0.92rem;
|
||
}
|
||
|
||
/* Movies page helpers (Bootstrap-first, minimal custom) */
|
||
.movie-poster {
|
||
width: 100%;
|
||
max-height: 360px;
|
||
object-fit: contain;
|
||
}
|
||
|
||
.movie-rating-block {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
text-align: left;
|
||
gap: 2px;
|
||
font-size: 0.72rem;
|
||
line-height: 1.15;
|
||
color: rgba(0,0,0,0.6);
|
||
}
|
||
|
||
.movie-imdb-block {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
font-size: 0.75rem;
|
||
line-height: 1.1;
|
||
color: rgba(0,0,0,0.7);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.movie-rating-sub {
|
||
font-size: 0.7rem;
|
||
color: rgba(0,0,0,0.55);
|
||
}
|
||
|
||
.movie-rating-block .imdb-icon {
|
||
width: 18px;
|
||
height: 18px;
|
||
margin-left: 4px;
|
||
}
|
||
|
||
.movie-info-box {
|
||
margin-top: 10px;
|
||
margin-bottom: 10px;
|
||
padding: 8px 10px;
|
||
border-radius: 10px;
|
||
background: rgba(0, 0, 0, 0.03);
|
||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||
}
|
||
|
||
.movie-info-category {
|
||
font-size: 0.78rem;
|
||
color: rgba(0, 0, 0, 0.65);
|
||
font-weight: 600;
|
||
font-style: italic;
|
||
margin-bottom: 6px;
|
||
}
|
||
|
||
.movie-info-desc {
|
||
margin: 0;
|
||
font-size: 0.82rem;
|
||
line-height: 1.35;
|
||
color: rgba(0, 0, 0, 0.75);
|
||
}
|
||
|
||
.imdb-icon {
|
||
width: 26px;
|
||
height: 26px;
|
||
vertical-align: middle;
|
||
margin-left: 6px;
|
||
display: inline-block;
|
||
}
|
||
|
||
.watched-badge {
|
||
z-index: 2;
|
||
}
|
||
|
||
.cam-badge {
|
||
z-index: 2;
|
||
}
|
||
|
||
/* Stats → "Films regardés" modal */
|
||
.stats-movies-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||
gap: 12px;
|
||
}
|
||
|
||
.stats-movie-item {
|
||
display: flex;
|
||
gap: 12px;
|
||
padding: 12px;
|
||
background: #fff;
|
||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||
border-radius: 14px;
|
||
}
|
||
|
||
.stats-movie-item--clickable {
|
||
cursor: pointer;
|
||
}
|
||
|
||
.stats-movie-item--clickable:hover {
|
||
background: rgba(0, 0, 0, 0.02);
|
||
border-color: rgba(0, 0, 0, 0.14);
|
||
}
|
||
|
||
.stats-movie-poster {
|
||
width: 56px;
|
||
height: 84px;
|
||
border-radius: 10px;
|
||
object-fit: cover;
|
||
background: rgba(0, 0, 0, 0.06);
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
.stats-movie-poster.stats-movie-poster--empty {
|
||
background: linear-gradient(135deg, rgba(0,0,0,0.08), rgba(0,0,0,0.03));
|
||
}
|
||
|
||
.stats-movie-title {
|
||
font-weight: 700;
|
||
line-height: 1.2;
|
||
margin: 0;
|
||
}
|
||
|
||
.stats-movie-meta {
|
||
margin-top: 6px;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 6px 10px;
|
||
align-items: center;
|
||
font-size: 0.875rem;
|
||
}
|
||
|
||
.stats-movie-details {
|
||
margin-top: 6px;
|
||
}
|
||
|
||
.stats-movie-details summary {
|
||
cursor: pointer;
|
||
user-select: none;
|
||
font-size: 0.85rem;
|
||
color: rgba(0, 0, 0, 0.6);
|
||
list-style: none;
|
||
}
|
||
|
||
.stats-movie-details summary::-webkit-details-marker {
|
||
display: none;
|
||
}
|
||
|
||
.stats-movie-details summary::before {
|
||
content: "›";
|
||
display: inline-block;
|
||
margin-right: 6px;
|
||
transform: rotate(0deg);
|
||
transition: transform 120ms ease;
|
||
}
|
||
|
||
.stats-movie-details[open] summary::before {
|
||
transform: rotate(90deg);
|
||
}
|
||
|
||
.stats-movie-details-body {
|
||
margin-top: 6px;
|
||
padding-left: 14px;
|
||
line-height: 1.25rem;
|
||
overflow-wrap: anywhere;
|
||
}
|
||
|
||
.stats-movie-imdb {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
padding: 0.2rem 0.45rem;
|
||
line-height: 1.1;
|
||
}
|
||
|
||
.stats-movie-imdb .imdb-icon {
|
||
width: 18px;
|
||
height: 18px;
|
||
margin-left: 0;
|
||
}
|
||
|
||
/* Admin → Settings: keep controls compact */
|
||
.admin-settings-narrow {
|
||
max-width: 520px;
|
||
}
|
||
|
||
@media (max-width: 576px) {
|
||
.admin-settings-narrow {
|
||
max-width: 100%;
|
||
}
|
||
} |