diff --git a/frontend/src/pages/Home.jsx b/frontend/src/pages/Home.jsx index aab9db7..ba264cf 100644 --- a/frontend/src/pages/Home.jsx +++ b/frontend/src/pages/Home.jsx @@ -15,17 +15,18 @@ import { } from "../components/icons/svgs"; import "../styles/Home.css"; -const BG = "#03060b"; +const BG = "#0a0b0d"; +const ACCENT = "#4c7af5"; const fadeEase = [0.16, 1, 0.3, 1]; const SECTION_IDS = ["hero", "discord", "web", "mobile", "individual", "cta"]; function fitText(ctx, text, maxWidth, startSize, minSize) { let size = startSize; - ctx.font = `800 ${size}px 'Outfit','Inter',sans-serif`; + ctx.font = `700 ${size}px 'General Sans','Outfit',sans-serif`; while (ctx.measureText(text).width > maxWidth && size > minSize) { size -= 2; - ctx.font = `800 ${size}px 'Outfit','Inter',sans-serif`; + ctx.font = `700 ${size}px 'General Sans','Outfit',sans-serif`; } return size; @@ -37,7 +38,7 @@ function drawServiceIcon(ctx, paths) { }); } -function drawFace(label, iconPaths, color) { +function drawFace(label, iconPaths, moduleTag) { const cv = document.createElement("canvas"); cv.width = 1024; cv.height = 1024; @@ -45,37 +46,54 @@ function drawFace(label, iconPaths, color) { const c = cv.getContext("2d"); c.clearRect(0, 0, 1024, 1024); - const iconSize = 335; - const iconCenterY = 365; + c.strokeStyle = "rgba(244,243,239,0.14)"; + c.lineWidth = 2; + const m = 54; + const corner = 46; + [ + [m, m, 1], + [1024 - m, m, -1], + [m, 1024 - m, 1], + [1024 - m, 1024 - m, -1], + ].forEach(([x, y, dx]) => { + c.beginPath(); + c.moveTo(x, y + corner * (y < 512 ? 1 : -1)); + c.lineTo(x, y); + c.lineTo(x + corner * dx, y); + c.stroke(); + }); + + c.font = `600 22px 'JetBrains Mono', monospace`; + c.fillStyle = "rgba(244,243,239,0.38)"; + c.textAlign = "left"; + c.fillText(moduleTag, m + 14, m + 40); + + const iconSize = 300; + const iconCenterY = 380; c.save(); c.translate(512 - iconSize / 2, iconCenterY - iconSize / 2); c.scale(iconSize / 24, iconSize / 24); - c.strokeStyle = color; - c.fillStyle = color; - c.lineWidth = 1.9; + c.strokeStyle = ACCENT; + c.fillStyle = ACCENT; + c.lineWidth = 1.7; c.lineCap = "round"; c.lineJoin = "round"; - c.shadowBlur = 16; - c.shadowColor = color; drawServiceIcon(c, iconPaths); c.restore(); - c.shadowBlur = 0; - c.strokeStyle = `${color}55`; - c.lineWidth = 3; + c.strokeStyle = "rgba(244,243,239,0.16)"; + c.lineWidth = 2; c.beginPath(); - c.moveTo(260, 635); - c.lineTo(764, 635); + c.moveTo(260, 640); + c.lineTo(764, 640); c.stroke(); - c.fillStyle = color; + c.fillStyle = "#f4f3ef"; c.textAlign = "center"; c.textBaseline = "middle"; - c.shadowBlur = 22; - c.shadowColor = color; - fitText(c, label, 780, 84, 48); - c.fillText(label, 512, 760); + fitText(c, label, 780, 72, 44); + c.fillText(label, 512, 730); const texture = new THREE.CanvasTexture(cv); texture.anisotropy = 16; @@ -104,21 +122,21 @@ function Particles({ count, progressRef }) { if (!ref.current) return; const time = state.clock.elapsedTime; - ref.current.rotation.y = time * 0.005 + progressRef.current * 0.1; - ref.current.position.y = Math.sin(time * 0.08) * 0.05; + ref.current.rotation.y = time * 0.004 + progressRef.current * 0.08; + ref.current.position.y = Math.sin(time * 0.07) * 0.04; }); return ( - + ); } -function AccentCubes({ mobile }) { +function ModuleFragments({ mobile }) { const groupRef = useRef(); - const cubes = useMemo(() => { + const fragments = useMemo(() => { const amount = mobile ? 3 : 5; return Array.from({ length: amount }).map((_, index) => ({ @@ -127,7 +145,7 @@ function AccentCubes({ mobile }) { (Math.random() - 0.5) * 6, -4 - Math.random() * 5, ], - scale: 0.04 + Math.random() * 0.07, + scale: 0.05 + Math.random() * 0.06, phase: Math.random() * Math.PI * 2, })); }, [mobile]); @@ -138,21 +156,21 @@ function AccentCubes({ mobile }) { const time = state.clock.elapsedTime; groupRef.current.children.forEach((child, index) => { - child.position.y = cubes[index].pos[1] + Math.sin(time * 0.3 + cubes[index].phase) * 0.12; - child.rotation.x = time * 0.035 + cubes[index].phase; - child.rotation.y = time * 0.048 + cubes[index].phase; + child.position.y = fragments[index].pos[1] + Math.sin(time * 0.25 + fragments[index].phase) * 0.1; + child.rotation.x = time * 0.025 + fragments[index].phase; + child.rotation.y = time * 0.035 + fragments[index].phase; }); }); return ( - {cubes.map((cube, index) => ( - + {fragments.map((frag, index) => ( + - + - + ))} @@ -173,8 +191,8 @@ function Grid() { const step = 1024 / amount; for (let i = 0; i <= amount; i += 1) { - const alpha = 0.38 - (i / amount) * 0.06; - c.strokeStyle = `rgba(16,42,100,${alpha})`; + const alpha = 0.16 - (i / amount) * 0.03; + c.strokeStyle = `rgba(244,243,239,${alpha})`; c.lineWidth = 1; c.beginPath(); c.moveTo(i * step, 0); @@ -194,7 +212,7 @@ function Grid() { return new THREE.MeshBasicMaterial({ map: texture, transparent: true, - opacity: 0.3, + opacity: 0.16, depthWrite: false, }); }, []); @@ -206,7 +224,7 @@ function Grid() { ); } -function NDissolveOverlay({ visible }) { +function AssemblyOverlay({ visible }) { const cvRef = useRef(); const rafRef = useRef(null); const startRef = useRef(null); @@ -232,56 +250,38 @@ function NDissolveOverlay({ visible }) { function render(timestamp) { if (!startRef.current) startRef.current = timestamp; - const raw = Math.min((timestamp - startRef.current) / 1800, 1); + const raw = Math.min((timestamp - startRef.current) / 1600, 1); const alpha = raw < 0.5 ? 4 * raw * raw * raw : 1 - Math.pow(-2 * raw + 2, 3) / 2; const ctx = cv.getContext("2d"); const width = cv.width; const height = cv.height; const cx = width / 2; const cy = height / 2; - const size = Math.min(width, height) * 0.28; - const lineWidth = size * 0.11; - const x0 = cx - size * 0.28; - const x1 = cx + size * 0.28; - const y0 = cy - size * 0.42; - const y1 = cy + size * 0.42; - const maxAlpha = 0.35 * alpha; + const size = Math.min(width, height) * 0.24; + const lineWidth = size * 0.06; + const x0 = cx - size * 0.3; + const x1 = cx + size * 0.3; + const y0 = cy - size * 0.4; + const y1 = cy + size * 0.4; + const maxAlpha = 0.28 * alpha; ctx.clearRect(0, 0, width, height); - const halo = ctx.createRadialGradient(cx, cy, size * 0.1, cx, cy, size * 1.1); - halo.addColorStop(0, `rgba(96, 80, 255, ${0.12 * alpha})`); - halo.addColorStop(0.5, `rgba(80, 40, 200, ${0.05 * alpha})`); - halo.addColorStop(1, "rgba(4, 13, 30, 0)"); - ctx.fillStyle = halo; - ctx.fillRect(0, 0, width, height); - - const gradient = ctx.createLinearGradient(x0, y0, x1, y1); - gradient.addColorStop(0, `rgba(96, 200, 255, ${maxAlpha})`); - gradient.addColorStop(0.38, `rgba(192, 132, 252, ${maxAlpha})`); - gradient.addColorStop(0.72, `rgba(128, 96, 255, ${maxAlpha})`); - gradient.addColorStop(1, `rgba(240, 238, 255, ${maxAlpha})`); - - ctx.shadowBlur = 24 * alpha; - ctx.shadowColor = `rgba(128, 96, 255, ${maxAlpha})`; - ctx.strokeStyle = gradient; + ctx.strokeStyle = `rgba(76,122,245,${maxAlpha})`; ctx.lineWidth = lineWidth; ctx.lineCap = "round"; ctx.lineJoin = "round"; + ctx.beginPath(); - ctx.moveTo(x0, y1); + ctx.moveTo(x0, y0 + lineWidth * 2); ctx.lineTo(x0, y0); - ctx.lineTo(x1, y1); - ctx.lineTo(x1, y0); + ctx.lineTo(x0 + lineWidth * 2, y0); ctx.stroke(); - ctx.shadowBlur = 10 * alpha; - ctx.shadowColor = `rgba(220, 210, 255, ${maxAlpha * 0.5})`; - ctx.strokeStyle = `rgba(255, 255, 255, ${0.12 * alpha})`; - ctx.lineWidth = lineWidth * 0.11; ctx.beginPath(); - ctx.moveTo(x0 + lineWidth * 0.55, y0 + lineWidth * 0.85); - ctx.lineTo(x1 - lineWidth * 0.55, y1 - lineWidth * 0.85); + ctx.moveTo(x1 - lineWidth * 2, y1); + ctx.lineTo(x1, y1); + ctx.lineTo(x1, y1 - lineWidth * 2); ctx.stroke(); if (raw < 1) rafRef.current = requestAnimationFrame(render); @@ -395,28 +395,28 @@ function useCubeController(progressRef, pointerRef, reducedMotion, mobile, cubeR targetPosition.current.lerp(target, 0.1); cubeRef.current.position.lerp(targetPosition.current, 0.12); - cubeRef.current.position.y += Math.sin(time * 0.4) * 0.0015; + cubeRef.current.position.y += Math.sin(time * 0.35) * 0.0012; if (p < 0.08 && !reducedMotion) { - cubeRef.current.rotation.y += 0.006; + cubeRef.current.rotation.y += 0.005; } else { const targetRotY = THREE.MathUtils.lerp(faceRotations[index], faceRotations[nextIndex], blend); cubeRef.current.rotation.y = THREE.MathUtils.lerp( cubeRef.current.rotation.y, - targetRotY + px * 0.045, + targetRotY + px * 0.04, 0.11 ); } cubeRef.current.rotation.x = THREE.MathUtils.lerp( cubeRef.current.rotation.x, - -0.12 + py * 0.018, + -0.1 + py * 0.016, 0.09 ); cubeRef.current.rotation.z = THREE.MathUtils.lerp( cubeRef.current.rotation.z, - Math.sin(time * 0.1) * 0.004, + Math.sin(time * 0.08) * 0.003, 0.08 ); @@ -427,7 +427,7 @@ function useCubeController(progressRef, pointerRef, reducedMotion, mobile, cubeR fade = 1 - t * t * (3 - 2 * t); } - cubeRef.current.scale.setScalar(mobile ? fade * 1.02 : fade * 1.08); + cubeRef.current.scale.setScalar(mobile ? fade * 1.0 : fade * 1.05); cubeRef.current.traverse((child) => { if (child.material && child.material.transparent) { @@ -436,7 +436,7 @@ function useCubeController(progressRef, pointerRef, reducedMotion, mobile, cubeR }); if (edgeRef.current) { - edgeRef.current.material.opacity = fade * 0.85; + edgeRef.current.material.opacity = fade * 0.5; } }); } @@ -447,10 +447,10 @@ function Scene({ progressRef, pointerRef, reducedMotion, mobile, cubeTexts = {} const textures = useMemo( () => ({ - discord: drawFace(cubeTexts.discord || "Discord Bot", SERVICE_ICON_PATHS.discord, "#5865f2"), - web: drawFace(cubeTexts.web || "Web Entwicklung", SERVICE_ICON_PATHS.web, "#0ea5e9"), - app: drawFace(cubeTexts.app || "Mobile App", SERVICE_ICON_PATHS.app, "#ec4899"), - individual: drawFace(cubeTexts.individual || "Individual", SERVICE_ICON_PATHS.individual, "#a855f7"), + discord: drawFace(cubeTexts.discord || "Discord Bot", SERVICE_ICON_PATHS.discord, "MOD_01 · AUTOMATION"), + web: drawFace(cubeTexts.web || "Web Entwicklung", SERVICE_ICON_PATHS.web, "MOD_02 · FRONTEND"), + app: drawFace(cubeTexts.app || "Mobile App", SERVICE_ICON_PATHS.app, "MOD_03 · APPS"), + individual: drawFace(cubeTexts.individual || "Individual", SERVICE_ICON_PATHS.individual, "MOD_04 · SYSTEMS"), }), [cubeTexts] ); @@ -467,23 +467,25 @@ function Scene({ progressRef, pointerRef, reducedMotion, mobile, cubeTexts = {} - - - + + + - + + + + + @@ -491,8 +493,8 @@ function Scene({ progressRef, pointerRef, reducedMotion, mobile, cubeTexts = {} - - + + ); } @@ -536,36 +538,26 @@ function HomeCanvas({ progressRef, pointerRef, webglSupported, ctaVisible, cubeT /> - + ); } -function TechList({ items }) { - return ( -
- {items.map((item) => ( - {item} - ))} -
- ); -} - -function ServiceSection({ id, serviceHref, icon, align = "left", title, desc, children, learnMore }) { +function ServiceSection({ id, serviceHref, icon, align = "left", tag, title, desc, learnMore }) { return (
+ {tag && {tag}} {icon &&
{icon}
}

{title}

{desc}

- {children} {learnMore} @@ -577,6 +569,24 @@ function ServiceSection({ id, serviceHref, icon, align = "left", title, desc, ch ); } +const PROJECTS = [ + { + tag: "WEB PLATFORM", + title: "Buchungssystem für einen Dienstleistungsbetrieb", + desc: "Individuelle Web-Anwendung mit Terminverwaltung, Kundenportal und Anbindung an bestehende Systeme.", + }, + { + tag: "AUTOMATION", + title: "Discord-Infrastruktur für eine Community-Plattform", + desc: "Skalierbarer Bot mit Rollenverwaltung, Ticket-System und automatisierten Workflows über Webhooks.", + }, + { + tag: "INTERNAL TOOLING", + title: "Admin-Panel zur Prozessautomatisierung", + desc: "Internes Werkzeug zur Steuerung wiederkehrender Abläufe, angebunden über n8n und eine eigene API.", + }, +]; + export default function Home() { const { t } = useLanguage(); const progressRef = useRef(0); @@ -701,24 +711,27 @@ export default function Home() {
- {t("home.hero.kicker")} + Software Engineering Studio

- {t("home.hero.title_1")} + Software, gebaut
- {t("home.hero.title_2")} + um eure Idee.

-

{t("home.hero.description")}

+

+ {t("home.hero.description") || + "Nexory entwickelt individuelle Software, Webanwendungen und Automatisierungen für reale Anforderungen."} +

- - {t("home.hero.cta.primary")} + + Projekt starten - - {t("home.hero.cta.secondary")} + + {t("nav.services")}
@@ -729,7 +742,7 @@ export default function Home() { onClick={() => document.getElementById("discord")?.scrollIntoView({ behavior: "smooth" })} > - {t("home.hero.scroll_hint")} + {t("home.hero.scroll_hint") || "Scrollen"}
@@ -738,63 +751,94 @@ export default function Home() { serviceHref="/services#discord-bots" icon={} align="left" + tag="Modul 01 — Automation" title={t("home.section.discord.title")} desc={t("home.section.discord.desc")} learnMore={t("home.section.learn_more")} - > - - + /> } align="right" + tag="Modul 02 — Frontend" title={t("home.section.web.title")} desc={t("home.section.web.desc")} learnMore={t("home.section.learn_more")} - > - - + /> } align="left" + tag="Modul 03 — Apps" title={t("home.section.app.title")} desc={t("home.section.app.desc")} learnMore={t("home.section.learn_more")} - > - - + /> } align="right" + tag="Modul 04 — Systeme" title={t("home.section.individual.title")} desc={t("home.section.individual.desc")} learnMore={t("home.section.learn_more")} - > - - + /> + +
+
+ + Beispielhafte Projekte +

Systeme, die wir so oder ähnlich gebaut haben.

+
+ +
+ {PROJECTS.map((project, i) => ( + + {project.tag} +

{project.title}

+

{project.desc}

+
+ ))} +
+
+
- {t("home.about.title")} -

{t("home.cta.title")}

-

{t("home.about.desc")}

+ Kontakt +

+ Habt ihr eine Idee? +
+ Lasst sie uns bauen. +

+

{t("home.about.desc") || "Wir sind ein kleines Team, das Software von der Architektur bis zum Deployment verantwortet."}

- {t("home.cta.button")} + {t("home.cta.button") || "Kontakt aufnehmen"} @@ -805,4 +849,4 @@ export default function Home() {
); -} +} \ No newline at end of file diff --git a/frontend/src/styles/Home.css b/frontend/src/styles/Home.css index fb0c968..d1aff53 100644 --- a/frontend/src/styles/Home.css +++ b/frontend/src/styles/Home.css @@ -1,7 +1,7 @@ .home-page { position: relative; - background: #03060b; - color: #fff; + background: var(--bg); + color: var(--text); min-height: 100dvh; overflow-x: hidden; } @@ -13,22 +13,10 @@ z-index: 0; pointer-events: none; background: - linear-gradient(90deg, rgba(126, 155, 190, 0.035) 1px, transparent 1px), - linear-gradient(0deg, rgba(126, 155, 190, 0.028) 1px, transparent 1px), - linear-gradient(135deg, transparent 0 49%, rgba(110, 231, 242, 0.035) 49.08% 49.18%, transparent 49.3% 100%); - background-size: 96px 96px, 96px 96px, 560px 560px; - mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.78), rgba(0, 0, 0, 0.34) 62%, transparent 100%); -} - -.home-page::after { - content: ""; - position: fixed; - inset: 0; - z-index: 0; - pointer-events: none; - background: - linear-gradient(90deg, rgba(3, 6, 11, 0.76) 0%, rgba(3, 6, 11, 0.36) 34%, transparent 58%), - linear-gradient(180deg, rgba(3, 6, 11, 0.2) 0%, transparent 35%, rgba(3, 6, 11, 0.38) 100%); + linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px), + linear-gradient(0deg, rgba(255, 255, 255, 0.018) 1px, transparent 1px); + background-size: 96px 96px, 96px 96px; + mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.2) 62%, transparent 100%); } .home-canvas-shell { @@ -36,7 +24,6 @@ inset: 0; z-index: 1; pointer-events: none; - filter: saturate(1.08) contrast(1.04) brightness(1.1); } .home-canvas-shell > canvas { @@ -52,20 +39,13 @@ display: flex; align-items: center; justify-content: center; - background: - linear-gradient(115deg, transparent 0 42%, rgba(110, 231, 242, 0.06) 42.2% 42.42%, transparent 42.62% 100%), - linear-gradient(180deg, rgba(143, 179, 255, 0.035), transparent 58%), - #03060b; + background: var(--bg); } .home-static-cube { font-size: 120px; - font-weight: 900; - letter-spacing: 0; - background: linear-gradient(135deg, #dff9ff 0%, #6ee7f2 100%); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; + font-weight: 800; + color: var(--accent); user-select: none; } @@ -74,10 +54,8 @@ inset: 0; z-index: 0; pointer-events: none; - background: - linear-gradient(115deg, transparent 0 18%, rgba(255, 255, 255, 0.02) 18.08% 18.18%, transparent 18.32% 100%), - linear-gradient(90deg, transparent 0 65%, rgba(110, 231, 242, 0.028) 65.08% 65.18%, transparent 65.32% 100%); - opacity: 0.64; + background: linear-gradient(180deg, transparent 0%, rgba(6, 7, 8, 0.4) 100%); + opacity: 0.7; } .journey-section { @@ -93,26 +71,18 @@ width: 100%; } -.journey-section::before, -.journey-section::after { +.journey-section::before { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; -} - -.journey-section::before { background: - linear-gradient(90deg, rgba(126, 155, 190, 0.026) 1px, transparent 1px), - linear-gradient(0deg, rgba(126, 155, 190, 0.018) 1px, transparent 1px); + linear-gradient(90deg, rgba(255, 255, 255, 0.02) 1px, transparent 1px), + linear-gradient(0deg, rgba(255, 255, 255, 0.014) 1px, transparent 1px); background-size: 96px 96px; - mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0.42), rgba(0, 0, 0, 0.14) 42%, transparent 78%); - opacity: 0.16; -} - -.journey-section::after { - display: none; + mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.1) 42%, transparent 78%); + opacity: 0.14; } .hero-journey-section { @@ -137,48 +107,43 @@ .journey-kicker { display: inline-flex; align-items: center; - gap: 8px; + gap: 9px; + font-family: var(--font-mono); font-size: 10.5px; - font-weight: 700; - letter-spacing: 0.22em; + font-weight: 600; + letter-spacing: 0.17em; text-transform: uppercase; - color: #6ee7f2; + color: var(--accent-strong); margin-bottom: 28px; - border: 0; - padding: 0; - border-radius: 0; - background: transparent; } .journey-kicker::before { - content: "+"; - font-size: 13px; - line-height: 1; - color: #6ee7f2; - opacity: 0.8; + content: ""; + width: 5px; + height: 5px; + border-radius: 50%; + background: var(--accent-strong); + flex-shrink: 0; } .hero-journey-content h1 { + font-family: var(--font-display); font-size: clamp(40px, 5.8vw, 76px); - font-weight: 800; + font-weight: 700; line-height: 1.06; - letter-spacing: 0; + letter-spacing: -0.015em; margin: 0 0 28px; - color: #f0f4ff; - max-width: 560px; + color: var(--text); + max-width: 620px; } .hero-accent { - background: linear-gradient(130deg, #f7fbff 0%, #6ee7f2 46%, #8fb3ff 100%); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - filter: none; + color: var(--accent-strong); } .hero-desc { font-size: clamp(14px, 1.45vw, 16.5px); - line-height: 1.74; - color: #6a7590; + line-height: 1.75; + color: var(--text-muted); max-width: 430px; - margin: 0 0 48px; + margin: 0 0 46px; font-weight: 400; } @@ -209,30 +174,14 @@ min-width: 0; max-width: 540px; padding: 44px 0 44px 34px; - border-radius: 0; - background: transparent; - backdrop-filter: none; - -webkit-backdrop-filter: none; - border: 0; - border-left: 1px solid rgba(122, 151, 185, 0.18); - box-shadow: - none; - transition: - border-color 0.4s cubic-bezier(0.16, 1, 0.3, 1), - transform 0.4s cubic-bezier(0.16, 1, 0.3, 1); + border-left: 1px solid var(--border); + transition: border-color 0.4s var(--ease-out-strong); } -.service--left .service-grid { - grid-template-areas: "text cube"; -} -.service--left .service-text { - grid-area: text; - justify-self: start; -} +.service--left .service-grid { grid-template-areas: "text cube"; } +.service--left .service-text { grid-area: text; justify-self: start; } -.service--right .service-grid { - grid-template-areas: "cube text"; -} +.service--right .service-grid { grid-template-areas: "cube text"; } .service--right .service-text { grid-area: text; justify-self: end; @@ -240,123 +189,57 @@ text-align: right; padding: 44px 34px 44px 0; border-left: 0; - border-right: 1px solid rgba(122, 151, 185, 0.18); + border-right: 1px solid var(--border); } #hero { - background: - linear-gradient(90deg, rgba(3, 6, 11, 0.72) 0%, rgba(3, 6, 11, 0.38) 34%, transparent 64%), - linear-gradient(180deg, rgba(3, 6, 11, 0.2), transparent 38%, rgba(3, 6, 11, 0.24)); + background: linear-gradient(90deg, rgba(10, 11, 13, 0.55) 0%, rgba(10, 11, 13, 0.2) 40%, transparent 68%); } -#hero::before { - opacity: 0.18; - background: - linear-gradient(90deg, rgba(126, 155, 190, 0.036) 1px, transparent 1px), - linear-gradient(0deg, rgba(126, 155, 190, 0.024) 1px, transparent 1px); - background-size: 88px 88px; - mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0.58), rgba(0, 0, 0, 0.12) 48%, transparent 74%); -} - -#discord { - --section-rgb: 88, 101, 242; - --section-color: #5865f2; - background: transparent; - border-top: 1px solid rgba(88, 101, 242, 0.06); - border-bottom: 1px solid rgba(88, 101, 242, 0.06); -} - -#web { - --section-rgb: 14, 165, 233; - --section-color: #0ea5e9; - background: transparent; - border-bottom: 1px solid rgba(14, 165, 233, 0.06); -} +#discord, #web, #mobile, #individual { background: transparent; border-top: 1px solid var(--border); } +#discord { border-bottom: 1px solid var(--border); } -#mobile { - --section-rgb: 236, 72, 153; - --section-color: #ec4899; - background: transparent; - border-bottom: 1px solid rgba(236, 72, 153, 0.06); -} - -#individual { - --section-rgb: 168, 85, 247; - --section-color: #a855f7; - background: transparent; - border-bottom: 1px solid rgba(168, 85, 247, 0.06); -} - -.service-journey-section::before { - opacity: 1; - background: - linear-gradient(90deg, rgba(3, 6, 11, 0.64) 0%, rgba(3, 6, 11, 0.24) 38%, transparent 68%), - linear-gradient(90deg, rgba(var(--section-rgb), 0.045), transparent 42%), - linear-gradient(90deg, rgba(var(--section-rgb), 0.08) 1px, transparent 1px), - linear-gradient(0deg, rgba(126, 155, 190, 0.018) 1px, transparent 1px); - background-size: auto, auto, 92px 92px, 92px 92px; - mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0.16) 52%, transparent 78%); -} - -.service-journey-section::after { - display: none; -} - -.service-journey-section.service--right::before { - background: - linear-gradient(270deg, rgba(3, 6, 11, 0.64) 0%, rgba(3, 6, 11, 0.24) 38%, transparent 68%), - linear-gradient(270deg, rgba(var(--section-rgb), 0.045), transparent 42%), - linear-gradient(90deg, rgba(var(--section-rgb), 0.08) 1px, transparent 1px), - linear-gradient(0deg, rgba(126, 155, 190, 0.018) 1px, transparent 1px); - background-size: auto, auto, 92px 92px, 92px 92px; - mask-image: linear-gradient(270deg, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0.16) 52%, transparent 78%); -} - -#cta { - background: - linear-gradient(90deg, transparent 0%, rgba(3, 6, 11, 0.36) 50%, transparent 100%), - linear-gradient(180deg, transparent, rgba(3, 6, 11, 0.28)); - border-top: 1px solid rgba(110, 231, 242, 0.08); -} - -#cta::after { - display: none; +.service-tag { + font-family: var(--font-mono); + font-size: 10.5px; + font-weight: 600; + letter-spacing: 0.13em; + text-transform: uppercase; + color: var(--accent-strong); + margin-bottom: 18px; } .svc-icon { display: inline-flex; align-items: center; justify-content: center; - width: 52px; - height: 52px; - border-radius: 12px; - margin-bottom: 24px; - background: rgba(110, 231, 242, 0.08); - border: 1px solid rgba(110, 231, 242, 0.2); - color: #6ee7f2; + width: 48px; + height: 48px; + border-radius: 10px; + margin-bottom: 22px; + background: var(--accent-10); + border: 1px solid var(--accent-24); + color: var(--accent-strong); transition: background 180ms var(--ease-out-strong), border-color 180ms var(--ease-out-strong), transform 180ms var(--ease-out-strong); } .svc-icon:hover { - background: rgba(110, 231, 242, 0.11); - border-color: rgba(110, 231, 242, 0.3); + background: var(--accent-16); + border-color: var(--accent-40); transform: translateY(-1px); } -#discord .svc-icon { background: rgba(88,101,242,0.10); border-color: rgba(88,101,242,0.22); color: #7888f8; } -#web .svc-icon { background: rgba(14,165,233,0.08); border-color: rgba(14,165,233,0.20); color: #38b8f8; } -#mobile .svc-icon { background: rgba(236,72,153,0.08); border-color: rgba(236,72,153,0.20); color: #e878b8; } -#individual .svc-icon { background: rgba(168,85,247,0.08); border-color: rgba(168,85,247,0.20); color: #c078f8; } .service-journey-section h2 { position: relative; - font-size: clamp(28px, 3.4vw, 48px); - font-weight: 800; - line-height: 1.08; - letter-spacing: 0; + font-family: var(--font-display); + font-size: clamp(26px, 3.2vw, 44px); + font-weight: 600; + line-height: 1.12; + letter-spacing: -0.015em; margin: 0 0 18px; - color: #eef0ff; + color: var(--text); padding-bottom: 18px; } .service-journey-section h2::after { @@ -364,34 +247,22 @@ position: absolute; bottom: 0; left: 0; - width: 40px; - height: 3px; - border-radius: 2px; - background: #6ee7f2; + width: 32px; + height: 2px; + background: var(--accent); } -.service--right .service-text h2::after { - left: auto; - right: 0; -} -#discord .service-text h2::after { background: #5865f2; } -#web .service-text h2::after { background: #0ea5e9; } -#mobile .service-text h2::after { background: #ec4899; } -#individual .service-text h2::after { background: #a855f7; } +.service--right .service-text h2::after { left: auto; right: 0; } .service-journey-section .service-text > p { font-size: 15.5px; - line-height: 1.74; - color: #5a637a; + line-height: 1.75; + color: var(--text-muted); max-width: 380px; - margin: 0 0 28px; + margin: 0 0 30px; font-weight: 400; } -.journey-actions { - display: flex; - gap: 14px; - align-items: center; -} +.journey-actions { display: flex; gap: 14px; align-items: center; } .journey-actions-center { justify-content: center; } .home-primary-button { @@ -399,119 +270,79 @@ align-items: center; gap: 9px; padding: 13px 28px; - border-radius: 999px; - background: linear-gradient(135deg, #1e5fe7 0%, #21aabd 100%); - color: #fff; + border-radius: 8px; + background: var(--accent); + color: #ffffff; font-size: 14px; - font-weight: 700; + font-weight: 600; text-decoration: none; - border: none; - box-shadow: 0 12px 26px rgba(20, 85, 140, 0.24); + border: 1px solid var(--accent); transition: transform 160ms var(--ease-out-strong), - box-shadow 180ms var(--ease-out-strong), - filter 180ms var(--ease-out-strong); + background 180ms var(--ease-out-strong), + border-color 180ms var(--ease-out-strong); white-space: nowrap; } .home-primary-button:hover { + background: var(--accent-strong); + border-color: var(--accent-strong); transform: translateY(-1px); - box-shadow: 0 16px 30px rgba(20, 85, 140, 0.32); - filter: brightness(1.05); + color: #ffffff; } .home-primary-button:active, .home-secondary-button:active, -.journey-link:active { - transform: scale(0.98); -} +.journey-link:active { transform: scale(0.98); } .home-secondary-button { display: inline-flex; align-items: center; gap: 9px; padding: 13px 28px; - border-radius: 100px; - background: rgba(255, 255, 255, 0.04); - color: rgba(200, 210, 255, 0.72); + border-radius: 8px; + background: transparent; + color: var(--text-muted); font-size: 14px; font-weight: 600; text-decoration: none; - border: 1.5px solid rgba(180, 190, 255, 0.1); + border: 1px solid var(--border); transition: transform 160ms var(--ease-out-strong), - background 180ms var(--ease-out-strong), border-color 180ms var(--ease-out-strong), color 180ms var(--ease-out-strong); white-space: nowrap; } .home-secondary-button:hover { - transform: translateY(-2px); - background: rgba(255, 255, 255, 0.08); - border-color: rgba(180, 190, 255, 0.22); - color: #e0e8ff; -} - -.journey-tags { - display: flex; - flex-wrap: wrap; - gap: 8px; - margin-bottom: 36px; -} -.service--right .service-text .journey-tags { - justify-content: flex-end; -} - -.journey-tags span { - padding: 5px 14px; - border-radius: 100px; - background: rgba(72, 88, 232, 0.07); - border: 1px solid rgba(72, 88, 232, 0.16); - font-size: 11.5px; - font-weight: 600; - color: #7080a8; - transition: - background 160ms var(--ease-out-strong), - border-color 160ms var(--ease-out-strong), - color 160ms var(--ease-out-strong); - cursor: default; - letter-spacing: 0.01em; -} -.journey-tags span:hover { - background: rgba(120, 100, 255, 0.09); - border-color: rgba(110, 231, 242, 0.22); - color: #9ca8dc; + border-color: var(--border-hover); + color: var(--text); } .journey-link { display: inline-flex; align-items: center; gap: 8px; - color: #7080b8; + color: var(--text); font-size: 13px; - font-weight: 700; + font-weight: 600; text-decoration: none; - letter-spacing: 0.02em; - border: 1px solid rgba(112, 128, 184, 0.2); + border: 1px solid var(--border); padding: 8px 16px 8px 14px; border-radius: 100px; - background: rgba(112, 128, 184, 0.06); + background: transparent; transition: gap 160ms var(--ease-out-strong), - color 160ms var(--ease-out-strong), border-color 160ms var(--ease-out-strong), - background 160ms var(--ease-out-strong), - transform 120ms var(--ease-out-strong); + background 160ms var(--ease-out-strong); } .journey-link:hover { gap: 12px; - color: #a8b8ff; - border-color: rgba(168, 184, 255, 0.32); - background: rgba(168, 184, 255, 0.09); + border-color: var(--accent-40); + background: var(--accent-06); } @keyframes scrollPulse { - 0%, 100% { transform: translateX(-50%) translateY(0px); opacity: 0.32; } - 50% { transform: translateX(-50%) translateY(7px); opacity: 0.58; } + 0%, 100% { transform: translateX(-50%) translateY(0px); opacity: 0.3; } + 50% { transform: translateX(-50%) translateY(7px); opacity: 0.55; } } .journey-scroll-cue { position: absolute; @@ -523,18 +354,80 @@ gap: 9px; background: none; border: none; - color: rgba(180, 192, 255, 0.32); + color: var(--text-dim); + font-family: var(--font-mono); font-size: 10px; - font-weight: 600; - letter-spacing: 0.2em; + font-weight: 500; + letter-spacing: 0.16em; text-transform: uppercase; cursor: pointer; padding: 8px; animation: scrollPulse 3.2s ease-in-out infinite; - font-family: inherit; z-index: 3; } -.journey-scroll-cue:hover { color: rgba(180, 192, 255, 0.65); } +.journey-scroll-cue:hover { color: var(--text-muted); } + +.projects-journey-section { min-height: 86dvh; } +.projects-title { + font-family: var(--font-display); + font-size: clamp(24px, 2.8vw, 36px); + font-weight: 600; + color: var(--text); + margin: 0 0 44px; + letter-spacing: -0.015em; + max-width: 640px; +} +.projects-list { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 22px; +} +.project-card { + border: 1px solid var(--border); + border-radius: 12px; + padding: 30px 26px; + background: var(--surface); + display: flex; + flex-direction: column; + transition: + border-color 220ms var(--ease-out-strong), + transform 220ms var(--ease-out-strong), + box-shadow 220ms var(--ease-out-strong); +} +.project-card:nth-child(2) { margin-top: 18px; } +.project-card:hover { + border-color: var(--accent-24); + transform: translateY(-4px); + box-shadow: var(--shadow-soft); +} +.project-tag { + font-family: var(--font-mono); + font-size: 10px; + font-weight: 600; + letter-spacing: 0.1em; + color: var(--accent-strong); + margin-bottom: 16px; +} +.project-card h3 { + font-family: var(--font-display); + font-size: 18px; + font-weight: 600; + color: var(--text); + margin: 0 0 12px; + line-height: 1.36; +} +.project-card p { + font-size: 13.5px; + line-height: 1.68; + color: var(--text-muted); + margin: 0; + flex: 1; +} + +#cta { + background: linear-gradient(180deg, transparent, rgba(76, 122, 245, 0.03)); + border-top: 1px solid var(--border); +} .final-journey-section { min-height: 82vh; @@ -552,40 +445,39 @@ } .final-journey-content .journey-kicker { margin-bottom: 20px; } .final-journey-content h2 { + font-family: var(--font-display); font-size: clamp(32px, 4.4vw, 58px); - font-weight: 800; - line-height: 1.08; - letter-spacing: 0; + font-weight: 600; + line-height: 1.14; + letter-spacing: -0.015em; margin: 0 0 20px; - color: #e8ecff; + color: var(--text); } .final-journey-content > p { - font-size: 16.5px; - line-height: 1.74; - color: #5a637a; + font-size: 16px; + line-height: 1.75; + color: var(--text-muted); max-width: 500px; margin-bottom: 48px; } ::-webkit-scrollbar { width: 5px; } -::-webkit-scrollbar-track { background: #05070c; } -::-webkit-scrollbar-thumb { background: rgba(110, 231, 242, 0.22); border-radius: 3px; } -::-webkit-scrollbar-thumb:hover { background: rgba(110, 231, 242, 0.36); } +::-webkit-scrollbar-track { background: var(--bg-deep); } +::-webkit-scrollbar-thumb { background: var(--accent-24); border-radius: 3px; } +::-webkit-scrollbar-thumb:hover { background: var(--accent-40); } @media (max-width: 1100px) { - .journey-content, - .service-grid { padding-left: 44px; padding-right: 44px; } + .journey-content, .service-grid { padding-left: 44px; padding-right: 44px; } .hero-journey-content h1 { max-width: 480px; } - .service-text { padding: 40px; } + .projects-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } + .project-card:nth-child(2) { margin-top: 0; } } @media (max-width: 980px) { .journey-section { padding: 96px 0; min-height: 90dvh; } .hero-journey-section { padding-top: 118px; padding-bottom: 56px; } - - .journey-content, - .final-journey-content { padding: 0 24px; } + .journey-content, .final-journey-content { padding: 0 24px; } .service-grid { grid-template-columns: 1fr; @@ -603,11 +495,9 @@ max-width: 620px !important; justify-self: center !important; padding: 32px 24px !important; - border: 1px solid rgba(122, 151, 185, 0.14) !important; + border: 1px solid var(--border) !important; border-radius: 12px !important; - background: rgba(5, 9, 17, 0.62); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); + background: var(--bg-elevated); margin-left: 0 !important; margin-right: 0 !important; } @@ -619,61 +509,19 @@ transform: translateX(-50%); } .service-journey-section .service-text > p { max-width: 100%; text-align: center; } - .journey-tags, - .service--right .service-text .journey-tags { justify-content: center; } .hero-journey-content h1 { font-size: 36px; max-width: 100%; } .hero-desc { max-width: 100%; font-size: 15px; } .journey-actions { flex-direction: column; gap: 12px; width: 100%; } - .home-primary-button, - .home-secondary-button { width: 100%; justify-content: center; } + .home-primary-button, .home-secondary-button { width: 100%; justify-content: center; } .journey-scroll-cue { display: none; } - .home-atmosphere { - background: - linear-gradient(90deg, rgba(126, 155, 190, 0.025) 1px, transparent 1px), - linear-gradient(0deg, rgba(126, 155, 190, 0.02) 1px, transparent 1px), - linear-gradient(to top, rgba(3, 6, 11, 0.5) 0%, transparent 28%); - background-size: 58px 58px, 58px 58px, auto; - } - - .journey-section::before { - opacity: 0.18; - mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.55), transparent 76%); - } - - .journey-section::after, - .service-journey-section::after, - #hero::after, - #cta::after { - opacity: 0.16; - } -} - -@media (min-width: 769px) and (max-width: 980px) { - .journey-content, - .final-journey-content { padding-left: 44px; padding-right: 44px; } - - .hero-journey-content { - max-width: 680px; - margin-left: 0; - } - - .hero-journey-content h1 { font-size: clamp(42px, 6.5vw, 58px); } - - .journey-actions { - flex-direction: row; - width: auto; - } - - .home-primary-button, - .home-secondary-button { width: auto; } + .projects-list { grid-template-columns: 1fr; } + .project-card:nth-child(2) { margin-top: 0; } } @media (max-width: 480px) { .hero-journey-content h1 { font-size: 30px; } - .journey-content, - .service-grid, - .final-journey-content { padding-left: 18px; padding-right: 18px; } - .svc-icon { width: 44px; height: 44px; border-radius: 12px; } -} + .journey-content, .service-grid, .final-journey-content { padding-left: 18px; padding-right: 18px; } + .svc-icon { width: 44px; height: 44px; border-radius: 10px; } +} \ No newline at end of file diff --git a/frontend/src/styles/Navbar.css b/frontend/src/styles/Navbar.css index 5553d0c..bbfaff1 100644 --- a/frontend/src/styles/Navbar.css +++ b/frontend/src/styles/Navbar.css @@ -5,20 +5,18 @@ transform: translateX(-50%); width: calc(100% - 34px); max-width: 1440px; - height: 74px; + height: 72px; padding: 0 24px; display: flex; align-items: center; justify-content: space-between; z-index: 80; - border-radius: 12px; - background: linear-gradient(180deg, rgba(8, 14, 24, 0.76) 0%, rgba(5, 9, 17, 0.82) 100%); + border-radius: 10px; + background: rgba(10, 11, 13, 0.72); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); - border: 1px solid rgba(122, 151, 185, 0.16); - box-shadow: - inset 0 1px 0 rgba(255, 255, 255, 0.06), - 0 18px 54px rgba(0, 0, 0, 0.38); + border: 1px solid var(--border); + box-shadow: var(--shadow-soft); transition: background 220ms var(--ease-out-strong), border-color 220ms var(--ease-out-strong), @@ -27,98 +25,54 @@ } .navbar.scrolled { - height: 66px; - background: linear-gradient(180deg, rgba(6, 10, 18, 0.88) 0%, rgba(3, 6, 12, 0.92) 100%); - backdrop-filter: blur(24px); - -webkit-backdrop-filter: blur(24px); - border-color: rgba(110, 231, 242, 0.22); - box-shadow: - inset 0 1px 0 rgba(255, 255, 255, 0.07), - 0 16px 48px rgba(0, 0, 0, 0.46); + height: 64px; + background: rgba(6, 7, 8, 0.88); + backdrop-filter: blur(22px); + -webkit-backdrop-filter: blur(22px); + border-color: var(--border-hover); + box-shadow: var(--shadow-card); } -.navbar-left { - display: flex; - align-items: center; - min-width: 0; -} +.navbar-left { display: flex; align-items: center; min-width: 0; } -.logo-wrapper { - display: flex; - align-items: center; - gap: 14px; - text-decoration: none; -} +.logo-wrapper { display: flex; align-items: center; gap: 14px; text-decoration: none; } .logo { - width: 38px; - height: 38px; + width: 36px; + height: 36px; border-radius: 999px; - border: 1.5px solid rgba(110, 231, 242, 0.24); - box-shadow: 0 10px 22px rgba(0, 0, 0, 0.26); - transition: - transform 180ms var(--ease-out-strong), - border-color 180ms var(--ease-out-strong), - box-shadow 180ms var(--ease-out-strong); -} - -.logo-wrapper:hover .logo { - border-color: rgba(110, 231, 242, 0.5); - box-shadow: 0 12px 24px rgba(0, 0, 0, 0.32); - transform: translateY(-1px); + border: 1.5px solid var(--border); + transition: border-color 180ms var(--ease-out-strong); } +.logo-wrapper:hover .logo { border-color: var(--accent-40); } .logo-text { - font-size: 19px; - font-weight: 800; - letter-spacing: 0; - background: linear-gradient(130deg, #f7fbff 0%, #9fd7ff 52%, #6ee7f2 100%); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - filter: none; + font-family: var(--font-display); + font-size: 18px; + font-weight: 700; + letter-spacing: -0.01em; + color: var(--text); transition: opacity 180ms var(--ease-out-strong); } +.logo-wrapper:hover .logo-text { opacity: 0.8; } -.logo-wrapper:hover .logo-text { - opacity: 0.86; -} - -.navbar-menu { - display: flex; - align-items: center; - gap: 34px; - list-style: none; -} +.navbar-menu { display: flex; align-items: center; gap: 32px; list-style: none; } .navbar-menu a { position: relative; display: inline-block; text-decoration: none; - color: rgba(255, 255, 255, 0.75); - font-size: 0.92rem; - letter-spacing: 0.05em; + color: var(--text-muted); + font-size: 0.9rem; + letter-spacing: 0.01em; padding: 6px 0; - text-transform: none; font-weight: 500; - font-family: 'Outfit', 'Inter', sans-serif; - transition: - color 180ms var(--ease-out-strong), - transform 180ms var(--ease-out-strong); + font-family: var(--font-body); + transition: color 180ms var(--ease-out-strong); } -.navbar-menu a.nav-link-featured { - font-size: 0.88rem; -} - -.navbar-menu a:hover { - color: #fff; - text-shadow: none; -} - -.navbar-menu a.active { - color: #ffffff; - text-shadow: none; -} +.navbar-menu a:hover { color: var(--text); } +.navbar-menu a.active { color: var(--text); } .navbar-menu a::after { content: ""; @@ -128,144 +82,77 @@ transform: translateX(-50%); width: 0; height: 2px; - border-radius: 99px; - background: linear-gradient(90deg, #6ee7f2, #8fb3ff); + background: var(--accent); transition: width 180ms var(--ease-out-strong); } - .navbar-menu a:hover::after, -.navbar-menu a.active::after { - width: 80%; -} +.navbar-menu a.active::after { width: 70%; } -.navbar-right { - display: flex; - align-items: center; - gap: 12px; - min-width: 0; -} +.navbar-right { display: flex; align-items: center; gap: 12px; min-width: 0; } -.navbar-menu-controls { - display: none; -} +.navbar-menu-controls { display: none; } .language-switch { display: flex; - position: relative; - overflow: hidden; - isolation: isolate; padding: 3px; border-radius: 999px; - background: rgba(7, 14, 24, 0.62); - border: 1px solid rgba(122, 151, 185, 0.14); - transition: - border-color 180ms var(--ease-out-strong), - background 180ms var(--ease-out-strong); -} - -.language-switch::before { - content: ""; - position: absolute; - inset: -60% -20%; - z-index: 0; - opacity: 0.16; - transform: translateX(-8%); - pointer-events: none; -} - -.language-switch:hover { - border-color: rgba(110, 231, 242, 0.28); - background: rgba(10, 20, 32, 0.76); + background: var(--surface); + border: 1px solid var(--border); + transition: border-color 180ms var(--ease-out-strong); } +.language-switch:hover { border-color: var(--border-hover); } .language-switch button { - position: relative; - z-index: 1; border: none; background: transparent; - color: rgba(220, 241, 255, 0.65); + color: var(--text-dim); padding: 6px 10px; border-radius: 999px; cursor: pointer; - font-family: "JetBrains Mono", monospace; - letter-spacing: 0.1em; + font-family: var(--font-mono); + letter-spacing: 0.08em; font-size: 0.64rem; - transition: - color 180ms var(--ease-out-strong), - background 180ms var(--ease-out-strong), - transform 120ms var(--ease-out-strong); + transition: color 180ms var(--ease-out-strong), background 180ms var(--ease-out-strong); } - .language-switch button.active { - background: rgba(110, 231, 242, 0.16); - color: #fff; - box-shadow: inset 0 0 0 1px rgba(110, 231, 242, 0.18); + background: var(--accent-16); + color: var(--text); } .login-btn { - position: relative; - overflow: hidden; - isolation: isolate; height: 36px; padding: 0 18px; border-radius: 8px; - border: 1px solid rgba(110, 231, 242, 0.28); - background: linear-gradient(135deg, #1e5fe7 0%, #21aabd 100%); - color: #fff; - font-family: "JetBrains Mono", monospace; - font-weight: 800; - letter-spacing: 0.1em; - font-size: 0.66rem; + border: 1px solid var(--accent); + background: var(--accent); + color: #ffffff; + font-family: var(--font-body); + font-weight: 600; + letter-spacing: 0.01em; + font-size: 0.82rem; cursor: pointer; - box-shadow: 0 10px 22px rgba(20, 85, 140, 0.22); transition: transform 160ms var(--ease-out-strong), - border-color 180ms var(--ease-out-strong), - box-shadow 180ms var(--ease-out-strong), - filter 180ms var(--ease-out-strong); -} - -.login-btn::before { - content: ""; - position: absolute; - inset: -140% -22%; - z-index: 0; - opacity: 0.34; - transform: translateX(-6%); - pointer-events: none; -} - -.login-btn > * { - position: relative; - z-index: 1; + background 180ms var(--ease-out-strong), + border-color 180ms var(--ease-out-strong); } - .login-btn:hover { transform: translateY(-1px); - border-color: rgba(110, 231, 242, 0.5); - box-shadow: - 0 12px 26px rgba(20, 85, 140, 0.3); + background: var(--accent-strong); + border-color: var(--accent-strong); } - .login-btn:active, .language-switch button:active, -.navbar-toggle:active { - transform: scale(0.97); -} +.navbar-toggle:active { transform: scale(0.97); } -.navbar-toggle { - display: none; -} +.navbar-toggle { display: none; } @media (max-width: 980px) { - .navbar { - width: calc(100% - 20px); - padding: 0 16px; - } + .navbar { width: calc(100% - 20px); padding: 0 16px; } .navbar-menu { position: absolute; - top: 95px; + top: 92px; left: 0; width: 100%; max-height: calc(100vh - 120px); @@ -273,10 +160,10 @@ flex-direction: column; align-items: stretch; padding: 24px; - border-radius: 14px; - background: rgba(5, 9, 17, 0.96); + border-radius: 12px; + background: rgba(6, 7, 8, 0.97); backdrop-filter: blur(20px); - border: 1px solid rgba(122, 151, 185, 0.18); + border: 1px solid var(--border); opacity: 0; visibility: hidden; transform: translateY(-10px) scale(0.98); @@ -288,20 +175,10 @@ gap: 18px; } - .navbar-menu.active { - opacity: 1; - visibility: visible; - transform: translateY(0) scale(1); - } + .navbar-menu.active { opacity: 1; visibility: visible; transform: translateY(0) scale(1); } - .navbar-menu li { - width: 100%; - text-align: center; - } - - .navbar-menu a { - width: 100%; - } + .navbar-menu li { width: 100%; text-align: center; } + .navbar-menu a { width: 100%; } .navbar-menu-controls { display: flex; @@ -310,29 +187,14 @@ gap: 14px; margin-top: 6px; padding-top: 14px; - border-top: 1px solid rgba(122, 151, 185, 0.14); + border-top: 1px solid var(--border); } .navbar-menu-controls .language-switch, - .navbar-menu-controls .login-btn { - display: inline-flex; - } - - .navbar-toggle { - display: flex; - flex-direction: column; - gap: 5px; - cursor: pointer; - } + .navbar-menu-controls .login-btn { display: inline-flex; } - .navbar-toggle span { - width: 24px; - height: 2px; - background: #fff; - border-radius: 999px; - } + .navbar-toggle { display: flex; flex-direction: column; gap: 5px; cursor: pointer; } + .navbar-toggle span { width: 24px; height: 2px; background: var(--text); border-radius: 999px; } - .navbar-right { - display: none; - } -} + .navbar-right { display: none; } +} \ No newline at end of file diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css index f7e784c..c8cb5f5 100644 --- a/frontend/src/styles/global.css +++ b/frontend/src/styles/global.css @@ -1,70 +1,37 @@ :root { - --bg: #05070c; - --bg-deep: #02040a; - --surface: rgba(8, 14, 24, 0.68); - --surface-hover: rgba(255, 255, 255, 0.04); - --border: rgba(122, 151, 185, 0.16); - --border-hover: rgba(110, 231, 242, 0.32); - --border-focus: rgba(110, 231, 242, 0.48); - --accent: #6ee7f2; - --accent-secondary: #8fb3ff; - --text: #f0f4ff; - --muted: #6a7590; - --text-dim: #5a637a; - - --color-bg: #05070c; - --color-bg-deep: #02040a; - --color-bg-elevated: rgba(9, 16, 28, 0.78); - --color-bg-surface: rgba(8, 14, 24, 0.68); - --color-bg-surface-2: rgba(10, 18, 30, 0.72); - --color-border: rgba(122, 151, 185, 0.16); - --color-border-subtle: rgba(122, 151, 185, 0.09); - --color-accent: #6ee7f2; - --color-accent-2: #8fb3ff; - --color-accent-soft: #c7d7ff; - --color-accent-soft-2: #9adbe4; - --color-grad-1: #6ee7f2; - --color-grad-2: #8fb3ff; - --color-grad-3: #b8a4ff; - --color-grad-4: #f0a3c4; - --color-text: #f0f4ff; - --color-text-bright: #ffffff; - --color-text-soft: #d0d8ff; - --color-text-muted: #6a7590; - --color-text-dim: #5a637a; - --color-shadow-soft: rgba(0, 0, 0, 0.2); - --color-shadow-card: 0 24px 60px rgba(0, 0, 0, 0.35); - --color-shadow-strong: rgba(0, 0, 0, 0.65); - - --color-accent-06: rgba(110, 231, 242, 0.06); - --color-accent-08: rgba(110, 231, 242, 0.08); - --color-accent-10: rgba(110, 231, 242, 0.1); - --color-accent-12: rgba(110, 231, 242, 0.12); - --color-accent-18: rgba(110, 231, 242, 0.18); - --color-accent-25: rgba(110, 231, 242, 0.25); - --color-accent-30: rgba(110, 231, 242, 0.3); - --color-accent-35: rgba(110, 231, 242, 0.35); - --color-accent-40: rgba(110, 231, 242, 0.4); - --color-accent-50: rgba(110, 231, 242, 0.5); - - --color-success: #6ce89a; - --color-success-08: rgba(108, 232, 154, 0.08); - --color-success-25: rgba(108, 232, 154, 0.25); - - --color-danger: #ff8a83; - --color-danger-08: rgba(255, 138, 131, 0.08); - --color-danger-20: rgba(255, 138, 131, 0.2); - --color-danger-25: rgba(255, 138, 131, 0.25); - - --fade-purple: linear-gradient(135deg, #2f6df6 0%, #34c3d6 100%); - --text-decoration: rgba(110, 231, 242, 0.48); - --text-decoration-shadow: rgba(110, 231, 242, 0.18); - --color-white-03: rgba(255, 255, 255, 0.03); - --color-white-04: rgba(255, 255, 255, 0.04); - --color-white-12: rgba(255, 255, 255, 0.12); - --color-white-78: rgba(255, 255, 255, 0.78); - --ease-out-strong: cubic-bezier(0.16, 1, 0.3, 1); - --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1); + + --bg: #0a0b0d; + --bg-deep: #060708; + --bg-elevated: #101216; + --surface: rgba(255, 255, 255, 0.035); + --surface-hover: rgba(255, 255, 255, 0.055); + --border: rgba(255, 255, 255, 0.09); + --border-hover: rgba(255, 255, 255, 0.16); + --border-focus: rgba(76, 122, 245, 0.55); + + --accent: #4c7af5; + --accent-strong: #6690ff; + --accent-dim: #2f4e9e; + --accent-06: rgba(76, 122, 245, 0.06); + --accent-10: rgba(76, 122, 245, 0.1); + --accent-16: rgba(76, 122, 245, 0.16); + --accent-24: rgba(76, 122, 245, 0.24); + --accent-40: rgba(76, 122, 245, 0.4); + + --text: #f4f3ef; + --text-bright: #ffffff; + --text-muted: #93959c; + --text-dim: #5e6067; + + --font-display: 'General Sans', 'Outfit', 'Inter', system-ui, sans-serif; + --font-body: 'Inter', system-ui, -apple-system, sans-serif; + --font-mono: 'JetBrains Mono', 'IBM Plex Mono', monospace; + + --ease-out-strong: cubic-bezier(0.16, 1, 0.3, 1); + --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1); + + --shadow-card: 0 24px 60px rgba(0, 0, 0, 0.4); + --shadow-soft: 0 12px 30px rgba(0, 0, 0, 0.28); } *, *::before, *::after { @@ -81,12 +48,12 @@ html { body { margin: 0; - font-family: 'Outfit', 'Inter', system-ui, -apple-system, sans-serif; + font-family: var(--font-body); font-display: swap; background-color: var(--bg); - background-image: - radial-gradient(circle at 78% 18%, rgba(110, 231, 242, 0.045) 0%, transparent 40%), - radial-gradient(circle at 16% 76%, rgba(143, 179, 255, 0.035) 0%, transparent 42%); + background-image: + radial-gradient(circle at 82% 12%, rgba(76, 122, 245, 0.05) 0%, transparent 42%), + radial-gradient(circle at 12% 82%, rgba(76, 122, 245, 0.03) 0%, transparent 46%); background-attachment: fixed; color: var(--text); display: flex; @@ -102,24 +69,15 @@ body { } a { - color: var(--accent-secondary); + color: var(--text); text-decoration: none; transition: color 180ms var(--ease-out-strong); } +a:hover { color: var(--accent-strong); } -a:hover { - color: var(--text); -} - -main { - flex: 1; - width: 100%; -} +main { flex: 1; width: 100%; } -button, -a { - -webkit-tap-highlight-color: transparent; -} +button, a { -webkit-tap-highlight-color: transparent; } :focus-visible { outline: 2px solid var(--border-focus); @@ -127,17 +85,15 @@ a { } ::selection { - background: rgba(110, 231, 242, 0.22); - color: var(--color-text-bright); + background: var(--accent-24); + color: var(--text-bright); } @media (prefers-reduced-motion: reduce) { - *, - *::before, - *::after { + *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: 1ms !important; } -} +} \ No newline at end of file