:root{
  --ink: #eef3ff;
  --ink-dim: rgba(238,243,255,0.6);
  /* Degrade du splash. Il est VERTICAL : chaque ligne est uniforme, donc sa
     derniere ligne vaut exactement --splash-edge. Cette meme teinte sert de
     couleur au canevas, seule chose que iOS peigne sous le viewport. */
  --splash-top: #060c26;
  --splash-mid: #0b2168;
  --splash-edge: #0f4dbe;
  /* Couleur de marque unique, employée telle quelle par l'en-tête, la barre
     de navigation et le fond système (safe area). Une seule teinte pleine =
     aucune jointure possible.
     Ne pas la recalculer via color-mix dont la somme des pourcentages est
     < 100 : CSS y applique alors une transparence involontaire. */
  --brand-blue: #0a63d6;

  /* REGLE DU CANEVAS — verifiee sur l'appareil.
     Sous le viewport, iOS ne peint que la COULEUR du canevas : ni image de
     fond, ni contenu ne s'y affichent. --canvas-edge est donc, a tout moment,
     la teinte peinte sur la derniere ligne visible du viewport. Toute vue qui
     change ce qui touche le bas de l'ecran doit redefinir cette variable,
     sinon une bande d'une autre couleur apparait en app installee. */
  --canvas-edge: var(--brand-blue);

  /* Echelle d'interface, mesuree depuis la largeur reelle (cf. layoutShell
     dans app.js). 1 correspond a un ecran de 390 pt. */
  --ui: 1;
  --brand-blue-light: #4fa8ff;
  --gold: #ffd479;
  --gold-dim: rgba(255,212,121,0.5);
  --ring-track: rgba(238,243,255,0.14);
  --glow: rgba(79,168,255,0.55);

  /* Palette de l'application : volontairement FIXE, jamais dérivée du thème
     du téléphone. C'est l'identité sombre validée sur le prototype.
     Auparavant une variante claire s'activait automatiquement sur un appareil
     en mode clair et l'app n'avait plus rien à voir avec la maquette. */
  --paper: #0d1330;
  --paper-card: #161d45;
  --text: #eef3ff;
  --text-dim: rgba(238,243,255,0.6);
  --hairline: rgba(238,243,255,0.12);
}

*{ box-sizing:border-box; }

/* En mode app installée (iOS notamment), la zone située hors de la safe area
   — sous l'indicateur d'accueil — n'est pas peinte par le contenu mais par le
   fond de html/body. On lui donne donc la couleur du bas de la barre de
   navigation pour que la jointure soit invisible. Les deux éléments sont
   ciblés car les versions d'iOS n'utilisent pas toujours le même.
   Cette couleur sert aussi de fond au rebond d'overscroll. */
html,body{
  height:100%;
  margin:0;
  background: var(--canvas-edge);
}
/* Le fond de l'élément racine est le seul à se peindre au-delà du viewport :
   il couvre toute la surface de rendu, y compris la bande que iOS réserve en
   bas en app installée. Aucun autre élément ne peut s'y afficher.

   Pendant le splash, c'est donc lui qui porte le dégradé, dimensionné pour
   déborder de --os-reserved (mesurée dans app.js). Le dégradé se prolonge
   ainsi jusqu'au bas physique de l'écran, sans raccord.
   --os-reserved vaut 0 hors app installée : le rendu est alors identique. */
html.is-splash{
  --canvas-edge: var(--splash-edge);
  background-color: var(--canvas-edge);
  background-image: linear-gradient(180deg,
    var(--splash-top) 0%, var(--splash-mid) 46%, var(--splash-edge) 100%);
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
html.is-splash body{ background: transparent; }
body{
  font-family: ui-rounded, "SF Pro Rounded", "Segoe UI", -apple-system, sans-serif;
  overflow:hidden;
}

/* ---------- Splash ----------------------------------------------------------
   Contrainte de depart, verifiee sur l'appareil : sous le viewport, iOS ne
   peint que la COULEUR du canevas, jamais l'image de fond. Un degrade ne peut
   donc pas s'y prolonger.

   Le fond est par consequent un degrade VERTICAL : chaque ligne y est d'une
   teinte uniforme, et sa derniere ligne vaut exactement --splash-edge, qui est
   aussi la couleur du canevas. La jointure est invisible par construction,
   quelle que soit la hauteur que iOS accorde.

   Corollaire : aucun effet ne doit atteindre le bas de l'ecran, sinon la
   derniere ligne cesse d'etre uniforme. Ils sont tous masques avant.        */

.splash{
  position:fixed;
  inset:0;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  background: transparent; /* le degrade est porte par l'element racine */
  overflow:hidden;
  z-index:100;
  transition: opacity 0.45s ease;
}
.splash.is-hidden{
  opacity:0;
  pointer-events:none;
}

/* --- Ciel : etoiles generees a partir des dimensions reelles (cf. app.js) --- */
.splash__sky{
  position:absolute;
  inset:0;
  pointer-events:none;
  -webkit-mask-image: linear-gradient(180deg,#000 0%,#000 58%,transparent 86%);
  mask-image: linear-gradient(180deg,#000 0%,#000 58%,transparent 86%);
}
.splash__star{
  position:absolute;
  border-radius:50%;
  background: var(--ink);
  animation: twinkle 3.4s ease-in-out infinite;
}
@keyframes twinkle{
  0%,100%{ opacity:0.14; transform:scale(1); }
  50%{ opacity:0.85; transform:scale(1.7); }
}

/* --- Voiles lumineux, dimensionnes par --halo-w / --halo-h (cf. app.js) --- */
.splash__aurora{
  position:absolute;
  inset:0;
  pointer-events:none;
  background:
    radial-gradient(var(--halo-w,60vw) var(--halo-h,40vh) at 20% 16%,
      rgba(79,168,255,0.24), transparent 70%),
    radial-gradient(var(--halo-w,60vw) var(--halo-h,40vh) at 86% 32%,
      rgba(255,212,121,0.12), transparent 70%);
  -webkit-mask-image: linear-gradient(180deg,#000 0%,#000 56%,transparent 84%);
  mask-image: linear-gradient(180deg,#000 0%,#000 56%,transparent 84%);
  animation: aurora 9s ease-in-out infinite alternate;
}
@keyframes aurora{
  from{ transform: translate3d(0,0,0) scale(1); opacity:0.85; }
  to{ transform: translate3d(0,-2.5%,0) scale(1.06); opacity:1; }
}

/* --- Scene : taille derivee du plus petit cote de l'ecran --- */
.splash__stage{
  position:relative;
  width: var(--stage, clamp(180px, 54vmin, 300px));
  height: var(--stage, clamp(180px, 54vmin, 300px));
  display:flex;
  align-items:center;
  justify-content:center;
}

.splash__halo{
  position:absolute;
  inset:-10%;
  border-radius:50%;
  background: radial-gradient(circle, var(--glow) 0%, transparent 68%);
  filter: blur(6px);
  animation: pulse 3.2s ease-in-out infinite;
}
@keyframes pulse{
  0%,100%{ transform:scale(0.92); opacity:0.5; }
  50%{ transform:scale(1.08); opacity:0.85; }
}

/* pathLength="1" rend le trace independant du rayon : l'anneau se boucle
   exactement, quelle que soit la taille de la scene. L'ancienne valeur en
   dur (dasharray 578 -> dashoffset 55) laissait 9,5 % du tour non parcouru. */
.ring{ position:absolute; inset:0; transform: rotate(-90deg); }
.ring circle{ fill:none; stroke-width:1.1; }
.ring .track{ stroke: var(--ring-track); }
.ring .fill{
  stroke: var(--gold);
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: fillring var(--ring-ms, 2300ms) cubic-bezier(.35,0,.15,1) forwards 120ms;
}
@keyframes fillring{ to{ stroke-dashoffset: 0; } }

.badge{
  position:relative;
  width:52%;
  height:52%;
  display:flex;
  align-items:center;
  justify-content:center;
  animation: breathe 3.1s ease-in-out infinite;
}
@keyframes breathe{
  0%,100%{ transform: scale(1) translateY(0); }
  50%{ transform: scale(1.045) translateY(-3px); }
}
.badge img{
  width:100%;
  height:100%;
  object-fit:contain;
  filter: drop-shadow(0 10px 22px rgba(0,0,0,0.35));
}

.splash__wordmark{
  margin-top: clamp(20px, 4.6vh, 44px);
  font-size: clamp(24px, 7.6vmin, 34px);
  font-weight: 800;
  letter-spacing: 0.01em;
  color: var(--ink);
  text-align:center;
  opacity:0;
  animation: rise 0.8s ease forwards 0.5s;
}
.splash__wordmark .dot{ color: var(--gold); }

.splash__tagline{
  margin-top: 8px;
  padding: 0 24px;
  font-size: clamp(12px, 3.4vmin, 14px);
  letter-spacing: 0.06em;
  color: var(--ink-dim);
  text-align:center;
  max-width: min(40ch, 88%);
  opacity:0;
  animation: rise 0.8s ease forwards 0.75s;
}

@keyframes rise{
  from{ opacity:0; transform: translateY(8px); }
  to{ opacity:1; transform: translateY(0); }
}

/* Pied de splash : place par rapport au bas du viewport. La bande que iOS
   reserve en dessous reste vide et de la meme teinte, donc invisible. */
.splash__footer{
  position:absolute;
  left:0; right:0;
  bottom: max(20px, 3.6vh);
  text-align:center;
}
.splash__status{
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-dim);
  opacity:0;
  animation: rise 0.6s ease forwards 1s;
}
.splash__status .dots span{ display:inline-block; animation: blink 1.4s infinite; }
.splash__status .dots span:nth-child(2){ animation-delay:0.2s; }
.splash__status .dots span:nth-child(3){ animation-delay:0.4s; }
@keyframes blink{
  0%,80%,100%{ opacity:0.25; }
  40%{ opacity:1; }
}
.splash__byline{
  margin-top: 14px;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
  opacity:0;
  animation: rise 0.6s ease forwards 1.15s;
}

@media (prefers-reduced-motion: reduce){
  .splash__star, .splash__halo, .splash__aurora, .badge, .ring .fill,
  .splash__wordmark, .splash__tagline, .splash__status, .splash__byline,
  .splash__status .dots span{
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
  .ring .fill{ stroke-dashoffset: 0; }
  .splash__wordmark, .splash__tagline, .splash__status, .splash__byline{
    opacity:1; transform:none;
  }
}

/* ---------- App shell ---------- */
/* inset:0 seul suffit et garantit exactement la zone visible.
   Ne PAS ajouter de height explicite ici : elle écraserait la contrainte
   bottom:0 et laisserait un vide sous la barre en mode app installée. */
/* La coquille tient STRICTEMENT dans le viewport. La zone que iOS laisse
   sous le viewport (barre d'accueil) ne peut pas recevoir de contenu : seul
   le fond de l'élément racine s'y peint. Toute tentative de l'étirer y pousse
   les libellés hors de la zone affichable. */
.app-shell{
  position:fixed;
  inset:0;
  display:flex;
  flex-direction:column;
  background: var(--paper);
  animation: rise 0.5s ease;
}
.app-shell[hidden]{ display:none; }

.app-header{
  flex: 0 0 auto;
  display:flex;
  align-items:center;
  gap:10px;
  padding: max(calc(14px * var(--ui)), env(safe-area-inset-top))
           calc(18px * var(--ui)) calc(14px * var(--ui));
  background: var(--brand-blue);
  color:#fff;
  overflow:hidden;
}
.app-header__mark{
  width: calc(26px * var(--ui));
  height: calc(26px * var(--ui));
  object-fit:contain;
  flex:0 0 auto;
}
.app-header__title{
  flex:1 1 auto;
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
  font-size: calc(18px * var(--ui));
  font-weight:800;
  letter-spacing:0.01em;
}

.install-header-btn{
  flex:0 0 auto;
  display:flex;
  align-items:center;
  gap:6px;
  padding:7px 12px;
  border-radius:999px;
  border:1px solid rgba(255,255,255,0.35);
  background: rgba(255,255,255,0.12);
  color:#fff;
  font-family:inherit;
  font-size:12px;
  font-weight:700;
  white-space:nowrap;
  cursor:pointer;
}
.install-header-btn[hidden]{ display:none; }
.install-header-btn svg{ width:16px; height:16px; flex:0 0 auto; }
.install-header-btn:active{ background: rgba(255,255,255,0.22); }
.install-header-btn:focus-visible{
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.install-tip{
  display:flex;
  align-items:flex-start;
  gap:10px;
  padding:10px 14px;
  background: color-mix(in srgb, var(--brand-blue) 12%, transparent);
  border-bottom:1px solid var(--hairline);
}
.install-tip[hidden]{ display:none; }
.install-tip p{
  flex:1 1 auto;
  margin:0;
  font-size:12.5px;
  line-height:1.4;
  color: var(--text);
}
.install-tip button{
  flex:0 0 auto;
  border:none;
  background:none;
  color: var(--text-dim);
  font-size:18px;
  line-height:1;
  cursor:pointer;
  padding:0;
}

.app-content{
  flex:1 1 auto;
  overflow:hidden;
  position:relative;
}

.panel{
  display:none;
  height:100%;
  padding: calc(20px * var(--ui)) calc(18px * var(--ui)) calc(32px * var(--ui));
  overflow-y:auto;
  -webkit-overflow-scrolling:touch;
}
.panel--active{ display:block; }

.radio-panel{
  position:relative;
  overflow:hidden;
  padding:0;
}

.placeholder{
  height:100%;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  text-align:center;
  gap:8px;
  color: var(--text-dim);
}
.placeholder__glyph{ font-size:40px; margin-bottom:6px; opacity:0.8; }
.placeholder__title{
  font-size:16px;
  font-weight:700;
  color: var(--text);
  margin:0;
}
.placeholder__text{ font-size:13px; margin:0; max-width:240px; }

.reseaux__intro{
  font-size:14px;
  color: var(--text-dim);
  margin: 4px 0 18px;
}

/* ---------- Accueil ---------- */
.home{
  display:flex;
  flex-direction:column;
  gap:16px;
}

.home__eyebrow{
  margin:0 0 2px;
  font-size:11.5px;
  font-weight:700;
  letter-spacing:0.1em;
  text-transform:uppercase;
  color: var(--text-dim);
}
.home__hello{
  margin:0;
  font-size:26px;
  font-weight:800;
  color: var(--text);
}

.home__weather{
  margin:6px 0 0;
  font-size:13.5px;
  color: var(--text-dim);
}
.home__weather strong{
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.card{
  background: var(--paper-card);
  border:1px solid var(--hairline);
  border-radius:16px;
  padding:16px;
}

.home__quick{
  display:grid;
  grid-template-columns: 1fr 1fr;
  gap:10px;
}
.quick-card{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:10px;
  padding:14px;
  border-radius:16px;
  background: var(--paper-card);
  border:1px solid var(--hairline);
  font-family:inherit;
  text-align:left;
  cursor:pointer;
  transition: transform 0.15s ease;
}
.quick-card:active{ transform: scale(0.97); }
.quick-card:focus-visible{
  outline: 2px solid var(--brand-blue-light);
  outline-offset: 2px;
}
.quick-card__icon{
  width:36px; height:36px;
  border-radius:11px;
  display:flex;
  align-items:center;
  justify-content:center;
  color:#fff;
}
.quick-card__icon svg{ width:19px; height:19px; }
.quick-card__logo{ width:22px; height:22px; object-fit:contain; }
.quick-card__icon--attractions{ background: var(--brand-blue); }
.quick-card__icon--radio{ background:#8a6bff; }
.quick-card__icon--reseaux{ background:#fff; }
.quick-card__label{
  font-size:13.5px;
  font-weight:700;
  color: var(--text);
}

.home__spotlight-eyebrow{
  margin:0 0 6px;
  font-size:11px;
  font-weight:700;
  letter-spacing:0.08em;
  text-transform:uppercase;
  color: var(--gold-dim);
}
.home__spotlight-text{
  margin:0;
  font-size:13.5px;
  line-height:1.5;
  color: var(--text-dim);
}

.home__hours-title{
  margin:0 0 12px;
  font-size:14.5px;
  font-weight:700;
  color: var(--text);
}
.hours-row{
  display:flex;
  gap:10px;
}
.hours-loading{
  margin:0;
  font-size:12.5px;
  color: var(--text-dim);
}
.hours-park{
  flex:1 1 0;
  padding:10px;
  border-radius:12px;
  background: color-mix(in srgb, var(--brand-blue) 8%, transparent);
  min-width:0;
}
.hours-park__name{
  margin:0 0 4px;
  font-size:11.5px;
  font-weight:700;
  color: var(--text-dim);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}
.hours-park__time{
  margin:0;
  font-size:14px;
  font-weight:700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.hours-park__emh{
  margin:2px 0 0;
  font-size:10.5px;
  color: var(--gold-dim);
}

/* ---------- Attractions ---------- */
.attractions__updated{
  margin:0 0 14px;
  font-size:11.5px;
  color: var(--text-dim);
}

.attractions__segments{
  display:flex;
  gap:4px;
  padding:4px;
  border-radius:14px;
  background: var(--paper-card);
  border:1px solid var(--hairline);
  margin-bottom:14px;
}
.segment{
  flex:1 1 0;
  padding:9px 4px;
  border-radius:10px;
  border:none;
  background:transparent;
  color: var(--text-dim);
  font-family:inherit;
  font-size:12.5px;
  font-weight:700;
  cursor:pointer;
}
.segment.is-active{
  background: var(--brand-blue);
  color:#fff;
}
.segment:focus-visible{
  outline: 2px solid var(--brand-blue-light);
  outline-offset: 2px;
}

ul.category-view{ display:none; }
ul.category-view.is-active{ display:flex; }

.attractions__filters{
  display:flex;
  gap:8px;
  overflow-x:auto;
  padding-bottom:4px;
  margin-bottom:14px;
}
.attractions__filters::-webkit-scrollbar{ display:none; }
.filter-chip{
  flex:0 0 auto;
  padding:7px 14px;
  border-radius:999px;
  border:1px solid var(--hairline);
  background: var(--paper-card);
  color: var(--text-dim);
  font-family:inherit;
  font-size:12.5px;
  font-weight:600;
  white-space:nowrap;
  cursor:pointer;
}
.filter-chip.is-active{
  background: var(--brand-blue);
  border-color: var(--brand-blue);
  color:#fff;
}
.filter-chip:focus-visible{
  outline: 2px solid var(--brand-blue-light);
  outline-offset: 2px;
}

.attraction-list{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:10px;
}
.attractions__loading{
  list-style:none;
  padding:24px 0;
  text-align:center;
  font-size:13px;
  color: var(--text-dim);
}
.attraction-card{
  display:flex;
  align-items:center;
  gap:12px;
  padding:14px;
  border-radius:16px;
  background: var(--paper-card);
  border:1px solid var(--hairline);
}
.attraction-card__icon{
  flex:0 0 auto;
  width: calc(38px * var(--ui));
  height: calc(38px * var(--ui));
  border-radius: calc(11px * var(--ui));
  display:flex;
  align-items:center;
  justify-content:center;
  font-size: calc(19px * var(--ui));
  background: rgba(10,99,214,0.10);
  overflow:hidden; /* pour la variante image */
}
/* Visuel photo : remplit la pastille sans deformer, quel que soit le cadrage
   de la source. Les attractions sans image gardent l'emoji. */
.attraction-card__icon img{
  width:100%;
  height:100%;
  object-fit:cover;
  display:block;
}
.attraction-card__body{
  flex:1 1 auto;
  min-width:0;
}
.attraction-card__name{
  margin:0 0 3px;
  font-size:14px;
  font-weight:700;
  color: var(--text);
}
.attraction-card__land{
  margin:0;
  font-size:11.5px;
  color: var(--text-dim);
}

.attraction-card--times{
  align-items:flex-start;
}
.time-chips{
  display:flex;
  flex-wrap:wrap;
  gap:6px;
  margin-top:8px;
}
.time-chip{
  padding:4px 9px;
  border-radius:999px;
  font-size:11.5px;
  font-weight:700;
  font-variant-numeric: tabular-nums;
}
.time-chip--past{
  background: var(--hairline);
  color: var(--text-dim);
}
/* Teintes lisibles sur fond sombre (palette fixe, cf. :root). */
.time-chip--upcoming{
  background: rgba(255,180,64,0.18);
  color:#ffc267;
}
.time-chip--live{
  background: rgba(111,207,143,0.18);
  color:#7fe0a3;
}
.attraction-card__bell{
  flex:0 0 auto;
  width:32px; height:32px;
  border-radius:50%;
  border:1px solid var(--hairline);
  background: transparent;
  color: var(--text-dim);
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
}
.attraction-card__bell svg{ width:16px; height:16px; }
.attraction-card__bell.is-watching{
  background: color-mix(in srgb, var(--gold) 22%, transparent);
  border-color: var(--gold-dim);
  color: var(--gold-dim);
}
.attraction-card__bell:focus-visible{
  outline: 2px solid var(--brand-blue-light);
  outline-offset: 2px;
}

.wait-pill{
  flex:0 0 auto;
  padding:6px 12px;
  border-radius:999px;
  font-size:12.5px;
  font-weight:700;
  white-space:nowrap;
}
/* Teintes lisibles sur fond sombre (palette fixe, cf. :root). */
.wait-pill--low{ background: rgba(111,207,143,0.18); color:#7fe0a3; }
.wait-pill--mid{ background: rgba(255,180,64,0.18); color:#ffc267; }
.wait-pill--high{ background: rgba(224,100,95,0.18); color:#ff9d97; }
.wait-pill--closed{ background: var(--hairline); color: var(--text-dim); }

.attractions__disclaimer{
  margin:16px 0 0;
  font-size:11px;
  color: var(--text-dim);
  text-align:center;
}


.social-list{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:10px;
}

.social-card__link{
  display:flex;
  align-items:center;
  gap:12px;
  padding:14px;
  border-radius:16px;
  background: var(--paper-card);
  border:1px solid var(--hairline);
  text-decoration:none;
  color:inherit;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.social-card__link:active{ transform: scale(0.98); }
.social-card__link:focus-visible{
  outline: 2px solid var(--brand-blue-light);
  outline-offset: 2px;
}

.social-card__icon{
  flex: 0 0 auto;
  width:38px; height:38px;
  border-radius:11px;
  display:flex;
  align-items:center;
  justify-content:center;
  color:#fff;
}
.social-card__icon svg{ width:20px; height:20px; }
.social-card__icon--instagram{ background: linear-gradient(135deg,#f5c04a,#e0507a,#7b4ad1); }
.social-card__icon--tiktok{ background:#0d1521; }
.social-card__icon--facebook{ background:#1877f2; }
.social-card__icon--youtube{ background:#ff0000; }
.social-card__icon--discord{ background:#5865f2; }

.social-card__body{
  flex:1 1 auto;
  display:flex;
  flex-direction:column;
  gap:2px;
  min-width:0;
}
.social-card__name{ font-size:14.5px; font-weight:700; color: var(--text); }
.social-card__handle{ font-size:12.5px; color: var(--text-dim); }

.social-card__chevron{
  flex:0 0 auto;
  font-size:20px;
  color: var(--text-dim);
}

.reseaux__note{
  margin-top:18px;
  font-size:11.5px;
  color: var(--text-dim);
  text-align:center;
}

.radio{
  position:relative;
  z-index:1;
  height:100%;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:14px;
  text-align:center;
  padding:20px 18px 32px;
}

.radio__blobs{ position:absolute; inset:0; overflow:hidden; pointer-events:none; }
.radio__blob{
  position:absolute;
  width:260px;
  height:260px;
  border-radius:50%;
  filter: blur(36px);
  opacity:0.45;
  animation: radio-blob-drift 9s ease-in-out infinite;
}
.radio__blob--blue{
  top:-50px; left:-70px;
  background: var(--brand-blue-light);
  animation-duration: 10s;
}
.radio__blob--gold{
  bottom:-70px; right:-50px;
  background: var(--gold);
  opacity:0.3;
  animation-duration: 8s;
  animation-delay: -2s;
}
.radio__blob--violet{
  top:35%; right:-90px;
  width:220px; height:220px;
  background: #8a6bff;
  opacity:0.35;
  animation-duration: 11s;
  animation-delay: -5s;
}
.radio__blob--pink{
  bottom:20%; left:-80px;
  width:200px; height:200px;
  background: #ff6fae;
  opacity:0.28;
  animation-duration: 12.5s;
  animation-delay: -7s;
}
@keyframes radio-blob-drift{
  0%,100%{ transform: translate(0,0) scale(1); }
  25%{ transform: translate(36px,-30px) scale(1.22); }
  50%{ transform: translate(-10px,22px) scale(0.88); }
  75%{ transform: translate(-32px,-18px) scale(1.1); }
}

.radio__stars{ position:absolute; inset:0; pointer-events:none; }
.radio__stars span{
  position:absolute;
  width:2px; height:2px;
  border-radius:50%;
  background: var(--text);
  opacity:0.5;
  animation: radio-twinkle 3s ease-in-out infinite;
}
@keyframes radio-twinkle{
  0%,100%{ opacity:0.12; transform:scale(1); }
  50%{ opacity:0.8; transform:scale(1.6); }
}

.radio__badge{
  position:relative;
  z-index:1;
  width:240px;
  max-width:80%;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:20px 0;
}
.radio__badge img{
  width:100%;
  height:auto;
  object-fit:contain;
  filter: drop-shadow(0 12px 24px rgba(0,0,0,0.35));
  position:relative;
  z-index:1;
}
.radio__ring{
  position:absolute;
  inset:0;
  border-radius:50%;
  background: radial-gradient(ellipse 70% 60% at center, var(--glow) 0%, transparent 70%);
  filter: blur(6px);
  opacity:0;
  transform:scale(0.9);
}
.radio__badge.is-live .radio__ring{
  animation: radio-pulse 2.2s ease-out infinite;
}
@keyframes radio-pulse{
  0%{ opacity:0.5; transform:scale(0.9); }
  100%{ opacity:0; transform:scale(1.15); }
}

.radio__eq{
  position:relative;
  z-index:1;
  display:flex;
  align-items:flex-end;
  justify-content:center;
  gap:4px;
  height:20px;
  opacity:0;
  transition: opacity 0.3s ease;
}
.radio__eq.is-live{ opacity:1; }
.radio__eq span{
  width:3px;
  height:100%;
  border-radius:2px;
  background: var(--gold);
  transform-origin: bottom center;
  animation: radio-eq-bar 1.2s ease-in-out infinite;
  animation-play-state: paused;
}
.radio__eq.is-live span{ animation-play-state: running; }
.radio__eq span:nth-child(1){ animation-duration:0.8s; animation-delay:-0.6s; }
.radio__eq span:nth-child(2){ animation-duration:1.1s; animation-delay:-0.2s; }
.radio__eq span:nth-child(3){ animation-duration:0.7s; animation-delay:-0.9s; }
.radio__eq span:nth-child(4){ animation-duration:1s; animation-delay:-0.4s; }
.radio__eq span:nth-child(5){ animation-duration:0.9s; animation-delay:-0.1s; }
@keyframes radio-eq-bar{
  0%,100%{ transform: scaleY(0.25); }
  50%{ transform: scaleY(1); }
}

@media (prefers-reduced-motion: reduce){
  .radio__stars span, .radio__eq span, .radio__badge.is-live .radio__ring, .radio__blob{
    animation: none !important;
  }
}

.radio__status{
  margin:0;
  font-size:11.5px;
  font-weight:700;
  letter-spacing:0.12em;
  text-transform:uppercase;
  color: var(--text-dim);
}
.radio__status.is-live{ color:#e0645f; }
.radio__status.is-live::before{
  content:"";
  display:inline-block;
  width:6px; height:6px;
  border-radius:50%;
  background:#e0645f;
  margin-right:6px;
  vertical-align:middle;
}

.radio__title{
  margin:0;
  max-width:280px;
  font-size:14.5px;
  font-weight:600;
  color: var(--text);
  min-height:20px;
  opacity:0;
  transform: translateY(4px);
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.radio__title.is-updating{
  opacity:1;
  transform: translateY(0);
}

.radio__play{
  width:64px; height:64px;
  border-radius:50%;
  border:none;
  background: var(--brand-blue);
  color:#fff;
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
  box-shadow: 0 12px 24px -8px rgba(10,99,214,0.55);
}
.radio__play svg{ width:26px; height:26px; }
.radio__play svg.is-hidden{ display:none; }
.radio__play:active{ transform: scale(0.96); }
.radio__play:focus-visible{
  outline: 2px solid var(--brand-blue-light);
  outline-offset: 3px;
}

.radio__volume{
  display:flex;
  align-items:center;
  gap:8px;
  width:200px;
  color: var(--text-dim);
}
.radio__volume svg{ width:18px; height:18px; flex:0 0 auto; }
.radio__volume input[type="range"]{
  flex:1 1 auto;
  accent-color: var(--brand-blue);
}

/* Conteneur transparent : les coins arrondis et l'encoche du logo laissent
   voir le contenu derrière. La zone système sous la barre est couverte par
   le fond de html/body, de même couleur que la surface. */
.tab-bar{
  position:relative;
  flex:0 0 auto;
  padding-top: calc(22px * var(--ui));
  background: transparent;
}

.tab-bar__surface{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:6px;
  /* --safe-bottom est mesuré à l'exécution (cf. applySafeBottom dans app.js)
     car iOS renvoie env(safe-area-inset-bottom)=0 en mode app installée. */
  padding: 10px 18px max(10px, var(--safe-bottom, env(safe-area-inset-bottom)));
  background: var(--brand-blue);
  border-radius: calc(28px * var(--ui)) calc(28px * var(--ui)) 0 0;
  box-shadow: 0 -8px 24px -12px rgba(10,20,60,0.35);
  /* l'encoche suit la taille du bouton central */
  -webkit-mask-image: radial-gradient(circle calc(34px * var(--ui)) at 50% 0px, transparent 99%, black 100%);
  mask-image: radial-gradient(circle calc(34px * var(--ui)) at 50% 0px, transparent 99%, black 100%);
}

.tab-bar__side{
  display:flex;
  flex:1 1 0;
  justify-content:space-evenly;
  gap:6px;
}

.tab-bar__item{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:4px;
  padding:3px 4px;
  background:none;
  border:none;
  font-family:inherit;
  font-size: calc(10.5px * var(--ui));
  font-weight:600;
  color: rgba(255,255,255,0.55);
  cursor:pointer;
  transition: color 0.15s ease;
}
.tab-bar__item svg{ width: calc(22px * var(--ui)); height: calc(22px * var(--ui)); }
.tab-bar__item[aria-current="true"]{ color:#fff; }
.tab-bar__item:focus-visible{
  outline: 2px solid #fff;
  outline-offset: 2px;
  border-radius:8px;
}

.tab-bar__center{
  position:absolute;
  left:50%;
  top: calc(-10px * var(--ui));
  transform: translateX(-50%);
  width: calc(60px * var(--ui));
  height: calc(60px * var(--ui));
  padding:0;
  border-radius:50%;
  background: var(--paper-card);
  border:none;
  display:flex;
  align-items:center;
  justify-content:center;
  box-shadow: 0 10px 18px -6px rgba(10,20,60,0.45);
  cursor:pointer;
  animation: tab-bar-float 3.6s ease-in-out infinite;
}
.tab-bar__center:active{ transform: translateX(-50%) scale(0.94); animation-play-state:paused; }
.tab-bar__center img{
  width: calc(30px * var(--ui));
  height: calc(30px * var(--ui));
  object-fit:contain;
}
.tab-bar__center:focus-visible{
  outline: 2px solid var(--brand-blue-light);
  outline-offset: 3px;
}
@keyframes tab-bar-float{
  0%,100%{ transform: translateX(-50%) translateY(0); }
  50%{ transform: translateX(-50%) translateY(-3px); }
}
@media (prefers-reduced-motion: reduce){
  .tab-bar__center{ animation:none; }
}


/* ---- Relevé d'affichage (temporaire) --------------------------------------
   Affiché dans l'onglet Profil pour caler la mise en page sur l'appareil réel
   plutôt que de la déduire de captures d'écran. À supprimer ensuite. */
.diag{
  margin: 12px 0 0;
  padding: 14px 16px;
  border-radius: 16px;
  background: var(--paper-card);
  border: 1px solid var(--hairline);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  line-height: 1.75;
  color: var(--text);
}
.diag h3{
  margin: 0 0 8px;
  font-family: inherit;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.diag__row{ display:flex; justify-content:space-between; gap:12px; }
.diag__row span:first-child{ color: var(--text-dim); }
.diag__row span:last-child{ font-weight:600; }
.diag__row--key span:last-child{ color:#ffd166; }
