Notes on type and the page
Notes on type, space, bilingual pages, and what a scene costs.
These notes treat right-to-left as part of the layout from the first pass: page direction, logical properties, and a Persian route that is not a mirrored English page. The main blog lists other subjects as well, so this archive is only the writing that carries this tag.
#persian6Persian on this site is a writing system and a layout direction, not a string that was translated at the end. These notes stay with the language of the page, the line, and an interface designed for Persian first.
#typography5This archive stays with the letters themselves: font choice, weight, spacing, and a face that changes when the language changes. It is not a stand-in for the full blog, and a note belongs here only when type is the subject.
#bilingual5Bilingual here means two real routes, not one page with the language swapped after the fact. The notes in this list keep Persian and English together in the layout, the URL, and the writing.
#performance4Page speed is whatever actually reaches the browser: a static file, an extra script, and the cost an effect charges before anyone sees it. This list is only the notes about that cost.
#reading3Reading on a screen comes down to line length, contrast, and how long the eye can move without fatigue. This tag collects the notes that take that reading experience as the subject.
#static2A static page is built ahead of the visit, so the host sends files instead of rendering a template each time. This archive gathers the notes about that output, the file host, and how far a site can go without a backend.
#motion2Motion on this site has to mean something, and it has to step aside when the system asks for less movement. The notes here are the ones that treat animation, transition, and stillness as a design decision.
#numerals1Persian and Latin digits do not behave the same inside one bilingual interface: the glyph, the thousands separator, and the way a number sits inside a right-to-left sentence. Only notes that actually open that problem are listed here.
The author is the about page
The about page is the author: Mohammad Honarvar, the portrait at /portrait.jpg, and Telegram @MH759. The page does not invent a public biography.
The link you send is one language
Copy, Telegram, and X send only this page URL. og:locale is fa_IR or en_US, and hreflang for the other language is written only when that twin file exists.
The HTML map is a page you can read
The HTML map at /fa/map/ and /en/map/ groups pages, the topics, every note in that language, and two cases. A new post is on the map after the next build.
Up to three notes that share a tag
Related notes are at most three same-language posts that share a tag, ranked by shared tags and then by date. The previous and next links are a separate list.
A topic page is not the blog index
A topic page lists a few notes on purpose. /en/topics/rtl/, /type/, and /speed/ are not the blog, and the Persian hubs are separate addresses.
The words are in the document first
The reveal class is visible by default. Only html.is-motion hides those lines, and that class is added when home or projects actually start animating.
The heading does not wait
The home heading is already in the HTML. The intro canvas keeps to the free space beside it, and skip works at once, before the font or the particles.
Focus starts where the reading starts
The skip link is first in Tab order and uses inset-inline-start, so on a Persian page it sits at the right. The focus ring does not invent a second edge.
The face swaps. The line stays.
Persian pages set Vazirmatn first for fa-IR. Inter on this site is Latin and Latin-extended only, and both variable faces declare font-display: swap.
Persian digits are not a font feature
Persian digits here are fa-IR characters drawn by Vazirmatn. Inter omits that range, OpenType never swaps the figures, and GitHub stars stay Latin.
The measure of a line
How this site sets the reading line: a 70ch article column, line-height 2 for Persian prose, and a drop cap that only English essays may use.
The translation is a second file
An hreflang pair is the same filename in the other language folder. A tag archive is indexed only when that name is in tagPairs.
The canonical address is the page itself
Persian and English are two files. hreflang is emitted only when the twin exists, and each page’s canonical URL is its own address, not the other language.
What a static page owes the reader
A static Astro page owes the sentence first: HTML already built, fonts that swap in, and no Three.js, GSAP, or Lenis billed to the essay itself.
When the animation stays out
GSAP and Lenis stay unloaded on articles and whenever reduced motion is set. The home intro can be skipped at once, before the particles finish.
Direction does not finish the page
dir on the html element sets the line’s start, not the font, the digits, or the canvas. Gradients, transform origins, and a few ltr islands stay manual.
Two routes, not a flipped page
How this site keeps Persian and English apart — separate URLs, direction, Vazirmatn, and a solar calendar — without pretending a missing translation exists.
This site
Mohammad Honarvar’s personal site, static in Astro, TypeScript, and Three.js. Persian and English are two addresses, and client work is not written up here.
Type, space, and the motion of a page
Font weight, Persian line height, and motion on this site — Vazirmatn, Inter, word-level splits, and when Lenis is allowed to load.
A static page, and when the scene earns its keep
This site is a static Astro build. Three.js runs on the home hero and the projects city, not on essays — and the intro can be skipped at once.
Put right-to-left in on day one
Persian and English here are two pages from the start. Direction, Vazirmatn, and the private card arrive with that layout, not as a patch added at the end.
Why I rebuilt this site
The first post on this blog: the site is static Astro and Three.js, and motion loads only when that page asks for it and reduced motion is off.