/* Brand loader and startup splash. Served from public/ and linked in
   index.html, not bundled: the static splash there must animate while the
   app's JavaScript is still downloading. BrandLoader and BootSplash use the
   same rules once React runs. */

/* ── Static splash shell (index.html) ────────────────────────────────────
   Plain CSS: Tailwind is not loaded yet. theme-init.js reveals it on app
   routes and picks the ground of the screen the boot will likely land on. */

#boot-splash {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f3f4f6;
}
#boot-splash[hidden] { display: none; }
.dark #boot-splash { background: #030712; }
#boot-splash[data-boot-bg='signin'] { background: linear-gradient(to bottom right, #eff6ff, #fff, #faf5ff); }
.dark #boot-splash[data-boot-bg='signin'] { background: linear-gradient(to bottom right, #111827, #111827, #1f2937); }
#boot-splash .boot-splash-mark { position: relative; display: grid; place-items: center; width: 5rem; height: 5rem; }
#boot-splash .boot-splash-halo {
  position: absolute; inset: -14px; border-radius: 30px;
  background: rgb(59 130 246 / 0.25); filter: blur(24px);
}
.dark #boot-splash .boot-splash-halo { background: rgb(96 165 250 / 0.25); }
#boot-splash .boot-splash-tile {
  position: relative; width: 4rem; height: 4rem;
  filter: drop-shadow(0 10px 22px rgb(29 78 216 / 0.35));
}

/* ── Brand loader ────────────────────────────────────────────────────────
   Hidden for the first 300ms so a fast load never flashes it; then the tile
   springs in and loops: strokes write on in order, hold, and lift off while
   the halo breathes and a light sweeps across. Transform, opacity and
   stroke-dashoffset only. */

[data-brand-loader] {
  animation: brand-loader-in 520ms linear(0, 0.009, 0.037 1.8%, 0.153 3.8%, 0.776 11.3%, 1.01 15.6%, 1.059 18.2%, 1.064 20.6%, 1.04 24.4%, 0.996 30.4%, 0.987 33.5%, 0.99 38.8%, 1.003 49%, 1) 300ms both;
}
[data-brand-loader='immediate'] { animation-delay: 0ms; }

/* The startup splash lifts away: the ground fades while the mark grows a
   little and dissolves, revealing the app beneath. */
[data-boot-splash='leaving'] {
  animation: boot-splash-out 380ms cubic-bezier(0.4, 0, 0.2, 1) both;
  pointer-events: none;
}
[data-boot-splash='leaving'] [data-brand-loader] {
  animation: brand-loader-out 380ms cubic-bezier(0.4, 0, 0.2, 1) both;
}
@keyframes boot-splash-out { to { opacity: 0; } }
@keyframes brand-loader-out { to { opacity: 0; transform: scale(1.12); } }
[data-brand-loader-halo] {
  animation: brand-loader-breathe 2.8s ease-in-out infinite;
}
[data-brand-loader-tile] {
  animation: brand-loader-bob 2.8s ease-in-out infinite;
  transform-origin: center;
}
[data-brand-loader-shine] {
  animation: brand-loader-shine 2.8s cubic-bezier(0.4, 0, 0.2, 1) 0.9s infinite;
}
[data-brand-loader-stroke] {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: brand-loader-write 2.8s cubic-bezier(0.65, 0, 0.35, 1) infinite;
  animation-delay: calc(300ms + var(--stroke-i) * 110ms);
}
[data-brand-loader-caption] {
  animation: brand-loader-caption 2.8s ease-in-out 800ms infinite both;
}

@keyframes brand-loader-in {
  from { opacity: 0; transform: translateY(8px) scale(0.86); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes brand-loader-breathe {
  0%, 100% { opacity: 0.45; transform: scale(0.9); }
  50%      { opacity: 1;    transform: scale(1.08); }
}
@keyframes brand-loader-bob {
  0%, 100% { transform: translateY(0) scale(1); }
  50%      { transform: translateY(-3px) scale(1.03); }
}
@keyframes brand-loader-shine {
  0%        { transform: translateX(0); }
  45%, 100% { transform: translateX(56px); }
}
/* Write on (0–35%), hold (35–70%), lift off forward (70–92%), rest. */
@keyframes brand-loader-write {
  0%        { stroke-dashoffset: 1; opacity: 1; }
  35%, 70%  { stroke-dashoffset: 0; opacity: 1; }
  92%       { stroke-dashoffset: -1; opacity: 0.6; }
  100%      { stroke-dashoffset: -1; opacity: 0; }
}
@keyframes brand-loader-caption {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 1; }
}

@keyframes boot-splash-in { from { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  [data-brand-loader] { animation: boot-splash-in 120ms ease-out 300ms both; }
  [data-brand-loader='immediate'] { animation-delay: 0ms; }
  [data-boot-splash='leaving'],
  [data-boot-splash='leaving'] [data-brand-loader] { animation: boot-splash-out 120ms ease-out both; }
  [data-brand-loader-halo],
  [data-brand-loader-tile],
  [data-brand-loader-shine],
  [data-brand-loader-caption] { animation: none; }
  [data-brand-loader-shine] { opacity: 0; }
  [data-brand-loader-stroke] { animation: none; stroke-dashoffset: 0; }
}
