+ {p.name} +
+{p.headline}
+{b}
+ ))} +diff --git a/public/file.svg b/public/file.svg deleted file mode 100644 index 004145c..0000000 --- a/public/file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/globe.svg b/public/globe.svg deleted file mode 100644 index 567f17b..0000000 --- a/public/globe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index 7705396..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/window.svg b/public/window.svg deleted file mode 100644 index b2b2a44..0000000 --- a/public/window.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/app/globals.css b/src/app/globals.css index a2dc41e..cc6aaf6 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,26 +1,1804 @@ @import "tailwindcss"; +/* ============================================================ + Design tokens — dark cinematic system + ============================================================ */ :root { - --background: #ffffff; - --foreground: #171717; + --rosso: #da291c; + --rosso-scuro: #9d2211; + --bianco: #ffffff; + --nero: #000000; + --notte: #181818; + --grafite: #303030; + --fumo: #8f8f8f; + --piombo: #666666; + --argento: #d2d2d2; + + --font-sans: var(--font-inter), "Helvetica Neue", Arial, sans-serif; + + --gutter: clamp(20px, 4.2vw, 60px); + --max: 1440px; + --section-y: clamp(88px, 9vw, 136px); + --ease: cubic-bezier(0.2, 0.7, 0.1, 1); } -@theme inline { - --color-background: var(--background); - --color-foreground: var(--foreground); - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); +*, +*::before, +*::after { + box-sizing: border-box; } -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } +html { + scroll-behavior: smooth; + scroll-padding-top: 72px; + -webkit-text-size-adjust: 100%; } body { - background: var(--background); - color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; + margin: 0; + background: var(--nero); + color: var(--bianco); + font-family: var(--font-sans); + font-feature-settings: "ss01" on, "cv11" on; + font-size: 15px; + line-height: 1.7; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + overflow-x: hidden; +} + +::selection { + background: var(--rosso); + color: var(--bianco); +} + +a { + color: inherit; + text-decoration: none; +} + +:focus-visible { + outline: 1px solid var(--rosso); + outline-offset: 4px; +} + +.wrap { + width: 100%; + max-width: var(--max); + margin-inline: auto; + padding-inline: var(--gutter); +} + +.skip-link { + position: absolute; + left: 16px; + top: -60px; + z-index: 100; + padding: 12px 18px; + background: var(--bianco); + color: var(--nero); + font-size: 11px; + letter-spacing: 0.2em; + text-transform: uppercase; +} + +.skip-link:focus { + top: 16px; +} + +/* ============================================================ + Typography + ============================================================ */ +.eyebrow { + display: inline-flex; + align-items: center; + gap: 14px; + margin: 0; + font-size: 11px; + font-weight: 500; + letter-spacing: 0.24em; + text-transform: uppercase; + color: var(--fumo); +} + +.eyebrow::before { + content: ""; + width: 24px; + height: 1px; + background: var(--rosso); +} + +.eyebrow .idx { + color: var(--bianco); +} + +.display { + margin: 0; + font-weight: 400; + text-transform: uppercase; + letter-spacing: -0.012em; + line-height: 1.02; +} + +.h1 { + font-size: clamp(40px, 5.6vw, 92px); + line-height: 0.98; + letter-spacing: -0.022em; +} + +.h2 { + font-size: clamp(30px, 4.2vw, 64px); +} + +.h3 { + font-size: clamp(22px, 2.1vw, 30px); + line-height: 1.12; + letter-spacing: -0.005em; +} + +.muted { + color: var(--fumo); +} + +.lead { + font-size: clamp(17px, 1.45vw, 21px); + line-height: 1.55; + font-weight: 400; + letter-spacing: -0.005em; + color: var(--bianco); +} + +.copy { + font-size: 15px; + line-height: 1.75; + color: var(--fumo); +} + +.copy p, +.lead p { + margin: 0; +} + +.copy p + p, +.lead p + p { + margin-top: 1em; +} + +.copy .hl { + color: var(--bianco); +} + +/* ============================================================ + Buttons & links + ============================================================ */ +.btn { + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 18px; + height: 54px; + padding: 0 28px; + border: 1px solid var(--bianco); + border-radius: 0; + font-size: 11px; + font-weight: 500; + letter-spacing: 0.2em; + text-transform: uppercase; + white-space: nowrap; + transition: + background-color 0.35s var(--ease), + color 0.35s var(--ease), + border-color 0.35s var(--ease); +} + +.btn .arrow { + transition: transform 0.35s var(--ease); +} + +.btn:hover .arrow { + transform: translateX(4px); +} + +.btn-solid { + background: var(--bianco); + color: var(--nero); +} + +.btn-solid:hover { + background: transparent; + color: var(--bianco); + border-color: var(--rosso); +} + +.btn-ghost { + background: transparent; + color: var(--bianco); + border-color: rgba(255, 255, 255, 0.35); +} + +.btn-ghost:hover { + border-color: var(--bianco); +} + +.arrow-link { + display: inline-flex; + align-items: center; + gap: 12px; + padding: 6px 0; + font-size: 11px; + font-weight: 500; + letter-spacing: 0.2em; + text-transform: uppercase; + color: var(--bianco); + border-bottom: 1px solid transparent; + transition: + color 0.3s var(--ease), + border-color 0.3s var(--ease); +} + +.arrow-link .arrow { + transition: transform 0.3s var(--ease); +} + +.arrow-link:hover { + color: var(--rosso); + border-color: var(--rosso); +} + +.arrow-link:hover .arrow { + transform: translateX(4px); +} + +.pill { + display: inline-flex; + align-items: center; + height: 30px; + padding: 0 14px; + border: 1px solid rgba(255, 255, 255, 0.28); + border-radius: 9999px; + font-size: 10px; + font-weight: 500; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--bianco); + white-space: nowrap; +} + +/* ============================================================ + Reveal on scroll + ============================================================ */ +[data-reveal] { + opacity: 0; + transform: translateY(28px); + transition: + opacity 1.1s var(--ease), + transform 1.1s var(--ease); + transition-delay: var(--d, 0ms); +} + +[data-reveal].is-in { + opacity: 1; + transform: none; +} + +/* ============================================================ + Header + ============================================================ */ +.site-header { + position: fixed; + inset: 0 0 auto 0; + z-index: 50; + border-bottom: 1px solid transparent; + transition: + background-color 0.5s var(--ease), + border-color 0.5s var(--ease), + transform 0.5s var(--ease); +} + +.site-header.is-scrolled { + background: rgba(0, 0, 0, 0.82); + backdrop-filter: blur(14px); + -webkit-backdrop-filter: blur(14px); + border-color: var(--grafite); +} + +.site-header.is-hidden { + transform: translateY(-100%); +} + +.site-header .bar { + display: flex; + align-items: center; + justify-content: space-between; + height: 76px; + gap: 24px; +} + +.logo { + display: inline-flex; + align-items: center; + gap: 14px; +} + +.logo-mark { + width: 30px; + height: 30px; + flex: none; +} + +.logo-type { + display: flex; + flex-direction: column; + line-height: 1; +} + +.logo-type b { + font-size: 14px; + font-weight: 600; + letter-spacing: 0.2em; +} + +.logo-type span { + margin-top: 5px; + font-size: 8.5px; + font-weight: 500; + letter-spacing: 0.42em; + color: var(--fumo); +} + +.nav { + display: flex; + align-items: center; + gap: clamp(20px, 2.6vw, 44px); +} + +.nav a { + position: relative; + padding: 5px 0; + font-size: 11px; + font-weight: 500; + letter-spacing: 0.2em; + text-transform: uppercase; + color: rgba(255, 255, 255, 0.78); + transition: color 0.3s var(--ease); +} + +.nav a::after { + content: ""; + position: absolute; + left: 0; + right: 100%; + bottom: 0; + height: 1px; + background: var(--rosso); + transition: right 0.35s var(--ease); +} + +.nav a:hover { + color: var(--bianco); +} + +.nav a:hover::after { + right: 0; +} + +.header-cta { + height: 42px; + padding: 0 20px; +} + +.menu-toggle { + display: none; + width: 44px; + height: 44px; + padding: 0; + border: 0; + background: transparent; + color: var(--bianco); + cursor: pointer; +} + +.menu-toggle span { + display: block; + width: 22px; + height: 1px; + margin: 6px auto; + background: currentColor; + transition: transform 0.35s var(--ease); +} + +.menu-toggle[aria-expanded="true"] span:first-child { + transform: translateY(3.5px) rotate(45deg); +} + +.menu-toggle[aria-expanded="true"] span:last-child { + transform: translateY(-3.5px) rotate(-45deg); +} + +.mobile-menu { + position: fixed; + inset: 76px 0 0 0; + z-index: 49; + display: flex; + flex-direction: column; + justify-content: space-between; + padding: 32px var(--gutter) 40px; + background: var(--nero); + border-top: 1px solid var(--grafite); + opacity: 0; + visibility: hidden; + transition: + opacity 0.4s var(--ease), + visibility 0.4s; +} + +.mobile-menu.is-open { + opacity: 1; + visibility: visible; +} + +.mobile-menu ul { + list-style: none; + margin: 0; + padding: 0; +} + +.mobile-menu li { + border-bottom: 1px solid var(--grafite); +} + +.mobile-menu li a { + display: flex; + justify-content: space-between; + padding: 22px 0; + font-size: 22px; + font-weight: 400; + letter-spacing: 0.02em; + text-transform: uppercase; +} + +@media (max-width: 1023px) { + .nav, + .header-cta { + display: none; + } + .menu-toggle { + display: block; + } +} + +/* ============================================================ + Hero + ============================================================ */ +.hero { + position: relative; + min-height: 100svh; + display: flex; + flex-direction: column; + justify-content: flex-end; + overflow: hidden; + background: var(--nero); + isolation: isolate; +} + +.hero-canvas { + position: absolute; + inset: 0; + z-index: -2; + width: 100%; + height: 100%; +} + +.hero::after { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + background: + linear-gradient(180deg, rgba(0, 0, 0, 0.55) 0%, transparent 22%), + linear-gradient(0deg, #000 4%, rgba(0, 0, 0, 0.6) 34%, transparent 62%), + linear-gradient(90deg, rgba(0, 0, 0, 0.7) 0%, transparent 55%); + pointer-events: none; +} + +.hero-inner { + padding-top: 132px; + padding-bottom: 40px; +} + +.hero h1 { + max-width: 17ch; + margin-top: 28px; +} + +.hero-grid { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + gap: 24px; + margin-top: clamp(40px, 5vw, 72px); + align-items: end; +} + +.hero-lead { + grid-column: 1 / span 5; +} + +.hero-body { + grid-column: 7 / span 5; +} + +.hero-actions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 32px; +} + +.hero-foot { + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; + margin-top: clamp(48px, 6vw, 88px); + padding-top: 22px; + border-top: 1px solid var(--grafite); + font-size: 10px; + font-weight: 500; + letter-spacing: 0.24em; + text-transform: uppercase; + color: var(--fumo); +} + +.hero-channels { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 8px 16px; +} + +.hero-channels i { + width: 4px; + height: 4px; + background: var(--grafite); +} + +.scroll-cue { + display: inline-flex; + align-items: center; + gap: 14px; +} + +.scroll-cue i { + position: relative; + display: block; + width: 1px; + height: 36px; + overflow: hidden; + background: var(--grafite); +} + +.scroll-cue i::after { + content: ""; + position: absolute; + left: 0; + top: -40%; + width: 1px; + height: 40%; + background: var(--bianco); + animation: cue 2.2s var(--ease) infinite; +} + +@keyframes cue { + to { + top: 100%; + } +} + +@media (max-width: 1023px) { + .hero-lead, + .hero-body { + grid-column: 1 / -1; + } + .hero-channels { + display: none; + } +} + +@media (max-width: 640px) { + .hero-actions .btn { + flex: 1 1 100%; + } +} + +/* ============================================================ + Section scaffolding + ============================================================ */ +.section { + position: relative; + padding-block: var(--section-y); +} + +.section-night { + background: var(--notte); +} + +.section-head { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + gap: 24px; + align-items: end; +} + +.section-head .title { + grid-column: 1 / span 8; +} + +.section-head .title .display { + margin-top: 28px; +} + +.section-head .aside { + grid-column: 9 / span 4; +} + +@media (max-width: 1023px) { + .section-head .title, + .section-head .aside { + grid-column: 1 / -1; + } +} + +/* two-column copy row used throughout */ +.split { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + gap: 24px; + margin-top: clamp(40px, 5vw, 72px); +} + +.split > :first-child { + grid-column: 1 / span 5; +} + +.split > :last-child { + grid-column: 7 / span 5; +} + +@media (max-width: 1023px) { + .split > :first-child, + .split > :last-child { + grid-column: 1 / -1; + } +} + +/* ============================================================ + Stats + ============================================================ */ +.stats { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + margin-top: clamp(56px, 7vw, 104px); + border-top: 1px solid var(--grafite); +} + +.stat { + padding: 36px 28px 8px; + border-left: 1px solid var(--grafite); +} + +.stat:first-child { + border-left: 0; + padding-left: 0; +} + +.stat-value { + display: flex; + align-items: flex-start; + font-size: clamp(56px, 7.4vw, 120px); + font-weight: 300; + line-height: 1; + letter-spacing: -0.045em; + font-variant-numeric: tabular-nums; +} + +.stat-value small { + margin-left: 6px; + font-size: 0.36em; + font-weight: 400; + line-height: 1.3; + letter-spacing: 0; + color: var(--fumo); +} + +.stat-label { + margin-top: 22px; + font-size: 11px; + font-weight: 500; + letter-spacing: 0.2em; + text-transform: uppercase; + color: var(--fumo); +} + +@media (max-width: 900px) { + .stats { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .stat:nth-child(3) { + border-left: 0; + padding-left: 0; + } + .stat:nth-child(n + 3) { + border-top: 1px solid var(--grafite); + } + .stat { + padding-bottom: 32px; + } +} + +/* ============================================================ + Capabilities + ============================================================ */ +.cap-layout { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + gap: 24px; + margin-top: clamp(64px, 8vw, 120px); + border-top: 1px solid var(--grafite); +} + +.cap-list { + grid-column: 1 / span 6; + list-style: none; + margin: 0; + padding: 0; +} + +.cap-item { + border-bottom: 1px solid var(--grafite); +} + +.cap-trigger { + display: grid; + grid-template-columns: 56px 1fr auto; + align-items: center; + width: 100%; + padding: 26px 0; + border: 0; + background: transparent; + color: var(--piombo); + font: inherit; + text-align: left; + cursor: pointer; + transition: color 0.4s var(--ease); +} + +.cap-trigger .num { + font-size: 11px; + font-weight: 500; + letter-spacing: 0.2em; + font-variant-numeric: tabular-nums; + transition: color 0.4s var(--ease); +} + +.cap-trigger .name { + font-size: clamp(22px, 2.4vw, 36px); + font-weight: 400; + line-height: 1.1; + letter-spacing: -0.01em; + text-transform: uppercase; +} + +.cap-trigger .tick { + width: 28px; + height: 1px; + background: var(--rosso); + transform: scaleX(0); + transform-origin: right; + transition: transform 0.45s var(--ease); +} + +.cap-trigger:hover, +.cap-item.is-active .cap-trigger { + color: var(--bianco); +} + +.cap-item.is-active .cap-trigger .num { + color: var(--rosso); +} + +.cap-item.is-active .cap-trigger .tick { + transform: scaleX(1); +} + +.cap-inline { + display: none; +} + +.cap-panel { + grid-column: 8 / span 5; + position: sticky; + top: 100px; + align-self: start; + padding-top: 40px; +} + +.cap-map { + display: block; + width: 100%; + max-width: 260px; + margin-bottom: 32px; + overflow: visible; +} + +.cap-map line { + stroke: #262626; + stroke-width: 1; + transition: stroke 0.5s var(--ease); +} + +.cap-map line.on { + stroke: rgba(255, 255, 255, 0.6); +} + +.cap-map .node { + fill: var(--nero); + stroke: var(--piombo); + transition: + fill 0.4s var(--ease), + stroke 0.4s var(--ease); +} + +.cap-map .node.on { + fill: var(--bianco); + stroke: var(--bianco); +} + +.cap-map .core { + fill: var(--nero); + stroke: rgba(255, 255, 255, 0.4); +} + +.cap-map text { + fill: var(--fumo); + font-size: 7px; + font-weight: 500; + letter-spacing: 0.22em; +} + +.cap-map .pulse { + fill: none; + stroke: var(--rosso); + stroke-width: 1; + transform-box: fill-box; + transform-origin: center; + animation: ring 2.4s var(--ease) infinite; +} + +@keyframes ring { + from { + transform: scale(1); + opacity: 0.9; + } + to { + transform: scale(3.4); + opacity: 0; + } +} + +.cap-detail { + animation: fade-up 0.6s var(--ease); +} + +.cap-detail .kicker { + font-size: 11px; + font-weight: 500; + letter-spacing: 0.2em; + text-transform: uppercase; + color: var(--fumo); +} + +.cap-detail h3 { + margin: 14px 0 22px; +} + +.cap-detail .copy { + max-width: 46ch; +} + +.cap-detail .arrow-link { + margin-top: 28px; +} + +@keyframes fade-up { + from { + opacity: 0; + transform: translateY(12px); + } + to { + opacity: 1; + transform: none; + } +} + +@media (max-width: 1023px) { + .cap-list { + grid-column: 1 / -1; + } + .cap-panel { + display: none; + } + .cap-trigger { + grid-template-columns: 44px 1fr; + color: var(--bianco); + cursor: default; + padding-bottom: 14px; + } + .cap-trigger .num { + color: var(--rosso); + } + .cap-trigger .tick { + display: none; + } + .cap-inline { + display: block; + padding: 0 0 30px 44px; + } + .cap-inline h3 { + margin: 0 0 14px; + font-size: 17px; + font-weight: 500; + line-height: 1.35; + } + .cap-inline .arrow-link { + margin-top: 16px; + } +} + +/* ============================================================ + Technology + ============================================================ */ +.products { + margin-top: clamp(72px, 9vw, 136px); + border-top: 1px solid var(--grafite); +} + +.product { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + gap: 24px; + padding-block: clamp(48px, 6vw, 88px); + border-bottom: 1px solid var(--grafite); + align-items: center; +} + +.product-visual { + grid-column: 1 / span 6; + position: relative; + aspect-ratio: 600 / 412; + background: #070707; + outline: 1px solid #1c1c1c; + overflow: hidden; +} + +.product-body { + grid-column: 8 / span 5; +} + +.product:nth-child(even) .product-visual { + grid-column: 7 / span 6; + grid-row: 1; +} + +.product:nth-child(even) .product-body { + grid-column: 1 / span 5; + grid-row: 1; +} + +.product-kind { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + margin-bottom: 28px; + font-size: 10px; + font-weight: 500; + letter-spacing: 0.24em; + text-transform: uppercase; + color: var(--piombo); +} + +.product-name { + margin: 0; + font-size: clamp(48px, 5.6vw, 88px); + font-weight: 300; + line-height: 1; + letter-spacing: -0.04em; +} + +.product-body .h3 { + margin: 28px 0 18px; +} + +.product-body .arrow-link { + margin-top: 28px; +} + +.viz { + position: absolute; + inset: 0; + width: 100%; + height: 100%; +} + +.viz text { + fill: var(--fumo); + font-size: 7.5px; + font-weight: 500; + letter-spacing: 0.22em; +} + +.viz .faint { + fill: var(--piombo); +} + +/* journey viz */ +.viz-journey .path { + fill: none; + stroke: rgba(255, 255, 255, 0.16); + stroke-width: 1; +} + +.viz-journey .flow { + fill: none; + stroke: var(--bianco); + stroke-width: 1.4; + stroke-dasharray: 24 600; + animation: flow 4.8s linear infinite; + animation-delay: var(--t, 0s); +} + +.viz-journey .flow.red { + stroke: var(--rosso); +} + +@keyframes flow { + from { + stroke-dashoffset: 624; + } + to { + stroke-dashoffset: 0; + } +} + +.viz-journey .node { + fill: var(--nero); + stroke: rgba(255, 255, 255, 0.6); +} + +.viz-journey .goal { + fill: var(--bianco); +} + +.viz-journey .goal-ring { + fill: none; + stroke: var(--rosso); + transform-box: fill-box; + transform-origin: center; + animation: ring 2.4s var(--ease) infinite; +} + +/* radar viz */ +.viz-radar .ring { + fill: none; + stroke: rgba(255, 255, 255, 0.12); +} + +.viz-radar .axis { + stroke: rgba(255, 255, 255, 0.07); +} + +.viz-radar .sweep { + transform-origin: 300px 206px; + animation: spin 7s linear infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.viz-radar .dot { + fill: var(--bianco); + animation: blip 7s linear infinite; + animation-delay: var(--t); +} + +.viz-radar .dot.red { + fill: var(--rosso); +} + +@keyframes blip { + 0%, + 100% { + opacity: 0.2; + } + 3% { + opacity: 1; + } + 35% { + opacity: 0.2; + } +} + +/* grid viz */ +.viz-grid .cell { + fill: rgba(255, 255, 255, 0.035); + stroke: rgba(255, 255, 255, 0.08); +} + +.viz-grid .cell.on { + fill: rgba(255, 255, 255, 0.85); + stroke: none; + animation: cell 4.8s var(--ease) infinite; + animation-delay: var(--t); +} + +.viz-grid .cell.alert { + fill: var(--rosso); +} + +@keyframes cell { + 0%, + 100% { + opacity: 0.12; + } + 45%, + 55% { + opacity: 1; + } +} + +.viz-grid .scan { + animation: scan 4.8s linear infinite; +} + +@keyframes scan { + from { + transform: translateY(-80px); + } + to { + transform: translateY(440px); + } +} + +.viz-grid .frame { + fill: none; + stroke: rgba(255, 255, 255, 0.5); +} + +@media (max-width: 1023px) { + .product-visual, + .product-body, + .product:nth-child(even) .product-visual, + .product:nth-child(even) .product-body { + grid-column: 1 / -1; + grid-row: auto; + } + .product-body { + margin-top: 12px; + } +} + +/* ============================================================ + Discovery + ============================================================ */ +.discovery { + overflow: hidden; +} + +.discovery-stage { + position: relative; + margin-top: clamp(64px, 8vw, 112px); + padding: clamp(56px, 7vw, 104px) 0; + border-block: 1px solid var(--grafite); + text-align: center; +} + +.query-label { + font-size: 10px; + font-weight: 500; + letter-spacing: 0.24em; + text-transform: uppercase; + color: var(--piombo); +} + +.query { + max-width: 980px; + min-height: 2.3em; + margin: 24px auto 0; + font-size: clamp(24px, 3.4vw, 48px); + font-weight: 300; + line-height: 1.15; + letter-spacing: -0.02em; +} + +.query .caret { + display: inline-block; + width: 2px; + height: 0.9em; + margin-left: 6px; + vertical-align: -0.08em; + background: var(--rosso); + animation: caret 1s steps(1) infinite; +} + +@keyframes caret { + 50% { + opacity: 0; + } +} + +.surfaces { + display: grid; + grid-template-columns: 1fr auto 1fr; + align-items: center; + gap: 24px; + margin-top: 56px; +} + +.surface { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.surface.left { + justify-content: flex-end; +} + +.surface-core { + position: relative; + display: grid; + place-items: center; + width: 96px; + height: 96px; + border: 1px solid rgba(255, 255, 255, 0.35); + border-radius: 9999px; + font-size: 9px; + font-weight: 600; + letter-spacing: 0.22em; + text-transform: uppercase; +} + +.surface-core::before, +.surface-core::after { + content: ""; + position: absolute; + top: 50%; + width: 24px; + height: 1px; + background: var(--grafite); +} + +.surface-core::before { + right: 100%; +} + +.surface-core::after { + left: 100%; +} + +@media (max-width: 1023px) { + .surfaces { + grid-template-columns: 1fr; + justify-items: center; + } + .surface, + .surface.left { + justify-content: center; + } + .surface-core::before, + .surface-core::after { + display: none; + } +} + +/* ============================================================ + Journey / Attribution + ============================================================ */ +.journey { + position: relative; + margin-top: clamp(64px, 8vw, 112px); +} + +.journey ol { + position: relative; + display: grid; + grid-template-columns: repeat(6, minmax(0, 1fr)); + list-style: none; + margin: 0; + padding: 0; +} + +.journey ol::before, +.journey ol::after { + content: ""; + position: absolute; + top: 6px; + left: 0; + right: 0; + height: 1px; + background: var(--grafite); +} + +.journey ol::after { + background: linear-gradient(90deg, rgba(255, 255, 255, 0.7), var(--rosso)); + transform: scaleX(0); + transform-origin: left; + transition: transform 2.6s var(--ease) 0.2s; +} + +.journey.is-in ol::after { + transform: scaleX(1); +} + +.journey li { + position: relative; + padding-right: 24px; +} + +.journey .dot { + position: relative; + z-index: 1; + display: block; + width: 13px; + height: 13px; + border: 1px solid var(--bianco); + background: var(--nero); + transition: background-color 0.4s var(--ease); + transition-delay: calc(var(--i) * 380ms + 300ms); +} + +.journey.is-in .dot { + background: var(--bianco); +} + +.journey li:last-child .dot { + border-color: var(--rosso); +} + +.journey.is-in li:last-child .dot { + background: var(--rosso); +} + +.journey .channel { + display: block; + margin-top: 28px; + font-size: 10px; + font-weight: 500; + letter-spacing: 0.24em; + text-transform: uppercase; + color: var(--fumo); +} + +.journey .step { + display: block; + max-width: 22ch; + margin-top: 10px; + font-size: 16px; + line-height: 1.45; + color: var(--bianco); +} + +@media (max-width: 1023px) { + .journey ol { + grid-template-columns: 1fr; + gap: 34px; + padding-left: 34px; + } + .journey ol::before, + .journey ol::after { + top: 0; + bottom: 0; + left: 6px; + right: auto; + width: 1px; + height: auto; + } + .journey ol::after { + background: linear-gradient(180deg, rgba(255, 255, 255, 0.7), var(--rosso)); + transform: scaleY(0); + transform-origin: top; + } + .journey.is-in ol::after { + transform: scaleY(1); + } + .journey .dot { + position: absolute; + left: -34px; + top: 4px; + } + .journey .channel { + margin-top: 0; + } +} + +.credit > :first-child { + grid-column: 1 / span 6; +} + +.credit > :last-child { + grid-column: 8 / span 5; + align-self: end; +} + +@media (max-width: 1023px) { + .credit > :first-child, + .credit > :last-child { + grid-column: 1 / -1; + } +} + +.credit { + margin-top: clamp(80px, 10vw, 144px); + padding-top: clamp(48px, 6vw, 80px); + border-top: 1px solid var(--grafite); +} + +.credit .question { + font-size: clamp(30px, 4.2vw, 64px); +} + +.pullquote { + margin: 0; + padding-top: clamp(80px, 10vw, 144px); + text-align: center; +} + +.pullquote blockquote { + max-width: 24ch; + margin: 28px auto 0; + font-size: clamp(28px, 3.8vw, 56px); + font-weight: 300; + line-height: 1.12; + letter-spacing: -0.025em; +} + +.pullquote figcaption { + max-width: 52ch; + margin: 36px auto 0; +} + +.pullquote .arrow-link { + margin-top: 36px; +} + +/* ============================================================ + Connections + ============================================================ */ +.gaps { + list-style: none; + margin: clamp(56px, 7vw, 96px) 0 0; + padding: 0; + border-top: 1px solid var(--grafite); + counter-reset: gap; +} + +.gaps li { + display: grid; + grid-template-columns: 80px 1fr 120px; + align-items: center; + gap: 24px; + padding: 28px 0; + border-bottom: 1px solid var(--grafite); + counter-increment: gap; + font-size: clamp(18px, 1.9vw, 28px); + font-weight: 300; + line-height: 1.3; + letter-spacing: -0.012em; + transition: padding 0.5s var(--ease); +} + +.gaps li::before { + content: counter(gap, decimal-leading-zero); + font-size: 11px; + font-weight: 500; + letter-spacing: 0.2em; + color: var(--piombo); +} + +.gaps .break { + justify-self: end; + width: 120px; + height: 14px; +} + +.gaps .break line { + stroke: rgba(255, 255, 255, 0.45); +} + +.gaps .break .cut { + stroke: var(--rosso); +} + +.gaps li:hover { + padding-left: 12px; +} + +@media (max-width: 720px) { + .gaps li { + grid-template-columns: 40px 1fr; + } + .gaps .break { + display: none; + } +} + +.nos { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + margin-top: clamp(64px, 8vw, 104px); + border-top: 1px solid var(--grafite); +} + +.nos div { + padding: 32px 28px 0; + border-left: 1px solid var(--grafite); + font-size: 17px; + line-height: 1.5; +} + +.nos div:first-child { + padding-left: 0; + border-left: 0; +} + +.nos span { + display: block; + margin-bottom: 16px; + font-size: 10px; + font-weight: 500; + letter-spacing: 0.24em; + text-transform: uppercase; + color: var(--piombo); +} + +.closing { + max-width: 30ch; + margin-top: clamp(64px, 8vw, 104px); + font-size: clamp(24px, 2.6vw, 38px); + font-weight: 300; + line-height: 1.25; + letter-spacing: -0.02em; +} + +@media (max-width: 1023px) { + .nos { + grid-template-columns: 1fr; + } + .nos div, + .nos div:first-child { + padding: 28px 0; + border-left: 0; + border-bottom: 1px solid var(--grafite); + } +} + +/* ============================================================ + Final CTA + ============================================================ */ +.cta { + position: relative; + min-height: 100svh; + display: flex; + align-items: center; + overflow: hidden; + isolation: isolate; + padding-block: 120px; + text-align: center; +} + +.cta .hero-canvas { + opacity: 0.6; +} + +.cta::after { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0.9) 55%, #000 80%); + pointer-events: none; +} + +.cta .display { + max-width: 17ch; + margin: 28px auto 0; +} + +.cta .copy { + max-width: 56ch; + margin: 40px auto 0; +} + +.cta .lead { + margin-top: 32px; +} + +.cta .btn { + margin-top: 48px; +} + +/* ============================================================ + Footer + ============================================================ */ +.footer { + background: var(--notte); + border-top: 1px solid var(--grafite); + padding-top: clamp(64px, 7vw, 104px); + overflow: hidden; +} + +.footer-top { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + gap: 24px; +} + +.footer-brand { + grid-column: 1 / span 4; +} + +.footer-brand p { + max-width: 34ch; + margin: 28px 0 0; + font-size: 13px; + line-height: 1.75; + color: var(--fumo); +} + +.footer-cols { + grid-column: 6 / span 7; + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 24px; +} + +.footer h4 { + margin: 0 0 22px; + font-size: 11px; + font-weight: 500; + letter-spacing: 0.22em; + text-transform: uppercase; +} + +.footer ul { + list-style: none; + margin: 0; + padding: 0; +} + +.footer li + li { + margin-top: 12px; +} + +.footer li a { + font-size: 11px; + letter-spacing: 0.16em; + text-transform: uppercase; + color: var(--fumo); + transition: color 0.3s var(--ease); +} + +.footer li a:hover { + color: var(--rosso); +} + +.socials { + display: flex; + gap: 8px; + margin-top: 32px; +} + +.socials a { + display: grid; + place-items: center; + width: 40px; + height: 40px; + border: 1px solid var(--grafite); + color: var(--bianco); + transition: + border-color 0.3s var(--ease), + color 0.3s var(--ease); +} + +.socials a:hover { + border-color: var(--rosso); + color: var(--rosso); +} + +.socials svg { + width: 16px; + height: 16px; +} + +.footer-word { + margin: clamp(64px, 8vw, 120px) 0 0; + font-size: min(7.1vw, 102px); + font-weight: 300; + line-height: 0.9; + letter-spacing: -0.05em; + text-transform: uppercase; + color: rgba(255, 255, 255, 0.07); + white-space: nowrap; + user-select: none; +} + +.footer-bottom { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + gap: 16px; + margin-top: 24px; + padding-block: 28px; + border-top: 1px solid var(--grafite); + font-size: 10px; + font-weight: 500; + letter-spacing: 0.2em; + text-transform: uppercase; + color: var(--piombo); +} + +.footer-bottom nav { + display: flex; + gap: 28px; +} + +.footer-bottom a:hover { + color: var(--bianco); +} + +@media (max-width: 1023px) { + .footer-brand, + .footer-cols { + grid-column: 1 / -1; + } + .footer-cols { + margin-top: 40px; + } +} + +@media (max-width: 560px) { + .footer-cols { + grid-template-columns: 1fr 1fr; + } +} + +/* ============================================================ + Reduced motion + ============================================================ */ +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + *, + *::before, + *::after { + animation-duration: 0.001ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.001ms !important; + transition-delay: 0ms !important; + } + [data-reveal] { + opacity: 1; + transform: none; + } +} + +@media (max-width: 767px) { + .hero .hero-canvas { + opacity: 0.45; + } } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 9852c15..fbf03c7 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,29 +1,39 @@ -import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; +import type { Metadata, Viewport } from "next"; +import { Inter } from "next/font/google"; import "./globals.css"; -const geistSans = Geist({ - variable: "--font-geist-sans", +const inter = Inter({ + variable: "--font-inter", subsets: ["latin"], + display: "swap", }); -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); +const description = + "AI Growth Technologies connects paid media, SEO, AI visibility, web, attribution, and technology into one accountable digital growth system."; export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + metadataBase: new URL("https://www.aigrowthtechnologies.com"), + title: "AI Growth Technologies | Digital Growth for the AI Era", + description, + alternates: { canonical: "/" }, + openGraph: { + type: "website", + url: "/", + siteName: "AI Growth Technologies", + title: "AI Growth Technologies | Digital Growth for the AI Era", + description, + }, +}; + +export const viewport: Viewport = { + themeColor: "#000000", + colorScheme: "dark", }; export default function RootLayout({ children }: LayoutProps<"/">) { return ( - -
{children} + + {children} ); } diff --git a/src/app/page.tsx b/src/app/page.tsx index c887311..c6210bf 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,69 +1,468 @@ -import Image from "next/image"; +import type { CSSProperties, ReactNode } from "react"; +import SiteHeader from "@/components/site-header"; +import GlobeCanvas from "@/components/globe-canvas"; +import RevealObserver from "@/components/reveal-observer"; +import StatCounter from "@/components/stat-counter"; +import Capabilities from "@/components/capabilities"; +import QueryTicker from "@/components/query-ticker"; +import ProductVisual from "@/components/product-visuals"; +import Logo from "@/components/logo"; +import { stats, products, journeySteps, gaps, footerColumns } from "@/content/home"; + +type Vars = CSSProperties & Record<`--${string}`, string | number>; +const delay = (ms: number) => ({ "--d": `${ms}ms` }) as Vars; + +const Arrow = () => →; + +function Eyebrow({ index, children }: { index?: string; children: ReactNode }) { + return ( ++ {index && {index}} + {children} +
+ ); +} export default function Home() { return ( -
- page.tsx
- {" "}
- file.
- - Looking for a starting point or more instructions? Head over to{" "} - - Templates - {" "} - or the{" "} - - Learning - {" "} - center. -
-+ Your customer might find you through Google today, an AI answer tomorrow, and a paid ad three + days later. +
+They don’t think in channels. Your growth strategy shouldn’t either.
++ AI Growth Technologies brings paid media, search, AI visibility, technology, and attribution + together so each part strengthens the others. +
+One strategy. Connected execution. A clearer view of what is actually driving growth.
++ A search can lead to an ad. An ad can lead to a website visit. An AI answer can introduce the brand + before either happens. +
+To your customer, that is not SEO, paid media, AI, and web.
+It is one experience with your business.
+Our capabilities are designed to work that way too.
+Marketing produces plenty of numbers.
+The harder part is knowing which ones matter.
++ Our proprietary technology gives our teams and clients a clearer view across attribution, organic and + AI visibility, and digital resilience. +
++ Not more data for the sake of it. Better information for the decisions that come next. +
+{b}
+ ))} +People still search Google.
++ Now they also ask AI platforms which companies to consider, how products compare, what to buy, and + who to trust. +
+That changes what visibility means.
++ Rankings still matter. But so do the information, authority, context, and signals that help AI + systems understand a brand well enough to surface it. +
+Our SEO and LLMO work connects both sides of that shift.
+Too often, the answer depends on which dashboard you open.
++ We bring media, search, AI visibility, and attribution closer together to answer a more useful + question: +
+What actually helped move the customer toward a decision?+
Better attribution isn’t about producing a prettier report.
++ It is about knowing where the next dollar has the best chance of doing something useful. +
+We look at how discovery, acquisition, experience, data, technology, and security affect one another.
+Then we strengthen the connections that make the whole system perform better.
++ Just a clearer system and a team accountable for making it work. +
++ Maybe acquisition is getting more expensive. Maybe organic visibility has stalled. Maybe AI is changing + how customers find you. +
+Or maybe every dashboard looks healthy, but the business is telling you something different.
+You don’t need to diagnose it before the call.
+Bring us what you’re seeing. We’ll start there.
+{p}
+ ))} ++ + +
+ ); +} diff --git a/src/components/reveal-observer.tsx b/src/components/reveal-observer.tsx new file mode 100644 index 0000000..2a883ae --- /dev/null +++ b/src/components/reveal-observer.tsx @@ -0,0 +1,25 @@ +"use client"; + +import { useEffect } from "react"; + +/** Adds `is-in` to every `[data-reveal]` / `[data-reveal-group]` element as it scrolls into view. */ +export default function RevealObserver() { + useEffect(() => { + const targets = document.querySelectorAll