# Venue format (`venue.json`)

Every import path in the Venue Studio — floor-plan image tracing, AutoCAD DXF, SVG, GeoJSON,
Apple IMDF, CSV/Excel, or hand-written JSON — produces **this one format**. The 3D viewer only
ever reads this format, so the map looks and behaves the same whatever the source was.

Coordinates are **metres** on a flat plan: `x` grows to the right, `y` grows *down* the drawing
(like an image). Heights are metres too. Headings are degrees clockwise from “plan-up”.

```jsonc
{
  "format": "indoor-venue",
  "version": 1,
  "venue": {
    "id": "grand-plaza",            // folder name under venues/
    "name": "Grand Plaza Mall",
    "address": "…",
    "brandColor": "#d9604a",        // buttons, highlights
    "languages": ["en", "es", "hi"],
    "walkingSpeed": 1.2,            // m/s, for ETAs
    "defaultFloor": "F0",
    "northOffset": 0,               // where true north is, ° clockwise from plan-up (compass)
    "publicUrl": "https://…/index.html"  // optional, used for printed QR codes
  },
  "categories": [
    { "id": "shop", "name": "Shop", "icon": "shopping-bag", "color": "#c7a7ad" },
    { "id": "fashion", "name": "Fashion", "icon": "shirt", "color": "#c7a7ad", "parent": "shop" }
  ],
  "floors": [
    { "id": "F0", "name": "Ground Floor", "shortName": "G", "level": 0, "height": 5,
      "outline": [[0,0],[160,0],[160,70],[0,70]],
      "plan": { "image": "data:image/png;base64,…", "x": 0, "y": 0, "width": 160, "height": 70,
                "showInViewer": false } }        // optional tracing image
  ],
  "spaces": [
    { "id": "S1", "floor": "F0", "kind": "unit", "name": "Zara", "category": "fashion",
      "polygon": [[2,2],[28,2],[28,27],[2,27]],
      "entrances": [[28,20]],       // optional; otherwise the corridor-facing side is used
      "height": 3.2,                // optional extrusion height
      "details": { "description": "…", "hours": "10:00 – 22:00", "phone": "…", "website": "…" } }
  ],
  "pois":       [ { "id": "P1", "floor": "F0", "x": 80, "y": -3, "name": "Gate 01", "category": "entrance" } ],
  "connectors": [ { "id": "C1", "type": "elevator", "name": "Main elevator", "accessible": true,
                    "stops": [ { "floor": "F0", "x": 90, "y": 29.5 }, { "floor": "F1", "x": 90, "y": 29.5 } ] },
                  { "id": "C2", "type": "escalator", "direction": "up",
                    "footprint": [[57,32.4],[66,32.4],[66,35],[57,35]],   // 3D model + obstacle on the lower floor
                    "stops": [ { "floor": "F0", "x": 67.5, "y": 33.7 }, { "floor": "F1", "x": 55, "y": 33.7 } ] } ],
  "anchors":    [ { "id": "Q-gate-n", "floor": "F0", "x": 80, "y": 3, "heading": 180, "label": "Gate 01" } ],
  "decor":      [ { "type": "plant", "floor": "F0", "x": 32, "y": 28.2, "rotation": 0, "scale": 1 } ]
}
```

## Look & feel (`venue.theme`) — optional

Sets the materials the map is rendered with. The Studio's **Look** tab can derive it from photos of the real interior (floor finish and colour, walls, metal frames, glass tint, sign colour, light temperature), or you can set it by hand.

```jsonc
"theme": {
  "floor":  { "finish": "polished-tile", "color": "#ece7df", "tile": 1.2, "texture": null },
            // finish: polished-tile | stone | terrazzo | wood | carpet | concrete | vinyl
            // texture: optional seamless image (data URL) cut from a photo of the real floor
  "wall":   { "finish": "plaster", "color": "#f3f1ed" },   // plaster | panel | stone | wood
  "frame":  { "color": "#8e959f" },                        // shopfront mullions, rails, curtain wall
  "glass":  { "tint": "#d6ebf2", "clarity": 0.75 },        // 0 frosted … 1 crystal clear
  "accent": null,                                          // one sign colour for all shops, or null
  "facade": "glass",                                       // outer walls: glass | solid
  "lighting": "neutral",                                   // warm | neutral | cool
  "photos": []                                             // reference thumbnails (optional)
}
```

Category colours on roofs are not affected — they stay the map's colour legend.

### Per-space photo and finish — optional

```jsonc
{ "id": "S285", "kind": "unit", "name": "Sephora", …,
  "photo": "data:image/jpeg;base64,…",       // shown on the place card
  "finish": { "floor": "wood", "floorColor": "#c49a6c", "wallColor": "#f1ece4", "accent": "#111111" } }
```

Without a finish, a shop's interior floor follows its category (fashion → wood, food → terrazzo, services → carpet, clinics → vinyl …).

## Space kinds

| kind | drawn as | walkable | destination |
|---|---|---|---|
| `unit` | extruded shop block + roof label | no | yes |
| `amenity` | extruded room (WC, prayer room…) + icon | no | yes |
| `kiosk` | low island block | no | yes |
| `structure` | grey block (cores, columns, back-of-house). Named “Stairs…” → 3D steps, “Elevator/Lift…” → glass shaft | no | no |
| `wall` | white wall | no | no |
| `void` | hole in the slab with glass railing (atrium) | no | no |
| `walkway` | white floor | yes | no |
| `outdoor` / `parking` / `road` | ground surfaces | yes | no |
| `parking-bay` | painted bay lines | no | no |
| `green` | raised planting | no | no |

**Walkable space = floor outline − everything that isn’t walkable.** No routing graph has to be
drawn: the router rasterises each floor at 0.5 m, keeps paths away from walls and pulls them into
straight corridor lines. Connectors join floors; `accessible: false` connectors (stairs,
escalators) are skipped when the visitor turns on accessible routing.

## Connectors
`elevator`, `escalator`, `stairs`, `ramp`. Add one stop per floor served. Escalators can be one-way
(`direction: "up" | "down"`). Stairs/escalators/ramps link consecutive levels; elevators link all
their stops directly.

## QR anchors (beacon-free positioning)
Each anchor is a printed “You are here” code. Its URL is
`index.html?venue=<venue id>&at=<anchor id>`; opening it (phone camera or in-app scanner) puts
the blue dot there. `heading` (optional) is the direction a person faces while reading the sign,
used to pre-align the compass.

## Decor (3D objects)
`plant`, `tree`, `bench`, `table-set`, `fountain`, `car`, `column`, `screen`. Fountains, table
sets, plants, trees, benches and columns are solid — routes go around them.

## Deep links (viewer URL parameters)
| param | meaning |
|---|---|
| `venue=<id>` | loads `venues/<id>/venue.json` (default `grand-plaza`) |
| `src=<url>` | load a venue.json from any URL |
| `floor=<floorId>` | initial floor |
| `poi=<placeId>` | open a place card |
| `to=<placeId>&from=<placeId>` | open a route |
| `at=<anchorId>` / `pos=F0,x,y` | set the visitor’s position |
| `accessible=1` | accessible routing on |
| `mode=2d` | start in 2D |
| `lng=en\|es\|hi` | language |
| `wl=true` | white-label (hide the footer credit) |
