Maksutov Design MAKSUTOV DESIGN
Self-project Web design SEO i18n

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

251static pages in Russian, English, Chinese and Arabic — cases, blog, FAQ, notebook.
4languages: RU is the source, EN/ZH/AR are full mirrors with the same page set.
0JS frameworks: no React, no Vue — plain HTML and inline CSS on every page.
100%static, hosted on Beget shared hosting; PHP powers only the private admin CRM.

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.

Color tokens · maksutovdesign.ru
--paper#f6f8fa
--paper-2#ffffff
--ink#171a4a
--ink-2#30366f
--ink-soft#57606a
--red#cf222e
--green#1a7f37
--blue#0969da
--line#d0d7de
--line-strong#8c959f
01 — Color tokensTen variables: two paper tones (--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.

Type specimen · Onest + JetBrains Mono
H1 / Hero — clamp(48px, 9vw, 142px)Maksutov Design
Lead — clamp(18px, 2.2vw, 28px)20+ years in design: logos, identity, websites, brand books
H2 / Section title — clamp(34px, 5.8vw, 82px)The site's design system
Body / Onest — clamp(18px, 1.7vw, 26px)Onest handles headings, body copy and captions almost everywhere on the site — Aa Bb 123
Eyebrow / JetBrains Mono — 12px / 80001 / Typography
Mono / JetBrains Mono — counters and labels251 PAGES · 4 LANGUAGES · 0 FRAMEWORKS
02 — Type scaleH1/Hero at 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.

Component strip · buttons, tags, lang switch, menu

Buttons — hover fills red

Tags

UX/UI Branding SEO

Language switch — RU / EN / ZH / AR

RU EN 中 ع

Burger menu — link hover turns red

03 — Component libraryButtons, tags, the four-language switch and the dark burger menu with a hover-to-red state on one nav link.
Site search & breadcrumbs
04 — Search & navigationClient-side search (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 · .next-card / .project-card
05 — Card patternThe site's most reused block: a heading, description, tags and a "Learn more" button — hover fills the whole card dark and turns the button red; the same pattern shows up in the "10 / other projects" section of this very page.
ButtonsTag pillsLang switchBurger menuSearchCardsBreadcrumbsMetrics grid

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.

Statistics · illustrative numbers

Sample KPI cards — illustrative, not real numbers (see the live page for current figures)

251pages indexed by the site search.
4languages, each with full statistics.
70/30illustrative desktop/mobile split.
0third-party trackers or ad cookies.
06 — Statistics panelThe public maksutovdesign.ru/stats/ page shows real, updating numbers; shown here is a simplified card mock-up with illustrative values so live data isn't pulled out of context.

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.

Order form · preview, inert

Order a design

Briefly describe the task. I usually reply within 24 hours.

Send request
07 — Order formAn inert mock-up of the real fields (name, contact, service, task details); on the live site the form opens in a modal from the "Order a design" button and submits via FormSubmit, not mailto.

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 design

10 / other projects in this service