> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zerodash.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Game assets

> Artwork in three aspect ratios, and how to render it sharply on every screen.

Every game ships artwork in three formats, delivered from the Zero-Dash CDN. The URLs and pixel dimensions come from the `images` array in [List games](/api-reference/customer/list-games).

## The three ratios

<Columns cols={3}>
  <Card title="Square — 1:1" icon="square">
    `270 × 270`

    Grid tiles, search results, compact lists.
  </Card>

  <Card title="Portrait — 3:4" icon="rectangle-vertical">
    `255 × 340`

    Mobile carousels and vertical lobby rows.
  </Card>

  <Card title="Wide — 3:2" icon="rectangle-wide">
    `600 × 400`

    Hero banners and featured slots.
  </Card>
</Columns>

```json theme={null}
"images": [
  { "ratio": "3:2", "width": 600, "height": 400, "url": "https://cdn.zerodash.studio/lucky-duck-600x400.webp" },
  { "ratio": "3:4", "width": 255, "height": 340, "url": "https://cdn.zerodash.studio/lucky-duck-255x340.webp" },
  { "ratio": "1:1", "width": 270, "height": 270, "url": "https://cdn.zerodash.studio/lucky-duck-270x270.webp" }
]
```

<Note>
  Match on `ratio`, not on array position or on parsing the filename. The order is not guaranteed and new formats may be added.
</Note>

## Rendering

Use `srcset` or CSS media queries so each viewport gets the right asset — that is what the three ratios are for.

<CodeGroup>
  ```html Art direction with <picture> theme={null}
  <picture>
    <source
      media="(min-width: 1024px)"
      width="600" height="400" />
    <source
      media="(min-width: 480px)"
      width="270" height="270" />
    <img
      src="https://cdn.zerodash.studio/lucky-duck-255x340.webp"
      width="255" height="340"
      alt="Lucky Duck"
      loading="lazy"
      decoding="async" />
  </picture>
  ```

  ```jsx React theme={null}
  function GameTile({ game, variant = '1:1' }) {
    const img = game.images.find((i) => i.ratio === variant) ?? game.images[0];

    return (
      <img
        src={img.url}
        width={img.width}
        height={img.height}
        alt={game.name}
        loading="lazy"
        decoding="async"
      />
    );
  }
  ```

  ```css CSS theme={null}
  .game-tile img {
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: cover;
  }

  @media (min-width: 1024px) {
    .game-tile--featured img {
      aspect-ratio: 3 / 2;
    }
  }
  ```
</CodeGroup>

<Tip>
  Always set `width` and `height` from the API values. The browser reserves the right box before the image arrives, so your lobby does not reflow as tiles load.
</Tip>

## Serving them well

<Steps>
  <Step title="Hotlink the CDN" icon="link">
    Point directly at `cdn.zerodash.studio`. It is already cached at the edge, and mirroring the assets means your copies go stale when artwork is refreshed.
  </Step>

  <Step title="Lazy-load below the fold" icon="down-long">
    `loading="lazy"` on everything except the first visible row. A lobby is dozens of images.
  </Step>

  <Step title="Refresh URLs with the catalogue" icon="rotate">
    Asset URLs travel with the games list. Re-read them when your cached catalogue updates instead of storing them separately.
  </Step>
</Steps>

<Warning>
  Do not resize wide artwork into a square slot with plain CSS scaling. The compositions are laid out per ratio — a squeezed 3:2 crops the game logo out of frame. Pick the asset that matches the slot.
</Warning>
