# About Me Page

Grayscale developer portfolio fully rendered in JS by PDRenderKit 1.5.2 from a PDConfig object, with scroll-spy nav, tabs and portfolio filter.

## Overview

| Item | Value |
|---|---|
| Created | 2023-06-13 |
| Category | Personal Examples |
| HTML files | `index.html` |
| Source | [target/20230613](https://github.com/pardnio/demo-web/tree/main/target/20230613) |

## Live Preview

<iframe src="/target/20230613/" title="About Me Page" loading="lazy" style="width:100%;height:640px;border:1px solid #e5e7eb;border-radius:8px"></iframe>

[Open the example in a new tab](/target/20230613/)

## Page Sections

| Section | Description |
|---|---|
| Nav (#nav) | Title from PDConfig.nav.title, 7 items (Home..Contact) in #nav-list with index-driven highlight, hamburger #button-tab; gets .min after scrolling. |
| Header | Social icon column, name, subtitle, description, Contact button, Scroll Down hint, and avatar in a rotated blob frame animated via border-radius keyframes. |
| About Me | Image, 3 stat items (Full-stack, iOS, Examples), intro paragraph and Contact button. |
| Skills | Front-end and back-end columns, each listing 4 technologies with years and check icons. |
| Services | 3 cards (iOS, Front-end, Back-end) with View More buttons (no handler). |
| Experiences | #tab-experience switches between Education and Experience timelines via the parent section's show attribute (initial show=1). |
| Portfolios | #tab-portfolio (All / Lorem1 / Lorem2) and #body-portfolio grid of 20 placeholder images filtered by tag-filter / tag-key. |
| Contact Me | Email and LinkedIn cards with Open buttons (no handler) and a 3-field message form whose labels come from label[key] via CSS attr(). |
| Footer | Brand, GitHub / LinkedIn / mail icon links and copyright. |
| Scroll-to-top button | Fixed #button-scrollTop shown once scrolled past the header. |

## Interactions

- js/index.js builds the whole page with document.body._child([...]) using PDRenderKit element factories ("tag#id"._(attrs, children), "i.fa-x"._(), array._$(map), string._fa, ._open(href), ._go(href)).
- Content strings come from the inline const PDConfig (nav, header, icon) declared in index.html.
- Nav item click closes the mobile menu and jumps body.scrollTop to the sum of preceding section heights; #button-tab toggles #nav-list.show.
- Body scroll listener: toggles #nav.min via $$_class(scrollTop &gt; 0), sets #nav-list[index] (scroll-spy, vh/3 offset) and shows/hides #button-scrollTop.
- Experience tab click sets show=i on the tab's parent; portfolio tab click sets #tab-portfolio[index] and #body-portfolio[tag-filter].

## Dependencies

| Name | Version | Source |
|---|---|---|
| Font Awesome Free | 6.5.2 | https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.2/css/all.min.css |
| PDRenderKit | 1.5.2 | https://cdn.jsdelivr.net/npm/pdrenderkit@1.5.2/dist/PDRenderKit.js |
| Google Analytics (gtag.js) | - | https://www.googletagmanager.com/gtag/js?id=G-L5VYEZPVXX |
| js/index.js | - | ./js/index.js |

## Styling

| Item | Value |
|---|---|
| SCSS entry | `sass/index.scss` |
| Output CSS | `css/index.css` |
| Partials | `_nav.scss`, `_footer.scss`, `_header.scss`, `_about.scss`, `_skills.scss`, `_services.scss`, `_experiences.scss`, `_portfolios.scss`, `_contact.scss` |

index.scss: reset, body scroll container, fixed #button-scrollTop; partials style each generated section. _nav handles .min shrink, mobile .show overlay and [index] highlight; _header has mouse-animation and head-animation (morphing border-radius blob); _experiences toggles lists via [show]; _portfolios uses [index] and [tag-filter]/[tag-key]; _contact prints label text with attr(key). Grayscale --col-brand-1..9 and --width-max 1280px are in an inline &lt;style&gt;.

```bash
cd target/20230613
npx sass sass/index.scss css/index.css --no-source-map || exit 1
```

## Techniques

- Config-driven rendering: page content in a global PDConfig object, markup produced entirely by JS (body contains only the config script).
- Attribute-state CSS ([index], [show], [tag-filter] + [tag-key]) toggled from JS instead of class juggling.
- Morphing avatar blob: animated border-radius keyframes on a rotated container with counter-rotated image.
- content: attr(key) for form labels; breakpoints 480px, 640px, 800px, 960px, 1024px.

## External Assets

- https://fakeimg.pl/1024/282828/eae0d0/?text=sample (avatar, about image, portfolio placeholders)
- https://pardn.io/image/head.png (favicon)
- https://pardn.io/web-template/image/20230613.jpg (og/twitter image)

## Related

- [Project Structure](/project-structure)
- [Styling Workflow](/styling-workflow)
- [Frameworks](/frameworks)
