Javis OS
Javis OS는 기업가를 돕는 에이전시 AI로, 업무를 지원하고 함께 성장합니다
RingPost는 지역 비즈니스를 위한 AI 비즈니스 파트너입니다
RingPost is the AI business partner for local businesses. It answers calls, texts, WhatsApp, Instagram, Messenger and email around the clock, books appointments into your calendar, makes and posts you
비즈니스TypeScript · MDXGitHub @asandhu5온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기RingPost is the AI business partner for local businesses. It answers calls, texts, WhatsApp, Instagram, Messenger and email around the clock, books appointments into your calendar, makes and posts your content, replies to comments and reviews, and tells you what's working.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Production Next.js 16 landing page for RingPost, the AI front desk for local service businesses.
npm install
npm run dev # http://localhost:3000
npm run build # production build
Node 18.18+ required. Deploys to Vercel with zero config.
lib/site.ts holds the booking link, the contact email, and the nav map.
Change BOOKING_URL there and every "Book a call" button on the page
updates — nav, mobile menu, CTA, footer.
export const BOOKING_URL = "mailto:[email protected]?subject=..."; // ← your Cal.com / Calendly link
export const CONTACT_EMAIL = "[email protected]"; // ← your inbox
| # | Section | id | Component |
|---|---|---|---|
| 1 | Hero | #top | hero-section.tsx |
| 2 | The 90-second save (live demo) | — | live-demo-section.tsx |
| 3 | Features (all 8) | #features | features-section.tsx |
| 4 | What's included (all 33 capabilities) | #included | included-section.tsx |
| 5 | How it works | #how-it-works | how-it-works-section.tsx |
| 6 | Channels | #channels | channels-section.tsx |
| 7 | Marketing | #marketing | marketing-section.tsx |
| 8 | Always answering | — | metrics-section.tsx |
| 9 | Trust | #trust | trust-section.tsx |
| 10 | Book a call | #contact | cta-section.tsx |
| 11 | Footer | — | footer-section.tsx |
Every nav link resolves to a real section. In the original template
Marketing and Trust pointed at nothing.
Entrance primitives — components/landing/motion/primitives.tsx:
<Reveal> — scroll-triggered fade + slide + de-blur<SplitText> — per-word/char staggered headline reveal<Parallax> — scroll-driven depth on image panels<Marquee> — seamless infinite scroll (duplicates children, shifts -50%)<Magnetic> — cursor-attracted primary CTAs<TiltCard> — 3D tilt + cursor-following sheen<Scramble> — decode effect on mono eyebrows<CountUp> — eased number roll-inScroll-scrubbed primitives — components/landing/motion/scroll-primitives.tsx.
These are GSAP/ScrollTrigger-style techniques rebuilt natively, so nothing
plays on a fixed timer — scroll up and they run backwards:
<ScrollScrub> — scale/opacity tied directly to scroll position<MaskReveal> — clip-path wipe instead of a fade (sharper on big imagery).
Note: the observed node and the clipped node are deliberately separate
elements. clip-path: inset(100%) zeroes an element's paint area, and the
browser then reports it as not intersecting — so an observer watching the
clipped node would never fire and the reveal would stay shut permanently.
Outer div observes, inner div clips. Don't collapse them.<VelocitySkew> — skews and squashes in proportion to scroll speed, springs back at rest<ScrollLine> — a rule that draws itself as the section passes<ScrollCharStagger> — sentences light word-by-word as you scroll through themBacking hooks in hooks/use-scroll-motion.ts: useScrollTrigger
(0→1 element progress), useScrollVelocity, useSmoothScroll.
Global atmosphere in motion/atmosphere.tsx:
<CustomCursor> — a precise dot plus a ring that lags behind it and
swells + turns pink over anything clickable<AuroraField> — a soft three-colour field that follows the pointer
across the whole page, screen-blended so it tints every section<ScrollProgress> — gradient hairline bar<Grain> — film grain over the flat colour fieldsCursor-reactive behaviour also lives in the sections themselves:
radial glow on the "What's included" cards, cursor-tracking sheen on
<TiltCard>, a spotlight on the CTA panel, and pointer-repelled
particles behind the flagship feature card.
Hooks in hooks/use-motion.ts: useInView, useParallax,
useScrollProgress, useReducedMotion.
Phones get the same layout and the same content — only the expensive
machinery is skipped. useIsMobileDevice() (coarse pointer or viewport
under 1024px) gates:
| Skipped on mobile | Replaced with | Why |
|---|---|---|
| Hero background video | Static gradient field | Multi-MB download over cellular |
| Particle canvas (features) | CSS gradient | 70 particles on an uncapped rAF loop |
| Grid canvas (metrics) | CSS dot lattice | Redrawn every frame |
| 3× sparkline canvases | CSS stripe + mask | Three more rAF loops |
<VelocitySkew> | Plain passthrough | Transform repaints a whole grid |
useScrollVelocity | Returns 0 | Was re-rendering every frame |
mix-blend-screen on the aurora | Un-blended gradient | iOS Safari composites fixed + blend badly |
| Film grain overlay | Nothing | Invisible at that pixel density |
Also mobile-specific:
min-h-[100svh], not 100vh. On iOS Safari 100vh is the
large viewport height, so the address bar covers the bottom of the hero
and hides the stats row. svh is the height that's actually visible.viewportFit: 'cover' plus env(safe-area-inset-bottom) so the dark
background runs into the notch and home-indicator areas.themeColor matches the plum background, so browser chrome blends in.Scroll safety net: useInView does not rely on IntersectionObserver
alone. A fast flick-scroll can carry a short element from below the fold to
above it between two observer samples, crossing no threshold and firing no
callback — leaving that content permanently invisible. So it also checks on
scroll and reveals when the element has entered, has been scrolled past, or
when the document is at its end (the footer can never scroll further into
view). Reveals fail open, never closed.
Accessibility: every primitive checks prefers-reduced-motion and
degrades to a static, fully-visible state. There's also a global CSS
guard in globals.css. Keyboard focus rings are visible on both light
and dark panels.
The palette is a deep plum (oklch(0.145 0.022 306)), lifted well
off the template's near-black and pulled toward the magenta/violet hue
that runs through the site's photography, so the UI and the imagery read
as one world instead of colour photos on neutral grey.
Everything is driven by tokens in app/globals.css:
--surface-1 / --surface-2 / --surface-3 elevation steps
--surface-light light panel token (currently unused)
--brand-pink #eca8d6 primary accent
--brand-violet #a78bfa secondary accent
--brand-cyan #67e8f9 tertiary accent
No section uses pure black or pure white any more. To reskin the whole site, change those tokens.
Per the brief, this page contains no invented social proof:
The live demo transcript is labelled on-screen as an illustration of the missed-call flow, not a recorded customer.
Trade-agnostic: the page never names a single industry anywhere. The live demo transcript, the Trust lookup example, and all feature copy are written so any local service business reads itself into them. This is a platform landing page, not a vertical-specific one.
Most imagery streams from the original Vercel blob CDN and works as-is.
Local assets live in public/images/. To self-host the remote images,
download them and swap the URLs — they're referenced directly in the
section components.