/* ==========================================================
   Logo sly.codes dans l'en-tête
   (PNG noir sur transparent : inversé en blanc sur le thème sombre)
   ========================================================== */
.brand { display: flex; align-items: center; gap: 10px; }
.brand__logo {
  width: 24px;
  height: 24px;
  transition: transform 0.6s var(--ease);
}
:root:not([data-theme="light"]) .brand__logo:not(.brand__logo--keep) { filter: invert(1); }
.brand__logo { object-fit: contain; } /* un logo envoyé depuis la console peut avoir un autre format */
.brand:hover .brand__logo { transform: rotate(90deg); } /* le losange pivote d'un quart de tour */

/* ==========================================================
   Statut en direct (pulse.js) : connecting / online / offline
   ========================================================== */
.status { cursor: help; }
.status__host { color: var(--text-faint); transition: color 0.2s; }
.status__host:hover { color: var(--text); }
/* connexion : point pâle qui pulse */
.status[data-state="connecting"] .status__dot,
.status[data-state="connecting"] .status__dot::after { background: var(--text-faint); }
/* hors ligne : point creux, sans halo */
.status[data-state="offline"] .status__dot { background: transparent; box-shadow: inset 0 0 0 1px var(--text-faint); }
.status[data-state="offline"] .status__dot::after { display: none; }
.status[data-state="offline"] #latency { text-decoration: line-through; }
@media (max-width: 520px) { .status__host { display: none; } }

/* ==========================================================
   Multilingue : sélecteur en / fr + fondu au changement de langue
   ========================================================== */
.lang-btn [data-l] { color: var(--text-faint); transition: color 0.25s; }
.lang-btn { color: var(--text-faint); }
html[lang="en"] .lang-btn [data-l="en"],
html[lang="fr"] .lang-btn [data-l="fr"] { color: var(--text); }

/* "to" explicite + fill "both" : l'élément reste visible même s'il avait
   aussi l'animation d'apparition (.reveal part d'une opacité 0) */
.i18n-swap { animation: i18nSwap 0.45s var(--ease) both; animation-delay: var(--i18n-d, 0ms); }
@keyframes i18nSwap {
  from { opacity: 0; filter: blur(3px); transform: translateY(3px); }
  to   { opacity: 1; filter: none; transform: none; }
}

/* ==========================================================
   Icônes, outils d'en-tête et réseaux sociaux
   ========================================================== */
.icon { width: 15px; height: 15px; flex-shrink: 0; }

.head__tools { display: flex; align-items: center; gap: 14px; }
.head__tools kbd { cursor: pointer; }

.socials { gap: 8px 22px; }
.social { display: inline-flex; align-items: center; gap: 8px; }
.social .icon { color: var(--text-faint); transition: color 0.25s, transform 0.35s var(--ease); }
.social:hover .icon { color: var(--accent); transform: translateY(-2px) rotate(-6deg); }
.social:hover .link { background-size: 100% 1px; }

/* ==========================================================
   Ancres de la palette : où la page s'arrête + signal d'arrivée
   ========================================================== */
.block, .proj { scroll-margin-top: 18vh; } /* la section s'arrête à ~1/5 de l'écran, pas collée en haut */

.block.atteint .label,
.proj.atteint .proj__name { animation: atteint 1.6s var(--ease); }
@keyframes atteint {
  0%, 30% { color: var(--accent); letter-spacing: 0.04em; }
  100%    { letter-spacing: normal; }
}

/* ==========================================================
   Palette ctrl+K
   États (data-state) : pre -> backdrop -> open -> closing
   ========================================================== */
.cmdk {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 14vh 16px 16px;
}
.cmdk[hidden] { display: none; }

.cmdk__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}
:root[data-theme="light"] .cmdk__backdrop { background: rgba(240, 240, 236, 0.6); }
.cmdk[data-state="backdrop"] .cmdk__backdrop,
.cmdk[data-state="open"] .cmdk__backdrop { opacity: 1; }
.cmdk[data-state="closing"] .cmdk__backdrop { opacity: 0; transition-duration: 0.22s; }

.cmdk__fx { position: fixed; inset: 0; pointer-events: none; z-index: 1; }
.cmdk__fx canvas { display: block; }

.cmdk__frame { position: relative; z-index: 2; width: 100%; max-width: 600px; }

.cmdk__box {
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.45);
  clip-path: inset(50% 50% 50% 50% round 5px); /* invisible avant l'ouverture */
}
.cmdk[data-state="open"] .cmdk__box { animation: materialiser 0.5s var(--ease) forwards; }
.cmdk[data-state="closing"] .cmdk__box { animation: replier 0.22s ease-in forwards; }

/* une ligne au centre -> s'étire en largeur -> s'ouvre en hauteur */
@keyframes materialiser {
  0%   { clip-path: inset(calc(50% - 1px) 50% calc(50% - 1px) 50% round 5px); }
  35%  { clip-path: inset(calc(50% - 1px) 0 calc(50% - 1px) 0 round 5px); }
  100% { clip-path: inset(0 0 0 0 round 5px); }
}
@keyframes replier {
  0%   { clip-path: inset(0 0 0 0 round 5px); opacity: 1; }
  60%  { clip-path: inset(calc(50% - 1px) 0 calc(50% - 1px) 0 round 5px); opacity: 1; }
  100% { clip-path: inset(calc(50% - 1px) 50% calc(50% - 1px) 50% round 5px); opacity: 0; }
}

/* deux traits lumineux qui partent du centre, vers le haut et vers le bas */
.cmdk__scan {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 3;
  height: 1px;
  top: 50%;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  box-shadow: 0 0 12px var(--accent);
  opacity: 0;
  pointer-events: none;
}
.cmdk[data-state="open"] .cmdk__scan--up { animation: balayerHaut 0.5s var(--ease) forwards; }
.cmdk[data-state="open"] .cmdk__scan--down { animation: balayerBas 0.5s var(--ease) forwards; }
@keyframes balayerHaut {
  0%   { top: 50%; transform: scaleX(0); opacity: 1; }
  35%  { top: 50%; transform: scaleX(1); opacity: 1; }
  100% { top: 0; opacity: 0; }
}
@keyframes balayerBas {
  0%   { top: 50%; transform: scaleX(0); opacity: 1; }
  35%  { top: 50%; transform: scaleX(1); opacity: 1; }
  100% { top: 100%; opacity: 0; }
}

/* Barre de recherche */
.cmdk__search {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 16px;
  border-bottom: 1px solid var(--border);
  color: var(--text-faint);
}
.cmdk__search input {
  flex: 1;
  min-width: 0;
  padding: 18px 0;
  border: none;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 15px;
  outline: none;
  caret-color: var(--accent);
}
.cmdk__search input::placeholder { color: var(--text-faint); }

/* Liste */
.cmdk__list {
  position: relative;
  max-height: min(380px, 52vh);
  overflow-y: auto;
  padding: 6px;
}
.cmdk__items { position: relative; }

/* surlignage qui glisse d'un élément à l'autre */
.cmdk__hl {
  position: absolute;
  left: 6px;
  right: 6px;
  top: 6px;
  border-radius: 5px;
  background: var(--surface);
  transition: transform 0.18s var(--ease), height 0.18s var(--ease), opacity 0.15s;
  pointer-events: none;
}

.cmdk__group {
  padding: 10px 10px 4px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-faint);
  letter-spacing: 0.04em;
}
.cmdk__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 10px;
  border-radius: 5px;
  color: var(--text-dim);
  cursor: pointer;
  transition: color 0.15s;
}
.cmdk__item[aria-selected="true"] { color: var(--text); }
.cmdk__icon {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 1px solid var(--border);
  border-radius: 5px;
  color: var(--text-faint);
  transition: color 0.15s, border-color 0.15s;
}
.cmdk__icon .icon { width: 13px; height: 13px; }
.cmdk__item[aria-selected="true"] .cmdk__icon { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); }
.cmdk__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmdk__label mark { background: none; color: var(--accent); font-weight: 500; }
.cmdk__hint { max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono); font-size: 11px; color: var(--text-faint); }
.cmdk__tag { padding: 1px 6px; border: 1px solid var(--border); border-radius: 5px; font-family: var(--mono); font-size: 10px; color: var(--text-faint); }
.cmdk__empty { padding: 28px 10px; text-align: center; color: var(--text-faint); }
.cmdk__empty b { color: var(--text-dim); font-weight: 500; }

/* arrivée en cascade des résultats (réutilise l'animation "arrive" de style.css) */
.cmdk__item.arrive, .cmdk__group.arrive {
  opacity: 0;
  animation: arrive 0.45s var(--ease) forwards;
  animation-delay: var(--d);
}

.cmdk__foot {
  display: flex;
  justify-content: space-between;
  padding: 10px 16px;
  border-top: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-faint);
}
.cmdk__foot kbd { margin-right: 2px; }

/* ==========================================================
   Toast "email copied"
   ========================================================== */
.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  z-index: 300;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--surface);
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text);
  opacity: 0;
  transform: translate(-50%, 12px) scale(0.96);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
  pointer-events: none;
}
.toast .icon { width: 14px; height: 14px; color: var(--accent); }
.toast.visible { opacity: 1; transform: translate(-50%, 0) scale(1); }

@media (max-width: 520px) {
  .cmdk { padding-top: 8vh; }
  .cmdk__hint, .cmdk__foot span:first-child { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .i18n-swap { animation: none; }
  .cmdk__box { clip-path: none !important; animation: none !important; }
  .cmdk__scan { display: none; }
  .cmdk__hl { transition: none; }
}

/* Safari iOS zoome sur un champ dont le texte fait moins de 16px :
   sur écran tactile, les champs passent à 16px (le zoom de la page reste possible). */
@media (hover: none) and (pointer: coarse) {
  input, textarea, select { font-size: 16px !important; }
}
