/* ── Portal Modern Effects v2 ──────────────────────────────────────────────────
   Layered on top of style.css. Adds:
   · Global top-of-page loading bar (indeterminate shimmer)
   · Creative preloader (bouncing dots)
   · Smooth section transitions (fade + slide)
   · Gradient headings with animated color shift
   · Kinetic text (shimmer sweep on h2/h3)
   · Scroll-reveal card stretch (IntersectionObserver-driven)
   · Skeleton / shimmer placeholders
   · Animated stat/score bars
   · Microinteractions: ripple, form glow, toast, button feedback
   · Sidebar active indicator
   ──────────────────────────────────────────────────────────────────────────── */

/* ── Keyframes ────────────────────────────────────────────────────────────── */
@keyframes portal-shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position:  400px 0; }
}
@keyframes portal-spin {
  to { transform: rotate(360deg); }
}
@keyframes portal-section-enter {
  from { opacity: 0; transform: translateX(12px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}
@keyframes portal-bar-grow {
  from { width: 0 !important; }
}
@keyframes portal-topbar-indeterminate {
  0%   { background-position: -400px 0; }
  100% { background-position:  400px 0; }
}
@keyframes portal-pulse-ring {
  0%   { transform: scale(1);   opacity: .6; }
  100% { transform: scale(1.6); opacity: 0;  }
}
@keyframes portal-gradient-shift {
  0%   { background-position: 0%   50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0%   50%; }
}
@keyframes portal-kinetic-sweep {
  0%   { background-position: -300% center; }
  100% { background-position:  300% center; }
}
@keyframes portal-dot-bounce {
  0%, 80%, 100% { transform: translateY(0);    opacity: .4; }
  40%            { transform: translateY(-8px); opacity: 1;  }
}
@keyframes portal-ripple-out {
  from { transform: scale(0); opacity: .45; }
  to   { transform: scale(4); opacity: 0;   }
}
@keyframes portal-toast-in {
  from { opacity: 0; transform: translateY(16px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
@keyframes portal-toast-out {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(8px) scale(.96); }
}
@keyframes portal-scroll-reveal {
  from { opacity: 0; transform: translateY(22px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}
@keyframes portal-count-up {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* Respect reduced-motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ── Branded splash and transition system ───────────────────────────────── */
.login-splash,
.portal-transition {
  position: fixed;
  inset: 0;
  z-index: 100000;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 18px;
  color: #fff;
  background:
    radial-gradient(circle at 20% 15%, rgba(255,255,255,.18), transparent 30%),
    linear-gradient(145deg, #1769d2, #3185fc 52%, #20a4c8);
  transition: opacity 500ms ease, visibility 500ms ease, transform 650ms cubic-bezier(.22,1,.36,1);
}
.login-splash.is-complete,
.portal-transition.departing {
  opacity: 0;
  visibility: hidden;
  transform: scale(1.025);
}
.splash-logo {
  width: min(240px, 62vw);
  height: auto;
  filter: drop-shadow(0 10px 28px rgba(0,0,0,.14));
  animation: splash-logo-in 700ms cubic-bezier(.22,1,.36,1) both;
}
.splash-copy { text-align: center; padding: 0 24px; }
.splash-copy strong { display:block; font: 600 clamp(20px,4vw,30px)/1.2 "Lora", Georgia, serif; }
.splash-copy span { display:block; margin-top:7px; font-size:13px; color:rgba(255,255,255,.82); }
.brand-motion { display:flex; align-items:center; gap:8px; height:24px; }
.brand-motion span { width:9px; height:9px; border-radius:50%; background:#fff; animation:portal-dot-bounce 1.15s ease-in-out infinite both; }
.brand-motion span:nth-child(2) { animation-delay:.14s; }
.brand-motion span:nth-child(3) { animation-delay:.28s; }
@keyframes splash-logo-in { from { opacity:0; transform:translateY(18px) scale(.94); } to { opacity:1; transform:none; } }

.portal-transition { opacity:0; visibility:hidden; transform:scale(.985); }
.portal-transition.visible { opacity:1; visibility:visible; transform:none; }
.portal-transition strong { font-size:14px; letter-spacing:.02em; }
.login-broadcast-icon { width:54px;height:54px;border-radius:18px;display:grid;place-items:center;background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.35);font-size:24px;animation:splash-logo-in 420ms cubic-bezier(.22,1,.36,1) both; }
.login-broadcast-copy { width:min(520px,calc(100vw - 40px));padding:4px 20px;text-align:center;animation:portal-section-enter 380ms cubic-bezier(.22,1,.36,1) both; }
.login-broadcast-copy small { display:block;margin-bottom:8px;font-size:10px;font-weight:800;letter-spacing:.14em;color:rgba(255,255,255,.72); }
.login-broadcast-copy strong { display:block;font:600 clamp(20px,4vw,28px)/1.25 "Lora",Georgia,serif; }
.login-broadcast-copy p { display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden;margin:10px 0 0;font-size:14px;line-height:1.55;color:rgba(255,255,255,.9);white-space:pre-line; }
.login-broadcast-copy span { display:block;margin-top:10px;font-size:11px;font-weight:700;color:rgba(255,255,255,.7); }

/* A small ambient loader accompanies the existing progress bar only after a
   request lasts long enough to be perceived. */
body.portal-page::after {
  content:"Updating";
  position:fixed;
  right:22px;
  bottom:22px;
  z-index:9998;
  padding:10px 14px 10px 36px;
  border:1px solid var(--border,#e1e6ee);
  border-radius:999px;
  background:rgba(255,255,255,.94);
  color:var(--muted,#6b7280);
  box-shadow:0 10px 30px rgba(31,36,48,.12);
  font-size:12px;
  font-weight:700;
  opacity:0;
  transform:translateY(8px);
  pointer-events:none;
  transition:opacity 180ms ease, transform 180ms ease;
}
body.portal-page.data-is-loading::after { opacity:1; transform:none; }
body.portal-page.data-is-loading::before {
  content:"";
  position:fixed;
  right:82px;
  bottom:34px;
  z-index:9999;
  width:8px;
  height:8px;
  border-radius:50%;
  background:#3185fc;
  box-shadow:0 0 0 5px rgba(49,133,252,.13);
  animation:portal-pulse-ring 1.25s ease-out infinite;
}
@media (max-width:820px) {
  body.portal-page.sidebar-open::after {
    content:"";
    position:fixed;
    inset:59px 0 0;
    z-index:80;
    padding:0;
    border:0;
    border-radius:0;
    background:rgba(20,25,40,.34);
    box-shadow:none;
    opacity:1;
    transform:none;
    backdrop-filter:blur(2px);
  }
  body.portal-page.sidebar-open::before { display:none; }
}

/* ── Top loading bar ──────────────────────────────────────────────────────── */
#portal-topbar {
  position: absolute;
  bottom: 0; left: 0;
  width: 100%;
  height: 3px;
  pointer-events: none;
  background: linear-gradient(90deg,
    #a5b4fc 0%, #60a5fa 30%, #67e8f9 60%, #a5b4fc 100%);
  background-size: 400px 100%;
  opacity: 0;
  transition: opacity 200ms ease;
}
#portal-topbar.running {
  opacity: 1;
  animation: portal-topbar-indeterminate 1.2s linear infinite;
}
#portal-topbar.finishing {
  opacity: 0;
  transition: opacity 400ms ease;
}
/* ── Creative Preloader ───────────────────────────────────────────────────── */
/* Usage: <div class="portal-preloader"><span></span><span></span><span></span></div> */
.portal-preloader {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 40px 0;
}
.portal-preloader span {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #6366f1;
  display: inline-block;
  animation: portal-dot-bounce 1.2s ease-in-out infinite both;
}
.portal-preloader span:nth-child(1) { animation-delay: 0s;    background: #6366f1; }
.portal-preloader span:nth-child(2) { animation-delay: 0.16s; background: #3b82f6; }
.portal-preloader span:nth-child(3) { animation-delay: 0.32s; background: #06b6d4; }

/* ── Section transitions ──────────────────────────────────────────────────── */
.section {
  display: none;
}
.section.active {
  display: block;
  animation: portal-section-enter 260ms cubic-bezier(0.34, 1.2, 0.64, 1) both;
}

/* ── Gradient headings ────────────────────────────────────────────────────── */
/* Add class .gradient-heading to any element, or via JS with applyGradientHeadings() */
.gradient-heading {
  background: linear-gradient(135deg, #6366f1 0%, #3b82f6 40%, #06b6d4 70%, #6366f1 100%);
  background-size: 300% 300%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: portal-gradient-shift 6s ease infinite;
}

/* ── Kinetic text headings ────────────────────────────────────────────────── */
/* Add class .kinetic-heading — a shimmer light sweeps across on hover/load */
.kinetic-heading {
  display: inline-block;
  background: linear-gradient(
    105deg,
    currentColor 0%,
    currentColor 35%,
    rgba(255,255,255,.75) 50%,
    currentColor 65%,
    currentColor 100%
  );
  background-size: 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: portal-kinetic-sweep 3.5s ease-in-out infinite;
  animation-play-state: paused;
}
.kinetic-heading:hover,
.section.active .kinetic-heading {
  animation-play-state: running;
}

/* ── Scroll-reveal / stretch cards ───────────────────────────────────────── */
/* JS adds .scroll-reveal to cards; .revealed triggers on IntersectionObserver */
.scroll-reveal {
  opacity: 0;
  transform: translateY(22px) scale(0.96);
}
.scroll-reveal.revealed {
  animation: portal-scroll-reveal 380ms cubic-bezier(0.34, 1.1, 0.64, 1) forwards;
}

/* ── Skeleton / shimmer ───────────────────────────────────────────────────── */
.skeleton {
  background: linear-gradient(90deg, var(--border, #e7e9f0) 25%, var(--surface, #f3f4f8) 50%, var(--border, #e7e9f0) 75%);
  background-size: 800px 100%;
  animation: portal-shimmer 1.4s infinite linear;
  border-radius: 6px;
}
.skeleton-text  { height: 14px; margin-bottom: 8px; border-radius: 4px; }
.skeleton-title { height: 22px; margin-bottom: 14px; border-radius: 4px; }
.skeleton-card  {
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 14px;
  min-height: 90px;
  border: 1px solid var(--border, #e7e9f0);
}
.skeleton-row   { display: flex; gap: 12px; margin-bottom: 12px; }
.skeleton-row .skeleton { flex: 1; }

/* ── Loading status ───────────────────────────────────────────────────────── */
.portal-loading-status {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 10px;
  background: var(--surface, #f5f6fa);
  border: 1px solid var(--border, #e7e9f0);
  color: var(--muted, #6b7280);
  font-size: 14px;
}
.portal-loading-status .pls-spinner {
  width: 18px; height: 18px; flex-shrink: 0;
  border: 2px solid var(--border, #e7e9f0);
  border-top-color: #6366f1;
  border-radius: 50%;
  animation: portal-spin 700ms linear infinite;
}
.portal-loading-status .pls-bar-wrap {
  flex: 1;
  height: 4px;
  background: var(--border, #e7e9f0);
  border-radius: 2px;
  overflow: hidden;
}
.portal-loading-status .pls-bar {
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(90deg, #6366f1, #3b82f6);
  background-size: 200% 100%;
  animation: portal-shimmer 1.4s infinite linear;
}

/* ── Animated stat/score bars ─────────────────────────────────────────────── */
.animate-bars [style*="width:"],
.animate-bars [style*="width: "] {
  animation: portal-bar-grow 700ms cubic-bezier(.4,0,.2,1) both;
}
/* Stat value count-up animation */
.stat-value.counting {
  animation: portal-count-up 350ms ease-out both;
}

/* ── Card hover lift ──────────────────────────────────────────────────────── */
.card,
.stat-card,
.activity-card,
.step-card {
  transition: box-shadow 220ms ease, transform 220ms ease;
}
.card:hover,
.stat-card:hover,
.activity-card:hover,
.step-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 28px rgba(99,102,241,.12);
}

/* ── Button press feedback + ripple ──────────────────────────────────────── */
button {
  transition: filter 150ms ease, transform 120ms ease, box-shadow 150ms ease;
  position: relative;
  overflow: hidden;
}
button:active:not(:disabled) {
  transform: scale(.97);
  filter: brightness(.93);
}
/* Ripple element injected by JS */
.portal-ripple {
  position: absolute;
  border-radius: 50%;
  background: rgba(255,255,255,.4);
  width: 80px; height: 80px;
  margin-top: -40px; margin-left: -40px;
  pointer-events: none;
  animation: portal-ripple-out 500ms ease-out forwards;
}
button.primary .portal-ripple  { background: rgba(255,255,255,.35); }
button.secondary .portal-ripple { background: rgba(99,102,241,.18); }
button.danger .portal-ripple   { background: rgba(255,255,255,.30); }

/* ── Form field focus glow ────────────────────────────────────────────────── */
input, textarea, select {
  transition: border-color 180ms ease, box-shadow 180ms ease, background 180ms ease;
}
input:focus:not(:read-only),
textarea:focus:not(:read-only),
select:focus {
  border-color: #6366f1 !important;
  box-shadow: 0 0 0 3px rgba(99,102,241,.18) !important;
  outline: none;
}

/* ── Gradient headings on section h2 elements ─────────────────────────────── */
/* Auto-applied by JS; only text-fill, doesn't break layouts */
.section h2.auto-gradient {
  background: linear-gradient(120deg, #4f46e5 0%, #2563eb 50%, #0891b2 100%);
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: portal-gradient-shift 8s ease infinite;
  display: inline-block;
}

/* ── Toast notifications ──────────────────────────────────────────────────── */
#portal-toast-container {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 99999;
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
}
.portal-toast {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 500;
  color: #fff;
  background: #1e293b;
  box-shadow: 0 8px 32px rgba(0,0,0,.22);
  pointer-events: auto;
  max-width: 360px;
  animation: portal-toast-in 240ms cubic-bezier(0.34,1.2,0.64,1) both;
}
.portal-toast.toast-success { background: linear-gradient(135deg, #059669, #047857); }
.portal-toast.toast-error   { background: linear-gradient(135deg, #dc2626, #b91c1c); }
.portal-toast.toast-info    { background: linear-gradient(135deg, #3b82f6, #2563eb); }
.portal-toast.toast-warning { background: linear-gradient(135deg, #d97706, #b45309); color: #fff; }
.portal-toast.hiding        { animation: portal-toast-out 220ms ease forwards; }

/* ── Sidebar active indicator ─────────────────────────────────────────────── */
.sidebar-link {
  position: relative;
  transition: background 160ms ease, color 160ms ease, padding-left 160ms ease;
}
.sidebar-link.active::before {
  content: "";
  position: absolute;
  left: 0; top: 20%; bottom: 20%;
  width: 3px;
  border-radius: 0 2px 2px 0;
  background: linear-gradient(180deg, #6366f1, #3b82f6);
}
.sidebar-link:not(.active):hover {
  background: rgba(99,102,241,.07);
}

/* ── Focus ring ───────────────────────────────────────────────────────────── */
button:focus-visible,
a:focus-visible {
  outline: 2px solid #6366f1;
  outline-offset: 2px;
}

/* ── Dark mode shimmer tint ───────────────────────────────────────────────── */
@media (prefers-color-scheme: dark) {
  .skeleton {
    background: linear-gradient(90deg, #2a2d3e 25%, #343750 50%, #2a2d3e 75%);
    background-size: 800px 100%;
  }
  .portal-toast { background: #1e293b; }
}
:root[data-theme="dark"] .skeleton {
  background: linear-gradient(90deg, #2a2d3e 25%, #343750 50%, #2a2d3e 75%);
  background-size: 800px 100%;
}
