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:
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>
|
||||
@@ -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}}
|
||||
@@ -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}}
|
||||
@@ -0,0 +1,3 @@
|
||||
<section class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner"></div>
|
||||
</section>
|
||||
@@ -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>
|
||||
@@ -0,0 +1 @@
|
||||
<link rel="stylesheet" href="/vendor/plyr/plyr.css" />
|
||||
@@ -0,0 +1,2 @@
|
||||
<script src="/js/skill-connectors.js" defer></script>
|
||||
<script type="module" src="/js/main.js"></script>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 "Experience" 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>
|
||||
@@ -0,0 +1 @@
|
||||
<div id="nav-more-menu-floating" class="nav-more__floating" hidden data-nav-more-menu-floating aria-hidden="true"></div>
|
||||
@@ -0,0 +1,2 @@
|
||||
<script src="/js/skill-connectors.js" defer></script>
|
||||
<script type="module" src="/js/main.js"></script>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
Reference in new issue
Block a user