My personal portfolio and engineering notebook at https://kunal26das.github.io.
The website is plain HTML, CSS and JavaScript. It has no framework, package installation, Kotlin compiler, Gradle build or application server. The homepage and articles remain readable without JavaScript; small scripts handle themes, navigation, section highlighting and reading tools.
site/ Website source, published at the domain root
index.html Homepage, project directory and contact details
home.css, home.js Homepage styles and interactions
assets/ Fonts, font license and project screenshot
blog/ Blog index, shared styles/scripts and article pages
multidex/ Multidex landing page
touche/ Touché product page, history guide and brand assets
bounty/ Bounty product page, policies, support and deletion information
feed.xml, sitemap.xml RSS and search discovery
.well-known/ Android Digital Asset Links
app-ads.txt, ads.txt Publisher verification
projects/
2048/ Adapted 2048 game, browser assets and game-rule tests
games/ Tetris, chess, Flow Free, Tic-Tac-Toe and game collection
resume/ Résumé source, export tools and generated index.html
involute/ Involute Explorer and original calculator files
scripts/
build.py Assemble dist/ without compiling the website
check.py Validate the assembled site
generate_bounty.py Render Bounty pages and synchronize its sitemap entries
content/bounty/ Approved notice snapshot/provenance and separate product copy
doom-dist/ Prebuilt DOOM, updated by its own repository's CI
Python 3 is the only requirement to build and preview:
python3 scripts/build.py
python3 scripts/check.py
python3 -m http.server 8080 --directory distOpen http://localhost:8080. After editing files in site/, run the build again and reload
the page. For quick work on the portfolio alone, serve site/ directly. /resume/, /involute/,
/2048/, /games/, /doom/ and legacy asset aliases are included in the assembled dist/ preview.
The /startup/ and /yify/ project sites are deployed independently;
their root-relative links resolve on the live GitHub Pages domain, not this local server.
python3 scripts/build.py
python3 scripts/check.py --check-js
node --test projects/2048/tests/*.test.cjs
node --test projects/games/tests/*.test.cjsPython checks the assembled pages, local links and anchors, assets, discovery files and
required deployment files. Node checks JavaScript syntax and runs the project regression
tests; it is not a build or runtime dependency for the website. There are no npm packages to
install. Project-specific checks and editing commands are documented in
projects/resume/README.md and
projects/involute/README.md, plus
projects/2048/README.md and
projects/games/README.md.
Pull requests targeting master run these checks. A push to master, or a manual run of
.github/workflows/deploy.yml, also publishes dist/ to GitHub Pages. Only the deployment job
has Pages and identity-token write permissions. The artifact includes hidden verification
files and only the website output, never repository configuration or local caches.
The résumé and Involute now share this deployment. The build publishes the résumé's generated
index.html at /resume/ and an explicit list of Involute web files at /involute/. Their
source tools, tests, original calculator artifacts and project configuration stay out of the
published output. Both original repositories and their Git histories were imported under
projects/; use normal commits in this repository for future changes.
The adapted 2048 game is published at /2048/ from projects/2048/. Its HTML, CSS,
JavaScript and original MIT license are explicitly included in the build; tests and
authoring documentation stay out of the published output.
The Games collection at /games/ adds browser adaptations of Tetris, chess puzzles,
Flow Free and Tic-Tac-Toe from kunal26das/game-algorithms, retaining its Apache-2.0
license and contributor notices. The original repository remains independent. Its
executables and object files are not imported into the website. Games are linked from
site footers, outside the main navigation and the homepage's project selection.
doom-dist/ is copied unchanged to /doom/. It is produced by kunal26das/doom and can still
use Kotlin independently; do not edit its generated files in this repository.
- Articles: add
site/blog/<slug>/index.html, then update the blog index, homepage article list,feed.xmlandsitemap.xml. - Projects and profile: edit
site/index.html. There is no second Kotlin copy to maintain. The homepage is written for hiring managers: positioning and proof points, what I do, experience, selected projects, writing, about and contact. Take every figure fromprojects/resume/src/resume.htmland follow the résumé's default view (Wish stays hidden). Keep the legacy#work,#codeand#journeyanchors, which older links and other pages use. - Résumé: edit
projects/resume/src/, then runpython3 projects/resume/src/build.pyto regenerateprojects/resume/index.htmlbefore building the combined site. - Involute: edit the web files in
projects/involute/; retain the legacyexplorer.htmlredirect and run its geometry checks before publishing. - 2048: edit
projects/2048/and run its Node game-rule tests before publishing. Preserve the original game's attribution and MIT license. - Game collection: edit
projects/games/and run its rule/solver tests. Keep the collection, footer link and sitemap current; preserve Apache notices. - Design: shared typography, colors, header and theme behavior live in
site/blog/blog.cssandsite/blog/blog.js; homepage-specific styles and interactions live inhome.cssandhome.js. Preserve keyboard access, mobile layouts and reduced-motion support.
site/touche/ publishes Touché’s product page at /touche/ and its practical
notification-history guide at /touche/notification-history/. They share the portfolio’s
theme tokens, local fonts and theme preference. Product-specific layout and brand assets
stay under /touche/; the homepage only links to the product page.
The pages link directly to the existing Google Play app. Touché’s privacy, purchase terms,
support and review-media URLs remain on https://touche-84483.web.app; this move does not
change app permissions, billing or those documents. Keep product claims aligned with the
published app version and update both canonical URLs and the root sitemap when adding pages.
/bounty/ introduces the Android shared-expense app and links to its public Google Play
listing. It describes the free core tools, optional Pro, and the current pause on Cloud
sharing. The homepage project directory links to it. Product copy lives separately in
content/bounty/marketing.json; it does not replace the approved policies.
The other five routes contain the approved privacy, terms, subscription, support and
account-deletion notices. Their canonical JSON is maintained by the Bounty application
project; an exact snapshot and its source revision/SHA-256 are checked in under
content/bounty/. This repository builds independently of that checkout. The generator
retains the approved headings and paragraphs, with shared site navigation and metadata
around them.
To explicitly update the snapshot after a coordinated canonical-copy review:
python3 scripts/generate_bounty.py \
--import-json /path/to/bounty/legal/content.json \
--source-revision FULL_BOUNTY_COMMIT_SHA \
--snapshot-date YYYY-MM-DD
python3 scripts/generate_bounty.py --check
python3 scripts/build.py
python3 scripts/check.py --check-jsUse the full commit containing those exact canonical bytes. The import copies bytes
without reformatting, records their SHA-256 and renders all five documents plus the product page.
To regenerate without updating canonical content, run python3 scripts/generate_bounty.py.
The normal site build checks generated-page parity, provenance and Bounty sitemap state before copying files.
Edit the generator or supplemental CSS rather than hand-editing generated HTML.
The six final routes have unique canonical, Open Graph and Twitter metadata. Structured data describes the app and each page without invented ratings, reviews or prices. The generator maintains only the Bounty sitemap entries: the product page uses its marketing update date, and the notices use their canonical content review date.
isDraft: true keeps visible draft notices and noindex, follow on all six pages and
removes their entries from the search sitemap. Publishing a draft preview
does not approve final legal terms, attest store declarations, enable cloud cleanup,
verify a monitored support process or promise account deletion. Email links only open
the visitor's email app. There are no tracking scripts, external fonts or request forms
in this area. It reuses the portfolio's local theme preference and shared reading tools.
Page URLs, article anchors and query links remain valid. Old ?view=interactive and
?view=html links now show the current portfolio. The former Compose interface was removed;
its source remains in Git history before this migration.
The consolidated résumé retains /resume/ and its layout, theme and filtering query links.
Involute retains /involute/ and the /involute/explorer.html redirect.
The build preserves the previous Lora semibold font and Yify screenshot addresses under
/composeResources/io.github.kunal26das.resources/ for older cached pages. New pages use
/assets/ URLs. These compatibility files do not load a Compose runtime.
Lora is bundled under the SIL Open Font License in site/assets/fonts/OFL-Lora.txt.
The Yify preview is an optimized copy of the public app screenshot.
The homepage bubble-sort sketch is an illustrative JavaScript demo, not an embedded AlgoScope instance.
2048 is adapted from Gabriele Cirulli's original game,
with its MIT license retained in projects/2048/LICENSE.txt.