From 4fe44f4a9ed30d07c5b4baa73d32693a46ba1aa4 Mon Sep 17 00:00:00 2001 From: bronkuu Date: Sun, 14 Jun 2026 23:16:01 +0200 Subject: [PATCH] new website --- favicon.svg | 4 +- index.html | 454 ++++++++++++++++++---------- screenshots/piekarnikgosi-hero.avif | Bin 0 -> 27936 bytes style.css | 378 ++++++++++++++++++++--- 4 files changed, 629 insertions(+), 207 deletions(-) create mode 100644 screenshots/piekarnikgosi-hero.avif diff --git a/favicon.svg b/favicon.svg index 39d4caa..defae87 100644 --- a/favicon.svg +++ b/favicon.svg @@ -1,4 +1,4 @@ - - + + JB diff --git a/index.html b/index.html index 30d3d7f..976f16d 100644 --- a/index.html +++ b/index.html @@ -1,174 +1,308 @@ - + - - - - - - Jakub Bronk | Portfolio - + + + + + + Jakub Bronk | Portfolio + - -
-

Jakub Bronk

-
- Email - GitHub - Somonino, Poland -
-
+ +
+
+

Jakub Bronk

+

+ Computer Science student @ Gdańsk University of Technology +

+
+ +
-
-

- Computer Science student at Gdańsk University of Technology with strong - foundations in algorithms, systems programming, and Linux environments. - Experienced in Go, C/C++, and C# as well as familiar with Java, Python, - Ruby, Rust, and TypeScript, through academic and personal projects, - including self-hosted infrastructure and low-level development. -

+
+

+ Computer Science student at Gdańsk University of Technology with + strong foundations in algorithms, systems programming, and Linux + environments. Experienced in Go, C/C++, and Python, as well as + familiar with Java, Ruby, Rust, and TypeScript - through + academic, personal, and professional projects including + full-stack web development, compiler design, and self-hosted + infrastructure. +

+
+ bronk.jakub@proton.me + git.bronku.xyz + Somonino, Poland +
+
-

AVAILABILITY & COMMITMENT

-

- I am looking for a long-term professional relationship rather than a - short-term placement. My intended availability is as follows: -

- -
+
+

Experience

+
+
+

Software Engineering Intern

+ +
+

+ Contributed to a full-stack web application. Worked with + Ruby on Rails, React, TypeScript, and RTK Query in a team - + delivering features, reviewing code, and participating in + the full development lifecycle. +

+
+ Ruby on Rails + React + TypeScript + RTK Query + PostgreSQL +
+
+
-
-

SELECTED PROJECTS

-
-

B+ Tree Implementation Rust

-

- A disk-friendly B+ tree implementation focusing on memory-efficient - data structures and safety. -

-
+
+

Selected Projects

+
+
+ + piekarnikgosi.pl screenshot + +
+

piekarnikgosi.pl

+

+ A multi-page business website for a local cake shop + and café, built for a real client. Features include + a categorized product catalog, photo gallery with + lightbox, café landing page, and contact information + - all server-rendered with HTMX-powered navigation + for instant page transitions. +

+
+ HTML/CSS + HTMX + Go + JavaScript +
+ +
+
-
-

- Python-to-Ruby Transpiler - Flex / Bison / C++ / Make -

-

- A compiler-front-end project focused on lexer/parser design. This - project allowed me to familiarize myself with lexer and parser design, - engineer a lexing solution for significant indentation in Python, - while effectively modeling real-world objects through class design. - Solved complex build challenges involving circular dependencies. -

-
+
+
+

Cake Order Tracker

+

+ Production-ready order management system for the + same cake shop. Single-binary Go application with + SQLite persistence, and a dynamic HTMX frontend. + Features real-time order filtering, transactional + integrity, and zero-dependency deployment. +

+
+ Go + SQLite + HTMX + SQL +
+ +
+
-
-

External Sorting Implementation C++

-

- High-performance implementation for sorting datasets exceeding RAM - capacity. Utilized min-heaps and optimized disk I/O buffers to manage - large-scale data processing efficiently. -

-
+
+
+

Python-to-Ruby Transpiler

+

+ A compiler front-end built with Flex, Bison, and + C++. Handles Python's significant indentation + through custom lexer logic, produces Ruby AST + output, and solves complex build challenges + including circular dependency resolution in + generated code. +

+
+ Input (Python) +
+class Counter:
+    def increment(self):
+        self.count = self.count + 1
+
+
+
+ Output (Ruby) +
+class Counter
+  def increment
+    @count = @count + 1
+  end
+end
+
+
+ Flex + Bison + C++ + Make +
+ +
+
-
-

Order Tracker for Cake Shop Go / SQLite / HTMX

-

- A production-ready logistics system for a local business. Features - transactional integrity, secure session-based auth, and a dynamic UI - using HTMX. The entire stack is compiled into a single binary using - Go's embed system for zero-dependency deployment. -

-
+
+
+

Minesweeper

+

+ A fully-playable Minesweeper clone built with C and + SDL3. Demonstrates comfort with low-level graphics + programming and C memory management. +

+
+ C + SDL3 + CMake +
+ +
+
-
-

- Self-Hosted Infrastructure - Debian / Docker / NixOS -

-

- Management of a production environment for media, backups, and small - business order-tracking. Running in Docker, secured behind an overlay - VPN, and exposed via Cloudflare tunnels when required. -

-
-
+
+
+

Disk-Friendly B+ Tree

+

+ A B+ tree implementation focused on memory-efficient + data structures and disk-aware storage. +

+
+ Rust + Data Structures +
+ +
+
-
-

DEVELOPMENT PHILOSOPHY

-

- I believe in Deep Ownership. Beyond writing code, I strive to - understand the entire delivery chain—from database commit logs and - memory management to final binary deployment. I am guided by: -

-
    -
  • - Intentional Tooling: I choose stacks based on problem-solving - efficiency rather than industry trends. This pragmatic approach - ensures the right tool is used for the specific performance - requirements of the task. -
  • -
  • - Minimalism: I prioritize low dependency counts to reduce attack - surfaces, minimize maintenance debt, and ensure lightning-fast - execution—whether in a systems binary or a browser-based UI. -
  • -
  • - Transparency: I value understanding the abstractions I use. My - experience with systems-level languages (C, Go, Rust) provides me with - a unique perspective on optimizing high-level applications and - debugging complex performance bottlenecks. -
  • -
-
+
+
+

Self-Hosted Infrastructure

+

+ Production server running Debian with Docker + containers and systemd-managed services. Hosts + media, backups, and the cake shop's order-tracking + system. Secured behind an overlay VPN, exposed + through Cloudflare tunnels where needed, with + automated backups and monitoring. +

+
+ Docker + Debian + systemd + Cloudflare + VPN +
+
+
-
-

OTHER INTERESTS

-
-

Literary

-

- I primarily read Science Fiction but also enjoy classic murder - mysteries. Some of my favorite books include: -

-
    -
  • Foundation (Isaac Asimov)
  • -
  • God Emperor of Dune (Frank Herbert)
  • -
  • The Three-Body Problem (Cixin Liu)
  • -
  • The Murder of Roger Ackroyd (Agatha Christie)
  • -
+
+
+

External Sorting

+

+ High-performance external sort for datasets + exceeding RAM capacity. Uses min-heaps and optimized + disk I/O buffers. +

+
+ C++ + Algorithms +
+ +
+
+ +
-

Gaming

-

I mostly play automation games but also enjoy other indie titles:

-
    -
  • Factorio
  • -
  • Satisfactory
  • -
  • Celeste
  • -
  • Outer Wilds
  • -
+
+

Availability & Commitment

+

+ I am looking for a paid internship or junior developer position + - full-time for summer 2026, then part-time during the academic + year. +

+
    +
  • + Summer 2026 (Jul–Sep): Full-time internship / junior + role. +
  • +
  • + Academic Year 2026/27: Part-time (approx. 20h/week). +
  • +
  • Post-Graduation (2027+): Full-time, permanent.
  • +
+
-

Other

-
    -
  • Bouldering
  • -
  • Motorcycling
  • -
  • Cubing (Rubik's Cube)
  • -
  • - Tinkering with hardware and building custom, hand-wired keyboards -
  • -
-
-
- - - +
+

Development Philosophy

+

+ I believe in Deep Ownership — understanding the full + delivery chain from memory management to deployment. I am guided + by: +

+ +
+ diff --git a/screenshots/piekarnikgosi-hero.avif b/screenshots/piekarnikgosi-hero.avif new file mode 100644 index 0000000000000000000000000000000000000000..5cc2b0179678f6e5bbf1b0818b06e44e798e0e1f GIT binary patch literal 27936 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 CQVXR3 literal 0 HcmV?d00001 diff --git a/style.css b/style.css index 4757d21..2d19b4b 100644 --- a/style.css +++ b/style.css @@ -1,65 +1,353 @@ :root { - --bg: #ffffff; - --text: #1a1a1a; - --accent: #000080; - --dim: #666; - --code-bg: #f4f4f4; + --bg: #fafafa; + --bg-card: #ffffff; + --text: #1a1a1a; + --text-dim: #666666; + --accent: #1a6b3c; + --accent-dim: #2d8a4e; + --border: #e0e0e0; + --tag-bg: #f0f0f4; + --tag-text: #333; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04); + --radius: 8px; +} + +@media (prefers-color-scheme: dark) { + :root { + --bg: #111113; + --bg-card: #1a1a1e; + --text: #e4e4e7; + --text-dim: #a1a1aa; + --accent: #4ade80; + --accent-dim: #22c55e; + --border: #27272a; + --tag-bg: #27272a; + --tag-text: #d4d4d8; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2); + } +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; } body { - font-family: "Liberation Sans", sans-serif; - line-height: 1.6; - color: var(--text); - max-width: 800px; - margin: 0 auto; - padding: 2rem 1.5rem; + font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, + sans-serif; + line-height: 1.65; + color: var(--text); + background: var(--bg); + max-width: 900px; + margin: 0 auto; + padding: 2.5rem 1.5rem; + transition: + color 0.2s, + background 0.2s; } -header { - border-bottom: 2px solid var(--text); - padding-bottom: 1rem; - margin-bottom: 2rem; +section { + margin-top: 3rem; } -a { - color: var(--accent); - text-decoration: none; - font-weight: bold; - margin-right: 15px; -} - -a:hover { - text-decoration: underline; +h1 { + font-size: 1.75rem; + font-weight: 700; + letter-spacing: -0.02em; } h2 { - font-size: 1.1rem; - text-transform: uppercase; - letter-spacing: 2px; - border-bottom: 1px solid #ddd; - padding-bottom: 0.3rem; - margin-top: 2.5rem; + font-size: 1rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--accent); + margin-bottom: 1.25rem; } h3 { - margin-bottom: 0.5rem; - font-size: 1.1rem; + font-size: 1.1rem; + font-weight: 600; + margin-bottom: 0.4rem; } -h3 span { - font-family: monospace; - font-size: 0.85rem; - background: var(--code-bg); - padding: 2px 6px; - border-radius: 4px; - font-weight: normal; - margin-left: 10px; - color: var(--text); +p { + margin-bottom: 0.75rem; +} + +a { + color: var(--accent); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 1rem; + padding-bottom: 1.5rem; + border-bottom: 1px solid var(--border); + margin-bottom: 0; +} + +header p { + color: var(--text-dim); + font-size: 0.95rem; + margin-top: 0.2rem; + margin-bottom: 0; +} + +header nav { + display: flex; + align-items: center; + gap: 0.75rem; + flex-shrink: 0; +} + +header nav a { + font-size: 0.875rem; + font-weight: 500; + color: var(--text-dim); +} + +header nav a:hover { + color: var(--accent); + text-decoration: none; +} + +.contact-bar { + display: flex; + gap: 1.5rem; + flex-wrap: wrap; + font-size: 0.9rem; + color: var(--text-dim); + margin-top: 0.5rem; +} + +.contact-bar a { + font-weight: 500; +} + +.entry { + padding: 1.25rem; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius); + box-shadow: var(--shadow); +} + +.entry-head { + margin-bottom: 0.75rem; +} + +.entry-head h3 { + font-size: 1rem; + margin-bottom: 0.15rem; +} + +.entry-meta { + font-size: 0.85rem; + color: var(--text-dim); +} + +.tags { + display: flex; + flex-wrap: wrap; + gap: 0.4rem; + margin-top: 0.75rem; +} + +.tags span { + font-size: 0.75rem; + font-family: "SF Mono", "Fira Code", "Fira Mono", Menlo, monospace; + background: var(--tag-bg); + color: var(--tag-text); + padding: 0.2rem 0.5rem; + border-radius: 4px; +} + +.tag-desc { + font-size: 0.85rem; + font-weight: 400; + color: var(--text-dim); + margin-left: 0.3rem; +} + +.project-grid { + display: grid; + grid-template-columns: 1fr; + gap: 1rem; +} + +@media (min-width: 640px) { + .project-grid { + grid-template-columns: 1fr 1fr; + } +} + +.card { + display: flex; + flex-direction: column; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius); + box-shadow: var(--shadow); + overflow: hidden; + transition: + border-color 0.2s, + box-shadow 0.2s; +} + +.card:hover { + border-color: var(--accent); + box-shadow: + 0 2px 8px rgba(0, 0, 0, 0.08), + 0 1px 3px rgba(0, 0, 0, 0.04); +} + +.card-img { + display: block; + line-height: 0; + overflow: hidden; +} + +.card-img:hover { + text-decoration: none; +} + +.card-img img { + width: 100%; + height: 180px; + object-fit: cover; + transition: transform 0.3s ease; +} + +.card-img img[src$=".svg"] { + height: auto; + max-height: 200px; + object-fit: contain; + background: var(--bg); + padding: 0.5rem 0; +} + +.card-img:hover img { + transform: scale(1.03); +} + +.card-body { + padding: 1.25rem; + flex: 1; + display: flex; + flex-direction: column; +} + +.card-body h3 { + font-size: 1rem; + margin-bottom: 0.4rem; +} + +.card-body p { + font-size: 0.9rem; + color: var(--text-dim); + line-height: 1.55; + flex: 1; +} + +.code-compare { + margin: 0.75rem 0 0; + font-size: 0.8rem; + border-radius: 6px; + overflow: hidden; + border: 1px solid var(--border); +} + +.code-compare .code-label { + display: block; + font-size: 0.65rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + padding: 0.3rem 0.6rem; + background: var(--tag-bg); + color: var(--text-dim); + border-bottom: 1px solid var(--border); +} + +.code-compare pre { + margin: 0; + padding: 0.6rem; + overflow-x: auto; + font-family: "SF Mono", "Fira Code", "Fira Mono", Menlo, monospace; + font-size: 0.75rem; + line-height: 1.45; + color: var(--text); + background: var(--bg); +} + +.code-compare + .code-compare { + border-top: 0; + border-radius: 0 0 6px 6px; +} + +.arrow-mid { + text-align: center; + font-size: 0.8rem; + color: var(--text-dim); + padding: 0.25rem 0; + line-height: 1; +} + +.card-links { + margin-top: 0.75rem; + font-size: 0.875rem; + display: flex; + gap: 1.25rem; +} + +.card-links a { + font-weight: 500; +} + +#availability ul { + list-style: none; + padding: 0; +} + +#availability li { + padding: 0.5rem 0; + border-bottom: 1px solid var(--border); + font-size: 0.95rem; +} + +#availability li:last-child { + border-bottom: none; +} + +#philosophy ul { + padding-left: 1.2rem; +} + +#philosophy li { + margin-bottom: 0.6rem; + font-size: 0.95rem; + line-height: 1.55; } footer { - margin-top: 4rem; - border-top: 1px solid #eee; - font-size: 0.85rem; - color: var(--dim); + margin-top: 4rem; + padding-top: 1.5rem; + border-top: 1px solid var(--border); + font-size: 0.85rem; + color: var(--text-dim); + text-align: center; +} + +footer p { + margin-bottom: 0; }