Skip to content
D. Svilenković
01Work02Services03Industries04Guides053D06Check your site07Contact

HomeWorkFOX Models

FOX Models

a modeling agency website without a single line of 3D

Same agency, same content, a different technical decision. When the content of a site is someone else's face, every effect standing between the visitor and the photo is a cost — so this version was written in plain HTML, CSS and JavaScript, with no framework and no build step. The working version is on our subdomain, open for review.

  • Multi-page website
  • Belgrade
  • August 2026
  • 13 min read
  • HTML
  • CSS
  • JavaScript without libraries
  • nginx
Customer
FOX Models, modeling agency
Industry
Model boards, scouting, booking
City
Belgrade
Type
Redesign of a multi-page website, without 3D
Technologies
HTML · CSS · JavaScript without libraries · nginx
Scope
6 page types, 17 model profiles, no build step
Website
models.svilenkovic.rs
Status
Live on our subdomain, closed to indexing
Home page of the FOX Models website, split into two panels, W for women and M for men
Home page — two panels, W for the women's board and M for the men's, with the agency name over the image

01 / 10

Who FOX Models is and whose site this is

FOX Models is a modeling agency from Belgrade. It runs a women's and a men's board, scouts new faces and places them with fashion houses, magazines and brands — from the first test shoot to the campaign. The agency's job is to put the right face in front of the client who is choosing, and the website is the first place where that choice begins: you open the board, browse it, remember two names and write to booking.

Let us be clear right away about whose site this is. models.svilenkovic.rs is our subdomain, and it hosts the working version of the redesign for the agency. The agency's official site is still foxmodel.com, so this version is closed to indexing and points search engines to it. The names, measurements and some of the photos are demo content kept in one place in the code, and when the site moves to the agency's real domain they are replaced with data from its database.

That is why the text below has no numbers on traffic, inquiries or campaign results. There is only what can be opened and checked: how the site is put together, why it was built this way and not another, where it broke and how it was fixed.

The women's Main Board with model photos
Women's board — Main Board with search and the New Faces and Commercial subnavigation

02 / 10

Two versions for the same agency, and why this one was taken further

Two sites were built for FOX Models, not one. This one is light and classic, without a single line of 3D. The other was dark, with a 3D ring of photos that rotated as you scrolled. Same content, same agency, two completely different impressions.

The reason for two builds is simple. At a fashion agency, the owner's taste decides more than any feature list, so instead of guessing we built two extremes: maximum atmosphere and maximum quiet. When the agency looked at both, the answer was that the richer version was too much and that the home page should be much simpler, with a reference to Scandinavian agency sites that show nothing but faces.

This is where the whole case study turns. 3D is not a bad choice because it is 3D, but because on this site it eats into the only content there is — the photograph. When a client comes to look through a board, every effect between their eye and the face is a cost someone pays. That is why the classic version got all further work and every round of revisions, while the 3D one remained as the answer to the question of where the upper limit of atmosphere lies.

The decision carried over to the typography too. The original pairing of a serif heading with a second typeface for body text was replaced with a single grotesque everywhere — the same typeface for headings, measurements and navigation. Fashion sites rarely mix two typefaces, and when they do, it is usually the only ornament anyone remembers.

The Editorials page with covers and campaigns
Editorials — a wall of covers, editorials and campaigns the models worked on

03 / 10

What needed solving

A modeling agency site looks like an ordinary gallery until you sit down to build it. Then it turns out there are five requirements pulling in different directions:

  • The photo is the product. Anything that sits on top of the image, crops it or stretches it works against the site. The framing has to be right at every width, from a phone to a large monitor.
  • A board is not read, it is scanned. The client does not read descriptions but runs their eye over the faces and stops at one. The grid has to be fast, and the basic measurements within reach without opening the profile.
  • Every model is their own address. A profile gets forwarded to a colleague, opened on a phone and pasted into a message, so it needs its own URL, its own title and its own preview image.
  • Applying as a new face is not the same as booking. Scouting submissions come from strangers, from a phone, with two or three photos. That is not the same form, and it must not look the same.
  • In the end, the content comes from a database. On the real domain, models and editorials are served by PHP from the agency's database, so the front end has to be written so it does not care where the data comes from.

The last point decided the technology. When you know in advance that the content will one day come from a database and will change more often than the code, a site that has to be rebuilt with every change works against itself.

04 / 10

The home page: two letters and nothing else

The first screen is exactly as tall as the device screen and is split into two panels: the left half leads to the women's board, the right half to the men's. Over each panel stands one huge letter — W on the left and M on the right — and below it a small caption with an arrow. The agency name is at the top, over a soft dark gradient that keeps it readable even when the photo underneath is light.

A detail nobody notices, but one that was explicitly requested: the letter M is not an M. It is the same W turned upside down, so the two panels are symmetrical twins instead of two different characters. That is why the lift on hover had to be written so the rotation stays in place, because an ordinary translate animation would quietly cancel it and the M would flip back into a W mid-motion.

Choosing the photos for the panels is not about aesthetics but about checking on a wide screen. On the panel the image scales to the width, with no horizontal cropping, so on a 1920-pixel monitor you see the whole frame. The first image for the men's panel had a full brand logo on the clothing, which did not show at all at the three smaller widths, and it was replaced with another. For the same reason, the selection below left out magazine covers with the magazine's name printed on them and a photo with ad copy across half the frame — an agency site must not look like it is advertising someone else's brand.

Below the first screen comes a section called Featured: eight faces, four from the women's board and four from the men's, balanced and with Main Board first. There was also a quiet bug here. The order of the boards is read from a table in which Main has the value zero, and zero is a falsy value in JavaScript, so the fallback number overrode the real one and Main Board would have ended up last instead of first. The fix is to check whether the key exists at all, instead of relying on it not being empty.

05 / 10

Boards, tabs and the A–Z index

The women's and men's boards are separate pages, not two states of the same page. The women's board and the men's board have the same subnavigation: Main Board, New Faces, Commercial and, set slightly apart, Contact. Every board has its own address, so a link to New Faces can be sent as a link to New Faces, not as instructions to click somewhere else.

Above the grid are a name search that works as you type and a count of the models shown that updates on the fly. Next to them is an A–Z index with Serbian letters, including Č, Ć, Đ, Š and Ž, in which letters without a single model are visibly grayed out and cannot be clicked. An index where a letter leads to an empty page is worse than no index at all, because the visitor thinks the site is broken.

The index itself hides on small boards and appears only when a board has twelve or more models. On a demo board of six faces, an alphabet with almost every letter grayed out looks like a bug; on the agency's real board, with several hundred names, the same strip is the fastest way to get to a surname. Same logic, two different behaviors, with no code changes when switching to the database.

The card shows the photo, name and city. On hover, a layer slides down over the image with the full set of details — height, measurements, shoe size, hair, eyes, the board label and a prompt to open the profile. On touch screens there is no such layer, because a phone has no hover: there the photos are clean and the details are read on the profile. The same code draws the same card on the home page, on the board and below the profile, so the display cannot drift apart between the three places.

06 / 10

The model page and booking by email

The profile is split into a gallery on one side and details on the other: the board label, name, city, then a tidy list of measurements — height, bust, waist, hips or suit size, shoe size, hair, eyes. Below them are two actions: Booking inquiry and the agency's Instagram account.

Booking deliberately stayed as email. A click opens the mail app with the recipient filled in, a subject line with the model's name and a message body that already contains the name, city and a link to the profile, with blank lines for the project, dates and contact. A client booking a model does it from their own inbox, because the inquiry has to stay in the email thread and be forwarded to a colleague. A form on the site would pull them out of the tool they actually work in and give the agency a message with no history.

Below every profile are four faces from the same board and a link to the full board. That is the only navigation that really works on a site like this: someone who opened one profile is rarely looking for that exact face, but for a face of that type.

The buttons on the profile went through a round of revisions. The first version was outlined pills, which looked cheap on the light page, and they were replaced with thin text links with an underline and an arrow. On a fashion site, a button that shouts is the only element people remember instead of the photo. For the same reason, the mobile menu was reduced to two straight lines that cross when it opens.

07 / 10

Editorials and the lightbox

The Editorials page is a wall of covers, editorials and campaigns — ELLE, Grazia, Stylist, Legend, Terranova — with the title and type of collaboration under each item. A click opens a full-page view.

The lightbox was also written for the keyboard: the arrow keys page through, Escape closes it, focus stays trapped inside the view while it is open and returns exactly to the image it started from. On a phone you swipe through, the neighboring image is preloaded so the transition does not wait, and a counter shows where you are in the sequence. A gallery that cannot be closed with a key is a gallery that some visitors leave by closing the entire browser tab.

Images rendered by JavaScript fade in softly when they arrive, instead of popping in and pushing everything below them. The static images on the first screen have no such delay — the hero photo is what gets measured as the largest element on the page and has to be there immediately, so it loads with priority and without a single effect in the way.

08 / 10

No build step: about seventy kilobytes of custom code

The site is written in plain HTML, CSS and JavaScript. No build step, no framework, not a single library. All of the custom code is three files — styles, behavior and data — about seventy kilobytes in total before compression, and the server sends them compressed. The only external thing the page pulls in is the font.

The content lives in a single data file: seventeen models, twelve on the women's board and five on the men's, and ten editorial items. The fields in that file were deliberately written to match the columns that PHP will return from the agency's database on the real domain — one model is one row in a table, editorials are another table. Moving from demo data to the database is therefore a swap of the source, not a rewrite of the site.

That is also the main practical difference from the 3D version. That one was a Next.js project that had to be rebuilt on the server with every content change, installing dependencies and assembling all the static pages. Here the changed file is copied to the server and that is the whole job. Deployment is direct, with a backup of every file before it changes, no middleman and no step that might one day fail because of someone else's change in some package.

There is also a safety net in case JavaScript fails. In the head, a marker saying that scripts are running is set on the document right away, and the reveal on scroll depends on that marker. If after loading it turns out that the site header was not rendered, the marker is removed and everything that was waiting to appear becomes visible at once. A site without scripts is not pretty, but it is readable — and a site that silently stays blank is a lost visitor.

Responsiveness was checked from narrow phones to very wide monitors. Horizontal overflow is clipped at the document level, so the page does not wobble left and right even at 320 pixels, and long URLs and email addresses in the footer wrap instead of pushing the layout past the edge. The content has a maximum width, because a grid of faces stretched across an entire very wide screen is no longer a grid but a strip.

09 / 10

Two bugs that only showed up on a phone

First: visitors on phones got stuck on the old version and had to clear their cache manually to see changes. The cause was not in the code but in the server configuration — styles and scripts were sent with an instruction to be kept for thirty days without being revalidated at all. That directive only makes sense for files with a content hash in the name; here the name was the same every time, so for a month the browser kept showing what it had stored, no matter what changed on the server.

The fix had two parts. Styles, scripts and HTML are now always revalidated with the server; if nothing has changed, the server replies with a short “unchanged” and does not send the content again. Images are still cached for seven days, but without the ban on revalidation. On top of that, the URL of the styles and scripts was changed once, because a rule change does not apply retroactively to what the phone has already stored — only a new URL unsticks a cache like that.

That fix came with two surprises worth more than the fix itself. First: as soon as you add your own header to one part of the configuration, the inherited security headers quietly disappear from that part, so they have to be added back into every such block — otherwise fixing the cache costs you the protection, and nobody notices. Second: the file the server actually reads was not a link to the file being edited but a separate file with its own content, so the first changes had no effect at all and it looked as if the server was ignoring the configuration.

The second bug was worse, because it looked like a bug in the code: whichever model you clicked, the same person opened — the first one on the list. Locally everything worked; on the live site it did not. The cause was a line in the configuration that redirects old URLs with an extension to clean ones: it redirected correctly, but in doing so it dropped the part of the URL that says which model is meant. So the page received an empty value and showed the first one in the list. The same thing affected the prefilled booking inquiry. The fix is one addition to that line that passes the query string along.

Both bugs are worth recording for the same reason: neither is visible in the site's code, and neither would have been found by testing on a local machine. They only show up when the site is opened the way a visitor opens it.

10 / 10

SEO, closed indexing and what the agency gets

Everything search needs is already in place. Every page has its own title, description and canonical URL; the home page carries data about the agency and the site, the boards carry the list of models as a collection, the profiles carry person data and a breadcrumb trail, the editorials carry a gallery. The URLs are clean — /women, /men, /editorials, /contact — and old URLs with an extension are permanently redirected to them.

Along with that comes a move that looks like an oversight until it is explained: the site is closed to indexing, and the canonical URL points to the agency's domain. On our subdomain it should not be in search, because it would show up as one more result for the agency's name and split the signals between two addresses. It is one line that comes off on the day of the move to the real domain, and then everything listed above starts working for the agency instead of just sitting there.

On the Contact and Apply page there is also a part that is not about technology but about protecting the industry: scouting is always free, the agency never asks for payment to join a board and never makes contact through unofficial accounts. Fake scouts on social media are a real problem in this business, and the only thing a website can do about it is state clearly what genuine contact looks like. To be open about the limits of this build: the application form validates the fields, accepts two to four photos by drag and drop and shows a confirmation, while actually sending and receiving the photos gets wired up at the move to the real domain, to the same server layer that will then also serve the model data.

What the agency gets in the end. A site that opens instantly because there is nothing to execute; a profile for every model with a URL that can be sent to a client; a board that can be filtered and searched instead of scrolled to the bottom; one file that its database plugs into, so adding a model does not mean calling us; and a design that does not compete with the photos. No subscription, no dependencies going stale and no build step that one day stops working.

And the part this case study exists for in the first place. The 3D version is stronger on the first screen; this one is better for the work done every day. When the content of a site is someone else's face, the best technical decision is usually the one nobody notices.

On a phone

The same site, in your hand.

Most visitors come from phones, so the layout, buttons and images are arranged for the small screen first.

FOX Models on a phone

Questions

What clients ask.

Why does this version have no 3D when a 3D one exists too?

Because on a modeling agency site the photograph carries the whole job, and every effect around it uses up attention meant for the photo. After comparing both versions, the agency asked for a much simpler home page, so this one got all further work. The dark 3D build served as an answer to the question of where the upper limit of atmosphere lies.

Why no framework and no build step?

Because the content is the only thing that really changes here. All of the custom code is three files totaling about seventy kilobytes, so every change means copying one file to the server. With a site that has to be rebuilt, the same change means installing dependencies and assembling every page — and one more step that can fail.

Can the agency add models on its own?

In this build the content sits in one place in the code, because it is a showcase. The fields in that file are already arranged to match the columns of the agency's database, so when the site moves to the real domain the data source is swapped without touching the design, and models and editorials are managed through the admin area.

Why doesn't the site show up in Google search?

It is deliberately closed to indexing because it sits on our subdomain. If it were open, it would compete with the agency's real site for the agency's own name and split the signals between two addresses. The block is one line in the head, and it comes off the day the site moves to the agency's domain.

Why does a booking inquiry go by email and not through a form?

Because a client booking a model works from their own inbox — the inquiry has to stay in the email thread and be forwarded to a colleague. A click on the profile opens a message with the recipient filled in, a subject line with the model's name and a body that already contains the city and a link to the profile. A form would pull them out of the tool they actually work in.

Why don't a model's measurements show on a phone when you tap the card?

Because a touch screen has no hover, so the measurements layer would either sit over the photo all the time or appear on the first tap instead of opening the profile. That is why the photos on a phone are clean, and the full set of details is on the model's page, which the same tap takes you to.

Related projects

From the same field.

Next projectBalkan RPOur own demo · Serbia

→Contact

Have a project? Write to us.

Four short questions, about a minute of your time. We reply within 24 hours.