diff --git a/docs/resources/index.md b/docs/resources/index.md
index 86aa4006dbc..58402cd0e45 100644
--- a/docs/resources/index.md
+++ b/docs/resources/index.md
@@ -98,7 +98,7 @@ PLR's `Resource` subclasses in the inheritance tree are:
| ├── TipSpot |
- | ├── Lid |
+ | ├── Lid |
| ├── PetriDishHolder |
| ├── PlateAdapter |
@@ -133,6 +133,7 @@ deck/deck
itemized-resource/itemized-resource
itemized-resource/tube-rack/tube-rack
resource-holder/resource-holder
+lid/lid
plate-adapter/plate-adapter
petri-dish-holder/petri-dish-holder
resource-stack/resource-stack
diff --git a/docs/resources/itemized-resource/plate/plate.rst b/docs/resources/itemized-resource/plate/plate.rst
index 63ab1ba2d4f..bbb83aac5ff 100644
--- a/docs/resources/itemized-resource/plate/plate.rst
+++ b/docs/resources/itemized-resource/plate/plate.rst
@@ -39,7 +39,7 @@ This standard is similar to the `Opentrons API labware naming standard `.
----
diff --git a/docs/resources/lid/lid.ipynb b/docs/resources/lid/lid.ipynb
new file mode 100644
index 00000000000..9e11eeb5e59
--- /dev/null
+++ b/docs/resources/lid/lid.ipynb
@@ -0,0 +1,184 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "lid-intro",
+ "metadata": {},
+ "source": [
+ "# Lid\n",
+ "\n",
+ "A {class}`~pylabrobot.resources.Lid` is a removable cover for a plate, a tip rack or a container.\n",
+ "It is a resource of its own: a lid on a plate is one of the plate's children, next to its wells,\n",
+ "and it can be taken off and put back."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "creating-a-lid",
+ "metadata": {},
+ "source": [
+ "## Creating a lid\n",
+ "\n",
+ "Besides a name and its outer dimensions, a lid has a `nesting_z_height`: the overlap, in mm,\n",
+ "between the lid and the resource it covers, in the z direction. `size_z` is the lid's full height.\n",
+ "Both can be measured with a caliper:\n",
+ "\n",
+ "\n",
+ "\n",
+ "The lid below has the dimensions of `cor_96_wellplate_360uL_Fb_lid` in the resource library, the\n",
+ "lid of a Corning 96-well plate:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "create-example",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from pylabrobot.resources import Lid\n",
+ "\n",
+ "lid = Lid(\n",
+ " name=\"plate_lid\",\n",
+ " size_x=127.76,\n",
+ " size_y=85.48,\n",
+ " size_z=8.9,\n",
+ " nesting_z_height=7.6,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "putting-a-lid-on",
+ "metadata": {},
+ "source": [
+ "## Putting a lid on\n",
+ "\n",
+ "Set the plate's `lid`, or assign the lid to the plate with `assign_child_resource`. Unless a\n",
+ "location is given, the lid is centred on the plate's top face and lowered by its\n",
+ "`nesting_z_height`. The lid's location, like any child's, is relative to the plate:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "put-on-example",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from pylabrobot.resources import Coordinate, cor_96_wellplate_360uL_Fb\n",
+ "\n",
+ "plate = cor_96_wellplate_360uL_Fb(name=\"plate\") # 14.2 mm tall\n",
+ "plate.lid = lid # the same as plate.assign_child_resource(lid)\n",
+ "\n",
+ "assert plate.lid is lid\n",
+ "assert lid.location == Coordinate(0, 0, 14.2 - 7.6)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lid-at-creation",
+ "metadata": {},
+ "source": [
+ "`Plate(..., lid=lid)` puts a lid on when the plate is created. Some library plates\n",
+ "do this when called with `with_lid=True`: `cor_96_wellplate_360uL_Fb(name=\"plate\",\n",
+ "with_lid=True)` creates the same plate with the library's `cor_96_wellplate_360uL_Fb_lid` on,\n",
+ "named `plate_lid`.\n",
+ "\n",
+ "The lid is one of the plate's `children`, next to its wells. The plate's item methods, such as\n",
+ "`get_all_items()`, return only the wells."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "taking-a-lid-off",
+ "metadata": {},
+ "source": [
+ "## Taking a lid off\n",
+ "\n",
+ "Unassign the lid, or set the plate's `lid` to `None`. The lid then has no parent and no location:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "take-off-example",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "lid.unassign() # the same as plate.lid = None\n",
+ "\n",
+ "assert not plate.has_lid()\n",
+ "assert lid.parent is None and lid.location is None"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "model-only",
+ "metadata": {},
+ "source": [
+ "Putting a lid on and taking it off change only the resource model; they do not move a physical\n",
+ "lid."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "resources-that-take-a-lid",
+ "metadata": {},
+ "source": [
+ "## Resources that take a lid\n",
+ "\n",
+ "A resource takes a lid through the `Liddable` mixin, which provides `lid`, `has_lid()` and\n",
+ "`get_lid_location()`, the location used above. {class}`~pylabrobot.resources.Plate`,\n",
+ "{class}`~pylabrobot.resources.TipRack` and {class}`~pylabrobot.resources.Container` (troughs,\n",
+ "tubes, petri dishes and wells) are liddable; a lid is not.\n",
+ "\n",
+ "A liddable resource holds one lid at a time: putting on a second raises `ValueError`. So does a lid\n",
+ "more than 1 mm smaller than the resource in x or y, which could not cover it. A larger lid is\n",
+ "centred, so it overhangs evenly:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "trough-example",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from pylabrobot.resources import hamilton_1_trough_200mL_Vb\n",
+ "\n",
+ "trough = hamilton_1_trough_200mL_Vb(name=\"trough\") # 37 x 118 x 95 mm\n",
+ "trough_lid = Lid(\n",
+ " name=\"trough_lid\",\n",
+ " size_x=39,\n",
+ " size_y=120,\n",
+ " size_z=10,\n",
+ " nesting_z_height=4,\n",
+ ")\n",
+ "trough.lid = trough_lid\n",
+ "\n",
+ "assert trough_lid.location == Coordinate(-1, -1, 95 - 4)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "api-reference",
+ "metadata": {},
+ "source": [
+ "See {class}`~pylabrobot.resources.Lid` for the API reference."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}