site.mochott.layout

Layout of one page. One account has one layout per page: the record key is 'self' for the account's profile home, and equals the minisite record's key for that minisite's home. Other keys are reserved for additional pages. The subject must be a record in the same repository; layouts pointing at another account's records are ignored. A minisite's home only shows blocks about that minisite: renderers skip archive, tagList and seriesList blocks on it, and the tag, series and minisite filters of article lists.

Repository @tokimeki.blue did:plc:4tr5dqti7nmu6g2czpthntak namespace authority
Details · record, key any
Kindrecord
Record keyany
Authoritymochott.site
Indexed
cid bafyreicmal36gwx44s3uscaf7uxe3od3kmgeq52ga5v3v37q33synvssfi

Checks

Valid Lint pass
JSONDownload
{
  "$type": "com.atproto.lexicon.schema",
  "defs": {
    "archive": {
      "description": "Post counts per month, by publish date in Japan time.",
      "properties": {
        "view": {
          "default": "year",
          "knownValues": [
            "year",
            "month"
          ],
          "maxLength": 64,
          "type": "string"
        },
        "weekStart": {
          "default": "monday",
          "knownValues": [
            "monday",
            "sunday"
          ],
          "maxLength": 64,
          "type": "string"
        }
      },
      "type": "object"
    },
    "articleList": {
      "properties": {
        "filter": {
          "description": "Absent means all articles of the subject: the author's articles on a profile, the minisite's articles on a minisite (in the minisite's own order). The category filter is for minisite homes only; the others are for the profile home only.",
          "refs": [
            "#tagFilter",
            "#seriesFilter",
            "#minisiteFilter",
            "#categoryFilter"
          ],
          "type": "union"
        },
        "limit": {
          "default": 5,
          "maximum": 20,
          "minimum": 1,
          "type": "integer"
        },
        "sort": {
          "default": "recent",
          "description": "'popular' orders by the number of likes. A popular list shows its own articles only and has no further pages.",
          "knownValues": [
            "recent",
            "popular"
          ],
          "maxLength": 64,
          "type": "string"
        },
        "view": {
          "default": "list",
          "knownValues": [
            "card",
            "list",
            "magazine"
          ],
          "maxLength": 64,
          "type": "string"
        }
      },
      "type": "object"
    },
    "aspectRatio": {
      "properties": {
        "height": {
          "minimum": 1,
          "type": "integer"
        },
        "width": {
          "minimum": 1,
          "type": "integer"
        }
      },
      "required": [
        "width",
        "height"
      ],
      "type": "object"
    },
    "background": {
      "description": "Theme color token. Never a raw color, so every theme keeps its contrast.",
      "knownValues": [
        "none",
        "surface",
        "accent"
      ],
      "maxLength": 64,
      "type": "string"
    },
    "blueskyPosts": {
      "description": "Recent Bluesky posts (app.bsky.feed.post) of the account that owns the layout, read by the reader's browser from a Bluesky AppView. Replies are never shown, and neither are posts labeled sexual, nudity, porn or graphic-media.",
      "properties": {
        "limit": {
          "default": 3,
          "maximum": 10,
          "minimum": 1,
          "type": "integer"
        },
        "mediaOnly": {
          "default": false,
          "description": "Only posts with images or a video, drawn as a grid of their first image.",
          "type": "boolean"
        },
        "overflow": {
          "default": "fade",
          "description": "In a tile, what happens to posts that do not fit: 'fade' cuts them off with a fade, 'scroll' scrolls inside the tile and reads further posts as the reader reaches the end. Blocks in a flow section grow to fit and ignore it.",
          "knownValues": [
            "fade",
            "scroll"
          ],
          "maxLength": 64,
          "type": "string"
        },
        "pinned": {
          "default": false,
          "description": "Show the account's pinned post first.",
          "type": "boolean"
        },
        "reposts": {
          "default": false,
          "description": "Also show posts the account reposted.",
          "type": "boolean"
        }
      },
      "type": "object"
    },
    "categoryFilter": {
      "description": "Articles of one of the minisite's own categories (its slug). Shows nothing once the minisite no longer has that category.",
      "properties": {
        "category": {
          "maxLength": 32,
          "type": "string"
        }
      },
      "required": [
        "category"
      ],
      "type": "object"
    },
    "customBlock": {
      "description": "A site.mochott.block placed on the page, stored the same way as in an article.",
      "properties": {
        "blockUri": {
          "format": "at-uri",
          "type": "string"
        },
        "snapshot": {
          "description": "Copy of the block definition at the time it was placed, so the page keeps rendering if the block changes or is deleted.",
          "type": "unknown"
        },
        "values": {
          "description": "Field values keyed by the block's field keys.",
          "type": "unknown"
        }
      },
      "required": [
        "blockUri"
      ],
      "type": "object"
    },
    "embed": {
      "description": "Embedded media. Only providers on the renderer's allowlist are shown, and the player loads on click.",
      "properties": {
        "uri": {
          "format": "uri",
          "type": "string"
        }
      },
      "required": [
        "uri"
      ],
      "type": "object"
    },
    "flowItem": {
      "properties": {
        "background": {
          "ref": "#background",
          "type": "ref"
        },
        "block": {
          "refs": [
            "#text",
            "#heading",
            "#articleList",
            "#otherServices",
            "#customBlock",
            "#pinnedArticle",
            "#archive",
            "#tagList",
            "#seriesList",
            "#minisiteCard",
            "#linkCard",
            "#linkButton",
            "#image",
            "#gallery",
            "#hero",
            "#socialLinks",
            "#record",
            "#embed",
            "#blueskyPosts"
          ],
          "type": "union"
        },
        "hideOnMobile": {
          "type": "boolean"
        },
        "id": {
          "maxLength": 16,
          "type": "string"
        }
      },
      "required": [
        "id",
        "block"
      ],
      "type": "object"
    },
    "flowSection": {
      "description": "One to four columns whose height follows the content. Collapses to one column on mobile.",
      "properties": {
        "columns": {
          "default": 1,
          "maximum": 4,
          "minimum": 1,
          "type": "integer"
        },
        "heading": {
          "maxGraphemes": 100,
          "maxLength": 300,
          "type": "string"
        },
        "id": {
          "maxLength": 16,
          "type": "string"
        },
        "items": {
          "items": {
            "ref": "#flowItem",
            "type": "ref"
          },
          "maxLength": 30,
          "type": "array"
        }
      },
      "required": [
        "id",
        "items"
      ],
      "type": "object"
    },
    "gallery": {
      "description": "Several images shown together.",
      "properties": {
        "images": {
          "items": {
            "ref": "#galleryImage",
            "type": "ref"
          },
          "maxLength": 20,
          "minLength": 1,
          "type": "array"
        },
        "view": {
          "default": "grid",
          "description": "'grid' lays the images out in a grid, 'scroll' in one row to scroll sideways, 'slides' one at a time. Unknown values fall back to 'grid'.",
          "knownValues": [
            "grid",
            "scroll",
            "slides"
          ],
          "maxLength": 64,
          "type": "string"
        }
      },
      "required": [
        "images"
      ],
      "type": "object"
    },
    "galleryImage": {
      "properties": {
        "alt": {
          "description": "Alternative text. May be empty for a purely decorative image.",
          "maxGraphemes": 1000,
          "maxLength": 10000,
          "type": "string"
        },
        "aspectRatio": {
          "ref": "#aspectRatio",
          "type": "ref"
        },
        "image": {
          "accept": [
            "image/png",
            "image/jpeg",
            "image/webp",
            "image/gif"
          ],
          "maxSize": 1000000,
          "type": "blob"
        }
      },
      "required": [
        "image",
        "alt"
      ],
      "type": "object"
    },
    "header": {
      "description": "How the page header is drawn: the subject's name, description, icon, cover image and links. The header always comes first and is not part of the sections; what it shows is the subject's own record. Only the profile home uses it; a minisite draws its own header.",
      "properties": {
        "links": {
          "default": "buttons",
          "description": "How the subject's social links are shown. Unknown values fall back to 'buttons'.",
          "knownValues": [
            "buttons",
            "icons",
            "text",
            "hidden"
          ],
          "maxLength": 64,
          "type": "string"
        },
        "showDescription": {
          "default": true,
          "type": "boolean"
        },
        "style": {
          "default": "standard",
          "description": "'standard' puts the icon beside the name, 'center' stacks them centred, 'cover' draws a large cover image with the icon over its edge. Unknown values fall back to 'standard'.",
          "knownValues": [
            "standard",
            "center",
            "cover"
          ],
          "maxLength": 64,
          "type": "string"
        }
      },
      "type": "object"
    },
    "heading": {
      "properties": {
        "level": {
          "default": 2,
          "maximum": 3,
          "minimum": 2,
          "type": "integer"
        },
        "text": {
          "maxGraphemes": 100,
          "maxLength": 300,
          "type": "string"
        }
      },
      "required": [
        "text"
      ],
      "type": "object"
    },
    "hero": {
      "description": "A large image with a heading, a short text and a button over it. Without an image the accent colour is drawn instead.",
      "properties": {
        "align": {
          "default": "left",
          "knownValues": [
            "left",
            "center"
          ],
          "maxLength": 64,
          "type": "string"
        },
        "buttonLabel": {
          "description": "Shown only together with buttonUri.",
          "maxGraphemes": 50,
          "maxLength": 150,
          "type": "string"
        },
        "buttonUri": {
          "description": "An http(s) URL. Renderers must ignore any other scheme.",
          "format": "uri",
          "maxLength": 2048,
          "type": "string"
        },
        "heading": {
          "maxGraphemes": 100,
          "maxLength": 300,
          "type": "string"
        },
        "image": {
          "accept": [
            "image/png",
            "image/jpeg",
            "image/webp",
            "image/gif"
          ],
          "maxSize": 1000000,
          "type": "blob"
        },
        "text": {
          "maxGraphemes": 300,
          "maxLength": 900,
          "type": "string"
        }
      },
      "required": [
        "heading"
      ],
      "type": "object"
    },
    "image": {
      "properties": {
        "alt": {
          "description": "Alternative text. May be empty for a purely decorative image.",
          "maxGraphemes": 1000,
          "maxLength": 10000,
          "type": "string"
        },
        "aspectRatio": {
          "ref": "#aspectRatio",
          "type": "ref"
        },
        "caption": {
          "maxGraphemes": 300,
          "maxLength": 3000,
          "type": "string"
        },
        "image": {
          "accept": [
            "image/png",
            "image/jpeg",
            "image/webp",
            "image/gif"
          ],
          "maxSize": 1000000,
          "type": "blob"
        }
      },
      "required": [
        "image",
        "alt"
      ],
      "type": "object"
    },
    "linkButton": {
      "properties": {
        "label": {
          "maxGraphemes": 50,
          "maxLength": 300,
          "type": "string"
        },
        "uri": {
          "format": "uri",
          "type": "string"
        }
      },
      "required": [
        "uri",
        "label"
      ],
      "type": "object"
    },
    "linkCard": {
      "description": "Card for an external page. The OGP fields are a snapshot taken when the card was edited; viewers never trigger a fetch.",
      "properties": {
        "description": {
          "maxGraphemes": 1000,
          "maxLength": 10000,
          "type": "string"
        },
        "thumb": {
          "accept": [
            "image/png",
            "image/jpeg",
            "image/webp"
          ],
          "maxSize": 1000000,
          "type": "blob"
        },
        "title": {
          "maxGraphemes": 300,
          "maxLength": 3000,
          "type": "string"
        },
        "uri": {
          "format": "uri",
          "type": "string"
        }
      },
      "required": [
        "uri"
      ],
      "type": "object"
    },
    "main": {
      "description": "Layout of one page. One account has one layout per page: the record key is 'self' for the account's profile home, and equals the minisite record's key for that minisite's home. Other keys are reserved for additional pages. The subject must be a record in the same repository; layouts pointing at another account's records are ignored. A minisite's home only shows blocks about that minisite: renderers skip archive, tagList and seriesList blocks on it, and the tag, series and minisite filters of article lists.",
      "key": "any",
      "record": {
        "properties": {
          "createdAt": {
            "format": "datetime",
            "type": "string"
          },
          "header": {
            "ref": "#header",
            "type": "ref"
          },
          "sections": {
            "description": "Sections from top to bottom, below the page header.",
            "items": {
              "refs": [
                "#tileSection",
                "#flowSection"
              ],
              "type": "union"
            },
            "maxLength": 20,
            "type": "array"
          },
          "subject": {
            "description": "The page this layout renders: the account's own site.mochott.profile or site.mochott.minisite record.",
            "format": "at-uri",
            "type": "string"
          },
          "theme": {
            "ref": "#theme",
            "type": "ref"
          },
          "updatedAt": {
            "format": "datetime",
            "type": "string"
          }
        },
        "required": [
          "subject",
          "sections",
          "createdAt"
        ],
        "type": "object"
      },
      "type": "record"
    },
    "minisiteCard": {
      "properties": {
        "minisite": {
          "format": "at-uri",
          "type": "string"
        }
      },
      "required": [
        "minisite"
      ],
      "type": "object"
    },
    "minisiteFilter": {
      "properties": {
        "minisite": {
          "format": "at-uri",
          "type": "string"
        }
      },
      "required": [
        "minisite"
      ],
      "type": "object"
    },
    "otherServices": {
      "description": "The author's articles on other standard.site services.",
      "properties": {
        "limit": {
          "default": 6,
          "maximum": 20,
          "minimum": 1,
          "type": "integer"
        }
      },
      "type": "object"
    },
    "pinnedArticle": {
      "properties": {
        "article": {
          "description": "Always shows the latest version. Skipped when the article is gone or hidden.",
          "format": "at-uri",
          "type": "string"
        }
      },
      "required": [
        "article"
      ],
      "type": "object"
    },
    "record": {
      "description": "Card for an AT Protocol record, drawn by a renderer chosen from the record's collection (e.g. sh.tangled.repo). Collections without a renderer are skipped.",
      "properties": {
        "description": {
          "description": "The record's description as it was when placed. Refreshed when the page is published.",
          "maxGraphemes": 1000,
          "maxLength": 3000,
          "type": "string"
        },
        "title": {
          "description": "The record's name as it was when placed (for sh.tangled.repo, its name or record key). Refreshed when the page is published.",
          "maxGraphemes": 200,
          "maxLength": 600,
          "type": "string"
        },
        "uri": {
          "format": "at-uri",
          "type": "string"
        }
      },
      "required": [
        "uri"
      ],
      "type": "object"
    },
    "seriesFilter": {
      "properties": {
        "series": {
          "format": "at-uri",
          "type": "string"
        }
      },
      "required": [
        "series"
      ],
      "type": "object"
    },
    "seriesList": {
      "properties": {
        "series": {
          "description": "Series to show, in order. Absent means all series, newest first.",
          "items": {
            "format": "at-uri",
            "type": "string"
          },
          "maxLength": 10,
          "type": "array"
        },
        "view": {
          "default": "list",
          "description": "'cover' shows each series with the cover image of its first article.",
          "knownValues": [
            "list",
            "card",
            "cover"
          ],
          "maxLength": 64,
          "type": "string"
        }
      },
      "type": "object"
    },
    "socialLinks": {
      "description": "The social links of the account's site.mochott.profile record. Deprecated: the page header shows them; editors no longer offer this block, renderers still draw it.",
      "properties": {},
      "type": "object"
    },
    "spacer": {
      "description": "Empty cell used to leave a gap in a tile section.",
      "properties": {},
      "type": "object"
    },
    "tagFilter": {
      "properties": {
        "tag": {
          "maxGraphemes": 64,
          "maxLength": 640,
          "type": "string"
        }
      },
      "required": [
        "tag"
      ],
      "type": "object"
    },
    "tagList": {
      "properties": {
        "limit": {
          "default": 10,
          "maximum": 30,
          "minimum": 1,
          "type": "integer"
        }
      },
      "type": "object"
    },
    "text": {
      "properties": {
        "content": {
          "ref": "site.mochott.article#tiptapDocument",
          "type": "ref"
        }
      },
      "required": [
        "content"
      ],
      "type": "object"
    },
    "theme": {
      "properties": {
        "cardStyle": {
          "knownValues": [
            "soft",
            "outline",
            "flat"
          ],
          "maxLength": 64,
          "type": "string"
        },
        "preset": {
          "description": "Color and typeface preset. Unknown values fall back to 'standard'.",
          "knownValues": [
            "standard",
            "wakaba",
            "yoru"
          ],
          "maxLength": 64,
          "type": "string"
        }
      },
      "type": "object"
    },
    "tileItem": {
      "properties": {
        "background": {
          "ref": "#background",
          "type": "ref"
        },
        "block": {
          "refs": [
            "#pinnedArticle",
            "#archive",
            "#tagList",
            "#seriesList",
            "#minisiteCard",
            "#linkCard",
            "#linkButton",
            "#image",
            "#gallery",
            "#hero",
            "#socialLinks",
            "#spacer",
            "#record",
            "#embed",
            "#blueskyPosts"
          ],
          "type": "union"
        },
        "hideOnMobile": {
          "type": "boolean"
        },
        "id": {
          "maxLength": 16,
          "type": "string"
        },
        "size": {
          "description": "Width x height in cells. A tile wider than its grid (the section's columns on desktop, 2 on mobile) takes the full width and keeps its shape. A size the block does not support is replaced by the block's first supported size.",
          "knownValues": [
            "1x1",
            "2x1",
            "1x2",
            "2x2",
            "4x1",
            "4x2"
          ],
          "maxLength": 8,
          "type": "string"
        }
      },
      "required": [
        "id",
        "size",
        "block"
      ],
      "type": "object"
    },
    "tileSection": {
      "description": "A grid of square cells, `columns` wide on desktop and 2 on mobile. Items are packed in order. Future section kinds may be added; renderers skip kinds they do not know.",
      "properties": {
        "columns": {
          "default": 4,
          "maximum": 6,
          "minimum": 2,
          "type": "integer"
        },
        "heading": {
          "maxGraphemes": 100,
          "maxLength": 300,
          "type": "string"
        },
        "id": {
          "maxLength": 16,
          "type": "string"
        },
        "items": {
          "items": {
            "ref": "#tileItem",
            "type": "ref"
          },
          "maxLength": 30,
          "type": "array"
        }
      },
      "required": [
        "id",
        "items"
      ],
      "type": "object"
    }
  },
  "description": "A block-based page layout. Renders the home of a mochott profile or of a minisite.",
  "id": "site.mochott.layout",
  "lexicon": 1,
  "revision": 5
}