/* src/styles/panel.css — v3.1 premium FIX Objectifs : - Lightbox AU-DESSUS du header (pas masquée) - bouton close toujours visible - le haut du média jamais coupé - CSS-only, aucune logique JS modifiée */ /* ===== Tokens ===== */ :root{ --panel-radius: 18px; --panel-radius-sm: 14px; --panel-border: rgba(127,127,127,0.16); --panel-border-strong: rgba(127,127,127,0.26); --panel-glass: rgba(255,255,255,0.055); --panel-glass-2: rgba(255,255,255,0.075); --panel-shadow: 0 14px 34px rgba(0,0,0,0.07); --panel-shadow-2: 0 22px 60px rgba(0,0,0,0.10); --panel-title: rgba(20,20,20,0.90); --panel-text: rgba(20,20,20,0.84); --panel-muted: rgba(20,20,20,0.62); --chip-bg: rgba(127,127,127,0.10); --chip-bd: rgba(127,127,127,0.22); --btn-bg: rgba(127,127,127,0.10); --btn-bd: rgba(127,127,127,0.30); /* thumbs */ --thumb: 84px; /* Motion */ --ease: cubic-bezier(.2,.85,.2,1); --ease2: cubic-bezier(.18,.9,.18,1); /* Lightbox sizing */ --lb-maxw: 1480px; /* Inset (viewport safe) : header + notch + marges */ --lb-inset-x: 14px; --lb-inset-top: max(calc(env(safe-area-inset-top, 0px) + 12px), 12px); --lb-inset-bot: max(calc(env(safe-area-inset-bottom, 0px) + 12px), 12px); /* Space reserved for close button strip inside dialog */ --lb-topbar-h: 56px; /* padding viewer */ --lb-pad: 16px; } @media (min-width: 900px){ :root{ --lb-inset-x: 24px; --lb-pad: 18px; } } @media (prefers-color-scheme: dark){ :root{ --panel-border: rgba(255,255,255,0.12); --panel-border-strong: rgba(255,255,255,0.18); --panel-glass: rgba(255,255,255,0.045); --panel-glass-2: rgba(255,255,255,0.070); --panel-shadow: 0 18px 48px rgba(0,0,0,0.26); --panel-shadow-2: 0 30px 80px rgba(0,0,0,0.38); --panel-title: rgba(255,255,255,0.90); --panel-text: rgba(255,255,255,0.86); --panel-muted: rgba(255,255,255,0.62); --chip-bg: rgba(255,255,255,0.08); --chip-bd: rgba(255,255,255,0.14); --btn-bg: rgba(255,255,255,0.07); --btn-bd: rgba(255,255,255,0.16); } } /* ===== Panel container ===== */ body[data-reading-level="1"] .page-panel{ display: none !important; } /* IMPORTANT : Pour que la Lightbox (enfant du panel) puisse passer AU-DESSUS du header, on met le panel dans une couche au-dessus du header (z=50). Comme le panel n’empiète pas sur le header (top calculé), c’est safe. */ .page-panel{ position: sticky; top: calc(var(--sticky-header-h) + var(--page-gap)); align-self: start; color: var(--panel-text); z-index: 80; /* ✅ au-dessus du header (50) => Lightbox non masquée */ } .page-panel__inner{ max-height: calc(100vh - (var(--sticky-header-h) + var(--page-gap) + 12px)); overflow: auto; scrollbar-gutter: stable; border: 1px solid var(--panel-border); border-radius: var(--panel-radius); padding: 14px; background: radial-gradient(1200px 600px at 20% 0%, rgba(140,140,255,0.10), transparent 55%), radial-gradient(900px 520px at 80% 20%, rgba(127,255,210,0.06), transparent 55%), linear-gradient(180deg, var(--panel-glass), transparent 68%); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); box-shadow: var(--panel-shadow); transition: border-color 140ms var(--ease), box-shadow 140ms var(--ease), transform 140ms var(--ease); } .page-panel.is-updating .page-panel__inner{ border-color: var(--panel-border-strong); box-shadow: var(--panel-shadow-2); transform: translateY(-1px); } /* ===== Head ===== */ .panel-head{ display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid rgba(127,127,127,0.18); } .panel-head__left{ display: inline-flex; align-items: center; gap: 10px; min-width: 0; } .panel-head__label{ font-weight: 900; opacity: .88; } .panel-head__id{ font-weight: 850; letter-spacing: .01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 16rem; padding: 2px 10px; border-radius: 999px; border: 1px solid var(--chip-bd); background: var(--chip-bg); } /* ===== Messages ===== */ .panel-msg{ margin-top: 8px; font-size: 12px; opacity: .92; } .panel-msg--head{ margin-top: 0; margin-bottom: 10px; } /* ===== Toolbar actions : compacte + sticky ===== */ .panel-top-actions{ position: sticky; top: 0; z-index: 6; margin: 10px 0 10px; padding: 10px; border: 1px solid rgba(127,127,127,0.14); border-radius: var(--panel-radius-sm); background: rgba(255,255,255,0.55); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); box-shadow: 0 10px 24px rgba(0,0,0,0.06); } @media (prefers-color-scheme: dark){ .panel-top-actions{ background: rgba(0,0,0,0.28); box-shadow: 0 12px 28px rgba(0,0,0,0.22); } } .panel-top-actions::after{ content: ""; display: block; margin-top: 10px; height: 1px; background: rgba(127,127,127,0.16); } /* ===== Buttons ===== */ .panel-actions{ display: flex; gap: 8px; flex-wrap: wrap; margin: 0; } .panel-btn{ border: 1px solid var(--btn-bd); background: var(--btn-bg); border-radius: 999px; padding: 6px 12px; font-size: 13px; cursor: pointer; color: inherit; transition: transform 120ms var(--ease2), background 120ms var(--ease2), border-color 120ms var(--ease2); } .panel-btn:hover{ transform: translateY(-1px); border-color: var(--panel-border-strong); background: rgba(127,127,127,0.14); } @media (prefers-color-scheme: dark){ .panel-btn:hover{ background: rgba(255,255,255,0.10); } } .panel-btn:disabled{ opacity: .55; cursor: default; transform: none; } .panel-btn--primary{ font-weight: 900; border-color: var(--panel-border-strong); } /* ===== Sections ===== */ .panel-block{ margin-top: 14px; padding-top: 12px; border-top: 1px solid rgba(127,127,127,0.16); } .panel-block:first-of-type{ margin-top: 10px; border-top: 0; padding-top: 0; } .panel-title{ margin: 0 0 10px; font-size: 13px; font-weight: 950; letter-spacing: 0.06em; text-transform: uppercase; color: var(--panel-title); opacity: .96; } .panel-subtitle{ font-size: 12px; font-weight: 900; margin: 12px 0 6px; opacity: .90; } .panel-body p{ margin: 8px 0; opacity: .92; } .panel-list{ margin: 0; padding-left: 18px; } .panel-list li{ margin: 7px 0; } .panel-chip{ display: inline-block; margin-left: 8px; font-size: 11px; font-weight: 900; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--chip-bd); background: var(--chip-bg); opacity: .95; } .panel-quote{ margin: 8px 0; padding: 10px 10px; border-left: 3px solid rgba(140,140,255,0.35); background: rgba(127,127,127,0.06); border-radius: 12px; } @media (prefers-color-scheme: dark){ .panel-quote{ background: rgba(255,255,255,0.05); } } .panel-quote__src{ margin-top: 6px; font-size: 12px; opacity: .72; } /* ===== Media grid ===== */ .panel-media-grid{ display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--thumb), 1fr)); gap: 10px; align-items: start; } .panel-media-tile{ width: 100%; border: 1px solid rgba(127,127,127,0.16); border-radius: 14px; padding: 8px; background: rgba(127,127,127,0.04); cursor: pointer; text-align: left; transition: transform 120ms var(--ease2), background 120ms var(--ease2), border-color 120ms var(--ease2); } @media (prefers-color-scheme: dark){ .panel-media-tile{ background: rgba(255,255,255,0.035); } } .panel-media-tile:hover{ transform: translateY(-1px); border-color: var(--panel-border-strong); background: rgba(127,127,127,0.08); } @media (prefers-color-scheme: dark){ .panel-media-tile:hover{ background: rgba(255,255,255,0.055); } } .panel-media-tile img{ width: 100%; height: var(--thumb); object-fit: cover; display: block; border-radius: 10px; margin-bottom: 8px; cursor: zoom-in; } .panel-media-ph{ width: 100%; height: var(--thumb); border-radius: 10px; display: grid; place-items: center; background: var(--chip-bg); margin-bottom: 8px; font-weight: 950; font-size: 12px; opacity: .9; } .panel-media-cap{ font-size: 12px; font-weight: 900; opacity: .92; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .panel-media-credit{ margin-top: 4px; font-size: 11px; opacity: .74; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* Featured (1 média) */ .panel-media-grid > .panel-media-tile:only-child{ grid-column: 1 / -1; padding: 10px; } .panel-media-grid > .panel-media-tile:only-child img, .panel-media-grid > .panel-media-tile:only-child .panel-media-ph{ height: min(52vh, 460px); object-fit: contain; background: rgba(0,0,0,0.08); } @media (prefers-color-scheme: dark){ .panel-media-grid > .panel-media-tile:only-child img, .panel-media-grid > .panel-media-tile:only-child .panel-media-ph{ background: rgba(0,0,0,0.22); } } .panel-media-grid > .panel-media-tile:only-child .panel-media-cap{ white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.35; } /* ===== Compose ===== */ .panel-compose{ margin-top: 12px; padding-top: 10px; border-top: 1px dashed rgba(127,127,127,0.22); } .panel-label{ display: block; font-size: 12px; font-weight: 950; opacity: .90; margin-bottom: 6px; } .panel-textarea{ width: 100%; box-sizing: border-box; border: 1px solid rgba(127,127,127,0.24); border-radius: 12px; padding: 9px 10px; background: transparent; font-size: 13px; resize: vertical; } /* ======================================================================= LIGHTBOX FIX (CRITIQUE) - overlay couvre le header - close toujours visible - le haut du média n’est jamais “mangé” - overrides forts (important) car styles inline du composant existent ======================================================================= */ /* Quand hidden => pas d’interaction */ .panel-lightbox[hidden]{ display: none !important; } /* Conteneur full-viewport AU DESSUS de tout */ .panel-lightbox{ position: fixed !important; inset: 0 !important; z-index: 2147483647 !important; /* max practical */ pointer-events: auto !important; } /* Overlay : couvre TOUT y compris header */ .panel-lightbox__overlay{ position: absolute !important; inset: 0 !important; background: rgba(0,0,0,0.86) !important; backdrop-filter: blur(10px) !important; -webkit-backdrop-filter: blur(10px) !important; } /* Dialog : on bannit transform/centering qui peut “couper” le haut. On utilise un inset fixe => le haut est toujours visible. */ .panel-lightbox__dialog{ position: fixed !important; left: auto !important; top: auto !important; right: auto !important; bottom: auto !important; transform: none !important; inset: var(--lb-inset-top) var(--lb-inset-x) var(--lb-inset-bot) var(--lb-inset-x) !important; width: auto !important; height: auto !important; max-height: none !important; border-radius: 18px !important; border: 1px solid rgba(255,255,255,0.14) !important; background: rgba(18,18,18,0.58) !important; backdrop-filter: blur(14px) !important; -webkit-backdrop-filter: blur(14px) !important; box-shadow: 0 28px 90px rgba(0,0,0,0.60) !important; overflow: hidden !important; /* layout interne */ display: flex !important; flex-direction: column !important; /* petite anim (discrète) */ animation: archiLbIn 160ms var(--ease) !important; } @keyframes archiLbIn{ from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } } /* Close : FIXED dans le viewport => ne peut plus être masqué par le header */ .panel-lightbox__close{ position: fixed !important; top: calc(var(--lb-inset-top) + 8px) !important; right: calc(var(--lb-inset-x) + 8px) !important; z-index: 2147483647 !important; display: inline-flex !important; align-items: center !important; justify-content: center !important; width: 46px !important; height: 42px !important; border-radius: 14px !important; border: 1px solid rgba(255,255,255,0.30) !important; background: rgba(0,0,0,0.50) !important; color: rgba(255,255,255,0.92) !important; cursor: pointer !important; font-size: 22px !important; font-weight: 950 !important; transition: transform 120ms var(--ease2), background 120ms var(--ease2) !important; } .panel-lightbox__close:hover{ transform: translateY(-1px) !important; background: rgba(255,255,255,0.14) !important; } /* Contenu : prend l’espace, jamais sous le close (close est fixed viewport) */ .panel-lightbox__content{ flex: 1 1 auto !important; min-height: 0 !important; padding: var(--lb-pad) !important; padding-top: 12px !important; display: grid !important; place-items: center !important; overflow: auto !important; } /* Média : contain, et jamais coupé en haut (dialog inset fixe + scroll possible) */ .panel-lightbox__content img, .panel-lightbox__content video{ display: block !important; max-width: min(var(--lb-maxw), calc(100vw - (var(--lb-inset-x) * 2) - (var(--lb-pad) * 2))) !important; max-height: calc(100vh - var(--lb-inset-top) - var(--lb-inset-bot) - 64px) !important; width: auto !important; height: auto !important; object-fit: contain !important; background: rgba(0,0,0,0.22) !important; border-radius: 14px !important; } /* audio */ .panel-lightbox__content audio{ width: min(860px, calc(100vw - (var(--lb-inset-x) * 2) - 28px)) !important; } /* Caption : en bas, sans masquer le média (on reste simple) */ .panel-lightbox__caption{ position: relative !important; z-index: 2 !important; padding: 10px 14px !important; font-size: 12px !important; font-weight: 950 !important; color: rgba(255,255,255,0.92) !important; background: linear-gradient(to top, rgba(0,0,0,0.72), rgba(0,0,0,0.00)) !important; } /* Bonus : si le navigateur supporte :has(), on fige le scroll arrière-plan (premium) */ @supports selector(html:has(*)){ html:has(.panel-lightbox:not([hidden])){ overflow: hidden; } } /* ===== Responsive : comme avant, panel caché sous 1100px ===== */ @media (max-width: 1100px){ .page-panel{ display: none; } } /* ===== Reduce motion ===== */ @media (prefers-reduced-motion: reduce){ .panel-lightbox__dialog{ animation: none !important; } .panel-btn, .panel-media-tile, .page-panel__inner{ transition: none !important; } }