/* The drawing of the home page in layers (functions/ville-accueil.php, 02/11/2026). Every motion keeps the video's loop
   (--doda-ville-duree, 12.88 s) and its times, read on the video frame by frame. */

.doda-ville {
  position: relative;
  width: 100%;
  aspect-ratio: 3000 / 1830;
  overflow: hidden;
  background: #000;
}

.doda-ville img {
  position: absolute;
  display: block;
  max-width: none;
  pointer-events: none;
}

.doda-ville .doda-ville__fond {
  position: static;
  width: 100%;
  height: 100%;
}

/* A building, at its largest in its layer, grows from a little smaller, eased at both ends, on the buildings' own loop
   (--doda-ville-ronde: 11 buildings, one every 2.7 s, so 29.7 s; functions/ville-accueil.php sets each one's delay).
   Christophe, 02/11/2026 : « encore trop rapide », « un peu trop », « 0.5 s entre deux bâtiments », then « un peu plus
   rapide » : 0.8 s to grow (2.694 % of the loop), 0.6 s at its largest from the middle (2.02 %), 0.8 s to settle, then
   0.5 s when none moves. The video took 0.26 s each way, one building every 0.9 s. */
.doda-ville__batiment {
  opacity: 0;
  transform: scale(0.95);
  will-change: opacity, transform;
  animation: doda-ville-grossir var(--doda-ville-ronde) infinite;
}

/* At its largest, 6 % beyond the frame of the video where it is largest (Christophe, 02/11/2026: « grossir légèrement
   plus »; at 10 %, the layer's soft margin blurs the lines next to it). js/ville-accueil.js uses the same, GRAND. */
@keyframes doda-ville-grossir {
  0%, 47.306% { opacity: 0; transform: scale(0.95); animation-timing-function: ease-in-out; }
  50% { opacity: 1; transform: scale(1.06); animation-timing-function: linear; }
  52.02% { opacity: 1; transform: scale(1.06); animation-timing-function: ease-in-out; }
  54.714%, 100% { opacity: 0; transform: scale(0.95); }
}

/* The building of the card under the mouse: js/ville-accueil.js (a transition does not start on a property that an
   animation moves, so it is played there, over the loop). Meanwhile the drawing stands still (Christophe, 02/11/2026:
   « que l'animation globale se fige »), but for the plane, which flies on (the same day: « l'avion ne s'arrête pas »),
   and the building's bubble opens beside it. */
.doda-ville.est-figee .doda-ville__batiment,
.doda-ville.est-figee .doda-ville__charge {
  animation-play-state: paused;
}

/* The bubble of a building: a panel set on the drawing (veil, blur behind, a fine line, sharp corners), the project's
   photograph, its name, the way to it; beside the building, joined to it by a leader line as on a plan. The hero's own
   card, which opened over the building, is not shown where the drawing is. */
.doda-ville ~ .dod-hero-cards .dod-project-card:hover .dod-card-inner {
  display: none !important;
}

.doda-bulle {
  position: absolute;
  z-index: 30;
  width: 15rem;
  padding: var(--espace-s);
  background: var(--doda-voile-dense);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 1px solid var(--doda-trait-fort);
  border-radius: 0;
  color: var(--doda-blanc);
  opacity: 0;
  visibility: hidden;
  transform: translateX(var(--doda-bulle-depart, 0.5rem));
  transition: opacity 0.3s ease-out, transform 0.3s ease-out, visibility 0s linear 0.3s;
}

.doda-bulle.est-ouverte {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.3s ease-out, transform 0.3s ease-out, visibility 0s;
}

.doda-bulle--gauche {
  --doda-bulle-depart: -0.5rem;
}

/* The leader line, from the bubble's side to the building, at the building's middle height (--doda-bulle-trait) */
.doda-bulle::before {
  content: "";
  position: absolute;
  top: var(--doda-bulle-trait, 50%);
  right: 100%;
  width: var(--doda-bulle-ecart, 2rem);
  border-top: 1px solid var(--doda-blanc);
}

/* and its end on the building, a small square, as the point of an annotation */
.doda-bulle::after {
  content: "";
  position: absolute;
  top: calc(var(--doda-bulle-trait, 50%) - 2px);
  right: calc(100% + var(--doda-bulle-ecart, 2rem) - 2px);
  width: 5px;
  height: 5px;
  background: var(--doda-blanc);
}

.doda-bulle--gauche::before {
  right: auto;
  left: 100%;
}

.doda-bulle--gauche::after {
  right: auto;
  left: calc(100% + var(--doda-bulle-ecart, 2rem) - 3px);
}

.doda-bulle__photo {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 0;
}

.doda-bulle__nom {
  margin: var(--espace-s) 0 var(--espace-xs);
  font-family: var(--font-titre);
  font-size: 0.95rem;
  line-height: 1.35;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--doda-blanc);
}

.doda-bulle__lien {
  display: inline-block;
  padding-bottom: 2px;
  font-family: var(--font-titre);
  font-size: 0.68rem;
  line-height: 1.4;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--doda-gris-clair);
  text-decoration: none;
  border-bottom: 1px solid var(--doda-trait-fort);
  transition: color 0.2s, border-color 0.2s;
}

.doda-bulle__lien:hover,
.doda-bulle__lien:focus-visible {
  color: var(--doda-blanc);
  border-bottom-color: var(--doda-blanc);
  outline: none;
}

@media (prefers-reduced-motion: reduce) {
  .doda-bulle,
  .doda-bulle.est-ouverte {
    transform: none;
    transition: none;
  }
}

/* The plane: across the whole drawing at an even speed, from wholly out of it on the left at 0 s to wholly out of it
   on the right at 11.16 s (86.65 % of the loop; the video's pace: its nose at 704 px on frame 60, 11.545 px further on
   each, ville-accueil.json « sortie »), behind the towers and the cliff (.doda-ville__premier-plan, laid over it).
   Meanwhile its 24 frames turn, one per 25th of a second; the sheet at full size on large screens, its half on others.
   A click (or a tap) on it makes it ride a wave (js/ville-accueil.js). */
.doda-ville__couloir {
  position: absolute;
  /* cut at the drawing's sides only, room above and below for its wave */
  clip-path: inset(-400% 0 -400% 0);
}

.doda-ville__avion {
  position: absolute;
  cursor: pointer;
  top: 0;
  height: 100%;
  width: var(--doda-avion-largeur);
  left: 100%;
  animation: doda-ville-voler var(--doda-ville-duree) linear infinite;
}

/* The same sheet twice, cut where the tow lines meet the plane's tail (158 px of each 231 px view: 68.4 %): the
   banner with its lines, and the plane. Under the mouse they ride a gentle wave as two pieces jointed at that point
   (js/ville-accueil.js, 02/11/2026: Christophe chose « une ondulation » over the roll he did not like); both turn
   about the joint, so the lines stay on the tail. */
.doda-ville__banderole,
.doda-ville__appareil {
  position: absolute;
  inset: 0;
  background: var(--doda-avion-planche-moitie) 0 0 / calc(var(--doda-avion-vues) * 100%) 100% no-repeat;
  animation: doda-ville-helice var(--doda-avion-tour) steps(24, jump-none) infinite;
  transform-origin: 68.4% 51%;   /* the joint: where the lines hold the tail */
}

.doda-ville__banderole {
  clip-path: inset(0 31.6% 0 0);
}

.doda-ville__appareil {
  clip-path: inset(0 0 0 68.4%);
}

@media (min-width: 1200px) {
  .doda-ville__banderole,
  .doda-ville__appareil {
    background-image: var(--doda-avion-planche);
  }
}

@keyframes doda-ville-voler {
  0% { left: calc(-1 * var(--doda-avion-largeur)); }
  86.65%, 100% { left: 100%; }
}

@keyframes doda-ville-helice {
  from { background-position: 0 0; }
  to { background-position: 100% 0; }
}

/* The load of the crane swings on its cable: about 29 degrees, at rest a moment at each end, three times per loop */
.doda-ville__charge {
  animation: doda-ville-balancer calc(var(--doda-ville-duree) / 6) ease-in-out infinite;
}

@keyframes doda-ville-balancer {
  0%, 10% { transform: rotate(0deg); }
  45%, 65% { transform: rotate(-29deg); }
  100% { transform: rotate(0deg); }
}

/* Without motion for those who ask for none: the town at rest */
@media (prefers-reduced-motion: reduce) {
  .doda-ville__batiment,
  .doda-ville .doda-ville__avion,
  .doda-ville__banderole,
  .doda-ville__appareil,
  .doda-ville__charge {
    animation: none;
  }
}

/* The « Agrandir » mode of phones: the hero takes the drawing's own proportions (extension dod-hero-section,
   frontend.css), so the drawing fills it as it is, and the cards stay on their buildings */
