/* Theme tokens — change here to retheme the whole site */
:root {
  /* Light theme (default) */
  --bg: #ffffff;
  --bg-elev: #f7f8fa;
  --bg-elev-2: #eef1f5;
  --surface: #ffffff;
  --text: #0f1115;
  --text-secondary: #4a5260;
  --text-muted: #7a8294;
  --border: #e3e7ee;
  --border-strong: #c9d0db;
  --accent: #01589B;
  --accent-strong: #003F73;
  --accent-soft: #e6f0f9;
  --on-accent: #ffffff;
  --shadow: 0 1px 2px rgba(15, 17, 21, 0.04), 0 4px 16px rgba(15, 17, 21, 0.06);
  --shadow-lg: 0 12px 40px rgba(15, 17, 21, 0.12);
  --ring: rgba(1, 88, 155, 0.25);

  color-scheme: light;
}

:root.dark {
  /* Dark theme */
  --bg: #0a0c10;
  --bg-elev: #11141a;
  --bg-elev-2: #161a22;
  --surface: #11141a;
  --text: #f1f3f7;
  --text-secondary: #c2c8d2;
  --text-muted: #8a92a0;
  --border: #1f2430;
  --border-strong: #2c3342;
  --accent: #4cc2ff;
  --accent-strong: #87d5ff;
  --accent-soft: rgba(76, 194, 255, 0.12);
  --on-accent: #001b2e;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.55);
  --ring: rgba(76, 194, 255, 0.35);

  color-scheme: dark;
}

/* System-preferred dark when no explicit choice */
@media (prefers-color-scheme: dark) {
  :root:not(.light):not(.dark) {
    --bg: #0a0c10;
    --bg-elev: #11141a;
    --bg-elev-2: #161a22;
    --surface: #11141a;
    --text: #f1f3f7;
    --text-secondary: #c2c8d2;
    --text-muted: #8a92a0;
    --border: #1f2430;
    --border-strong: #2c3342;
    --accent: #4cc2ff;
    --accent-strong: #87d5ff;
    --accent-soft: rgba(76, 194, 255, 0.12);
    --on-accent: #001b2e;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.55);
    --ring: rgba(76, 194, 255, 0.35);
    color-scheme: dark;
  }
}

/* Smooth theme transitions */
html {
  transition: background-color 0.25s ease, color 0.25s ease;
}
html, body {
  background-color: var(--bg);
  color: var(--text);
}

/* ------- Easing tokens ------- */
:root {
  /* Apple/iOS-style expo.out — premium entrance curve */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  /* Material standard — balanced two-sided motion */
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  /* Sine in/out — quiet sustained oscillation */
  --ease-sine: cubic-bezier(0.45, 0.05, 0.55, 0.95);
}

/* ------- Reusable animations ------- */
@keyframes fade-up {
  from { opacity: 0; transform: translateY(16px); filter: blur(3px); }
  to   { opacity: 1; transform: translateY(0);    filter: blur(0); }
}
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes pulse-dot {
  0%, 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.55); }
  50%      { box-shadow: 0 0 0 8px rgba(34, 197, 94, 0); }
}
@keyframes float-y {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-7px); }
}
@keyframes drift {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(3px, -6px); }
}
@keyframes blob-morph {
  0%, 100% { border-radius: 46% 54% 55% 45% / 48% 49% 51% 52%; }
  33%      { border-radius: 56% 44% 40% 60% / 50% 55% 45% 50%; }
  66%      { border-radius: 42% 58% 60% 40% / 45% 47% 53% 55%; }
}
@keyframes gradient-pan {
  0%   { background-position:   0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position:   0% 50%; }
}
@keyframes rotate-slow {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes char-rise {
  from { opacity: 0; transform: translateY(0.5em); filter: blur(4px); }
  to   { opacity: 1; transform: translateY(0);     filter: blur(0); }
}
@keyframes caret-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}
@keyframes underline-grow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* Entrance via TRANSITION (not animation) so it never restarts on
   hydration / client-side re-render. Initial state is applied only when
   JS is detected (.js class set synchronously in theme-init.js).
   When .is-ready is added on the next frame, elements transition to their
   final state. Without JS, .fade-up stays at the browser default (visible). */
.js:not(.is-ready) .fade-up {
  opacity: 0;
  transform: translateY(16px);
  filter: blur(3px);
}
.js .fade-up {
  transition: opacity 0.9s var(--ease-out-expo),
              transform 0.9s var(--ease-out-expo),
              filter 0.9s var(--ease-out-expo);
  will-change: opacity, transform, filter;
}
.js .fade-up.d1 { transition-delay: 0.08s; }
.js .fade-up.d2 { transition-delay: 0.16s; }
.js .fade-up.d3 { transition-delay: 0.24s; }
.js .fade-up.d4 { transition-delay: 0.32s; }
.js .fade-up.d5 { transition-delay: 0.40s; }
.js .fade-up.d6 { transition-delay: 0.48s; }
.js .fade-up.d7 { transition-delay: 0.56s; }

/* Char-by-char rise — wrap each character in <span class="ch">.
   Per-character delay is set inline via `transition-delay`. */
.text-reveal .ch {
  display: inline-block;
  white-space: pre;
}
.js:not(.is-ready) .text-reveal .ch {
  opacity: 0;
  transform: translateY(0.5em);
  filter: blur(4px);
}
.js .text-reveal .ch {
  transition: opacity 0.75s var(--ease-out-expo),
              transform 0.75s var(--ease-out-expo),
              filter 0.75s var(--ease-out-expo);
  will-change: opacity, transform, filter;
}

/* Underline-grow on the role text. Same pattern — gated by .is-ready. */
.js:not(.is-ready) .underline-grow::after { transform: scaleX(0); }
.js .underline-grow::after {
  transition: transform 0.9s var(--ease-out-expo);
  transition-delay: 0.85s;
}

/* Chips: each chip fades in with its own transition-delay set inline.
   The transition shorthand is defined on the .chip rule in home_page.dart so
   it can co-exist with the hover transform/box-shadow transition. */
.js:not(.is-ready) .chip { opacity: 0; }

/* Gradient sweep text (for accent words) */
.shimmer-text {
  background: linear-gradient(
    90deg,
    var(--accent) 0%,
    var(--accent-strong) 40%,
    var(--accent) 80%
  );
  background-size: 200% 100%;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
          color: transparent;
  animation: gradient-pan 6s ease-in-out infinite;
}

/* Respect reduced-motion */
@media (prefers-reduced-motion: reduce) {
  .fade-up, .text-reveal .ch { animation: none !important; opacity: 1 !important; transform: none !important; filter: none !important; }
  .shimmer-text { animation: none !important; }
}

/* ------- Selection ------- */
::selection {
  background: var(--accent);
  color: var(--on-accent);
}

/* ------- Theme toggle icon transitions ------- */
.theme-toggle { position: relative; }
.theme-toggle .icon {
  position: absolute;
  display: inline-block;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.theme-toggle .icon.sun  { opacity: 1; transform: rotate(0) scale(1); }
.theme-toggle .icon.moon { opacity: 0; transform: rotate(-90deg) scale(0.6); }
:root.dark .theme-toggle .icon.sun  { opacity: 0; transform: rotate(90deg) scale(0.6); }
:root.dark .theme-toggle .icon.moon { opacity: 1; transform: rotate(0) scale(1); }

/* ------- Smooth transitions for themed elements ------- */
.theme-toggle, .nav-link, .btn, .project-card, .skill-chip,
.contact-card, header, footer, .hero, .section {
  transition: background-color 0.25s ease, color 0.25s ease,
    border-color 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}

/* ------- Scrollbar ------- */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 999px; }
*::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
