Compare commits

..

No commits in common. "c435ceacdab7f194db4b7d2e663fdb48ad37072f" and "834e3194ca8e35da51da56e8f6e8946d35cb004a" have entirely different histories.

5 changed files with 129 additions and 2120 deletions

View File

@ -30,8 +30,3 @@ RewriteRule ^domains/[^/]+/(.+[^/])$ /$1/ [R]
# subdomeny - spravne presmerovani pri chybejicim / # subdomeny - spravne presmerovani pri chybejicim /
RewriteCond %{REQUEST_FILENAME} -d RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^subdom/[^/]+/(.+[^/])$ /$1/ [R] RewriteRule ^subdom/[^/]+/(.+[^/])$ /$1/ [R]
# Route /cv to index.php for CV view
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^cv/?$ index.php [L,QSA]

185
data.json
View File

@ -1,185 +0,0 @@
{
"name": "David Hrdina Němeček",
"photo": "photo.png",
"headline": "Principal Software Engineer at Oracle NetSuite",
"summary": "UI platform architect specializing in AI-assisted engineering enablement, telemetry and performance.",
"email": "explosive@dejvino.cz",
"location": "Brno, Czechia",
"phone": "+420 775 26 26 32",
"contact_links": {
"Website": "https://www.dejvino.cz",
"Email": "mailto:explosive@dejvino.cz",
"Resume": "https://dejvino.cz/cv"
},
"about": [
"Principal Software Engineer at Oracle NetSuite, focusing on AI-assisted developer enablement, UI platform architecture, performance, and observability for 40k+ enterprise customers."
],
"highlights": [
{
"title": "AI-first Design System Guidance Tooling",
"description": [
"Researched and prototyped an AI-first UI Toolkit guidance system leveraging Model Context Protocol (MCP). The tool covered over 260 component guideline documents, code samples and development best practices. It was authored in collaboration with 3 frontrunner UX designers, scaling their expertise across multiple teams.",
"Created an automated code review bot leveraging this knowledge corpus, successfully trialed across 4 platform and app delivery teams to validate UI changes early in development."
],
"date": "2025 2026"
},
{
"title": "Telemetry Stack Architecture",
"description": [
"Shaped product telemetry architecture spanning frontend UI, backend integration, and AI interaction streams. Championed migration from legacy telemetry solutions to OpenTelemetry. Integrated Oracle APM for enterprise-grade performance monitoring.",
"Designed action-root hybrid sampling strategy to achieve a 92% telemetry volume reduction while preserving critical user-behavior signals.",
"Delivered in-app trace visualizer, driving up telemetry adoption among teams."
],
"date": "2024 2026"
},
{
"title": "UI Performance & Bootstrap Optimization",
"description": [
"Analyzed UI app bootstrap performance, driving improvements that gained 28% speed improvement.",
"Eliminated redundant network requests by introducing TanStack Query network caching. Defined tiered JavaScript dependency loading mechanism for on-demand toolkit loading."
],
"date": "2025 2026"
},
{
"title": "Consumer-driven Contract Testing",
"description": [
"Prototyped UI <=> backend API contract testing using Pact to prevent cross-system breaking changes early in the development lifecycle.",
"Defined consumer test suites, contract generation, and provider verification workflows between frontend UI applications and backend services."
],
"date": "2025 2026"
},
{
"title": "UI Testing Strategy & Architecture",
"description": [
"Led senior QA engineers in defining and executing the long-term UI testing architecture strategy across platform teams.",
"Established automated test suites and quality guardrails to elevate testing standards."
],
"date": "2021 2023"
},
{
"title": "Pluggable Tax Calculation Engine",
"description": [
"Architected and led the development of a pluggable tax calculation engine for NetSuite cloud ERP.",
"Coordinated technical strategy across 20+ software engineers in 4 squads, standardizing global tax calculation pipelines."
],
"date": "2017 2020"
}
],
"cv": {
"experience": [
{
"title": "Principal Software Engineer (UI Platform Architecture)",
"company": "Oracle|NetSuite",
"date": "2023 present",
"description": "Driving technical vision and solution architecture for the NetSuite UI Platform (NetSuite Next). Leading initiatives in AI-assisted developer enablement, telemetry architecture, performance optimization."
},
{
"title": "Senior Software Development Manager (UI Platform)",
"company": "Oracle|NetSuite",
"date": "2022 2023",
"description": "Engineering lead for multiple UI Platform teams building core framework components and developer tooling."
},
{
"title": "Software Development Manager (UI Platform)",
"company": "Oracle|NetSuite",
"date": "2020 2022",
"description": "Engineering lead for a UI Platform team building shared UI components. Acted as technical product owner while bootstrapping the team and establishing component delivery standards."
},
{
"title": "Software Development Manager (ERP, Tax)",
"company": "Oracle|NetSuite",
"date": "2017 2020",
"description": "Engineering lead for ERP Tax domain. Designed and delivered a pluggable tax calculation engine, coordinating technical direction for 20+ engineers across 4 squads."
},
{
"title": "Senior Software Engineer (ERP, Tax)",
"company": "Oracle|NetSuite",
"date": "2013 2017",
"description": "Development of cloud ERP tax calculation and reporting modules. Led large-scale refactoring of legacy codebases and improved calculation reliability for enterprise clients."
},
{
"title": "Software Engineer",
"company": "Q2 Interactive",
"date": "2009 2013",
"description": "Development of e-commerce, ERP, and CRM web applications and custom services."
}
],
"skills": {
"Architecture & Domains": [
"UI Platform Architecture",
"AI-Assisted Engineering",
"Developer Enablement & Tooling",
"Telemetry & Observability",
"Performance Optimization",
"Consumer-Driven Contract Testing"
],
"Languages & Core Ecosystems": [
"TypeScript",
"JavaScript",
"Node.js",
"Java",
"Python",
"OpenTelemetry",
"Model Context Protocol (MCP)"
],
"Spoken Languages": [
"Czech (native)",
"English (proficient)",
"German (elementary)"
],
"Certifications": [
"OCI 2025 Certified Observability Professional",
"OCI 2025 Certified AI Foundations Associate"
]
},
"education": [
{
"degree": "Master's degree",
"field": "Parallel and Distributed Systems",
"institution": "Faculty of Informatics, Masaryk University Brno",
"date": "2011 2013",
"thesis": "Efficient computation and visualization of correlations in medical signals. High-performance computation of correlations on large volumes of analog data in C++ using supercomputers. Visualization of the computed results through interactive exploration and processing of the data by a researcher in Python."
},
{
"degree": "Bachelor's degree",
"field": "Parallel and Distributed Systems",
"institution": "Faculty of Informatics, Masaryk University Brno",
"date": "2008 2011",
"thesis": "Parallel implementation of force-field decompression algorithm. Executed on a supercomputer cluster to perform real-time simulation of molecular forces, providing haptic feedback to a 3D pointing device."
}
],
"philosophy": "I design platform layers that stay out of the way while enabling everything else.</br>Quiet infrastructure. Measurable value."
},
"interests": [
{
"name": "Mandolin",
"caption": "Octave mandolin is my instrument of choice. Wide range of tones, pleasant sound. Great way to relax your mind, explore melodies and harmonies.",
"image": null
},
{
"name": "Electronics tinkering",
"caption": "Building a useful device from scratch. Retrofitting modern brains into a broken vintage shell. Electronics is the magic that makes things alive.",
"image": null
},
{
"name": "Synthwave",
"caption": "Neon-filled nostalgia. Fun to create, relaxing to listen to it.",
"image": "interests/synthwave.png"
},
{
"name": "3D Printing & Design",
"caption": "Designing and printing custom parts that serve a purpose. Unique designs, useful accessories, toys or just repairs.",
"image": null
},
{
"name": "Mountain Biking",
"caption": "Going places under your own power. Exploring forests, trails and nature where cars aren't allowed.",
"image": null
},
{
"name": "RC Cars",
"caption": "Rock crawlers, construction trucks, military vehicles. Building a custom offroad course in the garden to trial them all.",
"image": null
}
]
}

381
index.php
View File

@ -1,157 +1,37 @@
<?php <?php
/** /**
* Content config: * Content config:
*/ */
$cvData = json_decode(file_get_contents(__DIR__ . '/data.json'), true); $name = "David Hrdina Němeček";
$site_title = "www.dejvino.cz";
$site_url = "https://www.dejvino.cz/";
$site_desc = "$name - Software Developer";
$subtitle = "Software Developer, Architect, Problem Solver";
$photo_file = "photo.png";
$email_user = "ciao";
$isCvPath = strpos($_SERVER['REQUEST_URI'], '/cv') !== false; $about_text = [
"Full-stack developer focused on pragmatic architecture, observability and performance.",
$name = $cvData['name'] ?? ''; //""
$headline = $cvData['headline'] ?? ''; ];
$summary = $cvData['summary'] ?? '';
$location = $cvData['location'] ?? '';
$photo_file = $cvData['photo'] ?? '';
$nav_links = [ $nav_links = [
'Blog' => 'https://wp.dejvino.com/', "~/blog" => "https://wp.dejvino.com/",
'Projects' => 'https://projects.dejvino.com/', "~/projects" => "https://projects.dejvino.com/",
'Code' => 'https://git.dejvino.cz/', "~/code" => "https://git.dejvino.cz/",
];
$highlights = $cvData['highlights'] ?? [];
/**
* Sourced Interests Showcase (from data.json)
*/
$interests_showcase = [];
if (!empty($cvData['interests'])) {
foreach ($cvData['interests'] as $item) {
$img = $item['image'] ?? null;
$has_image = $img && file_exists(__DIR__ . '/' . $img);
$interests_showcase[] = [
'name' => $item['name'] ?? '',
'image' => $has_image ? $img : null,
'caption' => $item['caption'] ?? ''
];
}
}
$site_url = "https://www.dejvino.cz/";
$site_title = $name;
$site_desc = "$name - $headline";
$mailto_link = $cvData['contact_links']['Email'] ?? '';
if (preg_match('/mailto:([^@]+)/', $mailto_link, $m)) {
$email_user = $m[1];
} else {
$email_user = $cvData['email'] ?? '';
}
$extra_contact_links = $cvData['contact_links'] ?? [];
/**
* Emoji icons for link pills
*/
$pill_icons = [
'Website' => '🌐',
'Email' => '✉️',
'Resume' => '📄',
'CV' => '📄',
'PDF' => '📑',
'Blog' => '✍️',
'Projects' => '📁',
'Code' => '💻',
'GitLab' => '🔶',
'GitHub' => '🐙',
]; ];
/** $hardware_info = "Playing the mandolin, mountain biking, 3D printing and tinkering.";
* Extract a readable URL from a href (strip protocol, trailing slash)
*/
function pillUrl(string $href): string {
$url = $href;
if (preg_match('/^[a-z]+:\/\//i', $url)) {
$url = preg_replace('/^[a-z]+:\/\//i', '', $url);
}
$url = rtrim($url, '/');
return strlen($url) > 30 ? mb_substr($url, 0, 27) . '…' : $url;
}
/**
* Render a standardized pill link
*/
function render_pill(string $href, string $label, string $icon_emoji, string $class_suffix = ''): string {
$url_display = pillUrl($href);
$classes = $class_suffix ? "pill {$class_suffix}" : 'pill';
return sprintf(
'<a href="%s" target="_blank" class="%s">' .
'<span class="pill-icon">%s</span>' .
'<span class="pill-label">%s</span>' .
'<span class="pill-url">%s</span>' .
'</a>',
htmlspecialchars($href, ENT_QUOTES, 'UTF-8'),
$classes,
$icon_emoji,
htmlspecialchars($label, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($url_display, ENT_QUOTES, 'UTF-8')
);
}
/**
* CV Data
*/
// Map experience to expected structure
$cv_experience = array_map(function ($e) {
return [
'title' => $e['title'] ?? '',
'org' => $e['company'] ?? '',
'date' => $e['date'] ?? '',
'desc' => $e['description'] ?? '',
];
}, $cvData['cv']['experience'] ?? []);
// Helper to calculate years between start and end dates
function calculateYears($dateStr) {
// Extract start and end years, support 'present' or 'current'
$dateStr = str_replace(['', '—', '', '-'], '-', $dateStr);
$parts = array_map('trim', explode('-', $dateStr, 2));
if (count($parts) < 2) {
return 0;
}
$start = (int)$parts[0];
$endRaw = strtolower($parts[1]);
$end = ($endRaw === 'present' || $endRaw === 'current') ? (int)date('Y') : (int)$endRaw;
$years = $end - $start;
if ($years <= 1) {
return "1 year";
}
return "$years years";
}
// Map education to expected structure
$cv_education = array_map(function ($e) {
return [
'title' => $e['degree'] ?? '',
'org' => $e['institution'] ?? '',
'date' => $e['date'] ?? '',
'desc' => $e['thesis'] ?? '',
];
}, $cvData['cv']['education'] ?? []);
// Keep skills categories as provided
$cv_skills = $cvData['cv']['skills'] ?? [];
/** /**
* Page design: * Page design:
* - clean and simple, human-maintainable * - clean and simple, human-maintaninable
* - no dependencies * - no dependencies
* - single-file website * - single-file website
*/ */
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title><?= $site_title ?></title> <title><?= $site_title ?></title>
@ -164,7 +44,7 @@ $cv_skills = $cvData['cv']['skills'] ?? [];
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<meta property="og:url" content="<?= $site_url ?>"> <meta property="og:url" content="<?= $site_url ?>">
<meta property="og:title" content="<?= $name ?>"> <meta property="og:title" content="<?= $name ?>">
<meta property="og:description" content="<?= $headline ?>"> <meta property="og:description" content="<?= $subtitle ?>">
<style> <style>
<?php <?php
@ -173,230 +53,59 @@ $cv_skills = $cvData['cv']['skills'] ?? [];
</style> </style>
<link rel="shortcut icon" href="favicon.ico"> <link rel="shortcut icon" href="favicon.ico">
</head> </head>
<body>
<body class="<?= $isCvPath ? 'cv-mode' : '' ?>">
<main class="bento-grid"> <main class="bento-grid">
<section class="card profile">
<section class="card hero">
<div class="hero-row hero-identity">
<?php <?php
if (file_exists($photo_file)) { if (file_exists($photo_file)) {
$avatarBase64 = base64_encode(file_get_contents($photo_file)); $avatarBase64 = base64_encode(file_get_contents($photo_file));
echo '<img src="data:image/png;base64,' . $avatarBase64 . '" alt="' . $name . '" class="avatar" width="80" height="106" />'; echo '<img src="data:image/png;base64,' . $avatarBase64 . '" alt="' . $name . '" class="avatar" width="120" height="160" />';
} else { } else {
echo '<div class="avatar-placeholder"></div>'; echo '<div class="avatar-placeholder"></div>';
} }
?> ?>
<div class="hero-name"> <div class="header-text">
<h1><?= $name ?></h1> <h1><?= $name ?></h1>
<?php if ($headline): ?> <p class="subtitle"><?= $subtitle ?></p>
<p class="headline"><?= $headline ?></p>
<?php endif; ?>
<?php if ($location): ?>
<p class="location"><?= $location ?></p>
<?php endif; ?>
</div>
</div>
<button class="print-button" onclick="window.print()">
🖨️ Print CV
</button>
<?php if ($summary): ?>
<div class="hero-row hero-description">
<p><?= $summary ?></p>
</div>
<?php endif; ?>
<div class="hero-row hero-contacts">
<?php foreach ($extra_contact_links as $label => $href): ?>
<?= render_pill($href, $label, $pill_icons[$label] ?? '🔗', 'contact-pill' . ($label === 'CV' || $label === 'Resume' ? ' pill-cv-only-print' : '')) ?>
<?php endforeach; ?>
</div>
<div class="hero-row hero-nav">
<?php foreach ($nav_links as $label => $href): ?>
<?= render_pill(trim($href), $label, $pill_icons[$label] ?? '🔗', 'nav-pill') ?>
<?php endforeach; ?>
</div> </div>
</section> </section>
<?php if (!$isCvPath && $interests_showcase): ?> <section class="card about">
<?php // Hardcoded palette of dark, varied tints <h2>Bio</h2>
$bg_palette = [ <?php foreach ($about_text as $para): ?>
'#1e2a33', // Dark Blue <p><?= $para ?></p>
'#1e332a', // Dark Green <?php endforeach; ?>
'#2a1e33', // Dark Purple </section>
'#331e2a', // Dark Red
'#1a3333', // Dark Teal <section class="card links">
'#33331a', // Dark Olive <h2>Navigation</h2>
]; <ul class="link-grid">
$palette_size = count($bg_palette); <?php foreach ($nav_links as $label => $url): ?>
?> <li><a href="<?= $url ?>"><span><?= $label ?></span></a></li>
<section class="card interests-showcase">
<nav class="interests-nav">
<h2>Things I like to do</h2>
<ul>
<?php foreach ($interests_showcase as $i => $item): ?>
<li class="<?= $i === 0 ? 'active' : '' ?>" data-index="<?= $i ?>">
<?= htmlspecialchars($item['name']) ?>
</li>
<?php endforeach; ?> <?php endforeach; ?>
</ul> </ul>
</nav>
<div class="interests-display">
<?php foreach ($interests_showcase as $i => $item): ?>
<div class="interest-slide <?= $i === 0 ? 'active' : '' ?>" data-index="<?= $i ?>" style="background-color: <?= $bg_palette[$i % $palette_size] ?>;">
<?php if ($item['image']): ?>
<img src="<?= htmlspecialchars($item['image']) ?>" alt="<?= htmlspecialchars($item['name']) ?>">
<?php endif; ?>
<p class="caption"><?= htmlspecialchars($item['caption']) ?></p>
</div>
<?php endforeach; ?>
</div>
</section>
<?php endif; ?>
<?php if ($isCvPath): ?>
<?php if ($highlights): ?>
<section class="card selected-work">
<h2>Selected Work</h2>
<?php foreach ($highlights as $h): ?>
<article class="highlight-item">
<h3><?= $h['title'] ?? '' ?><?php if ($h['date'] ?? ''): ?> <time class="highlight-date"><?= $h['date'] ?></time><?php endif; ?></h3>
<?php if ($h['description']): ?>
<div class="highlight-descriptions">
<?php if (is_array($h['description'])): ?>
<?php foreach ($h['description'] as $desc): ?>
<p class="highlight-description"><?= $desc ?></p>
<?php endforeach; ?>
<?php else: ?>
<p class="highlight-description"><?= $h['description'] ?></p>
<?php endif; ?>
</div>
<?php endif; ?>
</article>
<?php endforeach; ?>
<?php if ($cvData['cv']['philosophy'] ?? ''): ?>
<blockquote class="philosophy"><?= $cvData['cv']['philosophy'] ?></blockquote>
<?php endif; ?>
</section>
<?php endif; ?>
<section class="card skills">
<h2>Skills</h2>
<div class="skill-categories">
<?php foreach ($cv_skills as $category => $skills): ?>
<div class="skill-group">
<h3><?= $category ?></h3>
<div class="skill-tags">
<?php foreach ($skills as $skill): ?>
<span class="tag"><?= $skill ?></span>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</section> </section>
<?php <section class="card interests">
$firstJob = $cv_experience[0] ?? null; <h2>Likes</h2>
if ($firstJob): <p><?= $hardware_info ?></p>
?>
<section class="card first-experience">
<h2>Latest Experience</h2>
<article class="cv-item">
<header class="cv-item-header">
<h3 class="cv-title"><?= $firstJob['title'] ?></h3>
<span class="cv-date"><?= $firstJob['date'] ?> (<?= calculateYears($firstJob['date']) ?>)</span>
</header>
<p class="cv-org"><?= $firstJob['org'] ?></p>
<p class="cv-desc"><?= $firstJob['desc'] ?></p>
</article>
</section>
<?php endif; ?>
<section class="card experience">
<h2>Past Experience</h2>
<?php foreach (array_slice($cv_experience, 1) as $job): ?>
<article class="cv-item">
<header class="cv-item-header">
<h3 class="cv-title"><?= $job['title'] ?></h3>
<span class="cv-date"><?= $job['date'] ?> (<?= calculateYears($job['date']) ?>)</span>
</header>
<p class="cv-org"><?= $job['org'] ?></p>
<p class="cv-desc"><?= $job['desc'] ?></p>
</article>
<?php endforeach; ?>
</section>
<section class="card education">
<h2>Education</h2>
<?php foreach ($cv_education as $edu): ?>
<article class="cv-item">
<header class="cv-item-header">
<h3 class="cv-title"><?= $edu['title'] ?></h3>
<time class="cv-date"><?= $edu['date'] ?></time>
</header>
<p class="cv-org"><?= $edu['org'] ?></p>
<?php if ($edu['desc']): ?>
<p class="cv-desc"><?= $edu['desc'] ?></p>
<?php endif; ?>
</article>
<?php endforeach; ?>
</section> </section>
<?php if ($interests_showcase): ?> <section class="card contact">
<section class="card personal"> <h2>Remote_Access</h2>
<h2>Interests</h2> <p class="mono-addr">
<div class="personal-tags"> Contact email: <span id="contact-mail">uncovering...</span>
<?php foreach ($interests_showcase as $item): ?> </p>
<span class="personal-tag"><?= htmlspecialchars($item['name']) ?></span>
<?php endforeach; ?>
</div>
</section> </section>
<?php endif; ?>
<?php endif; ?>
</main> </main>
<script> <script>
((u, d, t) => { ((u, d, t) => {
const addr = (atob(u) + '@' + d + '.' + t).trim(); const addr = u + '@' + d + '.' + t;
const el = document.getElementById("contact-mail"); const el = document.getElementById("contact-mail");
if (el) el.innerHTML = `<a href="mailto:${addr}">${addr}</a>`; el.innerHTML = `<a href="mailto:${addr}">${addr}</a>`;
})('<?= base64_encode($email_user) ?>', 'dejvino', 'cz'); })('<?= $email_user ?>', 'dejvino', 'cz');
// Interests Showcase Logic
(() => {
const slides = document.querySelectorAll('.interest-slide');
const labels = document.querySelectorAll('.interests-nav li');
if (!slides.length) return;
let currentIndex = 0;
let interval = setInterval(next, 5000);
function show(index) {
slides.forEach(s => s.classList.remove('active'));
labels.forEach(l => l.classList.remove('active'));
slides[index].classList.add('active');
labels[index].classList.add('active');
currentIndex = index;
}
function next() { show((currentIndex + 1) % slides.length); }
labels.forEach((label, i) => {
label.addEventListener('click', () => {
show(i);
clearInterval(interval);
interval = setInterval(next, 8000); // Slower auto-switch after manual interaction
});
});
})();
</script> </script>
<!-- Cloudflare Web Analytics -->
<script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "90827cb740cd4b1db611be059f64daa9"}'></script><!-- End Cloudflare Web Analytics -->
<?php $file_mod_time = filemtime(__FILE__); ?>
<p class="page-footer">Modified: <?= date("Y-m-d", $file_mod_time) ?></p>
</body> </body>
</html> </html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 751 KiB

1630
style.css

File diff suppressed because it is too large Load Diff