feat(i18n): translate all case studies and resume to English

- add .en.html overrides for 16 case pages + resume via apinex translator
- translate remaining partials (projects-related, mini-projects-*, fab-stack-home-contact,
  fab-stack-resume, content-edit-fab-stack, cookie-notice)
- enhance translate.mjs to protect <script>/<style> from translation
- second pass: translate attribute values (aria-label/alt/title/placeholder/content/
  data-hint-default) and visible text DeepL skipped in html mode
- make logo language-aware (NM / НМ) via i18n
This commit is contained in:
root committed 2026-09-15 23:18:01 +02:00
1 parent 20ee81bfaf
commit 4b52cec00d
58 files changed
+14812 -6924

No files matched your search

@@ -0,0 +1,21 @@
<div class="content-edit-fab-stack" aria-label="Content Edits" data-content-edit-ui>
<button
type="button"
class="fab fab--secondary glass-neutral content-edit-fab"
data-content-edit-mode-toggle
hidden
aria-pressed="false"
aria-label="Content Editing Mode"
title="Edit Mode"
>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M4 20h4l10.5-10.5a2.12 2.12 0 0 0 0-3L16.5 4.5a2.12 2.12 0 0 0-3 0L3 15v5z"
stroke="currentColor"
stroke-width="1.75"
stroke-linejoin="round"
/>
</svg>
<span class="content-edit-fab__badge" hidden aria-hidden="true">0</span>
</button>
</div>
+12 -12
View File
@@ -1,12 +1,12 @@
<aside class="cookie-notice glass-neutral" hidden data-cookie-notice>
<p class="cookie-notice__text">
This site uses cookies for a comfortable experience. Read more in
<a href="{{pagePrefix}}cookie-policy/" data-cookie-policy-link>cookie policy</a>.
</p>
<button type="button" class="btn btn--secondary btn--flat cookie-notice__accept" data-cookie-accept>
<span>Accept</span>
<span class="cookie-notice__accept-icon" aria-hidden="true">
<img src="{{assetPrefix}}assets/shared/icons/сookie.svg" alt="" width="20" height="20" loading="eager" decoding="async" />
</span>
</button>
</aside>
<aside class="cookie-notice glass-neutral" hidden data-cookie-notice>
<p class="cookie-notice__text">
This site uses cookies to ensure a smooth user experience. For more information, see the
<a href="{{pagePrefix}}cookie-policy/" data-cookie-policy-link>cookie policy</a>.
</p>
<button type="button" class="btn btn--secondary btn--flat cookie-notice__accept" data-cookie-accept>
<span>Accept</span>
<span class="cookie-notice__accept-icon" aria-hidden="true"><img src="{{assetPrefix}}assets/shared/icons/сookie.svg" alt="" width="20" height="20" loading="eager" decoding="async" /></span>
</button>
</aside>
@@ -0,0 +1,62 @@
<div class="fab-stack" aria-label="Quick Actions">
<div class="theme-panel-fab-wrap">
<button type="button" class="fab fab--secondary glass-neutral" data-theme-panel-btn aria-expanded="false" aria-controls="theme-panel" aria-label="Style Settings">
<span class="theme-panel-fab__icon theme-panel-fab__icon--open-hide" aria-hidden="true"></span>
<svg class="theme-panel-fab__icon theme-panel-fab__icon--close" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M6 6L18 18M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
</svg>
</button>
<div id="theme-panel" class="theme-picker__panel glass-neutral" role="dialog" aria-label="Theme and Design" hidden data-theme-panel>
<div class="theme-picker__stack">
<section class="theme-picker__section" aria-labelledby="theme-accent-title">
<h3 id="theme-accent-title" class="theme-picker__section-title">Accent Color</h3>
<div class="colorpicker" data-colorpicker>
<div class="colorpicker__plane-box">
<canvas class="colorpicker__plane" width="320" height="180" data-sl-canvas aria-label="Saturation and brightness of the accent"></canvas>
<div class="colorpicker__knob" data-sl-knob></div>
</div>
<div class="colorpicker__hue-wrap">
<label class="colorpicker__hue-sr" for="theme-hue-slider">Accent shade</label>
<input id="theme-hue-slider" class="colorpicker__hue" type="range" min="0" max="360" value="210" data-hue-slider aria-valuemin="0" aria-valuemax="360" />
</div>
</div>
</section>
<section class="theme-picker__section" aria-labelledby="theme-mode-title">
<h3 id="theme-mode-title" class="theme-picker__section-title">Theme</h3>
<div class="radius-seg theme-mode-seg" role="radiogroup" aria-labelledby="theme-mode-title">
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="system" aria-label="As in the system"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--system"></span></span></button>
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="light" aria-label="Light-colored theme"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--light"></span></span></button>
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="dark" aria-label="Dark Theme"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--dark"></span></span></button>
</div>
</section>
<section class="theme-picker__section" aria-labelledby="theme-radius-title">
<h3 id="theme-radius-title" class="theme-picker__section-title">Corner Rounding</h3>
<div class="radius-seg" role="radiogroup" aria-labelledby="theme-radius-title">
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="soft" aria-label="Slight rounding"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--soft"></span></span></button>
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="medium" aria-label="Average rounding"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--medium"></span></span></button>
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="strong" aria-label="Significant rounding"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--strong"></span></span></button>
</div>
</section>
<section class="theme-picker__section" aria-labelledby="theme-typography-title">
<h3 id="theme-typography-title" class="theme-picker__section-title">Typography</h3>
<div class="radius-seg" role="radiogroup" aria-labelledby="theme-typography-title">
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="geologica" aria-label="Sans"><span class="theme-font-seg__label">Sans</span></button>
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="merriweather" aria-label="Sans Serif"><span class="theme-font-seg__label">Sans Serif</span></button>
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="mono" aria-label="Mono"><span class="theme-font-seg__label">Mono</span></button>
</div>
</section>
<section class="theme-picker__section" aria-labelledby="theme-mesh-bg-title">
<h3 id="theme-mesh-bg-title" class="theme-picker__section-title">Page Background</h3>
<div class="radius-seg radius-seg--two" role="radiogroup" aria-labelledby="theme-mesh-bg-title">
<button type="button" class="radius-seg__btn theme-mesh-bg-seg__btn" role="radio" aria-checked="false" data-mesh-bg-option="on" aria-label="Show background gradient"><span class="theme-mesh-bg-seg__label">On</span></button>
<button type="button" class="radius-seg__btn theme-mesh-bg-seg__btn" role="radio" aria-checked="false" data-mesh-bg-option="off" aria-label="Hide the background gradient"><span class="theme-mesh-bg-seg__label">Off</span></button>
</div>
</section>
</div>
</div>
</div>
<a class="fab fab--primary" href="{{pagePrefix}}#contact" aria-label="Contact Us">
<span class="fab-primary__ico" aria-hidden="true"></span>
</a>
</div>
{{> content-edit-fab-stack}}
+12
View File
@@ -0,0 +1,12 @@
<div class="fab-stack" aria-label="Quick Actions">
<div class="theme-panel-fab-wrap">
<button type="button" class="fab fab--secondary glass-neutral" data-resume-print-btn aria-label="Print Resume">
<span class="fab-secondary__ico fab-secondary__ico--print" aria-hidden="true"></span>
</button>
</div>
<a href="/assets/resume/Mamadaev_Nik__CV__Product_Designer_UX-UI.pdf" download="Mamadaev_Nik__CV__Product_Designer_UX-UI.pdf" class="fab fab--primary fab--label" aria-label="Download the resume as a PDF">
<span class="fab-primary__ico fab-primary__ico--pdf" aria-hidden="true"></span>
<span class="fab__label">Download as PDF</span>
</a>
</div>
{{> content-edit-fab-stack}}
+3
View File
@@ -0,0 +1,3 @@
<section class="section section--surface" aria-hidden="true">
<div class="section__inner"></div>
</section>
+8
View File
@@ -0,0 +1,8 @@
<footer class="footer">
<div class="footer__inner">
<span class="footer__chunk footer__chunk--date">© 2015–2026<span class="footer__sep" aria-hidden="true"> ·
</span></span>
<span class="footer__chunk footer__chunk--main">{{i18n:footer.credit}}</span> ·<span class="footer__chunk footer__chunk--meta footer__attr"><span class="footer__sep" aria-hidden="true"> </span><a href="{{pagePrefix}}cases/design-system/">{{i18n:footer.designSystem}}</a><span class="footer__sep" aria-hidden="true">·
</span><a href="{{pagePrefix}}cookie-policy/">{{i18n:footer.cookiePolicy}}</a></span> ·<span class="footer__chunk footer__chunk--lang"><span class="footer__sep" aria-hidden="true">
</span>{{> lang-switch}}</span></div>
</footer>
+1
View File
@@ -0,0 +1 @@
<link rel="stylesheet" href="/vendor/plyr/plyr.css" />
+2
View File
@@ -0,0 +1,2 @@
<script src="/js/skill-connectors.js" defer></script>
<script type="module" src="/js/main.js"></script>
+1 -1
View File
@@ -1,7 +1,7 @@
<a class="skip-link" href="#case-main">{{i18n:skip.case}}</a>
<header class="header" data-theme-picker>
<div class="header__inner">
<a class="logo" href="{{pagePrefix}}" aria-label="{{i18n:logo.aria}}">НМ</a>
<a class="logo" href="{{pagePrefix}}" aria-label="{{i18n:logo.aria}}">{{i18n:logo.text}}</a>
<div class="header__cluster">
<nav class="nav" aria-label="{{i18n:nav.aria}}">
<a href="#contact">{{i18n:nav.contact}}</a>
+1 -1
View File
@@ -3,7 +3,7 @@
<header class="header" data-theme-picker>
<div class="header__inner">
<a class="logo" href="#" aria-label="{{i18n:logo.aria}}">НМ</a>
<a class="logo" href="#" aria-label="{{i18n:logo.aria}}">{{i18n:logo.text}}</a>
<div class="header__cluster">
<nav class="nav" aria-label="{{i18n:nav.aria}}" data-top-nav>
<a href="#projects">{{i18n:nav.projects}}</a>
+1 -1
View File
@@ -2,7 +2,7 @@
<header class="header" data-theme-picker>
<div class="header__inner">
<a class="logo" href="{{pagePrefix}}" aria-label="{{i18n:logo.aria}}">НМ</a>
<a class="logo" href="{{pagePrefix}}" aria-label="{{i18n:logo.aria}}">{{i18n:logo.text}}</a>
<div class="header__cluster">
<nav class="nav" aria-label="{{i18n:nav.aria}}">
<a href="{{pagePrefix}}">{{i18n:back.home}}</a>
+18
View File
@@ -0,0 +1,18 @@
<nav class="lang-switch" aria-label="{{i18n:lang.aria}}" data-lang-switch>
<a class="lang-switch__btn" data-lang="ru" href="/">{{i18n:lang.ru}}</a>
<a class="lang-switch__btn" data-lang="en" href="/en/">{{i18n:lang.en}}</a>
</nav>
<script>
(function () {
var p = location.pathname.replace(/^\/+/, "");
var isEn = p.indexOf("en/") === 0;
var base = isEn ? p.slice(3) : p;
var links = document.querySelectorAll("[data-lang-switch] [data-lang]");
for (var i = 0; i < links.length; i++) {
var b = links[i];
var l = b.getAttribute("data-lang");
b.setAttribute("href", (l === "en" ? "/en/" : "/") + base);
if ((l === "en") === isEn) b.setAttribute("aria-current", "true");
}
})();
</script>
@@ -0,0 +1,52 @@
<section class="section section--surface" data-reveal>
<div class="section__inner">
<h2 class="section__title">See also</h2>
<ol class="mini-projects-grid" data-mini-projects-list>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="ai-assistant">
<a
class="mp-card mp-card--link mp-card--compact"
href="{{casesPrefix}}ai-assistant-figma/"
aria-label="AI Assistant — Open a Case"
>
<div class="mp-card__body">
<h3 class="mp-card__title">AI Assistant</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">Figma plugin</li>
</ul>
<p class="mp-card__desc">A Figma plugin with AI features.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="card-columns">
<a
class="mp-card mp-card--link mp-card--compact"
href="{{casesPrefix}}card-columns-obsidian/"
aria-label="Card Columns — Open a Case"
>
<div class="mp-card__body">
<h3 class="mp-card__title">Card Columns</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">Obsidian Plugin</li>
</ul>
<p class="mp-card__desc">A plugin for displaying cards in columns in Obsidian.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="site-with-ai-ide">
<a
class="mp-card mp-card--link mp-card--compact"
href="{{casesPrefix}}site-with-ai-ide/"
aria-label="This website — Open a Case"
>
<div class="mp-card__body">
<h3 class="mp-card__title">This website</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">Development with AI IDE</li>
</ul>
<p class="mp-card__desc">Website development using AI IDE.</p>
</div>
</a>
</li>
</ol>
</div>
</section>
@@ -0,0 +1,190 @@
<ol
id="mini-projects-showcase-grid"
class="mini-projects-grid mp-showcase-grid"
data-mini-projects-list
>
<li class="mini-projects-grid__item" data-mp-cells="2">
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[2] stack · link">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../assets/shared/placeholder.webp"
alt=""
width="560"
height="315"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">
[2] stack · link
<span class="mp-card__ext" aria-hidden="true"></span></h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">website</li>
</ul>
<p class="mp-card__desc">A base pair in a row of six cells.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="2">
<div class="mp-card mp-card--stack">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../assets/shared/placeholder.webp"
alt=""
width="560"
height="315"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">[2] stack</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">note</li>
</ul>
<p class="mp-card__desc">Stack without an external link.</p>
</div>
</div>
</li>
<li class="mini-projects-grid__item" data-mp-cells="2">
<div class="mp-card mp-card--horizontal">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../assets/shared/placeholder.webp"
alt=""
width="360"
height="203"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">[2] horizontal</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">utility</li>
</ul>
<p class="mp-card__desc">Horizontal, two cells wide, without a link.</p>
</div>
</div>
</li>
<li class="mini-projects-grid__item" data-mp-cells="2">
<article class="mp-card mp-card--compact">
<div class="mp-card__body">
<h3 class="mp-card__title">[2] compact</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">template</li>
</ul>
<p class="mp-card__desc">A two-cell text card.</p>
</div>
</article>
</li>
<li class="mini-projects-grid__item" data-mp-cells="1">
<a class="mp-card mp-card--link mp-card--compact" href="#" aria-label="[1] compact · link">
<div class="mp-card__body">
<h3 class="mp-card__title">
[1] compact · link
<span class="mp-card__ext" aria-hidden="true"></span></h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">cli</li>
</ul>
<p class="mp-card__desc">A narrow column with a link.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="1">
<article class="mp-card mp-card--compact">
<div class="mp-card__body">
<h3 class="mp-card__title">[1] compact</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">document</li>
</ul>
<p class="mp-card__desc">Compact, one cell wide.</p>
</div>
</article>
</li>
<li class="mini-projects-grid__item" data-mp-cells="2">
<div class="mp-card mp-card--decor" aria-hidden="true">
<span class="mp-card__decor-pattern" aria-hidden="true"></span>
</div>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3">
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[3] stack · link">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../assets/shared/placeholder.webp"
alt=""
width="560"
height="315"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">
[3] stack · link
<span class="mp-card__ext" aria-hidden="true"></span></h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">Appendix</li>
</ul>
<p class="mp-card__desc">
Half of a six-cell row. A longer description to check for line breaks and height after changing the font.
</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3">
<a class="mp-card mp-card--link mp-card--horizontal" href="#" aria-label="[3] horizontal · link">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../assets/shared/placeholder.webp"
alt=""
width="360"
height="203"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">
[3] horizontal · link
<span class="mp-card__ext" aria-hidden="true"></span></h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">plugin</li>
</ul>
<p class="mp-card__desc">Wide horizontal: preview and text in a single column.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3">
<div class="mp-card mp-card--horizontal">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../assets/shared/placeholder.webp"
alt=""
width="360"
height="203"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">[3] horizontal</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">widget</li>
</ul>
<p class="mp-card__desc">Three-cell Horizontal, without a link.</p>
</div>
</div>
</li>
</ol>
@@ -0,0 +1,217 @@
<div class="mp-showcase-specimens" aria-label="Card Types">
<div class="mp-showcase-specimen-row">
<div class="mp-showcase-specimen__card">
<p class="mp-showcase-specimen__label"><code>mp-card--stack</code> + <code>mp-card--link</code></p>
<a
class="mp-card mp-card--link mp-card--stack"
href="#"
aria-label="Stack with a link — example card"
>
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../assets/shared/placeholder.webp"
alt=""
width="560"
height="315"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">
Stack with a link
<span class="mp-card__ext" aria-hidden="true"></span></h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">website</li>
</ul>
<p class="mp-card__desc">
A small script: drafts generated from keywords, without external APIs.
</p>
</div>
</a>
</div>
<div class="mp-showcase-specimen__desc">
<p class="section__prose">
<strong>Stack with a link.</strong> Full-width preview, text at the bottom. For an external link:
<code>mp-card--link</code> and <code>mp-card__ext</code> in the title (as in the &quot;Experience&quot; block).
</p>
</div>
</div>
<div class="mp-showcase-specimen-row">
<div class="mp-showcase-specimen__card">
<p class="mp-showcase-specimen__label"><code>mp-card--stack</code> without a link</p>
<div class="mp-card mp-card--stack">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../assets/shared/placeholder.webp"
alt=""
width="560"
height="315"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Stack without a link</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">note</li>
</ul>
<p class="mp-card__desc">
A collection of databases and a rollup for a weekly overview, for personal use only.
</p>
</div>
</div>
</div>
<div class="mp-showcase-specimen__desc">
<p class="section__prose">
<strong>Stack without a link.</strong> Same view. Wrapper <code>div</code> or <code>article</code>, without
<code>mp-card--link</code>.
</p>
</div>
</div>
<div class="mp-showcase-specimen-row">
<div class="mp-showcase-specimen__card">
<p class="mp-showcase-specimen__label"><code>mp-card--horizontal</code> + <code>mp-card--link</code></p>
<a
class="mp-card mp-card--link mp-card--horizontal"
href="#"
aria-label="Horizontal with a link — example card"
>
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../assets/shared/placeholder.webp"
alt=""
width="360"
height="203"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">
Horizontal with a link
<span class="mp-card__ext" aria-hidden="true"></span></h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">app</li>
</ul>
<p class="mp-card__desc">
Local timer with short sounds and a feature to block unnecessary tabs.
</p>
</div>
</a>
</div>
<div class="mp-showcase-specimen__desc">
<p class="section__prose">
<strong>Horizontal with a link.</strong> Thumbnail on the left, text on the right. On a narrow screen, the card
stacks vertically.
</p>
</div>
</div>
<div class="mp-showcase-specimen-row">
<div class="mp-showcase-specimen__card">
<p class="mp-showcase-specimen__label"><code>mp-card--horizontal</code> No link</p>
<div class="mp-card mp-card--horizontal">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="../assets/shared/placeholder.webp"
alt=""
width="360"
height="203"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Horizontal without a link</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">Template</li>
</ul>
<p class="mp-card__desc">
Static website with a schedule and an application form on a separate service.
</p>
</div>
</div>
</div>
<div class="mp-showcase-specimen__desc">
<p class="section__prose">
<strong>Horizontal without a link.</strong> Same layout; the card does not link to an external URL.
</p>
</div>
</div>
<div class="mp-showcase-specimen-row">
<div class="mp-showcase-specimen__card">
<p class="mp-showcase-specimen__label"><code>mp-card--compact</code> + <code>mp-card--link</code></p>
<a
class="mp-card mp-card--link mp-card--compact"
href="#"
aria-label="Compact with a link — example card"
>
<div class="mp-card__body">
<h3 class="mp-card__title">
Compact with a link
<span class="mp-card__ext" aria-hidden="true"></span></h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">script</li>
</ul>
<p class="mp-card__desc">
Prefixes, numbering, and a dry run before writing files to disk.
</p>
</div>
</a>
</div>
<div class="mp-showcase-specimen__desc">
<p class="section__prose">
<strong>Compact with a link.</strong> Text only, no <code>mp-card__media</code>. In the grid, often with
<code>data-mp-cells="1"</code>.
</p>
</div>
</div>
<div class="mp-showcase-specimen-row">
<div class="mp-showcase-specimen__card">
<p class="mp-showcase-specimen__label"><code>mp-card--compact</code> no link</p>
<article class="mp-card mp-card--compact">
<div class="mp-card__body">
<h3 class="mp-card__title">Compact without a link</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">document</li>
</ul>
<p class="mp-card__desc">
Markdown checklist before releasing minor UI changes.
</p>
</div>
</article>
</div>
<div class="mp-showcase-specimen__desc">
<p class="section__prose">
<strong>Compact without a link.</strong> A short note or checklist without an external link.
</p>
</div>
</div>
<div class="mp-showcase-specimen-row">
<div class="mp-showcase-specimen__card">
<p class="mp-showcase-specimen__label"><code>mp-card--decor</code></p>
<div class="mp-card mp-card--decor" aria-hidden="true">
<span class="mp-card__decor-pattern" aria-hidden="true"></span>
</div>
</div>
<div class="mp-showcase-specimen__desc">
<p class="section__prose">
<strong>Decorative cell.</strong> A placeholder in the grid, with no project or link. Inside
<code>span.mp-card__decor-pattern</code>.
</p>
</div>
</div>
</div>
+1
View File
@@ -0,0 +1 @@
<div id="nav-more-menu-floating" class="nav-more__floating" hidden data-nav-more-menu-floating aria-hidden="true"></div>
+2
View File
@@ -0,0 +1,2 @@
<script src="/js/skill-connectors.js" defer></script>
<script type="module" src="/js/main.js"></script>
+167
View File
@@ -0,0 +1,167 @@
<section class="section section--surface" data-reveal>
<div class="section__inner">
<h2 class="section__title">See also</h2>
<ol class="mini-projects-grid" data-mini-projects-list>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="ai-platform-primo-rpa">
<a class="mp-card mp-card--link mp-card--stack" href="{{casesPrefix}}ai-platform-primo-rpa/" aria-label="AI Platform — Open a Case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="{{assetPrefix}}assets/ai-platform-primo-rpa/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Primo AI Server</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">UX/UI</li>
<li class="mp-card__tag">Web App</li>
</ul>
<p class="mp-card__desc">An interface for training and using AI models in business processes: working with data, automation scenarios, and Smart OCR.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="lunacy">
<a class="mp-card mp-card--link mp-card--stack" href="{{casesPrefix}}lunacy/" aria-label="Lunacy Image Editor — Open a Case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="{{assetPrefix}}assets/lunacy/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Lunacy</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">UX/UI</li>
<li class="mp-card__tag">Desktop App</li>
</ul>
<p class="mp-card__desc">Worked on the Lunacy interface as part of the Icons8 team: user flow, complex prototypes, and improvements to functionality and interface logic.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="manu-game-maker" hidden>
<a class="mp-card mp-card--link mp-card--stack" href="{{casesPrefix}}manu-game-maker/" aria-label="MANU Game Engine — Open a Case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="{{assetPrefix}}assets/manu-game-maker/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">MANU Game Engine</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">Product Design</li>
<li class="mp-card__tag">Desktop App</li>
</ul>
<p class="mp-card__desc">Redesign and development of the game engine’s user interface: a new operational concept, an updated visual system, and the development of hundreds of complex user scenarios.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="mobile-clinic-app" hidden>
<a class="mp-card mp-card--link mp-card--stack" href="{{casesPrefix}}mobile-clinic-app/" aria-label="Mobile app for a network of clinics — open a case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="{{assetPrefix}}assets/mobile-clinic-app/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Mobile app for a network of clinics</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">UX/UI</li>
<li class="mp-card__tag">Mobile App</li>
</ul>
<p class="mp-card__desc">Design of a mobile app for scheduling doctor appointments and managing medical services. Focus on a simple user journey, intuitive navigation, and quick access to necessary actions.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="orc-automation-panel">
<a class="mp-card mp-card--link mp-card--stack" href="{{casesPrefix}}orc-automation-panel/" aria-label="Web Panel for Automation Orchestration — Open a Case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="{{assetPrefix}}assets/orc-primo-rpa/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Primo Orc</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">Mentoring and Coaching</li>
</ul>
<p class="mp-card__desc">Primo RPA orchestrator’s web dashboard: projects, deployment, and monitoring of RPA robots. Redesign of key screens for production without interrupting releases.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="task-distribution-concept" hidden>
<a class="mp-card mp-card--link mp-card--stack" href="{{casesPrefix}}task-distribution-concept/" aria-label="The concept of a task-assignment service—open a case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="{{assetPrefix}}assets/task-distribution-concept/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Task Distribution Service Concept</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">UX/UI</li>
<li class="mp-card__tag">Analytics</li>
</ul>
<p class="mp-card__desc">Product concept for a service to create, assign, and track tasks, with an emphasis on process transparency and seamless teamwork.</p>
</div>
</a>
</li>
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-related-slug="task-tracker" hidden>
<a class="mp-card mp-card--link mp-card--stack" href="{{casesPrefix}}task-tracker/" aria-label="Task Tracker for the Back-Office System — Open a Case">
<div class="mp-card__media" aria-hidden="true">
<img
class="mp-card__image"
src="{{assetPrefix}}assets/task-tracker/cover.webp"
alt=""
width="400"
height="225"
loading="lazy"
decoding="async"
/>
</div>
<div class="mp-card__body">
<h3 class="mp-card__title">Task tracker for a back-office system</h3>
<ul class="mp-card__tags" aria-label="Project Type">
<li class="mp-card__tag">Product Design</li>
<li class="mp-card__tag">Web App</li>
</ul>
<p class="mp-card__desc">An interface for planning and assigning tasks in the operations department: shared pool, personal to-do list, overview by assignee; tabs, filters, board/list/table views, and drag-and-drop functionality.</p>
</div>
</a>
</li>
</ol>
</div>
</section>
+80
View File
@@ -0,0 +1,80 @@
<script>
(function () {
var FONT_CSS = {
merriweather: "/assets/fonts/merriweather.css",
geologica: "/assets/fonts/geologica.css",
mono: "/assets/fonts/mono.css",
};
try {
var t = JSON.parse(localStorage.getItem("siteThemeV1") || "{}");
var d = document.documentElement;
var m = t.mode;
if (m !== "light" && m !== "dark" && m !== "system") m = "system";
var eff =
m === "system"
? window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light"
: m;
d.dataset.theme = eff;
var h = typeof t.h === "number" ? t.h : typeof t.hue === "number" ? t.hue : null;
var s = typeof t.s === "number" ? t.s : typeof t.sat === "number" ? t.sat : null;
var l = typeof t.l === "number" ? t.l : typeof t.light === "number" ? t.light : null;
if (h !== null) d.style.setProperty("--theme-h", String(h));
if (s !== null) d.style.setProperty("--theme-s", String(s));
if (l !== null) {
var L = Number(l);
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
}
var hVal = h !== null ? h : 210;
var sVal = s !== null ? s : 90;
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
var H = (((hVal % 360) + 360) % 360) / 360;
var S = Math.min(100, Math.max(0, sVal)) / 100;
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
var r, g, b;
if (S === 0) { r = g = b = Lv; }
else {
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
var p = 2 * Lv - q;
var hue2rgb = function(p, q, t) {
if (t < 0) t += 1; if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
};
r = hue2rgb(p, q, H + 1/3);
g = hue2rgb(p, q, H);
b = hue2rgb(p, q, H - 1/3);
}
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
var rad = t.radius;
if (rad === "soft" || rad === "medium" || rad === "strong") {
d.dataset.radius = rad;
} else {
d.dataset.radius = "medium";
}
var f = t.font;
if (f === "onest") f = "geologica";
if (f === "anonymous") f = "mono";
if (f !== "merriweather" && f !== "mono" && f !== "geologica") f = "merriweather";
d.dataset.font = f;
var mb = t.meshBg;
if (mb === "off") {
d.dataset.meshBg = "off";
} else {
d.dataset.meshBg = "on";
}
var href = FONT_CSS[f];
if (href && !document.querySelector('link[data-theme-font="' + f + '"]')) {
var link = document.createElement("link");
link.rel = "stylesheet";
link.href = href;
link.setAttribute("data-theme-font", f);
document.head.appendChild(link);
}
} catch (e) {}
})();
</script>