[{"data":1,"prerenderedAt":643},["ShallowReactive",2],{"api:\u002Fapi\u002Fconfig:en":3,"api:\u002Fapi\u002Fstats:":8,"api:\u002Fapi\u002Fstack:en":140,"api:\u002Fapi\u002Fprojects:en":213},{"email":4,"lang":5,"name":6,"role":7},"hello@ewsirdev.example","en","Ewsirdev","Web developer: websites, landing pages and Go services",{"generated_at":9,"tests_method":10,"note":11,"totals":12,"projects":22},"2026-10-22","go test -list","Lines are non-blank lines. Endpoints are HandleFunc\u002FHandle route patterns (without \u002Fdemo\u002F*). Tests are top-level Test* functions.",{"projects":13,"go_projects":14,"go_lines":15,"go_test_lines":16,"tests":17,"endpoints":18,"html":19,"css":20,"js":21},17,13,26503,12027,418,230,1973,3525,4815,[23,33,42,51,60,67,76,84,90,94,98,102,106,112,120,127,133],{"slug":24,"kind":25,"go_lines":26,"go_test_lines":27,"tests":28,"endpoints":29,"html":30,"css":31,"js":32},"api-gateway","go",2334,1179,48,11,115,139,163,{"slug":34,"kind":25,"go_lines":35,"go_test_lines":36,"tests":37,"endpoints":38,"html":39,"css":40,"js":41},"auth-service",2826,1393,50,35,23,166,500,{"slug":43,"kind":25,"go_lines":44,"go_test_lines":45,"tests":46,"endpoints":47,"html":48,"css":49,"js":50},"booking-slots",891,338,12,18,146,123,309,{"slug":52,"kind":25,"go_lines":53,"go_test_lines":54,"tests":55,"endpoints":56,"html":57,"css":58,"js":59},"finance-tracker",3741,1371,30,45,24,1148,72,{"slug":61,"kind":25,"go_lines":62,"go_test_lines":63,"tests":64,"endpoints":65,"html":66,"css":66,"js":66},"gitpulse",2133,735,32,3,0,{"slug":68,"kind":25,"go_lines":69,"go_test_lines":70,"tests":71,"endpoints":72,"html":73,"css":74,"js":75},"job-queue",2161,833,25,19,138,188,331,{"slug":77,"kind":25,"go_lines":78,"go_test_lines":79,"tests":80,"endpoints":47,"html":81,"css":82,"js":83},"kanban-tasks",871,272,7,102,156,328,{"slug":85,"kind":86,"go_lines":66,"go_test_lines":66,"tests":66,"endpoints":66,"html":87,"css":88,"js":89},"landing-3d","static",201,162,377,{"slug":91,"kind":86,"go_lines":66,"go_test_lines":66,"tests":66,"endpoints":66,"html":48,"css":92,"js":93},"landing-event",122,59,{"slug":95,"kind":86,"go_lines":66,"go_test_lines":66,"tests":66,"endpoints":66,"html":96,"css":97,"js":93},"landing-saas",172,136,{"slug":99,"kind":86,"go_lines":66,"go_test_lines":66,"tests":66,"endpoints":66,"html":100,"css":101,"js":93},"landing-studio",187,109,{"slug":103,"kind":25,"go_lines":44,"go_test_lines":83,"tests":46,"endpoints":29,"html":104,"css":88,"js":105},"link-shortener",119,317,{"slug":107,"kind":25,"go_lines":108,"go_test_lines":78,"tests":64,"endpoints":72,"html":109,"css":110,"js":111},"notes-search",2027,174,192,517,{"slug":113,"kind":25,"go_lines":114,"go_test_lines":115,"tests":116,"endpoints":117,"html":118,"css":110,"js":119},"pixel-wall",2715,1910,77,16,106,625,{"slug":121,"kind":25,"go_lines":122,"go_test_lines":123,"tests":124,"endpoints":14,"html":125,"css":109,"js":126},"raft-kv",2646,895,27,91,213,{"slug":128,"kind":25,"go_lines":129,"go_test_lines":130,"tests":28,"endpoints":80,"html":131,"css":132,"js":111},"realtime-rooms",1822,1313,103,184,{"slug":134,"kind":25,"go_lines":135,"go_test_lines":136,"tests":47,"endpoints":137,"html":138,"css":96,"js":139},"uptime-monitor",1445,589,15,126,369,{"groups":141,"lang":5,"not":190,"stats":193},[142,157,166,175],{"name":143,"items":144},"Language and server",[145,148,151,154],{"name":146,"note":147},"Go","standard library: net\u002Fhttp, embed, log\u002Fslog, context",{"name":149,"note":150},"REST \u002F JSON","APIs behind a Bearer token or a session, errors as {\"error\": ...}",{"name":152,"note":153},"SSE","live dashboards in the monitor and the job queue",{"name":155,"note":156},"WebSocket","own RFC 6455 implementation in realtime-rooms",{"name":158,"items":159},"Data",[160,163],{"name":161,"note":162},"SQLite (modernc.org\u002Fsqlite)","pure Go, no CGO, WAL mode",{"name":164,"note":165},"SQL (no ORM)","atomic UPDATE … RETURNING, partial UNIQUE indexes, transactions",{"name":167,"items":168},"Front end",[169,172],{"name":170,"note":171},"HTML, CSS, vanilla JS","no frameworks in the learning projects, embedded in the binary",{"name":173,"note":174},"Canvas","the shared board in realtime-rooms",{"name":176,"items":177},"Quality and delivery",[178,181,184,187],{"name":179,"note":180},"go vet, gofmt, go test","checked in CI; go test -race runs in CI",{"name":182,"note":183},"GitHub Actions","CI in the project repositories",{"name":185,"note":186},"Docker","multi-stage images for the projects",{"name":188,"note":189},"Prometheus","job queue metrics on \u002Fmetrics in the text format",[191,192],"I do not claim experience beyond what is shown here: front-end frameworks, ORMs, Kubernetes and cloud platforms are not part of it.","No distributed systems: every service is designed for a single process and a single SQLite file.",{"generated_at":9,"tests_method":10,"note":11,"totals":194,"projects":195},{"projects":13,"go_projects":14,"go_lines":15,"go_test_lines":16,"tests":17,"endpoints":18,"html":19,"css":20,"js":21},[196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212],{"slug":24,"kind":25,"go_lines":26,"go_test_lines":27,"tests":28,"endpoints":29,"html":30,"css":31,"js":32},{"slug":34,"kind":25,"go_lines":35,"go_test_lines":36,"tests":37,"endpoints":38,"html":39,"css":40,"js":41},{"slug":43,"kind":25,"go_lines":44,"go_test_lines":45,"tests":46,"endpoints":47,"html":48,"css":49,"js":50},{"slug":52,"kind":25,"go_lines":53,"go_test_lines":54,"tests":55,"endpoints":56,"html":57,"css":58,"js":59},{"slug":61,"kind":25,"go_lines":62,"go_test_lines":63,"tests":64,"endpoints":65,"html":66,"css":66,"js":66},{"slug":68,"kind":25,"go_lines":69,"go_test_lines":70,"tests":71,"endpoints":72,"html":73,"css":74,"js":75},{"slug":77,"kind":25,"go_lines":78,"go_test_lines":79,"tests":80,"endpoints":47,"html":81,"css":82,"js":83},{"slug":85,"kind":86,"go_lines":66,"go_test_lines":66,"tests":66,"endpoints":66,"html":87,"css":88,"js":89},{"slug":91,"kind":86,"go_lines":66,"go_test_lines":66,"tests":66,"endpoints":66,"html":48,"css":92,"js":93},{"slug":95,"kind":86,"go_lines":66,"go_test_lines":66,"tests":66,"endpoints":66,"html":96,"css":97,"js":93},{"slug":99,"kind":86,"go_lines":66,"go_test_lines":66,"tests":66,"endpoints":66,"html":100,"css":101,"js":93},{"slug":103,"kind":25,"go_lines":44,"go_test_lines":83,"tests":46,"endpoints":29,"html":104,"css":88,"js":105},{"slug":107,"kind":25,"go_lines":108,"go_test_lines":78,"tests":64,"endpoints":72,"html":109,"css":110,"js":111},{"slug":113,"kind":25,"go_lines":114,"go_test_lines":115,"tests":116,"endpoints":117,"html":118,"css":110,"js":119},{"slug":121,"kind":25,"go_lines":122,"go_test_lines":123,"tests":124,"endpoints":14,"html":125,"css":109,"js":126},{"slug":128,"kind":25,"go_lines":129,"go_test_lines":130,"tests":28,"endpoints":80,"html":131,"css":132,"js":111},{"slug":134,"kind":25,"go_lines":135,"go_test_lines":136,"tests":47,"endpoints":137,"html":138,"css":96,"js":139},[214,236,252,267,287,303,318,334,350,366,389,410,432,456,480,504,523,545,569,594,609,625],{"slug":77,"title":215,"type":216,"stack":217,"description":219,"highlights":220,"run":225,"hue":226,"og":227,"shots":228},"Amber: kanban board","backend",[146,218,185],"SQLite","A multi-user kanban board: sign-up, boards, columns, drag-and-drop cards. Go + SQLite without CGO, the front end is embedded in the binary.",[221,222,223,224],"PBKDF2 and sessions in an HttpOnly cookie","Per-user data isolation","API tests","Multi-stage Docker","cd kanban-tasks && go run .",344,"\u002Fog\u002Fen\u002Fkanban-tasks.jpg",{"desktop":229,"desktop_sm":230,"mobile":231,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fkanban-tasks-desktop.webp","\u002Fshots\u002Fkanban-tasks-desktop-sm.webp","\u002Fshots\u002Fkanban-tasks-mobile.webp",1280,800,390,844,{"slug":103,"title":237,"type":216,"stack":238,"description":239,"highlights":240,"run":245,"hue":246,"og":247,"shots":248},"Short: link shortener",[146,218,185],"Link shortening with aliases and expiry, click statistics by day, browser and device, a token-protected dashboard. IP addresses are not stored.",[241,242,243,244],"Redirect and click tracking","Rate limiting","Private statistics (salted hash)","Tests and Docker","cd link-shortener && set SEED_DEMO=1&& go run .\u002Fcmd\u002Fserver",111,"\u002Fog\u002Fen\u002Flink-shortener.jpg",{"desktop":249,"desktop_sm":250,"mobile":251,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Flink-shortener-desktop.webp","\u002Fshots\u002Flink-shortener-desktop-sm.webp","\u002Fshots\u002Flink-shortener-mobile.webp",{"slug":43,"title":253,"type":216,"stack":254,"description":255,"highlights":256,"run":260,"hue":261,"og":262,"shots":263},"Appointment booking",[146,218,185],"Online booking: free slots computed from service duration and working hours, double-booking protection, an admin panel. A fictional studio, demo.",[257,258,259,244],"Free slot calculation","No double bookings","Admin for services and schedule","cd booking-slots && go run .",65,"\u002Fog\u002Fen\u002Fbooking-slots.jpg",{"desktop":264,"desktop_sm":265,"mobile":266,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fbooking-slots-desktop.webp","\u002Fshots\u002Fbooking-slots-desktop-sm.webp","\u002Fshots\u002Fbooking-slots-mobile.webp",{"slug":99,"title":268,"type":269,"stack":270,"description":274,"highlights":275,"run":280,"hue":281,"og":282,"shots":283},"Halftone: lighting studio","landing",[271,272,273],"HTML","CSS","JS","A landing page for a fictional interior lighting studio: warm palette, serif type, SVG illustration, FAQ and a demo form. Responsive, no external images.",[276,277,278,279],"Responsive 390-1280","SVG instead of images","Accessible FAQ and form","An honest demo form","cd landing-studio && python -m http.server 8091",212,"\u002Fog\u002Fen\u002Flanding-studio.jpg",{"desktop":284,"desktop_sm":285,"mobile":286,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Flanding-studio-desktop.webp","\u002Fshots\u002Flanding-studio-desktop-sm.webp","\u002Fshots\u002Flanding-studio-mobile.webp",{"slug":95,"title":288,"type":269,"stack":289,"description":290,"highlights":291,"run":296,"hue":297,"og":298,"shots":299},"Kill Switch: subscription tracker",[271,272,273],"A landing page for a fictional SaaS product: dark gradient hero, a UI mock-up in CSS, pricing, FAQ, a demo form. All prices and names are made up.",[292,293,294,295],"UI mock-up in CSS","Pricing grid","Responsive","Demo form that sends no data","cd landing-saas && python -m http.server 8092",182,"\u002Fog\u002Fen\u002Flanding-saas.jpg",{"desktop":300,"desktop_sm":301,"mobile":302,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Flanding-saas-desktop.webp","\u002Fshots\u002Flanding-saas-desktop-sm.webp","\u002Fshots\u002Flanding-saas-mobile.webp",{"slug":91,"title":304,"type":269,"stack":305,"description":306,"highlights":307,"run":311,"hue":312,"og":313,"shots":314},"Small Scale: conference",[271,272,273],"A landing page for a fictional one-day conference: poster typography, schedule, placeholder speakers, terms, a demo registration form.",[308,309,294,310],"Day schedule","Poster typography","No invented speaker names","cd landing-event && python -m http.server 8093",124,"\u002Fog\u002Fen\u002Flanding-event.jpg",{"desktop":315,"desktop_sm":316,"mobile":317,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Flanding-event-desktop.webp","\u002Fshots\u002Flanding-event-desktop-sm.webp","\u002Fshots\u002Flanding-event-mobile.webp",{"slug":134,"title":319,"type":216,"stack":320,"description":322,"highlights":323,"run":327,"hue":328,"og":329,"shots":330},"Pulse: uptime monitor",[146,218,152,321,185],"REST API","An uptime monitor: scheduled HTTP and TCP checks, uptime, p50\u002Fp95, an incident detector, a live SSE dashboard and a public status page. Go + SQLite without CGO.",[324,325,326,244],"A worker goroutine per check","Incidents after a series of failures","SSE dashboard and a public \u002Fstatus","cd uptime-monitor && set SEED_DEMO=1&& go run .\u002Fcmd\u002Fserver",101,"\u002Fog\u002Fen\u002Fuptime-monitor.jpg",{"desktop":331,"desktop_sm":332,"mobile":333,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fuptime-monitor-desktop.webp","\u002Fshots\u002Fuptime-monitor-desktop-sm.webp","\u002Fshots\u002Fuptime-monitor-mobile.webp",{"slug":68,"title":335,"type":216,"stack":336,"description":337,"highlights":338,"run":343,"hue":344,"og":345,"shots":346},"Conveyor: job queue",[146,218,321,152,188,185],"A background job queue: priorities, delayed and cron jobs, retries with backoff and jitter, dead-letter, idempotency keys, leases with fencing, Prometheus metrics.",[339,340,341,342],"At-least-once with lease and fencing","Retries with backoff and jitter + dead-letter","Custom cron parser","Prometheus metrics and graceful shutdown","cd job-queue && set API_TOKEN=demo&& set SEED_DEMO=1&& go run .\u002Fcmd\u002Fserver",249,"\u002Fog\u002Fen\u002Fjob-queue.jpg",{"desktop":347,"desktop_sm":348,"mobile":349,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fjob-queue-desktop.webp","\u002Fshots\u002Fjob-queue-desktop-sm.webp","\u002Fshots\u002Fjob-queue-mobile.webp",{"slug":128,"title":351,"type":216,"stack":352,"description":353,"highlights":354,"run":359,"hue":360,"og":361,"shots":362},"Rooms: realtime chat and board",[146,155,218,173,185],"Realtime rooms: chat with SQLite history, an online list, a typing indicator, a shared board with strokes and cursors, anonymous nicknames. WebSocket (RFC 6455) written on the stdlib.",[355,356,357,358],"Own WebSocket layer (RFC 6455) on the stdlib","Slow-client disconnects and rate limits","Graceful shutdown with close code 1001","Load test: 360 connections in 6 rooms","cd realtime-rooms && set SEED_DEMO=1&& go run .\u002Fcmd\u002Fserver",46,"\u002Fog\u002Fen\u002Frealtime-rooms.jpg",{"desktop":363,"desktop_sm":364,"mobile":365,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Frealtime-rooms-desktop.webp","\u002Fshots\u002Frealtime-rooms-desktop-sm.webp","\u002Fshots\u002Frealtime-rooms-mobile.webp",{"slug":24,"title":367,"type":216,"stack":368,"description":376,"highlights":377,"run":382,"hue":383,"og":384,"shots":385},"Sluice: API gateway",[146,369,370,371,372,152,188,373,374,375,185,182],"stdlib only","Reverse proxy","Circuit breaker","Token bucket","slog","Vanilla JS","embed","An API gateway on the pure stdlib: host\u002Fprefix routes from a JSON config with hot reload that keeps connections alive, round-robin and least-conn balancing, health checks, a per-node circuit breaker, retries of idempotent requests, rate limiting, hashed API keys, Prometheus metrics and a live SSE dashboard.",[378,379,380,381],"Zero dependencies: stdlib only","Config hot reload without dropping connections","Per-node circuit breaker and retries of idempotent requests","Load test: 4000 requests, 40 clients (a demo run)","cd api-gateway && set SEED_DEMO=1&& go run .\u002Fcmd\u002Fgateway",200,"\u002Fog\u002Fen\u002Fapi-gateway.jpg",{"desktop":386,"desktop_sm":387,"mobile":388,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fapi-gateway-desktop.webp","\u002Fshots\u002Fapi-gateway-desktop-sm.webp","\u002Fshots\u002Fapi-gateway-mobile.webp",{"slug":107,"title":390,"type":216,"stack":391,"description":397,"highlights":398,"run":403,"hue":404,"og":405,"shots":406},"Card Index: notes with search",[146,218,392,393,394,321,395,396,374,375,185,182],"FTS5","bm25","modernc.org\u002Fsqlite (no CGO)","Markdown (custom safe renderer)","SVG force-layout","A Markdown notes base on Go and SQLite: [[wiki]] links with backlinks and a link graph, FTS5 full-text search (bm25, highlighting, simplified Russian morphology), version history with its own diff, autosave with conflict resolution, .md export and import.",[399,400,401,402],"FTS5 search with bm25 and highlighting","Wiki links, backlinks and a link graph","Version history with its own diff","A custom safe Markdown renderer with an XSS test","cd notes-search && set SEED_DEMO=1&& go run .\u002Fcmd\u002Fserver",160,"\u002Fog\u002Fen\u002Fnotes-search.jpg",{"desktop":407,"desktop_sm":408,"mobile":409,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fnotes-search-desktop.webp","\u002Fshots\u002Fnotes-search-desktop-sm.webp","\u002Fshots\u002Fnotes-search-mobile.webp",{"slug":85,"title":411,"type":269,"stack":412,"description":419,"highlights":420,"run":425,"hue":426,"og":427,"shots":428},"OKSO T1: 3D landing page",[413,414,374,415,416,417,418,182],"HTML5","CSS3","WebGL2","GLSL ES 3.00","Raymarching\u002FSDF","Scroll choreography","A landing page for a fictional air sensor (demo): the object is drawn by one fragment shader on plain WebGL2 with no libraries, four SDF shapes morph on scroll, with an SVG fallback, reduced-motion support and a pause when off screen.",[421,422,423,424],"One fragment shader, WebGL2 without libraries","Four SDF shapes morphing on scroll","SVG fallback and prefers-reduced-motion","Rendering pauses off screen","cd landing-3d && python -m http.server 8094",90,"\u002Fog\u002Fen\u002Flanding-3d.jpg",{"desktop":429,"desktop_sm":430,"mobile":431,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Flanding-3d-desktop.webp","\u002Fshots\u002Flanding-3d-desktop-sm.webp","\u002Fshots\u002Flanding-3d-mobile.webp",{"slug":121,"title":433,"type":216,"stack":434,"description":443,"highlights":444,"run":449,"hue":450,"og":451,"shots":452},"Raft KV: a key-value store on Raft",[146,435,436,437,369,438,152,439,440,441,442,374,185,182],"Raft","Distributed systems","Consensus","HTTP\u002FJSON","WAL + fsync","Snapshots","Linearizability","Deterministic simulation testing","A from-scratch teaching implementation of Raft on the pure stdlib: leader election, log replication, quorum commit, a log and term\u002Fvote on disk with fsync, snapshots with compaction, linearizable reads (read-index) and follower-to-leader redirects. It is tested with a deterministic network and time simulator that checks linearizability; the dashboard can kill the leader and cut the network (demo).",[445,446,447,448],"Raft from scratch on the stdlib, no raft libraries","A deterministic network and time simulator + a linearizability check","Log and term\u002Fvote on disk with fsync, snapshots and compaction","A dashboard to kill the leader and cut the network (demo)","cd raft-kv && set SEED_DEMO=1&& go run .\u002Fcmd\u002Fraft-kv",290,"\u002Fog\u002Fen\u002Fraft-kv.jpg",{"desktop":453,"desktop_sm":454,"mobile":455,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fraft-kv-desktop.webp","\u002Fshots\u002Fraft-kv-desktop-sm.webp","\u002Fshots\u002Fraft-kv-mobile.webp",{"slug":34,"title":457,"type":216,"stack":458,"description":467,"highlights":468,"run":473,"hue":474,"og":475,"shots":476},"Keyring: an authentication service",[146,459,218,394,460,461,462,463,464,465,466,374,375,185,182],"stdlib crypto","JWT EdDSA\u002FEd25519","JWKS","PBKDF2","TOTP","RBAC","REST","OpenAPI 3","An authentication and authorization service in Go: EdDSA JWTs with key rotation and JWKS, refresh tokens with rotation and theft detection, TOTP 2FA (RFC 6238) with backup codes, RBAC, lockout on brute force, password reset by a one-time token, an audit log, a device list, openapi.yaml. Not independently audited, not a production IdP.",[469,470,471,472],"EdDSA JWTs with key rotation and JWKS","Refresh tokens with rotation and reuse detection","TOTP per RFC 6238, checked against the RFC test vectors","An append-only audit log (database triggers)","cd auth-service && set SEED_DEMO=1&& go run .\u002Fcmd\u002Fserver",20,"\u002Fog\u002Fen\u002Fauth-service.jpg",{"desktop":477,"desktop_sm":478,"mobile":479,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fauth-service-desktop.webp","\u002Fshots\u002Fauth-service-desktop-sm.webp","\u002Fshots\u002Fauth-service-mobile.webp",{"slug":52,"title":481,"type":216,"stack":482,"description":491,"highlights":492,"run":497,"hue":498,"og":499,"shots":500},"Ledger: personal finance tracker",[146,218,394,321,483,484,485,486,487,488,489,185,182,462,490],"Nuxt 4","Vue 3","TypeScript","Pinia","SVG charts","vitest","ESLint","CSV import\u002Fexport","Personal finance tracking: accounts in different currencies with manual exchange rates, income, expenses and transfers, budgets, payments on a cron-like schedule, CSV import with a preview, reports. Money is stored only in integer minor units, users' data is isolated, and the charts are drawn in SVG with no library. Go + SQLite with a Nuxt 4 front end.",[493,494,495,496],"Money only in integer minor units","Multi-currency with manual exchange rates","CSV import with a preview and a dry run","Hand-made SVG charts, no library","cd finance-tracker && set SEED_DEMO=1&& go run .",140,"\u002Fog\u002Fen\u002Ffinance-tracker.jpg",{"desktop":501,"desktop_sm":502,"mobile":503,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Ffinance-tracker-desktop.webp","\u002Fshots\u002Ffinance-tracker-desktop-sm.webp","\u002Fshots\u002Ffinance-tracker-mobile.webp",{"slug":113,"title":505,"type":216,"stack":506,"description":510,"highlights":511,"run":516,"hue":517,"og":518,"shots":519},"Pixel Wall: a shared canvas",[146,369,155,507,374,375,508,509,185,182],"Canvas 2D","Binary protocol","Snapshot + journal","A shared 256x256 canvas in the spirit of r\u002Fplace: 16 colors, a cooldown per session and IP, an own WebSocket layer on the stdlib (RFC 6455) with a binary protocol (4 bits per pixel), a snapshot plus deltas, a snapshot with a journal and recovery, a timelapse, zoom and pan, a minimap, PNG export and admin tools. A side project.",[512,513,514,515],"Own WebSocket (RFC 6455) on the stdlib","A binary protocol: 4 bits per pixel","Snapshot + journal with crash recovery","A timelapse over the change journal","cd pixel-wall && set SEED_DEMO=1&& set ADMIN_TOKEN=secret&& go run .\u002Fcmd\u002Fserver",320,"\u002Fog\u002Fen\u002Fpixel-wall.jpg",{"desktop":520,"desktop_sm":521,"mobile":522,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fpixel-wall-desktop.webp","\u002Fshots\u002Fpixel-wall-desktop-sm.webp","\u002Fshots\u002Fpixel-wall-mobile.webp",{"slug":61,"title":524,"type":525,"stack":526,"description":533,"highlights":534,"run":539,"hue":80,"og":540,"shots":541},"GitPulse: git repository analytics","cli",[146,369,527,528,529,530,531,532,182,185],"CLI","git","html\u002Ftemplate","SVG","ANSI","os\u002Fexec","A Go CLI that analyzes git repositories with no external dependencies (only git is needed): stats with colors and sparklines in the terminal, report, a self-contained HTML report with an activity heatmap, churn and hot files, author contributions, bus factor per directory, code growth by language and quiet periods (light and dark themes), diff-hotspots between revisions and a local serve on 127.0.0.1. History is read as a stream through git log -z --numstat -M. A side project.",[535,536,537,538],"Go stdlib only, a single external binary: git","A git log -z --numstat -M stream with .mailmap and renames handled","A self-contained HTML report: heatmap, churn, bus factor, light and dark themes","A synthetic history of 100,000 commits is analyzed in about 5 seconds","cd gitpulse && go run .\u002Fcmd\u002Fgitpulse stats .","\u002Fog\u002Fen\u002Fgitpulse.jpg",{"desktop":542,"desktop_sm":543,"mobile":544,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fgitpulse-desktop.webp","\u002Fshots\u002Fgitpulse-desktop-sm.webp","\u002Fshots\u002Fgitpulse-mobile.webp",{"slug":546,"title":547,"type":548,"stack":549,"description":554,"highlights":555,"run":562,"hue":563,"og":564,"shots":565},"legal-multipage-site","Multi-page legal services website","site",[483,484,485,550,551,552,553,185,182],"Bootstrap 5","Zod","Vitest","Playwright","A delivered website for a legal and expert-appraisal firm built with Nuxt 4: 65 server-rendered pages, JSON-LD markup and 301 redirects from the previous site. Lead requests go through a server endpoint that checks Origin, caps body size and rate-limits clients.",[556,557,558,559,560,561],"65 SSR routes, generated sitemap.xml and robots.txt; indexing is switched on by an explicit env flag","Lead form: server endpoint with Origin check, 10 KB body cap, 3 requests per 10 minutes per IP, honeypot and optional captcha","JSON-LD: LegalService, WebSite, BreadcrumbList","Single-hop 301 redirects from legacy URLs and trailing slashes, security headers (CSP, HSTS)","CI\u002FCD: lint, typecheck, Vitest, build, Playwright; then a Docker image and server deploy","210 unit tests in 13 files and 4 e2e spec files","npm install && npm run build && node .output\u002Fserver\u002Findex.mjs",250,"\u002Fog\u002Fen\u002Flegal-multipage-site.jpg",{"desktop":566,"desktop_sm":567,"mobile":568,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Flegal-multipage-site-desktop.webp","\u002Fshots\u002Flegal-multipage-site-desktop-sm.webp","\u002Fshots\u002Flegal-multipage-site-mobile.webp",{"slug":570,"title":571,"type":572,"stack":573,"description":581,"highlights":582,"run":587,"hue":588,"og":589,"shots":590},"bad-club-booking-app","Bad Club: seat booking for a gaming coworking space","app",[484,574,486,575,576,577,578,579,580],"Vite","Vue Router","GSAP","Express","node:sqlite","JWT (httpOnly cookie)","Resend","A demo app on Vue 3, Express and SQLite: an interactive hall map with seat booking, a user account and an admin panel with a layout editor. Passwordless sign-in via a one-time e-mail code.",[583,584,585,586],"Hall map with zones (standard, quiet, VIP, dual-monitor), a type filter and seat status","Admin panel: overview, bookings, seats, computers, users and a drag-and-drop layout editor","OTP sign-in with attempt and rate limits; the admin role is bootstrapped via an env variable","Demo data is created by a seed script on first start","npm install && npm run dev",150,"\u002Fog\u002Fen\u002Fbad-club-booking-app.jpg",{"desktop":591,"desktop_sm":592,"mobile":593,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fbad-club-booking-app-desktop.webp","\u002Fshots\u002Fbad-club-booking-app-desktop-sm.webp","\u002Fshots\u002Fbad-club-booking-app-mobile.webp",{"slug":595,"title":596,"type":269,"stack":597,"description":598,"highlights":599,"run":587,"hue":603,"og":604,"shots":605},"dovod-concept","Dovod: expert-firm landing concept",[483,484,485,272,182],"A Nuxt 4 landing concept for a fictional expert-appraisal firm: service areas, a consultation form with a phone mask, a reviews carousel and a policy page. The company, reviews, figures and contacts are made up; the form sends nothing.",[600,601,602],"Form with a phone mask, validation and error hints; in the demo it states that nothing is sent","Endless reviews carousel with swipe and autoplay","Mobile action bar, responsive layout, skeleton overlay on top of server-rendered HTML",215,"\u002Fog\u002Fen\u002Fdovod-concept.jpg",{"desktop":606,"desktop_sm":607,"mobile":608,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fdovod-concept-desktop.webp","\u002Fshots\u002Fdovod-concept-desktop-sm.webp","\u002Fshots\u002Fdovod-concept-mobile.webp",{"slug":610,"title":611,"type":548,"stack":612,"description":615,"highlights":616,"run":587,"hue":64,"og":620,"shots":621},"niche-landings","Catalog of 10 niche demo landing pages",[484,613,614,182],"Vue Router 4","Vite 8","A Vue catalog of ten standalone landing pages for different small-business niches, each with its own palette, fonts and section structure. Every landing loads as a separate chunk; all content is demonstration content.",[617,618,619],"10 niches: medicine, furniture, renovation, online school, glamping, legal, auto service, beauty, cafe, fitness","Route-level code splitting, a shared SVG icon set","A \"demo content\" badge on the catalog and every landing","\u002Fog\u002Fen\u002Fniche-landings.jpg",{"desktop":622,"desktop_sm":623,"mobile":624,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fniche-landings-desktop.webp","\u002Fshots\u002Fniche-landings-desktop-sm.webp","\u002Fshots\u002Fniche-landings-mobile.webp",{"slug":626,"title":627,"type":269,"stack":628,"description":631,"highlights":632,"run":636,"hue":637,"og":638,"shots":639},"dental-concept","Kvarts: dental clinic landing concept",[271,272,629,507,630,182],"JavaScript","htmlhint","A single-page landing concept for a fictional dental clinic in the Liquid Chrome Dark style: glass cards, chrome headings and a canvas-drawn 3D tooth blob. One HTML file with no build step or dependencies.",[633,634,635],"Animated canvas blob that respects prefers-reduced-motion and viewport visibility","Booking form with a phone mask and accessible error messages","CI: htmlhint and a local links and anchors check","python -m http.server 8080",190,"\u002Fog\u002Fen\u002Fdental-concept.jpg",{"desktop":640,"desktop_sm":641,"mobile":642,"dw":232,"dh":233,"mw":234,"mh":235},"\u002Fshots\u002Fdental-concept-desktop.webp","\u002Fshots\u002Fdental-concept-desktop-sm.webp","\u002Fshots\u002Fdental-concept-mobile.webp",1792697892477]