尚未偵測到更新。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.