/* Mise en page : page, en-tête, menu de cubes, scène et grille. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--surface-page);
  color: var(--text-primary);
  font: var(--fw-regular) var(--fs-m) / 1.5 var(--font-sans);
  -webkit-text-size-adjust: 100%;
  /* Filet de sécurité : les boîtes roulent au-delà des bords de l'écran, et
     rien de ce qui dépasse ne doit ajouter de défilement horizontal. (Le
     `contain: layout` de la scène y suffit déjà, mais pas partout de la même
     façon.) `clip` plutôt que `hidden` : aucun conteneur de défilement n'est
     créé, la barre de menu reste collante. */
  overflow-x: clip;
}

body {
  margin: 0;
  min-height: 100vh;
}

/* Barre de défilement : dans la matière des cubes. Le rail est la page, le
   curseur une face relevée cerclée d'un trait fin, comme une boîte posée sur
   son rail ; indigo (cube de genre) au survol, ambre pendant qu'on le tire.
   Chromium et Safari passent par ::-webkit-scrollbar, qui permet le trait et
   les angles ; Firefox n'a que scrollbar-color, réservé ici aux navigateurs
   sans ::-webkit-scrollbar, car dès qu'il est posé Chromium ignore le reste. */
::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}

::-webkit-scrollbar-track {
  background: var(--surface-page);
}

::-webkit-scrollbar-thumb {
  background: var(--surface-lift);
  border: 2px solid var(--surface-page);
  border-radius: 0;
  box-shadow: inset 0 0 0 1px var(--edge);
}

::-webkit-scrollbar-thumb:hover {
  background: var(--surface-genre);
}

::-webkit-scrollbar-thumb:active {
  background: var(--accent);
  box-shadow: none;
}

::-webkit-scrollbar-corner {
  background: var(--surface-page);
}

@supports not selector(::-webkit-scrollbar) {
  html,
  * {
    scrollbar-width: thin;
    scrollbar-color: var(--surface-lift) var(--surface-page);
  }
}

[hidden] {
  display: none !important;
}

img {
  max-width: 100%;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* En-tête : barre de navigation ---------------------------------------
   Adaptée du pen « CSS :has() :hover » de Jhey (codepen.io/jh3y/pen/mdoqEdj).
   Une barre collante ; au repos, une colonne par section. Au survol, la
   colonne descend comme une lame et ses voisines suivent de moins en moins
   loin (sin 30°, 20°, 10°) grâce à :has() et aux combinateurs de frères.
   Sous 740 px, un bouton « + » au bord droit fait glisser le volet des
   sections depuis derrière la barre. De 740 à 960 px, les colonnes se
   resserrent (espacement et marges réduits) pour que les six sections et les
   boutons de compte tiennent sans déborder. */

.site-header {
  /* Collante et au-dessus de la scène : une boîte qui bascule déborde de sa
     cellule ; elle passe derrière la barre, jamais devant. */
  position: sticky;
  top: 0;
  z-index: 2;
  height: var(--nav-height);
  background: var(--surface-face);
  color: var(--text-primary);
  font: var(--fw-medium) var(--fs-s) / 1 var(--font-mono);
  text-transform: uppercase;
  letter-spacing: .06em;
}

.nav {
  height: 100%;
}

.nav__content {
  position: relative;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  height: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 var(--page-pad);
  background: var(--surface-face);
}

/* Section courante (mobile seulement) : le volet fermé n'affiche rien d'autre.
   Elle cède la place (points de suspension) plutôt que de pousser le « + »
   hors de l'écran quand Compte et Déconnexion sont là. */
.nav__current {
  display: flex;
  align-items: center;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--text-muted);
}

/* Petits écrans : Compte, Déconnexion et le « + » doivent tenir sur 360 px. */
@media (max-width: 739.98px) {
  .site-header {
    letter-spacing: .04em;
  }

  .auth__btn {
    padding: 0 .6rem;
  }
}

/* Connexion, Compte, Déconnexion : hors de la grille de colonnes, à droite
   de la barre, sans filet qui les sépare. Sur mobile, avant le bouton du
   volet (order), qui garde le bord droit. Au survol, pas de lame : la case
   change seulement de couleur, comme un cube de playlist qu'on choisit
   (surface relevée) ; Déconnexion passe en corail, c'est un geste qui ferme,
   pas une section de plus. */
.auth {
  display: flex;
  align-items: stretch;
  flex: 0 0 auto;
  order: 1;
  z-index: 6;
  margin-left: auto;
}

.auth__btn {
  margin: 0;
  padding: 0 1rem;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-nav), color var(--dur-nav);
  -webkit-tap-highlight-color: transparent;
}

.auth__btn:hover,
.auth__btn:focus-visible {
  background: var(--surface-lift);
  color: var(--text-primary);
}

.auth__btn--logout:hover,
.auth__btn--logout:focus-visible {
  background: var(--danger);
  color: var(--text-on-danger);
}

.auth__btn:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -4px;
}

.authdlg {
  box-sizing: border-box;
  width: min(400px, calc(100vw - 32px));
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-tile);
  background: var(--surface-face);
  color: var(--text-primary);
}

.authdlg::backdrop {
  background: var(--backdrop);
}

.authdlg__form {
  display: grid;
  gap: 16px;
  padding: 20px;
}

.authdlg__title {
  margin: 0;
  font: var(--fw-medium) var(--fs-l) / 1.2 var(--font-sans);
  text-transform: none;
  letter-spacing: 0;
}

.authdlg__field {
  display: grid;
  gap: 5px;
}

.authdlg__label {
  font: var(--fw-regular) var(--fs-s) / 1.3 var(--font-sans);
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-muted);
}

.authdlg input {
  box-sizing: border-box;
  width: 100%;
  margin: 0;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-code);
  color: var(--text-primary);
  font: var(--fw-regular) var(--fs-m) / 1.35 var(--font-sans);
}

.authdlg input:focus-visible,
.authdlg button:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Champ de mot de passe : l'œil est posé dans le champ, à droite. */
.authdlg__pw {
  position: relative;
  display: block;
}

.authdlg__pw input {
  padding-right: 44px;
}

.authdlg__eye {
  position: absolute;
  top: 50%;
  right: 6px;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.authdlg__eye svg {
  width: 18px;
  height: 18px;
}

.authdlg__eye:hover,
.authdlg__eye--on {
  color: var(--text-primary);
}

/* Le trait ne s'affiche que lorsque le mot de passe est en clair. */
.authdlg__eye-slash {
  display: none;
}

.authdlg__eye--on .authdlg__eye-slash {
  display: inline;
}

.authdlg__hint {
  font: var(--fw-regular) var(--fs-s) / 1.4 var(--font-sans);
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-muted);
}

.authdlg [aria-invalid="true"] {
  border-color: var(--text-primary);
}

.authdlg__error {
  margin: 0;
  font: var(--fw-regular) var(--fs-s) / 1.4 var(--font-sans);
  text-transform: none;
  letter-spacing: 0;
}

.authdlg__buttons {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.authdlg__cancel,
.authdlg__save {
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: none;
  color: var(--text-primary);
  font: var(--fw-regular) var(--fs-s) / 1.2 var(--font-sans);
  text-transform: none;
  letter-spacing: 0;
  cursor: pointer;
}

.authdlg__save {
  background: var(--menu-active-bg);
  color: var(--menu-active-fg);
  border-color: var(--menu-active-bg);
}

/* Bouton du volet (mobile) : un « + » qui devient « × » en tournant, au bord
   droit de la barre (order : après Connexion). */
.nav__toggle {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  order: 2;
  width: var(--nav-height);
  height: 100%;
  margin: 0 calc(-1 * var(--page-pad)) 0 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.nav__toggle svg {
  width: 24px;
  stroke-width: 2.5;
  rotate: calc(var(--active-nav, 0) * 45deg);
  transition: rotate var(--dur-nav);
}

.nav__toggle:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -4px;
}

.site-header:has(.nav__toggle[aria-expanded="true"]) {
  --active-nav: 1;
}

/* Volet des sections (mobile) : posé sous la barre, remonté derrière elle
   quand il est fermé, il glisse vers le bas quand il s'ouvre. Invisible et
   non focalisable une fois fermé. */
.nav__options {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: -1;
  background: var(--surface-face);
  translate: 0 calc(-100% + var(--active-nav, 0) * (100% + 2px));
  visibility: hidden;
  transition: translate var(--dur-nav), visibility 0s var(--dur-nav);
}

.site-header:has(.nav__toggle[aria-expanded="true"]) .nav__options {
  visibility: visible;
  transition-delay: 0s;
}

.link {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  height: var(--nav-height);
  padding: 1rem var(--page-pad);
  color: inherit;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

.link:not(:last-child) {
  border-bottom: 2px solid var(--surface-page);
}

.link:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -4px;
}

.link[aria-current="page"] {
  background: var(--menu-active-bg);
  color: var(--menu-active-fg);
}

/* Flèche : apparaît au survol ou au focus, en tournant vers le haut. */
.link:is(:hover, :focus-visible) {
  --active: 1;
}

.link svg {
  flex: 0 0 auto;
  height: 16px;
  stroke-width: 2.5px;
  opacity: var(--active, 0);
  rotate: calc(var(--active, 0) * -45deg);
  scale: calc(1 + var(--active, 0) * .1);
  transition:
    opacity calc(var(--dur-nav) * 1.5),
    rotate var(--dur-nav),
    scale var(--dur-nav);
}

@media (min-width: 740px) {
  .nav__toggle,
  .nav__current {
    display: none;
  }

  /* Une colonne par section, en flux ; z-index : contexte d'empilement pour
     que les lames (::before, z-index -1) passent sous le texte des liens.
     min-width: 0 et minmax(0, 1fr) : les colonnes peuvent se resserrer, la
     barre ne déborde jamais et le bouton de connexion reste visible. */
  .nav__options {
    position: static;
    z-index: 1;
    flex: 1 1 auto;
    min-width: 0;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    translate: 0 0;
    visibility: visible;
    background: none;
    transition: none;
    /* Amplitudes de la cascade, de la colonne survolée à la quatrième voisine. */
    --lerp-0: 1;
    --lerp-1: sin(30deg);
    --lerp-2: sin(20deg);
    --lerp-3: sin(10deg);
    --lerp-4: 0;
  }

  .link,
  .link[aria-current="page"] {
    justify-content: space-between;
    min-width: 0;
    padding: 1rem 1.5rem;
    border-bottom: 0;
    background: none;
    white-space: nowrap;
    translate: 0 calc(var(--lerp, 0) * 80%);
    transition: translate var(--dur-nav);
  }

  /* La lame : trois hauteurs de barre, ancrée au bas du lien, elle suit la
     descente et garde la colonne pleine jusqu'en haut. */
  .link::before {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 300%;
    z-index: -1;
    background: var(--surface-face);
    border-right: 2px solid var(--surface-page);
  }

  .link[aria-current="page"]::before {
    background: var(--menu-active-bg);
  }


  /* Descente en cascade : la colonne survolée à fond, ses voisines de moins
     en moins (frères suivants par « + », précédents par :has()). */
  :is(.link:hover, .link:focus-visible) {
    --lerp: var(--lerp-0);
    z-index: 5;
  }

  .link:has(+ :is(.link:hover, .link:focus-visible)),
  :is(.link:hover, .link:focus-visible) + .link {
    --lerp: var(--lerp-1);
    z-index: 4;
  }

  .link:has(+ .link + :is(.link:hover, .link:focus-visible)),
  :is(.link:hover, .link:focus-visible) + .link + .link {
    --lerp: var(--lerp-2);
    z-index: 3;
  }

  .link:has(+ .link + .link + :is(.link:hover, .link:focus-visible)),
  :is(.link:hover, .link:focus-visible) + .link + .link + .link {
    --lerp: var(--lerp-3);
    z-index: 2;
  }

  .link:has(+ .link + .link + .link + :is(.link:hover, .link:focus-visible)),
  :is(.link:hover, .link:focus-visible) + .link + .link + .link + .link {
    --lerp: var(--lerp-4);
    z-index: 1;
  }
}

/* Écrans moyens : les six colonnes et les boutons de compte doivent tenir
   dans 740 px. Corps 12 px, espacement des lettres réduit, marges resserrées,
   flèche de survol retirée (elle réservait sa largeur même invisible). */
@media (min-width: 740px) and (max-width: 959.98px) {
  .site-header {
    font-size: 12px;
    letter-spacing: .03em;
  }

  .link,
  .link[aria-current="page"] {
    gap: 0;
    padding: 1rem .5rem;
  }

  .link svg {
    display: none;
  }

  .auth__btn {
    padding: 0 .5rem;
  }
}

/* Le système demande des animations réduites : le menu ne glisse plus, sauf
   si SITE.motion vaut "roll", qui impose le mouvement partout (js/a11y.js
   pose data-motion sur la racine). */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="roll"]) .nav__toggle svg,
  :root:not([data-motion="roll"]) .nav__options,
  :root:not([data-motion="roll"]) .link,
  :root:not([data-motion="roll"]) .link svg,
  :root:not([data-motion="roll"]) .auth__btn {
    transition: none;
  }
}

/* Fond « mer » (js/water.js) : un canvas fixe sous toute la page. Il a la
   taille de la simulation (une case par CELL px) et c'est le navigateur qui
   l'étire à la fenêtre, son lissage fait le flou de la vague. z-index
   négatif : peint après le fond de la racine, avant tout le reste ; caché
   (attribut hidden) quand l'eau ne bouge pas. */
.water {
  position: fixed;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Contenu principal --------------------------------------------------- */

.main {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 24px var(--page-pad) 48px;
}

.fatal {
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-tile);
  background: var(--surface-face);
  font-family: var(--font-mono);
  font-size: var(--fs-s);
  white-space: pre-wrap;
}

/* Scène 3D ------------------------------------------------------------ */

.stage {
  position: relative;
  /* Projection orthographique : pas de point de fuite, donc toutes les boîtes
     ont exactement la même orientation à l'écran, où qu'elles soient dans la
     grille. La 3D vient de la vue oblique posée sur .grid. */
  perspective: none;
  /* Rien n'est coupé ici : les boîtes roulent au-delà de la scène, jusqu'aux
     bords de la fenêtre. Couper à la scène les faisait disparaître au milieu
     de leur course, à la largeur du texte. Au-delà de la fenêtre elles ne sont
     plus peintes, et `contain: layout` empêche ce débordement d'agrandir la
     zone de défilement (html porte le même filet, overflow-x: clip). */
  overflow: visible;
  contain: layout;
  padding: var(--stage-pad-y) var(--stage-pad-x) calc(var(--stage-pad-y) * 1.5);
}

/* Sections feuilletées (Veille IA) --------------------------------------
   Au-dessus de la scène, la barre de filtres : deux dates, l'ordre, un bouton
   pour tout remontrer et le compte ; en dessous, les pages, « ‹ 1 2 3 › », la
   page courante en ambre comme la colonne active du menu. Champs dans la
   matière des champs du site (fond code, filet), en mono comme la barre. */
.browse {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px 18px;
  margin: 0 0 20px;
  padding: 0 var(--stage-pad-x);
  font: var(--fw-medium) var(--fs-s) / 1.35 var(--font-mono);
}

.browse[hidden] {
  display: none;
}

.browse__fields {
  display: contents;
}

/* Le bouton entonnoir n'existe que sur un écran étroit (voir plus bas). */
.browse__toggle {
  display: none;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-face);
  color: var(--text-primary);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.browse__toggle svg {
  width: 20px;
  height: 20px;
}

.browse__toggle[aria-expanded="true"] {
  background: var(--menu-active-bg);
  border-color: var(--menu-active-bg);
  color: var(--menu-active-fg);
}

.browse__field {
  display: grid;
  flex: 0 1 160px;
  gap: 4px;
  min-width: 0;
}

.browse__field .browse__input {
  width: 100%;
}

.browse__label {
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.browse__input {
  box-sizing: border-box;
  min-width: 0;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-code);
  color: var(--text-primary);
  font: var(--fw-regular) var(--fs-s) / 1.35 var(--font-sans);
  color-scheme: dark;
}

.browse__reset {
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: none;
  color: var(--text-muted);
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.browse__reset:hover,
.browse__reset:focus-visible {
  border-color: var(--text-primary);
  color: var(--text-primary);
}

.browse__count {
  flex: 1 1 auto;
  margin: 0;
  padding-bottom: 8px;
  text-align: right;
  color: var(--text-muted);
}

.browse__input:focus-visible,
.browse__reset:focus-visible,
.pager__btn:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.pager {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin: 8px 0 0;
  padding: 0 var(--stage-pad-x);
  font: var(--fw-medium) var(--fs-s) / 1 var(--font-mono);
}

.pager[hidden] {
  display: none;
}

.pager__btn {
  min-width: 40px;
  height: 40px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-face);
  color: var(--text-primary);
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.pager__btn--arrow {
  font-size: var(--fs-l);
  line-height: 1;
}

.pager__btn:hover:not(:disabled) {
  background: var(--surface-lift);
}

.pager__btn[aria-current="page"] {
  background: var(--menu-active-bg);
  border-color: var(--menu-active-bg);
  color: var(--menu-active-fg);
}

.pager__btn:disabled {
  opacity: .35;
  cursor: default;
}

/* Écran étroit (même seuil que le volet du menu) : un bouton entonnoir et le
   compte sur une ligne ; les champs, repliés dessous, ne s'ouvrent qu'au
   bouton (aria-expanded), sur toute la largeur. */
@media (max-width: 739.98px) {
  .browse {
    align-items: center;
    gap: 12px;
  }

  .browse__toggle {
    display: grid;
    place-items: center;
  }

  .browse__count {
    flex: 1 1 auto;
    padding-bottom: 0;
    text-align: left;
  }

  .browse__fields {
    display: none;
    flex-basis: 100%;
    flex-wrap: wrap;
    gap: 10px 14px;
    align-items: flex-end;
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-tile);
    background: var(--surface-face);
  }

  .browse--open .browse__fields {
    display: flex;
  }

  .browse__field {
    flex: 1 1 130px;
  }
}

/* Cube de chargement : une petite boîte (les mêmes six faces qu'une tuile,
   dimensionnées par --w/--h/--d) qui tourne au centre de la scène pendant que
   les contenus sont lus. Visible dès le premier rendu, sans JavaScript ;
   js/main.js le retire pour monter la grille, qui arrive en roulant. Sous
   animations réduites (et SITE.motion ≠ "roll"), il reste immobile. */
.loader {
  display: grid;
  place-items: center;
  min-height: 40vh;
  perspective: 800px;
}

.loader__cube {
  --w: 56px;
  --h: 56px;
  --d: 56px;
  position: relative;
  width: var(--w);
  height: var(--h);
  transform-style: preserve-3d;
  animation: loader-tumble 2.4s cubic-bezier(.45, .05, .55, .95) infinite;
}

@keyframes loader-tumble {
  from { transform: rotateX(-24deg) rotateY(0turn); }
  to { transform: rotateX(-24deg) rotateY(1turn); }
}

@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="roll"]) .loader__cube {
    animation: none;
    transform: rotateX(-24deg) rotateY(-30deg);
  }
}

/* Vue oblique (projection « cabinet ») : la scène entière est tournée de
   −view-y autour de Y (on voit le côté droit) et de −view-x autour de X (on
   voit le dessus), comme le .world de la démo. Le skewY annule le cisaillement
   produit par la composition des deux rotations : les faces avant restent des
   rectangles droits, seulement resserrés de cos(view-y) × cos(view-x), et les
   rangées restent horizontales. Chaque boîte est vue sous le même angle ; la
   roulade se fait à l'intérieur de cette vue, elle n'a rien à en savoir. */
.grid {
  display: grid;
  gap: var(--gap);
  grid-auto-flow: row dense;
  margin: 0;
  padding: 0;
  list-style: none;
  transform-style: preserve-3d;
  transform-origin: 50% 0;
  transform:
    skewY(atan(-1 * sin(var(--view-x)) * tan(var(--view-y))))
    rotateX(calc(-1 * var(--view-x)))
    rotateY(calc(-1 * var(--view-y)));
  outline: none;
}

/* Grille sortante : sortie du flux pour laisser la place à la nouvelle,
   sans bouger d'un pixel (mêmes décalages que le padding de la scène). */
.grid--leaving {
  position: absolute;
  top: var(--stage-pad-y);
  left: var(--stage-pad-x);
  pointer-events: none;
}

/* Route article : plus de 3D. */
body[data-route="article"] .stage {
  perspective: none;
}

body[data-route="article"] .grid,
body[data-route="article"] .tile {
  transform-style: flat;
}

body[data-route="article"] .grid {
  transform: none;
}

/* Couche FLIP : reçoit la tuile ou l'en-tête en transit, en coordonnées
   de fenêtre. */
.flip-layer {
  position: fixed;
  inset: 0;
  z-index: 10;
  overflow: hidden;
  pointer-events: none;
}

.flip-layer > * {
  position: absolute;
  margin: 0;
  list-style: none;
}
