Labels
Contents chips
Background & Active labels for liquid containers
A container with a declared properties.contents carries a screen-space label in one of two states. The Background state is the always-on ambient identity — white text lifted off the scene by a dark halo, no plate — naming the liquid (Cold water, HCl 1M, Mixture, …) with hazard badges from a closed taxonomy centred in a row above it. The Active state is the same label "turned on" when the container is the step's focus or under the pointer: it adopts the equipment hover-label card (.widget-label — cream surface, dark ink, hard offset shadow) and carries the live volume. Identity only — temperature, pH and concentration stay on instruments; volume (mL) is the sole numeric exception, shown only in the Active state. Empty containers carry no chip. Behind a nearer vessel a Background chip fades out where the body crosses it (a gradient occlusion mask); the Active card is never masked. By default the chip anchors just above the container's top; during a pipette-drip step the drip target's chip instead rides the middle of the cylinder, where the student works at the meniscus. Owned by ContentsChipHandler.
Identity, no hazard
Plain chip when the liquid is benign. Example: a freshly poured beaker of water.
Physical-state hazards — hot & cold
Temperature surfaces qualitatively, two ways by state. On the Background chip it is the word Hot (above ~40 °C) or Cold (below ~10 °C) — white like the identity, in the badge row above the name. On the Active card it is the original coloured disc (orange hot, blue cold) inline before the qualified identity (Hot water / Cold water). Same derived signal, two presentations: a clear word at rest, a compact coloured dot when focused. (#renderChip emits both; CSS shows the word on Background and the disc on Active.) The corrosive diamond, by contrast, is an icon in both states. The cue is the author's initial condition — it drops once the simulation perturbs the contents (heating, mixing), reverting the chip to the base identity (Water). The 10–40 °C band shows no mark.
Chemical hazards — corrosive
A red-bordered diamond with a black centre dot — categorical hazard mark, not strict GHS — for both acids and bases. Authoring vocabulary keeps corrosive_acid vs corrosive_base separate so sub-type lessons can elaborate later, but the chip collapses both to one mark; an acid + base mixture therefore shows a single diamond, not two. After cross-species pour the destination becomes Mixture and inherits the union of source hazards.
Active — the label turned on
When the container is the step's focus or under the pointer, the chip swaps its halo for the equipment hover-label card: cream surface, dark ink, 1px ink border, hard offset shadow (.contents-chip--active, kept in sync with .widget-label). The live volume rides in the same text run, so a hovered beaker and a hovered instrument read as one label system. The shared identity text means the transition reads as the same label snapping on, not a swap to a different chip. The Active card carries a positive z-index, so it always paints above neighbouring Background chips — without it a rear vessel's chip could cover the focused card (most visibly the mid-cylinder drip readout).
Occlusion depth
When a labelled vessel sits in front of another (nearer the camera), the rear Background chip fades out — via a horizontal gradient mask — over the screen span where the nearer body crosses it, so the stack reads front-to-back without the whole chip blinking off. ContentsChipHandler projects each vessel's screen bounding box from its localBounds (objectScreenAABB) and masks the rear chip where a nearer box overlaps; the base opacity stays 0.8, and a vessel flanked on both sides masks both spans (the union). The Active card is exempt — never masked. (Camera-correct via a real depth compare; the occluder silhouette is the AABB — faithful for upright vessels, boxy for tilted/curved ones, with a contour-accurate Unity pass deferred.) The masks below are inline stills; in the lab they are computed live per frame.