{
  "lexicon": 1,
  "id": "net.bisks.quadrants.position",
  "defs": {
    "main": {
      "type": "record",
      "description": "A person's marker on one quadrants chart. One record per (person, chart) — the record key is the chart's id, so re-placing a marker (via \"move my spot\") overwrites the previous position in place rather than creating a new one; \"remove my spot\" deletes it outright. Chart definitions themselves (title, axis labels, anchor points) are not atproto records — they live only in the creator's browser localStorage, so a chart's positions can outlive the chart's own metadata for other viewers. Written and read by quadrants (https://quadrants.bisks.net).",
      "key": "any",
      "record": {
        "type": "object",
        "required": ["chart", "chartTitle", "x", "y", "createdAt"],
        "properties": {
          "chart": {
            "type": "string",
            "maxLength": 64,
            "description": "The chart's id (from its /c/<id>/ URL) — a 12-character slug (crypto.randomUUID with dashes stripped, truncated). Also used as this record's own rkey."
          },
          "chartTitle": {
            "type": "string",
            "maxLength": 320,
            "maxGraphemes": 80,
            "description": "The chart's title, snapshotted at placement time (the chart itself isn't an atproto record, so this is the only durable copy of its title alongside a position). Bound matches the chart-creation title input's maxlength=80."
          },
          "x": {
            "type": "integer",
            "minimum": -1000,
            "maximum": 1000,
            "description": "Horizontal position as an integer permille: the normalized [-1, 1] value from eventToNorm() (lib/plot.js) times 1000 and rounded, so -1000 = left edge, 0 = center, 1000 = right edge. atproto records have no float type, only integer — chart.html rounds to this scale before writing (fixed 2026-08-15; this collection previously wrote the raw unrounded float, the same bug class paintmoot's mark.json documents and had already fixed)."
          },
          "y": {
            "type": "integer",
            "minimum": -1000,
            "maximum": 1000,
            "description": "Vertical position as an integer permille, same encoding as `x`: -1000 = bottom, 0 = center, 1000 = top, +y is up. See `x`'s description for why the scale is x1000."
          },
          "createdAt": {
            "type": "string",
            "format": "datetime",
            "description": "When this position was last written (placed or moved), as an ISO 8601 datetime."
          }
        }
      }
    }
  }
}
