diff --git a/index.css b/index.css index b21c891..4277b0a 100644 --- a/index.css +++ b/index.css @@ -573,35 +573,143 @@ body { } /* --- Player FAB menu (shared /watch & /shorts) ---------------------------- */ -/* Items/coque du panneau du menu flottant : petits, translucides, harmonisés - avec les commandes overlay des players YouTube/Dailymotion. */ +/* Coque du menu flottant : pastille « verre dépoli », panneau en élévation + avec en-tête, entrée/sortie animées. Harmonisé avec les commandes overlay + des players YouTube/Dailymotion (fond sombre translucide, blur, ring fin). */ + +/* Pastille FAB (haut-gauche du lecteur). */ +.pm-fab { + display: inline-flex; + align-items: center; + justify-content: center; + width: 2.5rem; /* 40px */ + height: 2.5rem; + border-radius: 9999px; + color: #fff; + background: rgba(0, 0, 0, .55); + border: 1px solid rgba(255, 255, 255, .14); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + cursor: pointer; + transition: background-color .15s ease, border-color .15s ease, transform .15s ease; +} +.pm-fab svg { width: 1.125rem; height: 1.125rem; } +.pm-fab:hover { background: rgba(0, 0, 0, .72); border-color: rgba(255, 255, 255, .24); } +.pm-fab:active { transform: scale(.93); } +.pm-fab-open { background: rgba(0, 0, 0, .72); border-color: rgba(255, 255, 255, .24); } +.pm-fab:focus-visible { outline: 2px solid rgba(255, 255, 255, .55); outline-offset: 2px; } + +/* Panneau déroulant (toujours monté, animé via open/close). */ +.pm-panel { + position: absolute; + top: calc(100% + 0.5rem); + left: 0; + width: 18rem; /* 288px */ + max-height: min(70vh, 480px); + display: flex; + flex-direction: column; + overflow: hidden; + border-radius: 1rem; + background: rgba(15, 23, 42, .92); /* slate-900/92 */ + border: 1px solid rgba(255, 255, 255, .1); + box-shadow: 0 18px 50px rgba(0, 0, 0, .55), 0 2px 10px rgba(0, 0, 0, .35); + backdrop-filter: blur(24px); + -webkit-backdrop-filter: blur(24px); + opacity: 0; + transform: translateY(-6px) scale(.97); + transform-origin: top left; + visibility: hidden; + pointer-events: none; + transition: opacity .18s ease, transform .18s cubic-bezier(.2, .9, .3, 1), visibility 0s linear .18s; +} +.pm-panel-open { + opacity: 1; + transform: translateY(0) scale(1); + visibility: visible; + pointer-events: auto; + transition: opacity .18s ease, transform .18s cubic-bezier(.2, .9, .3, 1); +} + +/* En-tête : titre + bouton fermer. */ +.pm-panel-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.75rem; + padding: 0.625rem 0.625rem 0.625rem 0.875rem; + border-bottom: 1px solid rgba(255, 255, 255, .08); + flex-shrink: 0; +} +.pm-panel-title { + font-size: 0.8125rem; + font-weight: 600; + letter-spacing: .02em; + color: rgba(255, 255, 255, .92); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.pm-panel-close { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.75rem; + height: 1.75rem; + border-radius: 9999px; + color: rgba(255, 255, 255, .7); + flex-shrink: 0; + transition: background-color .15s ease, color .15s ease; +} +.pm-panel-close svg { width: 1rem; height: 1rem; } +.pm-panel-close:hover { background: rgba(255, 255, 255, .1); color: #fff; } +.pm-panel-close:focus-visible { outline: 2px solid rgba(255, 255, 255, .5); outline-offset: 1px; } + +/* Corps scrollable du panneau. */ +.pm-panel-body { + padding: 0.5rem; + overflow-y: auto; + overscroll-behavior: contain; + flex: 1; + min-height: 0; +} +.pm-panel-body::-webkit-scrollbar { width: 6px; } +.pm-panel-body::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .18); border-radius: 9999px; } + +/* Libellé de section. */ .pm-section-label { - padding: 0.375rem 0.75rem 0.25rem; + padding: 0.625rem 0.75rem 0.375rem; font-size: 0.6875rem; /* 11px */ font-weight: 600; - letter-spacing: 0.04em; + letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); } + +/* Élément de menu. */ .pm-item { display: flex; align-items: center; - gap: 0.625rem; + gap: 0.75rem; width: 100%; - padding: 0.5rem 0.75rem; - border-radius: 0.5rem; - font-size: 0.8125rem; /* 13px */ + padding: 0.5625rem 0.75rem; + border-radius: 0.625rem; + font-size: 0.84375rem; /* 13.5px */ color: var(--text); text-align: left; - line-height: 1.25; - transition: background-color .15s ease; + line-height: 1.3; + cursor: pointer; + transition: background-color .12s ease, color .12s ease; } .pm-item:hover { background-color: rgba(255, 255, 255, .08); } +.pm-item:active { background-color: rgba(255, 255, 255, .12); } +.pm-item:focus-visible { outline: 2px solid rgba(255, 255, 255, .35); outline-offset: -2px; } .pm-item:disabled { opacity: .4; cursor: not-allowed; } -.pm-item svg { flex-shrink: 0; } +.pm-item svg { flex-shrink: 0; color: rgba(255, 255, 255, .75); } .pm-item .pm-item-label { flex: 1; min-width: 0; } -.pm-item .pm-item-hint { font-size: 0.6875rem; color: var(--muted); } -.pm-sep { height: 1px; margin: 0.375rem 0.5rem; background: rgba(255, 255, 255, .12); } +.pm-item .pm-item-hint { font-size: 0.71875rem; color: var(--muted); } + +/* Séparateur. */ +.pm-sep { height: 1px; margin: 0.375rem 0.625rem; background: rgba(255, 255, 255, .08); } /* --- Drawer / overlay plumbing -------------------------------------------- */ /* Applied to
while a full-screen drawer or modal owns the viewport. diff --git a/src/app/shared/components/player-menu/player-menu.component.ts b/src/app/shared/components/player-menu/player-menu.component.ts index 434ec9e..5928709 100644 --- a/src/app/shared/components/player-menu/player-menu.component.ts +++ b/src/app/shared/components/player-menu/player-menu.component.ts @@ -4,11 +4,11 @@ import { CommonModule } from '@angular/common'; /** * Bouton-menu flottant (FAB) partagé entre /watch et /shorts. * - * Pastille circulaire translucide en haut à gauche du lecteur, façon - * commandes overlay des players YouTube/Dailymotion : elle ouvre un panneau - * déroulant qui reçoit son contenu par projection (`ng-content`) — chaque page - * fournit ses propres options, la coque (position, style, open/close, clic - * extérieur) est identique partout. + * Pastille circulaire translucide en haut à gauche du lecteur (façon commandes + * overlay des players YouTube/Dailymotion) qui ouvre un panneau déroulant en + * « verre dépoli » avec en-tête (titre + fermeture) et contenu projeté via + * `ng-content`. Animation d'ouverture/fermeture fluide (fondu + glissement + + * échelle), fermeture au clic extérieur et à Échap. * * Usage : `