Loading …
This page is only for Winetastr administrators.
Components
Every shared component in its states – the real components and the real stylesheet. A missing one is added to src/components/ui or src/lib/ui first and shown here.
A. Basics
1 Button
.btn · button() and setLoading() in src/lib/ui/button.ts
.btn.on-photo and .on-photo-2 – shown on the photo under 44 Hero
2 Text button / text link
.text-btn · textButton() in src/lib/ui/text-button.ts · links in running text keep their underline
The guest page is at winetastr.com/t/portvin-2026/ – share it with your guests.
3 Icon button
.icon-act · iconButton(), closeButton(), setIconLoading() in src/lib/ui/icon-button.ts · CloseButton.astro
4 Text field
.field, label, .input, .help · fieldError() in src/lib/field-error.ts
Only the hosts see it.
5 Number and price field
.affix.w-num with .unit · .field-row
6 Search field
SearchField.astro
B. Choices
7 Dropdown, one choice
Dropdown.astro · dropdown() / getDropdown() in src/lib/ui/dropdown.ts · the menu is src/lib/ui/menu.ts
8 Filter, several choices
filterDropdown() in src/lib/filter-dd.ts
9 Combobox (type and choose)
combo() in src/lib/combo.ts – type "d" to see the suggestions
10 Choice cards
ChoiceCards.astro · choiceCards() in src/lib/ui/choice-cards.ts
11 Switch
Switch.astro · switchRow() / bindSwitch() in src/lib/ui/switch.ts – saves straight away
12 Checkbox
Checkbox.astro · checkbox() in src/lib/ui/checkbox.ts – choose several, and consent
13 Date and time
DateTimeFields.astro · initWhen() in src/lib/datetime.ts
14 Address
AddressFields.astro · initAddress() in src/lib/address.ts
15 Image picker
imagePicker(), pickButton() in src/lib/ui/image-picker.ts
16 Stars
starsInput(), starsRo() in src/lib/ui/stars.ts
17 Stepper
stepper() in src/lib/ui/stepper.ts
C. Display
18 Chip / status
chip(), statusChip() and STATUS in src/lib/ui/status.ts – one word and one tone per status
Ribbon.astro – a corner band on a card (class "has-ribbon")
19 Badge
Badge.astro · badge(), setBadge() in src/lib/ui/badge.ts
20 Avatar and wine thumbnail
avatar(), wineThumb() in src/lib/ui/thumb.ts · sizes small, normal, large
21 Price
price() in src/lib/ui/price.ts · every amount by formatKr() in src/lib/ui/kr.ts
22 Facts
Facts.astro + setFact() · facts() in src/lib/ui/facts.ts – an empty value is left out
- Date
- Wines
- Quiz
.ruled – a hairline between the pairs, for long values (a wine's notes); on phones the label goes above its value
A wine's details: each heading gets its icon from its words (detailIcon()), the info icon when none fits
23 Map with flag and credit
drawMap() in src/lib/region-map.ts · .map-box (normal, mini), .map-credit, .map-legend, .flag
Natural Earth · OpenStreetMap
Natural Earth
- 3DouroWines 1–3
- 1PortugalThe whole country
- 2Other placesNot on this map
24 Table
table() in src/lib/ui/table.ts – sortable, numbers right, a card per row on phones; cls 'stack': text in every cell, the label over the value on phones; empty: the empty state
D. Lists and rows
25 List row and card
listRow(), personRow() in src/lib/ui/list-row.ts – a list shows, the side panel edits
Activity rows – activityRow()
Card variant
26 Add row
AddRow.astro · addRow() in src/lib/ui/add-row.ts – the new row slides in at the top of the list
Wines
27 Highlight after saving
highlight() in src/lib/ui/highlight.ts
28 Delete with Undo
deleteWithUndo() in src/lib/ui/delete-undo.ts – ask first, then a toast with Undo
29 Reorder
reorder() in src/lib/ui/reorder.ts – drag the grip, or focus it and press ↑/↓
E. Panels, messages and states
30 Side panel
Sheet.astro + sheetPanel() · sheet() in src/lib/ui/sheet.ts – from the right, a bottom sheet on phones
31 Confirmation
confirmModal() in src/lib/ui/confirm.ts – the only way the site asks first
32 Toast
toast() in src/lib/ui/toast.ts – after saving, deleting or copying
33 Notice and status line
Notice.astro · notice(), setNotice() in src/lib/ui/notice.ts · setStatus() in src/lib/ui/status-line.ts
Guests see the wines when you reveal them.
Two wines have no price yet.
The changes could not be saved. Try again.
The invitations are sent.
34 Empty state
EmptyState.astro · emptyState(), setEmpty() in src/lib/ui/empty.ts – always a way forward
No messages yet
Write the first message below.
35 Loading
Loading.astro · pageLoading() in src/lib/ui/loading.ts · the one spinner .spin (shown after 350 ms)
Loading …
36 Help tip and tooltip
data-help + initHelpTips() in src/lib/help-tip.ts · tooltip() in src/lib/ui/tooltip.ts
All wines become blind until you press Reveal.
Read more in the help37 Fold-out
Disclosure.astro · disclosure() in src/lib/ui/disclosure.ts
Details
The content under the line.
Details(optional)
Open, with "(optional)" after the summary.
Details
In a box.
Details
A help topic.
38 Progress
Progress.astro · progress(), setProgress(), setSteps() in src/lib/ui/progress.ts · Steps.astro
- The wines11 wines
- Invite the guests22 guests, 14 invited
- SettingsPayment and quiz
- Code from the email
F. Page structure
39 Page header
PageHeader.astro – page (h1) and section (h2/h3) with the actions at the right
Guests
Search by name
Wines
Quiz
40 Headings and eyebrow
SectionTitle.astro · sectionTitle() in src/lib/ui/section-title.ts – one scale
During the tasting
Everything for the evening
How it works
41 Card
.card (8px radius) · a link card gets a red edge on hover · .card.add · .card.tight
42 Tabs
Tabs.astro · tabs(), tabButton(), setTabCount() in src/lib/ui/tabs.ts – two rows on phones, never cut off
43 Navigation
TopBar.astro (the top of this page, every page) · SideMenu.astro (the menu at the left of this page; "Menu" on phones) · the tasting switcher in TopBar
SideSwitch.astro · sideSwitcher() in src/lib/ui/side-menu.ts – the account choice at the top of the menu, only for a host on more than one account (one account: not shown); open, it is the dropdown of component 7 with the role under each name
44 Hero
Hero.astro – the long table photo (front page, sign-in) and the guest's tasting

Portvin 2026
- Saturday 14 November at 19:00
- Strandvejen 12, Hellerup
MapBackground.astro – a faint region map behind a heading, left or right (the sign-up page: Bourgogne, left)
For hosts
Wine tastings your guests remember
Winetastr gathers the whole evening in one place: invitations and replies, the wines with photos and prices, orders paid with MobilePay, ratings, and a quiz with a live leaderboard on the big screen. You prepare it in minutes – your guests only need their phone.
45 Footer
Footer.astro – at the bottom of this page, every page
46 Actions
Actions.astro – forms and panels: primary first; dialogs (end): primary last, right; stack on phones
47 Text for screen readers
Sr.astro / class "sr" – the next line has hidden text after "Cart":
Cart (3 bottles, 447,85 kr.)
G. Guest parts
48 Chat
ChatBox.astro · initChat() in src/lib/chat.ts (sample messages; nothing is sent)
No messages yet
Write the first message below.
49 Wine carousel and wine page
listRow() card variant as .wine-card in .carousel, .pager with round icon buttons, styleTag()
50 Cart line and cart bar
listRow() with cls "cart-line", stepper() and price() · CartBar.astro (src/lib/cart-bar.ts)
51 Payment box
payBox() in src/lib/pay.ts (copy buttons with a toast) – on a computer the QR code (54, src/lib/ui/qr.ts) instead of the app button; on a phone the button
52 Quiz
The answers are choice cards (10), locked with right / wrong after answering; the progress is the bar (38)
Which grape is not allowed in port?
53 Leaderboard
renderLeaderboard() in src/lib/leaderboard.ts · .board (and .board.big on the TV)