尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Bilingual (Hungarian/English) poetry portfolio: React, TypeScript, Vite and Motion in a TurboRepo monorepo, with an Express + Firestore admin portal. Swipeable full-screen poem reader, auto-advancing carousel, working contact form, WCAG AA contrast, and CI that gates every deploy on Playwright layout tests.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Bilingual (Hungarian/English) poetry portfolio. Every route is prerendered to static HTML, so the poems are indexable without JavaScript, and an admin portal edits the content live.
Live: https://artoriun.github.io/kov-cs-poetry/
Measured against the live deploy. CI runs the same audit on every push and gates accessibility, best practices and SEO at 100.
Mobile — LCP 2.7s · CLS 0 · TBT 0ms
Desktop — LCP 0.6s · CLS 0.004 · TBT 0ms
| Front end | React, TypeScript, Vite, Motion |
| Back end | Express, Firestore |
| Media | Cloudinary |
| Tooling | TurboRepo, Biome, Playwright |
| Hosting | GitHub Pages (site) · Render (API) |
Three workspaces: packages/web, packages/api, packages/shared.
npm install
npm run dev # web + API, with /api proxied in development
Copy .env.example to packages/api/.env and set at least:
ADMIN_PASSWORD= # or ADMIN_PASSWORD_HASH from `npm run hash-password`
JWT_SECRET=
FIREBASE_PROJECT_ID= # plus CLIENT_EMAIL, PRIVATE_KEY, STORAGE_BUCKET
CLOUDINARY_URL=
Contact email (RESEND_API_KEY or SMTP) is optional — without it the form returns 503 rather
than dropping messages. Firestore is optional too: leave the FIREBASE_* lines commented and
the API still starts and serves the bundled poems, so a fresh clone runs before you have signed
up for anything. The site runs with no API at all in the same way — the poems are in the bundle,
and the portal is simply unreachable.
npm run build # production build
npm run prerender # static HTML per route, sitemap and robots
npm run ci # everything CI runs, in order
npm run test # API and unit tests
npm run test:e2e # Playwright, four viewport and touch profiles
npm run check:lighthouse # accessibility / SEO / best-practices gate
npm run hash-password # prints an ADMIN_PASSWORD_HASH
npm run backup-poems # writes the live poems to backups/
prefers-reduced-motion respectedPassword login with JWT auth at /admin. Create, edit, hide and drag-to-reorder poems,
feature them on the home carousel, and upload images.
Hiding takes a poem off the site without destroying it: the card stays in the portal, marked and in its place in the order, with a button that puts it back. Nothing in the portal deletes anything permanently, which matters most for poems written there — their text exists nowhere else.
Sign-in is throttled three ways: three wrong passwords in a row pause it for thirty seconds, which the form counts down rather than calling a lockout an incorrect password, and two fifteen-minute limits sit behind that as the real ceiling — one in memory, one in Firestore so it survives a restart.
List is where a poem is written: the image preview sits beside the fields that produce it, because the text is laid over the image rather than beside it. Order is the same poems as cards, dragged into the sequence readers meet them in, beside a contents sidebar that mirrors the public one. Dragging either the cards or the sidebar reorders both, and the change is live for visitors straight away.
On a touch screen each sidebar entry is dragged by its grip. Reordering and scrolling are both vertical in a list like that, so the grip is what tells the browser which one a touch means — everywhere else on the row still scrolls.
Edits are live for visitors immediately. The prerendered HTML that crawlers read is a build-time snapshot and catches up on the next deploy — weekly by cron, or on demand.
Pages are filled with whole stanzas, so most poems need no markers at all: the reader breaks between stanzas and only splits one when that stanza alone is taller than the viewport.
Typing \n in a poem's text marks where it continues on a new page over the same background.
It is part of the poem text, so it needs no schema change, and a poem without one is a single
page. The reader never merges across a break, and still subdivides one further if it is too
tall for the viewport.
npm run ci runs the pipeline in CI's order: Biome, tsc, API and unit tests, Playwright
layout tests across four viewport and touch profiles, an axe accessibility sweep in both
themes, a gzipped bundle budget, a first-paint-versus-hydrated check, and Lighthouse against
the built output.
main; the deploy job needs every check to pass first.CORS_ORIGIN there, and add the API URL as the
VITE_API_URL GitHub Actions secret..nvmrc).Poems live in packages/shared/src/index.ts as a fallback; portal edits are stored in
Firestore and take precedence at runtime.
All rights reserved — see LICENSE. The source is published to be read, not reused: this is client work, and the poems and photographs belong to their author.