From 9f75341615defd0fef77605a7e8b8256223e61b4 Mon Sep 17 00:00:00 2001 From: Sergei Garin Date: Sat, 16 May 2026 08:13:38 +0300 Subject: [PATCH 1/7] Redesign homepage identity card --- DESIGN.md | 124 +++++++++++++++++ src/layouts/main.astro | 16 ++- src/pages/index.astro | 310 ++++++++++++++--------------------------- src/styles/global.css | 15 +- 4 files changed, 243 insertions(+), 222 deletions(-) create mode 100644 DESIGN.md diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..9b1c43f --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,124 @@ +# DESIGN.md + +Design memory for `garin.dev`. This file is the source of truth for the next visual pass. The current site content and assets are canon; the current visual layout is not canon. + +## Product intent + +- Product type: one-screen personal calling-card site for Sergei Garin. +- Audience: recruiters, founders, hiring managers, engineering leads, and people checking contact/CV credibility quickly. +- Primary read: name → role → short proof-of-work sentence → contact links. +- Primary action: open a profile, download CV, or email Sergei. +- Trust posture: calm, precise, senior, product-minded. No portfolio theatrics, no startup-template gloss. +- Target direction: Clean Identity Object — a compact masthead card where portrait, copy, and links feel like one composed identity artifact. + +Reference direction: `/Users/sergeygarin/.openclaw/media/tool-image-generation/website-clean-masthead-C-identity-object---5e6fe94d-e076-41be-b62b-68459e39537d.png`. +Use it for intent, hierarchy, density, and restraint only. Do not clone generated-image artifacts, exact composition, portrait treatment, typography, or link styling, and do not treat it as a pixel spec. + +## Artifact map + +- `DESIGN.md` is the only design-memory artifact for now. +- No supporting design docs are needed unless implementation reveals stable token/component/state rules that would make this file bloated. +- Downstream implementation should update this file if the approved design direction changes before code lands. + +## Canonical content and assets + +Current assets and approved identity content are the source of truth unless Sergey explicitly changes them. For this redesign, the preferred copy below is the copy contract; do not preserve legacy wording or layout just because it exists in the current implementation. + +- `src/pages/index.astro` +- `src/layouts/main.astro` +- `src/components/link.astro` +- `src/styles/global.css` +- `src/static/me.jpg` +- `src/static/me_cropped.jpg` +- `src/public/cv.pdf` +- `job@garin.dev` +- `https://github.com/MrFlashAccount` +- `https://twitter.com/mrflashaccount` +- `https://t.me/mrflashaccount` + +Preferred copy for the redesign: + +- Name: `Sergei Garin` +- Role: `Frontend engineer for sharp, reliable product interfaces.` +- Micro-bio: `I turn messy product ideas into calm, fast, production-ready UI.` +- Links: `GitHub`, `X`, `Telegram`, `CV`, `Email` + +Do not add invented proof, fake metrics, testimonials, project cards, employer logos, or extra sections to make the page feel fuller. + +## Composition law + +- The page should resolve as one screen, not a scroll portfolio. +- Build one compact masthead/card-like identity object. It may sit centered in the viewport with generous outer breathing room. +- Portrait and text must feel composed together, not like a photo column plus a content column. +- The photo may act as part of the object/background if readability is protected and the actual asset supports it; otherwise reduce photo dominance while keeping it visually integrated with the text block. +- The main reading path must be immediate: `Sergei Garin` first, role second, micro-bio third, links last. +- Keep the number of visible elements low. Every visible line should carry identity or action. +- Mobile should keep the same artifact feeling: compact, legible, calm, no stacked résumé page. + +## Visual system + +### Color + +- Use a restrained black / charcoal / soft-white / warm-ivory system. +- Prefer strong but soft contrast over harsh pure-white-on-pure-black glare. +- No bright accents, rainbow gradients, neon, glassmorphism, decorative blobs, textures, or noise. +- If an overlay is needed for photo readability, keep it functional and quiet. + +### Typography + +- Typography should create the drama, not decoration. +- Name gets the strongest display treatment: large, confident, elegant, and readable. +- If a serif/display face is used, keep it engineering-sharp rather than fashion/luxury editorial; readability and credibility beat reference-image mood. +- Role and micro-bio should be clean, direct, and lower-volume than the name. +- Links should feel editorial/systemic, not like app buttons. +- Avoid cramped text, generic SaaS hero scale, and random weight changes. + +### Shape, spacing, and density + +- Dense enough to feel like a precise identity card; airy enough to feel senior and deliberate. +- Use one dominant container/object at most. Do not break the page into multiple cards. +- Corners, borders, and shadows should be minimal and structural, not decorative. +- Alignment should feel measured. Avoid casual scatter, bento fragments, or floating badges. + +### Links and actions + +- Links are part of the identity system. +- Prefer plain text links in a composed row/list, optionally separated by subtle dividers. +- Avoid social-icon button clusters, filled pills, loud CTAs, and repeated competing actions. +- `Email` and `CV` can be present with equal restraint; neither should become a giant marketing button. + +### Motion and interaction + +- Motion is optional and should be nearly invisible. +- Use simple hover/focus feedback that preserves the strict identity-object feel. +- Respect reduced motion. +- Focus states must be visible and coherent with the restrained palette. + +## Hard nos + +Do not introduce: + +- portfolio/blog structure +- skills grid or `GREAT AT` chip wall +- project previews +- fake metrics, quotes, testimonials, logos, or badges +- bento/card clutter +- decorative gradients, blobs, textures, or noise +- generic `Senior Frontend Engineer` as the final hero copy +- social buttons as the primary link language +- the old/current split layout as design canon +- extra copy that weakens the sharp calling-card read + +## Implementation acceptance checks + +A later implementation is acceptable when: + +- The page reads as a one-screen personal calling-card site. +- Portrait + text + links feel like one composed identity artifact. +- The approved copy and canonical links/assets are present. +- The current content/assets are preserved unless deliberately replaced by Sergey. +- No app files treat the old visual layout as the source of truth. +- Links are restrained identity-system elements, not loud social buttons. +- The design has no decorative gradients/blobs/textures/noise and no portfolio-section creep. +- Desktop and mobile both preserve the compact masthead/card intent. +- Text contrast, readable order, focus visibility, keyboard access, and reduced-motion behavior are not visibly broken. diff --git a/src/layouts/main.astro b/src/layouts/main.astro index 7fa474d..8cf8ee6 100644 --- a/src/layouts/main.astro +++ b/src/layouts/main.astro @@ -40,7 +40,7 @@ const baseCSSString = result.root.toString(); lang="en" itemtype="https://schema.org/Person" itemscope - class="flex h-[100dvh] min-w-[320px] flex-col" + class="flex min-h-[100dvh] min-w-[320px] flex-col bg-[#eee9df]" > @@ -51,22 +51,28 @@ const baseCSSString = result.root.toString(); Sergei Garin - + - + diff --git a/src/pages/index.astro b/src/pages/index.astro index a61c49b..a17fedf 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,241 +1,143 @@ --- import { getImage } from "astro:assets"; -import resolveConfig from "tailwindcss/resolveConfig"; -import tailwindConfig from "../../tailwind.config.js"; -import me from "../static/me_cropped.jpg"; -import meOriginal from "../static/me.jpg?url"; +import me from "../static/me.jpg"; import Link from "../components/link.astro"; import MainLayout from "../layouts/main.astro"; -const fullConfig = resolveConfig(tailwindConfig); - -const meMobileAvif = await getImage({ +const portraitDesktop = await getImage({ src: me, format: "avif", - width: 80, - height: 80, - densities: [1, 2, 3], -}); -const meDesktopAvif = await getImage({ - src: me, - format: "avif", - width: 320, - height: 320, + width: 760, + height: 1060, densities: [1, 1.5], }); -const meScaledAvif = await getImage({ +const portraitMobile = await getImage({ src: me, format: "avif", - width: 360, - height: 360, - densities: [1, 2, 3], + width: 520, + height: 724, + densities: [1, 2], }); -const meFallback = await getImage({ +const portraitFallback = await getImage({ src: me, format: "jpg", - width: 240, - height: 240, + width: 760, + height: 1060, }); -const skills = [ - "TypeScript", - "React", - "Next.js", - "Node.js", - "Tailwind", - "Design Systems", - "Microfrontends", - "Web Performance", - "Accessibility", - "Testing", +const links = [ + { + label: "GitHub", + href: "https://github.com/MrFlashAccount", + rel: "me", + itemProp: "sameAs", + }, + { + label: "X", + href: "https://twitter.com/mrflashaccount", + rel: "me", + itemProp: "sameAs", + }, + { + label: "Telegram", + href: "https://t.me/mrflashaccount", + rel: "me", + itemProp: "sameAs", + }, + { + label: "CV", + href: "/cv.pdf", + download: "Sergei Garin CV.pdf", + }, + { + label: "Email", + href: "mailto:job@garin.dev", + itemProp: "email", + }, ]; ---
- - - - - - - - - +
+
-
-

- Sergei - Garin +

+ Sergei + Garin

-

Senior Frontend Engineer

-
- -

- Senior Frontend Engineer specializing in architecting performant - applications that drive business results. Proven track record of - achieving dramatic performance gains (10x+) and leading development of - revenue-generating features. -

-
-

GREAT AT

-
- { - skills.map((skill) => ( - - {skill} - - )) - } -
-
- -
- - Get in touch - - - - + +

- Download CV - - - - -

+ I turn messy product ideas into calm, fast, production-ready UI. +

-
-
- +
    - - - - GitHub - - - - - - - Twitter - - - - Telegram - -
+ { + links.map((link, index) => ( +
  • + {index > 0 && ( +
  • + )) + } + +
    - -
    -

    - © - - Sergei Garin -

    -
    diff --git a/src/styles/global.css b/src/styles/global.css index e8eb271..11d1ff5 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -66,9 +66,9 @@ font-family: OpenRunde, OpenRunde Fallback, - serif; + sans-serif; line-height: 1.5; - color-scheme: dark light; + color-scheme: light; } @media (prefers-reduced-motion: reduce) { @@ -81,17 +81,6 @@ } } - @media (prefers-color-scheme: dark) { - :where(body:not(:is(img, picture, video, canvas))) { - filter: invert(100%) hue-rotate(180deg) brightness(1.2); - } - - /* Invert to normal color images, pictures, videos, and canvases */ - :where(:is(img, picture, video, canvas)) { - filter: invert(90%) hue-rotate(180deg) brightness(1.2); - } - } - :where(*) { margin: 0; text-box-trim: trim-both; From 381e496b6d8aefa12c96bb1f2b6813c0a2836441 Mon Sep 17 00:00:00 2001 From: Sergei Garin Date: Sat, 16 May 2026 08:35:29 +0300 Subject: [PATCH 2/7] Polish identity card details --- src/pages/index.astro | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/index.astro b/src/pages/index.astro index a17fedf..a5ba0cb 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -60,10 +60,10 @@ const links = [
    @@ -74,7 +74,7 @@ const links = [ /> Portrait of Sergei Garin {link.label} From 35c46abc01e64d449d150733504d3ca1b3c01ecf Mon Sep 17 00:00:00 2001 From: Sergei Garin Date: Sat, 16 May 2026 09:03:57 +0300 Subject: [PATCH 3/7] Refine full-bleed identity layout --- src/layouts/main.astro | 4 ++-- src/pages/index.astro | 35 ++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/layouts/main.astro b/src/layouts/main.astro index 8cf8ee6..bab1144 100644 --- a/src/layouts/main.astro +++ b/src/layouts/main.astro @@ -40,7 +40,7 @@ const baseCSSString = result.root.toString(); lang="en" itemtype="https://schema.org/Person" itemscope - class="flex min-h-[100dvh] min-w-[320px] flex-col bg-[#eee9df]" + class="flex min-h-[100dvh] min-w-[320px] flex-col bg-[#080807]" > @@ -56,7 +56,7 @@ const baseCSSString = result.root.toString(); Sergei Garin
    - +