/* ClipMind – efekty w stylu Magic UI, odtworzone w czystym CSS (bez frameworków).
 *
 * Każdy efekt to mała klasa narzędziowa; kolory z tokenów w style.css (:root i [data-theme="dark"]).
 * Ruch tylko przy zmianie stanu albo pod kursorem. Przy "ogranicz animacje" efekty ruchu są
 * wyłączone (globalna reguła w style.css + reguły przy efektach poniżej).
 */

/* ---------------------------------------------------------------- E4 Word Rotate */
/* Wszystkie warianty słowa w jednej komórce siatki: pole ma szerokość najdłuższego, widać jeden.
   Kropka jest częścią każdego wariantu, więc zawsze idzie tuż za słowem. */
.word-rotate { display: inline-grid; }
.word-rotate-item { grid-area: 1 / 1; justify-self: start; white-space: nowrap; visibility: hidden; }
.word-rotate-item.current, .word-rotate-item.leaving { visibility: visible; }
.word-rotate-item.entering { animation: word-rotate-in 0.55s var(--ease-out) both; }
.word-rotate-item.leaving { animation: word-rotate-out 0.4s var(--ease-out) both; }
@keyframes word-rotate-in { from { opacity: 0; transform: translateY(0.45em); filter: blur(8px); } }
@keyframes word-rotate-out { to { opacity: 0; transform: translateY(-0.45em); filter: blur(8px); } }

/* ---------------------------------------------------------------- E1 Shiny Text */
/* Połysk przesuwa się po tekście: "AI albo serwer właśnie pracuje". */
.shiny-text {
  --shiny-base: var(--muted);
  --shiny-hi: var(--text);
  background: linear-gradient(100deg, var(--shiny-base) 0 40%, var(--shiny-hi) 50%, var(--shiny-base) 60% 100%) 0 0 / 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: shiny-sweep 2.2s linear infinite;
}
@keyframes shiny-sweep { from { background-position: 100% 0; } to { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) {
  .shiny-text { animation: none; background: none; color: var(--shiny-base); }
}

/* ---------------------------------------------------------------- E2 Border Beam */
/* Światło (żółty → turkus) biegnie po krawędzi: pseudo-element z conic-gradient obracanym przez
   @property, maskowany do samej ramki. Bez obsługi @property ramka po prostu się nie obraca. */
@property --beam-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
.border-beam { position: relative; isolation: isolate; }
.border-beam::after {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: 1;
  padding: 2px;
  border-radius: inherit;
  background: conic-gradient(from var(--beam-angle, 0deg), transparent 0 72%, var(--caption) 84%, var(--wave) 92%, transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: beam-spin var(--beam-duration, 2.4s) linear var(--beam-turns, infinite);
  pointer-events: none;
}
@keyframes beam-spin { to { --beam-angle: 360deg; } }
@media (prefers-reduced-motion: reduce) {
  .border-beam::after { display: none; }
}

/* ---------------------------------------------------------------- E6 Blur Fade */
/* Element pojawia się z rozmyciem i przesunięciem; --i opóźnia kolejne elementy listy. */
.blur-fade { animation: blur-fade 0.55s var(--ease-out) both; animation-delay: calc(var(--i, 0) * 70ms); }
@keyframes blur-fade { from { opacity: 0; transform: translateY(8px); filter: blur(6px); } }

/* ---------------------------------------------------------------- E7 Miękkie krawędzie list */
/* Zanik tylko po tej stronie, gdzie jest dalsza treść (klasy z Effects.attachEdgeFade). */
.edge-fade { --fade-top: 0px; --fade-bottom: 0px; }
.edge-fade.edge-top { --fade-top: 22px; }
.edge-fade.edge-bottom { --fade-bottom: 22px; }
.edge-fade.edge-top, .edge-fade.edge-bottom {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--fade-top), #000 calc(100% - var(--fade-bottom)), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 var(--fade-top), #000 calc(100% - var(--fade-bottom)), transparent 100%);
}

/* ---------------------------------------------------------------- E5 Magic Card */
/* Miękka poświata pod kursorem (tylko urządzenia z myszką); pozycja z Effects.attachSpotlight.
   Pseudo-element leży pod treścią (z-index: -1 w izolowanym kontekście), nad tłem elementu. */
@media (hover: hover) and (pointer: fine) {
  .spotlight { position: relative; isolation: isolate; }
  .spotlight::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: radial-gradient(260px circle at var(--mx, 50%) var(--my, 50%), var(--spot), transparent 70%);
    opacity: 0;
    transition: opacity 0.25s;
    pointer-events: none;
  }
  .spotlight:hover::before { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .spotlight::before { display: none; }
}

/* ---------------------------------------------------------------- E8 Dot Pattern */
/* Subtelna siatka kropek za sekcją, zanikająca ku krawędziom. Wystaje najwyżej na odstęp
   widoku (28 px / 12 px na telefonie), więc nie tworzy poziomego przewijania. */
.dot-pattern { position: relative; isolation: isolate; }
.dot-pattern::before {
  content: "";
  position: absolute;
  inset: -28px -24px;
  z-index: -1;
  background-image: radial-gradient(var(--dot) 1.1px, transparent 1.5px);
  background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(ellipse 60% 70% at 32% 45%, #000 15%, transparent 72%);
  mask-image: radial-gradient(ellipse 60% 70% at 32% 45%, #000 15%, transparent 72%);
  pointer-events: none;
}
@media (max-width: 900px) {
  .dot-pattern::before { inset: -12px -10px; }
}
