Skip to content

Repository files navigation

kdrgny.com

A credibility page. Someone searches the name, lands here, and quickly knows who Kadir Günay is, what he can be hired for, where he has worked, and how to reach him. Not a portfolio — the CV lives at cv.kdrgny.com.

npm install
npm run dev        # http://localhost:5180
npm run build      # → dist/
npm run preview    # serve dist/ on :4173

dist/ is plain static files — no server, no runtime, no third-party requests. Drop it on Vercel, Netlify, Cloudflare Pages or GitHub Pages as-is.

Shape

Four files carry the whole site.

Path
index.html every word on the page, plus meta and JSON-LD
src/styles/main.css type, layout, surface, light and dark palettes
src/styles/fonts.css the four @font-face declarations
src/main.js one IntersectionObserver, plus the name reveal

Things worth knowing

  • The page works with no JavaScript. The reveal is additive: JS puts .rise on <html>, and only then does anything start hidden. If the module never loads, the page is simply already visible.
  • .name__ch spans are created at runtime. index.html holds the name as one string; JS splits it, freezes each glyph's width, and varies weight by pointer distance. Freezing the widths is not optional — without it every weight change reflows the line.
  • --lx, --ly and --sy are unitless numbers set on <html> by JS and multiplied into percentages inside the .light gradients. Pointer, pointer, scroll progress.
  • Never hard-code the years. src/lib/since.js holds SINCE = 2007 and spells the count out. vite.config.js substitutes __YEARS__ in the HTML at build and at dev-server start, so crawlers and no-JS visitors get the current figure; main.js rewrites every [data-years] on load, which covers a year in which the site is never rebuilt. Add data-years to any new mention.
  • .name line-height is 1.26 for a reason. Fraunces measures 1.235em from ascent to descent, and the reveal clips to the line box — anything tighter guillotines the descender of the y in Günay. Measure with measureText().fontBoundingBoxAscent/Descent before changing it; do not eyeball it.
  • Fonts are declared by hand. Fontsource's per-subset entry points ship no unicode-range, so importing latin and latin-ext together leaves two faces claiming every codepoint — and the one holding no basic Latin wins. The type falls back to a system serif with no error and no warning.
  • Fraunces keeps its optical-size axis (opsz 144 for the name, 12 for the numerals, 28–40 in between). That axis is why the face is here; it costs 31 kB over the weight-only file.
  • Latin-ext is not optional. Doğuş needs it. Company names are set in Fraunces partly for that reason: Fraunces' latin-ext file is 26 kB lighter than Inter's.
  • Dark is the base, light is opt-in. :root carries the dark palette with no attribute and no media query, so there is nothing to resolve before the first paint. :root[data-theme='light'] overrides it. The OS preference is deliberately ignored; the inline script in <head> reads localStorage['kdrgny:theme'] before CSS so a returning light-theme visitor never sees the dark default flash. Switching back to dark removes both the attribute and the stored value — the default leaves no residue.
  • Both palettes are authored, not one inverted from the other. Changing a colour means changing it in two places on purpose.

Editing the content

All of it is in index.html, in reading order. When the role changes, update the eyebrow, the first .role, the JSON-LD jobTitle and worksFor, and the <meta name="description">.

Regenerating og.png and apple-touch-icon.png

Both are committed. qlmanage -t renders SVG including @font-face with base64 woff2, but always fits it into a square, so the card is authored 1200×1200 with the artwork in a centred 630-tall band and cropped back out with sips -c 630 1200.

About

hi

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages