Our own website
Maksutovdesign.ru is not a demo or a template — it's the studio's working tool: 251 static pages in four languages, hand-built with no CMS and no framework. Here I'm the client, the designer and the developer at once — this page breaks down the colors, typography, components, SEO and multilingual architecture behind it.
01 / project scope
251 pages in four languages, zero frameworks
Every page is its own HTML file with its own inline <style>: no bundler, no
preprocessor, no shared CSS bundle. The only thing tying pages together is a handful of shared
<script> files from assets/js/ — search, the contact form,
scroll-reveal animation and hover micro-interactions.
02 / colors
Warm paper, near-black ink and a single red accent
The palette rests on the contrast between a warm light background and dense "ink" text rather than pure black and white — long case-study pages read softer that way. Red is the site's only accent color: it marks the active interface language, hover links, CTA buttons and card hover states. Green and blue appear sparingly, for secondary statuses, links and data-viz numbers.
--paper/--paper-2), three text depths (--ink/--ink-2/--ink-soft), three accents (--red/--green/--blue) and two borders (--line/--line-strong).03 / typography
Two typefaces for the whole site: Onest for UI, JetBrains Mono for labels
Onest, a humanist sans, carries headings, body copy and captions almost everywhere on the site.
JetBrains Mono is reserved for "technical" elements only — section eyebrows, tags, stat labels
in the metrics grid and the language switcher — so those elements read as system information
rather than ordinary prose. The entire type scale runs on clamp(), scaling smoothly
between mobile and desktop with no per-breakpoint jumps.
clamp(48px, 9vw, 142px), H2/Section title at clamp(34px, 5.8vw, 82px), body in Onest, labels and figures in JetBrains Mono.04 / components & design system
One component set, 251 pages
Buttons, tags, the language switch and the burger menu are never reinvented per page — they're
assembled from the same class set: a solid CTA button, two outline buttons with an arrow,
compact tag pills, and a four-item language switch (RU/EN/中/ع) with the active state in red.
Every hover and focus state, including the arrow on card-action links, is added by
a single shared script — assets/js/micro-motion.js, loaded on all 251 pages.
This very page is part of the same design system: for instance, every section heading here is
built from the same .section-head class (label + heading) used on any other page
of the site.
Buttons — hover fills red
Tags
Language switch — RU / EN / ZH / AR
Burger menu — link hover turns red
Site search — the open panel with sample results
Breadcrumbs — on every inner page
assets/js/search.js) builds an index across all 251 pages and opens a results panel right in the header; the same breadcrumbs (.breadcrumbs) run on every inner page of the site.Card pattern — hover fills dark, the button turns red
05 / SEO & multilingual architecture
Canonical, hreflang and JSON-LD on all 251 pages
Every page in all four languages ships a canonical link and the full set of hreflang
alternates (ru/en/zh/ar +
x-default), a unique meta description and its own OG/Twitter preview image —
not one shared placeholder for the whole site. Heading structure is strictly single-level:
exactly one <h1> per page, keeping the semantics clean for both search
engines and screen readers.
Structured data runs on JSON-LD: one shared Organization + Person
graph for the whole site, with a unique BreadcrumbList/Service block
per page. An idempotent seopack.py script rebuilds this whole block across
186+ pages whenever the shared template changes.
- Canonical + hreflang ru/en/zh/ar/x-default on every page
- JSON-LD: Organization, Person and BreadcrumbList/Service in one graph
- A unique OG/Twitter preview image per page instead of one shared placeholder
- Maintained sitemap.xml and robots.txt, a dedicated 404 page and favicon
- One <h1> per page and a clean heading hierarchy
06 / site statistics
Open analytics instead of Google Analytics
Visit analytics run on a lightweight tracker built in-house, not a third-party service: a small
script in assets/js/search.js sends an anonymous beacon to
admin/track.php — no third-party cookies, no Google Analytics or Yandex.Metrica.
The accumulated numbers — sessions, unique visitors, the desktop/mobile split, lead conversion,
traffic sources, geography and the most-viewed pages — are surfaced on the open, publicly
reachable /stats/ page, which pulls them live from admin/stats-api.php.
Sample KPI cards — illustrative, not real numbers (see the live page for current figures)
07 / admin CRM
A homemade PHP CRM — no database, no exposed login
Publishing projects, case studies, the blog and other sections runs through a private
/admin/ panel — a small homemade PHP module reachable only with a login and
password (the login page isn't indexed and isn't linked from anywhere on the public site).
Data lives in flat JSON files — no MySQL, no network-facing database.
Sign-in is protected the way any ordinary CRM would be: the password is checked with bcrypt
(password_verify()), the session is regenerated on a successful login
(session_regenerate_id()), and failed login attempts are counted per IP address —
a run of them triggers a temporary lockout. Every form carries a CSRF token that's verified
server-side on every POST request.
- Storage — flat JSON files, no database
- Password — bcrypt hash only, session regenerated on login
- Per-IP login-attempt limit with a temporary lockout
- CSRF token verified on every POST request in the panel
- Image uploads — validated with
getimagesize()and a MIME allow-list (JPG/PNG/WEBP), filenames always generated server-side - All output is escaped through one shared
h()function
The login and password aren't published anywhere; to see what data this CRM actually surfaces, see the open site statistics page — it draws on the same data source.
08 / order form
The "Order a design" button opens a form, not a mail client
Every "Order a design" button on the site points to the same mailto: address —
that's the fallback for a browser with JavaScript disabled. With JS enabled, the click is
intercepted by assets/js/contact-form.js, which opens a modal with a real form
instead of a mail client: name, contact (phone/email/Telegram), a service dropdown and a
message. Submission is a fetch() request to the third-party form-handling service
FormSubmit, which forwards the request to the designer's inbox — there's no in-house
mail-processing server.
09 / security
Static pages shrink the attack surface; the admin panel is secured separately
The public site is flat HTML with no database and no server-side request processing, so SQL injection simply has no surface to exploit — there's no SQL to inject into. Anything that needs a backend — the private admin CRM for managing projects, the blog and inquiries — lives in a separate PHP module with its own security perimeter.
- Security headers: X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Strict-Transport-Security
- The admin CRM panel is protected by a CSRF token on every form
- Admin passwords are stored only as bcrypt hashes
- CRM data lives in flat JSON files with no network-facing SQL surface
Discuss a project
Need a website or app design?
Tell me about the project and audience — I will propose the structure, scope, timeline and price.
Order website design10 / other projects in this service