From 181e477a0e5abccd62b543ed6fe506c521f1601e Mon Sep 17 00:00:00 2001 From: Johnnybegood90 Date: Fri, 13 Mar 2026 22:05:06 +0100 Subject: [PATCH 1/2] Split the CSS from head.php into separate files. --- config.example.json | 5 - src/css/base.css | 35 ++ src/css/favorites.css | 16 + src/css/grid.css | 311 +++++++++++++++ src/css/mobile.css | 103 +++++ src/css/modals.css | 40 ++ src/css/player.css | 78 ++++ src/css/program.css | 52 +++ src/css/search.css | 39 ++ src/css/topbar.css | 211 ++++++++++ src/css/updater.css | 13 + src/tpl/head.php | 891 +----------------------------------------- 12 files changed, 908 insertions(+), 886 deletions(-) delete mode 100644 config.example.json create mode 100644 src/css/base.css create mode 100644 src/css/favorites.css create mode 100644 src/css/grid.css create mode 100644 src/css/mobile.css create mode 100644 src/css/modals.css create mode 100644 src/css/player.css create mode 100644 src/css/program.css create mode 100644 src/css/search.css create mode 100644 src/css/topbar.css create mode 100644 src/css/updater.css diff --git a/config.example.json b/config.example.json deleted file mode 100644 index 82b010a..0000000 --- a/config.example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "group_name": "MonGroupe TV", - "epg_url": "http://votre-serveur/api/xmltv.xml", - "m3u_url": "http://votre-serveur/api/channels.m3u" -} diff --git a/src/css/base.css b/src/css/base.css new file mode 100644 index 0000000..205f888 --- /dev/null +++ b/src/css/base.css @@ -0,0 +1,35 @@ +/* Variables de base — surchargées par le fichier thème */ + :root { + --bg: #0a0b0d; + --surface: #111318; + --surface2: #181b22; + --border: #232733; + --border-bright: #2e3444; + --accent: #e8c842; + --accent2: #4a9eff; + --accent-live: #ff4444; + --text: #c8cdd8; + --text-dim: #5a6070; + --text-bright: #eef0f5; + --prog-bg: #141820; + --prog-border: #1e2a3a; + --prog-live-bg: #0d2040; + --prog-live-border: #4a9eff; + --font-ui: 'Barlow Condensed', sans-serif; + --font-mono: 'Share Tech Mono', monospace; + --channel-w: 160px; + --row-h: 80px; + --header-h: 52px; + } + + html, body { height: 100%; } + + body { + background: var(--bg); + color: var(--text); + font-family: var(--font-ui); + font-size: 14px; + overflow: hidden; + display: flex; + flex-direction: column; + } diff --git a/src/css/favorites.css b/src/css/favorites.css new file mode 100644 index 0000000..05b4a17 --- /dev/null +++ b/src/css/favorites.css @@ -0,0 +1,16 @@ +/* ── FAVORITES ───────────────────────────────────────────────────────────── */ + .fav-btn { + background: none; border: none; color: var(--text-muted); + cursor: pointer; font-size: 14px; line-height: 1; + margin-left: auto; padding: 2px 4px; flex-shrink: 0; + transition: color .15s, transform .15s; + opacity: 0; + } + .channel-cell:hover .fav-btn { opacity: 1; } + .fav-btn.is-fav { color: var(--accent); opacity: 1; } + .fav-btn:hover { transform: scale(1.2); } + + .fav-separator { + height: 2px; background: var(--accent); + opacity: .3; margin: 0; + } diff --git a/src/css/grid.css b/src/css/grid.css new file mode 100644 index 0000000..48c62b5 --- /dev/null +++ b/src/css/grid.css @@ -0,0 +1,311 @@ +/* ═══════════════════════════════════════════ + GRID VIEW (desktop / tablet) + ═══════════════════════════════════════════ */ + .grid-wrapper { + flex: 1; + display: flex; + overflow: hidden; + position: relative; + min-height: 0; + } + + .channels-col { + width: var(--channel-w); + flex-shrink: 0; + background: var(--surface); + border-right: 1px solid var(--border-bright); + z-index: 10; + display: flex; + flex-direction: column; + min-height: 0; + } + + .channels-col-header { + height: var(--header-h); + border-bottom: 1px solid var(--border-bright); + display: flex; + align-items: center; + padding: 0 12px; + flex-shrink: 0; + } + .channels-col-header span { + font-family: 'Share Tech Mono', monospace; + font-size: 9px; + color: var(--text-dim); + letter-spacing: 0.15em; + text-transform: uppercase; + } + + .channels-list { + overflow-y: auto; + flex: 1; + scrollbar-width: none; + } + .channels-list::-webkit-scrollbar { display: none; } + + .channel-cell { + height: var(--row-h); + border-bottom: 1px solid var(--border); + display: flex; + align-items: center; + padding: 0 12px; + gap: 8px; + flex-shrink: 0; + } + + .channel-logo { + width: 32px; height: 32px; + border-radius: 4px; + object-fit: contain; + background: var(--surface2); + flex-shrink: 0; + } + .channel-logo-placeholder { + width: 32px; height: 32px; + border-radius: 4px; + background: var(--surface2); + border: 1px solid var(--border); + display: flex; + align-items: center; + justify-content: center; + font-family: 'Share Tech Mono', monospace; + font-size: 9px; + color: var(--text-dim); + flex-shrink: 0; + } + + .channel-name { + font-size: 12px; + font-weight: 600; + color: var(--text-bright); + letter-spacing: 0.04em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + text-transform: uppercase; + } + + .timeline-area { + flex: 1; + overflow: auto; + position: relative; + min-height: 0; + scrollbar-width: thin; + scrollbar-color: var(--border-bright) transparent; + } + .timeline-area::-webkit-scrollbar { height: 4px; width: 4px; } + .timeline-area::-webkit-scrollbar-track { background: transparent; } + .timeline-area::-webkit-scrollbar-thumb { background: var(--border-bright); border-radius: 2px; } + + /* Conteneur unique — ruler + programmes scrollent ensemble */ + .timeline-inner { + position: relative; + display: block; + min-width: 100%; + } + + .time-ruler { + height: var(--header-h); + background: var(--surface); + border-bottom: 1px solid var(--border-bright); + position: sticky; + top: 0; + z-index: 20; + } + .time-ruler-inner { + position: relative; + height: 100%; + } + .time-tick { + position: absolute; + bottom: 0; + display: flex; + flex-direction: column; + align-items: flex-start; + } + .time-tick-label { + font-family: 'Share Tech Mono', monospace; + font-size: 10px; + color: var(--text-dim); + letter-spacing: 0.08em; + padding: 0 6px 6px; + white-space: nowrap; + } + .time-tick-label.hour { color: var(--text); font-size: 12px; } + .time-tick-line { width: 1px; height: 8px; background: var(--border-bright); } + .time-tick-line.hour { height: 14px; } + + .now-line { + position: absolute; + top: 0; + width: 2px; + height: 100%; + background: var(--accent-live); + z-index: 50; + pointer-events: none; + } + .now-line::before { + content: ''; + position: absolute; + top: 0; left: -4px; + width: 10px; height: 10px; + background: var(--accent-live); + border-radius: 50%; + } + + .programs-inner { + position: relative; + background-image: repeating-linear-gradient( + to bottom, + transparent 0px, transparent 79px, + var(--border) 79px, var(--border) 80px + ); + } + + .program-row { + height: var(--row-h); + border-bottom: 1px solid var(--border); + position: absolute; + left: 0; right: 0; + } + + .program-block { + position: absolute; + top: 5px; bottom: 5px; + background: var(--surface2); + border: 1px solid var(--border); + border-radius: 3px; + padding: 0 8px; + display: flex; + flex-direction: column; + justify-content: center; + overflow: hidden; + cursor: default; + transition: background 0.12s, border-color 0.12s; + min-width: 2px; + } + .program-block:hover { background: var(--surface); border-color: var(--accent2); z-index: 5; } + .program-block.is-live { border-color: var(--accent2); background: #0d1a2e; } + .program-block.is-live::after { + content: ''; + position: absolute; + bottom: 0; left: 0; + height: 2px; + background: var(--accent2); + width: var(--progress, 0%); + transition: width 1s linear; + } + .program-block.is-past { opacity: 0.35; } + + .program-title { + font-size: 12px; + font-weight: 600; + color: var(--text-bright); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + letter-spacing: 0.02em; + } + .program-time { + font-family: 'Share Tech Mono', monospace; + font-size: 9px; + color: var(--text-dim); + letter-spacing: 0.06em; + white-space: nowrap; + } + + /* ═══════════════════════════════════════════ + MOBILE LIST VIEW + ═══════════════════════════════════════════ */ + .mobile-view { + display: none; + flex: 1; + overflow-y: auto; + min-height: 0; + /* TOOLTIP */ + .tooltip { + position: fixed; + background: var(--surface); + border: 1px solid var(--accent2); + border-radius: 4px; + padding: 10px 14px; + z-index: 999; + pointer-events: none; + max-width: 300px; + opacity: 0; + transition: opacity 0.15s; + } + .tooltip.visible { opacity: 1; } + .tooltip-title { font-size: 14px; font-weight: 700; color: var(--text-bright); margin-bottom: 4px; } + .tooltip-time { font-family: 'Share Tech Mono', monospace; font-size: 10px; color: var(--accent2); margin-bottom: 6px; } + .tooltip-desc { font-size: 12px; color: var(--text); line-height: 1.4; max-height: 80px; overflow: hidden; } + + /* LOADING */ + .loading { + position: fixed; inset: 0; + background: var(--bg); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 1000; + gap: 20px; + } + .loading-text { + font-family: 'Share Tech Mono', monospace; + font-size: 12px; + color: var(--text-dim); + letter-spacing: 0.2em; + text-transform: uppercase; + } + .loading-bar { + width: 200px; height: 2px; + background: var(--border); + position: relative; + overflow: hidden; + } + .loading-bar::after { + content: ''; + position: absolute; + top: 0; left: -60%; + width: 60%; height: 100%; + background: var(--accent); + animation: loading-anim 1.2s ease-in-out infinite; + } + @keyframes loading-anim { to { left: 110%; } } + + .error-msg { + position: fixed; inset: 0; + background: var(--bg); + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 1000; + gap: 16px; + display: none; + padding: 20px; + } + .err-title { font-family: 'Share Tech Mono', monospace; font-size: 14px; color: var(--accent-live); letter-spacing: 0.1em; } + .err-sub { font-size: 13px; color: var(--text-dim); text-align: center; max-width: 400px; line-height: 1.5; } + .epg-input-bar { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; justify-content: center; } + .epg-input { + background: var(--surface2); + border: 1px solid var(--border-bright); + color: var(--text-bright); + font-family: 'Share Tech Mono', monospace; + font-size: 12px; + padding: 8px 12px; + width: 320px; + outline: none; + } + .epg-input:focus { border-color: var(--accent); } + .epg-btn { + background: var(--accent); + border: none; color: #000; + font-family: 'Barlow Condensed', sans-serif; + font-weight: 700; font-size: 13px; + letter-spacing: 0.1em; + text-transform: uppercase; + padding: 8px 18px; + cursor: pointer; + } diff --git a/src/css/mobile.css b/src/css/mobile.css new file mode 100644 index 0000000..38fb563 --- /dev/null +++ b/src/css/mobile.css @@ -0,0 +1,103 @@ +/* ═══════════════════════════════════════════ + MOBILE LIST VIEW + ═══════════════════════════════════════════ */ + .mobile-view { + display: none; + flex: 1; + overflow-y: auto; + min-height: 0; + -webkit-overflow-scrolling: touch; + } + + .mobile-channel { + border-bottom: 2px solid var(--border-bright); + } + + .mobile-channel-header { + display: flex; + align-items: center; + gap: 10px; + padding: 10px 14px; + background: var(--surface); + position: sticky; + top: 0; + z-index: 10; + border-bottom: 1px solid var(--border); + } + + .mobile-programs { + padding: 6px 10px; + display: flex; + flex-direction: column; + gap: 4px; + } + + .mobile-program { + display: flex; + align-items: stretch; + border-radius: 4px; + overflow: hidden; + border: 1px solid var(--border); + background: var(--surface2); + position: relative; + } + .mobile-program.is-live { border-color: var(--accent2); background: #0d1a2e; } + .mobile-program.is-past { opacity: 0.4; } + + .mobile-program-progress { + position: absolute; + bottom: 0; left: 0; + height: 2px; + background: var(--accent2); + } + + .mobile-program-time { + font-family: 'Share Tech Mono', monospace; + font-size: 10px; + color: var(--text-dim); + padding: 8px 10px; + background: var(--surface); + border-right: 1px solid var(--border); + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + min-width: 72px; + flex-shrink: 0; + gap: 2px; + } + .mobile-program.is-live .mobile-program-time { color: var(--accent2); } + + .mobile-program-info { + padding: 8px 10px; + flex: 1; + min-width: 0; + } + .mobile-program-title { + font-size: 13px; + font-weight: 600; + color: var(--text-bright); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + .mobile-program-dur { + font-size: 10px; + color: var(--text-dim); + margin-top: 2px; + font-family: 'Share Tech Mono', monospace; + } + + .mobile-live-badge { + font-family: 'Share Tech Mono', monospace; + font-size: 9px; + color: var(--accent-live); + background: rgba(255,68,68,0.12); + border: 1px solid var(--accent-live); + border-radius: 2px; + padding: 2px 5px; + letter-spacing: 0.1em; + align-self: center; + margin-right: 8px; + flex-shrink: 0; + } diff --git a/src/css/modals.css b/src/css/modals.css new file mode 100644 index 0000000..ae82e04 --- /dev/null +++ b/src/css/modals.css @@ -0,0 +1,40 @@ +/* ── MODAL PERSONAL EPG ─────────────────────────────────────────────────── */ + .modal-overlay { + position: fixed; inset: 0; background: rgba(0,0,0,0.7); + z-index: 3000; display: none; align-items: center; justify-content: center; + } + .modal-overlay.visible { display: flex; } + .modal-card { + background: var(--surface); border: 1px solid var(--border-bright); + padding: 28px; width: 100%; max-width: 420px; margin: 16px; + } + .modal-title { + font-family: var(--font-mono); font-size: 13px; color: var(--accent); + letter-spacing: 0.1em; text-transform: uppercase; margin-bottom: 6px; + } + .modal-subtitle { font-size: 12px; color: var(--text-dim); margin-bottom: 20px; line-height: 1.5; } + .modal-field { margin-bottom: 14px; } + .modal-field label { + display: block; font-family: var(--font-mono); font-size: 10px; + letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-dim); margin-bottom: 6px; + } + .modal-field input { + width: 100%; background: var(--surface2); border: 1px solid var(--border-bright); + color: var(--text-bright); font-family: var(--font-mono); font-size: 12px; + padding: 9px 10px; outline: none; transition: border-color 0.15s; + } + .modal-field input:focus { border-color: var(--accent); } + .modal-field input::placeholder { color: var(--text-dim); opacity: 0.4; } + .modal-actions { display: flex; gap: 10px; margin-top: 20px; justify-content: flex-end; } + .modal-btn-cancel { + background: none; border: 1px solid var(--border-bright); color: var(--text-dim); + font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; + text-transform: uppercase; padding: 8px 16px; cursor: pointer; transition: border-color 0.15s; + } + .modal-btn-cancel:hover { border-color: var(--text-dim); color: var(--text); } + .modal-btn-apply { + background: var(--accent); border: none; color: #000; + font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; + text-transform: uppercase; padding: 8px 20px; cursor: pointer; transition: opacity 0.15s; + } + .modal-btn-apply:hover { opacity: 0.85; } diff --git a/src/css/player.css b/src/css/player.css new file mode 100644 index 0000000..7771f67 --- /dev/null +++ b/src/css/player.css @@ -0,0 +1,78 @@ +/* ═══════════════════════════════════════════ + PLAYER PiP + ═══════════════════════════════════════════ */ + .pip { + position: fixed; + bottom: 24px; + right: 24px; + width: 380px; + background: #000; + border: 1px solid var(--border-bright); + box-shadow: 0 8px 32px rgba(0,0,0,0.8); + z-index: 2000; + display: none; + flex-direction: column; + } + .pip.visible { display: flex; } + .pip-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 6px 10px; + background: var(--surface); + border-bottom: 1px solid var(--border); + gap: 8px; + flex-shrink: 0; + } + .pip-channel { + font-family: var(--font-mono); + font-size: 11px; + color: var(--accent); + letter-spacing: 0.08em; + text-transform: uppercase; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex: 1; + } + .pip-program { + font-size: 11px; + color: var(--text-dim); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex: 2; + text-align: center; + } + .pip-close { + background: none; + border: none; + color: var(--text-dim); + font-size: 18px; + cursor: pointer; + padding: 0 4px; + line-height: 1; + flex-shrink: 0; + transition: color 0.15s; + } + .pip-close:hover { color: var(--accent-live); } + .pip video { + width: 100%; + aspect-ratio: 16/9; + display: block; + background: #000; + } + .pip-error { + padding: 20px; + text-align: center; + font-family: var(--font-mono); + font-size: 11px; + color: var(--accent-live); + letter-spacing: 0.06em; + } + .channel-cell { cursor: pointer; } + .channel-cell:hover { background: var(--surface2); } + .program-block.is-live { cursor: pointer; } + @media (max-width: 600px) { + .pip { width: calc(100vw - 16px); bottom: 8px; right: 8px; left: 8px; } + } diff --git a/src/css/program.css b/src/css/program.css new file mode 100644 index 0000000..6c046b4 --- /dev/null +++ b/src/css/program.css @@ -0,0 +1,52 @@ +/* ── PROGRAM MODAL ───────────────────────────────────────────────────────── */ + .program-card { + max-width: 520px; padding: 28px; position: relative; + } + .pm-close { + position: absolute; top: 14px; right: 14px; + background: none; border: none; color: var(--text-muted); + cursor: pointer; font-size: 18px; line-height: 1; + transition: color .2s; + } + .pm-close:hover { color: var(--accent); } + .pm-channel { + font-size: 11px; letter-spacing: .1em; text-transform: uppercase; + color: var(--accent); margin-bottom: 6px; + } + .pm-title { + font-size: 20px; font-weight: 700; color: var(--text); + margin-bottom: 8px; line-height: 1.2; + } + .pm-time { + font-size: 12px; color: var(--accent); margin-bottom: 14px; + } + .pm-desc { + font-size: 13px; color: var(--text-muted); line-height: 1.6; + margin-bottom: 20px; max-height: 140px; overflow-y: auto; + } + .pm-actions { + display: flex; gap: 10px; flex-wrap: wrap; + } + .pm-btn { + border-radius: 4px; cursor: pointer; font-family: inherit; + font-size: 13px; font-weight: 600; padding: 8px 16px; + text-decoration: none; transition: opacity .2s; + display: inline-flex; align-items: center; gap: 6px; + border: none; + } + .pm-btn:hover { opacity: .8; } + .pm-watch { background: var(--accent); color: var(--bg); } + .pm-imdb { background: #f5c518; color: #000; } + .pm-cancel { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); } + + /* Date midnight dans la timebar */ + .time-tick-label.midnight { + color: var(--accent); font-weight: 700; font-size: 11px; + white-space: nowrap; + } + .time-tick-line.midnight { + background: var(--accent); opacity: .4; width: 2px; + } + + + /* ── FAVORITES ───────────────────────────────────────────────────────────── */ diff --git a/src/css/search.css b/src/css/search.css new file mode 100644 index 0000000..e76214d --- /dev/null +++ b/src/css/search.css @@ -0,0 +1,39 @@ +/* ── SEARCH ───────────────────────────────────────────────────────────────── */ + .search-btn { + background: none; border: 1px solid var(--border); border-radius: 4px; + color: var(--text-muted); cursor: pointer; font-size: 14px; + padding: 4px 8px; transition: color .2s, border-color .2s; + } + .search-btn:hover { color: var(--accent); border-color: var(--accent); } + + .search-bar { + display: none; align-items: center; gap: 8px; + background: var(--bg-card); border-bottom: 1px solid var(--border); + padding: 8px 16px; + } + .search-bar.visible { display: flex; } + + .search-input { + flex: 1; background: var(--bg); border: 1px solid var(--border); + border-radius: 4px; color: var(--text); font-family: inherit; + font-size: 14px; outline: none; padding: 6px 12px; + transition: border-color .2s; + } + .search-input:focus { border-color: var(--accent); } + .search-input::placeholder { color: var(--text-muted); } + + .search-clear { + background: none; border: none; color: var(--text-muted); + cursor: pointer; font-size: 16px; padding: 4px 8px; + transition: color .2s; + } + .search-clear:hover { color: var(--accent); } + + /* Highlight programmes qui matchent */ + .program-block.search-match { + border: 1px solid var(--accent); + box-shadow: 0 0 6px var(--accent); + } + .mobile-program.search-match { + border-left: 3px solid var(--accent); + } diff --git a/src/css/topbar.css b/src/css/topbar.css new file mode 100644 index 0000000..b1974c6 --- /dev/null +++ b/src/css/topbar.css @@ -0,0 +1,211 @@ +/* ═══════════════════════════════════════════ + TOP BAR + ═══════════════════════════════════════════ */ + .topbar { + height: 50px; + background: var(--surface); + border-bottom: 1px solid var(--border); + display: flex; + align-items: center; + padding: 0 16px; + gap: 12px; + flex-shrink: 0; + position: relative; + z-index: 100; + } + + .logo { + font-family: 'Share Tech Mono', monospace; + font-size: 13px; + color: var(--accent); + letter-spacing: 0.08em; + text-transform: uppercase; + white-space: nowrap; + } + .logo span { color: var(--text-dim); margin: 0 5px; } + .logo-sub { display: inline; } + + .live-dot { + display: flex; + align-items: center; + gap: 6px; + font-size: 11px; + font-family: 'Share Tech Mono', monospace; + color: var(--accent-live); + letter-spacing: 0.1em; + margin-left: auto; + flex-shrink: 0; + } + .live-dot::before { + content: ''; + width: 7px; height: 7px; + background: var(--accent-live); + border-radius: 50%; + animation: pulse 1.4s ease-in-out infinite; + } + @keyframes pulse { + 0%,100% { opacity:1; transform:scale(1); } + 50% { opacity:0.3; transform:scale(0.7); } + } + + .clock { + font-family: 'Share Tech Mono', monospace; + font-size: 20px; + color: var(--text-bright); + letter-spacing: 0.05em; + flex-shrink: 0; + } + + .date-label { + font-family: 'Share Tech Mono', monospace; + font-size: 10px; + color: var(--text-dim); + letter-spacing: 0.1em; + text-transform: uppercase; + white-space: nowrap; + } + + .nav-btns { + display: flex; + gap: 4px; + flex-shrink: 0; + } + .nav-btn { + background: var(--surface2); + border: 1px solid var(--border); + color: var(--text); + font-family: 'Barlow Condensed', sans-serif; + font-size: 12px; + letter-spacing: 0.06em; + padding: 4px 10px; + cursor: pointer; + text-transform: uppercase; + transition: all 0.15s; + white-space: nowrap; + } + .nav-btn:hover, .nav-btn.active { + background: var(--accent); + color: #000; + border-color: var(--accent); + } + + .copy-btns { + display: flex; + gap: 4px; + flex-shrink: 0; + } + .copy-btn { + background: transparent; + border: 1px solid var(--border-bright); + color: var(--text-dim); + font-family: 'Share Tech Mono', monospace; + font-size: 10px; + letter-spacing: 0.1em; + padding: 4px 9px; + cursor: pointer; + text-transform: uppercase; + transition: all 0.15s; + white-space: nowrap; + position: relative; + } + .copy-btn:hover { + border-color: var(--accent2); + color: var(--accent2); + } + .copy-btn.copied { + border-color: var(--accent); + color: var(--accent); + } + + /* ═══════════════════════════════════════════ + RESPONSIVE + ═══════════════════════════════════════════ */ + @media (max-width: 900px) { + :root { --channel-w: 110px; } + .logo-sub { display: none; } + .date-label { display: none; } + .clock { font-size: 16px; } + } + + /* ═══════════════════════════════════════════ + SÉLECTEUR DE THÈME + ═══════════════════════════════════════════ */ + .theme-select { + background: transparent; + border: 1px solid var(--border-bright); + color: var(--text-dim); + font-family: var(--font-mono); + font-size: 10px; + letter-spacing: 0.08em; + padding: 4px 8px; + cursor: pointer; + text-transform: uppercase; + transition: all 0.15s; + flex-shrink: 0; + -webkit-appearance: none; + appearance: none; + } + .theme-select:hover { border-color: var(--accent2); color: var(--accent2); } + .theme-select option { background: #111; color: #eee; font-family: sans-serif; } + + @media (max-width: 600px) { + html, body { height: 100%; overflow: hidden; } + body { overflow: hidden; } + + .topbar { + height: auto; + flex-wrap: wrap; + padding: 8px 12px; + gap: 8px; + } + .logo { font-size: 11px; } + .clock { font-size: 14px; } + + .grid-wrapper { display: none; } + .mobile-view { display: block; } + .tooltip { display: none !important; } + #navBtns { display: none !important; } + } + + + + /* ── MODAL PERSONAL EPG ─────────────────────────────────────────────────── */ + .modal-overlay { + position: fixed; inset: 0; background: rgba(0,0,0,0.7); + z-index: 3000; display: none; align-items: center; justify-content: center; + } + .modal-overlay.visible { display: flex; } + .modal-card { + background: var(--surface); border: 1px solid var(--border-bright); + padding: 28px; width: 100%; max-width: 420px; margin: 16px; + } + .modal-title { + font-family: var(--font-mono); font-size: 13px; color: var(--accent); + letter-spacing: 0.1em; text-transform: uppercase; margin-bottom: 6px; + } + .modal-subtitle { font-size: 12px; color: var(--text-dim); margin-bottom: 20px; line-height: 1.5; } + .modal-field { margin-bottom: 14px; } + .modal-field label { + display: block; font-family: var(--font-mono); font-size: 10px; + letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-dim); margin-bottom: 6px; + } + .modal-field input { + width: 100%; background: var(--surface2); border: 1px solid var(--border-bright); + color: var(--text-bright); font-family: var(--font-mono); font-size: 12px; + padding: 9px 10px; outline: none; transition: border-color 0.15s; + } + .modal-field input:focus { border-color: var(--accent); } + .modal-field input::placeholder { color: var(--text-dim); opacity: 0.4; } + .modal-actions { display: flex; gap: 10px; margin-top: 20px; justify-content: flex-end; } + .modal-btn-cancel { + background: none; border: 1px solid var(--border-bright); color: var(--text-dim); + font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; + text-transform: uppercase; padding: 8px 16px; cursor: pointer; transition: border-color 0.15s; + } + .modal-btn-cancel:hover { border-color: var(--text-dim); color: var(--text); } + .modal-btn-apply { + background: var(--accent); border: none; color: #000; + font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; + text-transform: uppercase; padding: 8px 20px; cursor: pointer; transition: opacity 0.15s; + } + .modal-btn-apply:hover { opacity: 0.85; } diff --git a/src/css/updater.css b/src/css/updater.css new file mode 100644 index 0000000..b10ca28 --- /dev/null +++ b/src/css/updater.css @@ -0,0 +1,13 @@ +/* ── UPDATE BADGE ────────────────────────────────────────────────────────── */ + .update-badge { + background: var(--accent); color: #000; + font-size: 11px; font-weight: 700; letter-spacing: 0.06em; + padding: 4px 10px; text-decoration: none; white-space: nowrap; + animation: pulse-badge 2s ease-in-out infinite; + border-radius: 2px; margin-left: 4px; + } + .update-badge:hover { opacity: .85; } + @keyframes pulse-badge { + 0%, 100% { opacity: 1; } + 50% { opacity: .65; } + } diff --git a/src/tpl/head.php b/src/tpl/head.php index 58602ab..6ca2685 100644 --- a/src/tpl/head.php +++ b/src/tpl/head.php @@ -1,890 +1,19 @@ - + GridTV — <?= $group_name ?> - +\n"; +foreach ($css_files as $file) { + echo file_get_contents($css_dir . $file . '.css') . "\n"; +} +echo "\n"; +?> From 8ca85e778e89f99f80a8b74542e1ee7602fe4dac Mon Sep 17 00:00:00 2001 From: Johnnybegood90 Date: Fri, 13 Mar 2026 23:04:55 +0100 Subject: [PATCH 2/2] Split the CSS from head.php into separate files. --- src/css/grid.css | 96 ---------------------------------------------- src/css/mobile.css | 88 ++++++++++++++++++++++++++++++++++++++++++ src/css/topbar.css | 61 +++++++++-------------------- 3 files changed, 106 insertions(+), 139 deletions(-) diff --git a/src/css/grid.css b/src/css/grid.css index 48c62b5..b5199ef 100644 --- a/src/css/grid.css +++ b/src/css/grid.css @@ -213,99 +213,3 @@ letter-spacing: 0.06em; white-space: nowrap; } - - /* ═══════════════════════════════════════════ - MOBILE LIST VIEW - ═══════════════════════════════════════════ */ - .mobile-view { - display: none; - flex: 1; - overflow-y: auto; - min-height: 0; - /* TOOLTIP */ - .tooltip { - position: fixed; - background: var(--surface); - border: 1px solid var(--accent2); - border-radius: 4px; - padding: 10px 14px; - z-index: 999; - pointer-events: none; - max-width: 300px; - opacity: 0; - transition: opacity 0.15s; - } - .tooltip.visible { opacity: 1; } - .tooltip-title { font-size: 14px; font-weight: 700; color: var(--text-bright); margin-bottom: 4px; } - .tooltip-time { font-family: 'Share Tech Mono', monospace; font-size: 10px; color: var(--accent2); margin-bottom: 6px; } - .tooltip-desc { font-size: 12px; color: var(--text); line-height: 1.4; max-height: 80px; overflow: hidden; } - - /* LOADING */ - .loading { - position: fixed; inset: 0; - background: var(--bg); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - z-index: 1000; - gap: 20px; - } - .loading-text { - font-family: 'Share Tech Mono', monospace; - font-size: 12px; - color: var(--text-dim); - letter-spacing: 0.2em; - text-transform: uppercase; - } - .loading-bar { - width: 200px; height: 2px; - background: var(--border); - position: relative; - overflow: hidden; - } - .loading-bar::after { - content: ''; - position: absolute; - top: 0; left: -60%; - width: 60%; height: 100%; - background: var(--accent); - animation: loading-anim 1.2s ease-in-out infinite; - } - @keyframes loading-anim { to { left: 110%; } } - - .error-msg { - position: fixed; inset: 0; - background: var(--bg); - flex-direction: column; - align-items: center; - justify-content: center; - z-index: 1000; - gap: 16px; - display: none; - padding: 20px; - } - .err-title { font-family: 'Share Tech Mono', monospace; font-size: 14px; color: var(--accent-live); letter-spacing: 0.1em; } - .err-sub { font-size: 13px; color: var(--text-dim); text-align: center; max-width: 400px; line-height: 1.5; } - .epg-input-bar { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; justify-content: center; } - .epg-input { - background: var(--surface2); - border: 1px solid var(--border-bright); - color: var(--text-bright); - font-family: 'Share Tech Mono', monospace; - font-size: 12px; - padding: 8px 12px; - width: 320px; - outline: none; - } - .epg-input:focus { border-color: var(--accent); } - .epg-btn { - background: var(--accent); - border: none; color: #000; - font-family: 'Barlow Condensed', sans-serif; - font-weight: 700; font-size: 13px; - letter-spacing: 0.1em; - text-transform: uppercase; - padding: 8px 18px; - cursor: pointer; - } diff --git a/src/css/mobile.css b/src/css/mobile.css index 38fb563..d36bdfb 100644 --- a/src/css/mobile.css +++ b/src/css/mobile.css @@ -101,3 +101,91 @@ margin-right: 8px; flex-shrink: 0; } + + /* TOOLTIP */ + .tooltip { + position: fixed; + background: var(--surface); + border: 1px solid var(--accent2); + border-radius: 4px; + padding: 10px 14px; + z-index: 999; + pointer-events: none; + max-width: 300px; + opacity: 0; + transition: opacity 0.15s; + } + .tooltip.visible { opacity: 1; } + .tooltip-title { font-size: 14px; font-weight: 700; color: var(--text-bright); margin-bottom: 4px; } + .tooltip-time { font-family: 'Share Tech Mono', monospace; font-size: 10px; color: var(--accent2); margin-bottom: 6px; } + .tooltip-desc { font-size: 12px; color: var(--text); line-height: 1.4; max-height: 80px; overflow: hidden; } + + /* LOADING */ + .loading { + position: fixed; inset: 0; + background: var(--bg); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 1000; + gap: 20px; + } + .loading-text { + font-family: 'Share Tech Mono', monospace; + font-size: 12px; + color: var(--text-dim); + letter-spacing: 0.2em; + text-transform: uppercase; + } + .loading-bar { + width: 200px; height: 2px; + background: var(--border); + position: relative; + overflow: hidden; + } + .loading-bar::after { + content: ''; + position: absolute; + top: 0; left: -60%; + width: 60%; height: 100%; + background: var(--accent); + animation: loading-anim 1.2s ease-in-out infinite; + } + @keyframes loading-anim { to { left: 110%; } } + + .error-msg { + position: fixed; inset: 0; + background: var(--bg); + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 1000; + gap: 16px; + display: none; + padding: 20px; + } + .err-title { font-family: 'Share Tech Mono', monospace; font-size: 14px; color: var(--accent-live); letter-spacing: 0.1em; } + .err-sub { font-size: 13px; color: var(--text-dim); text-align: center; max-width: 400px; line-height: 1.5; } + .epg-input-bar { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; justify-content: center; } + .epg-input { + background: var(--surface2); + border: 1px solid var(--border-bright); + color: var(--text-bright); + font-family: 'Share Tech Mono', monospace; + font-size: 12px; + padding: 8px 12px; + width: 320px; + outline: none; + } + .epg-input:focus { border-color: var(--accent); } + .epg-btn { + background: var(--accent); + border: none; color: #000; + font-family: 'Barlow Condensed', sans-serif; + font-weight: 700; font-size: 13px; + letter-spacing: 0.1em; + text-transform: uppercase; + padding: 8px 18px; + cursor: pointer; + } diff --git a/src/css/topbar.css b/src/css/topbar.css index b1974c6..a314444 100644 --- a/src/css/topbar.css +++ b/src/css/topbar.css @@ -117,7 +117,7 @@ color: var(--accent); } - /* ═══════════════════════════════════════════ +/* ═══════════════════════════════════════════ RESPONSIVE ═══════════════════════════════════════════ */ @media (max-width: 900px) { @@ -127,7 +127,7 @@ .clock { font-size: 16px; } } - /* ═══════════════════════════════════════════ +/* ═══════════════════════════════════════════ SÉLECTEUR DE THÈME ═══════════════════════════════════════════ */ .theme-select { @@ -167,45 +167,20 @@ #navBtns { display: none !important; } } - - - /* ── MODAL PERSONAL EPG ─────────────────────────────────────────────────── */ - .modal-overlay { - position: fixed; inset: 0; background: rgba(0,0,0,0.7); - z-index: 3000; display: none; align-items: center; justify-content: center; +/* ── SOURCE SELECTOR ─────────────────────────────────────────────────────── */ + .source-select { + background: var(--surface2); + border: 1px solid var(--border-bright); + color: var(--text); + font-family: var(--font-mono); + font-size: 11px; + padding: 5px 8px; + cursor: pointer; + letter-spacing: 0.06em; + height: 28px; + outline: none; + transition: border-color 0.15s, color 0.15s; + max-width: 130px; } - .modal-overlay.visible { display: flex; } - .modal-card { - background: var(--surface); border: 1px solid var(--border-bright); - padding: 28px; width: 100%; max-width: 420px; margin: 16px; - } - .modal-title { - font-family: var(--font-mono); font-size: 13px; color: var(--accent); - letter-spacing: 0.1em; text-transform: uppercase; margin-bottom: 6px; - } - .modal-subtitle { font-size: 12px; color: var(--text-dim); margin-bottom: 20px; line-height: 1.5; } - .modal-field { margin-bottom: 14px; } - .modal-field label { - display: block; font-family: var(--font-mono); font-size: 10px; - letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-dim); margin-bottom: 6px; - } - .modal-field input { - width: 100%; background: var(--surface2); border: 1px solid var(--border-bright); - color: var(--text-bright); font-family: var(--font-mono); font-size: 12px; - padding: 9px 10px; outline: none; transition: border-color 0.15s; - } - .modal-field input:focus { border-color: var(--accent); } - .modal-field input::placeholder { color: var(--text-dim); opacity: 0.4; } - .modal-actions { display: flex; gap: 10px; margin-top: 20px; justify-content: flex-end; } - .modal-btn-cancel { - background: none; border: 1px solid var(--border-bright); color: var(--text-dim); - font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; - text-transform: uppercase; padding: 8px 16px; cursor: pointer; transition: border-color 0.15s; - } - .modal-btn-cancel:hover { border-color: var(--text-dim); color: var(--text); } - .modal-btn-apply { - background: var(--accent); border: none; color: #000; - font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; - text-transform: uppercase; padding: 8px 20px; cursor: pointer; transition: opacity 0.15s; - } - .modal-btn-apply:hover { opacity: 0.85; } + .source-select:hover { border-color: var(--accent2); color: var(--accent2); } + .source-select option { background: #111; color: #eee; font-family: sans-serif; }