尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Statyczna, dwujęzyczna (EN / RU) strona dla Milana PMU Dubai — permanentny makijaż i kamuflaż blizn, z dojazdem do klientki w Dubaju i Szardży. Bez build stepu i bez zależności: otwierasz index.html i strona działa. Fonty są hostowane lokalnie, więc działa też offline. Dwie drogi — wybierz jedną i trzymaj się jej:查看完整 README ↗
Statyczna, dwujęzyczna (EN / RU) strona dla Milana PMU Dubai — permanentny makijaż i kamuflaż blizn, z dojazdem do klientki w Dubaju i Szardży.
Bez build stepu i bez zależności: otwierasz index.html i strona działa.
Fonty są hostowane lokalnie, więc działa też offline.
# najprościej
open index.html
# albo lokalny serwer (potrzebny, jeśli chcesz testować ścieżki jak na produkcji)
python3 -m http.server 8000
index.html services.html results.html pricing.html
about.html faq.html contact.html ← wersja angielska (root)
ru/… ← wersja rosyjska, te same strony
assets/
css/tokens.css ← cała warstwa wizualna: kolory, typografia, odstępy, ruch
css/fonts.css ← @font-face dla lokalnych fontów
css/site.css ← style komponentów
js/site.js ← nawigacja, reveal, suwaki przed/po, dobór pigmentu, formularz
fonts/ ← Manrope + JetBrains Mono (latin + cyrylica), OFL
img/ ← placeholdery do podmiany na prawdziwe zdjęcia
tools/
build.py ← generator: jeden szablon → EN w root + RU w /ru/
content_en.py ← cała treść angielska
content_ru.py ← cała treść rosyjska
make_placeholders.py← generator placeholderów graficznych
robots.txt sitemap.xml
Dwie drogi — wybierz jedną i trzymaj się jej:
tools/content_en.py
i tools/content_ru.py, potem python3 tools/build.py. Obie wersje językowe
pozostają zsynchronizowane strukturalnie.tools/ — ponowne uruchomienie
generatora nadpisze ręczne zmiany.Numery telefonu, adres e-mail, linki i domena siedzą w jednym miejscu:
SITE na górze tools/build.py.
Wszystkie kolory, rozmiary i czasy animacji są w assets/css/tokens.css.
Zmiana palety = zmiana kilku wartości w tym jednym pliku.
| Rola | Token | Wartość |
|---|---|---|
| Akcent (przyciski, linia pod headerem) | --gold | #DFA615 |
| Złoty tekst/ikony na jasnym tle | --gold-text | #8A6108 |
| Złoty tekst na ciemnym tle | --gold-light | #F0C960 |
| Ciemne pasma sekcji | --graphite / --graphite-deep | #5C5450 / #322D2A |
| Tło strony | --silk | #F4F2EF |
| Tekst | --ink / --ink-body | #141210 / #45403B |
| Skala odcieni skóry (kafle pigmentu) | --tone-01 … --tone-08 | — |
Typografia: Manrope (nagłówki i tekst) + JetBrains Mono (etykiety, kody, ceny, dni gojenia). Wersaliki występują tylko w dwóch miejscach: w nagłówkach display i w foncie mono. Wszystko, co się klika, jest pisane normalnie — Manrope ma zbyt luźne światła przy wersalikach w parach typu „TS" (ROZDZIELA słowa RESULTS i WHATSAPP).
Sekcje usług na zdjęciu: każda usługa na services.html ma zdjęcie jako tło całej
sekcji, z treścią na wierzchu. Siłę przyciemnienia (.svc::after) dobrano pomiarem,
a nie na oko: zrzut tła bez tekstu, próbkowanie luminancji i sprawdzenie kontrastu
względem koloru tekstu. Aktualnie najgorszy przypadek to 6.2:1 na desktopie i 7.4:1
na mobile, przy wymaganych 4.5:1. Podmieniając zdjęcie na jaśniejsze, powtórz pomiar —
jasna fotografia potrafi zjechać poniżej progu przy tym samym przyciemnieniu.
Element sygnaturowy: pasek odcieni skóry i interaktywny dobór pigmentu na stronie głównej. To nie ozdobnik — dobór pigmentu pod podton to faktyczne rzemiosło w kamuflażu blizn i to jedyna rzecz, której konkurencja nie ma.
| Zachowanie | Jak działa | Gdy się nie uda |
|---|---|---|
| Ciężki smooth scroll | Lenis z CDN, lerp: 0.085, pętla requestAnimationFrame | brak Lenisa (typeof Lenis === "undefined") → natywne przewijanie, strona działa normalnie |
| Linki kotwiczne | lenis.scrollTo(el, { offset }), offset liczony z realnej wysokości headera | window.scrollTo({ behavior: "smooth" }) |
| Przejścia między stronami | treść <main> gaśnie i unosi się, #veil zakrywa całość (320 ms), po wczytaniu treść wraca z dołu (460 ms). Header i stopka nie ruszają się — przejście czyta się jak jedna strona, która się zmienia | link nawiguje natychmiast |
| Zmiana języka | to samo, ale #veil w trybie --loading: rozmycie tła, znak firmowy i pasek postępu, ~680 ms | jak wyżej |
| Pozycja po nawigacji | każda zmiana podstrony startuje od góry — history.scrollRestoration = 'manual' plus reset pozycji Lenisa (immediate), bo inaczej Lenis przywraca poprzedni scroll w następnej klatce | window.scrollTo(0, 0) |
| Popup „Book" | natywny <dialog> — pułapka focusa, Esc i ::backdrop z pudełka | przycisk to prawdziwy link do WhatsApp i tak działa |
| FAQ | animacja wysokości przez Web Animations API, <details> zostaje źródłem prawdy | natywne rozwijanie bez animacji |
Jeśli nowa strona wczytuje się dłużej niż 500 ms, zwykła zasłona sama zamienia się
w tryb --loading — zamiast pustego ekranu widać znak firmowy i pasek.
Przy otwartym menu mobilnym i przy otwartym popupie leci lenis.stop(), przy zamknięciu
lenis.start(); bez Lenisa blokadę przejmuje klasa is-locked na <html>.
prefers-reduced-motion: Lenis w ogóle się nie inicjalizuje, przejścia i animacja FAQ
są pomijane, nawigacja jest natychmiastowa.
Uwaga o CDN: Lenis to jedyny zewnętrzny zasób na stronie (fonty są lokalne).
Bez internetu strona nadal działa — po prostu przewija się natywnie. Jeśli wolisz zero
zależności zewnętrznych, wgraj lenis.min.js do assets/js/ i podmień src w tools/build.py.
Wszystkie zdjęcia na stronie są prawdziwe — nie ma już żadnych placeholderów.
| Plik | Gdzie |
|---|---|
hero.webp | tło hero na stronie głównej |
service-brows/lips/camo/lashline.webp | tła sekcji usług + karty na głównej |
detail-pigments.webp · home-service.webp · studio.webp | sekcje procesu i bezpieczeństwa |
portrait.webp | „Meet Milana" i strona O mnie |
gallery-*.webp (6 szt.) | galeria na Rezultatach + trzy na głównej |
Pliki źródłowe PNG nie są trzymane w repo — w repozytorium są tylko skonwertowane
WebP. Wymiary są wpisane w DIMS w tools/build.py i trafiają na <img> jako
width/height, żeby przeglądarka rezerwowała miejsce zanim plik dojedzie.
Nowe zdjęcie wgrywa się jednym poleceniem — rozmiar bierze z DIMS, więc plik na
dysku nie może się rozjechać z atrybutami w HTML-u:
python3 tools/png_to_webp.py <ścieżka-do-PNG> service-lashline.webp [0-1]
Ostatni argument to pionowe kotwiczenie kadru (0 = góra, 1 = dół, domyślnie 0,5) —
przydaje się, gdy źródło ma inne proporcje niż docelowy box. Kadrowanie jest zawsze
typu „cover", nigdy nie rozciąga obrazu. W kontenerze nie ma PIL-a, cwebp ani
ffmpeg-a, więc skalowanie i kompresja idą przez canvas w headless Chromium.
Dodając zupełnie nowe zdjęcie, najpierw dopisz jego wymiary do DIMS.
+971 50 000 0000 (SITE w tools/build.py)[email protected]https://mockup-milanapmu-uae.vercel.app, czyli adres, pod
którym strona faktycznie stoi. Wpływa na canonical, hreflang i sitemap.xml.
Przy starcie pod milanapmu.ae zmień SITE["domain"] w tools/build.py
i przebuduj — inaczej wszystkie kanoniczne adresy będą wskazywać na mockuppricing.menu / pricing.offerassets/img/service-lashline.webp jest
wygenerowane przez AI i pełni rolę wyłącznie dekoracyjnego tła sekcji.
Nie jest to zdjęcie klientki ani efekt pracy Milany i nie wolno go tak
podpisać. Galeria wyników korzysta wyłącznie z prawdziwych zdjęć.
Jeżeli pojawi się prawdziwe zdjęcie tej strefy, podmień plikDowolny statyczny hosting: Netlify, Vercel, Cloudflare Pages, GitHub Pages albo zwykły FTP.
Wgrywasz całą zawartość repozytorium poza tools/.
Po ustawieniu domeny podmień SITE["domain"] i przebuduj — inaczej canonical,
hreflang i sitemap.xml będą wskazywać na placeholder.
skip linkprefers-reduced-motion respektowanealt na każdej grafice, lang i hreflang.js, „Book" pozostaje linkiem do
WhatsApp, FAQ rozwija się natywnie, a nakładka przejścia nigdy się nie pokazuje<!-- SAMPLE REVIEW ... -->, żeby nie dało się ich przeoczyć. Przed publikacją
podmień na prawdziwe cytaty, za zgodą klientek (slots w content_*.py).ba_block() w tools/build.py, style .ba
i obsługa klawiatury w site.js) jest w kodzie i udokumentowany. Jeśli Milana
kiedyś zbierze pary — to samo zdjęcie przed i po, ten sam kadr i światło —
przywrócenie sekcji to zmiana treści, nie przebudowa.