Skip to content

Q #11

Description

@23rus23

import React, { useEffect, useRef, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";

// Single-file React component for a futuristic SABSUS landing page
// Uses Tailwind CSS and Framer Motion. Default export a component.

export default function SABSUSGreenApple() {
const [lang, setLang] = useState("ru");
const [mouse, setMouse] = useState({ x: 0, y: 0 });
const [assembled, setAssembled] = useState(false);
const [flip, setFlip] = useState(false);
const containerRef = useRef(null);

// copy strings
const copy = {
ru: {
title: "GREEN APPLE",
subtitle:
"Новая эра интеллектуальных систем SABSUS — глубина, безопасность и масштабируемость.",
cta: "Запустить свою систему",
contact: "Почта: skl-viktoriya@yandex.ru",
},
en: {
title: "GREEN APPLE",
subtitle:
"A new era of intelligent systems — depth, security and scalable futures.",
cta: "Launch your system",
contact: "Email: skl-viktoriya@yandex.ru",
},
};

// mouse parallax handler
useEffect(() => {
const handleMove = (e) => {
const rect = containerRef.current?.getBoundingClientRect();
if (!rect) return;
const x = (e.clientX - rect.left) / rect.width - 0.5; // -0.5..0.5
const y = (e.clientY - rect.top) / rect.height - 0.5;
setMouse({ x, y });
};

window.addEventListener("mousemove", handleMove);
return () => window.removeEventListener("mousemove", handleMove);

}, []);

// scroll flip detection
useEffect(() => {
let lastY = window.scrollY;
const onScroll = () => {
const dy = window.scrollY - lastY;
if (Math.abs(dy) > 40) {
setFlip((f) => !f);
lastY = window.scrollY;
}
};
window.addEventListener("scroll", onScroll, { passive: true });
return () => window.removeEventListener("scroll", onScroll);
}, []);

// assemble shards after mount
useEffect(() => {
const t = setTimeout(() => setAssembled(true), 1200);
return () => clearTimeout(t);
}, []);

// generate rectangular 'abstracts'
const abstracts = Array.from({ length: 14 }).map((_, i) => ({
id: i,
w: 120 + (i % 4) * 40,
h: 40 + (i % 3) * 20,
top: Math.round(Math.random() * 70),
left: Math.round(Math.random() * 70),
rot: (Math.random() - 0.5) * 60,
glow: Math.random() > 0.6,
}));

// shards that will assemble into the outlined text using an SVG mask
const shardsCount = 24;
const shards = Array.from({ length: shardsCount }).map((_, i) => {
const rnd = (n) => Math.floor(Math.random() * n);
return {
id: i,
x0: rnd(1600) - 800,
y0: rnd(400) - 200,
x: 60 + rnd(680),
y: 30 + rnd(140),
rx: 2 + rnd(20),
ry: 2 + rnd(10),
dur: 0.9 + Math.random() * 1.2,
delay: Math.random() * 0.9,
};
});

return (
<div
ref={containerRef}
className="min-h-screen w-full bg-[radial-gradient(ellipse_at_top_right,#001219,#000814)] text-white overflow-hidden relative"
style={{
WebkitFontSmoothing: "antialiased",
MozOsxFontSmoothing: "grayscale",
}}
>
{/* Top bar with language switch */}



SABSUS

{lang === "ru" ? "Система" : "System"}



<button
onClick={() => setLang(lang === "ru" ? "en" : "ru")}
className="px-3 py-1 rounded-xl bg-white/6 backdrop-blur-sm border border-white/10 text-sm"
>
{lang === "ru" ? "EN" : "RU"}


  {/* Depth layers: background glow, particles */}
  <div
    aria-hidden
    className="absolute inset-0 -z-10 pointer-events-none"
    style={{
      background:
        "linear-gradient(120deg, rgba(16,185,129,0.08), rgba(79,70,229,0.06) 35%, rgba(14,165,233,0.04) 70%)",
      mixBlendMode: "screen",
    }}
  />

  {/* Abstract rectangles that react to mouse and flip on scroll */}
  {abstracts.map((a, idx) => {
    const moveX = mouse.x * (30 + idx * 6);
    const moveY = mouse.y * (18 + idx * 4);
    const rotate = mouse.x * (a.rot / 1.5);
    const scale = 1 + Math.abs(mouse.x) * 0.08;
    return (
      <motion.div
        key={a.id}
        className={`absolute rounded-2xl shadow-2xl/30 z-0 ${a.glow ? "filter blur-sm" : ""}`}
        initial={{ opacity: 0 }}
        animate={{
          x: `${a.left}vw`,
          y: `${a.top}vh`,
          rotateY: flip ? 180 : 0,
          opacity: 0.9,
          scale,
        }}
        transition={{ type: "spring", stiffness: 40 + idx * 5, damping: 12 }}
        style={{
          width: a.w,
          height: a.h,
          background: `linear-gradient(135deg, rgba(16,185,129,${0.08 + idx * 0.01}), rgba(79,70,229,${0.04 + idx * 0.005}))`,
          transform: `translate3d(${moveX}px, ${moveY}px, ${-idx * 6}px) rotate(${rotate}deg)`,
          border: "1px solid rgba(255,255,255,0.04)",
          boxShadow: "0 10px 40px rgba(2,6,23,0.6)",
          backdropFilter: "blur(6px)",
        }}
      />
    );
  })}

  {/* Center stage */}
  <main className="min-h-screen flex items-center justify-center relative z-20 px-6">
    <div className="max-w-5xl w-full grid grid-cols-1 md:grid-cols-3 gap-6 items-center">
      <div className="col-span-1 md:col-span-3 flex flex-col items-center text-center">
        {/* Big outline text made from shards inside an SVG mask */}
        <div className="relative w-full flex justify-center mb-6 pointer-events-none">
          <svg viewBox="0 0 1000 220" className="w-full max-w-4xl h-40 md:h-56">
            <defs>
              <mask id="text-mask">
                <rect width="100%" height="100%" fill="black" />
                <text
                  x="50%"
                  y="55%"
                  textAnchor="middle"
                  fontFamily="Inter, Roboto, system-ui, sans-serif"
                  fontWeight="800"
                  fontSize="120"
                  fill="white"
                  style={{ letterSpacing: 6 }}
                >
                  {copy[lang].title}
                </text>
              </mask>

              {/* Outline stroke for the title */}
              <filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
                <feGaussianBlur stdDeviation="6" result="coloredBlur" />
                <feMerge>
                  <feMergeNode in="coloredBlur" />
                  <feMergeNode in="SourceGraphic" />
                </feMerge>
              </filter>
            </defs>

            {/* Outline text */}
            <text
              x="50%"
              y="55%"
              textAnchor="middle"
              fontFamily="Inter, Roboto, system-ui, sans-serif"
              fontWeight="800"
              fontSize="120"
              fill="none"
              stroke="url(#grad)"
              strokeWidth="1.8"
              style={{ letterSpacing: 6, paintOrder: "stroke" }}
            >
              {copy[lang].title}
            </text>

            {/* Subtle gradient definition for stroke */}
            <linearGradient id="grad" x1="0" x2="1">
              <stop offset="0%" stopColor="#5EEAD4" />
              <stop offset="50%" stopColor="#60A5FA" />
              <stop offset="100%" stopColor="#7C3AED" />
            </linearGradient>

            {/* shards group clipped by text mask - they animate from dispersed to form the text body */}
            <g mask="url(#text-mask)">
              {shards.map((s) => (
                <motion.rect
                  key={s.id}
                  x={s.x0}
                  y={s.y0}
                  rx={s.rx}
                  ry={s.ry}
                  width={40 + (s.id % 5) * 8}
                  height={10 + (s.id % 3) * 6}
                  initial={{ x: s.x0, y: s.y0, opacity: 0 }}
                  animate={
                    assembled
                      ? { x: s.x, y: s.y, opacity: 1, rotate: (s.id % 2 ? 6 : -6) }
                      : { x: s.x0, y: s.y0, opacity: 0 }
                  }
                  transition={{ duration: s.dur, delay: s.delay, ease: "circOut" }}
                  style={{
                    fill: `rgba(255,255,255,${0.9 - (s.id % 7) * 0.06})`,
                    filter: "drop-shadow(0 6px 16px rgba(0,0,0,0.6))",
                  }}
                />
              ))}

              {/* After assembled, a subtle floating animation applied to group */}
              <motion.g
                animate={assembled ? { y: [0, -8, 0] } : { y: 0 }}
                transition={{ duration: 6, repeat: Infinity, ease: "easeInOut" }}
              />
            </g>
          </svg>
        </div>

        {/* Subtitle and CTA */}
        <p className="max-w-2xl text-sm md:text-base opacity-80 mb-6">
          {copy[lang].subtitle}
        </p>

        <div className="flex gap-4 items-center">
          <motion.button
            whileHover={{ y: -4, scale: 1.02 }}
            whileTap={{ scale: 0.98 }}
            className="px-8 py-3 rounded-full bg-gradient-to-r from-green-400/30 to-indigo-500/30 border border-white/10 backdrop-blur-md text-sm md:text-base"
            onClick={() => alert((lang === "ru" ? "Запуск..." : "Launching...") + "\n" + copy[lang].contact)}
          >
            {copy[lang].cta}
          </motion.button>

          <a
            href={`mailto:skl-viktoriya@yandex.ru`}
            className="text-xs md:text-sm opacity-70 underline underline-offset-2"
          >
            {copy[lang].contact}
          </a>
        </div>
      </div>
    </div>
  </main>

  {/* Footer decorative elements */}
  <footer className="absolute bottom-6 left-6 right-6 flex justify-between items-center text-xs opacity-60 z-30">
    <div>© SABSUS — {new Date().getFullYear()}</div>
    <div>Made for the future • Depth-driven UX</div>
  </footer>

  {/* Extra: subtle animated grid to give ZD space depth */}
  <svg className="pointer-events-none absolute inset-0 -z-20" width="100%" height="100%">
    <defs>
      <linearGradient id="gridGrad" x1="0" x2="1">
        <stop offset="0%" stopColor="#063F3B" stopOpacity="0.06" />
        <stop offset="100%" stopColor="#1E293B" stopOpacity="0.02" />
      </linearGradient>
    </defs>
    <rect width="100%" height="100%" fill="url(#gridGrad)" />
  </svg>
</div>

);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions