Skip to content

About

Bilingual portfolio of Wiktor Sielaszuk — art, design, systems, sound and moving image.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Wiktor Sielaszuk — Portfolio

Source for wik-wav.github.io: a static, trilingual (PL/EN/ZH) portfolio generated from JSON content and deployed to GitHub Pages.

15 routes, 11 project views, 66 works — 59 of them in the all-work gallery.

Po polsku. Strona portfolio Wiktora Sielaszuka publikowana przez GitHub Pages. Witryna jest trójjęzyczna: polski, angielski i chiński (uproszczony); każda trasa działa pod jednym adresem, a języki przełącza przełącznik w nagłówku. Treść jest oddzielona od kodu: źródłem prawdy są pliki w content/, a HTML tras, dane JS, metadane SEO, mapa witryny i manifest tras są generowane. Do edycji służy Portfolio Studio (npm run studio); publikacja odbywa się przez commit i push na main, a następnie przez GitHub Actions. Dalsza dokumentacja jest po angielsku.

Requirements

  • Node.js 22 or newer.
  • ImageMagick 7, as magick on PATH or pointed at by PORTFOLIO_MAGICK. The media pipeline and npm test need it.

Getting started

git clone https://github.com/wik-wav/wik-wav.github.io.git
cd wik-wav.github.io
npm ci
npm run studio

npm run studio starts two servers, both on loopback:

URL What
http://127.0.0.1:4310 Portfolio Studio editor
http://127.0.0.1:4177 Vite preview of the generated site

Override the ports with PORTFOLIO_STUDIO_PORT and PORTFOLIO_PREVIEW_PORT.

Commands

Command Does
npm run studio Editor plus live preview
npm run dev Regenerate, then start the preview only
npm run generate Rewrite all generated files
npm run generate:check Fail if generated files are stale
npm run validate:content Strict publish-time validation
npm run media:dimensions Rewrite assets/js/media-dimensions.js
npm test Validation, drift check, dimensions, build, unit tests
npm run build Regenerate, then emit dist/
npm run preview Serve the built dist/

npm run migrate:content is the one-off import from the pre-Studio assets/js/data.js format; it is not part of normal work.

Layout

content/    site.json, projects/, collections/, works/, updates/ — source of truth
studio/     local editor: server and browser UI
scripts/    generator, validator, media pipeline
assets/     css/, fonts/, media/, js/ (data.js and site-data.js are generated)
public/     passthrough: favicons, robots.txt, site.webmanifest, sitemap.xml
tests/      node:test suites
generated/  site-manifest.json

Generated by npm run generate; do not edit by hand:

  • every route index.html
  • assets/js/data.js and assets/js/site-data.js
  • seo-metadata.ts
  • generated/site-manifest.json
  • public/sitemap.xml

npm run generate:check fails when any of these drift from content/.

Content model

content/ is authoritative. A work carries trilingual copy (titlePL/titleEN/titleZH, summary, alt, caption), project, medium, year, types, tags, and optional cover, hero, and thumbnail media.

Every localized value is a …PL/…EN/…ZH sibling triple. Polish and English are required; Chinese is optional and falls back to English when absent, so a record created in Studio still renders before its Chinese copy exists. Studio itself edits Polish and English only — Chinese lives in the JSON and can be filled in by hand.

Fields that change behaviour:

  • collections — puts a work in a collection without duplicating the record.
  • galleryVisible / detailOnly — keep a work out of the all-work gallery while it stays in its project narrative.
  • projectPageVisible: false — hides a work from its project page only.
  • projectGroup — merges consecutive works into one semantic block without changing gallery presence.
  • detailMediaSize — compact, standard, large, or full; a work-level value overrides the project default.
  • disclosure — ai-generated or ai-elements, see Disclosure.

Sequence images open a shared viewer with zoom, pan, and an optional details panel; video stays a responsive 16:9 embed.

Routes

15 routes: 4 top-level pages and 11 project views. The 8 projects and 3 collections share one route type.

  • index.html — profile
  • portfolio/index.html — filterable gallery
  • projects/index.html — project index
  • activity/index.html — activity log
  • projects/latentne/index.html
  • projects/para-analog-on/index.html
  • projects/gaijin-no-mittsu-no-kuusou/index.html
  • projects/lem/index.html
  • projects/lozenge-t/index.html
  • projects/book-cover/index.html
  • projects/windows-zine/index.html
  • projects/cover-art/index.html
  • projects/small-design-projects/index.html
  • projects/character-art/index.html
  • projects/dissonance-perspective/index.html

portfolio/ and projects/ accept size, per, and page, and projects also accepts view=visual|list. A valid query string wins over the stored per-route preference. Explicit page navigation pushes history, while filter, size, and per-page changes replace the current entry. The gallery preserves repeated filter parameters, and collection=<id> narrows it to one collection.

Portfolio Studio

The editor writes content/ and never touches Git — no commit, no push.

It handles:

  • creating, duplicating, reordering, and archiving projects and works, by drag, buttons, or an explicit position
  • activity records built from ordered text, image, audio/video, and link blocks
  • PL/EN copy, captions, alt text, tags, medium, year, SEO, and sequence order
  • independent cover, hero, and thumbnail media, with cover/contain fit, focal point, page size, and a light or dark background for transparent works
  • image import: the original goes to the masters store, the repository gets an optimised WebP
  • structured YouTube, Vimeo, SoundCloud, and Bandcamp embeds only, with audio players in compact, standard, or expanded size

Saving a record validates the whole content graph, writes only the files that changed, and refreshes the preview. Drafts stay out of the public build without blocking ready content.

Archiving precedes deletion. An archived work keeps its JSON and its permanently reserved URL, and source media is never deleted; the JSON can be removed permanently by typing its exact ID. Build for publishing runs the production build and reports Build ready · Git unchanged.

Media

Site images are WebP derivatives; source originals are not committed.

The recipe: auto-orient, sRGB, long edge capped at 2400 px without upscaling, metadata stripped, WebP quality 82 / method 6, transparency preserved.

Exceptions:

  • assets/media/lem/ caps at 2000 px, and its three-form hero and thumbnail composites use quality 88.
  • assets/media/book-cover/ keeps the source dimensions.
  • The bachelor film is an approved YouTube embed on youtube-nocookie.com; no video files are committed.

npm run media:dimensions rebuilds assets/js/media-dimensions.js from the images on disk. Run it after adding or replacing media and commit the result — an image without recorded dimensions is an error.

Disclosure

disclosure belongs to a media asset and is rendered centrally by makeMedia(). ai-generated marks a generated visualisation; ai-elements marks work containing the named generated elements. It applies to the book mockup, the zine mockups, and the zine pages with ASCII art — not to the voice-model icon, character art, or video stills. This is a provenance convention for this portfolio, not legal certification.

SEO and GitHub Pages

The canonical origin is https://wik-wav.github.io, fixed in content/site.json and read-only in Studio. Metadata for all 15 routes is generated into seo-metadata.ts at build time.

Every production route emits one absolute canonical URL, a matching og:url, rel="author", rel="me" links to the configured profiles, and a JSON-LD graph joining Person, WebSite, and the page. Canonicals use a trailing slash and never carry filter, pagination, or viewer parameters. public/sitemap.xml comes from the same route manifest and is regression-tested against those canonicals.

The document is Polish on first paint; the PL/EN/ZH switch updates title, description, and the supported metadata. All three languages share one URL, so Chinese and English are client-side only; indexable per-language routes (/en/, /zh/) do not exist yet.

These signals make the original unambiguous to search engines. They do not prevent anyone from copying the public HTML or images.

Deployment

.github/workflows/deploy.yml runs on every push to main and on manual dispatch: install ImageMagick, npm ci, npm test, then upload dist/ and deploy to GitHub Pages. A local build publishes nothing.

Notes

  • public/og-social.png is an AI-generated portfolio preview visualisation and keeps its visible disclosure.
  • studio-preview/ holds draft previews, is gitignored, and is never published.
  • Chinese copy is set in 寒蝉锦书宋 (Chill Jinshu Song), a rounded Song-style face based on Source Han Serif. It ships as a subset covering only the glyphs this site uses (190 KB regular, 199 KB bold) in assets/fonts/, under the SIL Open Font License 1.1 (assets/fonts/ChillJinshuSong-OFL.txt). It leads the font stacks only under html[lang="zh"], so Polish and English pages never download it. Glyphs introduced by later Chinese copy fall back to the system font until the subset is rebuilt.
  • The header language control is a native <select>, so it needs no JavaScript to open and stays usable on touch devices.

About

Bilingual portfolio of Wiktor Sielaszuk — art, design, systems, sound and moving image.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages