173
Claude outputs/2026-09-06-dark-technical-redesign-design.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# dzanan.net — "Dark & technical" redesign
|
||||
|
||||
Date: 2026-09-06 · Status: approved by Amar (direction C of three mockups)
|
||||
|
||||
## Goal
|
||||
|
||||
Replace the current warm/editorial design of dzanan.net with the "Dark & technical"
|
||||
direction: near-black surfaces with a faint grid, monospace labels, a terminal-style
|
||||
profile panel, and a single glowing green accent. The site serves both employers and
|
||||
consulting clients equally. The CV becomes a PDF that Amar provides; the site links to it.
|
||||
|
||||
Non-goals: new content for the case studies (text stays), a light theme, a CMS, new routes.
|
||||
|
||||
## Scope
|
||||
|
||||
Kept: Angular 22 app structure, SSR + prerendering, `SeoService`, `PageShellComponent`
|
||||
(restyled), landing page, four `/work/*` case-study pages, `SystemDiagramComponent`
|
||||
(recoloured), not-found page, Tailwind v4 install, Docker deploy.
|
||||
|
||||
Removed: `CvPageComponent` + its spec, `ThemeService`, `ThemeToggleComponent`, the theme
|
||||
bootstrap script in `src/index.html`, the `cv` client route, the `cv` prerender route.
|
||||
|
||||
Added: `public/cv.pdf` (placeholder until Amar supplies the file), a 301 from `/cv` to
|
||||
`/cv.pdf` in `src/server.ts`, self-hosted fonts.
|
||||
|
||||
## Visual system
|
||||
|
||||
Defined as CSS custom properties on `:root` in `src/styles.scss`; no `.dark` variant.
|
||||
|
||||
| token | value | use |
|
||||
|---|---|---|
|
||||
| `--bg` | `#0D1015` | page background |
|
||||
| `--panel` | `#12161D` | cards, list panel, code panel |
|
||||
| `--panel-2` | `#0F1318` | panel headers / inset |
|
||||
| `--line` | `#232A33` | borders, dividers |
|
||||
| `--line-strong` | `#2A323D` | tag borders, button outline |
|
||||
| `--text` | `#E6EAF0` | primary text |
|
||||
| `--muted` | `#8B95A5` | secondary text |
|
||||
| `--dim` | `#5C6672` | tertiary text, comments |
|
||||
| `--accent` | `#8BE04A` | labels, links, primary button, status dot |
|
||||
| `--accent-glow` | `rgba(139,224,74,.22)` | button and dot glow |
|
||||
| `--code-key` / `--code-str` / `--code-num` | `#7AA2F7` / `#C3E88D` / `#F78C6C` | profile.json panel |
|
||||
|
||||
Grid: `linear-gradient` lines at 2.8% white, 64px cell, fixed to the page background.
|
||||
|
||||
Type: JetBrains Mono (labels, nav, meta, code, buttons) and IBM Plex Sans (headings and
|
||||
body), self-hosted via `@fontsource-variable/jetbrains-mono` and `@fontsource/ibm-plex-sans`
|
||||
(weights 400/500/600) imported in `styles.scss`. Fallbacks: Consolas/Menlo/monospace and
|
||||
"Segoe UI"/system-ui/sans-serif. Base body 16px; headline scale `clamp(2.4rem, 5vw, 3.9rem)`
|
||||
for h1, `clamp(1.75rem, 3vw, 2.1rem)` for h2, letter-spacing -0.03em/-0.025em, weight 600.
|
||||
|
||||
Labels (`.label`): mono, 12px, uppercase, 0.08em tracking, accent colour, prefixed with
|
||||
`// ` in markup (e.g. `// selected work`). Tags (`.tag`): mono 12px, 24px tall, 1px
|
||||
`--line-strong` border, 4px radius. Panels (`.panel`): `--panel` fill, 1px `--line`
|
||||
border, 10px radius. Buttons: 46px tall, 6px radius, mono 14px; `.btn-accent` accent fill
|
||||
with dark text and glow, `.btn-line` outlined.
|
||||
|
||||
Container: `.shell` = `min(1160px, 100% - 40px)` centred. Section spacing 96px desktop,
|
||||
64px below 720px.
|
||||
|
||||
## Pages
|
||||
|
||||
### Shell (header, footer, mobile menu)
|
||||
|
||||
Header: sticky, `--bg` at 92% with blur, bottom border. Left: mono wordmark `~/` (accent)
|
||||
+ `dzanan.net` (600). Right (desktop): mono nav `work · experience · contact · cv.pdf`,
|
||||
then a divider and the status `● available` (accent dot with glow). `cv.pdf` is an `<a
|
||||
href="/cv.pdf">` with a download icon, opens in a new tab. Below 720px the nav collapses to
|
||||
the existing signal-driven menu button; the status stays visible.
|
||||
|
||||
Navigation config: `[{work,'/',#work},{experience,'/',#experience},{contact,'/',#contact}]`
|
||||
plus the CV link rendered separately as a plain anchor (not a `SectionNavItem`).
|
||||
|
||||
Footer: mono 12px, `Amar Džanan · Sarajevo, Bosnia and Herzegovina` left; email and
|
||||
LinkedIn right.
|
||||
|
||||
### Landing (`/`)
|
||||
|
||||
1. Hero — two columns (1.05fr / .95fr, 64px gap), stacks below 1024px.
|
||||
Left: label `Senior full-stack engineer — .NET · Angular · MCP`; h1 "Complex systems,
|
||||
<accent>understood before changed.</accent>"; lead paragraph "I modernize enterprise
|
||||
software and connect it to AI through narrow, validated, verified interfaces — the kind
|
||||
you can run in production and sleep at night."; buttons `amar@dzanan.net` (accent,
|
||||
mailto) and `cv.pdf` (outline, download).
|
||||
Right: `profile.json` terminal panel — title bar with three dots and file name, then a
|
||||
`$ whoami --json` line and a JSON object: name, role, stack `[".NET","Angular",
|
||||
"TypeScript"]`, focus `["modernization","safe AI integration"]`, since `2018`, location
|
||||
`"Sarajevo · CET"`, open_to `["senior roles","consulting"]`, closing prompt with a
|
||||
blinking cursor. Rendered from a small typed data structure in the component so it can
|
||||
change without touching markup.
|
||||
2. `// selected work` (`#work`) — heading "Production systems, anonymized." and a right-aligned
|
||||
mono count `4 case studies`. One `.panel` containing four rows (`data-testid="project-row"`,
|
||||
`routerLink` to `/work/<slug>`): index (accent on the featured first row), title + one-line
|
||||
summary (a new short `tagline` field on `PortfolioProject`, ~60 chars), up to four stack
|
||||
tags (first four of `stack`), arrow. Hover: row background `--panel-2`, arrow turns accent.
|
||||
Below 720px: grid collapses to index+title, tagline, tags stacked.
|
||||
3. `// experience` (`#experience`) — grid 340px / 1fr. Left: 96px square grayscale portrait
|
||||
(`NgOptimizedImage`, 8px radius, 1px border), label, h2 "Eight years, one product at a
|
||||
time.", about paragraph, LinkedIn link. Right: four role rows (period mono `2025 — now`,
|
||||
title + company, focus sentence), 1px dividers.
|
||||
4. `// capabilities` — three equal `.panel` cards: `01 System modernization`, `02 Full-stack
|
||||
product delivery`, `03 Safe AI integration`, each with the existing detail text.
|
||||
Single column below 720px.
|
||||
5. Contact (`#contact`) — a `.panel` with a 1px accent-tinted border and inner glow:
|
||||
label `// contact`, h2 "Need a senior engineer who can understand the system before
|
||||
changing it?", `.btn-accent` mailto button, mono `Sarajevo · CET / CEST`.
|
||||
|
||||
Structured data (schema.org Person) unchanged.
|
||||
|
||||
### Case study (`/work/:slug`)
|
||||
|
||||
Breadcrumb as a path: `~/work/` (dim) + slug (text), mono. Header: label
|
||||
`<category> · <period>`, h1 title, lead summary, then a meta strip in a `.panel`: `role`,
|
||||
`period`, stack tags. Sections keep content; labels become `// 01 context`, `// 02 delivery`,
|
||||
`// 03 architecture`, `// 04 result`; contributions as a numbered list with mono indices;
|
||||
decisions as a 2×2 `.panel` grid (single column < 720px); technology as a tag row.
|
||||
`SystemDiagramComponent` stays, recoloured: node fill `--panel`, stroke `--line-strong`,
|
||||
accent node stroke/text `--accent`, lines `--line-strong`, notes `--dim`, mono text.
|
||||
Prev/next as two `.panel` links. Contact block reused. The "View full CV" link points to
|
||||
`/cv.pdf`.
|
||||
|
||||
### Not found
|
||||
|
||||
Terminal panel: `$ open <path>` then `command not found: <path>` in `--code-num`, a short
|
||||
sentence, and a `.btn-line` back to `/`. Server still returns 404.
|
||||
|
||||
## Behaviour
|
||||
|
||||
- Motion: hero children fade-up (opacity 0→1, translateY 12px→0, 480ms, 80ms stagger) once
|
||||
on load; cursor blink 1s step; row hover transitions 150ms. All wrapped in
|
||||
`@media (prefers-reduced-motion: no-preference)`.
|
||||
- Smooth anchor scrolling with `scroll-padding-top` for the sticky header (kept).
|
||||
- Focus rings: 2px accent outline, 3px offset.
|
||||
- `<meta name="theme-color">` → `#0D1015`; `color-scheme: dark`.
|
||||
|
||||
## Server
|
||||
|
||||
`src/server.ts`: before the Angular handler, `app.get('/cv', (_, res) => res.redirect(301,
|
||||
'/cv.pdf'))`. `public/cv.pdf` is served by the existing static middleware. Until Amar
|
||||
supplies the file, a one-page placeholder PDF saying "CV coming soon — amar@dzanan.net" is
|
||||
committed so the link never 404s. `public/sitemap.xml` drops `/cv`.
|
||||
|
||||
## Files
|
||||
|
||||
Modified: `styles.scss`, `index.html`, `server.ts`, `app.ts`, `app.routes.ts`,
|
||||
`app.routes.server.ts`, `app.routes.spec.ts`, `page-shell.component.ts`,
|
||||
`navigation.config.ts`, `landing-page.component.ts` + spec, `portfolio-page.component.ts`
|
||||
+ spec, `system-diagram.component.ts`, `not-found-page.component.ts`,
|
||||
`portfolio-project.model.ts`, `portfolio-projects.data.ts`, `public/sitemap.xml`,
|
||||
`package.json`/lock (fontsource packages).
|
||||
|
||||
Removed: `features/cv/cv-page.component.ts`, `features/cv/cv-page.component.spec.ts`,
|
||||
`core/services/theme.service.ts`, `shared/ui/theme-toggle/theme-toggle.component.ts`.
|
||||
|
||||
Added: `public/cv.pdf` (placeholder), this spec, the implementation plan.
|
||||
|
||||
## Testing
|
||||
|
||||
- Unit: route spec lists routes without `cv`; landing spec asserts the new h1, four project
|
||||
rows, `a[href="/cv.pdf"]`, mailto and LinkedIn links, the four role titles; portfolio spec
|
||||
unchanged in intent; new not-found assertion optional. Run with headless Chromium.
|
||||
- Build: `ng build` (production, SSR, prerender of `/` and the four work pages) with zero
|
||||
errors and within budgets (component styles are inline SCSS; keep under 8kB each).
|
||||
- Visual: serve `dist` and screenshot `/`, one case study and `/404` at 1440px and 390px;
|
||||
fix wrapping, overflow and contrast issues found.
|
||||
- Smoke: `curl -I /cv` → 301 to `/cv.pdf`; `/cv.pdf` → 200.
|
||||
|
||||
## Delivery
|
||||
|
||||
Work happens in the cloud copy of the repo; changed and new files are written back to the
|
||||
`dzanan.net` folder on Amar's machine, removed files are moved into `_to_delete/`. Amar runs
|
||||
`npm install` locally afterwards (new font packages) and drops the real PDF over
|
||||
`public/cv.pdf`.
|
||||
BIN
Claude outputs/case-study-field-sales.png
Normal file
|
After Width: | Height: | Size: 181 KiB |
BIN
Claude outputs/home-updated.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
Claude outputs/pages-experience-contact.png
Normal file
|
After Width: | Height: | Size: 340 KiB |
BIN
Claude outputs/pages-home.png
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
Claude outputs/pages-work.png
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
Claude outputs/redesign-case-study-desktop.png
Normal file
|
After Width: | Height: | Size: 251 KiB |
BIN
Claude outputs/redesign-home-desktop.png
Normal file
|
After Width: | Height: | Size: 291 KiB |
BIN
Claude outputs/redesign-home-phone.png
Normal file
|
After Width: | Height: | Size: 258 KiB |