<!-- SPDX-License-Identifier: CC-BY-4.0 -->
# Semantic Transit SVG - draft 0.1

An OTI profile in which one SVG can be both print artwork and a semantic basis for an interactive map.

## Motivation

The EMT Málaga reference inspected in the research on 27 September 2026 uses a hand-authored SVG with meaningful identifiers such as `linea-17` and stop identifiers, plus a JavaScript interaction layer. The source remains a third-party reference, not code to copy into OTI.

The proposed profile formalises a convention so that an engine can generate it from GTFS and GTFS-Carto, designers can edit the artwork without losing semantics, and an open runtime can interact with conforming outputs.

## Draft rules

1. The root `<svg>` includes `data-oti="0.1"`, `<title>`, `<desc>` and OTI product metadata in JSON-LD.
2. Identifiers use escaped GTFS identifiers: characters matching `[^A-Za-z0-9_-]` become `_`. Multiple identifiers are joined with `.`.
3. `data-*` attributes are the semantic source of truth because editing applications may change SVG IDs.

| Element | ID pattern | Required attributes | Notes |
|---|---|---|---|
| Background layer | `layer-<name>` | `data-layer` | Examples: `layer-water`, `layer-land`, `layer-streets`, `layer-rail`, `layer-areas`, `layer-poi`; only areas and POIs need interaction |
| Route bundle | `bundle-<edge_id>` | `data-routes="r1 r2 …"` in drawing order | Includes a `.casing` child |
| Individual route | `route-<route_id>` | `data-route-id`, `data-route-short-name`, `data-color` | Hidden by default where bundles are used; `pointer-events: stroke` |
| Direction marker | `dir-<route_id>-<direction_id>` | `data-route-id`, `data-direction-id` | Directional chevron |
| Stop | `stop-<stop_id>[.<stop_id>…]` | `data-stop-ids`, `data-name`, `data-routes`, `data-rank` (1-5) | Groups stop poles at one node; rank controls zoom visibility |
| Hub or interchange | `hub-<hub_id>` | `data-stop-ids`, `data-name` | Supports sub-stop information |
| Terminal | `terminal-<route_id>-<stop_id>` | `data-route-id`, `data-stop-id` | Always visible |
| Label | `label-<type>-<id>` | `data-for` | Searchable `<text>` elements; accessibility requires evaluation in the target interface |
| Legend item | `legend-<route_id>` | `data-route-id` | Interactive |
| Point of interest | `poi-<id>` | `data-name`, `data-category` | |
| Area | `area-<id>` | `data-name`, `data-kind` | For example a district or fare zone |

4. Interactive elements have appropriate `role`, `aria-label` and `tabindex="0"`. The runtime also provides a navigable text alternative listing routes and stops.
5. Runtime state uses classes such as `.is-active`, `.is-dimmed`, `.is-selected` and root `.mode-navigating`, rather than rewriting styles. Dim the other information instead of relying only on thickening the selected route.
6. Optional `data-min-zoom` controls detail visibility.
7. Selection is reflected in a deep link such as `#route=17`, `#stop=1234` or `#poi=…`.

## Remaining draft work

The attribute schema, validator and reference-runtime details require development and validation. Command examples in earlier research are proposals unless verified against the current CLI. Consult the package documentation for implemented behaviour.

English is the primary language. The official project website is https://opentransitinformation.org.
