Build personal DevOps portfolio site

Static HTML/CSS/JS site with local fonts and icons, certificate gallery,
work section and homelab diagrams, ready for rezayaghobi.ir.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
This commit is contained in:
rezayaghobi-dev
2026-10-19 10:19:26 +03:30
commit 56b728dc49
58 changed files with 2236 additions and 0 deletions

112
README.md Normal file
View File

@@ -0,0 +1,112 @@
# Reza Yaghobi — personal site
A static, single-page portfolio for `rezayaghobi.ir`. Plain HTML, CSS and one small
JavaScript file. There is no build step and the page makes no external requests.
## Preview locally
From this directory:
```bash
python3 -m http.server 8080
```
Open <http://localhost:8080/>.
## Structure
```
index.html all content and both inline SVG diagrams
favicon.svg "RY" monogram
robots.txt
assets/style.css design tokens, layout, components, motion, responsive rules
assets/brand.css generated per-tile brand colours (used for tile hover borders)
assets/app.js progress line, section reveals, diagram line drawing
assets/boot.js adds .js to <html> before render
assets/fonts/ two latin variable woff2 files
assets/icons/ 33 tool icons (simple-icons + neutral monograms)
assets/img/ screenshots, certificate images (WebP), og.png
tools/build-icons.mjs regenerates the icon set and assets/brand.css
tools/og.html template used to render the Open Graph image
```
## Fonts
The fonts are copied from the Fontsource packages, latin variable weight files only:
- `@fontsource-variable/bricolage-grotesque` →
`bricolage-grotesque-latin-wght-normal.woff2`
- `@fontsource-variable/instrument-sans` →
`instrument-sans-latin-wght-normal.woff2`
They are declared with `font-display: swap` and a system fallback stack. Small
labels use the system monospace stack.
## Icons
Icons are generated from [`simple-icons`](https://simpleicons.org/) in a scratch
folder outside this site. Install it once:
```bash
mkdir -p /tmp/ry-scratch
cd /tmp/ry-scratch
npm init -y
npm install simple-icons
```
Then, from this project:
```bash
node tools/build-icons.mjs
# or point at another install:
SIMPLE_ICONS_DIR=/path/to/node_modules/simple-icons node tools/build-icons.mjs
```
The script reads each icon's slug, path and brand hex from `simple-icons`, then:
- writes `assets/icons/<tool>.svg` with the brand colour as `fill`;
- lightens any brand colour that falls below 3:1 contrast on the `#0a0d14`
background (Helm and Elasticsearch needed this);
- writes `assets/brand.css` with one `--brand` custom property per tile;
- writes a neutral monogram tile for tools simple-icons does not include:
HAProxy, Keepalived, Argo CD, GitOps, Nexus Repository, Loki, Alloy, Zabbix,
C# and Microsoft SQL Server. These are plain letters, not imitations of logos.
## Images
`assets/img/pipeline.png` and `assets/img/dashboard.png` are copies of the supplied
screenshots. The page uses 1200 px wide WebP versions generated with Pillow:
```python
from PIL import Image
im = Image.open("images/pipline-green.png").convert("RGB")
im.resize((1200, round(im.height * 1200 / im.width)), Image.LANCZOS).save(
"assets/img/pipeline-1200.webp", "WEBP", quality=82, method=6
)
```
Repeat for `images/dashboard.png`.
The three ArvanCloud certificate images are converted from `images/Associate.jpg`,
`images/professional.png` and `images/expert.png` to 1000 px wide WebP at quality
80: `cert-associate.webp`, `cert-professional.webp` and `cert-expert.webp`. The
full-size WebP opens in a new tab when a thumbnail is clicked.
## Open Graph image
`assets/img/og.png` is a 1200 × 630 render of `tools/og.html`. With the preview
server running:
```bash
google-chrome --headless=new --hide-scrollbars --window-size=1200,630 \
--screenshot=assets/img/og.png http://localhost:8080/tools/og.html
```
## Notes
- Section reveals, hero fades and the staggered tile/row fades are gated behind
classes added by `app.js`, so the page remains fully visible if JavaScript is
disabled or fails.
- All motion is disabled under `prefers-reduced-motion: reduce`.
- The pipeline diagram uses the stage names from the devops-test repository
(`test`, `build`, `publish`, `deploy`) rather than invented steps.

63
assets/app.js Normal file
View File

@@ -0,0 +1,63 @@
/* Progress line, reveals, diagram draw. No dependencies. */
(function () {
var root = document.documentElement;
root.classList.add("anims");
var reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
var canObserve = "IntersectionObserver" in window;
function reveal(target, threshold) {
var nodes = [].slice.call(
typeof target == "string" ? document.querySelectorAll(target) : target
);
if (!canObserve || reduce) {
nodes.forEach(function (n) { n.classList.add("is-in"); });
return;
}
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (!entry.isIntersecting) return;
entry.target.classList.add("is-in");
io.unobserve(entry.target);
});
}, { threshold: threshold, rootMargin: "0px 0px -6% 0px" });
nodes.forEach(function (n) { io.observe(n); });
}
var bar = document.querySelector(".progress");
var waiting = false;
var groups = document.querySelectorAll(
".tiles, .chips, .ladder, .courses, .cert-gallery, .work-list, .timeline, .contact-rows"
);
function paint() {
waiting = false;
if (!bar) return;
var max = document.documentElement.scrollHeight - window.innerHeight;
var p = max > 0 ? window.scrollY / max : 0;
bar.style.transform = "scaleX(" + Math.min(1, Math.max(0, p)) + ")";
}
function queue() {
if (waiting) return;
waiting = true;
window.requestAnimationFrame(paint);
}
try {
[].forEach.call(groups, function (group) {
[].forEach.call(group.children, function (item, i) {
item.style.setProperty("--i", Math.min(i, 6));
});
});
reveal(".reveal", 0.08);
reveal(".diagram", 0.22);
reveal(groups, 0.12);
if (bar && !reduce) {
window.addEventListener("scroll", queue, { passive: true });
window.addEventListener("resize", queue, { passive: true });
paint();
}
} catch (err) {
root.classList.remove("anims");
}
})();

1
assets/boot.js Normal file
View File

@@ -0,0 +1 @@
document.documentElement.classList.add("js");

35
assets/brand.css Normal file
View File

@@ -0,0 +1,35 @@
/* Generated by tools/build-icons.mjs. Do not edit by hand. */
/* Brand colours are lightened where needed to reach 3:1 on #0a0d14. */
.brand--docker{--brand:#2496ed}
.brand--kubernetes{--brand:#326ce5}
.brand--rancher{--brand:#0075a8}
.brand--helm{--brand:#6267b2}
.brand--linux{--brand:#fcc624}
.brand--vmware{--brand:#607078}
.brand--traefik{--brand:#24a1c1}
.brand--nginx{--brand:#009639}
.brand--minio{--brand:#c72e49}
.brand--ceph{--brand:#ef5c55}
.brand--gitlab{--brand:#fc6d26}
.brand--gitlab-ci{--brand:#fc6d26}
.brand--git{--brand:#f03c2e}
.brand--ansible{--brand:#ee0000}
.brand--terraform{--brand:#844fba}
.brand--bash{--brand:#4eaa25}
.brand--prometheus{--brand:#e6522c}
.brand--grafana{--brand:#f46800}
.brand--elasticsearch{--brand:#1e6982}
.brand--python{--brand:#3776ab}
.brand--postgresql{--brand:#4169e1}
.brand--mysql{--brand:#4479a1}
.brand--keras{--brand:#d00000}
.brand--haproxy{--brand:#9aa7bc}
.brand--keepalived{--brand:#9aa7bc}
.brand--argocd{--brand:#9aa7bc}
.brand--gitops{--brand:#9aa7bc}
.brand--nexus{--brand:#9aa7bc}
.brand--loki{--brand:#9aa7bc}
.brand--alloy{--brand:#9aa7bc}
.brand--zabbix{--brand:#9aa7bc}
.brand--csharp{--brand:#9aa7bc}
.brand--mssql{--brand:#9aa7bc}

Binary file not shown.

1
assets/icons/alloy.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><rect x="1.25" y="1.25" width="21.5" height="21.5" rx="5" fill="none" stroke="#9aa7bc" stroke-width="1.1"/><text x="12" y="12" fill="#9aa7bc" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="8.6" font-weight="600" letter-spacing=".2" text-anchor="middle" dominant-baseline="central">AL</text></svg>

After

Width:  |  Height:  |  Size: 402 B

1
assets/icons/ansible.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#ee0000" d="M10.617 11.473l4.686 3.695-3.102-7.662zM12 0C5.371 0 0 5.371 0 12s5.371 12 12 12 12-5.371 12-12S18.629 0 12 0zm5.797 17.305c-.011.471-.403.842-.875.83-.236 0-.416-.09-.664-.293l-6.19-5-2.079 5.203H6.191L11.438 5.44c.124-.314.427-.52.764-.506.326-.014.63.189.742.506l4.774 11.494c.045.111.08.234.08.348-.001.009-.001.009-.001.023z"/></svg>

After

Width:  |  Height:  |  Size: 443 B

1
assets/icons/argocd.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><rect x="1.25" y="1.25" width="21.5" height="21.5" rx="5" fill="none" stroke="#9aa7bc" stroke-width="1.1"/><text x="12" y="12" fill="#9aa7bc" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="8.6" font-weight="600" letter-spacing=".2" text-anchor="middle" dominant-baseline="central">AC</text></svg>

After

Width:  |  Height:  |  Size: 402 B

1
assets/icons/bash.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#4eaa25" d="M21.038,4.9l-7.577-4.498C13.009,0.134,12.505,0,12,0c-0.505,0-1.009,0.134-1.462,0.403L2.961,4.9 C2.057,5.437,1.5,6.429,1.5,7.503v8.995c0,1.073,0.557,2.066,1.462,2.603l7.577,4.497C10.991,23.866,11.495,24,12,24 c0.505,0,1.009-0.134,1.461-0.402l7.577-4.497c0.904-0.537,1.462-1.529,1.462-2.603V7.503C22.5,6.429,21.943,5.437,21.038,4.9z M15.17,18.946l0.013,0.646c0.001,0.078-0.05,0.167-0.111,0.198l-0.383,0.22c-0.061,0.031-0.111-0.007-0.112-0.085L14.57,19.29 c-0.328,0.136-0.66,0.169-0.872,0.084c-0.04-0.016-0.057-0.075-0.041-0.142l0.139-0.584c0.011-0.046,0.036-0.092,0.069-0.121 c0.012-0.011,0.024-0.02,0.036-0.026c0.022-0.011,0.043-0.014,0.062-0.006c0.229,0.077,0.521,0.041,0.802-0.101 c0.357-0.181,0.596-0.545,0.592-0.907c-0.003-0.328-0.181-0.465-0.613-0.468c-0.55,0.001-1.064-0.107-1.072-0.917 c-0.007-0.667,0.34-1.361,0.889-1.8l-0.007-0.652c-0.001-0.08,0.048-0.168,0.111-0.2l0.37-0.236 c0.061-0.031,0.111,0.007,0.112,0.087l0.006,0.653c0.273-0.109,0.511-0.138,0.726-0.088c0.047,0.012,0.067,0.076,0.048,0.151 l-0.144,0.578c-0.011,0.044-0.036,0.088-0.065,0.116c-0.012,0.012-0.025,0.021-0.038,0.028c-0.019,0.01-0.038,0.013-0.057,0.009 c-0.098-0.022-0.332-0.073-0.699,0.113c-0.385,0.195-0.52,0.53-0.517,0.778c0.003,0.297,0.155,0.387,0.681,0.396 c0.7,0.012,1.003,0.318,1.01,1.023C16.105,17.747,15.736,18.491,15.17,18.946z M19.143,17.859c0,0.06-0.008,0.116-0.058,0.145 l-1.916,1.164c-0.05,0.029-0.09,0.004-0.09-0.056v-0.494c0-0.06,0.037-0.093,0.087-0.122l1.887-1.129 c0.05-0.029,0.09-0.004,0.09,0.056V17.859z M20.459,6.797l-7.168,4.427c-0.894,0.523-1.553,1.109-1.553,2.187v8.833 c0,0.645,0.26,1.063,0.66,1.184c-0.131,0.023-0.264,0.039-0.398,0.039c-0.42,0-0.833-0.114-1.197-0.33L3.226,18.64 c-0.741-0.44-1.201-1.261-1.201-2.142V7.503c0-0.881,0.46-1.702,1.201-2.142l7.577-4.498c0.363-0.216,0.777-0.33,1.197-0.33 c0.419,0,0.833,0.114,1.197,0.33l7.577,4.498c0.624,0.371,1.046,1.013,1.164,1.732C21.686,6.557,21.12,6.411,20.459,6.797z"/></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

1
assets/icons/ceph.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#ef5c55" d="M11.959.257A11.912 11.912 0 003.503 3.76 11.92 11.92 0 000 12.217a11.934 11.934 0 001.207 5.243c.72 1.474 1.888 2.944 3.208 4.044.86-.47 1.35-.99 1.453-1.545.1-.533-.134-1.107-.737-1.805a9.031 9.031 0 01-2.219-5.937c0-4.988 4.058-9.047 9.047-9.047h.08c4.99 0 9.048 4.059 9.048 9.047a9.03 9.03 0 01-2.218 5.936c-.599.693-.84 1.292-.735 1.83.108.556.595 1.068 1.449 1.522 1.322-1.1 2.489-2.57 3.209-4.046A11.898 11.898 0 0024 12.217a11.929 11.929 0 00-3.503-8.457A11.923 11.923 0 0012.04.257h-.041zm-.005 4.837a7.072 7.072 0 00-3.76 1.075A7.202 7.202 0 006.15 8.093a7.164 7.164 0 00-1.161 2.65 7.188 7.188 0 00.04 3.125 7.14 7.14 0 001.22 2.607c.154.207.326.396.509.597l.185.202.005.006c.007.007.017.016.026.027.635.738.957 1.533.957 2.36a3.4 3.4 0 01-1.788 2.989 11.924 11.924 0 002.685 1.087c.14-.088.614-.441 1.077-1.083a4.899 4.899 0 00.94-2.99 6.595 6.595 0 00-.49-2.37 6.717 6.717 0 00-1.302-2.033l-.002-.004-.124-.142c-.21-.245-.428-.497-.602-.792a4.104 4.104 0 01-.462-1.135 4.258 4.258 0 01-.024-1.85 4.25 4.25 0 01.686-1.564 4.216 4.216 0 013.432-1.773H12.042a4.202 4.202 0 013.432 1.773c.33.466.568 1.007.686 1.565a4.27 4.27 0 01-.023 1.849c-.093.39-.249.772-.463 1.135-.173.295-.391.547-.602.792l-.123.142-.004.004a6.736 6.736 0 00-1.301 2.033 6.607 6.607 0 00-.49 2.37 4.897 4.897 0 00.94 2.99c.463.642.937.995 1.076 1.083a11.776 11.776 0 002.687-1.087 3.399 3.399 0 01-1.789-2.988c0-.817.313-1.59.956-2.359.009-.012.02-.022.027-.03l.006-.004.184-.204c.183-.2.355-.39.51-.596a7.14 7.14 0 001.22-2.608 7.21 7.21 0 00.04-3.124 7.185 7.185 0 00-1.16-2.65 7.203 7.203 0 00-2.044-1.924 7.074 7.074 0 00-3.762-1.075h-.09zM12 9.97a2.365 2.365 0 00-2.362 2.361A2.364 2.364 0 0012 14.691c1.301 0 2.36-1.059 2.36-2.36A2.364 2.364 0 0012 9.968z"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

1
assets/icons/csharp.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><rect x="1.25" y="1.25" width="21.5" height="21.5" rx="5" fill="none" stroke="#9aa7bc" stroke-width="1.1"/><text x="12" y="12" fill="#9aa7bc" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="8.6" font-weight="600" letter-spacing=".2" text-anchor="middle" dominant-baseline="central">C#</text></svg>

After

Width:  |  Height:  |  Size: 402 B

1
assets/icons/docker.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#2496ed" d="M13.983 11.078h2.119a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.119a.185.185 0 00-.185.185v1.888c0 .102.083.185.185.185m-2.954-5.43h2.118a.186.186 0 00.186-.186V3.574a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m0 2.716h2.118a.187.187 0 00.186-.186V6.29a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.887c0 .102.082.185.185.186m-2.93 0h2.12a.186.186 0 00.184-.186V6.29a.185.185 0 00-.185-.185H8.1a.185.185 0 00-.185.185v1.887c0 .102.083.185.185.186m-2.964 0h2.119a.186.186 0 00.185-.186V6.29a.185.185 0 00-.185-.185H5.136a.186.186 0 00-.186.185v1.887c0 .102.084.185.186.186m5.893 2.715h2.118a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m-2.93 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.083.185.185.185m-2.964 0h2.119a.185.185 0 00.185-.185V9.006a.185.185 0 00-.184-.186h-2.12a.186.186 0 00-.186.186v1.887c0 .102.084.185.186.185m-2.92 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.082.185.185.185M23.763 9.89c-.065-.051-.672-.51-1.954-.51-.338.001-.676.03-1.01.087-.248-1.7-1.653-2.53-1.716-2.566l-.344-.199-.226.327c-.284.438-.49.922-.612 1.43-.23.97-.09 1.882.403 2.661-.595.332-1.55.413-1.744.42H.751a.751.751 0 00-.75.748 11.376 11.376 0 00.692 4.062c.545 1.428 1.355 2.48 2.41 3.124 1.18.723 3.1 1.137 5.275 1.137.983.003 1.963-.086 2.93-.266a12.248 12.248 0 003.823-1.389c.98-.567 1.86-1.288 2.61-2.136 1.252-1.418 1.998-2.997 2.553-4.4h.221c1.372 0 2.215-.549 2.68-1.009.309-.293.55-.65.707-1.046l.098-.288Z"/></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#1e6982" d="M13.394 0C8.683 0 4.609 2.716 2.644 6.667h15.641a4.77 4.77 0 0 0 3.073-1.11c.446-.375.864-.785 1.247-1.243l.001-.002A11.974 11.974 0 0 0 13.394 0zM1.804 8.889a12.009 12.009 0 0 0 0 6.222h14.7a3.111 3.111 0 1 0 0-6.222zm.84 8.444C4.61 21.283 8.684 24 13.395 24c3.701 0 7.011-1.677 9.212-4.312l-.001-.002a9.958 9.958 0 0 0-1.247-1.243 4.77 4.77 0 0 0-3.073-1.11z"/></svg>

After

Width:  |  Height:  |  Size: 474 B

1
assets/icons/git.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#f03c2e" d="M13.09 23.549a1.54 1.54 0 0 1-2.18 0L.451 13.089a1.54 1.54 0 0 1 0-2.179l7.191-7.19 2.733 2.733a1.85 1.85 0 0 0 .964 2.326v6.66a1.849 1.849 0 1 0 1.54 0V8.957l2.508 2.508a1.85 1.85 0 1 0 1.09-1.09l-2.634-2.634a1.85 1.85 0 0 0-2.378-2.377L8.73 2.63 10.91.451a1.54 1.54 0 0 1 2.179 0l10.459 10.46a1.54 1.54 0 0 1 0 2.179z"/></svg>

After

Width:  |  Height:  |  Size: 433 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#fc6d26" d="m23.6004 9.5927-.0337-.0862L20.3.9814a.851.851 0 0 0-.3362-.405.8748.8748 0 0 0-.9997.0539.8748.8748 0 0 0-.29.4399l-2.2055 6.748H7.5375l-2.2057-6.748a.8573.8573 0 0 0-.29-.4412.8748.8748 0 0 0-.9997-.0537.8585.8585 0 0 0-.3362.4049L.4332 9.5015l-.0325.0862a6.0657 6.0657 0 0 0 2.0119 7.0105l.0113.0087.03.0213 4.976 3.7264 2.462 1.8633 1.4995 1.1321a1.0085 1.0085 0 0 0 1.2197 0l1.4995-1.1321 2.4619-1.8633 5.006-3.7489.0125-.01a6.0682 6.0682 0 0 0 2.0094-7.003z"/></svg>

After

Width:  |  Height:  |  Size: 577 B

1
assets/icons/gitlab.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#fc6d26" d="m23.6004 9.5927-.0337-.0862L20.3.9814a.851.851 0 0 0-.3362-.405.8748.8748 0 0 0-.9997.0539.8748.8748 0 0 0-.29.4399l-2.2055 6.748H7.5375l-2.2057-6.748a.8573.8573 0 0 0-.29-.4412.8748.8748 0 0 0-.9997-.0537.8585.8585 0 0 0-.3362.4049L.4332 9.5015l-.0325.0862a6.0657 6.0657 0 0 0 2.0119 7.0105l.0113.0087.03.0213 4.976 3.7264 2.462 1.8633 1.4995 1.1321a1.0085 1.0085 0 0 0 1.2197 0l1.4995-1.1321 2.4619-1.8633 5.006-3.7489.0125-.01a6.0682 6.0682 0 0 0 2.0094-7.003z"/></svg>

After

Width:  |  Height:  |  Size: 577 B

1
assets/icons/gitops.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><rect x="1.25" y="1.25" width="21.5" height="21.5" rx="5" fill="none" stroke="#9aa7bc" stroke-width="1.1"/><text x="12" y="12" fill="#9aa7bc" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="8.6" font-weight="600" letter-spacing=".2" text-anchor="middle" dominant-baseline="central">GO</text></svg>

After

Width:  |  Height:  |  Size: 402 B

1
assets/icons/grafana.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#f46800" d="M23.02 10.59a8.578 8.578 0 0 0-.862-3.034 8.911 8.911 0 0 0-1.789-2.445c.337-1.342-.413-2.505-.413-2.505-1.292-.08-2.113.4-2.416.62-.052-.02-.102-.044-.154-.064-.22-.089-.446-.172-.677-.247-.231-.073-.47-.14-.711-.197a9.867 9.867 0 0 0-.875-.161C14.557.753 12.94 0 12.94 0c-1.804 1.145-2.147 2.744-2.147 2.744l-.018.093c-.098.029-.2.057-.298.088-.138.042-.275.094-.413.143-.138.055-.275.107-.41.166a8.869 8.869 0 0 0-1.557.87l-.063-.029c-2.497-.955-4.716.195-4.716.195-.203 2.658.996 4.33 1.235 4.636a11.608 11.608 0 0 0-.607 2.635C1.636 12.677.953 15.014.953 15.014c1.926 2.214 4.171 2.351 4.171 2.351.003-.002.006-.002.006-.005.285.509.615.994.986 1.446.156.19.32.371.488.548-.704 2.009.099 3.68.099 3.68 2.144.08 3.553-.937 3.849-1.173a9.784 9.784 0 0 0 3.164.501h.08l.055-.003.107-.002.103-.005.003.002c1.01 1.44 2.788 1.646 2.788 1.646 1.264-1.332 1.337-2.653 1.337-2.94v-.058c0-.02-.003-.039-.003-.06.265-.187.52-.387.758-.6a7.875 7.875 0 0 0 1.415-1.7c1.43.083 2.437-.885 2.437-.885-.236-1.49-1.085-2.216-1.264-2.354l-.018-.013-.016-.013a.217.217 0 0 1-.031-.02c.008-.092.016-.18.02-.27.011-.162.016-.323.016-.48v-.253l-.005-.098-.008-.135a1.891 1.891 0 0 0-.01-.13c-.003-.042-.008-.083-.013-.125l-.016-.124-.018-.122a6.215 6.215 0 0 0-2.032-3.73 6.015 6.015 0 0 0-3.222-1.46 6.292 6.292 0 0 0-.85-.048l-.107.002h-.063l-.044.003-.104.008a4.777 4.777 0 0 0-3.335 1.695c-.332.4-.592.84-.768 1.297a4.594 4.594 0 0 0-.312 1.817l.003.091c.005.055.007.11.013.164a3.615 3.615 0 0 0 .698 1.82 3.53 3.53 0 0 0 1.827 1.282c.33.098.66.14.971.137.039 0 .078 0 .114-.002l.063-.003c.02 0 .041-.003.062-.003.034-.002.065-.007.099-.01.007 0 .018-.003.028-.003l.031-.005.06-.008a1.18 1.18 0 0 0 .112-.02c.036-.008.072-.013.109-.024a2.634 2.634 0 0 0 .914-.415c.028-.02.056-.041.085-.065a.248.248 0 0 0 .039-.35.244.244 0 0 0-.309-.06l-.078.042c-.09.044-.184.083-.283.116a2.476 2.476 0 0 1-.475.096c-.028.003-.054.006-.083.006l-.083.002c-.026 0-.054 0-.08-.002l-.102-.006h-.012l-.024.006c-.016-.003-.031-.003-.044-.006-.031-.002-.06-.007-.091-.01a2.59 2.59 0 0 1-.724-.213 2.557 2.557 0 0 1-.667-.438 2.52 2.52 0 0 1-.805-1.475 2.306 2.306 0 0 1-.029-.444l.006-.122v-.023l.002-.031c.003-.021.003-.04.005-.06a3.163 3.163 0 0 1 1.352-2.29 3.12 3.12 0 0 1 .937-.43 2.946 2.946 0 0 1 .776-.101h.06l.07.002.045.003h.026l.07.005a4.041 4.041 0 0 1 1.635.49 3.94 3.94 0 0 1 1.602 1.662 3.77 3.77 0 0 1 .397 1.414l.005.076.003.075c.002.026.002.05.002.075 0 .024.003.052 0 .07v.065l-.002.073-.008.174a6.195 6.195 0 0 1-.08.639 5.1 5.1 0 0 1-.267.927 5.31 5.31 0 0 1-.624 1.13 5.052 5.052 0 0 1-3.237 2.014 4.82 4.82 0 0 1-.649.066l-.039.003h-.287a6.607 6.607 0 0 1-1.716-.265 6.776 6.776 0 0 1-3.4-2.274 6.75 6.75 0 0 1-.746-1.15 6.616 6.616 0 0 1-.714-2.596l-.005-.083-.002-.02v-.056l-.003-.073v-.096l-.003-.104v-.07l.003-.163c.008-.22.026-.45.054-.678a8.707 8.707 0 0 1 .28-1.355c.128-.444.286-.872.473-1.277a7.04 7.04 0 0 1 1.456-2.1 5.925 5.925 0 0 1 .953-.763c.169-.111.343-.213.524-.306.089-.05.182-.091.273-.135.047-.02.093-.042.138-.062a7.177 7.177 0 0 1 .714-.267l.145-.045c.049-.015.098-.026.148-.041.098-.029.197-.052.296-.076.049-.013.1-.02.15-.033l.15-.032.151-.028.076-.013.075-.01.153-.024c.057-.01.114-.013.171-.023l.169-.021c.036-.003.073-.008.106-.01l.073-.008.036-.003.042-.002c.057-.003.114-.008.171-.01l.086-.006h.023l.037-.003.145-.007a7.999 7.999 0 0 1 1.708.125 7.917 7.917 0 0 1 2.048.68 8.253 8.253 0 0 1 1.672 1.09l.09.077.089.078c.06.052.114.107.171.159.057.052.112.106.166.16.052.055.107.107.159.164a8.671 8.671 0 0 1 1.41 1.978c.012.026.028.052.04.078l.04.078.075.156c.023.051.05.1.07.153l.065.15a8.848 8.848 0 0 1 .45 1.34.19.19 0 0 0 .201.142.186.186 0 0 0 .172-.184c.01-.246.002-.532-.024-.856z"/></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

1
assets/icons/haproxy.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><rect x="1.25" y="1.25" width="21.5" height="21.5" rx="5" fill="none" stroke="#9aa7bc" stroke-width="1.1"/><text x="12" y="12" fill="#9aa7bc" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="8.6" font-weight="600" letter-spacing=".2" text-anchor="middle" dominant-baseline="central">HA</text></svg>

After

Width:  |  Height:  |  Size: 402 B

1
assets/icons/helm.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#6267b2" d="M12.337 0c-.475 0-.861 1.016-.861 2.269 0 .527.069 1.011.183 1.396a8.514 8.514 0 0 0-3.961 1.22 5.229 5.229 0 0 0-.595-1.093c-.606-.866-1.34-1.436-1.79-1.43a.381.381 0 0 0-.217.066c-.39.273-.123 1.326.596 2.353.267.381.559.705.84.948a8.683 8.683 0 0 0-1.528 1.716h1.734a7.179 7.179 0 0 1 5.381-2.421 7.18 7.18 0 0 1 5.382 2.42h1.733a8.687 8.687 0 0 0-1.32-1.53c.35-.249.735-.643 1.078-1.133.719-1.027.986-2.08.596-2.353a.382.382 0 0 0-.217-.065c-.45-.007-1.184.563-1.79 1.43a4.897 4.897 0 0 0-.676 1.325 8.52 8.52 0 0 0-3.899-1.42c.12-.39.193-.887.193-1.429 0-1.253-.386-2.269-.862-2.269zM1.624 9.443v5.162h1.358v-1.968h1.64v1.968h1.357V9.443H4.62v1.838H2.98V9.443zm5.912 0v5.162h3.21v-1.108H8.893v-.95h1.64v-1.142h-1.64v-.84h1.853V9.443zm4.698 0v5.162h3.218v-1.362h-1.86v-3.8zm4.706 0v5.162h1.364v-2.643l1.357 1.225 1.35-1.232v2.65h1.365V9.443h-.614l-2.1 1.914-2.109-1.914zm-11.82 7.28a8.688 8.688 0 0 0 1.412 1.548 5.206 5.206 0 0 0-.841.948c-.719 1.027-.985 2.08-.596 2.353.39.273 1.289-.338 2.007-1.364a5.23 5.23 0 0 0 .595-1.092 8.514 8.514 0 0 0 3.961 1.219 5.01 5.01 0 0 0-.183 1.396c0 1.253.386 2.269.861 2.269.476 0 .862-1.016.862-2.269 0-.542-.072-1.04-.193-1.43a8.52 8.52 0 0 0 3.9-1.42c.121.4.352.865.675 1.327.719 1.026 1.617 1.637 2.007 1.364.39-.273.123-1.326-.596-2.353-.343-.49-.727-.885-1.077-1.135a8.69 8.69 0 0 0 1.202-1.36h-1.771a7.174 7.174 0 0 1-5.227 2.252 7.174 7.174 0 0 1-5.226-2.252z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><rect x="1.25" y="1.25" width="21.5" height="21.5" rx="5" fill="none" stroke="#9aa7bc" stroke-width="1.1"/><text x="12" y="12" fill="#9aa7bc" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="8.6" font-weight="600" letter-spacing=".2" text-anchor="middle" dominant-baseline="central">KP</text></svg>

After

Width:  |  Height:  |  Size: 402 B

1
assets/icons/keras.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#d00000" d="M24 0H0v24h24V0zM8.45 5.16l.2.17v6.24l6.46-6.45h1.96l.2.4-5.14 5.1 5.47 7.94-.2.3h-1.94l-4.65-6.88-2.16 2.08v4.6l-.19.2H7l-.2-.2V5.33l.17-.17h1.48z"/></svg>

After

Width:  |  Height:  |  Size: 261 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#326ce5" d="M10.204 14.35l.007.01-.999 2.413a5.171 5.171 0 0 1-2.075-2.597l2.578-.437.004.005a.44.44 0 0 1 .484.606zm-.833-2.129a.44.44 0 0 0 .173-.756l.002-.011L7.585 9.7a5.143 5.143 0 0 0-.73 3.255l2.514-.725.002-.009zm1.145-1.98a.44.44 0 0 0 .699-.337l.01-.005.15-2.62a5.144 5.144 0 0 0-3.01 1.442l2.147 1.523.004-.002zm.76 2.75l.723.349.722-.347.18-.78-.5-.623h-.804l-.5.623.179.779zm1.5-3.095a.44.44 0 0 0 .7.336l.008.003 2.134-1.513a5.188 5.188 0 0 0-2.992-1.442l.148 2.615.002.001zm10.876 5.97l-5.773 7.181a1.6 1.6 0 0 1-1.248.594l-9.261.003a1.6 1.6 0 0 1-1.247-.596l-5.776-7.18a1.583 1.583 0 0 1-.307-1.34L2.1 5.573c.108-.47.425-.864.863-1.073L11.305.513a1.606 1.606 0 0 1 1.385 0l8.345 3.985c.438.209.755.604.863 1.073l2.062 8.955c.108.47-.005.963-.308 1.34zm-3.289-2.057c-.042-.01-.103-.026-.145-.034-.174-.033-.315-.025-.479-.038-.35-.037-.638-.067-.895-.148-.105-.04-.18-.165-.216-.216l-.201-.059a6.45 6.45 0 0 0-.105-2.332 6.465 6.465 0 0 0-.936-2.163c.052-.047.15-.133.177-.159.008-.09.001-.183.094-.282.197-.185.444-.338.743-.522.142-.084.273-.137.415-.242.032-.024.076-.062.11-.089.24-.191.295-.52.123-.736-.172-.216-.506-.236-.745-.045-.034.027-.08.062-.111.088-.134.116-.217.23-.33.35-.246.25-.45.458-.673.609-.097.056-.239.037-.303.033l-.19.135a6.545 6.545 0 0 0-4.146-2.003l-.012-.223c-.065-.062-.143-.115-.163-.25-.022-.268.015-.557.057-.905.023-.163.061-.298.068-.475.001-.04-.001-.099-.001-.142 0-.306-.224-.555-.5-.555-.275 0-.499.249-.499.555l.001.014c0 .041-.002.092 0 .128.006.177.044.312.067.475.042.348.078.637.056.906a.545.545 0 0 1-.162.258l-.012.211a6.424 6.424 0 0 0-4.166 2.003 8.373 8.373 0 0 1-.18-.128c-.09.012-.18.04-.297-.029-.223-.15-.427-.358-.673-.608-.113-.12-.195-.234-.329-.349-.03-.026-.077-.062-.111-.088a.594.594 0 0 0-.348-.132.481.481 0 0 0-.398.176c-.172.216-.117.546.123.737l.007.005.104.083c.142.105.272.159.414.242.299.185.546.338.743.522.076.082.09.226.1.288l.16.143a6.462 6.462 0 0 0-1.02 4.506l-.208.06c-.055.072-.133.184-.215.217-.257.081-.546.11-.895.147-.164.014-.305.006-.48.039-.037.007-.09.02-.133.03l-.004.002-.007.002c-.295.071-.484.342-.423.608.061.267.349.429.645.365l.007-.001.01-.003.129-.029c.17-.046.294-.113.448-.172.33-.118.604-.217.87-.256.112-.009.23.069.288.101l.217-.037a6.5 6.5 0 0 0 2.88 3.596l-.09.218c.033.084.069.199.044.282-.097.252-.263.517-.452.813-.091.136-.185.242-.268.399-.02.037-.045.095-.064.134-.128.275-.034.591.213.71.248.12.556-.007.69-.282v-.002c.02-.039.046-.09.062-.127.07-.162.094-.301.144-.458.132-.332.205-.68.387-.897.05-.06.13-.082.215-.105l.113-.205a6.453 6.453 0 0 0 4.609.012l.106.192c.086.028.18.042.256.155.136.232.229.507.342.84.05.156.074.295.145.457.016.037.043.09.062.129.133.276.442.402.69.282.247-.118.341-.435.213-.71-.02-.039-.045-.096-.065-.134-.083-.156-.177-.261-.268-.398-.19-.296-.346-.541-.443-.793-.04-.13.007-.21.038-.294-.018-.022-.059-.144-.083-.202a6.499 6.499 0 0 0 2.88-3.622c.064.01.176.03.213.038.075-.05.144-.114.28-.104.266.039.54.138.87.256.154.06.277.128.448.173.036.01.088.019.13.028l.009.003.007.001c.297.064.584-.098.645-.365.06-.266-.128-.537-.423-.608zM16.4 9.701l-1.95 1.746v.005a.44.44 0 0 0 .173.757l.003.01 2.526.728a5.199 5.199 0 0 0-.108-1.674A5.208 5.208 0 0 0 16.4 9.7zm-4.013 5.325a.437.437 0 0 0-.404-.232.44.44 0 0 0-.372.233h-.002l-1.268 2.292a5.164 5.164 0 0 0 3.326.003l-1.27-2.296h-.01zm1.888-1.293a.44.44 0 0 0-.27.036.44.44 0 0 0-.214.572l-.003.004 1.01 2.438a5.15 5.15 0 0 0 2.081-2.615l-2.6-.44-.004.005z"/></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

1
assets/icons/linux.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 KiB

1
assets/icons/loki.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><rect x="1.25" y="1.25" width="21.5" height="21.5" rx="5" fill="none" stroke="#9aa7bc" stroke-width="1.1"/><text x="12" y="12" fill="#9aa7bc" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="8.6" font-weight="600" letter-spacing=".2" text-anchor="middle" dominant-baseline="central">LO</text></svg>

After

Width:  |  Height:  |  Size: 402 B

1
assets/icons/minio.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#c72e49" d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Zm-.9024 9.8652v2.9941l-4.1523 2.1484a13.9787 13.9787 0 0 1 2.7676-3.9277 14.1784 14.1784 0 0 1 1.3847-1.2148z"/></svg>

After

Width:  |  Height:  |  Size: 714 B

1
assets/icons/mssql.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><rect x="1.25" y="1.25" width="21.5" height="21.5" rx="5" fill="none" stroke="#9aa7bc" stroke-width="1.1"/><text x="12" y="12" fill="#9aa7bc" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="7.4" font-weight="600" letter-spacing=".2" text-anchor="middle" dominant-baseline="central">SQL</text></svg>

After

Width:  |  Height:  |  Size: 403 B

1
assets/icons/mysql.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#4479a1" d="M16.405 5.501c-.115 0-.193.014-.274.033v.013h.014c.054.104.146.18.214.273.054.107.1.214.154.32l.014-.015c.094-.066.14-.172.14-.333-.04-.047-.046-.094-.08-.14-.04-.067-.126-.1-.18-.153zM5.77 18.695h-.927a50.854 50.854 0 00-.27-4.41h-.008l-1.41 4.41H2.45l-1.4-4.41h-.01a72.892 72.892 0 00-.195 4.41H0c.055-1.966.192-3.81.41-5.53h1.15l1.335 4.064h.008l1.347-4.064h1.095c.242 2.015.384 3.86.428 5.53zm4.017-4.08c-.378 2.045-.876 3.533-1.492 4.46-.482.716-1.01 1.073-1.583 1.073-.153 0-.34-.046-.566-.138v-.494c.11.017.24.026.386.026.268 0 .483-.075.647-.222.197-.18.295-.382.295-.605 0-.155-.077-.47-.23-.944L6.23 14.615h.91l.727 2.36c.164.536.233.91.205 1.123.4-1.064.678-2.227.835-3.483zm12.325 4.08h-2.63v-5.53h.885v4.85h1.745zm-3.32.135l-1.016-.5c.09-.076.177-.158.255-.25.433-.506.648-1.258.648-2.253 0-1.83-.718-2.746-2.155-2.746-.704 0-1.254.232-1.65.697-.43.508-.646 1.256-.646 2.245 0 .972.19 1.686.574 2.14.35.41.877.615 1.583.615.264 0 .506-.033.725-.098l1.325.772.36-.622zM15.5 17.588c-.225-.36-.337-.94-.337-1.736 0-1.393.424-2.09 1.27-2.09.443 0 .77.167.977.5.224.362.336.936.336 1.723 0 1.404-.424 2.108-1.27 2.108-.445 0-.77-.167-.978-.5zm-1.658-.425c0 .47-.172.856-.516 1.156-.344.3-.803.45-1.384.45-.543 0-1.064-.172-1.573-.515l.237-.476c.438.22.833.328 1.19.328.332 0 .593-.073.783-.22a.754.754 0 00.3-.615c0-.33-.23-.61-.648-.845-.388-.213-1.163-.657-1.163-.657-.422-.307-.632-.636-.632-1.177 0-.45.157-.81.47-1.085.315-.278.72-.415 1.22-.415.512 0 .98.136 1.4.41l-.213.476a2.726 2.726 0 00-1.064-.23c-.283 0-.502.068-.654.206a.685.685 0 00-.248.524c0 .328.234.61.666.85.393.215 1.187.67 1.187.67.433.305.648.63.648 1.168zm9.382-5.852c-.535-.014-.95.04-1.297.188-.1.04-.26.04-.274.167.055.053.063.14.11.214.08.134.218.313.346.407.14.11.28.216.427.31.26.16.555.255.81.416.145.094.293.213.44.313.073.05.12.14.214.172v-.02c-.046-.06-.06-.147-.105-.214-.067-.067-.134-.127-.2-.193a3.223 3.223 0 00-.695-.675c-.214-.146-.682-.35-.77-.595l-.013-.014c.146-.013.32-.066.46-.106.227-.06.435-.047.67-.106.106-.027.213-.06.32-.094v-.06c-.12-.12-.21-.283-.334-.395a8.867 8.867 0 00-1.104-.823c-.21-.134-.476-.22-.697-.334-.08-.04-.214-.06-.26-.127-.12-.146-.19-.34-.275-.514a17.69 17.69 0 01-.547-1.163c-.12-.262-.193-.523-.34-.763-.69-1.137-1.437-1.826-2.586-2.5-.247-.14-.543-.2-.856-.274-.167-.008-.334-.02-.5-.027-.11-.047-.216-.174-.31-.235-.38-.24-1.364-.76-1.644-.072-.18.434.267.862.422 1.082.115.153.26.328.34.5.047.116.06.235.107.356.106.294.207.622.347.897.073.14.153.287.247.413.054.073.146.107.167.227-.094.136-.1.334-.154.5-.24.757-.146 1.693.194 2.25.107.166.362.534.703.393.3-.12.234-.5.32-.835.02-.08.007-.133.048-.187v.015c.094.188.188.367.274.555.206.328.566.668.867.895.16.12.287.328.487.402v-.02h-.015c-.043-.058-.1-.086-.154-.133a3.445 3.445 0 01-.35-.4 8.76 8.76 0 01-.747-1.218c-.11-.21-.202-.436-.29-.643-.04-.08-.04-.2-.107-.24-.1.146-.247.273-.32.453-.127.288-.14.642-.188 1.01-.027.007-.014 0-.027.014-.214-.052-.287-.274-.367-.46-.2-.475-.233-1.238-.06-1.785.047-.14.247-.582.167-.716-.042-.127-.174-.2-.247-.303a2.478 2.478 0 01-.24-.427c-.16-.374-.24-.788-.414-1.162-.08-.173-.22-.354-.334-.513-.127-.18-.267-.307-.368-.52-.033-.073-.08-.194-.027-.274.014-.054.042-.075.094-.09.088-.072.335.022.422.062.247.1.455.194.662.334.094.066.195.193.315.226h.14c.214.047.455.014.655.073.355.114.675.28.962.46a5.953 5.953 0 012.085 2.286c.08.154.115.295.188.455.14.33.313.663.455.982.14.315.275.636.476.897.1.14.502.213.682.286.133.06.34.115.46.188.23.14.454.3.67.454.11.076.443.243.463.378z"/></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

1
assets/icons/nexus.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><rect x="1.25" y="1.25" width="21.5" height="21.5" rx="5" fill="none" stroke="#9aa7bc" stroke-width="1.1"/><text x="12" y="12" fill="#9aa7bc" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="8.6" font-weight="600" letter-spacing=".2" text-anchor="middle" dominant-baseline="central">NX</text></svg>

After

Width:  |  Height:  |  Size: 402 B

1
assets/icons/nginx.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#009639" d="M12 0L1.605 6v12L12 24l10.395-6V6L12 0zm6 16.59c0 .705-.646 1.29-1.529 1.29-.631 0-1.351-.255-1.801-.81l-6-7.141v6.66c0 .721-.57 1.29-1.274 1.29H7.32c-.721 0-1.29-.6-1.29-1.29V7.41c0-.705.63-1.29 1.5-1.29.646 0 1.38.255 1.83.81l5.97 7.141V7.41c0-.721.6-1.29 1.29-1.29h.075c.72 0 1.29.6 1.29 1.29v9.18H18z"/></svg>

After

Width:  |  Height:  |  Size: 418 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#e6522c" d="M12 0C5.373 0 0 5.372 0 12c0 6.627 5.373 12 12 12s12-5.373 12-12c0-6.628-5.373-12-12-12zm0 22.46c-1.885 0-3.414-1.26-3.414-2.814h6.828c0 1.553-1.528 2.813-3.414 2.813zm5.64-3.745H6.36v-2.046h11.28v2.046zm-.04-3.098H6.391c-.037-.043-.075-.086-.111-.13-1.155-1.401-1.427-2.133-1.69-2.879-.005-.025 1.4.287 2.395.511 0 0 .513.119 1.262.255-.72-.843-1.147-1.915-1.147-3.01 0-2.406 1.845-4.508 1.18-6.207.648.053 1.34 1.367 1.387 3.422.689-.951.977-2.69.977-3.755 0-1.103.727-2.385 1.454-2.429-.648 1.069.168 1.984.894 4.256.272.854.237 2.29.447 3.201.07-1.892.395-4.652 1.595-5.605-.529 1.2.079 2.702.494 3.424.671 1.164 1.078 2.047 1.078 3.716a4.642 4.642 0 01-1.11 2.996c.792-.149 1.34-.283 1.34-.283l2.573-.502s-.374 1.538-1.81 3.019z"/></svg>

After

Width:  |  Height:  |  Size: 847 B

1
assets/icons/python.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#3776ab" d="M14.25.18l.9.2.73.26.59.3.45.32.34.34.25.34.16.33.1.3.04.26.02.2-.01.13V8.5l-.05.63-.13.55-.21.46-.26.38-.3.31-.33.25-.35.19-.35.14-.33.1-.3.07-.26.04-.21.02H8.77l-.69.05-.59.14-.5.22-.41.27-.33.32-.27.35-.2.36-.15.37-.1.35-.07.32-.04.27-.02.21v3.06H3.17l-.21-.03-.28-.07-.32-.12-.35-.18-.36-.26-.36-.36-.35-.46-.32-.59-.28-.73-.21-.88-.14-1.05-.05-1.23.06-1.22.16-1.04.24-.87.32-.71.36-.57.4-.44.42-.33.42-.24.4-.16.36-.1.32-.05.24-.01h.16l.06.01h8.16v-.83H6.18l-.01-2.75-.02-.37.05-.34.11-.31.17-.28.25-.26.31-.23.38-.2.44-.18.51-.15.58-.12.64-.1.71-.06.77-.04.84-.02 1.27.05zm-6.3 1.98l-.23.33-.08.41.08.41.23.34.33.22.41.09.41-.09.33-.22.23-.34.08-.41-.08-.41-.23-.33-.33-.22-.41-.09-.41.09zm13.09 3.95l.28.06.32.12.35.18.36.27.36.35.35.47.32.59.28.73.21.88.14 1.04.05 1.23-.06 1.23-.16 1.04-.24.86-.32.71-.36.57-.4.45-.42.33-.42.24-.4.16-.36.09-.32.05-.24.02-.16-.01h-8.22v.82h5.84l.01 2.76.02.36-.05.34-.11.31-.17.29-.25.25-.31.24-.38.2-.44.17-.51.15-.58.13-.64.09-.71.07-.77.04-.84.01-1.27-.04-1.07-.14-.9-.2-.73-.25-.59-.3-.45-.33-.34-.34-.25-.34-.16-.33-.1-.3-.04-.25-.02-.2.01-.13v-5.34l.05-.64.13-.54.21-.46.26-.38.3-.32.33-.24.35-.2.35-.14.33-.1.3-.06.26-.04.21-.02.13-.01h5.84l.69-.05.59-.14.5-.21.41-.28.33-.32.27-.35.2-.36.15-.36.1-.35.07-.32.04-.28.02-.21V6.07h2.09l.14.01zm-6.47 14.25l-.23.33-.08.41.08.41.23.33.33.23.41.08.41-.08.33-.23.23-.33.08-.41-.08-.41-.23-.33-.33-.23-.41-.08-.41.08z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

1
assets/icons/rancher.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#0075a8" d="M22.727 9.007a.713.713 0 01-.726.855h-1.542V8.798h.468a.883.883 0 00.875-.875v-.388c0-.477.12-.875.269-.875.139 0 .328.388.407.865l.249 1.482zm-3.49-1.253c.486 0 .874.388.894.885v4.555a.883.883 0 01-.875.875h-2.357a.883.883 0 01-.875-.875v-1.79a.871.871 0 00-.348.696v1.502c0 .477.397.875.875.875h1.531v2.327a.535.535 0 01-.537.538h-2.884a.535.535 0 01-.537-.538v-2.168a.535.535 0 00-.537-.537h-7.2a.535.535 0 00-.538.537v2.168a.535.535 0 01-.537.538H2.428a.535.535 0 01-.537-.538V10.58L.588 11.603c-.06.04-.14.04-.189-.02l-.368-.438a.135.135 0 01-.01-.159l1.91-2.914a.536.536 0 01.487-.318h10.165a.54.54 0 01.527.627l-.21 1.243a.54.54 0 00.528.626h2.039a.535.535 0 00.527-.437c-.13.04-.269.06-.418.06h-1.452c-.487 0-.815-.388-.736-.866l.249-1.482c.08-.477.258-.865.407-.865.15 0 .269.398.269.875v.229c.02-.01.05-.01.08-.01h4.843zm3.65-.537c0-.388.288-.557.556-.557.269 0 .557.17.557.557 0 .378-.288.547-.557.547-.268 0-.557-.17-.557-.547zm.984 0c0-.308-.2-.438-.418-.438-.219 0-.428.13-.428.438 0 .298.21.438.428.438.219-.01.418-.14.418-.438zm-.607-.279h.199c.1 0 .199.03.199.17 0 .08-.06.129-.13.149l.13.228h-.12l-.119-.218h-.05v.218h-.109v-.547zm.199.25c.05 0 .09-.03.09-.08 0-.06-.05-.07-.09-.07h-.1v.15h.1z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#844fba" d="M1.44 0v7.575l6.561 3.79V3.787zm21.12 4.227l-6.561 3.791v7.574l6.56-3.787zM8.72 4.23v7.575l6.561 3.787V8.018zm0 8.405v7.575L15.28 24v-7.578z"/></svg>

After

Width:  |  Height:  |  Size: 254 B

1
assets/icons/traefik.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#24a1c1" d="M12 1.19c1.088 0 2.056.768 2.056 1.714 0 .947-.921 1.715-2.056 1.715-.13 0-.3-.022-.509-.064a.685.685 0 0 0-.475.076l-7.37 4.195a.344.344 0 0 0 .001.597l7.99 4.49c.208.116.461.116.669 0l8.034-4.468a.343.343 0 0 0 .003-.598l-2.507-1.424a.683.683 0 0 0-.67-.003l-2.647 1.468a.234.234 0 0 0-.119.18l-.001.025c0 .946-.921 1.714-2.056 1.714s-2.056-.768-2.056-1.714c0-.947.921-1.715 2.056-1.715.042 0 .09.002.145.007l.087.008.096.013a.685.685 0 0 0 .425-.08l3.913-2.173c.3-.166.662-.171.965-.017l.04.023 5.465 3.104c.686.39.693 1.368.03 1.773l-.037.021-3.656 2.033a.343.343 0 0 0 .007.604l3.62 1.906c.72.378.736 1.402.03 1.804l-10.995 6.272a1.03 1.03 0 0 1-1.019 0L.526 16.43a1.03 1.03 0 0 1 .034-1.806l3.66-1.911a.343.343 0 0 0 .01-.603L.524 10.029a1.03 1.03 0 0 1-.041-1.77l.036-.021L9.618 3.06a.688.688 0 0 0 .308-.369l.011-.036c.32-.952 1.046-1.466 2.063-1.466Zm5.076 12.63-4.492 2.586-.041.022c-.306.158-.671.152-.973-.018l-4.478-2.527a.682.682 0 0 0-.65-.01L3.86 15.224a.343.343 0 0 0-.012.602l7.887 4.515c.21.12.467.121.677 0l7.956-4.547a.343.343 0 0 0-.01-.602l-2.623-1.384a.683.683 0 0 0-.659.012z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

1
assets/icons/vmware.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="#607078" d="M.5 10.1a.505.505 0 00-.197.048.497.497 0 00-.25.68l1.138 2.475c.179.38.38.592.721.592.342 0 .542-.22.72-.592l1.003-2.186a.144.144 0 01.144-.092.16.16 0 01.157.16v2.118a.535.535 0 101.066 0v-1.73a.531.531 0 01.566-.552.52.52 0 01.541.551v1.73a.531.531 0 00.53.593.539.539 0 00.535-.592v-1.73a.531.531 0 01.564-.552.52.52 0 01.543.551v1.73a.531.531 0 00.528.593.535.535 0 00.535-.592v-1.969a1.234 1.234 0 00-1.283-1.23 1.647 1.647 0 00-1.14.486 1.26 1.26 0 00-1.095-.483 1.807 1.807 0 00-1.074.483 1.287 1.287 0 00-.961-.483 1.177 1.177 0 00-1.158.786l-.729 1.716-.933-2.203.011-.004A.505.505 0 00.5 10.1zm18.43.06a.27.27 0 00-.266.274h.002v3.142a.27.27 0 10.535 0v-1.222c0-1.037.571-1.56 1.27-1.643a.266.266 0 00.238-.274.258.258 0 00-.266-.269 1.465 1.465 0 00-1.242.88v-.614a.266.266 0 00-.271-.274zm-6.735.008a.273.273 0 00-.25.217l-.912 2.627-.902-2.62a.28.28 0 00-.274-.22.266.266 0 00-.27.258.493.493 0 00.034.144l1.09 3.037.02-.007a.319.319 0 00.298.242.3.3 0 00.293-.242l.903-2.583.896 2.583a.3.3 0 00.293.242h.018a.319.319 0 00.293-.242l1.097-3.038a.512.512 0 00.033-.144.258.258 0 00-.265-.25.262.262 0 00-.258.209l-.918 2.63-.904-2.626a.285.285 0 00-.278-.217h-.025a.273.273 0 00-.012 0zm10.168.008a1.75 1.75 0 00-1.691 1.851 1.765 1.765 0 001.76 1.858l-.008.013a1.784 1.784 0 001.33-.539.228.228 0 00.082-.17.228.228 0 00-.379-.168 1.435 1.435 0 01-1.018.415 1.237 1.237 0 01-1.24-1.207h2.555a.247.247 0 00.246-.247c0-.945-.593-1.806-1.637-1.806zm-5.744.002a1.571 1.571 0 00-.158.006 2.384 2.384 0 00-1.078.205.22.22 0 00-.143.222.24.24 0 00.235.229.266.266 0 00.095-.024 1.822 1.822 0 01.834-.162c.691 0 1.07.334 1.07.979v.125a3.796 3.796 0 00-1.103-.15c-.892 0-1.52.4-1.52 1.16l-.003-.004c0 .736.671 1.117 1.34 1.117a1.575 1.575 0 001.298-.62v.343a.247.247 0 00.254.25.254.254 0 00.258-.262v-1.983a1.416 1.416 0 00-.379-1.046 1.571 1.571 0 00-1-.385zm5.719.43c.714 0 1.085.565 1.139 1.214h-2.278a1.222 1.222 0 011.139-1.215zm-5.885 1.382a3.75 3.75 0 011.057.153V12.49c0 .57-.539.973-1.2.973-.485 0-.904-.261-.904-.713 0-.467.375-.76 1.047-.76Z"/></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

1
assets/icons/zabbix.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><rect x="1.25" y="1.25" width="21.5" height="21.5" rx="5" fill="none" stroke="#9aa7bc" stroke-width="1.1"/><text x="12" y="12" fill="#9aa7bc" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="8.6" font-weight="600" letter-spacing=".2" text-anchor="middle" dominant-baseline="central">ZB</text></svg>

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
assets/img/cert-expert.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
assets/img/dashboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

BIN
assets/img/og.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
assets/img/pipeline.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

1197
assets/style.css Normal file

File diff suppressed because it is too large Load Diff

5
favicon.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Reza Yaghobi">
<rect width="64" height="64" rx="14" fill="#0a0d14"/>
<rect x="1" y="1" width="62" height="62" rx="13" fill="none" stroke="#232b3a"/>
<text x="32" y="33" fill="#6fe3b0" font-family="system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif" font-size="24" font-weight="700" letter-spacing="-1" text-anchor="middle" dominant-baseline="central">RY</text>
</svg>

After

Width:  |  Height:  |  Size: 479 B

BIN
images/Associate.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

BIN
images/dashboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

BIN
images/expert.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
images/pipline-green.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

BIN
images/professional.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

595
index.html Normal file
View File

@@ -0,0 +1,595 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Reza Yaghobi · Junior DevOps engineer</title>
<meta name="description" content="Reza Yaghobi is a junior DevOps engineer working with Docker, Kubernetes, GitLab CI/CD, Ansible, Prometheus and Grafana.">
<meta name="theme-color" content="#0a0d14">
<link rel="canonical" href="https://rezayaghobi.ir/">
<meta property="og:type" content="website">
<meta property="og:url" content="https://rezayaghobi.ir/">
<meta property="og:title" content="Reza Yaghobi · Junior DevOps engineer">
<meta property="og:description" content="Reza Yaghobi is a junior DevOps engineer working with Docker, Kubernetes, GitLab CI/CD, Ansible, Prometheus and Grafana.">
<meta property="og:image" content="/assets/img/og.png">
<meta property="og:image:alt" content="Reza Yaghobi — Junior DevOps engineer">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Reza Yaghobi · Junior DevOps engineer">
<meta name="twitter:description" content="Junior DevOps engineer working with Docker, Kubernetes, GitLab CI/CD, Ansible, Prometheus and Grafana.">
<meta name="twitter:image" content="/assets/img/og.png">
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<link rel="preload" href="assets/fonts/bricolage-grotesque-latin-wght-normal.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="assets/fonts/instrument-sans-latin-wght-normal.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="assets/brand.css">
<link rel="stylesheet" href="assets/style.css">
<script src="assets/boot.js"></script>
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<div class="progress" aria-hidden="true"></div>
<header class="site-header">
<div class="wrap site-header__inner">
<a class="brand" href="#main">Reza Yaghobi</a>
<nav class="site-nav" aria-label="Main">
<a href="#stack">Stack</a>
<a href="#certificates">Certificates</a>
<a href="#work">Work</a>
<a href="#contact">Contact</a>
</nav>
</div>
</header>
<main id="main">
<section class="hero" aria-labelledby="hero-title">
<div class="wrap">
<p class="hero__label">Junior DevOps engineer</p>
<h1 class="hero__title" id="hero-title">Reza Yaghobi</h1>
<p class="hero__lede">I build and run containerized infrastructure: Docker, Kubernetes, GitLab CI/CD, Ansible and full observability with Prometheus and Grafana.</p>
<div class="hero__actions">
<a class="action" href="mailto:rezay5639@gmail.com">
<span class="action__label">Email</span>
<span class="action__meta">rezay5639@gmail.com</span>
</a>
<a class="action" href="https://github.com/rezayaghobi-dev" rel="noopener noreferrer">
<span class="action__label">GitHub</span>
<span class="action__meta">rezayaghobi-dev</span>
</a>
<a class="action" href="https://t.me/Rezay5639" rel="noopener noreferrer">
<span class="action__label">Telegram</span>
<span class="action__meta">@Rezay5639</span>
</a>
</div>
</div>
</section>
<section class="section section--stack reveal" id="stack" aria-labelledby="stack-title">
<div class="wrap">
<div class="section__head">
<h2 class="section__title" id="stack-title">Stack</h2>
</div>
<h3 class="group-title">Platform</h3>
<ul class="tiles">
<li class="tile brand--docker">
<img class="tile__icon" src="assets/icons/docker.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Docker</span>
</li>
<li class="tile brand--kubernetes">
<img class="tile__icon" src="assets/icons/kubernetes.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Kubernetes</span>
</li>
<li class="tile brand--rancher">
<img class="tile__icon" src="assets/icons/rancher.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Rancher</span>
</li>
<li class="tile brand--helm">
<img class="tile__icon" src="assets/icons/helm.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Helm</span>
</li>
<li class="tile brand--linux">
<img class="tile__icon" src="assets/icons/linux.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Linux</span>
</li>
<li class="tile brand--vmware">
<img class="tile__icon" src="assets/icons/vmware.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">VMware ESXi<span class="tile__note">server virtualization</span></span>
</li>
<li class="tile brand--traefik">
<img class="tile__icon" src="assets/icons/traefik.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Traefik</span>
</li>
<li class="tile brand--nginx">
<img class="tile__icon" src="assets/icons/nginx.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">nginx</span>
</li>
<li class="tile brand--haproxy">
<img class="tile__icon" src="assets/icons/haproxy.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">HAProxy</span>
</li>
<li class="tile brand--keepalived">
<img class="tile__icon" src="assets/icons/keepalived.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Keepalived</span>
</li>
<li class="tile brand--minio">
<img class="tile__icon" src="assets/icons/minio.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">MinIO</span>
</li>
<li class="tile brand--ceph">
<img class="tile__icon" src="assets/icons/ceph.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Ceph</span>
</li>
</ul>
<h3 class="group-title">Automation and delivery</h3>
<ul class="tiles">
<li class="tile brand--gitlab">
<img class="tile__icon" src="assets/icons/gitlab.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">GitLab</span>
</li>
<li class="tile brand--gitlab-ci">
<img class="tile__icon" src="assets/icons/gitlab-ci.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">GitLab CI/CD</span>
</li>
<li class="tile brand--git">
<img class="tile__icon" src="assets/icons/git.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Git</span>
</li>
<li class="tile brand--ansible">
<img class="tile__icon" src="assets/icons/ansible.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Ansible</span>
</li>
<li class="tile brand--terraform">
<img class="tile__icon" src="assets/icons/terraform.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Terraform</span>
</li>
<li class="tile brand--argocd">
<img class="tile__icon" src="assets/icons/argocd.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Argo CD</span>
</li>
<li class="tile brand--gitops">
<img class="tile__icon" src="assets/icons/gitops.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">GitOps</span>
</li>
<li class="tile brand--nexus">
<img class="tile__icon" src="assets/icons/nexus.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Nexus Repository</span>
</li>
<li class="tile brand--bash">
<img class="tile__icon" src="assets/icons/bash.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Shell scripting<span class="tile__note">Bash</span></span>
</li>
</ul>
<h3 class="group-title">Observability</h3>
<ul class="tiles">
<li class="tile brand--prometheus">
<img class="tile__icon" src="assets/icons/prometheus.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Prometheus</span>
</li>
<li class="tile brand--grafana">
<img class="tile__icon" src="assets/icons/grafana.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Grafana</span>
</li>
<li class="tile brand--loki">
<img class="tile__icon" src="assets/icons/loki.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Loki</span>
</li>
<li class="tile brand--alloy">
<img class="tile__icon" src="assets/icons/alloy.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Alloy</span>
</li>
<li class="tile brand--elasticsearch">
<img class="tile__icon" src="assets/icons/elasticsearch.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Elasticsearch</span>
</li>
<li class="tile brand--zabbix">
<img class="tile__icon" src="assets/icons/zabbix.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Zabbix</span>
</li>
</ul>
<h3 class="group-title">Languages and data</h3>
<ul class="tiles">
<li class="tile brand--python">
<img class="tile__icon" src="assets/icons/python.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Python</span>
</li>
<li class="tile brand--csharp">
<img class="tile__icon" src="assets/icons/csharp.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">C#</span>
</li>
<li class="tile brand--postgresql">
<img class="tile__icon" src="assets/icons/postgresql.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">PostgreSQL</span>
</li>
<li class="tile brand--mysql">
<img class="tile__icon" src="assets/icons/mysql.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">MySQL</span>
</li>
<li class="tile brand--mssql">
<img class="tile__icon" src="assets/icons/mssql.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Microsoft SQL Server</span>
</li>
<li class="tile brand--keras">
<img class="tile__icon" src="assets/icons/keras.svg" alt="" width="38" height="38" decoding="async" aria-hidden="true">
<span class="tile__name">Keras<span class="tile__note">for ML/DL</span></span>
</li>
</ul>
<h3 class="group-title">Networking and Windows</h3>
<ul class="chips">
<li class="chip">Routing</li>
<li class="chip">DNS administration</li>
<li class="chip">Active Directory</li>
<li class="chip">Windows Server</li>
<li class="chip">Network+ knowledge</li>
</ul>
</div>
</section>
<section class="section section--certs reveal" id="certificates" aria-labelledby="certs-title">
<div class="wrap">
<div class="section__head">
<h2 class="section__title" id="certs-title">Certificates</h2>
</div>
<p class="cert-ielts">IELTS · Band 7.0 · 2024</p>
<ol class="ladder" aria-label="ArvanCloud DevOps track">
<li class="cert-step">
<span class="cert-step__num">01</span>
<h3 class="cert-step__name">Associate DevOps Engineer</h3>
<p class="cert-step__meta">22 h · 2026</p>
<p class="cert-step__issuer">ArvanCloud</p>
</li>
<li class="cert-step">
<span class="cert-step__num">02</span>
<h3 class="cert-step__name">Professional DevOps Engineer</h3>
<p class="cert-step__meta">100 h · 2026</p>
<p class="cert-step__issuer">ArvanCloud</p>
</li>
<li class="cert-step">
<span class="cert-step__num">03</span>
<h3 class="cert-step__name">Expert DevOps Engineer</h3>
<p class="cert-step__meta">18 h · 2026</p>
<p class="cert-step__issuer">ArvanCloud</p>
</li>
</ol>
<div class="certs-block">
<h3 class="group-title">Completed courses</h3>
<p class="group-sub">Course only, no certificate issued</p>
<ul class="courses">
<li class="course">
<span class="course__name">LPIC-1</span>
<span class="course__meta">26 h · 2024</span>
</li>
<li class="course">
<span class="course__name">Network+</span>
<span class="course__meta">72 h · 2024</span>
</li>
<li class="course">
<span class="course__name">LPIC-2</span>
</li>
</ul>
</div>
</div>
</section>
<section class="section reveal" id="certificate-images" aria-labelledby="cert-images-title">
<div class="wrap">
<div class="section__head">
<h2 class="section__title" id="cert-images-title">ArvanCloud certificates</h2>
</div>
<ul class="cert-gallery">
<li class="cert-shot">
<a class="cert-shot__frame" href="assets/img/cert-associate.webp" target="_blank" rel="noopener">
<img src="assets/img/cert-associate.webp" width="1000" height="707" alt="ArvanCloud Associate DevOps Engineer certificate" loading="lazy" decoding="async">
</a>
<p class="cert-shot__caption">Associate DevOps Engineer</p>
</li>
<li class="cert-shot">
<a class="cert-shot__frame" href="assets/img/cert-professional.webp" target="_blank" rel="noopener">
<img src="assets/img/cert-professional.webp" width="1000" height="703" alt="ArvanCloud Professional DevOps Engineer certificate" loading="lazy" decoding="async">
</a>
<p class="cert-shot__caption">Professional DevOps Engineer</p>
</li>
<li class="cert-shot">
<a class="cert-shot__frame" href="assets/img/cert-expert.webp" target="_blank" rel="noopener">
<img src="assets/img/cert-expert.webp" width="1000" height="706" alt="ArvanCloud Expert DevOps Engineer certificate" loading="lazy" decoding="async">
</a>
<p class="cert-shot__caption">Expert DevOps Engineer</p>
</li>
</ul>
</div>
</section>
<section class="section reveal" id="work" aria-labelledby="work-title">
<div class="wrap">
<div class="section__head">
<h2 class="section__title" id="work-title">Selected work</h2>
</div>
<ul class="work-list">
<li class="work-row">
<h3 class="work-row__title">Homelab</h3>
<p class="work-row__text">Self-hosted Docker and K3s services behind Traefik, with a Prometheus, Grafana and Loki monitoring stack and CI/CD.</p>
<a class="work-row__link" href="https://github.com/rezayaghobi-dev/homelab" rel="noopener noreferrer">View on GitHub ↗</a>
</li>
<li class="work-row">
<h3 class="work-row__title">devops-test</h3>
<p class="work-row__text">A DevOps assessment task for a company, covering a 6-stage GitLab CI/CD pipeline, firewalling with iptables, monitoring and a web app.</p>
<a class="work-row__link" href="https://github.com/rezayaghobi-dev/devops-test" rel="noopener noreferrer">View on GitHub ↗</a>
</li>
</ul>
<p class="work-more">Also on GitHub: <a href="https://github.com/rezayaghobi-dev/agents" rel="noopener noreferrer">agents</a> · <a href="https://github.com/rezayaghobi-dev/ML-portfolio" rel="noopener noreferrer">ML portfolio</a> · <a href="https://github.com/rezayaghobi-dev/DL-portfolio" rel="noopener noreferrer">DL portfolio</a></p>
</div>
</section>
<section class="section reveal" id="diagrams" aria-labelledby="diagrams-title">
<div class="wrap">
<div class="section__head">
<h2 class="section__title" id="diagrams-title">Diagrams</h2>
</div>
<div class="diagram-block">
<div class="diagram">
<h3 class="diagram__title">Homelab architecture</h3>
<svg class="diagram--wide" viewBox="0 0 1000 320" role="img" aria-labelledby="hl-w-title hl-w-desc">
<title id="hl-w-title">Homelab architecture</title>
<desc id="hl-w-desc">Internet traffic reaches Traefik, which proxies to Docker and K3s workloads. A monitoring group runs Prometheus, Grafana, Loki and Alloy, and GitLab CI/CD deploys the workloads.</desc>
<defs>
<marker id="arrow-hl-w" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="6" markerHeight="6" orient="auto">
<path d="M0 0 L8 4 L0 8 Z" fill="#6fe3b0"/>
</marker>
</defs>
<path class="dg-line dg-soft draw" pathLength="1" d="M636 84 H552" marker-end="url(#arrow-hl-w)"/>
<path class="dg-line dg-soft draw d2" pathLength="1" d="M636 228 H552" marker-end="url(#arrow-hl-w)"/>
<path class="dg-line draw" pathLength="1" d="M142 160 H190" marker-end="url(#arrow-hl-w)"/>
<path class="dg-line draw d2" pathLength="1" d="M344 154 C370 154 380 84 402 84" marker-end="url(#arrow-hl-w)"/>
<path class="dg-line draw d3" pathLength="1" d="M344 166 C370 166 380 228 402 228" marker-end="url(#arrow-hl-w)"/>
<rect class="dg-box" x="24" y="136" width="118" height="48" rx="7"/>
<text class="dg-text" x="83" y="160" text-anchor="middle" dominant-baseline="middle">Internet</text>
<rect class="dg-box dg-box--accent" x="196" y="136" width="148" height="48" rx="7"/>
<text class="dg-text" x="270" y="154" text-anchor="middle" dominant-baseline="middle">Traefik</text>
<text class="dg-sub" x="270" y="171" text-anchor="middle" dominant-baseline="middle">reverse proxy</text>
<rect class="dg-box" x="408" y="60" width="138" height="48" rx="7"/>
<text class="dg-text" x="477" y="78" text-anchor="middle" dominant-baseline="middle">Docker</text>
<text class="dg-sub" x="477" y="95" text-anchor="middle" dominant-baseline="middle">containers</text>
<rect class="dg-box" x="408" y="204" width="138" height="48" rx="7"/>
<text class="dg-text" x="477" y="222" text-anchor="middle" dominant-baseline="middle">K3s</text>
<text class="dg-sub" x="477" y="239" text-anchor="middle" dominant-baseline="middle">cluster</text>
<rect class="dg-box" x="640" y="36" width="336" height="116" rx="8"/>
<text class="dg-sub" x="660" y="58" dominant-baseline="middle">MONITORING</text>
<circle class="dg-node" cx="661" cy="86" r="2.5"/>
<text class="dg-text" x="674" y="87" dominant-baseline="middle">Prometheus</text>
<circle class="dg-node" cx="831" cy="86" r="2.5"/>
<text class="dg-text" x="844" y="87" dominant-baseline="middle">Grafana</text>
<circle class="dg-node" cx="661" cy="118" r="2.5"/>
<text class="dg-text" x="674" y="119" dominant-baseline="middle">Loki</text>
<circle class="dg-node" cx="831" cy="118" r="2.5"/>
<text class="dg-text" x="844" y="119" dominant-baseline="middle">Alloy</text>
<rect class="dg-box" x="640" y="196" width="336" height="94" rx="8"/>
<text class="dg-text" x="660" y="228" dominant-baseline="middle">GitLab · CI/CD</text>
<text class="dg-sub" x="660" y="250" dominant-baseline="middle">BUILD · TEST · DEPLOY</text>
<text class="dg-sub" x="594" y="74" text-anchor="middle">METRICS · LOGS</text>
<text class="dg-sub" x="594" y="246" text-anchor="middle">DEPLOY</text>
</svg>
<svg class="diagram--narrow" viewBox="0 0 340 560" role="img" aria-labelledby="hl-n-title hl-n-desc">
<title id="hl-n-title">Homelab architecture</title>
<desc id="hl-n-desc">Internet traffic reaches Traefik, which proxies to Docker and K3s workloads. A monitoring group runs Prometheus, Grafana, Loki and Alloy, and GitLab CI/CD deploys the workloads.</desc>
<defs>
<marker id="arrow-hl-n" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="6" markerHeight="6" orient="auto">
<path d="M0 0 L8 4 L0 8 Z" fill="#6fe3b0"/>
</marker>
</defs>
<path class="dg-line draw" pathLength="1" d="M170 58 V88" marker-end="url(#arrow-hl-n)"/>
<path class="dg-line draw d2" pathLength="1" d="M170 140 V156 H94 V176" marker-end="url(#arrow-hl-n)"/>
<path class="dg-line draw d2" pathLength="1" d="M170 156 H248 V176" marker-end="url(#arrow-hl-n)"/>
<path class="dg-line dg-soft draw d3" pathLength="1" d="M94 276 V234" marker-end="url(#arrow-hl-n)"/>
<path class="dg-line dg-soft draw d3" pathLength="1" d="M248 276 V234" marker-end="url(#arrow-hl-n)"/>
<path class="dg-line dg-soft draw d4" pathLength="1" d="M316 472 H330 V205 H320" marker-end="url(#arrow-hl-n)"/>
<rect class="dg-box" x="95" y="16" width="150" height="42" rx="7"/>
<text class="dg-text" x="170" y="37" text-anchor="middle" dominant-baseline="middle">Internet</text>
<rect class="dg-box dg-box--accent" x="90" y="94" width="160" height="46" rx="7"/>
<text class="dg-text" x="170" y="111" text-anchor="middle" dominant-baseline="middle">Traefik</text>
<text class="dg-sub" x="170" y="127" text-anchor="middle" dominant-baseline="middle">reverse proxy</text>
<rect class="dg-box" x="24" y="182" width="140" height="46" rx="7"/>
<text class="dg-text" x="94" y="205" text-anchor="middle" dominant-baseline="middle">Docker</text>
<rect class="dg-box" x="180" y="182" width="136" height="46" rx="7"/>
<text class="dg-text" x="248" y="205" text-anchor="middle" dominant-baseline="middle">K3s</text>
<rect class="dg-box" x="24" y="276" width="292" height="100" rx="8"/>
<text class="dg-sub" x="40" y="298" dominant-baseline="middle">MONITORING</text>
<circle class="dg-node" cx="41" cy="326" r="2.5"/>
<text class="dg-text" x="54" y="327" dominant-baseline="middle">Prometheus</text>
<circle class="dg-node" cx="181" cy="326" r="2.5"/>
<text class="dg-text" x="194" y="327" dominant-baseline="middle">Grafana</text>
<circle class="dg-node" cx="41" cy="352" r="2.5"/>
<text class="dg-text" x="54" y="353" dominant-baseline="middle">Loki</text>
<circle class="dg-node" cx="181" cy="352" r="2.5"/>
<text class="dg-text" x="194" y="353" dominant-baseline="middle">Alloy</text>
<rect class="dg-box" x="24" y="424" width="292" height="96" rx="8"/>
<text class="dg-text" x="40" y="452" dominant-baseline="middle">GitLab · CI/CD</text>
<text class="dg-sub" x="40" y="474" dominant-baseline="middle">BUILD · TEST · DEPLOY</text>
<text class="dg-sub" x="40" y="496" dominant-baseline="middle">DEPLOY TO WORKLOADS</text>
</svg>
</div>
<figure class="shot">
<div class="shot__frame">
<img src="assets/img/dashboard-1200.webp" width="1200" height="568" alt="Grafana dashboard showing a metrics graph" loading="lazy" decoding="async">
</div>
<figcaption>Grafana dashboard</figcaption>
</figure>
</div>
<div class="diagram-block">
<div class="diagram">
<h3 class="diagram__title">CI/CD pipeline</h3>
<svg class="diagram--wide" viewBox="0 0 1000 220" role="img" aria-labelledby="ci-w-title ci-w-desc">
<title id="ci-w-title">CI/CD pipeline</title>
<desc id="ci-w-desc">A commit is pushed, then the pipeline runs the test, build, publish and deploy stages in order, and ends with a healthy container.</desc>
<defs>
<marker id="arrow-ci-w" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="6" markerHeight="6" orient="auto">
<path d="M0 0 L8 4 L0 8 Z" fill="#6fe3b0"/>
</marker>
</defs>
<path class="dg-line draw" pathLength="1" d="M116 118 H146" marker-end="url(#arrow-ci-w)"/>
<path class="dg-line draw d2" pathLength="1" d="M292 118 H322" marker-end="url(#arrow-ci-w)"/>
<path class="dg-line draw d3" pathLength="1" d="M468 118 H498" marker-end="url(#arrow-ci-w)"/>
<path class="dg-line draw d4" pathLength="1" d="M644 118 H674" marker-end="url(#arrow-ci-w)"/>
<path class="dg-line draw d5" pathLength="1" d="M820 118 H850" marker-end="url(#arrow-ci-w)"/>
<rect class="dg-box" x="20" y="98" width="96" height="40" rx="7"/>
<text class="dg-text" x="68" y="119" text-anchor="middle" dominant-baseline="middle">git push</text>
<rect class="dg-box" x="152" y="80" width="140" height="76" rx="8"/>
<text class="dg-sub" x="278" y="98" text-anchor="end">01</text>
<text class="dg-text" x="222" y="112" text-anchor="middle" dominant-baseline="middle">Test</text>
<text class="dg-sub" x="222" y="132" text-anchor="middle" dominant-baseline="middle">pytest</text>
<rect class="dg-box" x="328" y="80" width="140" height="76" rx="8"/>
<text class="dg-sub" x="454" y="98" text-anchor="end">02</text>
<text class="dg-text" x="398" y="112" text-anchor="middle" dominant-baseline="middle">Build</text>
<text class="dg-sub" x="398" y="132" text-anchor="middle" dominant-baseline="middle">docker image</text>
<rect class="dg-box" x="504" y="80" width="140" height="76" rx="8"/>
<text class="dg-sub" x="630" y="98" text-anchor="end">03</text>
<text class="dg-text" x="574" y="112" text-anchor="middle" dominant-baseline="middle">Publish</text>
<text class="dg-sub" x="574" y="132" text-anchor="middle" dominant-baseline="middle">optional</text>
<rect class="dg-box" x="680" y="80" width="140" height="76" rx="8"/>
<text class="dg-sub" x="806" y="98" text-anchor="end">04</text>
<text class="dg-text" x="750" y="112" text-anchor="middle" dominant-baseline="middle">Deploy</text>
<text class="dg-sub" x="750" y="132" text-anchor="middle" dominant-baseline="middle">compose</text>
<rect class="dg-box dg-box--accent" x="856" y="98" width="120" height="40" rx="7"/>
<text class="dg-text" x="916" y="119" text-anchor="middle" dominant-baseline="middle">healthy</text>
</svg>
<svg class="diagram--narrow" viewBox="0 0 340 520" role="img" aria-labelledby="ci-n-title ci-n-desc">
<title id="ci-n-title">CI/CD pipeline</title>
<desc id="ci-n-desc">A commit is pushed, then the pipeline runs the test, build, publish and deploy stages in order, and ends with a healthy container.</desc>
<defs>
<marker id="arrow-ci-n" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="6" markerHeight="6" orient="auto">
<path d="M0 0 L8 4 L0 8 Z" fill="#6fe3b0"/>
</marker>
</defs>
<path class="dg-line draw" pathLength="1" d="M170 56 V84" marker-end="url(#arrow-ci-n)"/>
<path class="dg-line draw d2" pathLength="1" d="M170 154 V178" marker-end="url(#arrow-ci-n)"/>
<path class="dg-line draw d3" pathLength="1" d="M170 248 V272" marker-end="url(#arrow-ci-n)"/>
<path class="dg-line draw d4" pathLength="1" d="M170 342 V366" marker-end="url(#arrow-ci-n)"/>
<path class="dg-line draw d5" pathLength="1" d="M170 436 V460" marker-end="url(#arrow-ci-n)"/>
<rect class="dg-box" x="110" y="16" width="120" height="40" rx="7"/>
<text class="dg-text" x="170" y="37" text-anchor="middle" dominant-baseline="middle">git push</text>
<rect class="dg-box" x="50" y="90" width="240" height="64" rx="8"/>
<text class="dg-sub" x="276" y="108" text-anchor="end">01</text>
<text class="dg-text" x="170" y="116" text-anchor="middle" dominant-baseline="middle">Test</text>
<text class="dg-sub" x="170" y="137" text-anchor="middle" dominant-baseline="middle">pytest</text>
<rect class="dg-box" x="50" y="184" width="240" height="64" rx="8"/>
<text class="dg-sub" x="276" y="202" text-anchor="end">02</text>
<text class="dg-text" x="170" y="210" text-anchor="middle" dominant-baseline="middle">Build</text>
<text class="dg-sub" x="170" y="231" text-anchor="middle" dominant-baseline="middle">docker image</text>
<rect class="dg-box" x="50" y="278" width="240" height="64" rx="8"/>
<text class="dg-sub" x="276" y="296" text-anchor="end">03</text>
<text class="dg-text" x="170" y="304" text-anchor="middle" dominant-baseline="middle">Publish</text>
<text class="dg-sub" x="170" y="325" text-anchor="middle" dominant-baseline="middle">optional</text>
<rect class="dg-box" x="50" y="372" width="240" height="64" rx="8"/>
<text class="dg-sub" x="276" y="390" text-anchor="end">04</text>
<text class="dg-text" x="170" y="398" text-anchor="middle" dominant-baseline="middle">Deploy</text>
<text class="dg-sub" x="170" y="419" text-anchor="middle" dominant-baseline="middle">compose</text>
<rect class="dg-box dg-box--accent" x="100" y="460" width="140" height="40" rx="7"/>
<text class="dg-text" x="170" y="481" text-anchor="middle" dominant-baseline="middle">healthy</text>
</svg>
</div>
<figure class="shot">
<div class="shot__frame">
<img src="assets/img/pipeline-1200.webp" width="1200" height="575" alt="Green GitLab CI pipeline, all stages passed" loading="lazy" decoding="async">
</div>
<figcaption>GitLab CI pipeline</figcaption>
</figure>
</div>
</div>
</section>
<section class="section reveal" id="background" aria-labelledby="background-title">
<div class="wrap">
<div class="section__head">
<h2 class="section__title" id="background-title">Background</h2>
</div>
<ol class="timeline">
<li class="timeline__item">
<span class="timeline__when">2025 to present</span>
<p class="timeline__what">Bachelor's degree in Computer Networks, Shamsipoor, currently term 3</p>
</li>
<li class="timeline__item">
<span class="timeline__when">March to June 2026</span>
<p class="timeline__what">IT Help Desk, Jahad Sharif University</p>
</li>
</ol>
</div>
</section>
<section class="section reveal" id="contact" aria-labelledby="contact-title">
<div class="wrap">
<div class="section__head">
<h2 class="section__title" id="contact-title">Contact</h2>
</div>
<p class="contact__lede">Open to junior and associate DevOps roles, on-site or remote.</p>
<div class="contact-rows">
<a class="contact-row" href="mailto:rezay5639@gmail.com">
<span class="contact-row__label">Email</span>
<span class="contact-row__value">rezay5639@gmail.com <span class="contact-row__arrow" aria-hidden="true">→</span></span>
</a>
<a class="contact-row" href="https://github.com/rezayaghobi-dev" rel="noopener noreferrer">
<span class="contact-row__label">GitHub</span>
<span class="contact-row__value">rezayaghobi-dev <span class="contact-row__arrow" aria-hidden="true">→</span></span>
</a>
<a class="contact-row" href="https://t.me/Rezay5639" rel="noopener noreferrer">
<span class="contact-row__label">Telegram</span>
<span class="contact-row__value">@Rezay5639 <span class="contact-row__arrow" aria-hidden="true">→</span></span>
</a>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="wrap">© 2026 Reza Yaghobi · Hosted on my own homelab</div>
</footer>
<script src="assets/app.js" defer></script>
</body>
</html>

2
robots.txt Normal file
View File

@@ -0,0 +1,2 @@
User-agent: *
Allow: /

146
tools/build-icons.mjs Normal file
View File

@@ -0,0 +1,146 @@
#!/usr/bin/env node
/**
* Regenerates assets/icons/*.svg and assets/brand.css from simple-icons.
*
* Setup (outside this project):
* mkdir -p /tmp/ry-scratch && cd /tmp/ry-scratch
* npm init -y && npm install simple-icons
*
* Run from the project root:
* node tools/build-icons.mjs
* SIMPLE_ICONS_DIR=/path/to/node_modules/simple-icons node tools/build-icons.mjs
*
* Brand colours below 3:1 contrast against the page background are lightened
* (blended towards white) until they reach 3:1, so every icon stays legible.
* Tools absent from simple-icons get a neutral monogram instead of a copied logo.
*/
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const siDir =
process.env.SIMPLE_ICONS_DIR ||
"/tmp/ry-scratch/node_modules/simple-icons";
const outIcons = path.join(root, "assets", "icons");
const outBrandCss = path.join(root, "assets", "brand.css");
const BG = "#0a0d14";
const icons = [
// group, file, simple-icons slug, display name
["platform", "docker", "docker", "Docker"],
["platform", "kubernetes", "kubernetes", "Kubernetes"],
["platform", "rancher", "rancher", "Rancher"],
["platform", "helm", "helm", "Helm"],
["platform", "linux", "linux", "Linux"],
["platform", "vmware", "vmware", "VMware ESXi"],
["platform", "traefik", "traefikproxy", "Traefik"],
["platform", "nginx", "nginx", "nginx"],
["platform", "minio", "minio", "MinIO"],
["platform", "ceph", "ceph", "Ceph"],
["automation", "gitlab", "gitlab", "GitLab"],
["automation", "gitlab-ci", "gitlab", "GitLab CI/CD"],
["automation", "git", "git", "Git"],
["automation", "ansible", "ansible", "Ansible"],
["automation", "terraform", "terraform", "Terraform"],
["automation", "bash", "gnubash", "Shell scripting (Bash)"],
["observability", "prometheus", "prometheus", "Prometheus"],
["observability", "grafana", "grafana", "Grafana"],
["observability", "elasticsearch", "elasticsearch", "Elasticsearch"],
["data", "python", "python", "Python"],
["data", "postgresql", "postgresql", "PostgreSQL"],
["data", "mysql", "mysql", "MySQL"],
["data", "keras", "keras", "Keras (for ML/DL)"],
];
const monograms = [
["platform", "haproxy", "HA", "HAProxy"],
["platform", "keepalived", "KP", "Keepalived"],
["automation", "argocd", "AC", "Argo CD"],
["automation", "gitops", "GO", "GitOps"],
["automation", "nexus", "NX", "Nexus Repository"],
["observability", "loki", "LO", "Loki"],
["observability", "alloy", "AL", "Alloy"],
["observability", "zabbix", "ZB", "Zabbix"],
["data", "csharp", "C#", "C#"],
["data", "mssql", "SQL", "Microsoft SQL Server"],
];
const neutral = "#9aa7bc";
function hexToRgb(hex) {
const n = parseInt(hex.replace("#", ""), 16);
return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
}
function luminance([r, g, b]) {
const f = (c) => {
const s = c / 255;
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
};
return 0.2126 * f(r) + 0.7152 * f(g) + 0.0722 * f(b);
}
function contrast(a, b) {
const [hi, lo] = [luminance(a), luminance(b)].sort((x, y) => y - x);
return (hi + 0.05) / (lo + 0.05);
}
const bg = hexToRgb(BG);
function readable(hex) {
let rgb = hexToRgb(hex);
let t = 0;
while (contrast(rgb, bg) < 3 && t < 1) {
t += 0.04;
rgb = rgb.map((c) => Math.round(c + (255 - c) * t));
}
return "#" + rgb.map((c) => c.toString(16).padStart(2, "0")).join("");
}
const toHex = (rgb) => "#" + rgb.map((c) => c.toString(16).padStart(2, "0")).join("");
const data = JSON.parse(
fs.readFileSync(path.join(siDir, "data", "simple-icons.json"), "utf8"),
);
const bySlug = new Map(data.map((i) => [i.slug, i]));
fs.mkdirSync(outIcons, { recursive: true });
const brandRules = [];
for (const [group, file, slug, title] of icons) {
const meta = bySlug.get(slug);
if (!meta) throw new Error(`simple-icons has no slug "${slug}" (${title})`);
const rawPath = fs.readFileSync(path.join(siDir, "icons", `${slug}.svg`), "utf8");
const d = rawPath.match(/<path[^>]*\sd="([^"]+)"/)?.[1];
if (!d) throw new Error(`no path found in ${slug}.svg`);
const colour = readable("#" + meta.hex);
fs.writeFileSync(
path.join(outIcons, `${file}.svg`),
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation"><path fill="${colour}" d="${d}"/></svg>\n`,
);
brandRules.push(`.brand--${file}{--brand:${colour}}`);
}
for (const [group, file, label, title] of monograms) {
const small = label.length > 2;
fs.writeFileSync(
path.join(outIcons, `${file}.svg`),
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation">` +
`<rect x="1.25" y="1.25" width="21.5" height="21.5" rx="5" fill="none" stroke="${neutral}" stroke-width="1.1"/>` +
`<text x="12" y="12" fill="${neutral}" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="${small ? 7.4 : 8.6}" font-weight="600" letter-spacing=".2" text-anchor="middle" dominant-baseline="central">${label}</text></svg>\n`,
);
brandRules.push(`.brand--${file}{--brand:${neutral}}`);
}
const header =
"/* Generated by tools/build-icons.mjs. Do not edit by hand. */\n" +
"/* Brand colours are lightened where needed to reach 3:1 on #0a0d14. */\n";
fs.writeFileSync(outBrandCss, header + brandRules.join("\n") + "\n");
console.log(`wrote ${icons.length + monograms.length} icons to assets/icons/`);
console.log(`wrote ${brandRules.length} brand rules to assets/brand.css`);
for (const r of brandRules) console.log(" " + r);

47
tools/og.html Normal file
View File

@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Open Graph card</title>
<style>
@font-face {
font-family: "Bricolage Grotesque";
src: url("../assets/fonts/bricolage-grotesque-latin-wght-normal.woff2") format("woff2");
font-weight: 200 800;
font-display: block;
}
@font-face {
font-family: "Instrument Sans";
src: url("../assets/fonts/instrument-sans-latin-wght-normal.woff2") format("woff2");
font-weight: 400 700;
font-display: block;
}
* { box-sizing: border-box; }
html, body { margin: 0; width: 1200px; height: 630px; }
body {
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 64px 72px 56px;
background: #0a0d14;
color: #eef2f8;
font-family: "Instrument Sans", system-ui, sans-serif;
overflow: hidden;
}
.top { display: flex; align-items: center; gap: 14px; color: #6fe3b0; font: 500 19px/1 ui-monospace, Menlo, monospace; letter-spacing: .16em; text-transform: uppercase; }
.top::before { content: ""; width: 40px; height: 2px; background: #6fe3b0; }
h1 { margin: 0; font-family: "Bricolage Grotesque", sans-serif; font-weight: 650; font-size: 126px; line-height: .9; letter-spacing: -.04em; }
.bottom { display: flex; align-items: flex-end; justify-content: space-between; border-top: 1px solid #232b3a; padding-top: 26px; }
.stack { max-width: 760px; color: #9aa7bc; font-size: 25px; line-height: 1.45; }
.domain { color: #6fe3b0; font: 400 22px/1 ui-monospace, Menlo, monospace; }
</style>
</head>
<body>
<div class="top">Junior DevOps engineer</div>
<h1>Reza<br>Yaghobi</h1>
<div class="bottom">
<p class="stack">Docker · Kubernetes · GitLab CI/CD · Ansible · Prometheus · Grafana</p>
<span class="domain">rezayaghobi.ir</span>
</div>
</body>
</html>