/* ============================================================
   Omixa interactive layer. Loaded after motion.css. Behaviour lives in js/interactive.js.

   What this adds (all of it decorative or feedback; nothing is needed to read or use the page):
   - A cursor-following aurora behind every page and a scroll progress line under the nav
   - Landing hero: word-by-word headline, a live "messy -> clean" sheet, a card that tilts toward the cursor
   - Cursor spotlight on cards, magnetic upload/clean buttons, press ripples
   - Full-page "drop your file" veil while a file is dragged over the window
   - Landing steps line that draws as you scroll, before/after values that resolve letter by letter
   - A confetti burst when a file finishes cleaning

   Rules: tokens or the logo rgba() triples only; keyframes only inside prefers-reduced-motion: no-preference;
   hover-only effects only on fine pointers; everything animates transform/opacity (no layout properties,
   except the one-off collapse of the removed duplicate row in the demo).
   ============================================================ */

:root { --i-ease: cubic-bezier(0.16, 1, 0.3, 1); }

/* ---------- Aurora (created by JS; sits behind everything) ---------- */
.aurora { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.aurora i { position: absolute; left: 0; top: 0; width: 0; height: 0; will-change: transform; }
.aurora i::before { content: ""; position: absolute; border-radius: 50%; }
.aurora i:nth-child(1)::before { width: 52vmax; height: 52vmax; margin: -26vmax 0 0 -26vmax; background: radial-gradient(closest-side, rgba(165, 84, 247, 0.30), transparent); }
.aurora i:nth-child(2)::before { width: 44vmax; height: 44vmax; margin: -22vmax 0 0 -22vmax; background: radial-gradient(closest-side, rgba(104, 52, 214, 0.22), transparent); }
.aurora i:nth-child(3)::before { width: 36vmax; height: 36vmax; margin: -18vmax 0 0 -18vmax; background: radial-gradient(closest-side, rgba(244, 238, 253, 0.9), transparent); }

/* ---------- Scroll progress ---------- */
.scroll-progress { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 60; pointer-events: none; transform: scaleX(0); transform-origin: left center; background: var(--edge); }

/* ---------- Headline: words arrive one by one (markup is in landing.html) ---------- */
.hero-copy h1 { animation: none; }
.hero-copy h1 .w { display: inline-block; }
.hero-copy h1 .grad-text { background: linear-gradient(90deg, var(--omixa-violet), var(--omixa-glow), var(--omixa-violet)); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; }

/* ---------- Live demo sheet ---------- */
.live-demo { position: relative; margin: 0 auto 22px; max-width: 560px; border-radius: 20px; overflow: hidden; text-align: left; cursor: pointer;
  background: rgba(255, 255, 255, 0.78); border: 1px solid rgba(14, 5, 36, 0.07); box-shadow: 0 14px 40px rgba(56, 21, 147, 0.10);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); -webkit-user-select: none; user-select: none; }
.live-demo:empty { display: none; }
body.has-file .live-demo { display: none; }
.ld-bar { display: flex; align-items: center; gap: 6px; padding: 10px 14px; border-bottom: 1px solid rgba(14, 5, 36, 0.06); }
.ld-bar > i { width: 9px; height: 9px; border-radius: 50%; background: var(--gray-200); }
.ld-title { margin-left: 8px; font-size: 0.8rem; font-weight: 700; color: var(--gray-600); }
.ld-badge { margin-left: auto; font-size: 0.74rem; font-weight: 700; padding: 3px 10px; border-radius: 999px; transition: background-color var(--dur-base) var(--ease), color var(--dur-base) var(--ease); }
.ld-badge.is-messy { background: var(--danger-bg); color: var(--danger-ink); }
.ld-badge.is-scan { background: var(--info-bg); color: var(--info-ink); }
.ld-badge.is-clean { background: var(--success-bg); color: var(--success-ink); }
.ld-row { display: grid; grid-template-columns: 1fr 1.5fr 1.15fr 0.95fr; gap: 6px; padding: 0 10px; }
.ld-head > span { font-size: 0.74rem; font-weight: 700; color: var(--gray-600); padding: 9px 8px 3px; }
.ld-body { position: relative; padding: 2px 0 8px; overflow: hidden; }
.ld-row.r { margin: 3px 0; max-height: 44px; transition: opacity 0.35s var(--ease), transform 0.35s var(--ease), max-height 0.4s var(--ease), margin 0.4s var(--ease); }
.ld-row.gone { opacity: 0; transform: translateX(18px); max-height: 0; margin: 0; overflow: hidden; }
.ld-row.dup .ld-cell { background: var(--warning-bg); color: var(--warning); }
.ld-cell { min-width: 0; font-size: 0.82rem; font-weight: 600; padding: 8px; border-radius: 9px; white-space: pre; overflow: hidden; text-overflow: ellipsis; color: var(--ink);
  font-variant-numeric: tabular-nums; transition: background-color 0.45s var(--ease), color 0.45s var(--ease); }
.ld-cell.bad { background: var(--danger-bg); color: var(--danger-ink); }
.ld-cell.fixed { background: var(--success-bg); color: var(--success-ink); }
.ld-beam { position: absolute; left: 0; right: 0; top: 0; height: 46px; opacity: 0; pointer-events: none;
  background: linear-gradient(to bottom, transparent, rgba(165, 84, 247, 0.28)); border-bottom: 2px solid var(--omixa-violet); }
.ld-foot { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 10px 16px 12px; border-top: 1px solid rgba(14, 5, 36, 0.06); font-size: 0.8rem; color: var(--gray-600); }
.ld-sum { font-weight: 700; color: var(--ink); }
@media (max-width: 559px) {
  .ld-row { grid-template-columns: 0.95fr 1.3fr 1.15fr; }
  .ld-row > :nth-child(4) { display: none; }
  .ld-cell { font-size: 0.74rem; padding: 8px 5px; }
}

/* ---------- Spotlight + tilt (fine pointers only) ---------- */
[data-spot] { position: relative; }
[data-spot]::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity var(--dur-base) var(--ease);
  background: radial-gradient(260px circle at var(--px, 50%) var(--py, 50%), rgba(165, 84, 247, 0.16), transparent 70%); }
@media (hover: hover) and (pointer: fine) {
  [data-spot]:hover::after { opacity: 1; }
  .tool-card { will-change: transform; transition: transform 0.6s var(--i-ease); }
  .tool-card.is-tilting { transition: transform 90ms linear; }
}
.step3-art { position: relative; }

/* ---------- Magnetic buttons + ripple ---------- */
.btn-upload, .btn-main { position: relative; overflow: hidden; translate: var(--tx, 0px) var(--ty, 0px);
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease), filter var(--dur-fast) var(--ease), translate 0.35s var(--i-ease); }
.btn-upload.is-pulled, .btn-main.is-pulled { transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease), filter var(--dur-fast) var(--ease), translate 80ms linear; }
.ripple { position: absolute; border-radius: 50%; pointer-events: none; background: rgba(255, 255, 255, 0.35); transform: scale(0); opacity: 1; }
.tab, .btn { position: relative; overflow: hidden; }
.btn-main::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transform: translateX(-100%);
  background: linear-gradient(105deg, transparent 30%, rgba(255, 255, 255, 0.28) 50%, transparent 70%); }
.btn-main[aria-busy="true"]::after { content: ""; position: static; inset: auto; opacity: 1; transform: none; background: none; }

/* ---------- Drop veil ---------- */
.drop-veil { position: fixed; inset: 0; z-index: 80; display: grid; place-items: center; padding: 24px; pointer-events: none; visibility: hidden; opacity: 0;
  background: rgba(14, 5, 36, 0.55); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); transition: opacity 0.2s var(--ease), visibility 0s linear 0.2s; }
.drop-veil.on { visibility: visible; opacity: 1; transition: opacity 0.2s var(--ease), visibility 0s; }
.drop-veil-card { text-align: center; padding: 38px 46px; border-radius: 28px; background: var(--white); border: 3px dashed var(--omixa-violet); box-shadow: var(--shadow-lg); max-width: 420px; }
.drop-veil-card svg { width: 52px; height: 52px; padding: 13px; margin-bottom: 14px; border-radius: 50%; background: var(--edge); fill: none; stroke: var(--white); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.drop-veil-card strong { display: block; font-size: 1.3rem; color: var(--ink); letter-spacing: -0.01em; }
.drop-veil-card span { display: block; margin-top: 6px; font-size: 0.92rem; color: var(--gray-600); }

/* ---------- Confetti ---------- */
.confetti { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 85; pointer-events: none; }

/* ---------- Landing steps: a line that draws as the section scrolls into view ---------- */
@media (min-width: 761px) {
  html.i-ready .steps3 { position: relative; }
  html.i-ready .steps3::before, html.i-ready .steps3::after { content: ""; position: absolute; left: calc(100% / 6); right: calc(100% / 6); top: 95px; height: 3px; border-radius: 3px; z-index: 1; pointer-events: none; }
  html.i-ready .steps3::before { background: var(--omixa-violet-light); }
  html.i-ready .steps3::after { background: var(--edge); transform-origin: left center; transform: scaleX(var(--p, 0)); }
  html.i-ready .step3-art svg { position: relative; z-index: 2; }
  html.i-ready .step3.lit .step3-art svg { box-shadow: 0 0 0 9px rgba(165, 84, 247, 0.16), 0 8px 20px rgba(165, 84, 247, 0.4); }
}

/* ---------- Brand mark ---------- */
@media (hover: hover) { .topnav .brand img { transition: transform var(--dur-base) var(--i-ease); } .topnav .brand:hover img { transform: rotate(-8deg) scale(1.08); } }

/* ============================================================
   Everything below moves. Skipped entirely under reduced motion.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  @keyframes i-word { from { opacity: 0; transform: translateY(0.45em); filter: blur(8px); } to { opacity: 1; transform: none; filter: none; } }
  @keyframes i-sheen { from { background-position: 100% 0; } to { background-position: 0% 0; } }
  @keyframes i-drift-a { from { transform: translate3d(-3vmax, -2vmax, 0); } to { transform: translate3d(3vmax, 2vmax, 0); } }
  @keyframes i-drift-b { from { transform: translate3d(2vmax, 3vmax, 0); } to { transform: translate3d(-3vmax, -2vmax, 0); } }
  @keyframes i-ripple { to { transform: scale(1); opacity: 0; } }
  @keyframes i-nudge { 0% { box-shadow: 0 0 0 0 rgba(165, 84, 247, 0.5); } 100% { box-shadow: 0 0 0 20px rgba(165, 84, 247, 0); } }
  @keyframes i-sweep { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
  @keyframes i-veil-card { from { transform: scale(0.94); } to { transform: none; } }
  @keyframes i-veil-ring { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.04); } }
  @keyframes i-demo-in { from { opacity: 0; transform: translateY(18px) scale(0.98); } to { opacity: 1; transform: none; } }

  .hero-copy h1 .w { animation: i-word 720ms var(--i-ease) calc(120ms + var(--wi, 0) * 95ms) backwards; }
  .hero-copy h1 .grad-text { animation: i-word 720ms var(--i-ease) calc(120ms + var(--wi, 0) * 95ms) backwards, i-sheen 2.2s var(--ease) 1.1s 1 backwards; }
  .hero-copy .lead { animation-delay: 520ms; }
  .live-demo { animation: i-demo-in 640ms var(--i-ease) 640ms backwards; }

  .aurora i:nth-child(1)::before { animation: i-drift-a 17s ease-in-out infinite alternate; }
  .aurora i:nth-child(2)::before { animation: i-drift-b 21s ease-in-out infinite alternate; }
  .aurora i:nth-child(3)::before { animation: i-drift-a 25s ease-in-out infinite alternate-reverse; }

  .ripple { animation: i-ripple 620ms var(--ease-out) forwards; }
  .btn-upload.nudge { animation: i-nudge 1.5s var(--ease-out) 3; }
  .btn-main.is-ready::after { animation: i-sweep 900ms var(--ease-out) 1; }

  .drop-veil.on .drop-veil-card { animation: i-veil-card 320ms var(--i-ease) backwards, i-veil-ring 1.6s ease-in-out 320ms infinite; }

  .steps3::after { transition: transform 120ms linear; }
  .step3-art svg { transition: transform var(--dur-base) var(--ease-out), box-shadow 0.5s var(--ease); }
}

@media (prefers-reduced-motion: reduce) {
  .aurora, .scroll-progress, .confetti { display: none; }
  .ld-row.r, .ld-cell { transition: none; }
}

@media print { .aurora, .scroll-progress, .confetti, .drop-veil, .live-demo { display: none !important; } }

/* ============================================================
   Inner pages: dashboard, sign-in, pricing, batch, quality report, profile editor
   ============================================================ */

/* Focus: a soft ring on every field, and the label follows */
input:focus, select:focus, textarea:focus { box-shadow: 0 0 0 4px rgba(165, 84, 247, 0.16); }
.field:focus-within > label { color: var(--omixa-indigo); }
.field > label { transition: color var(--dur-fast) var(--ease); }

/* Tables: a violet marker on the row under the pointer */
tbody tr { transition: background-color var(--dur-fast) var(--ease); }
tbody td:first-child { transition: box-shadow var(--dur-base) var(--ease-out); }
@media (hover: hover) { tbody tr:hover td:first-child { box-shadow: inset 3px 0 0 var(--omixa-violet); } }

/* Tilting cards keep their own hover transitions for everything except the tilt */
.price-card.is-tilting, .stat-card.is-tilting { transition: transform 90ms linear, box-shadow var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease); }
.stat-card, .price-card { will-change: auto; }

/* Sign-in: show/hide password */
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 68px; }
.pw-toggle { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); border: 0; background: none; cursor: pointer; padding: 8px 10px; border-radius: 8px;
  font-family: inherit; font-size: 0.82rem; font-weight: 700; color: var(--omixa-indigo); }
.pw-toggle:hover { background: var(--gray-100); }
.pw-toggle:focus-visible { outline: var(--focus-outline); outline-offset: 1px; }
.pw-toggle:active { transform: translateY(-50%) scale(0.96); }

/* Dashboard: placeholders while the numbers, profiles and history load (they vanish when the app fills the block) */
#usage:empty::before, #profiles:empty::before, #history:empty::before {
  content: ""; display: block; grid-column: 1 / -1; border-radius: 16px;
  background: linear-gradient(100deg, var(--gray-100) 30%, rgba(244, 238, 253, 0.9) 50%, var(--gray-100) 70%); background-size: 220% 100%; }
#usage:empty::before { height: 84px; }
#profiles:empty::before, #history:empty::before { height: 96px; }

/* Pro badge: a single sheen */
.badge-plan-pro { position: relative; overflow: hidden; }
.badge-plan-pro::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transform: translateX(-100%);
  background: linear-gradient(105deg, transparent 30%, rgba(255, 255, 255, 0.35) 50%, transparent 70%); }

@media (prefers-reduced-motion: no-preference) {
  @keyframes i-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
  @keyframes i-shake { 0%, 100% { transform: none; } 20% { transform: translateX(-7px); } 40% { transform: translateX(6px); } 60% { transform: translateX(-4px); } 80% { transform: translateX(2px); } }
  @keyframes i-swap { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
  @keyframes i-badge-sheen { 0% { opacity: 1; transform: translateX(-100%); } 100% { opacity: 1; transform: translateX(100%); } }
  @keyframes i-field-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

  /* Page heading words (inner pages). The header keeps a simple fade so the two don't stack. */
  html.i-ready .dash-header { animation: m-fade 380ms var(--i-ease) backwards; }
  .dash-header h1 .w { display: inline-block; animation: i-word 640ms var(--i-ease) calc(80ms + var(--wi, 0) * 80ms) backwards; }

  /* Cards rise as they scroll in (class added by JS, removed again after the transition) */
  html.i-ready .i-rv { opacity: 0; transform: translateY(22px); }
  html.i-ready .i-rv.i-in { opacity: 1; transform: none; transition: opacity 600ms var(--i-ease) var(--rd, 0ms), transform 600ms var(--i-ease) var(--rd, 0ms); }

  /* Table rows arrive in sequence */
  .card > table tbody tr:nth-child(2) { animation-delay: 40ms; }
  .card > table tbody tr:nth-child(3) { animation-delay: 80ms; }
  .card > table tbody tr:nth-child(4) { animation-delay: 120ms; }
  .card > table tbody tr:nth-child(5) { animation-delay: 160ms; }
  .card > table tbody tr:nth-child(6) { animation-delay: 200ms; }
  .card > table tbody tr:nth-child(7) { animation-delay: 240ms; }
  .card > table tbody tr:nth-child(n + 8) { animation-delay: 280ms; }

  /* Loading placeholders */
  #usage:empty::before, #profiles:empty::before, #history:empty::before { animation: i-shimmer 1.4s linear infinite; }

  /* Sign-in */
  .auth-card.shake { animation: i-shake 480ms var(--ease-out); }
  #loginTitle.swap { animation: i-swap 280ms var(--ease-out); }
  #nameField:not(.hidden) { animation: i-field-in 300ms var(--ease-out) backwards; }

  /* Pro badge sheen, once */
  .badge-plan-pro::after { animation: i-badge-sheen 1.1s var(--ease) 1.2s 1 backwards; }

  /* Files chosen on the batch page, profile-editor rows: arrive when added */
  #batchList li { animation: m-rise 320ms var(--ease-out) backwards; }
  #batchList li:nth-child(2) { animation-delay: 50ms; }
  #batchList li:nth-child(3) { animation-delay: 100ms; }
  #batchList li:nth-child(4) { animation-delay: 150ms; }
  #batchList li:nth-child(n + 5) { animation-delay: 200ms; }
  #typeRows > *, #missRows > *, #allowRows > * { animation: i-field-in 280ms var(--ease-out) backwards; }
}

@media (prefers-reduced-motion: reduce) {
  .pw-toggle:active { transform: translateY(-50%); }
}
@media print { html.i-ready .i-rv { opacity: 1 !important; transform: none !important; } }
