{
  "$schema": "https://mian.ro/schema/v2/registry.json",
  "schemaVersion": "2.0.0",
  "generatedAt": "2026-10-02T13:14:06.957Z",
  "id": "product-gallery",
  "name": "Product gallery",
  "category": "Data display",
  "description": "A main image with clickable thumbnails, pure CSS, keyboard-friendly, up to six images.",
  "tags": [
    "gallery",
    "product gallery",
    "images",
    "thumbnails",
    "photos",
    "ecommerce",
    "shop",
    "carousel",
    "lightbox"
  ],
  "requiresJs": false,
  "license": "LicenseRef-MIAN-1.0",
  "composition": {
    "role": null,
    "intents": [
      "product images",
      "image gallery",
      "thumbnails",
      "product photos"
    ],
    "prominence": null,
    "density": null,
    "worksAfter": [],
    "worksBefore": [],
    "alternatives": [],
    "avoid": null
  },
  "url": "https://mian.ro/components/product-gallery",
  "markdownUrl": "https://mian.ro/ai/components/product-gallery.md",
  "classes": [
    {
      "name": "mn-gallery",
      "description": "The wrapper, with one radio input per image first."
    },
    {
      "name": "mn-gallery-main",
      "description": "The large images (mn-media), in the same order as the radios."
    },
    {
      "name": "mn-gallery-thumbs",
      "description": "The thumbnails: one <label for> per radio."
    },
    {
      "name": "mn-gallery-thumb",
      "description": "A thumbnail label."
    }
  ],
  "accessibility": [
    "The radios are a real group: Tab to it, then arrow keys switch images. Name the group (role=\"group\" aria-label) and each radio (aria-label).",
    "Give the main images alt text; thumbnails repeat them, so their images can be decorative."
  ],
  "examples": [
    {
      "title": "Gallery",
      "description": null,
      "html": "<div class=\"mn-gallery\" role=\"group\" aria-label=\"Product images\" style=\"max-width:26rem\">\n  <input type=\"radio\" name=\"gal\" id=\"gal-1\" aria-label=\"Image 1: three vases\" checked><input type=\"radio\" name=\"gal\" id=\"gal-2\" aria-label=\"Image 2: glaze detail\"><input type=\"radio\" name=\"gal\" id=\"gal-3\" aria-label=\"Image 3: the studio\">\n  <div class=\"mn-gallery-main\">\n    <div class=\"mn-media mn-media-portrait\"><svg viewBox=\"0 0 400 320\" preserveAspectRatio=\"xMidYMid slice\" role=\"img\" aria-label=\"Illustration: three ceramic vases\" xmlns=\"http://www.w3.org/2000/svg\">\n<rect width=\"400\" height=\"320\" fill=\"var(--mn-surface-2)\"/>\n<rect y=\"262\" width=\"400\" height=\"58\" fill=\"color-mix(in srgb, var(--mn-fg) 7%, var(--mn-surface-2))\"/>\n<path d=\"M88 262c-30-24-34-70-10-96 8-9 10-20 6-34h40c-4 14-2 25 6 34 24 26 20 72-10 96Z\" fill=\"var(--mn-primary)\"/>\n<path d=\"M186 262c-22-4-36-24-34-58 2-40 22-70 26-110h40c4 40 24 70 26 110 2 34-12 54-34 58Z\" fill=\"var(--mn-surface)\" stroke=\"var(--mn-fg)\" stroke-width=\"2.5\"/>\n<path d=\"M170 150h56\" stroke=\"var(--mn-fg)\" stroke-width=\"2.5\" opacity=\".35\"/>\n<path d=\"M270 262c-6-30 0-64 22-84h52c22 20 28 54 22 84Z\" fill=\"var(--mn-accent)\"/>\n<ellipse cx=\"318\" cy=\"178\" rx=\"26\" ry=\"6\" fill=\"color-mix(in srgb, #000 22%, var(--mn-accent))\"/></svg></div>\n    <div class=\"mn-media mn-media-portrait\"><svg viewBox=\"0 0 600 450\" preserveAspectRatio=\"xMidYMid slice\" role=\"img\" aria-label=\"Glaze detail\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"600\" height=\"450\" fill=\"var(--mn-surface)\"/><g fill=\"none\" stroke=\"var(--mn-fg)\" stroke-width=\"1.5\"><circle cx=\"300\" cy=\"225\" r=\"12\"/><circle cx=\"300\" cy=\"225\" r=\"26\"/><circle cx=\"300\" cy=\"225\" r=\"40\"/><circle cx=\"300\" cy=\"225\" r=\"54\"/><circle cx=\"300\" cy=\"225\" r=\"68\"/><circle cx=\"300\" cy=\"225\" r=\"82\"/><circle cx=\"300\" cy=\"225\" r=\"96\"/><circle cx=\"300\" cy=\"225\" r=\"110\"/><circle cx=\"300\" cy=\"225\" r=\"124\"/><circle cx=\"300\" cy=\"225\" r=\"138\"/><circle cx=\"300\" cy=\"225\" r=\"152\"/><circle cx=\"300\" cy=\"225\" r=\"166\"/><circle cx=\"300\" cy=\"225\" r=\"180\"/><circle cx=\"300\" cy=\"225\" r=\"194\"/></g><circle cx=\"300\" cy=\"225\" r=\"12\" fill=\"var(--mn-primary)\"/></svg></div>\n    <div class=\"mn-media mn-media-portrait\"><svg viewBox=\"0 0 600 400\" preserveAspectRatio=\"xMidYMid slice\" role=\"img\" aria-label=\"The studio’s hills\" xmlns=\"http://www.w3.org/2000/svg\">\n<defs><linearGradient id=\"hills-sky-1\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"var(--mn-surface-2)\"/><stop offset=\"1\" stop-color=\"var(--mn-surface)\"/></linearGradient></defs>\n<rect width=\"600\" height=\"400\" fill=\"url(#hills-sky-1)\"/>\n<circle cx=\"430\" cy=\"120\" r=\"46\" fill=\"var(--mn-accent)\" opacity=\".85\"/>\n<path d=\"M0 250c80-40 150-70 230-40s140 20 210-20 120-10 160 10v200H0Z\" fill=\"color-mix(in srgb, var(--mn-primary) 30%, var(--mn-surface))\"/>\n<path d=\"M0 300c90-30 170-40 250-10s170 10 230-10 90 0 120 10v110H0Z\" fill=\"color-mix(in srgb, var(--mn-primary) 55%, var(--mn-surface))\"/>\n<path d=\"M0 350c120-20 220-24 320-6s200 4 280-6v62H0Z\" fill=\"var(--mn-primary)\"/></svg></div>\n  </div>\n  <div class=\"mn-gallery-thumbs\">\n    <label class=\"mn-gallery-thumb\" for=\"gal-1\"><span class=\"mn-media mn-media-square\"><svg viewBox=\"0 0 400 320\" preserveAspectRatio=\"xMidYMid slice\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\">\n<rect width=\"400\" height=\"320\" fill=\"var(--mn-surface-2)\"/>\n<rect y=\"262\" width=\"400\" height=\"58\" fill=\"color-mix(in srgb, var(--mn-fg) 7%, var(--mn-surface-2))\"/>\n<path d=\"M88 262c-30-24-34-70-10-96 8-9 10-20 6-34h40c-4 14-2 25 6 34 24 26 20 72-10 96Z\" fill=\"var(--mn-primary)\"/>\n<path d=\"M186 262c-22-4-36-24-34-58 2-40 22-70 26-110h40c4 40 24 70 26 110 2 34-12 54-34 58Z\" fill=\"var(--mn-surface)\" stroke=\"var(--mn-fg)\" stroke-width=\"2.5\"/>\n<path d=\"M170 150h56\" stroke=\"var(--mn-fg)\" stroke-width=\"2.5\" opacity=\".35\"/>\n<path d=\"M270 262c-6-30 0-64 22-84h52c22 20 28 54 22 84Z\" fill=\"var(--mn-accent)\"/>\n<ellipse cx=\"318\" cy=\"178\" rx=\"26\" ry=\"6\" fill=\"color-mix(in srgb, #000 22%, var(--mn-accent))\"/></svg></span></label>\n    <label class=\"mn-gallery-thumb\" for=\"gal-2\"><span class=\"mn-media mn-media-square\"><svg viewBox=\"0 0 600 450\" preserveAspectRatio=\"xMidYMid slice\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"600\" height=\"450\" fill=\"var(--mn-surface)\"/><g fill=\"none\" stroke=\"var(--mn-fg)\" stroke-width=\"1.5\"><circle cx=\"300\" cy=\"225\" r=\"12\"/><circle cx=\"300\" cy=\"225\" r=\"26\"/><circle cx=\"300\" cy=\"225\" r=\"40\"/><circle cx=\"300\" cy=\"225\" r=\"54\"/><circle cx=\"300\" cy=\"225\" r=\"68\"/><circle cx=\"300\" cy=\"225\" r=\"82\"/><circle cx=\"300\" cy=\"225\" r=\"96\"/><circle cx=\"300\" cy=\"225\" r=\"110\"/><circle cx=\"300\" cy=\"225\" r=\"124\"/><circle cx=\"300\" cy=\"225\" r=\"138\"/><circle cx=\"300\" cy=\"225\" r=\"152\"/><circle cx=\"300\" cy=\"225\" r=\"166\"/><circle cx=\"300\" cy=\"225\" r=\"180\"/><circle cx=\"300\" cy=\"225\" r=\"194\"/></g><circle cx=\"300\" cy=\"225\" r=\"12\" fill=\"var(--mn-primary)\"/></svg></span></label>\n    <label class=\"mn-gallery-thumb\" for=\"gal-3\"><span class=\"mn-media mn-media-square\"><svg viewBox=\"0 0 600 400\" preserveAspectRatio=\"xMidYMid slice\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\">\n<defs><linearGradient id=\"hills-sky-2\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"var(--mn-surface-2)\"/><stop offset=\"1\" stop-color=\"var(--mn-surface)\"/></linearGradient></defs>\n<rect width=\"600\" height=\"400\" fill=\"url(#hills-sky-2)\"/>\n<circle cx=\"430\" cy=\"120\" r=\"46\" fill=\"var(--mn-accent)\" opacity=\".85\"/>\n<path d=\"M0 250c80-40 150-70 230-40s140 20 210-20 120-10 160 10v200H0Z\" fill=\"color-mix(in srgb, var(--mn-primary) 30%, var(--mn-surface))\"/>\n<path d=\"M0 300c90-30 170-40 250-10s170 10 230-10 90 0 120 10v110H0Z\" fill=\"color-mix(in srgb, var(--mn-primary) 55%, var(--mn-surface))\"/>\n<path d=\"M0 350c120-20 220-24 320-6s200 4 280-6v62H0Z\" fill=\"var(--mn-primary)\"/></svg></span></label>\n  </div>\n</div>"
    }
  ],
  "css": ".mn-gallery { position: relative; display: grid; gap: .75rem; min-width: 0; }\n.mn-gallery > input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }\n.mn-gallery .mn-gallery-main > * { display: none; }\n.mn-gallery-thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(4rem, 1fr)); gap: .5rem; }\n.mn-gallery-thumb { display: block; overflow: hidden; border-radius: var(--mn-radius-field); cursor: pointer; opacity: .6; transition: opacity var(--mn-duration) var(--mn-ease); }\n.mn-gallery-thumb:hover { opacity: .9; }\n.mn-gallery-thumb > .mn-media { border-radius: inherit; }\n.mn-gallery:has(> input:nth-of-type(1):checked) .mn-gallery-main > :nth-child(1),\n.mn-gallery:has(> input:nth-of-type(2):checked) .mn-gallery-main > :nth-child(2),\n.mn-gallery:has(> input:nth-of-type(3):checked) .mn-gallery-main > :nth-child(3),\n.mn-gallery:has(> input:nth-of-type(4):checked) .mn-gallery-main > :nth-child(4),\n.mn-gallery:has(> input:nth-of-type(5):checked) .mn-gallery-main > :nth-child(5),\n.mn-gallery:has(> input:nth-of-type(6):checked) .mn-gallery-main > :nth-child(6) { display: block; animation: var(--mn-enter) var(--mn-enter-duration) var(--mn-ease-enter); }\n.mn-gallery:has(> input:nth-of-type(1):checked) .mn-gallery-thumb:nth-child(1),\n.mn-gallery:has(> input:nth-of-type(2):checked) .mn-gallery-thumb:nth-child(2),\n.mn-gallery:has(> input:nth-of-type(3):checked) .mn-gallery-thumb:nth-child(3),\n.mn-gallery:has(> input:nth-of-type(4):checked) .mn-gallery-thumb:nth-child(4),\n.mn-gallery:has(> input:nth-of-type(5):checked) .mn-gallery-thumb:nth-child(5),\n.mn-gallery:has(> input:nth-of-type(6):checked) .mn-gallery-thumb:nth-child(6) { opacity: 1; box-shadow: 0 0 0 2px var(--mn-bg), 0 0 0 4px var(--mn-fg); }\n.mn-gallery:has(> input:nth-of-type(1):focus-visible) .mn-gallery-thumb:nth-child(1),\n.mn-gallery:has(> input:nth-of-type(2):focus-visible) .mn-gallery-thumb:nth-child(2),\n.mn-gallery:has(> input:nth-of-type(3):focus-visible) .mn-gallery-thumb:nth-child(3),\n.mn-gallery:has(> input:nth-of-type(4):focus-visible) .mn-gallery-thumb:nth-child(4),\n.mn-gallery:has(> input:nth-of-type(5):focus-visible) .mn-gallery-thumb:nth-child(5),\n.mn-gallery:has(> input:nth-of-type(6):focus-visible) .mn-gallery-thumb:nth-child(6) { outline: 2px solid var(--mn-ring); outline-offset: 5px; }",
  "js": null,
  "install": {
    "css": "https://mian.ro/dist/mian.css",
    "js": null,
    "registryItem": "https://mian.ro/r/product-gallery.json"
  }
}
