diff --git a/app/globals.css b/app/globals.css index 2f5f444..61abe73 100644 --- a/app/globals.css +++ b/app/globals.css @@ -610,3 +610,317 @@ main, html { scroll-behavior: auto; } *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } } + +/* IP Lens */ +.ip-lens-promo { + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto; + align-items: center; + gap: 1.2rem; + margin-top: 1rem; + padding: 1rem 1.1rem; + border: 1px solid var(--line); + border-radius: 12px; + background: linear-gradient(115deg, rgba(105, 227, 176, 0.045), rgba(155, 135, 245, 0.055)); +} + +.ip-lens-promo-icon { + width: 46px; + height: 46px; + border-radius: 10px; + box-shadow: 0 8px 24px rgba(25, 66, 230, 0.28); +} + +.ip-lens-promo .section-kicker { margin: 0 0 0.2rem; color: var(--green); font-size: 0.54rem; } +.ip-lens-promo h2 { font-size: 1rem; } +.ip-lens-promo p { margin-top: 0.15rem; color: var(--muted); font-size: 0.75rem; } +.ip-lens-promo > a { color: var(--purple-bright); font-family: var(--font-mono); font-size: 0.67rem; } +.ip-lens-promo > a span { margin-left: 0.5rem; } + +.ip-lens-page { --product-line: rgba(255, 255, 255, 0.105); } + +.product-hero { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(330px, 0.72fr); + align-items: center; + gap: clamp(3rem, 8vw, 7rem); + min-height: 720px; + padding: clamp(4.5rem, 8vw, 7rem) 0; +} + +.product-hero-copy { max-width: 650px; } +.product-hero .eyebrow { color: var(--green); } +.product-hero .live-dot { background: var(--green); box-shadow: 0 0 12px rgba(105, 227, 176, 0.62); } + +.product-identity { + display: flex; + align-items: center; + gap: 0.9rem; + margin-bottom: 1.15rem; +} + +.product-app-icon { + width: 58px; + height: 58px; + border: 1px solid rgba(255, 255, 255, 0.17); + border-radius: 13px; + box-shadow: 0 12px 34px rgba(25, 66, 230, 0.28); +} + +.product-name { + color: var(--purple-bright); + font-family: var(--font-mono); + font-size: 0.92rem; + font-weight: 700; + letter-spacing: -0.03em; +} + +.product-name span { display: block; margin-top: 0.2rem; color: var(--faint); font-size: 0.5rem; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase; } + +.product-hero h1 { + max-width: 690px; + font-size: clamp(3.4rem, 6.7vw, 5.75rem); + line-height: 0.98; + letter-spacing: -0.072em; +} + +.product-hero-description { + max-width: 620px; + margin-top: 1.5rem; + color: var(--muted); + font-size: 1rem; + line-height: 1.75; +} + +.app-store-cta { gap: 0.85rem; } +.app-store-cta small { font-family: var(--font-mono); font-size: 0.52rem; font-weight: 700; text-transform: uppercase; } +.app-store-cta.is-disabled, +.app-store-cta.is-disabled:disabled { cursor: not-allowed; opacity: 0.72; } + +.product-badges { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + padding: 0; + margin: 1.35rem 0 0; + list-style: none; +} + +.product-badges li { + display: inline-flex; + align-items: center; + gap: 0.45rem; + min-height: 30px; + padding: 0 0.62rem; + border: 1px solid var(--line); + border-radius: 999px; + color: var(--faint); + background: rgba(255, 255, 255, 0.022); + font-family: var(--font-mono); + font-size: 0.56rem; +} + +.product-badges i, +.placeholder-status i, +.privacy-signal i { + width: 5px; + height: 5px; + border-radius: 50%; + background: var(--green); + box-shadow: 0 0 8px rgba(105, 227, 176, 0.48); +} + +.hero-app-preview { position: relative; display: grid; place-items: center; min-width: 0; } +.preview-orbit { position: absolute; width: min(46vw, 500px); aspect-ratio: 1; border: 1px solid rgba(155, 135, 245, 0.12); border-radius: 50%; background: radial-gradient(circle, rgba(155, 135, 245, 0.11), transparent 62%); } +.preview-orbit::before, +.preview-orbit::after { position: absolute; inset: 14%; border: 1px solid rgba(255, 255, 255, 0.045); border-radius: inherit; content: ""; } +.preview-orbit::after { inset: 31%; border-color: rgba(105, 227, 176, 0.08); } + +.app-screenshot-frame { position: relative; z-index: 1; width: min(100%, 250px); margin: 0; } +.app-screenshot-frame.is-featured { width: min(100%, 348px); transform: rotate(1.25deg); } + +.app-device-shell { + position: relative; + overflow: hidden; + aspect-ratio: 1290 / 2796; + padding: 10px; + border: 1px solid rgba(255, 255, 255, 0.24); + border-radius: 38px; + background: #07070b; + box-shadow: 0 34px 85px rgba(0, 0, 0, 0.55), 0 0 55px rgba(116, 87, 231, 0.12), inset 0 0 0 2px rgba(255, 255, 255, 0.025); +} + +.app-device-shell img { display: block; width: 100%; height: 100%; border-radius: 29px; object-fit: cover; } +.app-device-speaker { position: absolute; top: 17px; left: 50%; z-index: 3; width: 30%; height: 20px; border-radius: 999px; background: #060609; transform: translateX(-50%); } + +.app-screenshot-placeholder { + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100%; + padding: 3.2rem 1.15rem 1.2rem; + border: 1px solid rgba(255, 255, 255, 0.07); + border-radius: 29px; + background: + linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px), + linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px), + linear-gradient(155deg, #12121a, #0b0b11); + background-size: 28px 28px, 28px 28px, auto; +} + +.placeholder-command { + align-self: flex-start; + padding: 0.4rem 0.55rem; + border: 1px solid rgba(155, 135, 245, 0.3); + border-radius: 6px; + color: var(--purple-bright); + background: rgba(155, 135, 245, 0.08); + font-family: var(--font-mono); + font-size: 0.58rem; +} + +.app-screenshot-placeholder small { display: block; margin-bottom: 0.65rem; color: var(--faint); font-family: var(--font-mono); font-size: 0.52rem; letter-spacing: 0.1em; text-transform: uppercase; } +.app-screenshot-placeholder strong { display: block; font-size: clamp(1.1rem, 2vw, 1.4rem); line-height: 1.15; } +.app-screenshot-placeholder p { margin-top: 0.7rem; color: var(--faint); font-size: 0.65rem; line-height: 1.55; } +.app-screenshot-placeholder code { color: var(--muted); font-family: var(--font-mono); overflow-wrap: anywhere; } +.placeholder-status { display: flex; align-items: center; gap: 0.45rem; color: var(--faint); font-family: var(--font-mono); font-size: 0.5rem; text-transform: uppercase; } +.app-screenshot-frame figcaption { display: flex; justify-content: space-between; gap: 0.75rem; margin-top: 0.75rem; color: var(--muted); font-size: 0.68rem; } +.app-screenshot-frame figcaption span { color: var(--purple-bright); font-family: var(--font-mono); font-size: 0.58rem; } + +.product-section { padding: 7rem 0; border-top: 1px solid var(--product-line); } +.product-section-header { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(280px, 0.75fr); align-items: end; gap: 4rem; margin-bottom: 3rem; } +.product-section-header > div { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 0 0.75rem; } +.product-section-header .section-kicker { margin: 0; } +.product-section-header h2 { grid-column: 1 / -1; margin-top: 0.9rem; font-size: clamp(2.3rem, 4.7vw, 3.9rem); line-height: 1.07; letter-spacing: -0.055em; } +.product-section-header > p { max-width: 500px; color: var(--muted); font-size: 0.9rem; line-height: 1.75; } + +.screenshot-section { overflow: hidden; } +.screenshot-gallery { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: start; justify-items: center; gap: clamp(1rem, 4vw, 3rem); padding: 1.5rem clamp(0rem, 3vw, 2rem) 0; } +.screenshot-gallery > :nth-child(2) { margin-top: 3rem; } + +.ip-lens-feature-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.75rem; } +.ip-lens-feature-card { min-height: 230px; } +.ip-lens-feature-card h3 { font-size: 1.05rem; } +.ip-lens-feature-card p { font-size: 0.8rem; line-height: 1.65; } + +.sample-workflow { overflow: hidden; border: 1px solid var(--line-strong); border-radius: var(--radius); background: rgba(13, 13, 19, 0.92); box-shadow: 0 30px 90px rgba(0, 0, 0, 0.35); } +.sample-workflow-bar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; min-height: 46px; padding: 0 1rem; border-bottom: 1px solid var(--line); color: var(--faint); font-family: var(--font-mono); font-size: 0.6rem; } +.sample-workflow-bar .terminal-dots { justify-self: start; } +.sample-workflow-bar strong { color: var(--muted); font-weight: 500; text-transform: uppercase; } +.sample-workflow-bar > :last-child { justify-self: end; } +.sample-workflow-body { display: grid; grid-template-columns: 0.72fr 1.28fr; min-height: 370px; } +.sample-address { display: flex; flex-direction: column; justify-content: center; padding: clamp(1.5rem, 4vw, 3.5rem); border-right: 1px solid var(--line); background: radial-gradient(circle at 10% 15%, rgba(155, 135, 245, 0.12), transparent 65%); } +.sample-address > span { color: var(--green); font-family: var(--font-mono); font-size: 0.63rem; } +.sample-address strong { margin-top: 0.8rem; font-family: var(--font-mono); font-size: clamp(1.5rem, 3.5vw, 2.8rem); letter-spacing: -0.06em; overflow-wrap: anywhere; } +.sample-address p { max-width: 340px; margin-top: 1.2rem; color: var(--faint); font-size: 0.72rem; line-height: 1.65; } +.sample-workflow dl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: center; padding: clamp(1rem, 3vw, 2rem); } +.sample-workflow dl div { min-width: 0; padding: 1rem; border-bottom: 1px solid var(--line); } +.sample-workflow dt { color: var(--faint); font-family: var(--font-mono); font-size: 0.55rem; letter-spacing: 0.06em; text-transform: uppercase; } +.sample-workflow dd { margin-top: 0.35rem; color: #d8d4e2; font-family: var(--font-mono); font-size: 0.72rem; overflow-wrap: anywhere; } + +.privacy-callout { display: grid; grid-template-columns: 1.25fr 0.75fr; overflow: hidden; border: 1px solid rgba(105, 227, 176, 0.2); border-radius: var(--radius); background: linear-gradient(125deg, rgba(105, 227, 176, 0.055), rgba(155, 135, 245, 0.035)); } +.privacy-copy { padding: clamp(1.5rem, 5vw, 4rem); } +.privacy-signal { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--green); font-family: var(--font-mono); font-size: 0.57rem; text-transform: uppercase; } +.privacy-copy h3 { max-width: 570px; margin-top: 1.2rem; font-size: clamp(1.65rem, 3.5vw, 2.75rem); letter-spacing: -0.045em; } +.privacy-copy > p { max-width: 650px; margin-top: 1rem; color: var(--muted); font-size: 0.87rem; line-height: 1.75; } +.privacy-links { display: flex; flex-wrap: wrap; gap: 1rem 1.5rem; margin-top: 1.75rem; } +.privacy-links a { color: var(--purple-bright); font-family: var(--font-mono); font-size: 0.63rem; } +.privacy-facts { display: grid; align-content: center; padding: 1rem clamp(1rem, 3vw, 2rem); margin: 0; border-left: 1px solid rgba(105, 227, 176, 0.15); list-style: none; } +.privacy-facts li { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 0.9rem; min-height: 62px; border-bottom: 1px solid var(--line); } +.privacy-facts li:last-child { border-bottom: 0; } +.privacy-facts span { color: var(--green); font-family: var(--font-mono); font-size: 0.55rem; } +.privacy-facts strong { font-size: 0.78rem; font-weight: 500; } + +.audience-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); padding: 0; margin: 0; border-top: 1px solid var(--line); border-left: 1px solid var(--line); list-style: none; } +.audience-list li { display: flex; align-items: center; gap: 1rem; min-height: 76px; padding: 1rem; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); color: #d8d4e2; font-size: 0.82rem; } +.audience-list span { color: var(--purple); font-family: var(--font-mono); font-size: 0.56rem; } + +.pricing-panel { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--line-strong); border-radius: var(--radius); background: rgba(13, 13, 19, 0.9); } +.pricing-panel > div { padding: clamp(1.5rem, 5vw, 4rem); } +.pricing-status { color: var(--green); font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.08em; text-transform: uppercase; } +.pricing-panel h3 { margin-top: 1rem; font-size: clamp(1.7rem, 3.3vw, 2.6rem); letter-spacing: -0.045em; } +.pricing-panel p { margin: 0.6rem 0 1.6rem; color: var(--muted); font-size: 0.78rem; } +.pricing-panel > ul { display: grid; align-content: center; gap: 0; padding: 2rem clamp(1.5rem, 5vw, 4rem); margin: 0; border-left: 1px solid var(--line); list-style: none; } +.pricing-panel li { display: flex; align-items: center; gap: 0.8rem; min-height: 48px; border-bottom: 1px solid var(--line); color: var(--muted); font-size: 0.78rem; } +.pricing-panel li:last-child { border-bottom: 0; } +.pricing-panel li span { color: var(--green); font-family: var(--font-mono); } + +.faq-list { border-top: 1px solid var(--line-strong); } +.faq-list details { border-bottom: 1px solid var(--line); } +.faq-list summary { display: grid; grid-template-columns: 2rem 1fr auto; align-items: center; gap: 1rem; min-height: 72px; padding: 0.8rem 0.25rem; cursor: pointer; color: #dcd8e5; font-size: 0.9rem; list-style: none; } +.faq-list summary::-webkit-details-marker { display: none; } +.faq-list summary::after { color: var(--purple-bright); content: "+"; font-family: var(--font-mono); font-size: 1rem; } +.faq-list details[open] summary::after { content: "−"; } +.faq-list summary span { color: var(--faint); font-family: var(--font-mono); font-size: 0.55rem; } +.faq-list details > div { max-width: 800px; padding: 0 1rem 1.4rem 3.25rem; } +.faq-list details p { color: var(--muted); font-size: 0.8rem; line-height: 1.7; } +.faq-list details a { display: inline-block; margin-top: 0.8rem; color: var(--purple-bright); font-family: var(--font-mono); font-size: 0.62rem; } + +.product-final-cta { display: grid; grid-template-columns: 1fr auto; align-items: end; gap: 3rem; margin: 1rem 0 8rem; padding: clamp(1.5rem, 4vw, 3rem); border: 1px solid var(--line-strong); border-radius: var(--radius); background: linear-gradient(120deg, rgba(155, 135, 245, 0.08), rgba(105, 227, 176, 0.035)); } +.product-final-cta .section-kicker { color: var(--green); } +.product-final-cta h2 { font-size: clamp(2rem, 4.5vw, 3.5rem); line-height: 1.08; letter-spacing: -0.055em; } +.product-final-cta p { margin-top: 0.8rem; color: var(--muted); font-size: 0.86rem; } +.product-final-cta .hero-actions { justify-content: flex-end; margin: 0; } + +.product-legal-page .breadcrumbs { margin-bottom: 3rem; } +.product-legal-page .section-kicker { color: var(--green); } +.product-legal-page > p + p { margin-top: 1rem; } +.support-warning { display: grid; grid-template-columns: auto 1fr; gap: 1rem; margin: 2rem 0; padding: 1rem; border: 1px solid rgba(243, 187, 107, 0.25); border-radius: 10px; background: rgba(243, 187, 107, 0.055); } +.support-warning > span { display: grid; place-items: center; width: 28px; height: 28px; border: 1px solid rgba(243, 187, 107, 0.35); border-radius: 7px; color: var(--amber); font-family: var(--font-mono); } +.support-warning p { font-size: 0.78rem; } +.support-warning strong { color: #e2d5bd; } +.inline-support-button { width: max-content; margin: 0.5rem 0; color: #d6d2df !important; } + +@media (max-width: 960px) { + .product-hero { grid-template-columns: 1fr; gap: 4rem; } + .hero-app-preview { width: min(100%, 600px); } + .preview-orbit { width: min(90vw, 520px); } + .product-section-header { grid-template-columns: 1fr; gap: 1.2rem; } + .product-section-header > p { max-width: 650px; } + .ip-lens-feature-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } + .product-final-cta { grid-template-columns: 1fr; align-items: start; } + .product-final-cta .hero-actions { justify-content: flex-start; } +} + +@media (max-width: 700px) { + .ip-lens-promo { grid-template-columns: auto 1fr; margin-top: 0.75rem; padding: 0.85rem; } + .ip-lens-promo > a { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; min-height: 44px; padding: 0 0.75rem; border: 1px solid var(--line); border-radius: 8px; } + .product-hero { gap: 3rem; min-height: 0; padding: 3.5rem 0 4.5rem; } + .product-hero h1 { font-size: clamp(3rem, 15vw, 4.45rem); } + .product-hero-description { margin-top: 1.1rem; font-size: 0.9rem; line-height: 1.65; } + .product-hero .hero-actions > * { flex: 1 1 150px; } + .product-badges { gap: 0.4rem; } + .product-badges li { font-size: 0.52rem; } + .hero-app-preview { width: 100%; } + .app-screenshot-frame.is-featured { width: min(84vw, 330px); transform: none; } + .product-section { padding: 4.25rem 0; } + .product-section-header { margin-bottom: 2rem; } + .product-section-header h2 { font-size: clamp(2rem, 11.5vw, 3rem); } + .product-section-header > p { font-size: 0.84rem; line-height: 1.65; } + .screenshot-gallery { display: flex; justify-content: start; gap: 1rem; width: calc(100% + 14px); padding: 0 14px 1rem 0; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: thin; } + .screenshot-gallery .app-screenshot-frame { flex: 0 0 min(75vw, 260px); scroll-snap-align: start; } + .screenshot-gallery > :nth-child(2) { margin-top: 0; } + .ip-lens-feature-grid { grid-template-columns: 1fr; gap: 0.55rem; } + .ip-lens-feature-card { display: flex; min-height: 190px; } + .sample-workflow-bar { grid-template-columns: 1fr auto; } + .sample-workflow-bar strong { display: none; } + .sample-workflow-body { grid-template-columns: 1fr; } + .sample-address { min-height: 250px; border-right: 0; border-bottom: 1px solid var(--line); } + .sample-workflow dl { grid-template-columns: 1fr; padding: 0.75rem; } + .sample-workflow dl div { padding: 0.85rem 0.5rem; } + .privacy-callout { grid-template-columns: 1fr; } + .privacy-facts { border-top: 1px solid rgba(105, 227, 176, 0.15); border-left: 0; } + .privacy-links { flex-direction: column; } + .privacy-links a { display: flex; align-items: center; justify-content: space-between; min-height: 44px; padding: 0 0.75rem; border: 1px solid var(--line); border-radius: 8px; } + .audience-list { grid-template-columns: 1fr; } + .audience-list li { min-height: 62px; } + .pricing-panel { grid-template-columns: 1fr; } + .pricing-panel > ul { border-top: 1px solid var(--line); border-left: 0; } + .pricing-panel .app-store-cta { width: 100%; } + .faq-list summary { min-height: 64px; font-size: 0.82rem; } + .faq-list details > div { padding-left: 3.25rem; } + .product-final-cta { margin-bottom: 5rem; } + .product-final-cta .hero-actions { width: 100%; } + .product-final-cta .hero-actions > * { flex: 1 1 150px; } + .product-legal-page .breadcrumbs { margin-bottom: 2rem; } +} diff --git a/app/ip-lens/page.tsx b/app/ip-lens/page.tsx new file mode 100644 index 0000000..ec37958 --- /dev/null +++ b/app/ip-lens/page.tsx @@ -0,0 +1,235 @@ +import type { Metadata } from "next"; +import Image from "next/image"; +import Link from "next/link"; +import { AppScreenshotFrame } from "@/components/ip-lens/AppScreenshotFrame"; +import { AppStoreCTA } from "@/components/ip-lens/AppStoreCTA"; +import { IPLensFeatureCard } from "@/components/ip-lens/IPLensFeatureCard"; +import { SiteChrome } from "@/components/landing/SiteChrome"; +import { ipLensConfig } from "@/data/ip-lens"; + +const description = + "IP Lens is a focused iPhone networking toolkit for IP lookup, DNS records, registration data, subnet calculations, batch analysis, and more—with no ads or subscription."; + +export const metadata: Metadata = { + title: { absolute: "IP Lens — Networking Tools for iPhone | buffer.lol" }, + description, + alternates: { canonical: "/ip-lens" }, + robots: { index: true, follow: true }, + openGraph: { + title: "IP Lens — Networking Tools for iPhone", + description, + type: "website", + url: "/ip-lens", + siteName: "buffer.lol" + }, + twitter: { + card: "summary", + title: "IP Lens — Networking Tools for iPhone", + description + } +}; + +const sampleFields = [ + ["Address", "203.0.113.42"], + ["IP version", "IPv4"], + ["ASN", "AS64500 · sample"], + ["Provider", "Example Network"], + ["Reverse DNS", "host-42.example.test"], + ["Network range", "203.0.113.0/24"], + ["Approximate region", "Example region"] +] as const; + +function SectionHeader({ id, number, label, title, text }: { id: string; number: string; label: string; title: string; text: string }) { + return ( +
+
+ {number} + {label} +

{title}

+
+

{text}

+
+ ); +} + +export default function IPLensPage() { + const [heroScreenshot, ...galleryScreenshots] = ipLensConfig.screenshots; + + return ( + +
+
+
+
native://ios
+
+ IP Lens app icon +

{ipLensConfig.appName}IP lookup and network tools

+
+

See the network more clearly.

+

IP lookup, DNS inspection, registration data, subnet calculations, and more—built into one focused networking toolkit for iPhone.

+
+ + Explore features +
+
    + {ipLensConfig.badges.map((badge) =>