/* ============================================================ MIX — "Ink & Ember" creative layer over the Arsam Sabbagh portfolio. Preloader, WebGL hero canvas, intro choreography, giant footer CTA. All colors ride the site's theme variables so light/dark + accent tweaks keep working. ============================================================ */ /* ------------------------------------------------------------ Preloader ------------------------------------------------------------ */ .mix-preloader { position: fixed; inset: 0; z-index: 100000; background: var(--bg, #F4F0E8); display: flex; align-items: center; justify-content: center; transition: background 0.4s ease; } .mix-preloader__inner { display: flex; align-items: baseline; gap: 18px; } .mix-preloader__word { margin: 0; font-family: var(--serif, 'Instrument Serif', serif); font-style: italic; font-weight: 400; font-size: clamp(28px, 4.5vw, 52px); letter-spacing: -0.01em; color: var(--ink, #1A1815); } .mix-preloader__count { margin: 0; font-family: var(--mono, 'JetBrains Mono', monospace); font-size: 12px; letter-spacing: 0.12em; color: var(--accent, #0F6B73); } .mix-preloader__bar { position: absolute; left: 0; bottom: 0; width: 100%; height: 2px; background: var(--rule, #d8d1be); } .mix-preloader__bar span { display: block; width: 0%; height: 100%; background: var(--accent, #0F6B73); } /* ------------------------------------------------------------ WebGL ember field in the hero ------------------------------------------------------------ */ .mix-ember { position: absolute; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none; } /* the SVG mesh grid stays on top of the shader; its blobs retire */ .hero.has-ember .hero-mesh { position: absolute; z-index: 1; } .hero.has-ember .hero-mesh .blob { display: none; } .hero.has-ember .hero-wrap { z-index: 2; will-change: transform, opacity; } /* the big wordmark leans with scroll velocity (js/mix.js) */ .bw-text { will-change: transform; } /* ------------------------------------------------------------ Hero intro choreography — initial (hidden) states. html.mix-intro-wait is added by mix.js only when it will actually run the intro, so nothing stays hidden if JS fails. ------------------------------------------------------------ */ html.mix-intro-wait .hero-kicker, html.mix-intro-wait .hero-meta, html.mix-intro-wait .hero-ctas, html.mix-intro-wait .hero-foot { opacity: 0; } html.mix-intro-wait .hero-name .hero-line { opacity: 0; transform: translateY(0.35em); clip-path: inset(0 0 100% 0); } /* ------------------------------------------------------------ Giant footer CTA ------------------------------------------------------------ */ .mix-cta-wrap { padding: clamp(8px, 2vw, 24px) 0 clamp(48px, 8vw, 110px); border-bottom: 1px solid var(--rule); margin-bottom: clamp(40px, 6vw, 80px); } .mix-cta-kicker { margin: 0 0 clamp(18px, 3vw, 36px); color: var(--accent); } .mix-cta { display: block; width: max-content; max-width: 100%; } .mix-cta-line { display: block; font-family: var(--sans); font-weight: 300; font-size: clamp(64px, 15vw, 220px); line-height: 0.88; letter-spacing: -0.05em; color: var(--ink); transition: letter-spacing 0.8s cubic-bezier(0.2, 0.7, 0.2, 1), color 0.45s ease; } .mix-cta-line--stroke { color: transparent; -webkit-text-stroke: 1.5px var(--ink); /* ink-fill sweep: gradient revealed through the glyphs on hover */ background-image: linear-gradient(90deg, var(--accent), var(--accent)); background-repeat: no-repeat; background-size: 0% 100%; background-position: 0 0; -webkit-background-clip: text; background-clip: text; transition: letter-spacing 0.8s cubic-bezier(0.2, 0.7, 0.2, 1), background-size 0.7s cubic-bezier(0.2, 0.7, 0.2, 1), -webkit-text-stroke-color 0.45s ease; } .mix-cta:hover .mix-cta-line { letter-spacing: -0.01em; } .mix-cta:hover .mix-cta-line--stroke { background-size: 100% 100%; -webkit-text-stroke-color: var(--accent); } html[lang="fa"] .mix-cta-line--stroke { background-position: 100% 0; } html[lang="fa"] .mix-cta-line { font-family: var(--farsi-display, 'Lalezar', sans-serif); font-weight: 400; letter-spacing: 0; line-height: 1.05; font-size: clamp(56px, 13vw, 190px); } html[lang="fa"] .mix-cta-line--stroke { -webkit-text-stroke-width: 1.2px; } html[lang="fa"] .mix-cta:hover .mix-cta-line { letter-spacing: 0.02em; } /* ------------------------------------------------------------ Reduced motion ------------------------------------------------------------ */ @media (prefers-reduced-motion: reduce) { .mix-preloader { display: none; } html.mix-intro-wait .hero-kicker, html.mix-intro-wait .hero-meta, html.mix-intro-wait .hero-ctas, html.mix-intro-wait .hero-foot, html.mix-intro-wait .hero-name .hero-line { opacity: 1; transform: none; clip-path: none; } }