# Emil Shanayev — resume site Live at **https://shanaty.ru/resume/**. A static Next.js site whose content is read live from Gitea, so it is updated by editing repositories, not by redeploying. ## What comes from where | On the page | Source | |---|---| | Name, role, bio, skills, experience, education, languages, contacts | [`data/resume.json`](data/resume.json) (English) and [`data/resume.ru.json`](data/resume.ru.json) (Russian) in this repo (`main` branch) | | Projects | Public repos of `Emil_Shanaty` on Gitea that carry the topic **`resume`** | | The "full portfolio" link and its project count | The site's `/portfolio/` page, which lists the public repos with the topic `portfolio` (button in the hero and a block after the project list; also in the top bar) | | Project picture | Optional `demo.png`, `demo.jpg`, `demo.gif` or `demo.webp` in the root of that repo | | Project title, kind, description, highlights, tech tags, links, order | Optional `resume-card.json` in the root of that repo | A timer on the server (`resume_sync.py` in the `auto` repo) rebuilds `https://shanaty.ru/data/resume.json` every minute from these sources, so a change shows up within about a minute. If a source is broken (invalid JSON, missing fields, unsafe links) the previous published data stays and the problem is logged (`journalctl -u gitea-resume`). ## Adding a project 1. On Gitea, add the topic `resume` to the repository (it must be public). 2. Optional: put a `demo.png` (or `.jpg`, `.gif`, `.webp`) in the repo root. Up to 6 MB, any proportions; animated GIFs and WebP keep animating. Without one the project gets a generated picture. 3. Optional: put a `resume-card.json` in the repo root to control how the project reads: ```json { "title": "Cortex Engine", "kind": "AI-native 3D game engine", "description": "One or two sentences on what it is and what makes it interesting.", "highlights": ["Pure Vulkan 1.3 backend", "Playable FPS demo"], "tech": ["C#", "Vulkan", "MCP"], "links": [{ "label": "Docs", "href": "https://example.com/docs" }], "rank": 1, "hidden": false } ``` Every field is optional. Without a card the page uses the Gitea description, the repo language and its topics (the topics `resume`, `portfolio` and `featured` are not shown as tags). `rank` puts a project first (lower first, unranked ones follow, newest first); `"hidden": true` removes it from the page. The same values can also live centrally in `projectNotes` (keyed by repo name) in `data/resume.json`; a `resume-card.json` wins over it. The layout adapts to any number of projects: rows of two or three plates with a wider feature plate first, no lone project left in the last row, and a single project gets the whole width. ## Languages The site is bilingual and **Russian is the default** (the browser language is ignored). The RU/EN switch is in the top bar, the choice is stored in `localStorage` and is shared with the front page and the portfolio. Both languages are in the markup and `html[data-lang]` picks one, so there is no flash on load. `data/resume.ru.json` must keep the same structure as `data/resume.json`: skills, experience, education, languages, interests and contacts are paired **by position**, and anything missing in the Russian file falls back to the English text. Project names, descriptions and highlights come from the repositories (English) and are the same in both languages. ## Editing the text To point the portfolio button somewhere else (or rename it), add `"portfolio": { "href": "https://...", "label": "All work" }` to `data/resume.json`. Edit `data/resume.json` (and its Russian twin `data/resume.ru.json`), commit and **push to Gitea** (`git push gitea main`). No rebuild or deploy is needed. ## Development ```bash npm install npm run dev # http://localhost:3000, data from the public https://shanaty.ru/data/resume.json npm run build # static export in out/ ``` `BASE_PATH` sets the URL prefix (default `/Emil_Shanayev_Resume`, for GitHub Pages), `NEXT_PUBLIC_DATA_URL` the data URL and `NEXT_PUBLIC_SITE_ORIGIN` where the other pages of shanaty.ru live (empty in the production build, so the bar's links are root-relative). Fonts (Unbounded, Onest; SIL Open Font License) are bundled in `app/fonts`, so building needs no network. ## Deploy Automatic: every push to `main` (except changes that only touch `data/**` or `*.md`) runs `.gitea/workflows/deploy.yml` on the server's Gitea Actions runner. It builds the site and swaps the `resume/` folder of shanaty.ru in. Gitea runs `.gitea/workflows` instead of `.github/workflows`, so the GitHub Pages workflow (for the copy on GitHub) does not run on the server. By hand, with the ssh key `~/.ssh/MyGitea`: `./deploy-shanaty.sh`.