/* Yurei Studio — page d'attente.
   Tokens sémantiques, light + dark. Grille 4px stricte. Zéro JS. */

@font-face {
  font-family: "Geist";
  src: url("/fonts/geist-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Geist";
  src: url("/fonts/geist-medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #f7f7f8;

  --text-primary: #0a0a0a;
  --text-secondary: #62626a;

  --border: rgba(10, 10, 10, 0.16);

  --focus: #0a0a0a;

  /* Accent — une seule fonction déclarée dans tout le produit : signaler que
     ce site est dans un état transitoire et actif. Il n'apparaît nulle part
     ailleurs. Ambre et non vert : le message est « en cours », pas « en
     ligne » — un vert lirait « opérationnel », ce qui n'est pas ce qu'on dit. */
  --accent-text: #92400e;
  --accent-dot: #d97706;
  --accent-surface: rgba(180, 83, 9, 0.08);
  --accent-border: rgba(180, 83, 9, 0.22);

  --font-sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;

    --text-primary: #fafafa;
    --text-secondary: #8f8f96;

    --border: rgba(255, 255, 255, 0.18);

    --focus: #fafafa;

    --accent-text: #fbbf24;
    --accent-dot: #f59e0b;
    --accent-surface: rgba(251, 191, 36, 0.10);
    --accent-border: rgba(251, 191, 36, 0.24);

    color-scheme: dark;
  }
}

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100svh;
  background: var(--bg);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.page {
  min-height: 100svh;
  display: flex;
  padding: 64px 24px;
}

/* `margin: auto` plutôt que `align-items: center` : sur un viewport court, un
   flex item centré par align-items déborde par le HAUT et devient inatteignable
   au scroll. Les marges auto centrent sans jamais rogner. */
.layout {
  width: 100%;
  max-width: 640px;
  margin: auto;
}

@media (min-width: 900px) {
  .page { padding: 96px 64px; }
}

/* — Identité —————————————————————————————————— */

.wordmark {
  margin: 0 0 48px;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--text-secondary);
}

/* — Statut ——————————————————————————————————— */

/* Le seul élément coloré de la page, et le seul animé. Pill compacte : c'est
   un état, pas un titre — il se lit d'un coup d'œil sans prendre la place du
   hero. */
.status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 32px;
  padding: 0 12px;
  min-height: 32px;
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  background: var(--accent-surface);
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  color: var(--accent-text);
}

.status__dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent-dot);
  animation: pulse 2000ms cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* Battement lent, sans halo ni clignotement : `transform` et `opacity`
   uniquement (compositées, aucun reflow), amplitude volontairement courte —
   la pastille doit avoir l'air vivante, pas alerter. */
@keyframes pulse {
  0%, 100% { opacity: 1;    transform: scale(1); }
  50%      { opacity: 0.42; transform: scale(0.82); }
}

/* — Hero ————————————————————————————————————— */

.title {
  margin: 0 0 24px;
  font-size: 32px;
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

@media (min-width: 640px) {
  .title { font-size: 48px; }
}

/* `balance` plutôt que `pretty` : mesuré sur ce texte, en colonne mobile
   `pretty` laisse un orphelin de neuf caractères sur la dernière ligne là où
   `balance` répartit. En colonne desktop les deux rendent le même découpage :
   le gain est gratuit. */
.lede {
  margin: 0 0 16px;
  font-size: 20px;
  line-height: 1.45;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

/* `pretty` et non `balance` ici : ce paragraphe dépasse six lignes en colonne
   étroite, seuil au-delà duquel Chrome cesse d'appliquer `balance` sans rien
   dire. Un rendu qui change de comportement selon la largeur est pire qu'un
   rendu constant. */
.body {
  margin: 0 0 48px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-secondary);
  text-wrap: pretty;
}

/* — Bloc secondaire ——————————————————————————— */

/* Décrochement éditorial : le bloc d'état et de contact recule d'un cran par
   rapport au hero, la note personnelle d'un cran de plus. Les deux retraits
   sont sur l'échelle (48 et 96) et ne s'appliquent qu'à partir de 900px —
   en dessous, l'escalier mangerait la largeur de lecture. */
.aside { margin: 0 0 64px; }

.rebuild {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.contact { margin: 24px 0 0; }
.contact--secondary { margin-top: 12px; }

/* Un seul composant de lien, deux tailles : l'email mène la hiérarchie du
   contact, LinkedIn se range dessous. Pas de bouton — le brief demande un
   contact facile à trouver, pas un CTA qui prend la page. */
.link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 500;
  color: var(--text-secondary);
  text-decoration: none;
  transition: color 150ms cubic-bezier(0.2, 0, 0, 1);
}

.link--lead {
  font-size: 20px;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}

.link__label {
  border-bottom: 1px solid transparent;
  transition: border-color 150ms cubic-bezier(0.2, 0, 0, 1);
}

.link__arrow {
  flex: none;
  transition: transform 150ms cubic-bezier(0.2, 0, 0, 1);
}

.link:hover { color: var(--text-primary); }
.link:hover .link__label { border-bottom-color: currentColor; }
.link:hover .link__arrow { transform: translate(3px, 0); }
.link:active { opacity: 0.7; }

.link:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 4px;
  border-radius: 4px;
}

.location {
  margin: 24px 0 0;
  font-size: 14px;
  color: var(--text-secondary);
}

/* — Note personnelle —————————————————————————— */

/* Un aparté, pas une section : l'espace au-dessus et la couleur muette
   suffisent à changer de registre — pas besoin d'un filet. */
.note {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-secondary);
}

@media (min-width: 900px) {
  .aside { padding-left: 48px; }
  .note  { padding-left: 96px; }
}

/* — Motion ——————————————————————————————————— */

/* Une seule apparition, sur le bloc entier : pas de cascade au scroll, pas
   d'entrée par élément. Le contenu existe sans JavaScript et l'animation ne
   fait jamais attendre. */
@keyframes appear {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.layout {
  animation: appear 400ms cubic-bezier(0.2, 0, 0, 1) backwards;
}

@media (prefers-reduced-motion: reduce) {
  .layout { animation: none; }
  .status__dot { animation: none; }
  .link,
  .link__label,
  .link__arrow { transition: none; }
}
