Skip to content
Sign inJoin waitlist

Editing the site — Tustel HTML

Every page of Tustel is a plain HTML file that you edit in a code editor. This guide shows where everything is, and how to add a project, a post or a page.

Double-click index.html: the site opens in your browser and every link works, straight from the folder. To see it exactly as a host serves it (and to test the form), run a small local server from the folder:

Terminal window
npx serve .

npm start runs the same command. Then edit the files in a code editor and reload the browser to see the change.

index.html, about.html, portfolio.html, blog.html, contact.html
404.html shown for addresses that don't exist
style-guide.html every component with its name (noindex; delete it if you don't want it)
portfolio/*.html one page per project
blog/*.html one page per post
assets/css/style.css the stylesheet (generated — see design.md)
assets/js/main.js the site's scripts (you rarely need to touch it)
assets/js/config.js your settings: form endpoint
assets/images/ photos, your portrait, the client logos, the logo as files
assets/fonts/ Inter
icon.svg, apple-icon.png, opengraph-image.png
sitemap.xml, robots.txt
src/css/style.css the stylesheet's source: colours, breakpoints, fonts

portfolio.html is the page the menu calls “Works”.

Find the words on the page and change them in the HTML. Keep the tags and classes around them, because they carry the layout. A heading looks like this:

<h2 class="text-[32px] md:text-[36px] lg:text-[42px] leading-[1.2] font-medium tracking-[-0.03em] [font-variation-settings:'opsz'_32] md:max-w-[420px]">Selected work from recent projects.</h2>

Change Selected work from recent projects., leave the class. Apostrophes and ampersands are often written as &#39; and &amp; (Let&#39;s work together, Form &amp; Field), and the demo also uses the typographic ’ (I’d love to hear about it); typing ' works too, & should stay &amp;. When you search for a sentence, search for a part without them.

Button labels are written three times: once to size the button (class="opacity-0", the copy screen readers read) and twice in the copy that rolls up on hover (aria-hidden="true"). The project titles on their cards work the same way. Change all three:

<span class="opacity-0">Book a call</span><span aria-hidden="true" …><span …>Book a call</span><span …>Book a call</span></span>

Some texts appear as the page loads: the Home hero letter by letter, page titles word by word (the About hero, Works, Blog, Contact, every project and post), labels and introductions line by line. Each is written twice: once whole, for screen readers and search engines (class="sr-only"), and once split into one <span> per letter or word for the effect (aria-hidden="true"):

<h1 …>
<span class="sr-only">Made with intention.</span
><span aria-hidden="true"><span class="inline-block" data-appear="word" data-delay="0" style="…">Made</span> </span
><span aria-hidden="true"><span class="inline-block" data-appear="word" data-delay="0.05" style="…">with</span> </span
><span aria-hidden="true"><span class="inline-block" data-appear="word" data-delay="0.1" style="…">intention.</span></span>
</h1>

To change one, write the new text in the sr-only span, then in the split copy: one pair of spans per word, each word starting 0.05 seconds after the one before it (data-delay). In the Home hero, each word holds one span per letter (data-appear="letter"), 0.05 seconds apart as well. Paragraphs that appear line by line carry data-appear="lines" and one <span data-word="true"> per word, without delays: the script finds the lines by itself.

To drop the effect, replace both copies with the plain text, <h1 class="…">Made with intention.</h1>, and remove data-appear="lines" from a paragraph.

The header, the footer, your links and your contact details are copied into many pages. Change them once for all files with your editor’s Find in Files / Replace in Files (VS Code: Ctrl/Cmd + Shift + H):

Replace With
https://tustel-html-erapee.vercel.app Your domain, e.g. https://www.yourname.com (canonical links, share cards, sitemap.xml, robots.txt)
https://cal.com/ Your booking page (Cal.com, Calendly…): the “Book a call” buttons in the header, the phone menu, the Home and About heroes, the photo band and “Let’s work together”
hello@example.com Your e-mail (“Let’s work together” on Home and every project page; in the mailto: link and three times as text)
+1 (415) 123-4567 and tel:+14151234567 Your phone, as shown and as dialled (same places)
California, USA, Within 24 hours Your location and response time (same places)
https://behance.net, https://dribbble.com, https://instagram.com, https://youtube.com Your profiles (the Home and About heroes, the footer); change the link texts (Behance, …) too
aria-label="Alex Carter" Your name: the name of the logo link for screen readers, four times per page
Available worldwide · © <span data-current-year>2026</span> Alex Carter Your own footer note; keep the <span data-current-year> for the year
| Tustel in <title> and share tags | Your Name (the Home title, Tustel - Portfolio for Photographers &amp; Creative Designers, has no suffix)
content="Tustel" Your site’s name (application-name and og:site_name)
Tustel — photographer and creative designer portfolio template A description of your share image (og:image:alt, twitter:image:alt)

Include the .html, .xml and .txt files. Review each change before replacing all: “Alex” and “Tustel” also appear in text you may want to rewrite rather than replace (your name, the Home title and description). The year in the footer updates itself (data-current-year). The Contact page shows only the form: your e-mail and phone appear in “Let’s work together”.

The logo is an <svg> drawing in the header and the footer of every page; see Making it look like your brand.

Some sections are copied into several pages. Change them in every copy (find and replace in files works for text):

Section Pages
Header and footer Every page
The photo band (“Creating Visual Stories That Inspire”) index.html, about.html
The counters (“80+ Years Experience”, …) index.html, about.html
“Let’s work together”, with your contact details index.html and every page in portfolio/
“From the journal” (three posts and “View all articles”) index.html and every page in blog/
“Other Projects” (six projects) Every page in portfolio/
The social links of the hero index.html, about.html

The demo is the portfolio of Alex Carter. The name appears in:

  • the Home hero (“Hello, I’m” / “Alex Carter”, letter by letter) and the About hero (word by word), see text that appears on load;
  • the logo drawing and the logo link’s aria-label (Making it look like your brand);
  • the footer note of every page;
  • the descriptions of About, Works, Blog and Contact (description, og:description, twitter:description);
  • the descriptions (alt) of the two “About me” photos on Home;
  • the testimonials (“Working with Alex…”).

Search the folder for “Alex” to find them all. Your role (“Photographer & Creative Designer Based in California”) is in the Home and About heroes, and your portrait is assets/images/portrait-alex-carter.jpg (the Home hero card and the About hero).

Each page’s <head> holds what search engines and share cards show:

<title>About | Tustel</title>
<meta name="description" content="…" />
<link rel="canonical" href="https://yourdomain.com/about.html" />
<meta property="og:title" content="About | Tustel" />
<meta property="og:url" content="https://yourdomain.com/about.html" />
<meta property="og:description" content="…" />
<meta property="og:image" content="https://yourdomain.com/opengraph-image.png" />
<meta name="twitter:title" content="About | Tustel" />
<meta name="twitter:description" content="…" />
<meta name="twitter:image" content="https://yourdomain.com/opengraph-image.png" />

Keep these in step:

  • The title, the og: and the twitter: versions say the same thing.
  • The canonical link and og:url are the page’s own address (Home’s is the root, https://yourdomain.com/).
  • A description of 80–160 characters shows in full in search results, and so does a title of up to 60 characters (drop the | Tustel suffix when a title is longer, as four of the demo posts do).
  • Home’s title and description describe the template: write them for your work.
  • Project and post pages use their own photo as og:image and twitter:image (https://yourdomain.com/assets/images/<file>), with their title as og:image:alt. Posts are shared as articles, with their date in article:published_time.

assets/images/ holds every photo. The easiest change is to replace a file with yours under the same name: every page that shows it updates. The download ships with grey placeholders that state the size each image was designed for (for example 2400 × 1600).

To use a new file instead, change the src: <img src="assets/images/my-photo.jpg" …>. In pages inside a folder (portfolio/…, blog/…), the path starts with ../: src="../assets/images/my-photo.jpg". In 404.html it starts at the site’s root: src="/assets/images/…".

Photos in a fixed frame are cropped to fill it, so a photo of another shape still fits: the Home slideshow, the photo band, the 404 photo, “About me”, “How I work”, “Let’s work together”, the services, the portraits and the post cards (about 1.41 : 1).

Photos that set their own shape are project covers, gallery photos and the photo at the top of a post. Their shape is written in the HTML next to the image, so when the new photo has another shape, write its width and height there too, or it is cropped to the old shape:

Where What to change
A project card (Home, Works, “Other Projects”) aspect-ratio: 2400 / 3600 twice (the photo shows sharp over a blurred copy of itself), and width and height on both <img>
The List view on Home (desktop) aspect-ratio on the photo’s link (data-portfolio-image), and width and height on its <img>
The cover of a project page, the photo of a post The number in height: min(100vh, calc(100cqw / 1.5)), which is the width divided by the height (1.5 for 2400 × 1600), and width and height on the <img>
A gallery photo aspect-ratio: 1200 / 800, and width and height on the <img>

A portrait cover makes a tall card, and the cards of a row line up at the top. The cover of a project page and the photo of a post are at most one screen tall (cropped beyond). A project’s cover is also on its cards in other pages: search the folder for its file name to change every one.

Use photos at least as large as the demo’s, which the placeholders show:

Photos Demo size
The Home slideshow 2400 px wide, landscape (they fill the screen, cropped)
The photo band (Home, About) and the 404 photo 2400 × 3600, portrait (they fill the screen, cropped)
Project covers 2400 px wide, any proportion
Project gallery photos 1200 px wide, any proportion
Post photos 2400 px wide
“Let’s work together” (Home, project pages) 1200 × 1600, portrait
“How I work” on About 1200 × 1800, portrait
“About me” on Home 1000 × 750 and 600 × 399
Service photos 800 px wide (shown 300 × 200)
Your portrait (the Home hero card, the About hero) 300 × 300
Testimonial portraits 200 × 200

A few files are used in more than one place: your portrait, band.jpg (Home and About), contact-cta.jpg (“Let’s work together” on Home and every project page), and every project cover and post photo (their page and their cards). Replacing such a file changes every place; to show another photo in one of them, use a new file there.

Use .jpg for photos and keep files small; compress them with Squoosh or TinyPNG. Write an alt text for images that carry meaning; leave it empty for decorative ones (written alt or alt="").

The ticker under the Home hero (“Trusted by creative brands worldwide”) shows seven sample logos, assets/images/client-*.svg, 25 px tall at their own width. Replace the files with your clients’ logos (or change the src, for a PNG), the alt with each client’s name, and the width and height with the logo’s size at 25 px tall (width="62" height="25"): they keep its space while it loads. The row is written three times inside the ticker (data-ticker-copy="0", "1" and "2") so that it loops without a gap: make the same change in all three. If you change the line above the logos, change the aria-label of the box around the ticker too.

To drop the section, delete the <section> that holds “Trusted by creative brands worldwide”. It also tells the solid header on Home when to appear (data-header-reveal): add that attribute to the next <section> (“About me”), or the header that comes back as you scroll up never shows on Home (Making it look like your brand).

Pages link to each other as about.html, portfolio.html, portfolio/<slug>.html; from inside a folder, add ../ (../contact.html). Keep the .html: it’s what lets the site work from any host and from disk. 404.html is the exception: its links start at the site’s root (/contact.html), because hosts show it at any address.

Links that start with https:// (the booking link, the social links) open in a new tab (target="_blank"); mailto: and tel: links open the visitor’s mail app or phone.

Home and About show four counters (“80+ Years Experience”, “120+ Projects Completed”, “45+ Happy Clients”, “18 Awards Received”). Each number counts up by one every 5 ms, from data-from to data-counter, when it scrolls into view:

<span data-counter="120" data-from="40" class="…">40</span><span class="…">+</span>

Change the numbers in index.html and about.html, and write the starting number as the text too: it is what shows before the count starts. The + is the span after it; delete that span for no suffix, as for the awards. Write whole numbers, and keep the distance between data-from and data-counter to a few hundred (a counter to 5000 from 0 would count for 25 seconds).

  • The slideshow shows three photos (hero-1.jpg to hero-3.jpg), a new one every 5 seconds. Its track holds the three slides and then a copy of the first, which lets it loop: replace hero-1.jpg in both, and keep data-count="3" on the data-slideshow element equal to the number of photos without the copy. To add a photo, copy the second slide (it carries aria-hidden="true" inert), paste it before the last one and raise data-count.
  • The card (“I specialize in”, with your portrait) scrolls five specialities upwards. They are written four times: twice in the card and twice in the faded lines above it (data-ticker-copy="0" and "1" of each of the two tickers). Change all four, in the same order.
  • The texts appear letter by letter (text that appears on load); the buttons, the card and the social links rise into place after them.
  • The services (“What I Do” on Home): pointing at a service on a desktop (or tapping it on a tablet) shows its title, text and photo beside the list; on phones, the chosen service opens under its name. Each service is written twice: in the list, as a button (01 — Photography) followed by the panel phones open (id="services-0"), and beside the list, in a data-service-details block. The first is chosen when the page loads: its button is orange (style="color: #eb4b3d; opacity: 1", aria-expanded="true") and its panel open (style="height: auto"); the others are faded (style="color: #000000; opacity: 0.3"), their panels closed (style="display: none; height: 0px") and their details hidden. To add a service, copy the last <li> of the list and the last data-service-details block, paste each after its original, and edit both: the number and name on the button (“06 — Retouching”), its data-service and aria-controls (5, services-5), the panel’s id (services-5), and the title, text and photo in both copies.
  • The testimonials (“What clients say”): a slideshow like the hero’s, with a quote, a round portrait, a name and a role per slide, then a copy of the first slide so that it loops. It moves on every 8 seconds, and the arrows step through it. To add one, copy a slide that is not the first (it carries aria-hidden="true" inert), paste it before the last slide, edit it and raise data-count by one. When you change the first testimonial, change its copy at the end too.

Edit the text and keep these attributes: the site script relies on them.

“My Portfolio” on Home shows the first six projects on desktops and four on tablets and phones (the fifth and sixth cards carry class="hidden lg:block"). On desktops, “Catalog” and “List” switch between the cards and a list of titles: pointing at a title shows its photo, category and summary. The List view is three lists in the same order, after the cards:

  • the photos (data-portfolio-image, one link each);
  • the titles (data-portfolio-row);
  • the details (data-portfolio-details: the category and the summary).

The first project is the active one: its row has style="opacity: 1; color: #eb4b3d", and its photo and details have no hidden; the others carry hidden and their rows style="opacity: 0.3; color: #000000". To change which projects Home shows, change the card and its three List view entries together.

Works (portfolio.html) and the Blog hold every project or post, but show six on desktops and four on tablets and phones; more appear each time the visitor scrolls to the spinner under the list. The list is <ul data-paged-list data-page-size="6" data-small-page-size="4">: the first four cards are <li class>, the fifth and sixth <li class="max-lg:hidden">, the others <li class="max-lg:hidden lg:hidden">. Keep that pattern when you add or remove cards (the script also recounts them when the page loads). To show more at a time, change the two numbers and the classes with them. Every card is in the page’s HTML, so search engines find them all.

The lists keep the order of the HTML: the Blog doesn’t sort posts by date, so put a new post where it should show.

A project is a page plus its cards in the lists:

  1. The page. Copy an existing one, e.g. portfolio/aurora-coffee.html → portfolio/lumen-studio.html. Use lower-case words joined by - for the file name; it becomes the address. Edit:

    • the title (text that appears on load) and the four details under it (Client, Category, Year, Timeline);
    • the cover: its src, alt and size (images);
    • “Project Description” (one <p> per paragraph), “Project Details” (Industry, Deliverables, Timeline, Scope) and “The Challenge”;
    • the two galleries: each has two columns of photos, the first half of its photos on the left and the rest on the right; copy a photo’s block to add one, and give each photo its size;
    • the <head>: title, description, canonical, og:url, and the cover as og:image and twitter:image.

    “Other Projects” and “Let’s work together” stay as they are.

  2. Works. Copy a card (<li>) in portfolio.html and paste it where the project belongs. Edit its link, its photo (src, width, height and aspect-ratio, twice each), its title (three times) and its category, and keep the classes of the cards in their pattern (the lists).

  3. Home, if the project should be among the first six: add its card to the grid and its photo, title and details at the same place in the three lists of the List view (the portfolio on Home), and remove the sixth project from each, so that six remain. The fifth and sixth cards of the grid keep class="hidden lg:block".

  4. Other Projects. Each project page lists six other projects at its end. Copy a card there in the pages where the new project should appear.

  5. The sitemap. Add a line to sitemap.xml:

    <url><loc>https://yourdomain.com/portfolio/lumen-studio.html</loc></url>
  1. The page. Copy a page in blog/, e.g. blog/the-power-of-a-strong-brand-foundation.html → blog/my-new-post.html. Edit the category, the title and the excerpt (text that appears on load), the photo (src and size, images), the text, and the <head>, with the post’s date in article:published_time and its photo as og:image and twitter:image. The text is plain HTML: paragraphs are <p class="mt-5 first:mt-0">, headings <h2 class="… mt-10 first:mt-0"> and lists <ul class="mt-5 pl-5 first:mt-0 [list-style-type:disc]">, for the space above them; <em> sets a word in italics, <br /> starts a new line inside a paragraph. The page itself shows no date: the cards do.

  2. The Blog. Copy a card in blog.html and paste it where the post belongs. Edit its link, photo, date (the <time> element’s datetime and its text, Oct 6, 2026), category and title, and keep the classes of the cards in their pattern (the lists).

  3. “From the journal”. Home shows the first three posts of the Blog, and every post the first three others. Copy a card there for the new post to appear, and remove one so that three remain.

  4. The sitemap. Add a line with the post’s date:

    <url><loc>https://yourdomain.com/blog/my-new-post.html</loc><lastmod>2026-10-06</lastmod></url>

To remove a project or a post, do the reverse: delete the page, its cards, any link to it and its line in sitemap.xml. Search the folder for the file name to catch any link left behind.

  1. Copy about.html and rename it, e.g. services.html. About opens without a photo, so it has the solid header; a page whose first section carries data-header-cover gets the header over the photo, like Home (Making it look like your brand).
  2. Replace the sections inside <main> with the ones you want. Every section in the template is a block you can copy from its page (or from style-guide.html) and paste between <main> and </main>. Without a photo at the top, the first section needs room for the header, like the first section of Works, Blog or Contact (pt-[110px] md:pt-[130px] lg:pt-[150px]).
  3. Update the <head> (title, description, canonical, og:url, and the og: and twitter: titles and descriptions).
  4. The copy marks About as the current page: remove aria-current="page" from its six About links (the header has three bars, and each has a menu for desktops and one for phones).
  5. Link to it: in each of the six menus, copy the <li> of a neighbouring link and change its href and its text. The header is the same in every page of a folder apart from those aria-current marks, so once one page is done, copy everything from <header to <main> into the others and mark each page’s own links again (pages in portfolio/ and blog/ mark none, and 404.html writes its links from the root, /services.html). Add the page to sitemap.xml.

Delete the file, remove its links from the six menus of every page and its line from sitemap.xml. Search the folder for the file name to catch any link left behind: buttons link to pages too (“View my works”, “More about me”, “View all articles”).

style-guide.html shows every component with its name, which is handy for copying a button or a card. It’s hidden from search engines. Delete it before publishing if you don’t want it online; its sample form never sends anything.