# Visit Card (Moonarc)

Where to find a studio, a shop or a counter, as one card in a colour block: a drawn map with a pin, the address with a directions link, the opening hours for the week, the ways to get in touch, and above them a live line that says whether it is open now and until when (or when it opens next), with the time where the place is. Today's row of the week is marked. The live line is a small script reading the hours in the place's own time zone; without JavaScript the week reads as it is.

- Pro block. Install: `npx shadcn@latest add @moonarc-pro/visit-card` (license key required)
- Tier B · category section · trigger load
- Readout: `<VisitCard address={[…]} hours={[{ day, label, open, close }]} timezone="Europe/Lisbon" />`
- Browser support: widely (every browser)
- Measured cost: 1006 B raw JS · 626 B gzip · + runtime (with dependencies 2.7 kB raw; CSS 11.0 kB raw)
- Page: https://moonarc.dev/components/visit-card/

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `address` | `string[]` | none | The address, one line an entry, in an address element. |
| `hours` | `{ day: 'mon' … 'sun'; label: string; open?: string; close?: string }[]` | none | The week; open and close in 24-hour time, both unset for a closed day. |
| `timezone` | `string` | none | The place's IANA time zone, e.g. Europe/Lisbon: the live line and today's row read the hours in it, wherever the reader is. |
| `eyebrow` | `string` | none | A short line above the heading. |
| `headline` | `string` | none | The heading. Slot "headline" wins and may hold an <em>, set in the emphasis face and colour. |
| `directions` | `{ href: string; label: string }` | none | A link to a map. |
| `contacts` | `{ label: string; value: string; href?: string }[]` | none | Ways to get in touch: an email, a phone. |
| `note` | `string` | none | A line under the week: holidays, appointments. |
| `openText` | `string` | `'Open now, until {close}'` | The live line while open. |
| `closedText` | `string` | `'Closed now, opens {day} at {open}'` | The live line while closed; {day} is todayWord, tomorrowWord or the day's label. |
| `todayWord` | `string` | `'today'` | The word for today in the live line. |
| `tomorrowWord` | `string` | `'tomorrow'` | The word for tomorrow in the live line. |
| `closedLabel` | `string` | `'Closed'` | The word for a closed day in the week. |
| `hoursLabel` | `string` | `'Opening hours'` | The week table's caption, for a screen reader. |
| `timeLabel` | `string` | `'Local time'` | The words a screen reader hears before the time. |
| `block` | `1 | 2 | 3 | 4 | 5` | `2` | The colour block the card paints. |
| `level` | `2 | 3` | `2` | Heading level. |
| `density` | `'compact' | 'cozy' | 'roomy'` | `'cozy'` | Block padding ×0.8 / ×1 / ×1.25 through --ma-density. |

## Usage

```astro
---
import VisitCard from '@/components/moonarc/pro/VisitCard.astro';
---
<VisitCard
  address={['Your street 12', 'Your city']}
  directions={{ href: 'https://www.openstreetmap.org/', label: 'Directions' }}
  timezone="Europe/Lisbon"
  hours={[
    { day: 'mon', label: 'Monday' },
    { day: 'tue', label: 'Tuesday', open: '10:00', close: '18:00' },
    { day: 'wed', label: 'Wednesday', open: '10:00', close: '18:00' },
    { day: 'thu', label: 'Thursday', open: '10:00', close: '18:00' },
    { day: 'fri', label: 'Friday', open: '10:00', close: '19:00' },
    { day: 'sat', label: 'Saturday', open: '10:00', close: '17:00' },
    { day: 'sun', label: 'Sunday' },
  ]}
  contacts={[{ label: 'Email', value: 'hello@your-studio.com', href: 'mailto:hello@your-studio.com' }]}
>
  <span slot="headline">Come and <em>see the kiln</em></span>
</VisitCard>
```

## Reduced motion

The pin's halo does not breathe; the live line and the time still update.

## With ClientRouter

Binds once per swap through the runtime's onMount; the half-minute timer stops when the page is swapped away.

## Craft

- The hours are read in the place's time zone with Intl.DateTimeFormat, so a reader in another country sees whether the shop is open now, not whether it would be at their own clock time.
- Without JavaScript the live line is not rendered at all, rather than showing a guess; the week reads the same either way.
- Today's row of the week is marked by a dot and weight, set by the same tick, so the table and the line never disagree.
- The map is a drawing in the block's two drawing colours: a placeholder that never loads a third-party tile.

## Replaces

- Store locator cards (Shopify themes)
- Opening hours widgets

## Source

Pro block. The source is served by the license-gated registry: `npx shadcn@latest add @moonarc-pro/visit-card` with a key in components.json (https://moonarc.dev/account/).
