/* Ozdoby szablonu strony projektu (02.10) — warstwa nad crossfade.css. Wzorowane na komponentach z 21st.dev.
   Wyłączenie wszystkiego: usuń <link ozdoby.css> i <script ozdoby.js> ze strony. Ruch tylko dla tych, którzy go nie wyłączyli. */

/* 1. Hero: nagłówek wyostrza się z rozmycia, reszta wjeżdża po kolei, ekran laptopa „włącza się” (Blur In / Blur Fade, Magic UI) */
@keyframes oz-blur-in { from { opacity: 0; filter: blur(12px); transform: translateY(14px); } to { opacity: 1; filter: none; transform: none; } }
@keyframes oz-screen-on { 0% { opacity: 0; filter: brightness(2.2) blur(6px); } 60% { opacity: 1; filter: brightness(1.25) blur(0); } 100% { opacity: 1; filter: none; } }
.oz .hero .project-label { animation: oz-blur-in .7s cubic-bezier(.2, .7, .2, 1) .05s both; }
.oz .hero h1 .oz-hw > span { display: inline-block; animation: oz-blur-in .8s cubic-bezier(.2, .7, .2, 1) both; animation-delay: calc(.15s + var(--wi) * .08s); }
/* szafirowa poświata raz przesuwa się za nagłówkiem (Spotlight, Aceternity) */
@keyframes oz-glow { from { opacity: 0; transform: translateX(-25%) scale(.9); } to { opacity: 1; transform: none; } }
.oz .hero-inner::before { content: ''; position: absolute; left: -12%; top: 4%; width: 68%; height: 82%; z-index: -1; pointer-events: none;
  background: radial-gradient(ellipse at 40% 45%, rgba(59, 130, 246, .2), transparent 62%); filter: blur(24px); animation: oz-glow 2.2s cubic-bezier(.2, .7, .2, 1) .1s both; }
.oz .hero .intro { animation: oz-blur-in .8s cubic-bezier(.2, .7, .2, 1) .6s both; }
.oz .hero .package-icons { animation: oz-blur-in .8s cubic-bezier(.2, .7, .2, 1) .75s both; }
.oz .hero .facts { animation: oz-blur-in .8s cubic-bezier(.2, .7, .2, 1) .9s both; }
.oz .hero-screen { animation: oz-screen-on 1.4s ease-out .5s both; }
.oz .hero-preview.has-video { animation: oz-blur-in .9s ease-out .5s both; }

/* 2. Sekcje wjeżdżają przy przewijaniu: lekki ruch w górę + wyostrzenie (Blur Fade) */
.oz [data-oz] { opacity: 0; filter: blur(8px); transform: translateY(22px); transition: opacity .8s cubic-bezier(.2, .7, .2, 1), filter .8s cubic-bezier(.2, .7, .2, 1), transform .8s cubic-bezier(.2, .7, .2, 1); transition-delay: var(--oz-d, 0s); }
.oz [data-oz].oz-in { opacity: 1; filter: none; transform: none; }

/* 3. „Dla kogo”: złote odhaczenia wskakują po kolei */
@keyframes oz-pop { 0% { transform: scale(.4); } 70% { transform: scale(1.15); } 100% { transform: scale(1); } }
.oz .fit li.oz-in .check { animation: oz-pop .5s cubic-bezier(.3, 1.4, .5, 1) both; animation-delay: calc(var(--oz-d, 0s) + .15s); }

/* 4. Karty: światło idzie za kursorem (Spotlight Card) + lekki przechył zrzutów (3D Card / Tilt) */
.oz-spot { position: relative; isolation: isolate; }
.oz-spot::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 3; opacity: 0; transition: opacity .35s;
  background: radial-gradient(380px circle at var(--mx, 50%) var(--my, 50%), rgba(59, 130, 246, .16), transparent 55%);
  mix-blend-mode: screen;
}
.oz-spot:hover::after { opacity: 1; }
.oz .screenshot { transition: transform .35s cubic-bezier(.2, .7, .2, 1), box-shadow .35s, border-color .35s; transform-style: preserve-3d; }
.oz .screenshot:hover { box-shadow: 0 24px 60px #0009, 0 0 40px #3b82f61f; }
.oz .screenshot img.shot { transition: transform .6s cubic-bezier(.2, .7, .2, 1); }
.oz .screenshot:hover img.shot:not(.fit) { transform: scale(1.04); }

/* 5. Okienko na maila: wolno krążące światło na krawędzi (Border Beam) */
@keyframes oz-spin { to { rotate: 360deg; } }
.oz-beam { position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none; overflow: hidden;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; }
.oz-beam i { position: absolute; left: 50%; top: 50%; width: 170%; aspect-ratio: 1; translate: -50% -50%;
  background: conic-gradient(transparent 0 70%, #3B82F6 82%, #D9B775 92%, transparent 100%); }
@keyframes oz-rest { to { opacity: .45; } }
.email-card.oz-in .oz-beam i { animation: oz-spin 3.4s cubic-bezier(.45, .05, .55, .95) .5s 2 both; }
.email-card.oz-in .oz-beam { animation: oz-rest 1s ease 7.3s both; }

/* 6. Złote przyciski: przy najechaniu przelatuje odblask (Shiny Button) */
.oz .button.gold { position: relative; overflow: hidden; }
.oz .button.gold::after { content: ''; position: absolute; top: 0; bottom: 0; left: -60%; width: 45%; pointer-events: none;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .55), transparent); transform: skewX(-18deg); transition: left .7s cubic-bezier(.2, .7, .2, 1); }
.oz .button.gold:hover::after { left: 120%; }

/* 7. Delikatne ziarno na całej stronie (dozwolone w DESIGN.md §7 od 31.08) */
.oz body::before { content: ''; position: fixed; inset: 0; z-index: 50; pointer-events: none; opacity: .045; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }

/* ruch wyłączony w systemie → wszystko od razu widoczne, bez animacji */
@media (prefers-reduced-motion: reduce) {
  .oz .hero *, .oz .hero-screen, .oz .hero-preview { animation: none !important; }
  .oz [data-oz] { opacity: 1 !important; filter: none !important; transform: none !important; transition: none !important; }
  .oz-beam i, .oz-beam { animation: none !important; }
}

/* 8. Nagłówki sekcji: słowa wysuwają się spod maski (Text Reveal Mask) — bez rozmycia, tanie na telefonie */
.oz-mw { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .14em; margin-bottom: -.14em; }
.oz-mw > span { display: inline-block; }
.oz [data-ozm] .oz-mw > span { transform: translateY(108%); transition: transform .85s cubic-bezier(.2, .7, .2, 1); transition-delay: calc(var(--wi) * .06s); }
.oz [data-ozm].oz-in .oz-mw > span { transform: none; }

/* 9. „Dla kogo”: ptaszek sam się rysuje (Animated Signature — stroke-dashoffset) */
.fit .check svg { width: 18px; height: 18px; fill: none; stroke: #1b1609; stroke-width: 2.8; stroke-linecap: round; stroke-linejoin: round; }
.oz .fit li .check path { stroke-dasharray: 24; stroke-dashoffset: 24; transition: stroke-dashoffset .55s ease-out; transition-delay: calc(var(--oz-d, 0s) + .4s); }
.oz .fit li.oz-in .check path { stroke-dashoffset: 0; }

/* 10. Linki w stopce i okruszek (menu u góry ma świetlówkę): podkreślenie rysuje się przy najechaniu i przy klawiaturze (Underline Link) */
.footer nav a, .footer .text-link, .breadcrumb {
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat; transition: background-size .35s cubic-bezier(.2, .7, .2, 1), color .2s; padding-bottom: 2px; }
.footer nav a:hover, .footer .text-link:hover, .breadcrumb:hover,
.footer nav a:focus-visible, .footer .text-link:focus-visible { background-size: 100% 1px; }

@media (prefers-reduced-motion: reduce) {
  .oz [data-ozm] .oz-mw > span { transform: none !important; transition: none !important; }
  .oz .fit li .check path { stroke-dashoffset: 0 !important; transition: none !important; }
  .oz .hero-inner::before { animation: none !important; }
}
