尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Atomity Frontend Engineering Challenge
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
An original, animated, scroll-driven visualization of multi-cloud resource cost aggregation — four cloud providers feeding into a shared cost analysis, a focus transition onto one specific workload, and a savings conclusion. Built as a self-built, from-scratch frontend engineering exercise: every visual element (nodes, connectors, chart, cards, badges) is hand-built, with no pre-made UI component library.查看完整 README ↗An original, animated, scroll-driven visualization of multi-cloud resource cost aggregation — four cloud providers feeding into a shared cost analysis, a focus transition onto one specific workload, and a savings conclusion. Built as a self-built, from-scratch frontend engineering exercise: every visual element (nodes, connectors, chart, cards, badges) is hand-built, with no pre-made UI component library.
useScroll/useTransform primitives, which drive every stage off a single progress value so the whole sequence reverses correctly on scroll-up with no separate "undo" logicNo UI/component libraries, no icon packages, and no dependencies beyond what's listed above.
npm install
npm run dev
Then open http://localhost:3000. For a production build:
npm run build
npm run start
Other scripts: npm run lint (ESLint), npm run typecheck (tsc --noEmit).
The page is a single scroll-driven narrative, pinned to the viewport while you scroll through five stages:
Every stage is driven by a single scroll-progress value, so scrolling back up reverses the whole sequence exactly, rather than relying on one-shot "play on enter" animations.
On mobile widths and whenever the OS/browser's reduced-motion preference is on, the page switches to a simpler, non-pinned layout: the same content reveals as you scroll past it with a plain fade-and-slide-in, with no scroll-scrubbing, scaling, or zoom.
Data comes from the public DummyJSON products endpoint:
GET https://dummyjson.com/products?limit=10&select=id,title,price,rating,discountPercentage,stock
The fetched price, rating, discountPercentage, and stock fields are deterministically transformed (see src/lib/mapResourceData.ts) into this visualization's own domain model — cost figures per resource category, provider glyph "lit" states, and a computed savings figure. This is a genuine, dynamic fetch with real async state handling; the numbers are not presented as real cloud telemetry, just realistic-looking figures derived from a real API response, remapped honestly into the visualization's own language.
Loading / error / success states: a skeleton placeholder renders on first load; a network failure shows an explicit error message with a working Retry button; on success, the real values feed the animation and count-up numbers. TanStack Query caches responses for 5 minutes, so revisiting or remounting the section within that window shows data instantly with no redundant network request.
<section>, <h2>, <figure>/<figcaption>, <dl> for label/value pairs) rather than generic <div>s.prefers-reduced-motion is handled as a first-class alternate render path (see above), not a single disabled transition.<button> with a visible focus ring.aria-hidden; all meaningful content is real text in the DOM.src/app/globals.css (colors, spacing, radius, typography, motion durations/easing) are the single source of truth, referenced from components via Tailwind's arbitrary-value syntax (bg-[var(--color-bg-surface)]) rather than scattered hex values.CloudProviderNode, ResourceGlyph, ConnectionLayer, ResourceVisualization, ResourceMetric, SavingsDetail, plus generic Badge/Button/StatValue primitives) rather than one large monolithic section component; the orchestrating MultiCloudSection owns the scroll wiring and passes a single progress value down.@container) drive component-level responsiveness (e.g. the chart's bar layout), color-mix() produces accessible-contrast text variants of the accent color, and clamp() handles fluid type sizing.getBoundingClientRect measurement; this is robust for the current layout but would need to become measurement-based if the composition grew more dynamic.