/* MINUIT — Défis flash (js/defis.js). Un « télégramme » doré, posé par Casino.ux.libre : jamais sur une commande ni un résultat.
   Couches (échelle de css/base.css) : .df-banner 942 (entre la réglette des potes 940 et les bulles 944) · .df-tools 900 (hall,
   hôte seul, comme .rp-tools) · .df-pop 1090 (petite fenêtre de l'hôte, comme .rp-pop). */
.df-banner {
  position: fixed; left: auto; right: 14px; top: 76px; z-index: 942;
  display: grid; grid-template-columns: 50px 1fr; align-items: center; gap: 11px;
  width: min(344px, calc(100vw - 28px)); min-height: 74px; padding: 8px 13px 11px 9px; margin: 0;
  border: 1px solid rgba(247,221,143,.55); border-radius: 14px; cursor: pointer; text-align: left; color: var(--text);
  font: 500 13px/1.3 var(--font-ui); letter-spacing: .01em;
  background:
    linear-gradient(115deg, rgba(247,221,143,.10) 0 1px, transparent 1px 100%) 0 0 / 9px 9px,
    radial-gradient(120% 140% at 0% 0%, rgba(222,184,92,.20), transparent 55%),
    linear-gradient(180deg, #1a1630 0%, #0d0f1e 100%);
  box-shadow: 0 0 0 1px rgba(0,0,0,.6), 0 0 0 4px rgba(222,184,92,.08), 0 16px 40px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,240,190,.18);
  overflow: hidden; isolation: isolate; opacity: 0; transform: translateY(-8px) scale(.97);
  transition: opacity .28s ease, transform .28s cubic-bezier(.2,.9,.25,1.2), border-color .3s, box-shadow .3s;
}
.df-banner::before {  /* perforations du ticket, côté anneau */
  content: ""; position: absolute; left: 64px; top: 8px; bottom: 8px; width: 0; border-left: 2px dotted rgba(247,221,143,.28); z-index: -1;
}
.df-banner.is-on { opacity: 1; transform: none; }
.df-banner.is-out { opacity: 0; transform: translateY(-6px) scale(.97); pointer-events: none; }
.df-banner:hover { border-color: var(--gold-hi); box-shadow: 0 0 0 1px rgba(0,0,0,.6), 0 0 0 4px rgba(222,184,92,.16), 0 18px 46px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,240,190,.25); }
.df-banner:focus-visible { outline: 2px solid var(--gold-hi); outline-offset: 3px; }
.df-banner.is-in { animation: df-arrive .7s cubic-bezier(.2,.9,.25,1.25) both; }
.df-banner.is-in .df-shine { animation: df-shine 1.1s .25s ease-out both; }
.df-banner.is-poke { animation: df-poke .45s ease-out; }
@keyframes df-arrive {
  0% { opacity: 0; transform: translateY(-26px) scale(.9) rotate(-1.2deg); filter: brightness(2.2); }
  55% { opacity: 1; transform: translateY(3px) scale(1.02) rotate(.3deg); filter: brightness(1.35); }
  100% { opacity: 1; transform: none; filter: none; }
}
@keyframes df-shine { from { transform: translateX(-120%) skewX(-18deg); opacity: .0; } 30% { opacity: .9; } to { transform: translateX(260%) skewX(-18deg); opacity: 0; } }
@keyframes df-poke { 0%, 100% { transform: none; } 30% { transform: translateX(-4px); } 60% { transform: translateX(3px); } }
.df-shine { position: absolute; inset: 0 auto 0 0; width: 40%; pointer-events: none; opacity: 0;
  background: linear-gradient(90deg, transparent, rgba(255,244,205,.35), transparent); transform: translateX(-120%) skewX(-18deg); }

/* l'anneau du décompte */
.df-ring { position: relative; width: 50px; height: 50px; display: grid; place-items: center; }
.df-ring-svg { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.df-ring-bg { fill: rgba(5,6,11,.55); stroke: rgba(222,184,92,.18); stroke-width: 4; }
.df-ring-fg { fill: none; stroke: var(--gold); stroke-width: 4; stroke-linecap: round; stroke-dasharray: 100 100; transition: stroke-dashoffset .25s linear, stroke .3s;
  filter: drop-shadow(0 0 4px rgba(222,184,92,.55)); }
.df-time { position: relative; font: 700 14px/1 var(--font-num); color: var(--gold-hi); letter-spacing: .02em; }
.df-banner.is-urgent .df-ring-fg { stroke: var(--lose); filter: drop-shadow(0 0 5px rgba(255,90,103,.7)); }
.df-banner.is-urgent .df-time { color: #ffd0d4; animation: df-battement 1s ease-in-out infinite; }
@keyframes df-battement { 50% { transform: scale(1.12); } }

/* le texte */
.df-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.df-top { display: flex; align-items: baseline; gap: 6px; }
.df-top .df-prime { margin-left: auto; }
.df-kick { font: 600 10.5px/1.4 var(--font-ui); letter-spacing: .22em; text-transform: uppercase; color: var(--gold); white-space: nowrap; }
.df-prime { font: 700 14px/1 var(--font-num); color: #241904; background: linear-gradient(180deg, var(--gold-hi), var(--gold) 60%, #b8913b); padding: 3px 8px 2px; border-radius: 999px;
  box-shadow: 0 0 0 1px rgba(255,236,170,.5) inset, 0 3px 10px rgba(222,184,92,.3); white-space: nowrap; }
.df-prime:empty { display: none; }
.df-titre { font: 400 16px/1.15 var(--font-display); color: var(--text); letter-spacing: .01em; text-wrap: balance; }
.df-lead { font-size: 12.5px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.df-dim { color: var(--text-dim); }
.df-who { color: var(--pc, var(--gold-hi)); font-weight: 600; }
.df-val { color: var(--gold-hi); font-weight: 700; }
.df-each { color: var(--win); font-weight: 600; }
.df-go { font: 600 10.5px/1.4 var(--font-ui); color: var(--text-dim); letter-spacing: .06em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.df-go:empty { display: none; }
.df-banner.is-here .df-go { color: var(--win); }
.df-bar { display: block; height: 5px; border-radius: 99px; background: rgba(255,255,255,.07); overflow: hidden; margin: 3px 0 1px; }
.df-bar[hidden] { display: none; }
.df-bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--gold-lo), var(--gold-hi)); transform-origin: left; transform: scaleX(0); transition: transform .4s cubic-bezier(.2,.9,.3,1); }

/* la mèche qui brûle, au pied du télégramme */
.df-fuse { position: absolute; left: 12px; right: 12px; bottom: 5px; height: 2px; border-radius: 2px; background: rgba(222,184,92,.12); overflow: visible; }
.df-fuse::before { content: ""; position: absolute; inset: 0; border-radius: inherit; background: linear-gradient(90deg, #8c6a22, var(--gold-hi)); transform-origin: left;
  transform: scaleX(var(--p0, 1)); }
.df-fuse.is-burn::before { animation: df-meche var(--dur, 180s) linear forwards; }
.df-spark { position: absolute; top: 50%; left: calc(var(--p0, 1) * 100%); width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; border-radius: 50%;
  background: radial-gradient(circle, #fff7d6 0 30%, #ffc44d 45%, rgba(255,120,40,0) 72%); box-shadow: 0 0 8px 3px rgba(255,170,60,.55); }
.df-fuse.is-burn .df-spark { animation: df-etincelle var(--dur, 180s) linear forwards, df-crepite .18s steps(2) infinite; }
@keyframes df-meche { from { transform: scaleX(var(--p0, 1)); } to { transform: scaleX(0); } }
@keyframes df-etincelle { from { left: calc(var(--p0, 1) * 100%); } to { left: 0%; } }
@keyframes df-crepite { 50% { transform: scale(1.35); opacity: .75; } }

/* résultat */
.df-banner.is-won { border-color: var(--gold-hi); background:
    radial-gradient(130% 160% at 50% 0%, rgba(247,221,143,.32), transparent 60%),
    linear-gradient(180deg, #2a2210 0%, #120f08 100%);
  box-shadow: 0 0 0 1px rgba(0,0,0,.6), 0 0 0 5px rgba(247,221,143,.16), 0 0 38px rgba(222,184,92,.45), 0 16px 40px rgba(0,0,0,.55); }
.df-banner.is-won .df-kick { color: var(--gold-hi); }
.df-banner.is-won .df-titre { color: #fff4cf; }
.df-banner.is-won .df-time { color: var(--win); font-size: 22px; }
.df-banner.is-won .df-ring-fg { stroke: var(--win); }
.df-banner.is-won .df-shine { animation: df-shine 1.3s ease-out 2; }
.df-banner.is-lost { opacity: .92; filter: saturate(.55); }
.df-banner.is-lost .df-kick { color: var(--text-dim); }
.df-banner.is-lost .df-ring-fg { stroke: rgba(222,184,92,.25); }
.df-banner.is-won .df-fuse, .df-banner.is-lost .df-fuse { visibility: hidden; }

/* qualité allégée et animations réduites */
.perf-low .df-banner { box-shadow: 0 0 0 1px rgba(0,0,0,.6), 0 10px 26px rgba(0,0,0,.5); background: linear-gradient(180deg, #1a1630 0%, #0d0f1e 100%); }
.perf-low .df-ring-fg, .perf-low .df-spark { filter: none; box-shadow: none; }
.perf-low .df-fuse.is-burn .df-spark { animation: df-etincelle var(--dur, 180s) linear forwards; }
.reduce-motion .df-banner, .reduce-motion .df-banner.is-in, .reduce-motion .df-banner.is-poke { animation: none; transition: opacity .2s; }
.reduce-motion .df-shine, .reduce-motion .df-banner.is-urgent .df-time { animation: none; }

/* chez l'hôte : ⚡ et sa petite fenêtre */
.df-tools { position: fixed; left: 118px; bottom: 10px; z-index: 900; display: flex; gap: 6px; }
.df-tools[hidden] { display: none; }
.df-tool { width: 40px; height: 40px; border-radius: 12px; border: 1px solid var(--line-strong); background: rgba(10,13,24,.82); color: var(--gold-hi); font-size: 18px; cursor: pointer;
  box-shadow: var(--shadow-1); transition: border-color .2s, transform .12s; }
.df-tool:hover { border-color: var(--gold); transform: translateY(-1px); }
.df-pop { position: fixed; left: 12px; bottom: 60px; z-index: 1090; width: min(340px, calc(100vw - 24px)); padding: 14px 14px 12px; border-radius: 14px;
  border: 1px solid var(--line-strong); background: linear-gradient(180deg, rgba(26,32,64,.97), rgba(10,13,24,.98)); box-shadow: var(--shadow-2);
  display: flex; flex-direction: column; gap: 9px; }
.df-pop-t { font: 400 18px/1.1 var(--font-display); color: var(--gold-hi); }
.df-pop-sub { font-size: 12px; color: var(--text-dim); }
.df-pop-info { font-size: 12.5px; color: var(--text); min-height: 1.3em; }
.df-pop-row { display: flex; gap: 8px; flex-wrap: wrap; }
.df-seg { display: grid; grid-template-columns: repeat(5, 1fr); gap: 4px; padding: 3px; border-radius: 12px; border: 1px solid var(--line); background: rgba(5,6,11,.5); }
.df-segb { height: 32px; border: 0; border-radius: 9px; background: transparent; color: var(--text-dim); font: 600 12.5px/1 var(--font-ui); cursor: pointer; }
.df-segb:hover { color: var(--text); background: rgba(222,184,92,.08); }
.df-segb.is-on { color: #241904; background: linear-gradient(180deg, var(--gold-hi), var(--gold)); }

/* ACCUEIL 01/10 — au hall, la bannière se range en tête de la colonne de droite (js : poser) : largeur des panneaux, plus rien ne
   flotte sur le hall qui défile ; à une table, elle reste posée par Casino.ux.libre */
.hall-side > .df-banner.is-colonne, .hall-inner > .df-banner.is-colonne { position: relative; left: auto; right: auto; top: auto; width: auto; z-index: auto; }
.hall-inner > .df-banner.is-colonne { grid-column: 1 / -1; }   /* écran étroit : tout en haut du hall, sur toute la largeur */
/* TÉLÉPHONE — N1c (revue au téléphone du 13/10, n° 21) : à une table, le télégramme (344 × 74 px) ne trouvait aucune place libre sur un
   écran de téléphone et couvrait les infos du jeu (« Entrée / Pot » du Menteur, « Série / Gain en cours » du Plus ou Moins, « Tes
   dés »). Au téléphone, À UNE TABLE, il se replie en son anneau de décompte, la prime en pastille dessous (comme le cadeau du jour du
   hall) : Casino.ux.libre lui trouve une place libre (souvent le coin que laisse la réglette flottante). Le kicker, le titre et la
   ligne d'état restent dans le bouton pour les lecteurs d'écran (cachés comme .signal-voix) ; un toucher mène au jeu du défi, comme
   avant. Au hall (colonne), le télégramme reste entier. Bornée au téléphone : le PC ne change pas. */
@media (orientation: portrait) and (max-width: 480px), (orientation: landscape) and (max-height: 560px) {
  .df-banner:not(.is-colonne) { grid-template-columns: 50px; gap: 0; right: auto; width: auto; min-height: 0; padding: 5px 5px 21px; border-radius: 22px; overflow: visible; }
  .df-banner:not(.is-colonne)::before, .df-banner:not(.is-colonne) .df-fuse, .df-banner:not(.is-colonne) .df-shine { display: none; }
  .df-banner:not(.is-colonne) .df-body > :not(.df-top), .df-banner:not(.is-colonne) .df-top > :not(.df-prime) {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
  .df-banner:not(.is-colonne) .df-prime { position: absolute; left: 50%; bottom: 3px; transform: translateX(-50%); font-size: 12.5px; padding: 3px 7px 2px; }
  /* Q4 (D5, dev/audit/DECISIONS-TEL-1310.md:232-302) : l'anneau dit « défi » (sa prime marquée ⚡ ; l'éclair est un décor, la prime se lit
     seule) ; à l'arrivée d'un défi, à son résultat et au toucher sur l'anneau (js/defis.js, deplier), le télégramme compact : même matière
     (bord d'or, dégradé nuit, reflet à l'entrée), l'anneau à gauche avec le temps, ligne 1 « ⚡ DÉFI FLASH · <jeu> ↗ » et la prime, ligne 2 le
     titre ; posé sur la voie de la réglette des potes (js/defis.js, poserBandeau). */
  .df-banner:not(.is-colonne):not(.is-arrivee) .df-prime::before { content: "⚡ " / ""; }
  .df-banner.is-arrivee:not(.is-colonne) { grid-template-columns: 40px minmax(0, 1fr); gap: 9px; height: 52px; padding: 0 10px 0 5px; border-radius: 14px; overflow: hidden; }
  .df-banner.is-arrivee:not(.is-colonne) .df-shine { display: block; }
  .df-banner.is-arrivee:not(.is-colonne) .df-ring { width: 40px; height: 40px; }
  .df-banner.is-arrivee:not(.is-colonne) .df-time { font-size: 12px; }
  .df-banner.is-arrivee:not(.is-colonne) .df-body { gap: 2px; }
  .df-banner.is-arrivee:not(.is-colonne) .df-top { align-items: center; gap: 0; min-width: 0; }
  .df-banner.is-arrivee:not(.is-colonne) .df-top > .df-kick, .df-banner.is-arrivee:not(.is-colonne) .df-top > .df-go,
  .df-banner.is-arrivee:not(.is-colonne) .df-body > .df-titre { position: static; width: auto; height: auto; margin: 0; clip-path: none; }
  .df-banner.is-arrivee:not(.is-colonne) .df-kick, .df-banner.is-arrivee:not(.is-colonne) .df-go {
    font: 600 12px/1.3 var(--font-ui); letter-spacing: .16em; text-transform: uppercase; color: var(--gold); }
  .df-banner.is-arrivee:not(.is-colonne) .df-kick { flex: none; }
  .df-banner.is-arrivee:not(.is-colonne) .df-go { flex: 1 1 auto; min-width: 0; padding-left: .45em; overflow: hidden; text-overflow: ellipsis; }
  .df-banner.is-arrivee:not(.is-colonne) .df-prime { position: static; transform: none; flex: none; margin-left: 8px; font-size: 13px; padding: 3px 8px 2px; }
  .df-banner.is-arrivee:not(.is-colonne) .df-titre { display: block; font: 400 15px/1.2 var(--font-display); white-space: nowrap; text-wrap: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
@media (orientation: landscape) and (max-height: 560px) {
  .df-banner.is-arrivee:not(.is-colonne) { grid-template-columns: 36px minmax(0, 1fr); height: 46px; }
  .df-banner.is-arrivee:not(.is-colonne) .df-ring { width: 36px; height: 36px; }
}
/* le bandeau (téléphone seulement : is-arrivee n'existe qu'au téléphone), animations réduites : ni rebond ni reflet, un fondu de 150 ms */
.reduce-motion .df-banner.is-arrivee, .reduce-motion .df-banner.is-arrivee .df-shine { animation: none; }
.reduce-motion .df-banner.is-arrivee { transition: opacity .15s; }
@media (prefers-reduced-motion: reduce) {
  .df-banner.is-arrivee, .df-banner.is-arrivee .df-shine { animation: none; }
  .df-banner.is-arrivee { transition: opacity .15s; }
}
/* TÉLÉPHONE — N11 (annexe A de la revue au téléphone, REMESURÉE sur 1bedc6a) : « ⚡ Défi flash » et le jeu du défi (10,5 px) : 12 px. Mêmes polices, même interlettrage,
   même couleur ; on agrandit le texte, on ne redessine pas. Bornée au téléphone : le PC ne change pas (dev/tests-client/s5-tel-textes.mjs, D et D2). */
@media (orientation: portrait) and (max-width: 480px), (orientation: landscape) and (max-height: 560px) {
  .df-kick, .df-go { font-size: 12px; }
}
/* en PORTRAIT, au hall (la colonne), la ligne du haut passe sur deux : « ⚡ DÉFI FLASH » et la prime ; le jeu du défi dessous, sur toute la largeur (à 12 px,
   « · Plus ou Moins ↗ » ne tenait plus entre le kicker et la prime : il se coupait en « Plus ou Moi… »). Pas couché : la ligne y tient, et le hall couché n'a pas
   une ligne de plus à donner (le texte du héros passait sous le quai du bas : épreuve s5-tel-textes, « défi au hall » 844 × 390). */
@media (orientation: portrait) and (max-width: 480px) {
  .df-banner.is-colonne .df-top { flex-wrap: wrap; }
  .df-banner.is-colonne .df-prime { order: 2; }
  .df-banner.is-colonne .df-go { order: 3; flex: 1 0 100%; }
}
