diff --git a/landing/assets/styles/cyberpunk-hero.scss b/landing/assets/styles/cyberpunk-hero.scss index e92ae270..c771cd8c 100644 --- a/landing/assets/styles/cyberpunk-hero.scss +++ b/landing/assets/styles/cyberpunk-hero.scss @@ -516,51 +516,163 @@ .cyber-hero__actions { display: flex; flex-wrap: wrap; - gap: 12px; + gap: 14px; margin-bottom: 18px; } -.cyber-hero__action.v-btn { - min-height: 52px !important; - min-width: 148px !important; - border-radius: var(--cyber-radius-sm) !important; - padding-inline: 18px !important; - font-weight: 800 !important; - font-size: 0.9rem !important; - letter-spacing: 0.01em !important; +.cyber-action-button.v-btn { + --action-accent-a: var(--cyber-cyan); + --action-accent-b: var(--cyber-magenta); + --action-bg: + linear-gradient(135deg, rgba(0, 210, 255, 0.74) 0%, rgba(43, 103, 255, 0.56) 48%, rgba(207, 34, 215, 0.76) 100%), + linear-gradient(180deg, rgba(7, 18, 42, 0.9), rgba(4, 10, 25, 0.92)); + --action-border: rgba(0, 234, 255, 0.78); + --action-text: #f2fbff; + --action-subtext: rgba(231, 240, 255, 0.72); + --action-clip: polygon(18px 0, calc(100% - 12px) 0, 100% 12px, 100% calc(100% - 18px), calc(100% - 18px) 100%, 0 100%, 0 18px); + + position: relative; + min-height: 76px !important; + min-width: 312px !important; + overflow: hidden !important; + border: 0 !important; + border-radius: 0 !important; + padding: 0 26px !important; + color: var(--action-text) !important; + background: var(--action-bg) !important; + clip-path: var(--action-clip); + box-shadow: + 0 0 0 1px rgba(255, 255, 255, 0.1) inset, + 0 0 22px color-mix(in srgb, var(--action-accent-a) 24%, transparent), + 0 0 34px color-mix(in srgb, var(--action-accent-b) 20%, transparent) !important; + font-weight: 900 !important; + letter-spacing: 0 !important; text-transform: uppercase !important; transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease, - background 0.18s ease !important; + filter 0.18s ease !important; } -.cyber-hero__action.v-btn:hover { - transform: translateY(-1px); +.cyber-action-button.v-btn .v-btn__content { + position: static; + display: flex; + align-items: center; + justify-content: flex-start; + width: 100%; + gap: 16px; } -.cyber-hero__action--primary.v-btn { - color: var(--cyber-action-primary-color) !important; - background: linear-gradient(135deg, var(--cyber-cyan), var(--cyber-magenta)) !important; +.cyber-action-button.v-btn .v-btn__overlay, +.cyber-action-button.v-btn .v-btn__underlay { + display: none !important; +} + +.cyber-action-button.v-btn:hover { + filter: brightness(1.08) saturate(1.08); + transform: translateY(-2px); +} + +.cyber-action-button__glow { + position: absolute; + inset: 0; + z-index: 1; + pointer-events: none; + background: + linear-gradient(90deg, rgba(255, 255, 255, 0.16), transparent 28%), + radial-gradient(ellipse at 16% 48%, color-mix(in srgb, var(--action-accent-a) 22%, transparent), transparent 38%), + linear-gradient(180deg, rgba(255, 255, 255, 0.08), transparent 52%); + opacity: 0.62; +} + +.cyber-action-button__frame { + position: absolute; + inset: 0; + z-index: 3; + width: 100%; + height: 100%; + overflow: visible; + color: var(--action-border); + pointer-events: none; + filter: + drop-shadow(0 0 8px color-mix(in srgb, var(--action-accent-a) 22%, transparent)) + drop-shadow(0 0 12px color-mix(in srgb, var(--action-accent-b) 12%, transparent)); +} + +.cyber-action-button__frame path { + fill: none; + stroke: currentColor; + stroke-linecap: square; + stroke-linejoin: miter; + stroke-width: 1.35; + shape-rendering: geometricPrecision; +} + +.cyber-action-button__icon { + position: relative; + z-index: 4; + display: grid; + flex: 0 0 auto; + width: 34px; + height: 34px; + place-items: center; + color: var(--action-accent-a); + filter: + drop-shadow(0 0 10px color-mix(in srgb, var(--action-accent-a) 54%, transparent)) + drop-shadow(0 0 18px color-mix(in srgb, var(--action-accent-b) 30%, transparent)); +} + +.cyber-action-button--primary .cyber-action-button__icon { + color: #00d8ff; + filter: + drop-shadow(0 0 10px rgba(0, 234, 255, 0.56)) + drop-shadow(0 0 16px rgba(35, 91, 255, 0.22)); +} + +.cyber-action-button__copy { + position: relative; + z-index: 4; + display: grid; + min-width: 0; + gap: 6px; + text-align: left; +} + +.cyber-action-button__label { + color: var(--action-text); + font-size: 1rem; + line-height: 1; +} + +.cyber-action-button__subtitle { + color: var(--action-subtext); + font-size: 0.66rem; + font-weight: 700; + line-height: 1.1; + text-transform: none; + opacity: 0.92; +} + +.cyber-action-button--primary.v-btn { + --action-text: #f8fbff; + --action-subtext: rgba(237, 247, 255, 0.74); +} + +.cyber-action-button--secondary.v-btn { + --action-accent-a: #91b6ff; + --action-accent-b: var(--cyber-cyan); + --action-bg: + linear-gradient(135deg, rgba(10, 18, 38, 0.96), rgba(7, 14, 31, 0.78)), + rgba(1, 7, 18, 0.84); + --action-border: rgba(123, 160, 231, 0.64); + --action-text: #f3f7ff; + --action-subtext: rgba(182, 198, 226, 0.76); + box-shadow: - 0 0 0 1px rgba(255, 255, 255, 0.16) inset, - 0 0 24px rgba(0, 234, 255, 0.34), - 0 0 34px rgba(255, 43, 255, 0.22) !important; -} - -.cyber-hero__action--watch.v-btn, -.cyber-hero__action--docs.v-btn { - color: var(--cyber-text) !important; - border-color: rgba(0, 234, 255, 0.46) !important; - background: var(--cyber-action-secondary-bg) !important; -} - -.cyber-hero__action--watch.v-btn:hover, -.cyber-hero__action--docs.v-btn:hover { - color: var(--cyber-cyan) !important; - border-color: rgba(0, 234, 255, 0.74) !important; - background: var(--cyber-action-secondary-hover-bg) !important; + 0 0 0 1px rgba(255, 255, 255, 0.05) inset, + 0 0 24px rgba(80, 130, 255, 0.16), + 0 0 34px rgba(0, 234, 255, 0.1) !important; } .cyber-hero__terminal-note { @@ -1210,31 +1322,67 @@ .cyber-feature-rail-shell { position: relative; z-index: 7; - margin: 28px auto 0; - width: min(1540px, 96%); + margin: clamp(42px, 5vw, 72px) auto 0; + width: min(1580px, 96%); } .cyber-feature-rail-shell::before { content: ""; position: absolute; z-index: -1; - inset: -118px -3vw -96px; + inset: -82px -4vw -76px; pointer-events: none; - background: var(--cyber-feature-shell-bg); - opacity: 0.86; - mask-image: radial-gradient(ellipse at 50% 54%, black 0 48%, rgba(0, 0, 0, 0.5) 62%, transparent 78%); + background: + radial-gradient(ellipse at 50% 42%, rgba(0, 234, 255, 0.12), transparent 48%), + radial-gradient(ellipse at 88% 54%, rgba(255, 43, 255, 0.12), transparent 42%); + opacity: 0.72; + mask-image: radial-gradient(ellipse at 50% 52%, black 0 48%, rgba(0, 0, 0, 0.5) 62%, transparent 78%); } .cyber-feature-rail { + --feature-line-top: 118px; + position: relative; z-index: 1; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0; width: 100%; - padding: 17px 18px; - background: var(--cyber-feature-rail-bg); - box-shadow: var(--cyber-feature-rail-shadow); + min-height: 300px; + padding: 0 22px; + background: transparent; + box-shadow: none; +} + +.cyber-feature-rail::before { + position: absolute; + z-index: 0; + top: var(--feature-line-top); + left: 0; + right: 0; + height: 3px; + content: ""; + background: + linear-gradient(90deg, transparent 0 2.5%, var(--cyber-cyan) 6%, rgba(0, 234, 255, 0.92) 78%, rgba(255, 43, 255, 0.95) 92%, transparent 98%), + linear-gradient(90deg, transparent 0 3%, rgba(255, 255, 255, 0.34) 6%, transparent 13%, transparent 86%, rgba(255, 255, 255, 0.24) 92%, transparent 98%); + box-shadow: + 0 0 18px rgba(0, 234, 255, 0.42), + 0 0 30px rgba(255, 43, 255, 0.18); +} + +.cyber-feature-rail::after { + position: absolute; + z-index: 0; + top: calc(var(--feature-line-top) - 7px); + left: 0; + width: 86px; + height: 17px; + content: ""; + background: + repeating-linear-gradient(115deg, var(--cyber-cyan) 0 4px, transparent 4px 10px), + linear-gradient(90deg, transparent, rgba(0, 234, 255, 0.6)); + clip-path: polygon(0 42%, 44% 42%, 54% 0, 100% 0, 100% 100%, 54% 100%, 44% 58%, 0 58%); + filter: drop-shadow(0 0 10px rgba(0, 234, 255, 0.45)); } .cyber-feature-rail__collaboration { @@ -1405,41 +1553,127 @@ } .cyber-feature-rail__item { + --feature-accent: var(--cyber-cyan); + + position: relative; + z-index: 1; display: grid; - grid-template-columns: 46px minmax(0, 1fr); - align-items: center; - gap: 12px; + grid-template-rows: 82px 54px minmax(0, 1fr); + justify-items: center; + align-items: start; + gap: 0; min-width: 0; - padding: 0 18px; - border-right: 1px solid var(--cyber-feature-divider); + padding: 0 14px; + text-align: center; } -.cyber-feature-rail__item:last-child { - border-right: 0; +.cyber-feature-rail__item:nth-child(5) { + --feature-accent: var(--cyber-magenta); } .cyber-feature-rail__icon { + position: relative; display: grid; place-items: center; - width: 46px; - height: 46px; - color: var(--cyber-cyan); - border: 1px solid rgba(0, 234, 255, 0.44); - border-radius: var(--cyber-radius-sm); - box-shadow: 0 0 22px rgba(0, 234, 255, 0.16); + width: 80px; + height: 70px; + color: var(--feature-accent); + filter: + drop-shadow(0 0 16px color-mix(in srgb, var(--feature-accent) 48%, transparent)) + drop-shadow(0 0 28px color-mix(in srgb, var(--feature-accent) 18%, transparent)); +} + +.cyber-feature-rail__icon::before, +.cyber-feature-rail__icon::after { + position: absolute; + width: 18px; + height: 18px; + content: ""; + opacity: 0.82; +} + +.cyber-feature-rail__icon::before { + top: 0; + left: 0; + border-top: 1px solid var(--feature-accent); + border-left: 1px solid var(--feature-accent); +} + +.cyber-feature-rail__icon::after { + right: 0; + bottom: 0; + border-right: 1px solid var(--feature-accent); + border-bottom: 1px solid var(--feature-accent); +} + +.cyber-feature-rail__icon .v-icon { + font-size: 46px !important; +} + +.cyber-feature-rail__node { + position: relative; + display: grid; + width: 58px; + height: 58px; + place-items: center; + color: var(--feature-accent); + background: rgba(2, 10, 24, 0.9); + border: 2px solid var(--feature-accent); + clip-path: polygon(28% 0, 72% 0, 100% 28%, 100% 72%, 72% 100%, 28% 100%, 0 72%, 0 28%); + box-shadow: + 0 0 0 1px rgba(255, 255, 255, 0.08) inset, + 0 0 20px color-mix(in srgb, var(--feature-accent) 34%, transparent); + font-family: var(--at-font-mono); + font-size: 1.14rem; + font-weight: 900; + line-height: 1; +} + +.cyber-feature-rail__node::before { + position: absolute; + left: 50%; + top: -26px; + width: 1px; + height: 25px; + content: ""; + background: linear-gradient(180deg, var(--feature-accent), transparent); + box-shadow: 0 0 12px color-mix(in srgb, var(--feature-accent) 46%, transparent); +} + +.cyber-feature-rail__copy { + position: relative; + isolation: isolate; + max-width: 235px; + padding: 18px 12px 12px; +} + +.cyber-feature-rail__copy::before { + position: absolute; + z-index: -1; + inset: 2px -8px -4px; + content: ""; + background: + linear-gradient(180deg, rgba(3, 8, 22, 0.46), rgba(3, 8, 22, 0.2)), + radial-gradient(ellipse at 50% 38%, rgba(0, 234, 255, 0.08), transparent 72%); + border: 1px solid rgba(0, 234, 255, 0.08); + border-radius: 18px; + opacity: 0.92; + backdrop-filter: blur(11px) saturate(1.08); + mask-image: radial-gradient(ellipse at 50% 50%, black 0 76%, rgba(0, 0, 0, 0.62) 88%, transparent 100%); } .cyber-feature-rail__title { - margin-bottom: 3px; + margin-bottom: 11px; color: var(--cyber-feature-title); font-weight: 800; - font-size: 0.92rem; + font-size: clamp(0.98rem, 1.12vw, 1.22rem); + line-height: 1.18; } .cyber-feature-rail__text { color: var(--cyber-feature-text); - font-size: 0.8rem; - line-height: 1.45; + font-size: clamp(0.82rem, 0.88vw, 1rem); + line-height: 1.52; } @keyframes cyberRobotBob { @@ -1554,36 +1788,38 @@ .cyber-feature-rail { grid-template-columns: repeat(3, minmax(0, 1fr)); + min-height: auto; + row-gap: 34px; + padding: 0; } - .cyber-feature-rail__collaboration { - left: 50%; - bottom: calc(100% - 14px); - width: 132px; + .cyber-feature-rail::before, + .cyber-feature-rail::after { + display: none; } - .cyber-feature-rail__reviewer { - --reviewer-robot-width: 78px; - - right: 56px; - gap: 10px; + .cyber-feature-rail__item { + grid-template-rows: 72px 48px minmax(0, 1fr); + padding-inline: 12px; } - .cyber-feature-rail__reviewer-card { - width: 220px; - font-size: 0.62rem; + .cyber-feature-rail__icon { + width: 72px; + height: 62px; } - .cyber-feature-rail__robot { - width: var(--reviewer-robot-width); + .cyber-feature-rail__icon .v-icon { + font-size: 38px !important; } - .cyber-feature-rail__item:nth-child(3) { - border-right: 0; + .cyber-feature-rail__node { + width: 50px; + height: 50px; + font-size: 1rem; } - .cyber-feature-rail__item:nth-child(n + 4) { - margin-top: 16px; + .cyber-feature-rail__copy { + padding-top: 12px; } } @@ -1678,9 +1914,11 @@ grid-template-columns: 1fr; } - .cyber-hero__action.v-btn { + .cyber-action-button.v-btn { width: 100%; + min-height: 72px !important; min-width: 0 !important; + padding-inline: 20px !important; } .cyber-hero__terminal-note { @@ -1751,26 +1989,64 @@ .cyber-feature-rail { grid-template-columns: 1fr; - padding: 16px; - } - - .cyber-feature-rail__collaboration { - display: none; - } - - .cyber-feature-rail__reviewer { - display: none; + gap: 20px; + padding: 0 4px; } .cyber-feature-rail__item { - grid-template-columns: 42px minmax(0, 1fr); - padding: 12px 0; - border-right: 0; - border-bottom: 1px solid rgba(0, 234, 255, 0.14); + grid-template-columns: 48px 44px minmax(0, 1fr); + grid-template-rows: auto; + align-items: center; + justify-items: start; + gap: 10px; + padding: 0; + text-align: left; } - .cyber-feature-rail__item:last-child { - border-bottom: 0; + .cyber-feature-rail__icon { + width: 44px; + height: 44px; + } + + .cyber-feature-rail__icon::before, + .cyber-feature-rail__icon::after { + width: 12px; + height: 12px; + } + + .cyber-feature-rail__icon .v-icon { + font-size: 26px !important; + } + + .cyber-feature-rail__node { + width: 40px; + height: 40px; + font-size: 0.8rem; + } + + .cyber-feature-rail__node::before { + display: none; + } + + .cyber-feature-rail__copy { + max-width: none; + padding: 8px 10px 9px; + } + + .cyber-feature-rail__copy::before { + inset: 0 -6px; + border-radius: 14px; + backdrop-filter: blur(9px) saturate(1.06); + } + + .cyber-feature-rail__title { + margin-bottom: 5px; + font-size: 0.92rem; + } + + .cyber-feature-rail__text { + font-size: 0.78rem; + line-height: 1.42; } } diff --git a/landing/components/hero/CyberHeroActionButton.vue b/landing/components/hero/CyberHeroActionButton.vue new file mode 100644 index 00000000..bbfeb733 --- /dev/null +++ b/landing/components/hero/CyberHeroActionButton.vue @@ -0,0 +1,49 @@ + + + diff --git a/landing/components/hero/CyberHeroFeatureStrip.vue b/landing/components/hero/CyberHeroFeatureStrip.vue index bf68c512..cdc354ff 100644 --- a/landing/components/hero/CyberHeroFeatureStrip.vue +++ b/landing/components/hero/CyberHeroFeatureStrip.vue @@ -6,24 +6,10 @@ import { mdiShieldCheckOutline, mdiMonitorDashboard, } from "@mdi/js"; -import { - heroCollaborationFeature, - getLocalizedHeroFeatureRail, - getLocalizedHeroReviewerFeatureCard, - type HeroMessage, - type HeroMessagePhase, -} from "~/data/heroScene"; - -const props = defineProps<{ - activeMessage?: HeroMessage | null; - phase?: HeroMessagePhase; - reducedMotion?: boolean; -}>(); +import { getLocalizedHeroFeatureRail } from "~/data/heroScene"; const { locale } = useI18n(); const localizedHeroFeatureRail = computed(() => getLocalizedHeroFeatureRail(locale.value)); -const localizedHeroReviewerFeatureCard = computed(() => getLocalizedHeroReviewerFeatureCard(locale.value)); -const statusLabel = computed(() => locale.value === "ru" ? "Статус:" : "Status:"); const icons = [ mdiRobotOutline, @@ -32,73 +18,11 @@ const icons = [ mdiShieldCheckOutline, mdiMonitorDashboard, ] as const; - -const reviewerIsSender = computed(() => - props.activeMessage?.from === "reviewer" && props.phase !== "cooldown", -); -const reviewerIsReceiver = computed(() => - props.activeMessage?.to === "reviewer" && props.phase === "receiver", -); -const reviewerIsActive = computed(() => reviewerIsSender.value || reviewerIsReceiver.value); -const reviewerBubbleText = computed(() => { - if (!props.activeMessage || props.reducedMotion) return null; - if (props.activeMessage.from === "reviewer" && (props.phase === "sender" || props.phase === "packet")) { - return props.activeMessage.text; - } - if (props.activeMessage.to === "reviewer" && props.phase === "receiver") { - return props.activeMessage.response; - } - return null; -});