Theme rework: polish dark mode and previews

Refine mobile nav layout, improve dark theme UI polish, and update README previews with light/dark variants.
This commit is contained in:
Mathieu Moran
2026-01-26 01:47:17 -05:00
parent 6f66eef0d4
commit 01c478aafe
21 changed files with 1301 additions and 66 deletions
+23 -1
View File
@@ -4,15 +4,37 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pool Oscars - Changer le mot de passe</title>
<script src="./js/app_theme.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="./css/app.css" rel="stylesheet">
</head>
<body class="bg-light">
<button class="theme-toggle theme-toggle--floating" type="button" data-theme-toggle role="switch" aria-checked="false" aria-label="Basculer le mode sombre">
<span class="theme-toggle-icon theme-toggle-icon-sun" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="M4.93 4.93l1.41 1.41"></path>
<path d="M17.66 17.66l1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="M4.93 19.07l1.41-1.41"></path>
<path d="M17.66 6.34l1.41-1.41"></path>
</svg>
</span>
<span class="theme-toggle-thumb" aria-hidden="true"></span>
<span class="theme-toggle-icon theme-toggle-icon-moon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"></path>
</svg>
</span>
</button>
<div class="container d-flex justify-content-center align-items-center vh-100">
<div class="card p-4" style="max-width: 420px; width: 100%;">
<div class="text-center mb-3">
<img src="img/logo.png" style="width: 80%;">
<img src="img/logo.png" class="logo-invert" style="width: 80%;" alt="Pool Oscars">
</div>
<div class="alert alert-warning" role="alert">
+34 -4
View File
@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pool Oscars - Checklist</title>
<script src="./js/app_theme.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="./css/app.css" rel="stylesheet">
<link rel="preload" as="image" href="img/logo_w.png">
@@ -61,9 +62,10 @@
<!-- Black banner with buttons and user info -->
<nav class="navbar navbar-expand-lg navbar-custom">
<div class="container">
<a class="navbar-brand" style="margin-left: -7px;" href="movies.html">
<a class="navbar-brand" href="movies.html">
<img src="img/logo_w.png" width="220" height="70" loading="eager" fetchpriority="high" decoding="async" style="max-width: 220px; height: 70px; object-fit: contain;">
</a>
<span class="navbar-text ms-auto me-2 d-lg-none navbar-user-name-mobile" data-user-name></span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@@ -76,15 +78,36 @@
<a id="admin-control-link" href="control.html" class="nav-link btn btn-warning me-2 d-none">Admin</a>
</div>
<!-- Move user info inside collapsible navbar and align it properly -->
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center">
<span id="user-name" class="navbar-text me-3"></span>
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center gap-2 navbar-user">
<span id="user-name" class="navbar-text" data-user-name></span>
<button class="theme-toggle" type="button" data-theme-toggle role="switch" aria-checked="false" aria-label="Basculer le mode sombre">
<span class="theme-toggle-icon theme-toggle-icon-sun" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="M4.93 4.93l1.41 1.41"></path>
<path d="M17.66 17.66l1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="M4.93 19.07l1.41-1.41"></path>
<path d="M17.66 6.34l1.41-1.41"></path>
</svg>
</span>
<span class="theme-toggle-thumb" aria-hidden="true"></span>
<span class="theme-toggle-icon theme-toggle-icon-moon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"></path>
</svg>
</span>
</button>
<button id="log-off" class="btn btn-danger">Déconnexion</button>
</div>
</div>
</div>
</nav>
<div class="container mt-5">
<div class="container mt-4">
<h2>Checklist</h2>
<!-- Summary card (match Stats page spacing/structure) -->
@@ -149,8 +172,15 @@
</div>
</div>
<!-- Footer Section -->
<footer>
<p id="footer-copy">Oscar Pool <span aria-hidden="true">·</span> <a id="copy" href="https://github.com/quoije/oscars-pool">quoije</a></p>
<p id="footer-text"></p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="./js/app_checklist.js"></script>
<script src="./js/app_version.js"></script>
</body>
</html>
+34 -4
View File
@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pool Oscars - Admin</title>
<script src="./js/app_theme.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="./css/app.css" rel="stylesheet">
<link rel="preload" as="image" href="img/logo_w.png">
@@ -32,9 +33,10 @@
<nav class="navbar navbar-expand-lg navbar-custom">
<div class="container">
<a class="navbar-brand" style="margin-left: -7px;" href="movies.html">
<a class="navbar-brand" href="movies.html">
<img src="img/logo_w.png" width="220" height="70" loading="eager" fetchpriority="high" decoding="async" style="max-width: 220px; height: 70px; object-fit: contain;">
</a>
<span class="navbar-text ms-auto me-2 d-lg-none navbar-user-name-mobile" data-user-name></span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@@ -46,15 +48,36 @@
<a href="picks.html" class="nav-link btn btn-outline-light me-2" id="nav-link-picks" style="display: none;">Mes picks</a>
<a href="control.html" class="nav-link btn btn-warning me-2">Admin</a>
</div>
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center">
<span id="user-name" class="navbar-text me-3"></span>
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center gap-2 navbar-user">
<span id="user-name" class="navbar-text" data-user-name></span>
<button class="theme-toggle" type="button" data-theme-toggle role="switch" aria-checked="false" aria-label="Basculer le mode sombre">
<span class="theme-toggle-icon theme-toggle-icon-sun" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="M4.93 4.93l1.41 1.41"></path>
<path d="M17.66 17.66l1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="M4.93 19.07l1.41-1.41"></path>
<path d="M17.66 6.34l1.41-1.41"></path>
</svg>
</span>
<span class="theme-toggle-thumb" aria-hidden="true"></span>
<span class="theme-toggle-icon theme-toggle-icon-moon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"></path>
</svg>
</span>
</button>
<button id="log-off" class="btn btn-danger">Déconnexion</button>
</div>
</div>
</div>
</nav>
<div class="container mt-5">
<div class="container mt-4">
<div class="mb-3">
<h2 class="mb-0">Admin</h2>
<div class="text-muted">Paramètres, utilisateurs et gestion des films.</div>
@@ -1465,8 +1488,15 @@
</div>
</div>
<!-- Footer Section -->
<footer>
<p id="footer-copy">Oscar Pool <span aria-hidden="true">·</span> <a id="copy" href="https://github.com/quoije/oscars-pool">quoije</a></p>
<p id="footer-text"></p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="./js/app_control.js"></script>
<script src="./js/app_version.js"></script>
</body>
</html>
+783 -11
View File
@@ -1,27 +1,36 @@
footer {
margin-top: auto;
padding: 25px;
padding: 20px 25px;
/* Light mode: keep the original light gray footer */
background-color: #f8f9fa;
color: var(--app-text);
text-align: center;
width: min(100%, calc(1320px - 24px));
margin-left: auto;
margin-right: auto;
}
#footer-text {
margin: -5px;
margin: 6px 0 0;
font-family:monospace;
font-size: small;
}
#footer-copy {
margin: -5px;
margin: 0;
font-family:monospace;
font-size: smaller;
padding-top: 10px;
padding-top: 0;
}
#copy {
text-decoration: none;
}
#copy::after {
content: " 🐴";
}
/* Simple, clean loading indicator (no spinner spam) */
.loading-indicator {
display: flex;
@@ -219,6 +228,8 @@ footer {
color: rgba(0,0,0,0.6);
}
/* (reserved) */
.movie-imdb-block {
display: inline-flex;
align-items: center;
@@ -245,16 +256,21 @@ footer {
}
.movie-rating-block .imdb-icon {
width: 18px;
height: 18px;
padding: 0 5px;
margin-left: 4px;
font-size: 10px;
}
.movie-imdb-wrap {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 0;
gap: 4px;
}
.movie-imdb-wrap .movie-rating-stars {
margin-top: 1px;
}
.movie-rating-stars {
@@ -267,7 +283,7 @@ footer {
.movie-star {
border: 0;
background: transparent;
color: rgba(0,0,0,0.25);
color: rgba(0, 0, 0, 0.5);
font-size: 0.9rem;
line-height: 1;
padding: 0 1px;
@@ -331,11 +347,23 @@ footer {
}
.imdb-icon {
width: 26px;
height: 26px;
height: 18px;
padding: 0 6px;
vertical-align: middle;
margin-left: 6px;
display: inline-block;
display: inline-flex;
align-items: center;
justify-content: center;
background: #f5c518;
color: #111;
border-radius: 4px;
font-family: "Arial Black", Arial, sans-serif;
font-size: 11px;
font-weight: 900;
letter-spacing: -0.4px;
line-height: 1;
text-transform: none;
white-space: nowrap;
}
.watched-badge {
@@ -442,10 +470,25 @@ footer {
line-height: 1.1;
}
.stats-movie-imdb.btn {
border: 0;
background: transparent;
padding: 0;
box-shadow: none;
}
.stats-movie-imdb.btn:hover,
.stats-movie-imdb.btn:focus {
border: 0;
background: transparent;
box-shadow: none;
}
.stats-movie-imdb .imdb-icon {
width: 18px;
height: 18px;
padding: 0 5px;
margin-left: 0;
font-size: 10px;
}
/* Admin → Settings: keep controls compact */
@@ -457,4 +500,733 @@ footer {
.admin-settings-narrow {
max-width: 100%;
}
}
:root {
--app-bg: #f5f6fb;
--app-surface: #ffffff;
--app-surface-alt: #f1f3f9;
--app-text: #111827;
--app-text-muted: rgba(17, 24, 39, 0.6);
--app-border: rgba(15, 23, 42, 0.12);
--app-ring: rgba(37, 99, 235, 0.35);
--app-shadow: 0 12px 30px rgba(15, 23, 42, 0.12);
--app-overlay: rgba(246, 247, 251, 0.7);
--app-loader-card: rgba(255, 255, 255, 0.9);
--app-navbar: #0a0b0d;
--app-navbar-border: rgba(255, 255, 255, 0.08);
--app-link: #1d4ed8;
--app-link-hover: #1e40af;
}
html[data-theme="dark"] {
color-scheme: dark;
/* Darker overall background + slightly deeper surfaces */
--app-bg: #05070b;
--app-surface: #0b1017;
--app-surface-alt: #101825;
--app-text: #e6e9f0;
--app-text-muted: rgba(230, 233, 240, 0.7);
--app-border: rgba(255, 255, 255, 0.11);
--app-ring: rgba(96, 165, 250, 0.45);
--app-shadow: 0 18px 38px rgba(0, 0, 0, 0.45);
--app-overlay: rgba(4, 6, 10, 0.78);
--app-loader-card: rgba(18, 22, 33, 0.9);
--app-navbar: #0b0d12;
--app-navbar-border: rgba(255, 255, 255, 0.1);
--app-link: #8ab4ff;
--app-link-hover: #b1ccff;
}
body {
background: var(--app-bg);
color: var(--app-text);
min-height: 100vh;
display: flex;
flex-direction: column;
}
body > .container {
flex: 1 0 auto;
}
body > footer {
margin-top: auto;
}
a {
color: var(--app-link);
}
a:hover {
color: var(--app-link-hover);
}
/* Tabs (light mode): keep it neutral (no bright blue) */
.nav-tabs .nav-link {
color: rgba(17, 24, 39, 0.72);
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
font-size: 0.9rem;
font-weight: 500;
letter-spacing: 0.1px;
padding: 0.45rem 0.8rem;
}
.nav-tabs .nav-link:hover {
color: rgba(17, 24, 39, 0.9);
}
.nav-tabs .nav-link.active {
color: #111827;
}
body.bg-light {
background-color: var(--app-bg) !important;
}
.bg-light {
background-color: var(--app-surface-alt) !important;
}
.text-dark {
color: var(--app-text) !important;
}
.text-muted {
color: var(--app-text-muted) !important;
}
html[data-theme="dark"] .logo-invert {
filter: invert(1) brightness(1.05);
}
/* Dark mode: footer matches tiles/cards */
html[data-theme="dark"] footer {
background-color: var(--app-surface);
color: var(--app-text);
}
footer.footer--plain {
background-color: transparent;
border: 0;
box-shadow: none;
}
footer.footer--player {
width: min(100%, calc(1100px - 24px));
}
footer.footer--auth {
width: min(100%, 400px);
}
.card,
.modal-content,
.list-group-item,
.dropdown-menu {
background-color: var(--app-surface);
color: var(--app-text);
border-color: var(--app-border);
box-shadow: var(--app-shadow);
}
.modal-header,
.modal-footer {
border-color: var(--app-border);
}
/* Bootstrap modal close (X) visibility in dark mode */
html[data-theme="dark"] .modal-header .btn-close {
filter: invert(1) grayscale(100%);
opacity: 0.85;
}
html[data-theme="dark"] .modal-header .btn-close:hover {
opacity: 1;
}
html[data-theme="dark"] .modal-header .btn-close:focus {
box-shadow: 0 0 0 0.2rem rgba(96, 165, 250, 0.25);
}
.table {
--bs-table-color: var(--app-text);
--bs-table-bg: transparent;
--bs-table-striped-bg: rgba(15, 23, 42, 0.05);
--bs-table-hover-bg: rgba(15, 23, 42, 0.08);
--bs-table-border-color: var(--app-border);
}
html[data-theme="dark"] .table {
--bs-table-striped-bg: rgba(255, 255, 255, 0.04);
--bs-table-hover-bg: rgba(255, 255, 255, 0.06);
}
html[data-theme="dark"] .progress {
background-color: rgba(255, 255, 255, 0.10);
}
html[data-theme="dark"] .progress-bar {
background-color: #60a5fa;
}
.page-loader-overlay {
background: var(--app-overlay);
}
.page-loader-card {
background: var(--app-loader-card);
border-color: var(--app-border);
box-shadow: var(--app-shadow);
}
.page-loader-title,
.page-loader-subtitle {
color: var(--app-text);
}
.page-loader-progress {
background: rgba(0, 0, 0, 0.08);
}
html[data-theme="dark"] .page-loader-progress {
background: rgba(255, 255, 255, 0.1);
}
.page-loader-bar {
background: var(--app-text);
}
.navbar-custom {
background-color: var(--app-navbar);
border-bottom: 1px solid var(--app-navbar-border);
}
/* The logo image has a bit of built-in left whitespace; nudge it back to align with page titles. */
.navbar-custom .navbar-brand img {
margin-left: -9px;
}
/* Mobile navbar: add vertical gaps + clean user row */
@media (max-width: 991.98px) {
.navbar-custom .navbar-nav {
gap: 0.5rem;
}
.navbar-custom .navbar-nav .nav-link.btn {
width: 100%;
text-align: center;
margin-right: 0 !important; /* overrides me-2 on mobile */
}
.navbar-custom .navbar-user {
width: 100%;
margin-top: 0.85rem !important;
padding-top: 0.85rem;
/* Mobile divider between nav buttons and user row */
border-top: 1px solid rgba(255, 255, 255, 0.18);
flex-wrap: wrap;
justify-content: space-between;
}
.navbar-custom .navbar-user-name-mobile {
max-width: 42vw;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-right: 0.75rem;
margin-right: 0.75rem !important; /* extra gap before hamburger */
border-right: 1px solid rgba(255, 255, 255, 0.18);
}
/* Avoid showing the username twice when the menu is open */
.navbar-custom .navbar-user #user-name {
display: none;
}
.navbar-custom .navbar-user .theme-toggle {
margin-right: 0 !important;
}
}
html[data-theme="dark"] .navbar-custom .btn-outline-light {
color: rgba(255, 255, 255, 0.9);
border-color: rgba(255, 255, 255, 0.25);
}
html[data-theme="dark"] .navbar-custom .btn-outline-light:hover {
background: rgba(255, 255, 255, 0.12);
}
html[data-theme="dark"] .btn-outline-dark {
color: var(--app-text);
border-color: var(--app-border);
}
html[data-theme="dark"] .btn-outline-dark:hover {
background: rgba(255, 255, 255, 0.08);
}
html[data-theme="dark"] .badge.bg-warning.text-dark {
color: #1f2937 !important;
}
/* Use a consistent "admin" blue instead of Bootstrap warning yellow. */
.btn-warning {
background-color: #1d4ed8;
border-color: #1d4ed8;
color: #fff;
}
.btn-warning:hover {
background-color: #1e40af;
border-color: #1e40af;
color: #fff;
}
.btn-warning:focus,
.btn-warning:focus-visible {
box-shadow: 0 0 0 0.2rem rgba(29, 78, 216, 0.35);
}
html[data-theme="dark"] .badge.bg-light {
background-color: var(--app-surface-alt) !important;
color: var(--app-text) !important;
}
html[data-theme="dark"] .badge.bg-dark {
background-color: #0f172a !important;
}
.movie-info-box {
background: var(--app-surface-alt);
border-color: var(--app-border);
}
.movie-rating-block,
.movie-imdb-block,
.movie-rating-sub,
.movie-info-summary,
.movie-info-category,
.movie-info-desc,
.stats-movie-details summary {
color: var(--app-text-muted);
}
html[data-theme="dark"] .movie-star {
color: rgba(255, 255, 255, 0.55);
}
html[data-theme="dark"] .movie-star.is-active {
color: #f4b400;
}
html[data-theme="dark"] .stats-movie-item {
background: var(--app-surface);
border-color: var(--app-border);
}
html[data-theme="dark"] .stats-movie-item--clickable:hover {
background: rgba(255, 255, 255, 0.04);
}
html[data-theme="dark"] .admin-subtabs.nav-pills .nav-link {
background: var(--app-surface);
border-color: var(--app-border);
color: var(--app-text);
}
html[data-theme="dark"] .admin-subtabs.nav-pills .nav-link:hover {
background: rgba(255, 255, 255, 0.06);
}
html[data-theme="dark"] .admin-subtabs.nav-pills .nav-link.active {
background: #4f7cff;
border-color: #4f7cff;
color: #fff;
}
html[data-theme="dark"] .nominee-option:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
}
html[data-theme="dark"] .nominee-option.selected {
box-shadow: 0 2px 8px rgba(79, 124, 255, 0.35);
}
html[data-theme="dark"] .nominee-checkmark {
background-color: rgba(255, 255, 255, 0.18);
color: #cfe1ff;
}
html[data-theme="dark"] .nominee-option.selected .nominee-checkmark {
background-color: rgba(255, 255, 255, 0.9);
color: #1d4ed8;
}
html[data-theme="dark"] .picks-table tbody tr:hover {
background-color: rgba(99, 102, 241, 0.12);
}
html[data-theme="dark"] .picks-table tbody tr.has-selection {
background-color: rgba(99, 102, 241, 0.18);
border-left-color: #6ea8fe;
}
html[data-theme="dark"] .pick-item {
border-bottom-color: rgba(255, 255, 255, 0.12);
}
html[data-theme="dark"] .correct-pick {
background-color: rgba(16, 185, 129, 0.18);
}
html[data-theme="dark"] .incorrect-pick {
background-color: rgba(248, 113, 113, 0.18);
}
html[data-theme="dark"] .meta-muted {
color: var(--app-text-muted);
}
html[data-theme="dark"] .player-surface {
border-color: rgba(255, 255, 255, 0.12);
}
html[data-theme="dark"] .quality-toggle {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.18);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}
html[data-theme="dark"] .quality-label {
color: var(--app-text-muted);
}
html[data-theme="dark"] .quality-pill {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.15);
}
html[data-theme="dark"] .quality-btn {
color: rgba(255, 255, 255, 0.7);
}
html[data-theme="dark"] .quality-btn.is-active {
background: #f8fafc;
color: #0f172a;
}
html[data-theme="dark"] .movie-table thead th,
html[data-theme="dark"] .user-table thead th {
color: rgba(255, 255, 255, 0.85);
}
html[data-theme="dark"] .user-table tbody td:first-child,
html[data-theme="dark"] .user-table tbody td:nth-child(3) {
color: rgba(255, 255, 255, 0.82);
}
html[data-theme="dark"] .stats-tabs .nav-link {
color: rgba(255, 255, 255, 0.7);
border-color: transparent;
}
html[data-theme="dark"] .stats-tabs .nav-link:hover {
color: #fff;
background: rgba(255, 255, 255, 0.06);
}
html[data-theme="dark"] .stats-tabs .nav-link.active {
color: #fff;
background: rgba(79, 124, 255, 0.18);
border-color: rgba(79, 124, 255, 0.4);
}
.user-table,
#pane-winners .table,
#pane-completion .table {
font-size: 1rem;
font-family: inherit;
}
html[data-theme="dark"] #pane-winners .table,
html[data-theme="dark"] #pane-completion .table {
color: var(--app-text);
}
html[data-theme="dark"] #pane-winners .table thead th,
html[data-theme="dark"] #pane-winners .table tbody td,
html[data-theme="dark"] #pane-completion .table thead th,
html[data-theme="dark"] #pane-completion .table tbody td {
color: rgba(255, 255, 255, 0.88);
}
html[data-theme="dark"] .user-table a {
color: #b9e3ff;
}
html[data-theme="dark"] .user-table a:hover {
color: #d7efff;
}
html[data-theme="dark"] #picksTabs .nav-link {
color: rgba(255, 255, 255, 0.7);
border-color: transparent;
}
html[data-theme="dark"] #picksTabs .nav-link:hover {
color: #fff;
background: rgba(255, 255, 255, 0.06);
}
html[data-theme="dark"] #picksTabs .nav-link.active {
color: #fff;
background: rgba(79, 124, 255, 0.18);
border-color: rgba(79, 124, 255, 0.4);
}
html[data-theme="dark"] #picksTabsContent .table {
--bs-table-color: var(--app-text);
--bs-table-striped-color: var(--app-text);
}
html[data-theme="dark"] #picksTabsContent .table thead th {
background-color: var(--app-surface-alt);
color: var(--app-text);
border-color: var(--app-border);
}
html[data-theme="dark"] #picksTabsContent .table tbody td {
color: rgba(230, 235, 245, 0.92);
}
html[data-theme="dark"] #picksTabsContent .table .table-success {
--bs-table-bg: rgba(96, 165, 250, 0.14);
--bs-table-striped-bg: rgba(96, 165, 250, 0.1);
--bs-table-hover-bg: rgba(96, 165, 250, 0.18);
color: rgba(230, 235, 245, 0.92);
}
html[data-theme="dark"] .bg-white {
background-color: var(--app-surface) !important;
color: var(--app-text);
}
html[data-theme="dark"] .border {
border-color: var(--app-border) !important;
}
html[data-theme="dark"] #adminTabs,
html[data-theme="dark"] #editMovieTabs {
border-bottom-color: var(--app-border);
}
html[data-theme="dark"] #adminTabs .nav-link,
html[data-theme="dark"] #editMovieTabs .nav-link {
color: rgba(255, 255, 255, 0.7);
border-color: transparent;
}
html[data-theme="dark"] #adminTabs .nav-link:hover,
html[data-theme="dark"] #editMovieTabs .nav-link:hover {
color: #fff;
background: rgba(255, 255, 255, 0.06);
}
html[data-theme="dark"] #adminTabs .nav-link.active,
html[data-theme="dark"] #editMovieTabs .nav-link.active {
color: #fff;
background: rgba(79, 124, 255, 0.18);
border-color: rgba(79, 124, 255, 0.4);
}
html[data-theme="dark"] #adminTabsContent .table,
html[data-theme="dark"] #adminTabs + .tab-content .table {
--bs-table-color: var(--app-text);
--bs-table-striped-color: var(--app-text);
}
html[data-theme="dark"] #adminTabsContent .table thead th,
html[data-theme="dark"] #adminTabs + .tab-content .table thead th {
background-color: var(--app-surface-alt);
color: var(--app-text);
border-color: var(--app-border);
}
html[data-theme="dark"] #adminTabsContent .table tbody td,
html[data-theme="dark"] #adminTabs + .tab-content .table tbody td {
color: rgba(230, 235, 245, 0.92);
}
html[data-theme="dark"] #adminTabsContent .table .text-muted,
html[data-theme="dark"] #adminTabs + .tab-content .table .text-muted {
color: rgba(230, 235, 245, 0.65) !important;
}
html[data-theme="dark"] #adminTabsContent .table a,
html[data-theme="dark"] #adminTabsContent .table .btn-link,
html[data-theme="dark"] #adminTabs + .tab-content .table a,
html[data-theme="dark"] #adminTabs + .tab-content .table .btn-link {
color: rgba(230, 235, 245, 0.92);
}
html[data-theme="dark"] #adminTabsContent .admin-movies-table td,
html[data-theme="dark"] #adminTabsContent .admin-movies-table th,
html[data-theme="dark"] #adminTabsContent .admin-movies-table .text-muted,
html[data-theme="dark"] #adminTabs + .tab-content .admin-movies-table td,
html[data-theme="dark"] #adminTabs + .tab-content .admin-movies-table th,
html[data-theme="dark"] #adminTabs + .tab-content .admin-movies-table .text-muted {
color: rgba(230, 235, 245, 0.92) !important;
}
html[data-theme="dark"] #picksTabsContent .btn-outline-primary {
color: rgba(226, 232, 240, 0.95);
border-color: rgba(148, 163, 184, 0.6);
background: rgba(15, 23, 42, 0.2);
}
html[data-theme="dark"] #picksTabsContent .btn-outline-primary:hover {
color: #fff;
border-color: rgba(148, 163, 184, 0.85);
background: rgba(148, 163, 184, 0.18);
}
html[data-theme="dark"] .movie-table .table-success {
--bs-table-bg: rgba(96, 165, 250, 0.14);
--bs-table-striped-bg: rgba(96, 165, 250, 0.1);
--bs-table-hover-bg: rgba(96, 165, 250, 0.18);
color: var(--app-text);
}
html[data-theme="dark"] .movie-table .table-success td {
border-color: rgba(96, 165, 250, 0.22);
}
html[data-theme="dark"] .movie-table .table-danger {
--bs-table-bg: rgba(148, 163, 184, 0.12);
--bs-table-striped-bg: rgba(148, 163, 184, 0.09);
--bs-table-hover-bg: rgba(148, 163, 184, 0.16);
color: var(--app-text);
}
html[data-theme="dark"] .movie-table .table-danger td {
border-color: rgba(148, 163, 184, 0.2);
}
html[data-theme="dark"] .movie-table {
--bs-table-color: var(--app-text);
--bs-table-striped-color: var(--app-text);
}
html[data-theme="dark"] .movie-table tbody td {
color: var(--app-text);
}
html[data-theme="dark"] .form-control,
html[data-theme="dark"] .form-select,
html[data-theme="dark"] .form-check-input {
background-color: var(--app-surface);
border-color: var(--app-border);
color: var(--app-text);
}
html[data-theme="dark"] .form-control::placeholder {
color: rgba(255, 255, 255, 0.5);
}
html[data-theme="dark"] .form-control:focus,
html[data-theme="dark"] .form-select:focus,
html[data-theme="dark"] .form-check-input:focus {
border-color: rgba(96, 165, 250, 0.6);
box-shadow: 0 0 0 0.2rem rgba(96, 165, 250, 0.25);
}
.theme-toggle {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 56px;
height: 30px;
border-radius: 999px;
border: 1px solid var(--app-border);
background: var(--app-surface-alt);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);
transition: background 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}
/* Make spacing between toggle and logout feel equal to username→toggle */
nav.navbar .theme-toggle {
margin-right: 0.45rem;
}
.theme-toggle:focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--app-ring);
}
.theme-toggle-icon {
position: absolute;
width: 16px;
height: 16px;
color: var(--app-text-muted);
transition: color 160ms ease;
top: 50%;
transform: translateY(-50%);
display: flex;
align-items: center;
justify-content: center;
}
.theme-toggle-icon svg {
display: block;
}
.theme-toggle-icon-sun {
left: 8px;
}
.theme-toggle-icon-moon {
right: 8px;
}
.theme-toggle-thumb {
position: absolute;
width: 22px;
height: 22px;
border-radius: 50%;
background: var(--app-text);
transform: translateX(-12px);
transition: transform 180ms ease, background 160ms ease;
}
html[data-theme="dark"] .theme-toggle {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.2);
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.4);
}
html[data-theme="dark"] .theme-toggle-icon {
color: rgba(255, 255, 255, 0.65);
}
html[data-theme="dark"] .theme-toggle-thumb {
transform: translateX(12px);
background: #f8fafc;
}
.theme-toggle--floating {
position: fixed;
top: 16px;
right: 16px;
z-index: 1060;
}
@media (max-width: 576px) {
.theme-toggle--floating {
top: 12px;
right: 12px;
}
}
+23 -9
View File
@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pool Oscars</title>
<script src="./js/app_theme.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="./css/app.css" rel="stylesheet">
<style>
@@ -23,11 +24,32 @@
</style>
</head>
<body class="bg-light">
<button class="theme-toggle theme-toggle--floating" type="button" data-theme-toggle role="switch" aria-checked="false" aria-label="Basculer le mode sombre">
<span class="theme-toggle-icon theme-toggle-icon-sun" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="M4.93 4.93l1.41 1.41"></path>
<path d="M17.66 17.66l1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="M4.93 19.07l1.41-1.41"></path>
<path d="M17.66 6.34l1.41-1.41"></path>
</svg>
</span>
<span class="theme-toggle-thumb" aria-hidden="true"></span>
<span class="theme-toggle-icon theme-toggle-icon-moon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"></path>
</svg>
</span>
</button>
<div class="container">
<div class="card p-4" style="max-width: 400px; margin: auto;">
<div class="text-center mb-4">
<img src="img/logo.png" style="width: 80%;">
<img src="img/logo.png" class="logo-invert" style="width: 80%;" alt="Pool Oscars">
</div>
<form id="login-form">
<div class="mb-3">
@@ -43,18 +65,10 @@
<p class="mt-3 text-center">Pas de compte? <a href="/register.html">Enregistrez-vous</a></p>
</div>
<!-- Footer Section -->
<footer>
<p id="footer-copy"><a id="copy" href="https://github.com/quoije/oscars-pool">quoije</a></p>
<p id="footer-text"></p>
</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="./js/app_index.js"></script>
<script src="./js/app_version.js"></script>
</body>
</html>
+11 -3
View File
@@ -41,9 +41,17 @@
return;
}
const nameEl = document.getElementById('user-name');
if (nameEl && !nameEl.textContent) {
nameEl.textContent = decoded.name || '';
const name = decoded.name || '';
const nameTargets = document.querySelectorAll('[data-user-name]');
if (nameTargets.length) {
nameTargets.forEach((el) => {
if (el && !el.textContent) el.textContent = name;
});
} else {
const nameEl = document.getElementById('user-name');
if (nameEl && !nameEl.textContent) {
nameEl.textContent = name;
}
}
const adminLink = document.getElementById('admin-control-link');
+1 -1
View File
@@ -579,7 +579,7 @@ window.addEventListener('DOMContentLoaded', async function () {
<div class="movie-imdb-block">
${movie.rating ? `<span>⭐ ${movie.rating}</span>` : ''}
<a href="https://www.imdb.com/title/${movie.imdb_id}/" target="_blank" rel="noopener noreferrer" aria-label="Voir sur IMDb">
<img src="/img/imdb.png" class="imdb-icon" alt="IMDb">
<span class="imdb-icon" aria-hidden="true">IMDb</span>
</a>
</div>
<div class="movie-rating-stars" role="group" aria-label="Noter ce film" data-movie-id="${movieId}" data-current-rating="${Number.isFinite(userRating) ? userRating : ''}">
+133
View File
@@ -0,0 +1,133 @@
// Theme toggle with system preference fallback.
(function () {
const STORAGE_KEY = 'theme_preference';
const THEME_ATTR = 'data-theme';
const SOURCE_ATTR = 'data-theme-source';
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const API_ENDPOINT = '/api/users/theme';
function normalizeTheme(value) {
return value === 'light' || value === 'dark' ? value : null;
}
function getSystemTheme() {
return mediaQuery.matches ? 'dark' : 'light';
}
function setTheme(theme, source) {
document.documentElement.setAttribute(THEME_ATTR, theme);
document.documentElement.setAttribute(SOURCE_ATTR, source);
updateToggleUi(theme, source);
}
function getAuthToken() {
try {
return localStorage.getItem('auth_token');
} catch (_) {
return null;
}
}
async function savePreferenceToServer(themePreference) {
const token = getAuthToken();
if (!token) return;
try {
await fetch(API_ENDPOINT, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({ themePreference: themePreference ?? null })
});
} catch (_) {
// Ignore network errors to avoid blocking UI.
}
}
async function syncPreferenceFromServer() {
const token = getAuthToken();
if (!token) return;
try {
const res = await fetch(API_ENDPOINT, {
headers: { 'Authorization': `Bearer ${token}` },
cache: 'no-store'
});
if (!res.ok) return;
const data = await res.json();
const pref = normalizeTheme(data?.themePreference);
if (pref) {
localStorage.setItem(STORAGE_KEY, pref);
} else {
localStorage.removeItem(STORAGE_KEY);
}
applyStoredOrSystem();
} catch (_) {
// Ignore fetch errors.
}
}
function applyStoredOrSystem() {
const stored = normalizeTheme(localStorage.getItem(STORAGE_KEY));
const theme = stored || getSystemTheme();
const source = stored ? 'user' : 'system';
setTheme(theme, source);
}
function toggleTheme() {
const stored = normalizeTheme(localStorage.getItem(STORAGE_KEY));
const current = stored || getSystemTheme();
const next = current === 'dark' ? 'light' : 'dark';
localStorage.setItem(STORAGE_KEY, next);
setTheme(next, 'user');
savePreferenceToServer(next);
}
function resetToSystem() {
localStorage.removeItem(STORAGE_KEY);
applyStoredOrSystem();
savePreferenceToServer(null);
}
function updateToggleUi(theme, source) {
const buttons = document.querySelectorAll('[data-theme-toggle]');
const isDark = theme === 'dark';
buttons.forEach((button) => {
button.setAttribute('aria-checked', String(isDark));
button.dataset.theme = theme;
const label = isDark ? 'Mode sombre' : 'Mode clair';
const sourceLabel = source === 'system' ? ' (système)' : '';
button.setAttribute('title', `${label}${sourceLabel} — Shift+clic pour système`);
});
}
applyStoredOrSystem();
syncPreferenceFromServer();
mediaQuery.addEventListener('change', () => {
const stored = normalizeTheme(localStorage.getItem(STORAGE_KEY));
if (!stored) {
applyStoredOrSystem();
}
});
function bindToggleButtons() {
document.querySelectorAll('[data-theme-toggle]').forEach((button) => {
if (button.dataset.themeBound === 'true') return;
button.dataset.themeBound = 'true';
button.addEventListener('click', (event) => {
if (event.shiftKey) {
resetToSystem();
return;
}
toggleTheme();
});
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', bindToggleButtons);
} else {
bindToggleButtons();
}
})();
+3 -8
View File
@@ -515,16 +515,11 @@ window.addEventListener('DOMContentLoaded', async function () {
imdbLink.rel = 'noopener noreferrer';
imdbLink.setAttribute('aria-label', 'Voir sur IMDb');
const imdbText = document.createElement('span');
imdbText.className = 'small';
imdbText.textContent = 'IMDb';
const imdbIcon = document.createElement('img');
imdbIcon.src = '/img/imdb.png';
const imdbIcon = document.createElement('span');
imdbIcon.className = 'imdb-icon';
imdbIcon.alt = 'IMDb';
imdbIcon.setAttribute('aria-hidden', 'true');
imdbIcon.textContent = 'IMDb';
imdbLink.appendChild(imdbText);
imdbLink.appendChild(imdbIcon);
right.appendChild(imdbLink);
}
+34 -4
View File
@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pool Oscars - Films</title>
<script src="./js/app_theme.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="./css/app.css" rel="stylesheet">
<link rel="preload" as="image" href="img/logo_w.png">
@@ -48,9 +49,10 @@
<!-- Black banner with buttons and user info -->
<nav class="navbar navbar-expand-lg navbar-custom">
<div class="container">
<a class="navbar-brand" style="margin-left: -7px;" href="movies.html">
<a class="navbar-brand" href="movies.html">
<img src="img/logo_w.png" width="220" height="70" loading="eager" fetchpriority="high" decoding="async" style="max-width: 220px; height: 70px; object-fit: contain;">
</a>
<span class="navbar-text ms-auto me-2 d-lg-none navbar-user-name-mobile" data-user-name></span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@@ -63,15 +65,36 @@
<a id="admin-control-link" href="control.html" class="nav-link btn btn-warning me-2 d-none">Admin</a>
</div>
<!-- Move user info inside collapsible navbar and align it properly -->
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center">
<span id="user-name" class="navbar-text me-3"></span>
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center gap-2 navbar-user">
<span id="user-name" class="navbar-text" data-user-name></span>
<button class="theme-toggle" type="button" data-theme-toggle role="switch" aria-checked="false" aria-label="Basculer le mode sombre">
<span class="theme-toggle-icon theme-toggle-icon-sun" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="M4.93 4.93l1.41 1.41"></path>
<path d="M17.66 17.66l1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="M4.93 19.07l1.41-1.41"></path>
<path d="M17.66 6.34l1.41-1.41"></path>
</svg>
</span>
<span class="theme-toggle-thumb" aria-hidden="true"></span>
<span class="theme-toggle-icon theme-toggle-icon-moon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"></path>
</svg>
</span>
</button>
<button id="log-off" class="btn btn-danger">Déconnexion</button>
</div>
</div>
</div>
</nav>
<div class="container mt-5 pb-5">
<div class="container mt-4 pb-5">
<h2>Films</h2>
<!-- Summary card (match Statistiques/Checklist structure) -->
@@ -104,8 +127,15 @@
</div>
</div>
<!-- Footer Section -->
<footer>
<p id="footer-copy">Oscar Pool <span aria-hidden="true">·</span> <a id="copy" href="https://github.com/quoije/oscars-pool">quoije</a></p>
<p id="footer-text"></p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="./js/app_movies.js"></script>
<script src="./js/app_version.js"></script>
</body>
</html>
+34 -4
View File
@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pool Oscars - Mes picks</title>
<script src="./js/app_theme.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="./css/app.css" rel="stylesheet">
<link rel="preload" as="image" href="img/logo_w.png">
@@ -121,9 +122,10 @@
<nav class="navbar navbar-expand-lg navbar-custom">
<div class="container">
<a class="navbar-brand" style="margin-left: -7px;" href="movies.html">
<a class="navbar-brand" href="movies.html">
<img src="img/logo_w.png" width="220" height="70" loading="eager" fetchpriority="high" decoding="async" style="max-width: 220px; height: 70px; object-fit: contain;">
</a>
<span class="navbar-text ms-auto me-2 d-lg-none navbar-user-name-mobile" data-user-name></span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@@ -135,15 +137,36 @@
<a href="picks.html" class="nav-link btn btn-outline-light me-2" id="nav-link-picks" style="display: none;">Mes picks</a>
<a id="admin-control-link" href="control.html" class="nav-link btn btn-warning me-2 d-none">Admin</a>
</div>
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center">
<span id="user-name" class="navbar-text me-3"></span>
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center gap-2 navbar-user">
<span id="user-name" class="navbar-text" data-user-name></span>
<button class="theme-toggle" type="button" data-theme-toggle role="switch" aria-checked="false" aria-label="Basculer le mode sombre">
<span class="theme-toggle-icon theme-toggle-icon-sun" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="M4.93 4.93l1.41 1.41"></path>
<path d="M17.66 17.66l1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="M4.93 19.07l1.41-1.41"></path>
<path d="M17.66 6.34l1.41-1.41"></path>
</svg>
</span>
<span class="theme-toggle-thumb" aria-hidden="true"></span>
<span class="theme-toggle-icon theme-toggle-icon-moon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"></path>
</svg>
</span>
</button>
<button id="log-off" class="btn btn-danger">Déconnexion</button>
</div>
</div>
</div>
</nav>
<div class="container mt-5 pb-5">
<div class="container mt-4 pb-5">
<h2>Mes picks Oscars</h2>
<div id="alert-container"></div>
@@ -241,8 +264,15 @@
</div>
</div>
<!-- Footer Section -->
<footer>
<p id="footer-copy">Oscar Pool <span aria-hidden="true">·</span> <a id="copy" href="https://github.com/quoije/oscars-pool">quoije</a></p>
<p id="footer-text"></p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.js"></script>
<script src="./js/app_picks.js"></script>
<script src="./js/app_version.js"></script>
</body>
</html>
+43 -5
View File
@@ -6,6 +6,7 @@
<!-- IMPORTANT: the player may use ?token=... for cross-origin video streaming -->
<meta name="referrer" content="no-referrer" />
<title>Pool Oscars</title>
<script src="./js/app_theme.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="./css/app.css" rel="stylesheet">
<link rel="preload" as="image" href="img/logo_w.png">
@@ -123,7 +124,7 @@
.star-btn {
border: 0;
background: transparent;
color: rgba(0,0,0,0.25);
color: rgba(0,0,0,0.5);
font-size: 1.1rem;
line-height: 1;
padding: .15rem .2rem;
@@ -131,6 +132,14 @@
.star-btn.is-active {
color: #f4b400;
}
html[data-theme="dark"] .star-btn {
color: rgba(255, 255, 255, 0.55);
}
html[data-theme="dark"] .star-btn.is-active {
color: #f4b400;
}
.star-btn:focus-visible {
outline: 2px solid rgba(13,110,253,.35);
outline-offset: 2px;
@@ -194,9 +203,10 @@
<!-- Black banner with buttons and user info -->
<nav class="navbar navbar-expand-lg navbar-custom">
<div class="container">
<a class="navbar-brand" style="margin-left: -7px;" href="movies.html">
<a class="navbar-brand" href="movies.html">
<img src="img/logo_w.png" width="220" height="70" loading="eager" fetchpriority="high" decoding="async" style="max-width: 220px; height: 70px; object-fit: contain;">
</a>
<span class="navbar-text ms-auto me-2 d-lg-none navbar-user-name-mobile" data-user-name></span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@@ -208,15 +218,36 @@
<a href="picks.html" class="nav-link btn btn-outline-light me-2" id="nav-link-picks" style="display: none;">Mes picks</a>
<a id="admin-control-link" href="control.html" class="nav-link btn btn-warning me-2 d-none">Admin</a>
</div>
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center gap-2">
<span id="user-name" class="navbar-text me-1"></span>
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center gap-2 navbar-user">
<span id="user-name" class="navbar-text" data-user-name></span>
<button class="theme-toggle" type="button" data-theme-toggle role="switch" aria-checked="false" aria-label="Basculer le mode sombre">
<span class="theme-toggle-icon theme-toggle-icon-sun" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="M4.93 4.93l1.41 1.41"></path>
<path d="M17.66 17.66l1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="M4.93 19.07l1.41-1.41"></path>
<path d="M17.66 6.34l1.41-1.41"></path>
</svg>
</span>
<span class="theme-toggle-thumb" aria-hidden="true"></span>
<span class="theme-toggle-icon theme-toggle-icon-moon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"></path>
</svg>
</span>
</button>
<button id="log-off" class="btn btn-danger">Déconnexion</button>
</div>
</div>
</div>
</nav>
<div class="container mt-5 pb-4 player-wrap">
<div class="container mt-4 pb-4 player-wrap">
<div id="alert" class="alert alert-danger d-none" role="alert"></div>
<!-- Header / metadata -->
@@ -288,10 +319,17 @@
</div>
</div>
<!-- Footer Section -->
<footer class="footer--player">
<p id="footer-copy">Oscar Pool <span aria-hidden="true">·</span> <a id="copy" href="https://github.com/quoije/oscars-pool">quoije</a></p>
<p id="footer-text"></p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<!-- HLS support (m3u8) -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/hls.min.js"></script>
<script src="./js/app_player.js"></script>
<script src="./js/app_version.js"></script>
</body>
</html>
+23 -1
View File
@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pool Oscars - Enregistrement</title>
<script src="./js/app_theme.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="./css/app.css" rel="stylesheet">
</head>
@@ -16,11 +17,32 @@
}
</style>
<body class="bg-light">
<button class="theme-toggle theme-toggle--floating" type="button" data-theme-toggle role="switch" aria-checked="false" aria-label="Basculer le mode sombre">
<span class="theme-toggle-icon theme-toggle-icon-sun" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="M4.93 4.93l1.41 1.41"></path>
<path d="M17.66 17.66l1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="M4.93 19.07l1.41-1.41"></path>
<path d="M17.66 6.34l1.41-1.41"></path>
</svg>
</span>
<span class="theme-toggle-thumb" aria-hidden="true"></span>
<span class="theme-toggle-icon theme-toggle-icon-moon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"></path>
</svg>
</span>
</button>
<div class="container d-flex justify-content-center align-items-center vh-100">
<div class="card p-4" style="max-width: 400px;">
<div class="text-center mb-4">
<img src="img/logo.png" style="width: 80%";>
<img src="img/logo.png" class="logo-invert" style="width: 80%;" alt="Pool Oscars">
</div>
<form id="register-form">
<div class="mb-3">
+35 -5
View File
@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pool Oscars - Statistiques des utilisateurs</title>
<script src="./js/app_theme.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="./css/app.css" rel="stylesheet">
<link rel="preload" as="image" href="img/logo_w.png">
@@ -32,7 +33,7 @@
/* Stats tabs */
.stats-tabs .nav-link {
font-weight: 600;
font-weight: 400;
}
.stats-tab-panel {
padding-top: 1rem;
@@ -54,9 +55,10 @@
<!-- Black banner with buttons and user info -->
<nav class="navbar navbar-expand-lg navbar-custom">
<div class="container">
<a class="navbar-brand" style="margin-left: -7px;" href="movies.html">
<a class="navbar-brand" href="movies.html">
<img src="img/logo_w.png" width="220" height="70" loading="eager" fetchpriority="high" decoding="async" style="max-width: 220px; height: 70px; object-fit: contain;">
</a>
<span class="navbar-text ms-auto me-2 d-lg-none navbar-user-name-mobile" data-user-name></span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@@ -69,15 +71,36 @@
<a id="admin-control-link" href="control.html" class="nav-link btn btn-warning me-2 d-none">Admin</a>
</div>
<!-- Move user info inside collapsible navbar and align it properly -->
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center">
<span id="user-name" class="navbar-text me-3"></span>
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center gap-2 navbar-user">
<span id="user-name" class="navbar-text" data-user-name></span>
<button class="theme-toggle" type="button" data-theme-toggle role="switch" aria-checked="false" aria-label="Basculer le mode sombre">
<span class="theme-toggle-icon theme-toggle-icon-sun" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="M4.93 4.93l1.41 1.41"></path>
<path d="M17.66 17.66l1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="M4.93 19.07l1.41-1.41"></path>
<path d="M17.66 6.34l1.41-1.41"></path>
</svg>
</span>
<span class="theme-toggle-thumb" aria-hidden="true"></span>
<span class="theme-toggle-icon theme-toggle-icon-moon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"></path>
</svg>
</span>
</button>
<button id="log-off" class="btn btn-danger">Déconnexion</button>
</div>
</div>
</div>
</nav>
<div class="container mt-5">
<div class="container mt-4">
<h2>Statistiques des utilisateurs</h2>
<!-- Tabs -->
@@ -185,8 +208,15 @@
</div>
</div>
<!-- Footer Section -->
<footer>
<p id="footer-copy">Oscar Pool <span aria-hidden="true">·</span> <a id="copy" href="https://github.com/quoije/oscars-pool">quoije</a></p>
<p id="footer-text"></p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="./js/app_user-stat.js"></script>
<script src="./js/app_version.js"></script>
</body>
</html>
+34 -4
View File
@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pool Oscars - Voir Tous les Choix</title>
<script src="./js/app_theme.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="./css/app.css" rel="stylesheet">
<link rel="preload" as="image" href="img/logo_w.png">
@@ -48,9 +49,10 @@
<nav class="navbar navbar-expand-lg navbar-custom">
<div class="container">
<a class="navbar-brand" style="margin-left: -7px;" href="movies.html">
<a class="navbar-brand" href="movies.html">
<img src="img/logo_w.png" width="220" height="70" loading="eager" fetchpriority="high" decoding="async" style="max-width: 220px; height: 70px; object-fit: contain;">
</a>
<span class="navbar-text ms-auto me-2 d-lg-none navbar-user-name-mobile" data-user-name></span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@@ -63,15 +65,36 @@
<a href="control.html" class="nav-link btn btn-warning me-2">Admin</a>
<a href="view-picks.html" class="nav-link btn btn-info me-2 active">Voir Tous les Choix</a>
</div>
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center">
<span id="user-name" class="navbar-text me-3"></span>
<div class="d-flex ms-auto mt-2 mt-lg-0 align-items-center gap-2 navbar-user">
<span id="user-name" class="navbar-text" data-user-name></span>
<button class="theme-toggle" type="button" data-theme-toggle role="switch" aria-checked="false" aria-label="Basculer le mode sombre">
<span class="theme-toggle-icon theme-toggle-icon-sun" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="M4.93 4.93l1.41 1.41"></path>
<path d="M17.66 17.66l1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="M4.93 19.07l1.41-1.41"></path>
<path d="M17.66 6.34l1.41-1.41"></path>
</svg>
</span>
<span class="theme-toggle-thumb" aria-hidden="true"></span>
<span class="theme-toggle-icon theme-toggle-icon-moon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"></path>
</svg>
</span>
</button>
<button id="log-off" class="btn btn-danger">Déconnexion</button>
</div>
</div>
</div>
</nav>
<div class="container mt-5 pb-5">
<div class="container mt-4 pb-5">
<h2>Voir Tous les Choix</h2>
<div id="alert-container"></div>
@@ -100,8 +123,15 @@
</div>
</div>
<!-- Footer Section -->
<footer>
<p id="footer-copy">Oscar Pool <span aria-hidden="true">·</span> <a id="copy" href="https://github.com/quoije/oscars-pool">quoije</a></p>
<p id="footer-text"></p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.js"></script>
<script src="./js/app_view-picks.js"></script>
<script src="./js/app_version.js"></script>
</body>
</html>