How to make a website look expensive

Expensive is restraint plus consistency, written as values: a 1.25 type scale, an eight pixel grid, two easing curves and five hex codes.

One frosted glass composition of extreme restraint floating in vast black space, only four elements in it, perfectly aligned, with enormous empty margins
One surface, one light, one shadow. The cost is in how few things there are.

A page reads as expensive when it uses a small number of values and reuses them exactly. That is the mechanism, and it is countable: on a page that looks costly you will find five or six distinct font sizes, not nineteen.

The page ranking first for this phrase publishes three hex values and one duration, 130ms, with no curve attached to it. The nine results under it publish nothing measurable at all: no type scale, no spacing ladder, no easing value, no section order. They say whitespace, minimalism, better typography, restrained palette, good images, which describes the result and withholds the method.

So here is the method, as values you can paste. All of it is one system: one ratio, one grid, one palette, two curves. Thanor sells that system as prompts, because the reason a generated page looks cheap is not that the model is weak.

It's average. Painfully average, to the point of it being easily mistaken for a scam.

A founder on Hacker News, describing an AI-built landing page

Where the expensive look comes from#

Restraint first, consistency second, and the second one is doing more work than anybody admits. A page with three shadow definitions looks cheaper than a page with one, even when all three are tasteful, because a reader who cannot name the inconsistency still registers that nobody was in charge.

Open your page and count. These are the numbers a page that reads as expensive hits, and they are hard ceilings rather than averages:

  • Font sizes: 6 or fewer on any one page, all from the same ratio.
  • Font weights: 2. A text weight and a display weight, nothing between.
  • Border radius values: 1, applied to every corner on the site.
  • Shadow definitions: 1, or zero and a hairline border instead.
  • Easing curves: 2, one for entrance and one for state.
  • Durations: 2, and the state one is shorter than the entrance one.
  • Colours: 5, each with a written role.
  • Spacing values: 8 or fewer, every one a step on the same ladder.

Now the objection, which the people who complain about this have already made: prompting harder does not fix it. They are right, and it matters that they are. Asking for a premium, elegant, high end feel is asking for an adjective, and an adjective resolves to a distribution of plausible values, which is why the same guideline produces a different page every time. A number does not resolve to a distribution. 1.25 is 1.25. The fix is specification, not phrasing, and the proof that it worked is that you can measure the output against the input.

The type scale, with every size in it#

Ratio 1.25, the major third, from a body size of 18px. Every size is the one before it times 1.25, rounded to whole pixels, and there are no sizes off the ladder anywhere on the page.

StepSizeLine heightTrackingUsed for
-114px20px0.01emcaptions, labels, legal
018px29px0body copy, the default
122px32px0lead paragraph, large list
228px36px-0.005emh4, card titles
335px42px-0.01emh3
444px50px-0.015emh2, section openers
555px60px-0.02emh1 on an interior page
669px72px-0.025emthe hero headline only

Two rules make the ladder read as deliberate rather than merely present. Tracking tightens as size grows, because letterfit that is correct at 18px is loose at 69px. And line height converges on 1.05 at the top of the scale while sitting at 1.6 at the bottom, so a display line is a block and a paragraph is a texture.

Skip a step between a heading and its body. 44px over 18px is a confident pair. 22px over 18px is the single most common tell of a page nobody art directed, because it looks like an accident rather than a decision.

Eight pixels, and five colours#

Every gap on the page is one of these, and nothing between them exists: 4, 8, 12, 16, 24, 32, 48, 64, 96, 128, 160, 192. The run from 24 up is just the previous value times roughly 1.5, which is why adjacent steps never look ambiguous. Vertical section padding is 128px on desktop, 96px on tablet, 64px on a phone, and it is the same value top and bottom on every section on the site.

RoleHexContrast on groundWhere it goes
Ground#F6F4EFthe page, every section
Surface#FFFFFFcards, inputs, one step up
Ink#17171B16.26:1all headings and body copy
Muted#6B67605.12:1captions, labels, meta
Accent#1C3B2E11.14:1buttons, links, one rule

The ground is a warm off white, not #FFFFFF, and that single decision does more than the rest of the palette combined. A pure mid grey or a pure white ground is the value nobody chose, which is exactly why generated pages arrive wearing it. Bias the neutrals warm or cool on purpose and hold the bias across every value in the set.

A vertical split with a cluttered glass panel crowded with mismatched colour blocks on the left and a panel holding four aligned elements on the right
Five values with a written role each. A sixth would not add range, it would subtract authority.

Two curves, two durations#

Entrances use cubic-bezier(0.22, 1, 0.36, 1) at 620ms. That is an ease out quint: it leaves fast and lands slowly, so movement reads as weight settling rather than a thing sliding into place. Travel is 24px upward and opacity runs 0 to 1. Where several items enter together, stagger them 90ms apart and cap the run at six items.

State changes use cubic-bezier(0.33, 1, 0.68, 1) at 240ms. Hover, focus, open, close, all of it. A state change slower than about 300ms feels broken rather than luxurious, because the user has already committed and is waiting.

  • Entrance trigger: the element crosses 18% of the viewport, once, never again on scroll back.
  • Nothing animates on a scroll position other than these entrances. Parallax on a marketing page is the second tell after the mid grey.
  • Transition opacity, transform, color, background-color and border-color only. Animating height, width or box-shadow costs layout work on every frame and reads as lag on the hardware your visitors have.
  • transition-delay is 0 everywhere except inside a stagger. A delay on a hover is a page that hesitates before answering.
  • Under prefers-reduced-motion: reduce, entrances become opacity: 1 with no transform and no duration, and state changes drop to 1ms.

Two curves is the ceiling, not a starting point. Three curves on one page is the same error as three shadows, and it is the reason a page built from four different component libraries never resolves however good each part is.

The order the sections run in#

Sequence carries as much of the read as the palette, because it decides what a visitor knows at the moment they are asked for something.

  1. Hero, at 88vh rather than 100vh, so the next section's top edge is visible and the page announces that it continues.
  2. Proof, immediately: logos, a number, a named customer. It goes second because a claim with nothing behind it ages badly over one scroll.
  3. The problem, in the reader's words, so the rest reads as an answer.
  4. How it works, three steps, because three is the largest number a reader will accept without a diagram.
  5. The detail section, one per real differentiator, each with a value in it.
  6. Objection handling, the thing a buyer worries about, answered flatly.
  7. The ask, alone on the ground colour, one button, no competing link.

Two widths hold the page together: a content container of min(100% - 48px, 1160px), and a text measure of 68ch inside it. The hero is the only section allowed to break the container, and it breaks to the viewport edge rather than to some third width nobody declared.

The primary action appears exactly three times: in the hero, once directly after how it works, and in the ask. Every additional repeat lowers the value of the other three, because a button offered seven times reads as pressure.

Vertical rhythm between sections stays constant at 128px throughout. Resist the urge to compress the ones you think are less important: unequal section padding is the inconsistency that reads as cheap most reliably, and it is the default output of generating a page section by section.

The verdict, and how to check it#

Specify the system, then generate the page. Not the other way round, and not with adjectives. The eight counts at the top of this article are the audit: open your page, count font sizes, count radii, count curves, and if any count is above its ceiling you have found the thing making the page look cheap without having to develop taste first.

Everything here is one coherent set, and that is the part worth taking:

  • Ratio 1.25 from 18px, eight steps, tracking tightening as size grows.
  • Spacing from a single ladder, section padding 128px and identical on every section.
  • Five colours on a warm ground, each with a role written down.
  • cubic-bezier(0.22, 1, 0.36, 1) at 620ms in, cubic-bezier(0.33, 1, 0.68, 1) at 240ms for state, and nothing else.
  • Seven sections, proof in position two.

Writing that set is a day of decisions, and it is the same day at the start of every project, on every brief, which is the entire reason a library of them is worth paying for rather than repeating. Every prompt in the Thanor library arrives with the ratio, the grid, the curve, the durations, the palette and the order already chosen, so the model you already build in has nothing left to guess. If you want the diagnosis first, the case for why unspecified pages converge is the companion to this one. Then browse the Thanor library and take a specification instead of writing one.

Questions this raises

What makes a website look expensive?

A small number of values, reused exactly. Six font sizes from one ratio, one border radius, one shadow, two easing curves, five colours with a role each. Cheap pages are not ugly, they are inconsistent, and inconsistency is what the eye reads as low effort.

Can AI make a website that looks expensive?

Yes, once you hand it the decisions. Models build to any curve, any duration and any palette you name. What they cannot do is choose a type ratio for you, so an unspecified page arrives wearing the defaults every other unspecified page is wearing.

What type scale should I use?

A major third, ratio 1.25, from an 18px body size. That gives 14, 18, 22, 28, 35, 44, 55 and 69 pixels, which is enough range for a display headline and still tight enough that two adjacent sizes never look like a mistake.

How long should animations be on a premium looking site?

620ms for a section entrance on cubic-bezier(0.22, 1, 0.36, 1), and 240ms for a hover or focus change on cubic-bezier(0.33, 1, 0.68, 1). Two durations, two curves, and a reduced motion rule that turns the entrances off entirely.

Where can I get prompts that already contain these decisions?

The Thanor library is available now and every prompt in it names the scale, the grid, the curve, the durations, the palette and the section order before a model ever sees it.

Part of

The expensive look

What makes a site read as expensive, written as values rather than adjectives: the type scale, the spacing, the curve and its duration, and the order the sections run in.