# The catalog

Every design is listed under one family and one of that family's types, from the catalog vocabulary. You can't add families or types: use the closest one. `get_reference` with topic "vocabulary" gives every type's description and maximum load, and the ids for `holds`, `where`, `works_with` and `needs`.

`holds` lists the things the design is really for: the catalog's "What do you want to hang?" pages list it under each one, so leave out anything it only sort of holds.

## Parts: listings

People browse **parts**, never design files. A file makes one part by default: named by its `title`, holding its `holds`, with every preset a **size**. Add `listings:` when the presets aren't all sizes of one thing:

- If a preset holds **a different thing**, or a person would look for it **under a different name**, it is its own part.
- If it only changes a dimension of the same thing, it is a size.

```yaml
listings:
  angled-spray-can-shelf: # the part id: its URL, /p/angled-spray-can-shelf. Never rename one that is published.
    name: Angled spray-can shelf
    holds: [spray-can] # some of the design's holds; together the parts hold exactly the design's holds
    sizes: # preset names; the first is the lead size and the card picture
      - { preset: Spray cans 4 in, label: "4 in wide, 80 mm deep" }
  angled-paint-tin-shelf:
    name: Angled paint-tin shelf
    holds: [paint-can]
    sizes: [Pint paint tin 4 in]
    goes_with: # write each pair once, it shows on both parts
      - { part: caulk-tube-rack, why: "the other tubes and tins on the same wall" }
```

Every preset is a size of exactly one part. `sizes: []` is the design at its defaults (at most one part). A part's `holds` says what an item's page lists it under, so each is one of the design's own `holds`. In descriptions, call the printed pieces in `parts:` **pieces** ("Prints as 2 pieces").

Limits: `listings:` has at most 8 parts. A part id is at most 60 characters. A part holds at most 8 items and has at most 32 sizes. A size's `label` is at most 40 characters and its `note` at most 120. A part goes with at most 5 others.

### A part's seat: how it holds its item

A part's `seat:` says how it holds the item it is for, so the site can show that item on it in 3D, at every size. It is data that follows the settings, like a shape. Give one to a part that holds something:

```yaml
listings:
  spray-can-holder:
    name: Spray-can holder
    holds: [spray-can]
    sizes: [Standard can (66 mm), Slim can (53 mm)]
    seat:
      kind: floor # floor, over, channel, grip or onto
      at: # roughly above the right spot, in an anchor's frame as a shape's move + attach; the item settles down onto the part
        anchor: mount.arm_root
        offset:
          [
            "=settings.can_d / 2 + settings.room + settings.wall_t",
            0,
            "=min(101.6, max(25.4, 2 * (settings.can_d / 2 + settings.room + settings.wall_t))) / 2",
          ]
      size: { diameter: "=settings.can_d" } # what the part is made for: the nearest item is shown
```

- **kind:**
  - `floor`: the item stands on an upward surface, inside a cup, ring or hole or not; `tilt` leans it (degrees about z).
  - `over`: it hangs over an arm, peg, prong, rail, saddle or post; `axis` is the hang line (default x, or z; never y); `tilt` raises it (degrees about z), as on a peg that rises. A hook arm's `arm_top` anchor already runs along its arm, tilt and all.
  - `channel`: its rim, lip, neck or wire drops into a slot; `axis` is the slot's run (default z); `tilt` leans it, as in a plate that falls toward the front.
  - `grip`: a sprung jaw or a magnet holds it; `axis` is the jaw's axis (default y), `squeeze` the mm the jaw is made under the item (0 or more).
  - `onto`: the part fits onto the item, which sits in the wall itself, such as a wire slatwall hook.
- **size:** one or more of `diameter`, `width`, `depth`, `height`, `length`, `thickness`, each above 0 mm or a formula. They are the item's own measures, before `turn`: a tape measure turned to point out of the wall is still `width` 45 (across the tape) and `depth` 85 (its length). A `grip` names `diameter`; a `floor` names `diameter`, or `width` and `depth`.
- **at:** where the item starts, in the anchor's frame, turned by `tilt` when there is one (x then runs along a sloped plate or a rising arm). It only moves straight down from there to the first thing under it, so start it above where it rests and clear of every tip, lip and rim on the way: a hank started over a J-hook's tip lands on the tip, not in the J.
- **item:** which of the part's `holds` it places, when it holds several (default: the first).
- **Optional:** `turn` (degrees about the item's free axis, for the view); `copies: { count, step: [x, y, z] }` for more items (count is 2 to 12, or a formula that comes to 1 to 12 at the defaults and every size, such as a rack for one or two bottles); `pair: { spacing }` when the item rests on two of the part, `spacing` mm apart along z (above 0); `none: [preset]` for sizes that show no item.
- **Leave `anchor` out** in a design without bricks: the offset is then in the design's own coordinates. Such a design has no wall of its own, so only an `onto` seat can place it.

A seat is only for the picture and the 3D view: no geometry, check, rule or export reads it. One that can't be used is a warning, and the part shows without its item. Every catalog seat is checked after a geometry change, and shown only when all of these hold:

- the item doesn't pierce the part or the wall (an `onto` item may be in the slots);
- it starts above where it rests: an item that has to be lifted more than 2 mm out of the part isn't shown;
- it rests on something under it, not only against a side;
- a `floor` item stands on more than a point or an edge, its weight over what it stands on; or it leans toward its weight on the part or the wall, high enough that its foot won't slide out;
- an `over` item's weight is under what it hangs on, along its hang line; to one side of it only where the part keeps it from swinging; a loop hangs by its upper half, and an item that straddles (a drill on a fork) rests at the point it hangs from;
- a `channel` item bears by its rim, its rim itself is held in a slot at least 1 mm deep, and its weight is under the rim along the slot;
- a `grip` item touches the jaws at its size and isn't pushed into them at its size less the squeeze;
- on a seat that slopes more than about 26.6°, where friction alone no longer holds it, a lip at least 1 mm tall or the wall at the low end stops it sliding.

An item on a seat that slopes (an arm that rises, a plate that falls) really tilts with it: give the seat that `tilt`, or put it on an anchor that slopes, or it won't be shown at rest.

`preset_holds` (`{ "<preset name>": [hold ids] }`) is retired: a file that still has it gets a `deprecated-preset-holds` warning, and its fix writes the same thing as `listings:`. Don't write it in a new design.

## Families and their types

- `hooks` (Hooks & grippers): `broom-gripper`, `utility-hook`, `multi-prong-hook`, `j-hook`, `cradle`, `cord-wrap`, `coat-hook`, `swap-tip-hook`, `flag-hook` and `pivot-hook`.
- `locks` (Locks): `hook-lock`, `snap-lock`, `anti-sweep-stop` and `accessory-clip`.
- `labels` (Labels & signs): `press-in-label`, `clip-label`, `label-flag`, `groove-label-strip`, `sign-holder` and `paper-clip`.
- `tool-storage` (Tool storage): `screwdriver-rack`, `plier-bar`, `bit-holder`, `battery-cleat`, `charger-mount`, `drill-holster`, `instrument-holder`, `magnet-bar` and `long-handle-rack`.
- `bins` (Bins, cups & trays): `bin-hook`, `item-holder`, `spray-can-holder`, `caulk-holder`, `cube-bin`, `tray` and `gridfinity-shelf`.
- `shelves` (Shelf brackets & clips): `shelf-bracket`, `angled-shelf`, `shelf-clip` and `glass-shelf-rest`.
- `mounts` (Mounts & adapters): `base-plate`, `keyhole-plate`, `t-nut`, `system-receiver` and `pegboard-adapter`.
- `fit-finish` (Fit & finish): `test-fit`, `starter-set`, `groove-filler`, `end-cap` and `outlet-trim`.
- `rods` (Rods & dowel brackets): `dowel-bracket`, `paper-towel-holder`, `hang-rail` and `bungee-retainer`.
- `devices` (Power & devices): `power-strip-cradle`, `led-channel`, `cable-channel`, `phone-holder` and `headphone-mount`.
- `sports` (Sports & outdoors): `helmet-holder`, `cap-holder`, `fishing-rod-holder`, `glasses-rack` and `ball-ring`.
- `garden` (Cleaning & garden): `spray-bottle-rack`, `trash-bag-holder`, `hose-saddle` and `glove-dispenser`.

## Load classes

- `light`: Light · under 2 kg.
- `moderate`: Moderate · 2–5 kg.

The studio calculates what a part holds on each wall, at the defaults and at its weakest, for stated print assumptions (the reference print: PLA, 2 walls, 15 % infill, 0.2 mm layers). It is feedback for improving the design, not a guarantee, and never a reason a design is refused. The catalog's class is calculated too: `moderate` from 5 kg at the defaults and every preset, else `light`; under 2 kg it says so as a warning. A class is backed when the calculated figure reaches its top (light 2 kg, moderate 5 kg). A design's own `load` field is optional: a note, never the listing. A type's rating caps the class too.

How the calculation works, and what it can't promise:

- Every figure is labelled "calculated, not tested", with the print assumptions beside it. It errs low: when the studio isn't sure, it counts less. These numbers are feedback for improving a design, not a guarantee.
- The print matters: walls (perimeters), infill, material and how each part lies on the bed. The reference print is what the catalog lists at. `validate_draft` and `inspect_draft` take `print_assumptions` to ask what if, say 4 walls, 40 % infill or PETG; a what-if changes the load figures only and is never kept as the draft's report.
- A brick that carries the load reports its own capacity, for its printed parts.
- When your own shapes carry the load (an arm or a peg you drew), the studio calculates them with the item at their worst point, so the figure is rough: the load's `rough` says so, and the catalog lists the design as light. A `load_point` (the anchor and the offset, in mm, where the item hangs) says where the item really hangs. A print report can confirm more later.
- `limiting` names the weakest section by its cut plane, never by its size. "Cut 12 mm out from the wall" is the plane 12 mm in front of the slat face; "at height 30 mm" a level plane; "across its width at z = 40 mm" the plane at z = 40, which crosses the part from front to back. The section is all the material that plane passes through, and the mm² is its area. Find the shapes that cross that plane there and make them thicker, wider or shorter: material anywhere else doesn't move the figure. The issue's `corner` says which settings it was read at: the quick check reads only the defaults, while `inspect_draft` and the full check also read the weakest corner.
- Shapes that can't be calculated (a loose piece, a gap) get a warning: join them to the mount as one solid piece if the figure matters.
- A brick's rating on the load path still counts when your shapes are welded to it: the lowest reading wins.
- The mount's own limit doesn't cap the figure for an arm you draw. A high number there says how strong your arm is, not how much the mount holds.
- Twist from an item hung far to one side isn't counted.

No load finding ever refuses a design or blocks saving or publishing. When holding matters for what the part is for, use the figures in the loop: strengthen what `limiting` names, check again, and compare. [presets-and-checks.md](presets-and-checks.md) lists every load code.

## One pick per type, variants as presets

Each type shows one design first: its pick. Sizes and options of that design are its presets, not new designs. `get_reference` with topic "coverage" shows each type's pick and which types still have none.

## Near-duplicates

When a draft is at least 90% similar to a published design of the same type, the change report's `similar_warning` names it. Make a preset of that design, or remix it with `create_draft` and `remix_of`, instead of a near copy.

A design an admin took down can't come back as a copy. Publishing refuses a new design that builds the same part at its defaults (renaming, adding or inlining settings, or renaming shapes and parts, changes nothing) or, when both were measured, has the same bricks and shapes with every side and the volume within 2%. The design it was copied from still publishes, and so do remixes of it that don't carry the taken-down build.

## Research and sources

Research may set sizes and ideas. Never copy another model's shape. If a licensed model inspired the design, name it in `sources` with the kind "inspired-by". The market research (`get_reference` topic "research/market") and the buy-instead list name heavy products to recommend buying: respect them by saying plainly what the part is for, not by skipping a type.
