/* Kit « appareils » des maquettes refonte outils — v3.3
 *
 * Téléphone et ordinateur dessinés en CSS, à l'échelle de leur conteneur
 * (unités cqi) : nets à toute taille, écran toujours aligné au pixel près,
 * appareil toujours entier. La capture d'écran réelle est un simple <img>.
 * Aucune ombre portée lourde : un reflet de sol très léger, c'est tout.
 * Voir DEVICE.md pour le balisage.
 */

.dv {
  --dv-w: 300px;
  --dv-frame-a: #eceef1;
  --dv-frame-b: #a9adb4;
  --dv-frame-c: #d9dce0;
  --dv-frame-d: #8c9098;
  --dv-bezel: #0c0c0e;
  --dv-screen-bg: #fff;
  --dv-floor: rgba(17, 24, 39, .10);
  container-type: inline-size;
  position: relative;
  /* contexte d'empilement propre : le reflet de sol (z-index -1) reste
     visible au-dessus d'une section à fond teinté */
  isolation: isolate;
  width: min(var(--dv-w), 100%);
  margin: 0 auto;
  line-height: 0;
}

.dv img,
.dv video {
  display: block;
  width: 100%;
  height: auto;
}

/* ---------------------------------------------------------------- téléphone */

.dv--phone { --dv-w: 300px; }

.dv--phone .dv__body {
  position: relative;
  /* hauteur explicite plutôt qu'aspect-ratio : sous WebKit (Safari, iPhone),
     aspect-ratio + padding/bordure en cqi donnait un corps 4,5 % trop haut */
  box-sizing: border-box;
  height: 205.6cqi;
  padding: 3.6cqi;
  border: 1.05cqi solid transparent;
  border-radius: 16.4cqi;
  background:
    linear-gradient(var(--dv-bezel), var(--dv-bezel)) padding-box,
    linear-gradient(150deg, var(--dv-frame-a) 0%, var(--dv-frame-b) 22%, var(--dv-frame-c) 48%, var(--dv-frame-d) 76%, var(--dv-frame-c) 100%) border-box;
  box-shadow: inset 0 0 0 .3cqi #2b2b2f;
}

/* boutons latéraux : action + volume à gauche, marche à droite */
.dv--phone .dv__body::before,
.dv--phone .dv__body::after {
  content: "";
  position: absolute;
  width: .9cqi;
  border-radius: .5cqi;
  background: linear-gradient(90deg, var(--dv-frame-d), var(--dv-frame-a));
}
.dv--phone .dv__body::before {
  left: -1.95cqi;
  top: 21%;
  height: 16%;
  box-shadow: 0 -9cqi 0 0 var(--dv-frame-b);
  clip-path: inset(-10cqi 0 0 0);
}
.dv--phone .dv__body::after {
  right: -1.95cqi;
  top: 27%;
  height: 11%;
  background: linear-gradient(270deg, var(--dv-frame-d), var(--dv-frame-a));
}

.dv--phone .dv__screen {
  position: relative;
  height: 100%;
  overflow: hidden;
  border-radius: 12.4cqi;
  background: var(--dv-screen-bg);
  isolation: isolate;
}

/* barre d'état façon app installée (heure + pictos), sous l'îlot */
.dv__status {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 11.5cqi;
  padding: 1.4cqi 7.5cqi 0 8.5cqi;
  background: var(--dv-status-bg, var(--dv-screen-bg));
  color: #0b0b0c;
  font: 600 4.3cqi/1 -apple-system, "SF Pro Text", "Figtree", system-ui, sans-serif;
  letter-spacing: -.01em;
}
.dv__status-icons {
  display: flex;
  align-items: center;
  gap: 1.3cqi;
}
.dv__bars {
  display: flex;
  align-items: flex-end;
  gap: .55cqi;
  height: 3.2cqi;
}
.dv__bars i {
  display: block;
  width: .95cqi;
  border-radius: .3cqi;
  background: currentColor;
}
.dv__bars i:nth-child(1) { height: 35%; }
.dv__bars i:nth-child(2) { height: 55%; }
.dv__bars i:nth-child(3) { height: 78%; }
.dv__bars i:nth-child(4) { height: 100%; }
.dv__wifi {
  width: 4.6cqi;
  height: 3.3cqi;
  background: radial-gradient(circle at 50% 100%, currentColor 0 18%, transparent 19% 36%, currentColor 37% 55%, transparent 56% 73%, currentColor 74% 92%, transparent 93%);
  clip-path: polygon(50% 100%, -8% 4%, 108% 4%);
}
.dv__battery {
  position: relative;
  width: 6.6cqi;
  height: 3.2cqi;
  border: .35cqi solid currentColor;
  border-radius: .95cqi;
  opacity: .9;
}
.dv__battery::before {
  content: "";
  position: absolute;
  inset: .35cqi;
  width: 72%;
  border-radius: .45cqi;
  background: currentColor;
}
.dv__battery::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -1.1cqi;
  width: .55cqi;
  height: 1.3cqi;
  translate: 0 -50%;
  border-radius: 0 .4cqi .4cqi 0;
  background: currentColor;
  opacity: .55;
}

/* île dynamique : dans l'écran (pas sur le cadre), à 11 pt du haut comme sur
   un iPhone (écran 393 pt = 90,7cqi, soit 2,54cqi), centrée sur la ligne de
   l'heure. Repère : padding du corps 3,6cqi + 2,54cqi. */
.dv__island {
  position: absolute;
  z-index: 3;
  top: 6.14cqi;
  left: 50%;
  width: 29cqi;
  height: 8.4cqi;
  translate: -50% 0;
  border-radius: 99px;
  background: #000;
}

/* zone qui montre la capture ; la capture peut défiler si elle est haute */
.dv__view {
  position: relative;
  overflow: hidden;
  height: calc(100% - 11.5cqi);
}
.dv--phone.dv--bare .dv__view { height: 100%; }

.dv__view > img,
.dv__view > video,
.dv__view > picture > img {
  width: 100%;
  height: auto;
}
/* capture : toujours pleine largeur, hauteur naturelle, même si une règle de
   page du type « .cadre img { height: 100%; object-fit: cover } » s'applique */
.dv.dv--phone .dv__view > img:not(.dv__appbar),
.dv.dv--phone .dv__view > picture > img,
.dv.dv--phone .dv__scroller > img,
.dv.dv--phone .dv__scroller > picture > img {
  width: 100%;
  height: auto;
  object-fit: fill;
  max-width: none;
}
/* capture fixe : --dv-view-offset (px CSS de l'app, à 390 px de large) remonte
   l'image pour que le bas de l'écran tombe dans un blanc, pas sur un bouton coupé
   (l'en-tête collant .dv__appbar, lui, ne bouge pas) */
.dv--phone .dv__view > img:not(.dv__appbar),
.dv--phone .dv__view > picture {
  display: block;
  translate: 0 calc(var(--dv-view-offset, 0) * -90.7cqi / 390);
}

/* en-tête collant de l'app, découpé en haut de la capture haute et posé
   au-dessus du défilement (<img class="dv__appbar"> avant .dv__scroller) */
.dv__view > .dv__appbar {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  width: 100%;
  height: auto;
  pointer-events: none;
}
/* barre d'action fixe en bas de l'app : même principe, collée en bas ; le
   .dv__scroller prend alors un padding-bottom égal à sa hauteur (page) */
.dv__view > .dv__appbar--bottom { top: auto; bottom: 0; }

/* barre d'accueil */
.dv--phone .dv__screen::after {
  content: "";
  position: absolute;
  z-index: 3;
  bottom: 2.2cqi;
  left: 50%;
  width: 34cqi;
  height: 1.25cqi;
  translate: -50% 0;
  border-radius: 99px;
  background: rgba(10, 10, 12, .82);
}

/* défilement automatique d'une capture haute (data-dv-scroll)
   --dv-scroll-end : marge sous la fin de la capture, pour que la dernière
   carte s'arrête au-dessus de la barre d'accueil (fond = couleur de l'app) */
.dv__scroller {
  will-change: transform;
}
@media (prefers-reduced-motion: no-preference) {
  .dv--phone .dv__scroller {
    padding-bottom: var(--dv-scroll-end, 6cqi);
    background: var(--dv-scroll-end-bg, var(--dv-status-bg, var(--dv-screen-bg)));
  }
}
/* avant le premier cycle (et entre deux entrées à l'écran) : même position que
   la pause haute, pour qu'il n'y ait aucun saut au démarrage */
@media (prefers-reduced-motion: no-preference) {
  .dv--scrollable:not(.is-scrolling) .dv__scroller {
    transform: translateY(calc(var(--dv-scroll-to, 0px) * var(--dv-scroll-top, 0)));
  }
}
.dv.is-scrolling .dv__scroller {
  animation: dv-scroll var(--dv-scroll-duration, 14s) cubic-bezier(.45, 0, .2, 1) infinite;
  animation-delay: var(--dv-scroll-delay, 0s);
}
/* sans animation, la capture haute reste sur --dv-scroll-rest
   (0 = haut, 1 = bas, 0.5 = milieu) */
@media (prefers-reduced-motion: reduce) {
  .dv--scrollable .dv__scroller {
    transform: translateY(calc(var(--dv-scroll-to, 0px) * var(--dv-scroll-rest, var(--dv-scroll-top, 0))));
  }
}
/* --dv-scroll-top (0 à 1, défaut 0) : pause haute ; --dv-scroll-stop (0 à 1,
   défaut 1) : pause basse. Les deux se règlent pour que la barre d'accueil
   tombe entre deux blocs de l'app. */
@keyframes dv-scroll {
  0%, 14%   { transform: translateY(calc(var(--dv-scroll-to, 0px) * var(--dv-scroll-top, 0))); }
  46%, 60%  { transform: translateY(calc(var(--dv-scroll-to, 0px) * var(--dv-scroll-stop, 1))); }
  92%, 100% { transform: translateY(calc(var(--dv-scroll-to, 0px) * var(--dv-scroll-top, 0))); }
}

/* ---------------------------------------------------------------- ordinateur */

.dv--laptop { --dv-w: 1040px; }

.dv--laptop .dv__lid {
  position: relative;
  width: 84%;
  margin: 0 auto;
  padding: 1.55cqi 1.55cqi 2.35cqi;
  border: .32cqi solid transparent;
  border-radius: 2.6cqi 2.6cqi .9cqi .9cqi;
  background:
    linear-gradient(var(--dv-bezel), var(--dv-bezel)) padding-box,
    linear-gradient(180deg, var(--dv-frame-c), var(--dv-frame-d)) border-box;
}
/* caméra */
.dv--laptop .dv__lid::before {
  content: "";
  position: absolute;
  top: .55cqi;
  left: 50%;
  width: .55cqi;
  height: .55cqi;
  translate: -50% 0;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #3b4250, #0d0f14 70%);
}
.dv--laptop .dv__screen {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-radius: .45cqi;
  background: var(--dv-screen-bg);
}
.dv--laptop .dv__screen > img,
.dv--laptop .dv__screen > video,
.dv--laptop .dv__screen > picture > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}
.dv--laptop .dv__view { height: 100%; }

.dv--laptop .dv__base {
  position: relative;
  height: 1.9cqi;
  margin-top: -.05cqi;
  border-radius: .25cqi .25cqi 50% 50% / .25cqi .25cqi 100% 100%;
  background: linear-gradient(180deg, #f4f5f7 0%, #d5d8dd 38%, #b3b7be 78%, #8f939a 100%);
}
/* encoche d'ouverture */
.dv--laptop .dv__base::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 13cqi;
  height: .75cqi;
  translate: -50% 0;
  border-radius: 0 0 1cqi 1cqi;
  background: linear-gradient(180deg, #a9adb4, #c9ccd1);
}
/* charnière sombre sous l'écran */
.dv--laptop .dv__base::after {
  content: "";
  position: absolute;
  top: -.4cqi;
  left: 8%;
  right: 8%;
  height: .4cqi;
  border-radius: .2cqi .2cqi 0 0;
  background: linear-gradient(180deg, #4a4d53, #2a2c30);
}

/* ---------------------------------------------------------------- sol */
/* Les deux appareils d'un duo sont posés sur le même sol, d'office. */

.dv--floor::after,
.dv-duo > .dv::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 8%;
  right: 8%;
  bottom: -2.4cqi;
  height: 4.8cqi;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--dv-floor), transparent);
  pointer-events: none;
}
.dv--phone.dv--floor::after,
.dv-duo > .dv--phone::after {
  left: 12%;
  right: 12%;
  /* un petit téléphone (duo) garde un reflet lisible */
  bottom: min(-3.2cqi, -7px);
  height: max(7cqi, 16px);
}

/* ---------------------------------------------------------------- duo */
/* Ordinateur + téléphone posé devant, à droite. Le téléphone ne recouvre
   que le cadre de l'ordinateur, jamais son écran. Toutes les mesures sont
   en % du duo lui-même (pas du parent) : le raccord est identique à toute
   largeur. Il descend un peu sous la boîte du duo : prévoir ~4 % de la
   largeur en marge basse du bloc. */

.dv-duo {
  --dv-duo-w: 1080px;
  position: relative;
  width: min(var(--dv-duo-w), 100%);
  margin: 0 auto;
}
.dv-duo > .dv--laptop { --dv-w: 100%; width: 87%; margin: 0; }
.dv-duo > .dv--phone {
  --dv-w: 100%;
  position: absolute;
  right: 0;
  bottom: -2%;
  width: 21%;
}

/* ---------------------------------------------------------------- mobile */

/* bascule ordinateur / téléphone : un seul seuil pour les 7 outils */
@media (max-width: 720px) {
  .dv--phone { --dv-w: min(74vw, 290px); }
  /* même si --dv-w est posé en ligne, le téléphone ne dépasse pas 74vw / 290 px */
  .dv--phone { width: min(var(--dv-w), 74vw, 290px, 100%); }
  .dv-duo > .dv--laptop { width: 84%; }
  .dv-duo > .dv--phone { width: 26%; bottom: -6%; }
  .dv-only-desktop { display: none !important; }
}
@media (min-width: 721px) {
  .dv-only-mobile { display: none !important; }
}
/* second seuil, tablette : ordinateur réservé aux grands écrans */
@media (max-width: 1024px) {
  .dv-only-wide { display: none !important; }
}
@media (min-width: 1025px) {
  .dv-only-compact { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .dv.is-scrolling .dv__scroller { animation: none; }
}
