
A hotel is not a product until it has a date attached. The same room is ninety pounds in February and three hundred in July, so a page that shows a photograph and a from price has not told the guest anything they can act on.
So the booking control is the first screen, not a bar bolted to the top of it. Two date fields, a guest count, and then every room card shows the rate for those dates, with taxes stated and the cancellation deadline printed as a real date.
Short verdict: ratio 1.6 from a 12px root, body at 19px on a 32px baseline that nothing breaks, #7A5E2C on paper at 5.52:1 and never on the dark panel. The Thanor library publishes designs at that resolution.
The rate is the product#
Hotel sites fail in a specific and expensive way: they are built as brochures and then have a booking engine attached at the end. The result is a page where the photography is excellent and the only question the guest has is unanswered until the third click.
Four decisions reverse that:
- The date picker in the first screen. Check in, check out, guests. Three controls,
56pxtall, over a single photograph rather than a carousel. A carousel behind a form is two things asking for attention in the same rectangle. - Rates recalculated on the cards, not on a separate results page. A guest who changes the dates should see four numbers change in place.
- No from prices anywhere. A from price is true on four nights a year. When the card figure and the checkout figure differ, the guest has been handed a reason to check another site, and they will find one.
- The cancellation deadline as a date, on the card: free cancellation until 14 July. Not flexible rates available, which tells nobody anything.
Then the room card itself, which needs six fields and gets them in a fixed order: rate, size in square metres, bed configuration, maximum occupancy, view, and the cancellation date. Square metres is the field most often omitted and the one that separates two rooms whose photographs look identical.
A hotel's photography still matters, second, and it works hardest where nobody puts it: the bathroom and the view from the actual window rather than from the roof. Those two frames answer the questions a guest is really asking.
A baseline that never breaks#
Ratio 1.6, the minor sixth, from a 12px root, body at 19px on a 32px line height. Every spacing value above 16px is a multiple of 32, so nothing lands off the baseline.
| Step | Size | Line height | Weight | Role |
|---|---|---|---|---|
| 0 | 12px | 17px | 500 | taxes, deadlines |
| 1 | 19px | 32px | 400 | body, facts |
| 2 | 31px | 38px | 400 | room names |
| 3 | 49px | 54px | 500 | the rate, section headings |
| 4 | 79px | 78px | 400 | the statement line |
| 5 | 126px | 118px | 400 | the property name, once |
Step 3 is the only step carrying two roles, and that is the argument. The rate is a heading: the thing a guest reads first and the thing the page exists to deliver, so it is set at the size of a section title rather than tucked beside a button.
Spacing runs 8, 16, 32, 64, 96, 128, 192. Section padding 128px, 96px, 64px. Room cards 32px apart with 32px padding, and 64px between the date bar and the first card.
| Role | Hex | Contrast | Where it goes |
|---|---|---|---|
| Paper | #F7F4EE | light backgrounds | |
| Deep | #122A26 | 13.81:1 | date bar, footer |
| Ink | #141311 | 16.91:1 | type on paper |
| Muted | #6E6A61 | 4.91:1 | footnotes |
| Brass | #7A5E2C | 5.52:1 | book button, rules |
Brass on the deep panel measures 2.5:1 and is never used there. The dark panel takes paper coloured type at 13.81:1, which is why the date bar reads cleanly at 19px.
Three curves and the rate that updates#

Three curves, and the shortest one runs on the only interaction that matters.
--ease-rate: cubic-bezier(0.5, 0.05, 0.4, 1); /* 240ms */
--ease-gallery: cubic-bezier(0.18, 0.89, 0.32, 1); /* 560ms */
--ease-arrive: cubic-bezier(0.2, 0.8, 0.2, 1); /* 680ms */--ease-rate at 240ms handles a rate changing when the dates change: a cross fade on the figure only, with the card and its six fields static. No counting, no sliding digits. A guest comparing two dates needs to read two numbers, and a number in motion is a number being read twice.
--ease-gallery at 560ms advances a room gallery as a horizontal translate. --ease-arrive at 680ms runs section entrances, 24px up, once, at 20% of the viewport, 110ms stagger across a maximum of four cards.
Four things never move, and three of them are money:
- The rate figure, beyond its cross fade.
- The tax line and the cancellation date under it.
- The date fields, which never animate on focus beyond a border change.
- The property name at step 5, which loads in place.
One accessibility line belongs in the brief and is usually absent: under prefers-reduced-motion: reduce all three curves collapse to 0.01ms and every element renders at its final state, including the rate. Three lines of CSS, and it is the difference between a page that reads a system setting and one that overrides it on a guest with vestibular sensitivity.
Seven blocks, and no from prices#
Seven blocks. The first one is the page and the other six are reasons to trust it.
- The date bar. Property name at step 5, one line at step 4, three controls on the deep panel over one photograph.
- Rooms. Four cards, six fields each, real rates,
32pxapart. - What is included. Breakfast, parking, late checkout, wifi, each marked included or priced. A facilities list with no prices is a list of future surprises.
- The place. Three photographs and walking times to three named landmarks, in minutes.
- Eating. Hours for each outlet and whether non residents can book, which is the question the page is asked most and answers least.
- Policies. Check in and check out times, the cancellation window in full, the deposit, and the pet rule.
- The story. Last, and short.
Block 3 is where a page keeps a guest or loses them at checkout. Breakfast at £18 stated on the page is a fact. Breakfast discovered at checkout is a grievance, and it arrives in the review.
Block 4 gives walking times rather than a map for the same reason a property page pairs its list with its map: the guest is not asking where the hotel is, they are asking whether it is near the thing they came for. Eleven minutes to the station answers that. A map pin does not.
Block 5 earns its place because a hotel restaurant is two businesses sharing one page. The hours and the line about non residents are worth more to a booking than any photograph of a plate, and they belong here rather than behind a link to a second site with its own navigation.
The verdict on a hotel brief#
Dates in the first screen, real rates on every card, six fields per room including square metres, the cancellation deadline as a date, included items priced, walking times in minutes. The rest is photography, and photography cannot answer a question about July. Thanor sells the values that can.
The brief to paste#
Build a hotel site, rates first.
TYPE: ratio 1.6 from a 12px root: 12, 19, 31, 49, 79, 126. Footnotes
12/17. Body and facts 19/32. Room names 31/38. The rate and section
headings both 49/54. Statement 79/78. Property name 126/118, once.
SPACE: 8, 16, 32, 64, 96, 128, 192. Every value above 16 is a multiple of
32, the body line height, so the baseline holds. Section padding
128 / 96 / 64. Cards 32px apart, 32px padding.
COLOUR: paper #F7F4EE, deep #122A26, ink #141311, muted #6E6A61, brass
#7A5E2C. Brass on paper only, never on deep, which takes paper coloured
type.
FIRST SCREEN: property name, one line, then check in, check out and guests
as three 56px controls on the deep panel over one photograph.
ROOM CARD: rate for the chosen dates in 49px tabular figures, then square
metres, bed configuration, occupancy, view, free cancellation until a real
date. No from prices.
MOTION: rate cross fade cubic-bezier(0.5, 0.05, 0.4, 1) 240ms, figure
only, no counting. Gallery translate cubic-bezier(0.18, 0.89, 0.32, 1)
560ms. Entrances 24px up, cubic-bezier(0.2, 0.8, 0.2, 1) 680ms, once at
20% of viewport, 110ms stagger, four maximum. Rates, taxes, dates and the
property name never animate.
BLOCKS: date bar / four room cards / included items, each marked included
or priced / three photographs plus walking times to three landmarks /
eating, with hours and whether non residents book / policies in full / the
story, short.Change the property, keep the rate at heading size. Browse the Thanor library for the one that matches the building.
Questions this raises
What should a hotel website prompt specify?
A date picker in the first screen, room cards carrying the rate for those dates rather than a from price, the cancellation deadline as a real date, and the full type, spacing, colour and motion values.
Why avoid from prices on a hotel website?
Because a from price is true on four nights a year and wrong on the rest. A guest who sees one figure on the card and a different figure at checkout has been given a reason to check another site.
What belongs on a room card?
The rate for the selected dates, room size in square metres, bed configuration, maximum occupancy, view, and the cancellation deadline as a date. Six fields, in that order, on every card.
How big should hotel body copy be?
19px on a 32px line height. Every spacing value above 16px is a multiple of 32, so the baseline never breaks, which is most of why a generous page reads as an expensive one.
Can the brass accent carry text on the dark panel?
No. #7A5E2C measures 2.5:1 against #122A26 and fails. It is used on paper at 5.52:1, and the dark panel takes paper coloured type at 13.81:1 instead.
Is this specification sold as a prompt?
Yes. The Thanor library is available now, and each design in it ships with the ladder, the spacing, the palette, the curves and the block order written out for whichever model you build in.
Part of
Prompts by industry
The design decisions a given kind of site actually needs, written as values. What a restaurant page has to do that a SaaS page does not, and the specification that gets you there.
