Make a website look professional without a designer

A full specification you can paste: a 1.2 type scale, a four pixel spacing ladder, one curve at 180ms, five hex values and eight component states.

A precise glass grid snapping translucent tiles into perfect alignment along crisp guide lines, lit slate blue and cool white
Professional is not a style. It is a grid that nothing on the page escapes.

A designer's real deliverable is a list of about eight decisions, and you can hold that list without being able to draw. Ratio, spacing unit, radius, shadow, curve, duration, palette, control height. Everything a visitor reads as professional comes out of those eight being the same everywhere.

What reads as amateur is almost never an ugly choice. It is two choices that disagree: a card with a 12px radius next to a button with 6px, a section with 72px of padding above and 56px below, three font sizes within four pixels of each other. A reader cannot name any of that and closes the tab anyway.

the paddings and margins are inconsistent and don't convey visual rhythm

A developer on Hacker News, reviewing a generated site

The call, up front: write the eight decisions down as numbers before you generate anything, and the page arrives professional on the first attempt. That is what the Thanor library is, a subscription to those lists already written, because the decisions are identical work at the start of every project.

The eight decisions, with values#

Copy these. They are conservative on purpose, which is the correct posture for a business site that has to be believed rather than admired.

  • Type ratio: 1.2, a minor third, from 16px.
  • Spacing unit: 4px, and every gap is a multiple of it from a fixed set.
  • Radius: 6px, on buttons, inputs, cards and images alike. One value.
  • Shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.10), used on raised surfaces only, never on a section.
  • Curve: cubic-bezier(0.4, 0, 0.2, 1), and no second curve.
  • Duration: 180ms, for every state change on the site.
  • Palette: five values, listed further down, each with a written role.
  • Control height: 44px for inputs and secondary buttons, 52px for the primary button, because 44px is the smallest reliable touch target.

Two of those deserve an argument. The radius is one value, not a scale, because a radius scale is a designer's tool for expressing hierarchy and it reads as noise when nothing else on the page expresses hierarchy that way. And the duration is a single number because a site with 150ms on buttons, 300ms on a dropdown and 500ms on a modal feels assembled by three people, which it usually was.

The objection people raise here is fair: prompting harder does not produce this. Correct. An instruction to look clean and modern resolves to whatever the model's defaults are, and defaults vary run to run, which is why the same style guideline yields a different page each time. 180ms does not vary.

The type scale for a business site#

Ratio 1.2 from 16px, rounded to whole pixels. A minor third is the calm ratio: adjacent steps are clearly different without either one shouting.

StepSizeLine heightWeightUsed for
-113px18px500labels, table headers, badges
016px26px400body copy, form fields
119px29px400lead paragraph, card body
223px31px600h4, card title
328px36px600h3
433px41px600h2
540px47px600h1 on an interior page
648px54px600the home page headline

Two weights, 400 and 600, and nothing else. A 500 in the mix alongside both is invisible at body size and muddy at heading size. The one exception in the table is the 13px label at 500, which exists because small type at 400 under a heading at 600 looks faint rather than quiet.

  • Measure: 60ch to 75ch on any paragraph. Wider than that and the eye loses the line return, which is read as carelessness rather than as width.
  • Set headings at -0.01em tracking from step 4 up, 0 below it.
  • Never centre a paragraph longer than two lines. Centring is a decision that has to be earned by brevity.

Five colours, and eight states#

The palette is where a site announces whether anybody chose. Five values, one role each, and the accent is deliberately not the default gradient blue.

RoleHexContrastWhere it goes
Page#FBFBFDthe background of every section
Surface#FFFFFFcards, inputs, menus
Ink#10182817.17:1headings and body copy
Muted#5A64725.80:1labels, help text, placeholders
Accent#123E5E10.83:1primary button, links, focus ring
Border#E3E6EBevery hairline, at 1px

White text on the accent measures 11.19:1, which clears the 4.5:1 threshold with room to spare, so a primary button never needs a second thought. Alternate sections between #FBFBFD and #FFFFFF rather than introducing a third background, and let the border do the separating work a coloured band would do badly.

Every interactive element needs all eight states specified, and missing states are the most common reason a competent looking page feels unfinished the moment somebody uses it: rest, hover, active, focus visible, disabled, loading, error, success. The focus ring is not optional: 2px solid accent at 2px offset, and it must be visible on the page background and on the surface colour.

Two groups of glass tiles, the left sitting crooked and unevenly spaced, the right in exact alignment on a visible baseline
Eight states, specified once. A model will build all eight and will invent none of them.

Spacing, and where the rhythm breaks#

The ladder: 4, 8, 12, 16, 20, 24, 32, 40, 56, 72, 96, 120. Twelve values, no thirteenth, and 18px does not exist on your site.

Section padding is 96px top and bottom on desktop, 72px on tablet, 56px on a phone, applied identically to every section. The three places rhythm breaks in practice, in order of how often:

  1. Between a heading and its own paragraph. Use 12px. The gap under the paragraph, before the next heading, is 40px. Unequal on purpose: a heading belongs to what follows it, and equal gaps make it float between two things.
  2. Inside cards in a grid. Padding 24px on all four sides, gap 24px between cards. When the internal padding and the external gap differ, the grid stops reading as a grid.
  3. Above and below the last section. Generated pages routinely put 96px above the footer and 24px below the final button. Same value, both sides, every time.

Buttons: 52px tall, 24px horizontal padding, label at 16px weight 600. Inputs: 44px tall, 12px horizontal padding, 1px border in the border colour, 6px radius, label above at 13px weight 500.

Container width is min(100% - 40px, 1140px) with paragraphs capped at 68ch inside it, on a 12 column grid with a 24px gutter. A three card row is four columns each and a two column text block is five and five with one column left empty between them, which is the cheapest way to stop a layout looking like it filled the available width by accident.

Motion, and the one thing to delete#

One curve, cubic-bezier(0.4, 0, 0.2, 1), at 180ms, on background-color, border-color, color, opacity and transform only. Never on width, height or box-shadow, which cost layout work and read as laggy on the hardware your customers actually use.

Then delete the scroll triggered entrance animation. All of it. A fade and slide on every section is the single most reliable signal that a page came out of a generator, and on a business site it buys nothing: your visitor is trying to find out whether you can be trusted with money, not watching a sequence.

  • Page load: content is present at full opacity. No stagger, no reveal.
  • Hover on a card: border-color to the accent, nothing moves.
  • Hover on a button: background-color one shade darker, no lift, no scale.
  • Menu or accordion open: 180ms, on opacity and transform only, with the panel height set rather than transitioned.
  • Loading: the button keeps its width and its label is replaced by a 16px spinner at 700ms linear infinite. A button that changes width mid click moves the thing the visitor just aimed at.
  • Skeletons only for content that takes longer than 400ms, and as a flat #F4F5F7 block with no shimmer. The shimmer is decoration on a wait.
  • Toast: enters 180ms, sits 4000ms, leaves 180ms, and is dismissible.
  • prefers-reduced-motion: reduce sets every transition to 1ms.

The restraint is the professionalism. A page where nothing moves until the visitor acts, and then responds in 180ms every single time, feels built.

The verdict on doing this yourself#

You do not need a designer to hold eight numbers, and you do need somebody to choose them. That is the honest split. Choosing well takes either taste or a reference, and a written specification is a reference that does not require you to have developed the taste first.

What to do, in order:

  1. Paste the eight decisions into whatever you build in, before the first prompt about layout.
  2. Paste the type table and the palette table as literal values.
  3. State the spacing ladder and say that no value outside it may be used.
  4. Name the eight component states and require all eight.
  5. Say explicitly that there is no entrance animation.

Then audit it by counting rather than by looking. Search the stylesheet for border-radius and expect one value. Search for cubic-bezier and expect one. Search for px in a font size and count the distinct results: eight or fewer, all from the table. Three searches, thirty seconds, and they find the inconsistency before a visitor does.

That is a page that reads as professional, and none of it was a matter of opinion once the numbers were written. Every prompt in the Thanor library ships with exactly this layer already decided, for whichever model you already use, so you are editing a specification rather than inventing one. If you want the version tuned for expense rather than credibility, the expensive look specification runs a tighter palette and a wider scale. Otherwise, browse the Thanor library and start from a list that is already complete.

Questions this raises

How do I make a website look professional without hiring a designer?

Decide eight things and then hold them everywhere: one type ratio, one spacing unit, one radius, one shadow, one easing curve, one duration, five colours and one button height. A designer's real output is that list, not the picture.

What font size should body text be?

16px minimum on a business site, 17px or 18px if the page is text heavy, at a line height of 1.55 to 1.65 and a measure of 60 to 75 characters. Anything under 16px reads as a document nobody expected you to read.

What is the safest type scale for a business website?

A minor third, ratio 1.2, from 16px. It gives 13, 16, 19, 23, 28, 33, 40 and 48 pixels. The steps are close enough to stay calm and far enough apart that a heading never looks like body copy set slightly large.

How much animation should a professional site have?

One curve, cubic-bezier(0.4, 0, 0.2, 1), at 180ms, on state changes only. No section entrance animation at all. Scroll triggered fades are the most common thing that makes a competent page feel like a template.

Do I need a blue accent colour to look trustworthy?

No, and the default blue to purple gradient is now a recognised signal that nobody chose anything. One deep, desaturated accent at a measured contrast ratio does the same job without the association.

Where do these decisions come from if I am building with AI?

From a written specification handed to the model before it generates. The Thanor library is available now and sells those specifications as prompts for Claude, ChatGPT, Lovable, v0, Bolt and Cursor.

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.