%% tikzphysics.tex -- user manual for tikzphysics 1.7.0
\documentclass[11pt]{article}

\usepackage[T1]{fontenc}
\usepackage{fourier}
\usepackage[a4paper,margin=22mm,headheight=14pt]{geometry}
\usepackage{microtype}
\usepackage{parskip}
\usepackage{needspace}
\usepackage{booktabs}
\usepackage{tabularx}
\usepackage{array}
\usepackage{enumitem}
\usepackage{xcolor}
\usepackage{minted}
\usepackage{fancyhdr}
\usepackage{hyperref}
\usepackage{tikzphysics}

\definecolor{physicsblue}{HTML}{1E4E79}
\definecolor{physicsteal}{HTML}{0B6E69}
\definecolor{physicssoft}{HTML}{F2F6F8}
\definecolor{physicscode}{HTML}{263238}
\definecolor{physicsgray}{HTML}{5E6A71}
\definecolor{physicscodebg}{HTML}{282A36}

\hypersetup{
  colorlinks=true,
  linkcolor=physicsblue,
  urlcolor=physicsteal,
  pdftitle={tikzphysics - TikZ-native physics diagrams},
  pdfauthor={Vaibhav Blayer},
  pdfsubject={User manual for tikzphysics 1.7.0},
  pdfkeywords={LaTeX, TikZ, physics, diagrams, mechanics, optics},
}

\pagestyle{fancy}
\fancyhf{}
\fancyhead[L]{\textcolor{physicsgray}{\texttt{tikzphysics} 1.7.0}}
\fancyhead[R]{\textcolor{physicsgray}{User manual}}
\fancyfoot[C]{\thepage}
\renewcommand{\headrulewidth}{0.3pt}

\setlist{nosep,leftmargin=*}
\setcounter{tocdepth}{2}
\makeatletter
\renewcommand*\l@subsection{\@dottedtocline{2}{1.5em}{3.5em}}
\makeatother
\setlength{\emergencystretch}{2em}

\usemintedstyle{friendly}
\setminted{
  fontsize=\footnotesize,
  bgcolor=physicssoft,
  breaklines=true,
  breakanywhere=true,
  autogobble=true,
  tabsize=2,
  frame=single,
  framesep=3mm,
  baselinestretch=1.05,
  formatcom=\color{black},
  linenos=false,
  samepage=true,
}

\let\physicsoriginalsubsection\subsection
\renewcommand{\subsection}{\Needspace{8\baselineskip}\physicsoriginalsubsection}
\let\physicsoriginalsubsubsection\subsubsection
\renewcommand{\subsubsection}{\Needspace{6\baselineskip}\physicsoriginalsubsubsection}

\newcommand{\key}[1]{\texttt{#1}}
\newcommand{\sty}[1]{\texttt{#1}}
\newcommand{\module}[1]{\texttt{tikzphysics.#1}}
\newcommand{\physicsnote}[1]{%
  \par\smallskip
  \noindent\colorbox{physicssoft}{%
    \parbox{\dimexpr\linewidth-2\fboxsep\relax}{\textcolor{physicsblue}{\textbf{Note.}} #1}}%
  \par\smallskip
}

\newcolumntype{K}{>{\ttfamily\raggedright\arraybackslash}p{0.31\linewidth}}
\newcolumntype{D}{>{\raggedright\arraybackslash}X}

\title{%
  \vspace{-1.5cm}
  {\Huge\bfseries\textcolor{physicsblue}{\texttt{tikzphysics}}}\\[5pt]
  {\Large TikZ-native physics diagrams}\\[12pt]
  {\large Version 1.7.0}}
\author{Vaibhav Blayer\\\href{mailto:vaibhavblayer@gmail.com}{vaibhavblayer@gmail.com}}
\date{2026-09-30}

\begin{document}
\maketitle

\begin{abstract}
\noindent
\texttt{tikzphysics} extends TikZ with reusable shapes and geometric anchors for
classical-physics diagrams. It provides continuous contact surfaces, straight
and circular ramps, inclined planes, blocks, springs, pulleys, differential
elements, shell and slice constructions, native fluid vessels, and optical
components. Mechanics primitives include particles, disks, supports, vectors,
and pendulums. Diagrams use ordinary TikZ nodes, paths, and named pics.
\end{abstract}

\noindent\colorbox{physicssoft}{%
  \parbox{\dimexpr\linewidth-2\fboxsep\relax}{%
    \textbf{In one line:}
    \key{\textbackslash node[wedge, wedge angle=30] (W) \{\};}}}

\tableofcontents
\clearpage

% -----------------------------------------------------------------------------
\section{Start here}\label{sec:start}


\subsection{Your first diagram in five minutes}
Install the package normally, or upload the generated single-file
\texttt{output/overleaf/tikzphysics.sty} beside an Overleaf document. Compile
this complete document with pdfLaTeX. No shell escape is needed to use the
package.
\Needspace{10\baselineskip}
\begin{minted}{latex}
\documentclass[tikz,border=5mm]{standalone}
\usepackage{tikzphysics}
\begin{document}
\begin{tikzpicture}
  \node[block] (B) at (3,0) {$m$};
  \draw[spring] (0,0) -- node[above] {$k$} (B.west);
\end{tikzpicture}
\end{document}
\end{minted}
\begin{center}
\begin{tikzpicture}
  \node[block] (B) at (3,0) {$m$};
  \draw[spring] (0,0) -- node[above] {$k$} (B.west);
\end{tikzpicture}
\end{center}
Read this as: create a \sty{block}, name it \key{B}, and connect a
\sty{spring} to its \key{west} anchor. Change \key{(3,0)} to move the block;
change \key{minimum width} to resize it. The spring follows its endpoints.

\subsection{How to explore this manual}
\begin{tabularx}{\linewidth}{@{}p{.36\linewidth}D@{}}
\toprule
Your next task & Where to go \\
\midrule
Choose defaults for a whole worksheet & Section~\ref{sec:defaults} \\
Build the spring--block--pulley example & Section~\ref{sec:complete-system} \\
Find anchors while drawing & Section~\ref{sec:debug} \\
Draw supports, vectors, or pendulums & Section~\ref{sec:primitives} \\
Draw a polar area or differential ring & Section~\ref{sec:elements} \\
Look up every feature's keys and anchors & Section~\ref{sec:reference} \\
Troubleshoot placement or transformations & Section~\ref{sec:troubleshooting} \\
\bottomrule
\end{tabularx}
The examples directory contains complete documents. Its \texttt{README.md}
provides a learning route and explains what each example demonstrates.

\subsection{Loading}

Load every module with the package wrapper:

\Needspace{3\baselineskip}
\begin{minted}{latex}
\usepackage{tikzphysics}
\end{minted}

For smaller documents, load only the required TikZ libraries:

\Needspace{4\baselineskip}
\begin{minted}{latex}
\usepackage{tikz}
\usetikzlibrary{tikzphysics.surface, tikzphysics.mechanics}
\end{minted}

The available libraries are \module{surface}, \module{ramps}, \module{mechanics},
\module{elements}, \module{fluids}, \module{optics}, \module{waves}, and \module{core}.
Thermodynamic diagrams are in \module{thermodynamics}.
Heat-transfer apparatus is in \module{thermalphysics}.
Each feature library loads
\module{core} automatically.

\subsection{The design model}

\begin{enumerate}
  \item Choose a node style such as \sty{wedge}, \sty{block}, \sty{convex-lens},
        \sty{concave-lens}, \sty{slab}, or \sty{prism}.
  \item Use familiar TikZ sizing keys where they apply, and \key{physics ...}
        keys for shape-specific geometry or as unit-aware conveniences.
  \item Give each node a name and compose the diagram through its anchors;
        draw a spring directly between any two such coordinates.
\end{enumerate}

Short style names are the normal user interface. The longer forms remain
available when another package or the surrounding document already defines a
generic TikZ style such as \sty{block}.

\begin{tabularx}{\linewidth}{@{}KKD@{}}
\toprule
Short style & Collision-safe style & Object \\
\midrule
platform & physicsplatform-both & General platform with two configurable walls \\
platform-left / platform-right / platform-both & physicsplatform-left / physicsplatform-right /
  physicsplatform-both & Explicit platform variants \\
platform-left-up / platform-right-up & physicsplatform-left-up /
  physicsplatform-right-up & One-wall presets with \key{wall angle=90} \\
wedge & physicswedge & Inclined plane \\
ramp / ramp-left & physicsramp & Continuous wall--floor--linear-incline body \\
curved-ramp / curved-ramp-left & physicscurvedramp & Circular contact ramp with a filled body \\
ground / ceiling & physicsground / physicsceiling & Horizontal contact strips \\
wall-left / wall-right & physicswall-left / physicswall-right & Vertical contact strips \\
block / pulley & physicsblock / physicspulley & Mechanics nodes \\
spring & physics spring / physicsspring & Positioned node or coil decoration for paths \\
polar element & physicspolarelement & General annular-sector differential element \\
differential sector & physicsdifferentialsector & Zero-inner-radius sector preset \\
differential ring & physicsdifferentialring & Full thin-annulus preset \\
unwrapped ring & physicsunwrappedring & Equivalent rectangular strip \\
concave-mirror / convex-mirror & physicsconcavemirror / physicsconvexmirror & Curved mirrors \\
convex-lens & physicsconvexlens & Symmetric biconvex lens \\
concave-lens & physicsconcavelens & Symmetric biconcave lens \\
slab & physicsslab & Parallel-sided rectangular slab \\
prism & physicsprism & Isosceles triangular prism \\
\bottomrule
\end{tabularx}

\Needspace{7\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}
  \node[wedge, pulley edge, wedge width=5.6, wedge angle=30] (W) at (0,0) {};
  \node[block, minimum width=0.9cm, minimum height=0.7cm,
        rotate=30, anchor=south] at (W.slope-mid) {$m$};
\end{tikzpicture}
\end{minted}

\begin{center}
\begin{tikzpicture}
  \node[wedge, wedge width=5, wedge angle=30] (W) at (0,0) {};
  \node[block, minimum width=0.9cm, minimum height=0.7cm,
        rotate=30, anchor=south] at (W.slope-mid) {$m$};
\end{tikzpicture}
\end{center}


\subsection{Set defaults once}\label{sec:defaults}
The default block is a 1\,cm square and the default pulley diameter is 1\,cm.
Simple names are the public interface: \sty{spring}, \sty{block},
\sty{pulley}, and \sty{wedge}. No slash-prefixed style is required.
Each node or path style offers an \key{every <name>} hook:
\Needspace{10\baselineskip}
\begin{minted}{latex}
\tikzset{
  every block/.style={minimum width=1cm,minimum height=1cm,fill=white},
  every spring/.style={pre length=3mm,post length=3mm,amplitude=2mm},
  every pulley/.style={minimum size=1cm}
}
\node[block] (A) {};
\node[block,minimum width=2cm] (B) at (3,0) {};
\draw[spring] (A.east) -- (B.west);
\end{minted}
For node and path styles, the order is built-in settings, the shared hook,
the feature hook, then later options on your node or path. This means a
local \key{minimum width=2cm} overrides \key{every block} when placed after
\sty{block}. A scope contains its own settings without changing later pictures.
A bare \key{minimum width} set at picture level may still be replaced by the
object's built-in dimensions; use \key{every block} for object-wide sizing.

\key{every physics object} applies to package node styles;
\key{every physics connection} applies to package path styles.
\key{every platform} covers all platform variants; the other node/path hooks
use the short feature name. The collision-safe hook \key{every physics block}
is called by the initial definition of \key{every block}; redefining the short
hook replaces that forwarding style. Do not put \sty{block} inside
\key{every block}, since that would call the hook recursively.

You can also use \key{spring/.append style=\{...\}}. Hooks are a convenient,
explicit place to keep preferences while retaining the short drawing syntax.
Built-in defaults are not the same as a key's missing-value default:
\key{show anchors} means \key{show anchors=true}, whereas geometric keys such
as \key{wedge angle} require a value. An omitted geometry key keeps its
inherited or built-in setting.

\subsection{Dimensions}

TikZ's native sizing keys are fully supported and are often the most familiar
choice. Use explicit units with them, for example
\key{minimum width=1.2cm}, \key{minimum height=8mm}, or
\key{minimum size=0.7cm}. Package convenience keys may be used instead. They
accept explicit dimensions and also interpret a bare value as centimetres, so
\key{block width=1.2} and \key{minimum width=1.2cm} produce the same
block size requirement.

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.37\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.27\linewidth}D@{}}
\toprule
\normalfont Native TikZ (preferred) & \normalfont Package convenience & \normalfont Applies to \\
\midrule
minimum width / height & block width / height & \sty{block} \\
minimum size & pulley diameter & \sty{pulley} \\
minimum width / height & platform width / depth & Bent platforms \\
minimum width / height & ground width / depth & \sty{ground} \\
minimum width / height & ceiling width / depth & \sty{ceiling} \\
minimum width / height & wall thickness / height & Left and right walls \\
minimum width & wedge width & \sty{wedge} width only \\
minimum width & --- & \sty{ramp} overall horizontal width \\
minimum width / height & slab width / height & \sty{slab} \\
minimum width / height & prism width / height & \sty{prism} \\
\bottomrule
\end{tabularx}

The alternatives in each row set the same underlying TikZ size requirement.
If both are supplied, normal TikZ option ordering applies: the last value wins.
Put the shape style first, then the desired sizing keys, for example
\key{block, minimum width=1.2cm}. These are minimum dimensions; a node
may grow to contain wider or taller text.

Shape-specific keys remain necessary when they control more than a native node
size. In particular, use \key{wedge height} rather than
\key{minimum height} when the height should determine wedge geometry. Keys
such as \key{wall angle}, \key{strip width},
\key{convex lens radius}, and \key{prism apex angle} have no native TikZ sizing
equivalent. All package
size keys require positive values. Each concise wedge key also has a
collision-safe form prefixed by \key{physics}, as listed in the wedge section.

\subsection{Complete copy-paste examples}

Each example below includes the document class, package loading, document
environment, and complete TikZ picture. The first shows the basic composition
pattern: name a node, then place another node at one of its anchors.

\Needspace{14\baselineskip}
\begin{minted}{latex}
\documentclass[tikz, border=6mm]{standalone}
\usepackage{tikzphysics}

\begin{document}
\begin{tikzpicture}
  \node[platform, minimum width=5cm, minimum height=2cm]
    (platform) at (0,0) {};

  \node[pulley, minimum size=8mm]
    (pulley) at (platform.north east) {};
\end{tikzpicture}
\end{document}
\end{minted}

\begin{center}
\begin{tikzpicture}[scale=0.8,every node/.append style={transform shape}]
  \node[platform, minimum width=5cm, minimum height=2cm]
    (platform) at (0,0) {};
  \node[pulley, minimum size=8mm]
    (pulley) at (platform.north east) {};
\end{tikzpicture}
\end{center}

The next complete document composes an inclined plane, two blocks, a pulley,
and one exactly tangent string.

\Needspace{22\baselineskip}
\begin{minted}{latex}
\documentclass[tikz, border=6mm]{standalone}
\usepackage{tikzphysics}

\begin{document}
\begin{tikzpicture}
  \node[ground, ground width=8.6cm, ground depth=3mm,
        anchor=top-left] (ground) at (-0.6,0) {};
  \node[wedge, pulley edge, wedge width=7cm, wedge angle=30]
    (plane) at (0,0) {};

  \node[block, minimum width=1cm, minimum height=1cm,
        rotate=30, anchor=south]
    (surface-block) at (plane.slope-mid) {$m$};

  \node[pulley] (pulley) at (plane.pulley-center) {};

  \node[block, anchor=north]
    (load) at ($(pulley.east)+(0,-2.5cm)$) {$M$};

  \physicsstringoverpulley{surface-block.east}{pulley}{load.north}
\end{tikzpicture}
\end{document}
\end{minted}

\begin{center}
\begin{tikzpicture}[scale=0.72,every node/.append style={transform shape}]
  \node[ground, ground width=8.6cm, ground depth=3mm,
        anchor=top-left] (ground) at (-0.6,0) {};
  \node[wedge, pulley edge, wedge width=7cm, wedge angle=30]
    (plane) at (0,0) {};
  \node[block, minimum width=1cm, minimum height=1cm,
        rotate=30, anchor=south]
    (surface-block) at (plane.slope-mid) {$m$};
  \node[pulley] (pulley) at (plane.pulley-center) {};
  \node[block, anchor=north]
    (load) at ($(pulley.east)+(0,-2.5cm)$) {$M$};
  \physicsstringoverpulley{surface-block.east}{pulley}{load.north}
\end{tikzpicture}
\end{center}

The 7 cm, 30-degree wedge resolves to a height of about 4.04 cm. Placing the
hanging block's north anchor 2.5 cm below the pulley centre leaves the full
1 cm block about 5.4 mm above the ground.

\subsubsection*{Wedge key variants}

This complete document demonstrates angle-driven and height-driven geometry,
both width interfaces, and every value of
\key{wedge right angle at}.

\Needspace{32\baselineskip}
\begin{minted}{latex}
\documentclass[tikz, border=6mm]{standalone}
\usepackage{tikzphysics}

\begin{document}
\begin{tikzpicture}[font=\small]
  \node[wedge, minimum width=3cm, wedge angle=30,
        anchor=base-mid]
    (angle-br) at (0,0) {};
  \node[align=center] at (0,-0.65)
    {angle 30\textdegree\\right angle at br};

  \node[wedge, wedge width=3, wedge angle=40,
        wedge right angle at=bl, anchor=base-mid]
    (angle-bl) at (4.2,0) {};
  \node[align=center] at (4.2,-0.65)
    {width 3cm, angle 40\textdegree\\right angle at bl};

  \node[wedge, minimum width=3cm, wedge angle=45,
        wedge right angle at=top, anchor=base-mid]
    (angle-top) at (8.4,0) {};
  \node[align=center] at (8.4,-0.65)
    {angle 45\textdegree\\right angle at top};

  \node[wedge, minimum width=3.2cm, wedge height=2cm,
        anchor=base-mid]
    (height-driven) at (12.6,0) {};
  \node[align=center] at (12.6,-0.65)
    {height 2cm\\angle derived};
\end{tikzpicture}
\end{document}
\end{minted}

\begin{center}
\begin{tikzpicture}[font=\scriptsize,scale=0.8,every node/.append style={transform shape}]
  \node[wedge, minimum width=3cm, wedge angle=30,
        anchor=base-mid]
    (angle-br) at (0,0) {};
  \node[align=center] at (0,-0.65)
    {angle 30\textdegree\\right angle at br};
  \node[wedge, wedge width=3, wedge angle=40,
        wedge right angle at=bl, anchor=base-mid]
    (angle-bl) at (4.2,0) {};
  \node[align=center] at (4.2,-0.65)
    {width 3cm, angle 40\textdegree\\right angle at bl};
  \node[wedge, minimum width=3cm, wedge angle=45,
        wedge right angle at=top, anchor=base-mid]
    (angle-top) at (8.4,0) {};
  \node[align=center] at (8.4,-0.65)
    {angle 45\textdegree\\right angle at top};
  \node[wedge, minimum width=3.2cm, wedge height=2cm,
        anchor=base-mid]
    (height-driven) at (12.6,0) {};
  \node[align=center] at (12.6,-0.65)
    {height 2cm\\angle derived};
\end{tikzpicture}
\end{center}

% -----------------------------------------------------------------------------
\clearpage
\section{Contact surfaces and wedges}

\subsection{Bent platforms}

The three underlying platform shapes share a horizontal floor strip. The left
and right variants extend that strip through one bent wall; the general
\sty{platform} style uses the two-wall shape and is equivalent to the explicit
\sty{platform-both} style. Each node is rendered as one continuous
platform, without a hinge mark or seam. Wall direction is continuous rather
than limited to presets, so the gallery below covers every distinct
configuration class; intermediate angles use the same keys.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Style & Configuration \\
\midrule
platform & General two-wall platform; equivalent to \sty{platform-both}. \\
platform-left & One wall at the left floor corner. \\
platform-right & One wall at the right floor corner. \\
platform-left-up & Left-wall preset with \key{wall angle=90}. \\
platform-right-up & Right-wall preset with \key{wall angle=90}. \\
platform-both & Two walls; set both with \key{wall angle}, or set them
  independently with \key{left wall angle} and
  \key{right wall angle}. \\
\bottomrule
\end{tabularx}

\subsubsection*{Variant gallery}

\begin{center}
\begin{tikzpicture}[font=\scriptsize]
  % Row 1: vertical variants
  \node[platform-left-up, platform width=2.2, platform depth=1,
        anchor=surface] at (0,0) {};
  \node[align=center] at (0,-1.45) {up-left preset\\\key{90}};
  \node[platform-right-up, platform width=2.2, platform depth=1,
        anchor=surface] at (3.8,0) {};
  \node[align=center] at (3.8,-1.45) {up-right preset\\\key{90}};
  \node[platform, platform width=2.2, platform depth=1,
        wall angle=-90, anchor=surface] at (7.6,0) {};
  \node[align=center] at (7.6,-1.45) {down both\\\key{-90/-90}};
  \node[platform-both, platform width=2.2, platform depth=1,
        wall angle=90, anchor=surface] at (11.4,0) {};
  \node[align=center] at (11.4,-1.45) {up both\\\key{90/90}};

  % Row 2: sloped variants
  \node[platform-left, platform width=2.2, platform depth=1,
        wall angle=135, anchor=surface] at (0,-3) {};
  \node[align=center] at (0,-4.45) {outward left\\\key{135}};
  \node[platform-right, platform width=2.2, platform depth=1,
        wall angle=45, anchor=surface] at (3.8,-3) {};
  \node[align=center] at (3.8,-4.45) {outward right\\\key{45}};
  \node[platform, platform width=2.2, platform depth=1,
        left wall angle=135, right wall angle=45,
        anchor=surface] at (7.6,-3) {};
  \node[align=center] at (7.6,-4.45) {outward both\\\key{135/45}};
  \node[platform-both, platform width=2.2, platform depth=1,
        left wall angle=45, right wall angle=135,
        anchor=surface] at (11.4,-3) {};
  \node[align=center] at (11.4,-4.45) {inward both\\\key{45/135}};

  % Row 3: straight and independently angled variants
  \node[platform-left, platform width=2.2, platform depth=1,
        wall angle=180, anchor=surface] at (0,-6) {};
  \node[align=center] at (0,-7.45) {straight left\\\key{180}};
  \node[platform-right, platform width=2.2, platform depth=1,
        wall angle=0, anchor=surface] at (3.8,-6) {};
  \node[align=center] at (3.8,-7.45) {straight right\\\key{0}};
  \node[platform-both, platform width=2.2, platform depth=1,
        left wall angle=180, right wall angle=0,
        anchor=surface] at (7.6,-6) {};
  \node[align=center] at (7.6,-7.45) {straight both\\\key{180/0}};
  \node[platform-both, platform width=2.2, platform depth=1,
        left wall angle=120, right wall angle=-35,
        anchor=surface] at (11.4,-6) {};
  \node[align=center] at (11.4,-7.45) {asymmetric\\\key{120/-35}};
\end{tikzpicture}
\end{center}

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.28\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.28\linewidth}D@{}}
\toprule
\normalfont Concise key & \normalfont Collision-safe alias & \normalfont Meaning and default \\
\midrule
minimum width / platform width & physics platform width & Overall floor width; default \texttt{5cm}. \\
minimum height / platform depth & physics platform depth & Wall length and nominal vertical extent; default
  \texttt{2cm}. \\
strip width & physics strip width & Thickness of the floor and walls; default \texttt{0.25cm}. \\
wall angle & physics wall angle & Direction of every wall, measured counter-clockwise from the
  positive x-axis; default \texttt{-90}. \\
left wall angle & physics left wall angle & Left-wall override for \sty{platform-both}. \\
right wall angle & physics right wall angle & Right-wall override for \sty{platform-both}. \\
wall inset & physics wall inset & Horizontal distance from each projecting floor tip to its wall root;
  default \texttt{0cm}. \\
wall drop & physics wall drop & Downward distance from each projecting floor tip to its wall root;
  default \texttt{0cm}. \\
left/right wall inset & physics left/right wall inset & Independent inset overrides for
  \sty{platform-both}. \\
left/right wall drop & physics left/right wall drop & Independent drop overrides for
  \sty{platform-both}. \\
\bottomrule
\end{tabularx}

\subsubsection*{Continuous pulley edges}

The \sty{pulley edge} preset adds the tapered corner found in many textbook
pulley diagrams. It sets \key{wall inset=0.5cm} and
\key{wall drop=0.5cm}, half the default pulley diameter in each direction.
The floor, diagonal transition, and wall remain one closed, patterned path.
There is no separately overlaid bracket.
An upward wall meets the floor at its sharp corner; keep its wall inset and
wall drop at zero. Inset and drop are for walls extending below the floor.

\begin{minted}{latex}
\node[platform-right, pulley edge, platform width=5] (S) {};
\node[pulley] (P) at (S.pulley-center) {};

\node[platform, pulley edges] (Both) {};
\node[pulley] at (Both.left-pulley-center) {};
\node[pulley] at (Both.right-pulley-center) {};
\end{minted}

\begin{center}
\begin{tikzpicture}[font=\scriptsize]
  \node[platform-left, pulley edge, platform width=2.8,
        platform depth=1.1, anchor=surface] (LPE) at (0,0) {};
  \node[pulley] at (LPE.pulley-center) {};
  \node[below=5pt] at (LPE.wall-surface-100) {left};
  \node[platform-right, pulley edge, platform width=2.8,
        platform depth=1.1, anchor=surface] (RPE) at (4.7,0) {};
  \node[pulley] at (RPE.pulley-center) {};
  \node[below=5pt] at (RPE.wall-surface-100) {right};
  \node[platform, pulley edges, platform width=2.8,
        platform depth=1.1, anchor=surface] (BPE) at (9.4,0) {};
  \node[pulley] at (BPE.left-pulley-center) {};
  \node[pulley] at (BPE.right-pulley-center) {};
  \node[below=5pt] at (BPE.bottom-50) {both};
\end{tikzpicture}
\end{center}

On a one-wall platform, \key{pulley-center} marks the projecting tip.
The \key{wall-root} anchor marks the end of the transition;
\key{transition-0..100} addresses points along it, with \key{transition-50}
at its midpoint.
For \sty{platform-both}, prefix these anchors with \key{left-} or
\key{right-}. The styles \sty{left pulley edge} and
\sty{right pulley edge} enable one side independently. Shared and
side-specific inset/drop keys accept bare centimetre values or explicit TeX
dimensions. Both values default to zero, so existing platform drawings retain
their original geometry. The length set by \key{platform depth} remains the
wall length from the wall root; the transition drop adds to the complete
vertical extent.

Use \key{show anchors} with the \key{transition} family to inspect points on
the diagonal. The complete in-picture reference card also lists every new key
and anchor. See \path{examples/debug-pulley-edge.tex} for a standalone example.

\clearpage
\subsubsection*{Key-by-key variants}

Each public platform key can be varied independently and combined with any
configuration from the preceding gallery. These examples isolate the original
sizing and direction controls; the pulley-edge controls are shown above.

\begin{center}
\begin{tikzpicture}[font=\scriptsize]
  % Row 1: dimensions
  \node[platform-both, platform width=3.8, platform depth=0.8,
        anchor=surface] at (0,0) {};
  \node[align=center] at (0,-1.85)
    {wide floor\\\key{platform width=3.8}};
  \node[platform-both, platform width=2.5, platform depth=1.5,
        anchor=surface] at (5.2,0) {};
  \node[align=center] at (5.2,-1.85)
    {deep walls\\\key{platform depth=1.5}};
  \node[platform-both, platform width=2.8, platform depth=1,
        strip width=0.5, anchor=surface] at (10.4,0) {};
  \node[align=center] at (10.4,-1.85)
    {thick material\\\key{strip width=0.5}};

  % Row 2: shared and independent directions
  \node[platform-both, platform width=2.6, platform depth=1.1,
        wall angle=70, anchor=surface] at (0,-4) {};
  \node[align=center] at (0,-5.65)
    {shared direction\\\key{wall angle=70}};
  \node[platform-both, platform width=2.6, platform depth=1.1,
        left wall angle=135, right wall angle=-90,
        anchor=surface] at (5.2,-4) {};
  \node[align=center] at (5.2,-5.65)
    {left override\\\key{left wall angle=135}};
  \node[platform-both, platform width=2.6, platform depth=1.1,
        left wall angle=-90, right wall angle=45,
        anchor=surface] at (10.4,-4) {};
  \node[align=center] at (10.4,-5.65)
    {right override\\\key{right wall angle=45}};
\end{tikzpicture}
\end{center}

With zero inset and drop, the floor and wall contact lines meet at
\key{pulley-center}. With either transition dimension set, that point remains the
projecting floor tip and the wall begins at \key{wall-root}. The complete body
is still one closed polygon with exact inner miters. The two-wall style exposes
\key{left-pulley-center} and \key{right-pulley-center}; these lie on the same continuous
geometry. Angles may vary
continuously; only a left wall at $0^\circ$ and a right wall at $180^\circ$
(modulo $360^\circ$) are excluded because they retrace the floor and have no
finite miter.

\begin{center}
\begin{tikzpicture}[font=\small]
  \node[platform-left, platform width=5, platform depth=2.2,
        wall angle=125, anchor=pulley-center] (P) at (0,0) {};
  \draw[physicsblue,very thick]
    (P.wall-surface-55) -- (P.pulley-center) -- (P.surface-75);
  \fill[physicsblue] (P.pulley-center) circle (1.5pt);
  \node[physicsblue,below left=2pt] at (P.pulley-center) {\key{pulley-center}};
  \fill[physicsteal] (P.surface-75) circle (1.2pt);
  \node[physicsteal,above=2pt] at (P.surface-75) {\key{surface-75}};
\end{tikzpicture}
\end{center}

\subsubsection*{Platform anchors}

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Part & Available anchors \\
\midrule
Floor contact & \key{surface-0..100}, left to right; \key{surface} is its midpoint. \\
Other floor edges & \key{bottom-0..100} left to right; \key{left-0..100}
  and \key{right-0..100} bottom to top. \\
Wall edges & \key{wall-surface-0..100} and \key{wall-back-0..100} root to tip;
  \key{wall-base-0..100} and \key{wall-tip-0..100} outer to inner. \\
Transition & \key{transition-0..100} from \key{pulley-center} to
  \key{wall-root}. \\
Inside & \key{floor-center} and \key{wall-center}. \\
Two-wall form & Prefix wall and transition families with \key{left-} or
  \key{right-}; use \key{left-pulley-center} and \key{right-pulley-center}. \\
\bottomrule
\end{tabularx}

Every boundary family accepts integer percentages from 0 through 100; for
example, \key{surface-0}, \key{surface-50}, and \key{surface-100} mark the
floor contact face's start, midpoint, and end.

To see the floor without a crowded wall legend, use \key{show anchors} and
select its four edge families at 0, 50, and 100:
\begin{minted}{latex}
physics debug/anchor families={surface,bottom,left,right},
physics debug/anchor samples={0,50,100}
\end{minted}
Inspect a wall separately with the \key{transition}, \key{wall-surface},
\key{wall-back}, \key{wall-base}, and \key{wall-tip} families.
On \sty{platform}, prefix these five with
\key{left-} or \key{right-}. The complete thirteen-page visual reference is
\path{surface-anchor-coverage.pdf} in \path{docs/}. Its copy-ready source is
\path{surface-anchor-coverage.tex} in \path{examples/}.

\begin{center}
\begin{tikzpicture}
  \node[platform-left,platform width=5cm,platform depth=2cm,
    wall angle=135,show anchors,
    physics debug/anchor list={pulley-center},
    physics debug/anchor families={surface,wall-surface},
    physics debug/anchor samples={0,50,100}] (P) {};
\end{tikzpicture}
\end{center}
An upward wall has zero inset and drop, so its visible contact line meets the
floor at one corner.

\subsection{Wedges}

\sty{wedge} creates a right triangle for inclined-plane diagrams.
Its material uses TikZ's \key{dots} pattern by default; a later
\key{pattern=...} option can replace it normally.

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[wedge, wedge width=3.2, wedge angle=32] (A) at (0,0) {};
  \node[below=3pt] at (A.base-mid) {right angle at \key{br}};

  \node[wedge, wedge width=3.2, wedge angle=40,
        wedge right angle at=bl] (B) at (4.4,0) {};
  \node[below=3pt] at (B.base-mid) {right angle at \key{bl}};

  \node[wedge, wedge width=3.2,
        wedge right angle at=top] (C) at (8.8,0) {};
  \node[below=3pt] at (C.base-mid) {right angle at \key{top}};
\end{tikzpicture}
\end{center}

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.27\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.34\linewidth}D@{}}
\toprule
\normalfont Concise key & \normalfont Collision-safe alias & \normalfont Meaning and default \\
\midrule
wedge width & physics wedge width & Horizontal foot-to-tip span; default
  \texttt{4cm}. A pulley edge shortens the base by its inset. \\
wedge height & physics wedge height & Explicit height when no angle is supplied. \\
wedge angle & physics wedge angle & Authoritative acute angle; default is 30 degrees for
  \key{bl}/\key{br}, and 45 degrees for \key{top}. \\
wedge right angle at & physics wedge right angle at & One of \key{br} (default), \key{bl}, or
  \key{top}. \\
wedge top inset & physics wedge top inset & Horizontal clearance behind the fixed pulley tip;
  default \texttt{0cm}. \\
wedge top drop & physics wedge top drop & Vertical distance from the pulley tip to the wall root;
  default \texttt{0cm}. \\
\bottomrule
\end{tabularx}

Geometry precedence is \key{wedge angle}, then \key{wedge height}, then
the mode default. The principal anchors are \key{bl}, \key{br}, \key{top},
\key{base-mid}, \key{right-mid}, \key{slope-mid},
\key{slope-right-mid}, and \key{centroid}. Numeric edge families are
\key{base-0..100}, \key{right-0..100}, \key{slope-0..100}, and
\key{transition-0..100}.
\key{right-mid} equals \key{right-50}, \key{slope-mid} equals
\key{surface-50}, and \key{mid} equals the area \key{centroid}. The
four-point pulley-edge variant computes that centroid from its visible body.
The complete rendered wedge anchor map is in \path{docs/wedge-anchors.md} and
\path{docs/wedge-anchor-coverage.pdf}.

\subsubsection*{Pulley edge on a wedge}

The shared \sty{pulley edge} preset keeps the wedge tip fixed and inserts a
5 mm inward transition followed by a 10 mm drop. It therefore accommodates a
full default 1 cm hanging block beside the supporting wall.

\begin{minted}{latex}
\node[ground, ground width=8.6cm, ground depth=3mm,
      anchor=top-left] (G) at (-0.6,0) {};
\node[wedge, pulley edge, wedge width=7cm, wedge angle=30] (W) {};
\node[pulley] (P) at (W.pulley-center) {};
\node[block, anchor=north] (H)
  at ($(P.east)+(0,-2.5cm)$) {$m_2$};
\end{minted}

The complete patterned wedge is one closed path. The anchors \key{top} and
\key{pulley-center} coincide at the projecting tip. \key{wall-root} marks the
start of the vertical side, while \key{transition-mid} and
\key{transition-0..100} sample the diagonal nose. Direct customisation uses
\key{wedge top inset} and \key{wedge top drop}; both default to zero, preserving
the triangular wedge. The inset must remain smaller than the wedge width and
the drop smaller than its resolved height. For a nonzero inset, the drop must
also place the wall root strictly below the incline.

The preset supports the default \key{right angle at=br} mode and mirrors for
\key{right angle at=bl}. It is unavailable in \key{right angle at=top}, which
has two sloping sides and no vertical supporting side.

\Needspace{8\baselineskip}
\begin{minted}{latex}
\node[wedge, pulley edge, show anchors, show keys,
  physics debug/anchor list={pulley-center,wall-root,transition-mid},
  physics debug/anchor families={transition},
  physics debug/anchor samples={0,50,100}] (W) {};
\end{minted}


\subsubsection*{Attach to the usable incline}
Prefer \key{surface-0..100} when positioning an object on the contact face.
Unlike the older CCW edge names, this family selects the actual incline in
all three modes and always runs left to right. In \key{top} mode it selects
the left face; \key{right-surface-0..100} selects the right face. In the other
two modes the right family refers to the same incline.
\Needspace{6\baselineskip}
\begin{minted}{latex}
\node[wedge,wedge right angle at=bl,wedge angle=30] (W) {};
\path (W.tangent-before-50) -- (W.tangent-after-50)
  node[midway,sloped,block,anchor=south] (B) {$m$};
\draw[force] (W.surface-25) -- (W.normal-25);
\end{minted}
The endpoint names are \key{surface-start} and \key{surface-end}.
The following guides are saved per node:
\begin{tabularx}{\linewidth}{@{}p{.48\linewidth}D@{}}
\toprule
Anchor or key & Meaning \\
\midrule
\key{tangent-before-T}, \key{tangent-after-T} & Two points straddling the contact point. \\
\key{normal-T} & A point outside the wedge, along its normal. \\
\key{surface guide length} & Tangent separation and normal length; initially 0.5cm. \\
\key{right-tangent-before-T}, \key{right-tangent-after-T} & Corresponding guides on the right face in top mode. \\
\key{right-normal-T} & Normal guide for that face. \\
\bottomrule
\end{tabularx}
Nonuniform scaling changes perpendicularity; use rigid transformations or
uniform scaling for physical normals.

\subsubsection*{Named geometry values}

Every named wedge snapshots its resolved scalar geometry. Query the value
owned by node \key{W} with

\begin{center}
  \key{\textbackslash geometryvalue\{W\}\{property\}}
\end{center}

The collision-safe command
\key{\textbackslash tikzphysicsgeometryvalue\{W\}\{property\}} has the same
result. The wedge must be named and its node command must finish before either
command is used. Because the result is a fixed literal, it can appear directly
inside \key{rotate=...}, a PGF calculation, or a label.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Property & Meaning \\
\midrule
left angle & Interior angle at \key{bl}, in degrees \\
right angle & Interior angle at \key{br}, in degrees \\
top angle & Interior angle at \key{top}, in degrees \\
base direction & Direction from \key{bl} to \key{br} \\
left edge direction & Rising direction from \key{bl} to \key{top} \\
right edge direction & Rising direction from \key{br} to \key{top} \\
slope angle, slope direction, surface angle & Placement rotation for the surface at \key{slope-mid} \\
right slope angle & Placement rotation for the surface at \key{slope-right-mid} \\
base angle, right edge angle & Aliases for \key{base direction} and \key{right edge direction} \\
width, height & Resolved TeX dimensions \\
top inset, top drop & Resolved pulley-edge dimensions \\
wall root angle & Interior angle at \key{wall-root}; 180 degrees when the
  transition is absent or collinear \\
right angle at & The text value \key{bl}, \key{br}, or \key{top} \\
\bottomrule
\end{tabularx}

\clearpage
Angles and directions are returned as numbers without a degree symbol.
Directions use degrees counter-clockwise from the wedge's local positive
$x$-axis. The placement rotations for all wedge modes are:

\begin{center}
\begin{tabular}{@{}lcccc@{}}
\toprule
\key{right angle at} & \key{left angle} & \key{right angle} & \key{top angle} & \key{slope angle} \\
\midrule
\key{br} & $\theta$ & $90$ & $90-\theta$ & $\theta$ \\
\key{bl} & $90$ & $\theta$ & $90-\theta$ & $-\theta$ \\
\key{top} & $\theta$ & $90-\theta$ & $90$ & $\theta$ \\
\bottomrule
\end{tabular}
\end{center}

Here \key{slope angle} follows the contact surface selected by
\key{slope-mid}; it is therefore the property normally wanted for a block.
In \key{top} mode this is the left face. Use \key{right slope angle}, equal to
$\theta-90$, with \key{slope-right-mid} for the right face.

\Needspace{10\baselineskip}
\begin{minted}{latex}
\node[wedge, minimum width=6cm, wedge angle=32] (W) at (0,0) {};

\node[block, minimum width=1cm, minimum height=0.8cm,
      rotate=\geometryvalue{W}{slope angle}, anchor=south]
  (B) at (W.slope-mid) {$m$};

\node at (W.bl)
  {$\pgfmathprintnumber{\geometryvalue{W}{left angle}}^\circ$};
\end{minted}

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[wedge, minimum width=6cm, wedge angle=32] (GW) at (0,0) {};
  \node[block, minimum width=1cm, minimum height=0.8cm,
        rotate=\geometryvalue{GW}{slope angle}, anchor=south]
    at (GW.slope-mid) {$m$};
  \node[below left=2pt] at (GW.bl)
    {$\pgfmathprintnumber{\geometryvalue{GW}{left angle}}^\circ$};
  \node[below right=2pt] at (GW.br)
    {$\pgfmathprintnumber{\geometryvalue{GW}{right angle}}^\circ$};
  \node[above right=2pt] at (GW.top)
    {$\pgfmathprintnumber{\geometryvalue{GW}{top angle}}^\circ$};
  \node[fill=white,inner sep=2pt] at (GW.centroid)
    {slope direction
     $=\pgfmathprintnumber{\geometryvalue{GW}{slope direction}}^\circ$};
\end{tikzpicture}
\end{center}

These direction values describe the untransformed wedge. They work directly
when the wedge and attached object share the same transformed scope. If the
wedge has its own independent rotation or a non-uniform scale, orient the
attached object from edge anchors with TikZ's \key{sloped} placement instead;
that follows the final rendered edge. The complete copy-ready source is
\path{examples/wedge-geometry-values.tex}.

\clearpage
\subsection{Ground, ceiling, and walls}

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[ground, ground width=3.3] (G) at (0,0) {};
  \node[below=3pt] at (G.bottom-50) {\sty{ground}};
  \node[ceiling, ceiling width=3.3] (C) at (4.7,0) {};
  \node[above=3pt] at (C.top-50) {\sty{ceiling}};
  \node[wall-left, wall height=1.7] (WL) at (8.2,0) {};
  \node[below=3pt] at (WL.bottom-50) {\sty{wall-left}};
  \node[wall-right, wall height=1.7] (WR) at (10.2,0) {};
  \node[below=3pt] at (WR.bottom-50) {\sty{wall-right}};
\end{tikzpicture}
\end{center}

The sizing keys are grouped by shape:

\begin{center}
\begin{tabular}{@{}ll@{}}
\sty{ground} & \key{ground width}, \key{ground depth} \\
\sty{ceiling} & \key{ceiling width}, \key{ceiling depth} \\
\sty{wall-left}, \sty{wall-right} & \key{wall thickness},
  \key{wall height}
\end{tabular}
\end{center}

Each shape exposes four corners, \key{center}, and \key{surface} at the usable
face's midpoint. \key{surface-0..100} covers that face: left to right on ground
and ceiling, bottom to top on either wall. The other three edges use their
physical names, \key{top}, \key{bottom}, \key{left}, or \key{right}, with the
same horizontal and vertical directions. Use \key{-50} for any edge midpoint.

\subsubsection*{Inspect all four with \key{show anchors}}

Select the contact family and the other three boundaries for each shape.
Numbers 0, 50, and 100 show each edge's start, midpoint, and end. Coincident
corners share a marker and appear together in the table.

\begin{center}
\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Shape & \key{physics debug/anchor families} \\
\midrule
\sty{ground} & \key{\{surface,bottom,left,right\}} \\
\sty{ceiling} & \key{\{surface,top,left,right\}} \\
\sty{wall-left} & \key{\{surface,top,bottom,left\}} \\
\sty{wall-right} & \key{\{surface,top,bottom,right\}} \\
\bottomrule
\end{tabularx}
\end{center}

\begin{minted}{latex}
\node[ground,ground width=7cm,show anchors,
  physics debug/anchor list={surface,top-left,top-right},
  physics debug/anchor families={surface,bottom,left,right},
  physics debug/anchor samples={0,50,100}] (G) {};
\end{minted}

The same \key{show anchors} overlay is rendered for ground, ceiling,
\sty{wall-left}, \sty{wall-right}, and every platform in
\path{docs/surface-anchor-coverage.pdf}. The full explanation and copy-ready
settings are in \path{docs/surface-anchors.md}.

\begin{center}
\begin{tikzpicture}
  \node[ground,ground width=5cm,ground depth=0.6cm,show anchors,
    physics debug/anchor list={surface},
    physics debug/anchor families={surface,bottom,left,right},
    physics debug/anchor samples={0,50,100}] (G) {};
\end{tikzpicture}
\end{center}

% -----------------------------------------------------------------------------
\clearpage
\section{Straight and curved ramps}

The \module{ramps} library provides two comparatively unusual mechanics
surfaces as genuine TikZ node shapes.  They are not collections of overlaid
lines: each ramp body is one closed path that receives the node's fill or
pattern, and each usable contact surface is drawn once as a continuous line.

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[ramp, minimum width=5.2cm, ramp run=1.8cm,
        ramp angle=32, ramp wall height=1.3cm] (SR) at (0,0) {};
  \node[below=5pt] at (SR.floor-mid) {\sty{ramp}};
  \fill[physicsblue] (SR.ramp-foot) circle (1.4pt);
  \physicsrampangle[angle radius=5mm]{SR}{$32^\circ$}

  \node[curved-ramp, curved ramp floor length=1.3cm,
        curved ramp radius=2.1cm,
        curved ramp angle=75, curved ramp back extension=0.6cm]
    (CR) at (7.2,0) {};
  \node[below=5pt] at (CR.base-end) {\sty{curved-ramp}};
  \fill[physicsblue] (CR.curve-55) circle (1.4pt);
  \draw[physicsblue,->] (CR.curve-55) -- (CR.curve-normal-55);
\end{tikzpicture}
\end{center}

The default direction is right: parameter 0 is the low end and parameter 100
is the high end.  Use \key{ramp direction=left}, or the convenience styles
\sty{ramp-left} and \sty{curved-ramp-left}, to mirror the body.  The parameter
direction still runs from low to high, so algorithms and annotations do not
need to reverse their anchor numbers.

\subsection{Straight ramp geometry}

The straight ramp combines a vertical wall, a horizontal floor, and a linear
incline.  The floor-to-incline meeting point is a mathematically sharp vertex;
no rounding, joint circle, or seam is inserted.  \key{minimum width} is the
horizontal distance from the wall contact line to the high end.  The
\key{ramp run} occupies the final part of that width, so the flat length is

\[
  L_{\mathrm{flat}}=\texttt{minimum width}-\texttt{ramp run}.
\]

When \key{ramp angle} is supplied it is authoritative and the rise is
$h=L_{\mathrm{run}}\tan\theta$.  Otherwise an explicit \key{ramp rise}
determines the angle.  With neither key, the default angle is $30^\circ$.
Use \key{\textbackslash physicsrampangle\{R\}\{label\}}
after the node to draw the dashed reference ray, acute angle arc, and label at
the exact \key{ramp-foot}.  The command also works for \sty{ramp-left}; its
optional argument accepts ordinary TikZ angle-pic options.

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.27\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.27\linewidth}D@{}}
\toprule
\normalfont Concise key & \normalfont Collision-safe alias & \normalfont Meaning and default \\
\midrule
minimum width & --- & Overall horizontal width; default \texttt{8.6cm}. \\
ramp run & physics ramp run & Horizontal run of the incline; default \texttt{2.6cm}. \\
ramp angle & physics ramp angle & Incline angle; default 30 degrees. \\
ramp rise & physics ramp rise & Explicit rise when no angle is supplied. \\
ramp wall height & physics ramp wall height & Contact-wall height; default \texttt{1.5cm}. \\
ramp wall width & physics ramp wall width & Material behind the wall; default \texttt{0.25cm}. \\
ramp depth & physics ramp depth & Material below the baseline; default \texttt{0.25cm}. \\
ramp direction & physics ramp direction & \key{right} (default) or \key{left}. \\
ramp guide length & physics ramp guide length & Length used by tangent/normal guide anchors; default \texttt{0.5cm}. \\
\bottomrule
\end{tabularx}

The following is a complete copy-paste document reproducing a wall, spring,
block, floor, and rising end as a single ramp node.

\Needspace{17\baselineskip}
\begin{minted}{latex}
\documentclass[tikz,border=6mm]{standalone}
\usepackage{tikzphysics}
\begin{document}
\begin{tikzpicture}[>=stealth]
  \node[ramp, minimum width=8.6cm, ramp run=2.6cm,
        ramp rise=1.5cm, ramp wall height=1.5cm] (R) at (0,0) {};

  \node[block, minimum width=1cm, minimum height=0.75cm,
        anchor=south] (B) at (R.floor-mid) {$m$};
  \coordinate (A) at (R.wall-mid |- B.west);
  \draw[spring] (A) -- node[above=3pt] {$k$} (B.west);
  \draw[->,thick] (B.east) -- ++(1.2,0) node[right] {$v$};
  \physicsrampangle{R}{$30^\circ$}
\end{tikzpicture}
\end{document}
\end{minted}

\subsection{Circular curved ramp geometry}

\sty{curved-ramp} begins with a horizontal floor extending left, then enters a
circular arc tangentially at $(0,0)$; it is not an arbitrary B\'ezier curve.
For radius $R$, sweep angle $\alpha$, and circular-arc parameter $t=T/100$,
the right-facing \key{curve-T} point is

\[
  x(T)=R\sin(t\alpha),\qquad
  y(T)=R\bigl(1-\cos(t\alpha)\bigr).
\]

Thus a 90-degree sweep ends at $(R,R)$ with a vertical tangent, exactly matching
the common quarter-circle ramp. The floor-to-curve transition has a common
horizontal tangent, so it contains no corner or visible joint. The body continues horizontally by
\key{curved ramp back extension}, then closes down to the baseline.  The
supported sweep range is greater than 0 and at most 90 degrees; this keeps the
filled body single-valued and prevents it folding back over itself.

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.31\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.31\linewidth}D@{}}
\toprule
\normalfont Concise key & \normalfont Collision-safe alias & \normalfont Meaning and default \\
\midrule
curved ramp floor length & physics curved ramp floor length & Horizontal floor before the arc; default \texttt{3.75cm}. \\
curved ramp radius & physics curved ramp radius & Circular radius; default \texttt{4cm}. \\
curved ramp angle & physics curved ramp angle & Sweep angle; default 90 degrees. \\
curved ramp back extension & physics curved ramp back extension & Horizontal body after the arc; default \texttt{1cm}. \\
ramp depth & physics ramp depth & Material below the low endpoint; default \texttt{0.25cm}. \\
ramp direction & physics ramp direction & \key{right} or \key{left}. \\
ramp guide length & physics ramp guide length & Tangent/normal guide length; default \texttt{0.5cm}. \\
\bottomrule
\end{tabularx}

\subsection{Surface, tangent, and normal anchors}

Both ramp shapes expose \key{surface-0} through \key{surface-100}.  The short
forms \key{.0} through \key{.100} name exactly the same points.  On the
straight ramp the parameter follows arc length over the floor and then the
incline; it deliberately excludes the vertical wall. On the curved ramp it
follows arc length over the new horizontal floor and then the circular arc.
Use \key{curve-0..100} when a fraction of the circular portion alone is needed.
The straight ramp also has \key{floor}, \key{incline}, \key{wall-surface},
\key{wall-back}, \key{wall-tip}, \key{base}, and \key{end} percentage families.
The curved ramp has \key{floor}, \key{start}, \key{base}, \key{back}, and
\key{top} families alongside \key{curve}. Together these cover every
drawn boundary. The complete visual map is in \path{docs/ramp-anchors.md}
and \path{docs/ramp-anchor-coverage.pdf}.

At every integer $T$, three orientation helpers are available:

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Anchor & Meaning \\
\midrule
tangent-before-T & Half a guide length before \key{surface-T} along the local tangent. \\
tangent-after-T & Half a guide length after \key{surface-T} along the local tangent. \\
normal-T & One guide length outward from \key{surface-T}, perpendicular to the surface. \\
curve-tangent-before-T & Half a guide length before \key{curve-T}. \\
curve-tangent-after-T & Half a guide length after \key{curve-T}. \\
curve-normal-T & Outward normal at \key{curve-T} only. \\
\bottomrule
\end{tabularx}

The tangent pair is symmetric about \key{surface-T}.  Consequently TikZ can
position and rotate a block without manually calculating its angle:

\Needspace{6\baselineskip}
\begin{minted}{latex}
\path (R.tangent-before-60) -- (R.tangent-after-60)
  node[midway,sloped,block,anchor=south] (B) {$m$};
\draw[->] (B.north) --
  ($(B.north)+(R.normal-60)-(R.surface-60)$) node[above left] {$N$};
\end{minted}

Named anchors provide the structural points:

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Shape & Named anchors \\
\midrule
Both & \key{center}, \key{surface-start}, \key{surface-mid},
  \key{surface-end}, \key{base-start}, \key{base-end}. \\
Straight ramp & \key{floor-start}, \key{floor-mid}, \key{floor-end},
  \key{ramp-foot}, \key{ramp-mid}, \key{ramp-top}, \key{wall-top},
  \key{wall-mid}, \key{wall-bottom}, \key{angle-baseline}, \key{angle-label}. \\
Curved ramp & \key{floor-start}, \key{floor-mid}, \key{floor-end},
  \key{curve-start}, \key{curve-mid}, \key{curve-end}, \key{curve-center},
  \key{back-top}, \key{back-bottom}. \\
\bottomrule
\end{tabularx}

Here is a complete curved-ramp document.  The dashed radius is perpendicular
to the tangent. The blue force arrow uses the exact outward-normal vector,
translated to begin at the block's north anchor so it does not cross the body.

\Needspace{20\baselineskip}
\begin{minted}{latex}
\documentclass[tikz,border=6mm]{standalone}
\usepackage{tikzphysics}
\begin{document}
\begin{tikzpicture}[>=stealth]
  \node[curved-ramp, curved ramp radius=4cm,
        curved ramp angle=90,
        curved ramp back extension=1cm] (R) at (0,0) {};

  \path (R.curve-tangent-before-60) -- (R.curve-tangent-after-60)
    node[midway,sloped,block,minimum width=1cm,
         minimum height=0.75cm,anchor=south] (B) {$m$};
  \draw[->,blue,thick] (B.north) --
    ($(B.north)+(R.curve-normal-60)-(R.curve-60)$)
    node[above left] {$N$};
  \draw[dashed] (R.curve-center) -- (R.curve-60)
    node[midway,left] {$r$};
\end{tikzpicture}
\end{document}
\end{minted}

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[curved-ramp, curved ramp floor length=1.7cm,
        curved ramp radius=3.2cm,
        curved ramp angle=90, curved ramp back extension=0.8cm] (R) {};
  \path (R.curve-tangent-before-60) -- (R.curve-tangent-after-60)
    node[midway,sloped,block,minimum width=0.8cm,
         minimum height=0.6cm,anchor=south] (B) {$m$};
  \draw[physicsblue,->,thick] (B.north) --
    ($(B.north)+(R.curve-normal-60)-(R.curve-60)$)
    node[above left] {$N$};
  \draw[physicsgray,dashed] (R.curve-center) -- (R.curve-60);
  \fill[physicsteal] (R.floor-mid) circle (1.2pt)
    node[below=6pt,fill=white,inner sep=1pt] {\key{floor-mid}};
  \fill[physicsteal] (R.curve-20) circle (1.2pt)
    node[above left=3pt,fill=white,inner sep=1pt] {\key{curve-20}};
  \fill[physicsteal] (R.curve-80) circle (1.2pt)
    node[above left=3pt,fill=white,inner sep=1pt] {\key{curve-80}};
\end{tikzpicture}
\end{center}

\subsection{Styling and debug use}

The body follows ordinary TikZ styling.  Place the shape style first, then
override \key{pattern}, \key{pattern color}, \key{fill}, or \key{draw} in the
usual option order.  The contact line is always emitted once by the shape.
For example, \key{curved-ramp, pattern=grid, pattern color=gray} changes the
material rendering without changing anchors.

Debug overlays are especially useful for unfamiliar ramp geometry:

\Needspace{7\baselineskip}
\begin{minted}{latex}
\node[curved-ramp, curved ramp floor length=1.5cm,
      curved ramp radius=2.5cm,
      curved ramp angle=70,
      physics debug/anchors=true,
      physics debug/keys=true] (R) {};
\end{minted}

The key panel presents \key{minimum width} before package-specific sizing on
the straight ramp.  Anchor overlays show a compact representative set rather
than all 101 samples.  Use explicit \key{surface-T}, tangent, and normal
anchors when inspecting a particular value.

% -----------------------------------------------------------------------------
\clearpage
\section{Blocks, springs, and pulleys}

The \module{mechanics} library supplies block and pulley nodes, a spring path
style, and tangent pulley strings. They accept ordinary TikZ styling such as
\key{draw}, \key{line width}, and \key{scale}.


\subsection{Complete spring--block--pulley system}\label{sec:complete-system}
This example combines reusable defaults, a surface tangent, and the native
\key{to[over pulley=P]} connection. Copy the complete document below.
\Needspace{25\baselineskip}
\begin{minted}{latex}
\documentclass[tikz,border=6mm]{standalone}
\usepackage{tikzphysics}
\tikzset{
  every block/.style={minimum width=1cm,minimum height=1cm,fill=white},
  every pulley/.style={minimum size=1cm,fill=white},
  every spring/.style={pre length=3mm,post length=3mm,
    amplitude=2mm,segment length=2mm}
}
\begin{document}
\begin{tikzpicture}
  \node[wedge,minimum width=6cm,wedge angle=30] (W) {};
  % The contact anchors select the actual incline in every wedge mode.
  \path (W.tangent-before-50) -- (W.tangent-after-50)
    node[midway,sloped,block,anchor=south] (B) {$m_1$};
  \edef\InclineAngle{\geometryvalue{W}{slope angle}}
  \draw[thick] (W.surface-start) -- ++({\InclineAngle+90}:10mm);
  \coordinate (S) at ($(W.surface-start)+({\InclineAngle+90}:5mm)$);
  \draw[spring] (S) -- node[above=3mm,sloped] {$k$} (B.west);
  \node[pulley] (P) at (W.top) {};
  \node[block,minimum width=8mm,anchor=north] (H) at ($(P.east)+(0,-4cm)$) {$m_2$};
  \draw[rope] (B.east) to[over pulley=P] (H.north);
\end{tikzpicture}
\end{document}

\end{minted}
\begin{center}\begingroup
\tikzset{
  every block/.style={minimum width=1cm,minimum height=1cm,fill=white},
  every pulley/.style={minimum size=1cm,fill=white},
  every spring/.style={pre length=3mm,post length=3mm,
    amplitude=2mm,segment length=2mm}
}
\begin{tikzpicture}
  \node[wedge,minimum width=6cm,wedge angle=30] (W) {};
  % The contact anchors select the actual incline in every wedge mode.
  \path (W.tangent-before-50) -- (W.tangent-after-50)
    node[midway,sloped,block,anchor=south] (B) {$m_1$};
  \edef\InclineAngle{\geometryvalue{W}{slope angle}}
  \draw[thick] (W.surface-start) -- ++({\InclineAngle+90}:10mm);
  \coordinate (S) at ($(W.surface-start)+({\InclineAngle+90}:5mm)$);
  \draw[spring] (S) -- node[above=3mm,sloped] {$k$} (B.west);
  \node[pulley] (P) at (W.top) {};
  \node[block,minimum width=8mm,anchor=north] (H) at ($(P.east)+(0,-4cm)$) {$m_2$};
  \draw[rope] (B.east) to[over pulley=P] (H.north);
\end{tikzpicture}

\endgroup\end{center}
The 10\,mm block height matches the 10\,mm pulley diameter.
The hanging block has a local 8\,mm width for readability; the package default
remains a 1\,cm square. With the pulley
centred at the top vertex, the incoming rope is parallel to the incline.
The support's attachment is half the block height above the surface, so the
spring is parallel too. Changing one of these dimensions independently
requires adjusting the placement. This example is specifically the rising
\key{br} wedge arrangement; contact anchors support the other modes, but a
complete pulley layout must still be chosen for the intended route.

\subsection{Native rope connections}
\Needspace{5\baselineskip}
\begin{minted}{latex}
\draw[rope] (A) to[over pulley=P] (B);
\draw[rope,string route=under,red]
  (A) to[over pulley=P] node[right] {$T$} (B);
\end{minted}
Both endpoints must lie outside the pulley. Use a circular pulley, without
nonuniform scaling. The \key{to} segment computes both tangencies and the
contact arc; its labels belong to the final straight segment. Place labels
on another segment explicitly when that is what your diagram requires.
The compatibility command uses the same route:
\Needspace{3\baselineskip}
\begin{minted}{latex}
\physicsstringoverpulley[string route=under]{A}{P}{B}
\end{minted}
Both forms now respect scoped route settings. \key{shortest} selects the
shorter arc for the current tangent pair, not the globally shortest path
over every possible tangent combination. The safe path names are
\sty{physics string} and \key{physics over pulley}.

\subsection{Spring nodes and paths}

\sty{spring} is a drawing style used directly between two coordinates. The
path endpoints determine its complete length and direction, so horizontal,
vertical, and inclined springs all use the same syntax. Zero-length leads are supported. Straight leads of
\key{pre length} and \key{post length} surround the coil; the remaining keys
map directly to TikZ's standard \key{coil} decoration parameters. Use
explicit units for typographic sizes such as \texttt{5pt}; bare convenience-key
values are interpreted as centimetres.

\begin{center}
\begin{tikzpicture}
  \coordinate (A) at (-2.5,0);
  \coordinate (B) at ( 2.5,0);
  \draw[spring, pre length=7mm, post length=4mm,
        amplitude=5pt, segment length=7pt]
    (A) -- node[above=4pt] {$k$} (B);
  \fill (A) circle[radius=1.2pt] (B) circle[radius=1.2pt];
  \node[below=4pt] at (A) {\key{A}};
  \node[below=4pt] at (B) {\key{B}};
\end{tikzpicture}
\end{center}

For a spring path, use its endpoints and ordinary TikZ nodes placed along
it. Alternatively, use the same style in a positioned node:

\begin{minted}{latex}
\node[spring,minimum width=3cm,rotate=30] (S) {};
\draw (A) -- (S.start);
\draw (S.end) -- (B.west);
\end{minted}

The node defaults to a length of 3 cm. Set \key{minimum width} or
\key{spring length} to change it; \key{rotate} sets its direction.
Both APIs use the same coil decoration and \key{every spring} hook.
Node anchors \key{start} and \key{end} lie exactly at the axis attachments;
\key{coil-start} and \key{coil-end} delimit the straight leads.
\key{axis-0..100} samples the straight axis from start to end, not the coil
wire. Compass anchors bound the coil; \key{minimum height} can reserve more
space but does not change its amplitude. Lead lengths must sum to less than
the node length. Put labels above or below the node to keep them off the coil.

\begin{minted}{latex}
\node[spring,show anchors,show keys,
  physics debug/anchor families={axis},
  physics debug/anchor samples={0,50,100}] (S) {};
\end{minted}

For a wall--spring--block system, a path can connect directly from a chosen
wall coordinate to the block anchor:

\Needspace{18\baselineskip}
\begin{minted}{latex}
\documentclass[tikz,border=5mm]{standalone}
\usepackage{tikzphysics}
\begin{document}
\begin{tikzpicture}[>=stealth]
  \node[platform-left, minimum width=6cm, minimum height=2cm,
        anchor=surface] (P) at (0,0) {};
  \node[block, minimum width=1cm, minimum height=0.8cm,
        anchor=south] (B) at (P.surface-75) {$m$};
  \coordinate (A) at ($(B.west)+(-4cm,0)$);
  \draw[spring,
        pre length=5pt, post length=5pt,
        amplitude=4.5pt, segment length=4.5pt]
    (A) -- node[above=3pt] {$k$} (B.west);
  \draw[->,thick] (B.east) -- ++(1.1,0) node[right] {$v$};
\end{tikzpicture}
\end{document}
\end{minted}

\subsection{Blocks, pulleys, and tangent strings}

\begin{center}
\begin{tikzpicture}[scale=0.78, every node/.append style={transform shape}]
  \node[wedge, wedge width=5.2, wedge angle=30] (W) at (0,0) {};
  \node[block, minimum width=0.8cm, minimum height=1cm,
        rotate=30, anchor=south] (B) at (W.slope-mid) {$m$};
  \node[pulley] (P) at (W.top) {};
  \node[block, minimum width=8mm, minimum height=1cm]
    (H) at ($(P.east)+(0,-2.1)$) {$M$};
  \physicsstringoverpulley{B.east}{P}{H.north}
\end{tikzpicture}
\end{center}

The pulley centre is exactly \key{W.top}. Its default diameter is
\texttt{1cm}; matching the surface block's height to that diameter places
\key{B.east} one radius above the slope, so the approaching tangent remains
exactly parallel to the incline.

\key{\textbackslash physicsstringoverpulley\{start\}\{pulley\}\{end\}}
draws a single physical string. Both straight portions meet the circular
pulley tangentially, and the intervening portion follows the pulley arc. The
default \key{surface-right} route matches the layout shown above: the pulley
is just beyond the incline's right end, the first string portion is parallel
to the slope, the contact arc passes over the upper rim, and the second
portion descends vertically on the right.

\subsection{String-routing variants}

The endpoint coordinates may be placed at any unequal positions outside the
pulley. The named routes below include two common left-to-right wraps and the
default surface-to-right-hanging turn. \key{shortest} keeps the selected
tangent pair and chooses the shorter contact arc. For other endpoint
orderings, select tangent solutions and wrap direction explicitly.

\begin{center}
\begin{tikzpicture}[font=\scriptsize]
  \begin{scope}
    \coordinate (RA) at (-1.5,-0.7);
    \coordinate (RB) at ( 1.5,-0.7);
    \node[pulley,minimum size=0.7cm] (RP) at (0,0) {};
    \physicsstringoverpulley[string route=over]{RA}{RP}{RB}
    \node at (0,-1.25) {\key{over}};
  \end{scope}
  \begin{scope}[xshift=4.1cm]
    \coordinate (RA) at (-1.5,0.7);
    \coordinate (RB) at ( 1.5,0.7);
    \node[pulley,minimum size=0.7cm] (RP) at (0,0) {};
    \physicsstringoverpulley[string route=under]{RA}{RP}{RB}
    \node at (0,-1.25) {\key{under}};
  \end{scope}
  \begin{scope}[xshift=8.2cm]
    \coordinate (RA) at (-1.5,-0.45);
    \coordinate (RB) at (0.35,-1.45);
    \node[pulley,minimum size=0.7cm] (RP) at (0,0) {};
    \physicsstringoverpulley{RA}{RP}{RB}
    \node at (0,-1.9) {\key{surface-right}};
  \end{scope}
  \begin{scope}[xshift=12.3cm]
    \coordinate (RA) at (-1.5,0.25);
    \coordinate (RB) at ( 1.25,-1.1);
    \node[pulley,minimum size=0.7cm] (RP) at (0,0) {};
    \physicsstringoverpulley[string route=shortest]{RA}{RP}{RB}
    \node at (0,-1.55) {unequal endpoints};
  \end{scope}
\end{tikzpicture}
\end{center}

\begin{tabularx}{\linewidth}{@{}>{\ttfamily\raggedright\arraybackslash}p{0.28\linewidth}
  >{\ttfamily\raggedright\arraybackslash}p{0.34\linewidth}D@{}}
\toprule
\normalfont Concise key & \normalfont Collision-safe alias & \normalfont Meaning and default \\
\midrule
block width & physics block width & Convenience alias for \key{minimum width}; default
  \texttt{1cm}. \\
block height & physics block height & Convenience alias for \key{minimum height}; default
  \texttt{1cm}. \\
pre length / post length & physics spring pre length / physics spring post length & Straight attachment leads; each defaults
  to \texttt{5pt}. \\
amplitude & physics spring amplitude & Coil half-height; default \texttt{4.5pt}. \\
segment length & physics spring segment length & Axial length of one repeated coil segment; default
  \texttt{4.5pt}. \\
aspect & physics spring aspect & Coil projection factor; default \texttt{0.5}. \\
pulley diameter & physics pulley diameter & Convenience alias for \key{minimum size}; default
  \texttt{1cm}. \\
pulley axle radius & physics pulley axle radius & Axle-dot radius; default \texttt{1.5pt}. Use
  \key{none} to hide the dot. \\
pulley axle color & physics pulley axle color & Axle-dot colour; default \texttt{black}. \\
string start solution & physics string start solution & Start-side tangent, \texttt{1} or \texttt{2};
  default \texttt{2}. \\
string end solution & physics string end solution & End-side tangent, \texttt{1} or \texttt{2};
  default \texttt{1}. \\
string route & physics string route & \texttt{surface-right} (default), \texttt{over},
  \texttt{under}, or \texttt{shortest}. \\
string wrap & physics string wrap & \texttt{clockwise} (default), \texttt{counterclockwise},
  or \texttt{shortest}. \\
\bottomrule
\end{tabularx}

\clearpage
\subsection{Complete pulley systems}

The mechanics shapes compose directly with every surface family. In each
diagram below, one call to \key{\textbackslash physicsstringoverpulley} draws both
straight tangent portions and the circular contact arc; no pulley compass
anchor is used as a substitute for the contact point. All four diagrams omit
a pulley sizing key and therefore use the documented default
\key{minimum size=1cm}. The inclined and bent systems place the pulley centre
directly at the endpoint anchors \key{W.top} and \key{S.wall-surface-100}.
Their \key{block height=1cm} makes \key{B.east} exactly one pulley radius from
the supporting surface, so the incoming tangent is surface-parallel.

\noindent
\begin{minipage}[t]{0.48\linewidth}
\centering
\begin{tikzpicture}
  \node[ground, ground width=5.6, ground depth=0.35] (G) at (0,0) {};
  \node[block, block width=0.9, block height=1,
        anchor=south] (B) at (G.surface-70) {$m_1$};
  \coordinate (mount) at ($(G.top-right)+(0.5,0)$);
  \draw (G.top-right) -- (mount);
  \node[pulley] (P) at (mount) {};
  \node[block, minimum width=8mm, minimum height=1cm]
    (H) at ($(P.east)+(0,-2.1)$) {$m_2$};
  \physicsstringoverpulley{B.east}{P}{H.north}
\end{tikzpicture}

\smallskip\textbf{Horizontal plane}
\end{minipage}\hfill
\begin{minipage}[t]{0.48\linewidth}
\centering
\begin{tikzpicture}
  \node[wedge, wedge width=5, wedge angle=30] (W) at (0,0) {};
  \node[block, block width=0.9, block height=1,
        rotate=30, anchor=south] (B) at (W.slope-mid) {$m_1$};
  \node[pulley] (P) at (W.pulley-center) {};
  \node[block]
    (H) at ($(P.east)+(0,-2.1)$) {$m_2$};
  \physicsstringoverpulley{B.east}{P}{H.north}
\end{tikzpicture}

\smallskip\textbf{Inclined plane}
\end{minipage}

\vspace{1.2em}
\noindent
\begin{minipage}[t]{0.48\linewidth}
\centering
\begin{tikzpicture}
  \node[platform-right, platform width=4.6, platform depth=1.9,
        strip width=0.28, wall angle=42,
        anchor=surface] (S) at (0,0) {};
  \node[block, block width=0.85, block height=1,
        rotate=42, anchor=south]
    (B) at (S.wall-surface-42) {$m_1$};
  \node[pulley] (P) at (S.wall-surface-100) {};
  \node[block, minimum width=8mm, minimum height=1cm]
    (H) at ($(P.east)+(0,-2.1)$) {$m_2$};
  \physicsstringoverpulley{B.east}{P}{H.north}
\end{tikzpicture}

\smallskip\textbf{Continuous bent platform}
\end{minipage}\hfill
\begin{minipage}[t]{0.48\linewidth}
\centering
\begin{tikzpicture}
  \node[ceiling, ceiling width=3.2, ceiling depth=0.3]
    (C) at (0,0) {};
  \draw (C.surface) -- ++(0,-0.5) coordinate (mount);
  \node[pulley] (P) at (mount) {};
  \node[block, minimum width=8mm, minimum height=1cm]
    (L) at ($(P.west)+(0,-2.1)$) {$m_1$};
  \node[block, minimum width=8mm, minimum height=1cm]
    (R) at ($(P.east)+(0,-2.7)$) {$m_2$};
  \physicsstringoverpulley[string route=over]{L.north}{P}{R.north}
\end{tikzpicture}

\smallskip\textbf{Two hanging masses}
\end{minipage}

\medskip
Copy-ready standalone sources are included in the \key{examples} directory:

\begin{itemize}
  \item \path{mechanics-pulley-flat-plane.tex} and
    \path{mechanics-block-pulley.tex};
  \item \path{mechanics-pulley-bent-platform.tex} and
    \path{mechanics-pulley-two-masses.tex};
  \item \path{mechanics-spring-block.tex}, a complete wall--spring--block system;
  \item \path{mechanics-pulley-string-variants.tex}, a gallery of six endpoint
    and wrapping arrangements.
\end{itemize}

\clearpage
% -----------------------------------------------------------------------------

\subsection{Bodies, forces and named assemblies}\label{sec:primitives}
\begin{tabularx}{\linewidth}{@{}p{.30\linewidth}D@{}}
\toprule
Feature & Use and defaults \\
\midrule
\sty{particle} & Filled circular node, diameter 3\,mm. \\
\sty{disk}, \sty{ring} & Circular nodes, diameter 15\,mm. Disk has a white fill;
ring is unfilled with a thicker outline. \\
\sty{force}, \sty{velocity}, \sty{acceleration} & Arrow path styles; you choose
origin, direction, length, and labels. \\
\sty{torque} & Arrow style for an arc you specify. \\
\sty{rod} & Straight or curved path with a 2\,pt stroke and round caps. \\
\sty{pin-support}, \sty{roller-support} & Named pics, controlled by
\key{support size} (6\,mm). The pic origin is the pivot. \\
\sty{pendulum} & Named pic with a particle bob. Length defaults to 2\,cm,
angle to 30 degrees from downward vertical, positive towards the right. \\
\bottomrule
\end{tabularx}
Circular bodies have ordinary compass and angular anchors. Use
\key{D.center} for an axle and \key{D.south} for bottom contact in an
unrotated disk. These are two-dimensional diagram symbols, not automatic
mass-distribution or rigid-body solvers.

\Needspace{8\baselineskip}
\begin{minted}{latex}
\pic (A) {pin-support};
\pic (B) at (4,0) {roller-support};
\draw[rod] (A-pivot) -- (B-pivot);
\draw[force] (2,1) -- (2,0) node[pos=0,left] {$F$};
\pic[pendulum length=2cm,pendulum angle=25] (P) at (6,1) {pendulum};
\draw[force] (P-bob.south) -- ++(0,-1) node[below] {$mg$};
\end{minted}
Support coordinates are \key{A-pivot}, \key{A-base}, \key{A-left}, and
\key{A-right}; \key{base} is the ground line's midpoint, while left/right
are the triangle's bottom corners. A pendulum exposes \key{P-pivot} and a
real bob node \key{P-bob}. Its specified length is pivot to bob centre;
the rope stops at the bob's border. Rotate or shift a pic using normal TikZ
options. Pic coordinates use a hyphen after the pic name, unlike a node's
\key{B.west} anchor syntax.

\key{every support} and \key{every pendulum} are applied when the pic type
is expanded. As with TikZ pics generally, type styles are processed after
options preceding the type; avoid conflicting geometric values in these
hooks and the pic options. Use the hooks for shared appearance or set
\key{support size} and \key{pendulum length} in the surrounding scope.
The collision-safe pic types are \sty{physics pin-support},
\sty{physics roller-support}, and \sty{physics pendulum}.
See \texttt{examples/mechanics-primitives.tex} for a complete gallery.
\begin{center}
\resizebox{\linewidth}{!}{%
\begin{tikzpicture}[font=\small]
  % A simply supported beam with an applied load.
  \pic (A) at (0,0) {pin-support};
  \pic (B) at (4,0) {roller-support};
  \draw[rod] (A-pivot) -- (B-pivot);
  \draw[force] (2,1) -- (2,0) node[pos=0,left] {$F$};
  \node[below] at (2,-1) {Supports and a rod};
  % A rolling body with independently styled vectors.
  \node[ground,minimum width=3cm] (G) at (7,-.75) {};
  \node[disk,anchor=south] (D) at (G.surface) {$M$};
  \draw[velocity] (D.north) -- ++(1,0) node[right] {$v$};
  \draw[torque] ($(D.center)+(130:1cm)$)
    arc[start angle=130,end angle=30,radius=1cm]
    node[right] {$\tau$};
  \node[below] at (7,-1.2) {Disk, velocity and torque};
  % Pic names prefix their coordinates; bob is a real node.
  \pic[pendulum length=2cm,pendulum angle=25] (P) at (11,1) {pendulum};
  \draw[dashed] (P-pivot) -- ++(0,-2.2);
  \draw[force] (P-bob.south) -- ++(0,-.8) node[below] {$mg$};
  \node[above] at (P-pivot) {Pendulum};
\end{tikzpicture}
}
\end{center}

\clearpage
% -----------------------------------------------------------------------------
\section{Circular differential elements}\label{sec:elements}

Element labels inherit the surrounding document or native TikZ \key{font},
including per-node font overrides. Dimensions use font-relative arrow tips
and spacing; \key{every element label} and \key{every element dimension}
remain user-overridable. \texttt{examples/elements-fonts.tex} illustrates this.

The \module{elements} library turns the shaded regions used in polar-coordinate
integration and moment-of-inertia derivations into reusable TikZ nodes. The
general \sty{polar element} is an annular sector. Its zero-radius and full-ring
limits are available as named presets.

\begin{center}
\resizebox{\linewidth}{!}{%
\begin{tikzpicture}[font=\small]
  \node[polar element,
    element inner radius=16mm,element radial thickness=3mm,
    element start angle=20,element delta angle=38,
    show dimensions] (PE) at (0,0) {};
  \node[below=7mm] at (PE.south) {\sty{polar element}};
  \node[differential sector,element outer radius=19mm,
    element start angle=20,element delta angle=38,
    show dimensions] (SE) at (6,0) {};
  \node[below=7mm] at (SE.south) {\sty{differential sector}};
  \node[differential ring,element inner radius=16mm,
    element radial thickness=3mm,show dimensions] (RE) at (11.5,0) {};
  \node[below=7mm] at (RE.south) {\sty{differential ring}};
\end{tikzpicture}%
}
\end{center}

\subsection{General polar element}

Use explicit inner and outer radii, or give an inner radius and radial
thickness. The later of \key{element outer radius} and
\key{element radial thickness} controls the outer boundary.

\Needspace{10\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}
  \node[polar element,
    element inner radius=18mm,
    element radial thickness=2mm,
    element start angle=30,
    element delta angle=30,
    show dimensions] (dA) at (0,0) {};
\end{tikzpicture}
\end{minted}

The inner radius may be zero. The outer radius must be larger than the inner
radius. The angular extent must lie in the interval $(0,360]$ degrees.
Bare radial values are centimetres; explicit TeX dimensions retain their unit.

\subsection{Sector, ring, and unwrapped strip}

\sty{differential sector} fixes the inner radius at zero.
\sty{differential ring} fixes the angular extent at 360 degrees and produces a
closed annulus without a radial seam. The differential strip uses the inner
reference radius, so its width is $2\pi r$ and its height is $d\!r$.

\begin{minted}{latex}
\node[differential ring,
  element inner radius=18mm,
  element radial thickness=2mm] (R) {};
\node[unwrapped ring,source element=R,
  show dimensions] (U) at (0,-4) {};
\end{minted}

The named pic keeps the original circular body, annular element, centre mark,
and opened strip in one construction. It exposes both component nodes:

\begin{minted}{latex}
\pic (D) {differential ring diagram={
  element inner radius=1cm,
  element radial thickness=2mm
}};
% Refer to (D-ring), (D-strip), and (D-body-east), etc.
\end{minted}

\begin{center}
\begin{tikzpicture}[scale=.9,every node/.append style={transform shape}]
  \pic (D) {differential ring diagram={
    element inner radius=1cm,element radial thickness=2mm}};
\end{tikzpicture}
\end{center}

The body radius defaults to 2 cm, the centre-dot radius to 1.2 pt, and the gap
above the strip to 5 mm. Set them with \key{element body radius},
\key{element center dot radius}, and \key{element diagram gap}. The body
coordinates are \key{D-center}, \key{D-body-north}, \key{D-body-south},
\key{D-body-east}, and \key{D-body-west}.

\clearpage
\subsection{Solid, shell, slice, and sheet constructions}

The integration method is part of each public name. A solid sphere can use a
concentric shell or a circular disk; a cylinder can use a radial shell or an
axial disk. Each construction is a named pic containing separately named body
and element components.

\begin{center}
\resizebox{\linewidth}{!}{%
\begin{tikzpicture}[font=\small]
  \pic (SS) at (0,0) {sphere shell diagram};
  \node[above=5mm] at (SS-body.north) {sphere shell};
  \pic (SX) at (5.6,0) {sphere slice diagram};
  \node[above=5mm] at (SX-body.north) {sphere slice};
  \pic (CS) at (10.8,0) {cylinder shell diagram};
  \node[above=6mm] at (CS-body.north) {cylinder shell};
  \pic (KX) at (15.5,0) {cone slice diagram};
  \node[above=6mm] at (KX-body.north) {cone slice};
\end{tikzpicture}%
}
\end{center}

\begin{tabularx}{\linewidth}{@{}lXl@{}}
\toprule
Construction & Public pic & Default expression \\
\midrule
Solid sphere, shells & \sty{sphere shell diagram} & $dV=4\pi r^2\,d\!r$ \\
Solid sphere, disks & \sty{sphere slice diagram} & $dV=\pi y^2\,d\!x$ \\
Finite hollow sphere & \sty{hollow sphere diagram} & $V=\frac{4\pi}{3}(R^3-a^3)$ \\
Cylinder, shells & \sty{cylinder shell diagram} & $dV=2\pi rh\,d\!r$ \\
Cylinder, disks & \sty{cylinder slice diagram} & $dV=\pi R^2\,d\!z$ \\
Cone, disks & \sty{cone slice diagram} & $dV=\pi r(x)^2\,d\!x$ \\
Cartesian sheet & \sty{sheet element diagram} & $dA=d\!x\,d\!y$ \\
\bottomrule
\end{tabularx}

\Needspace{13\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}
  \pic (S) {sphere shell diagram={
    element body radius=2cm,
    element inner radius=1cm,
    element radial thickness=1.5mm
  }};
  \pic (C) at (6,0) {cylinder slice diagram={
    element body radius=1.6cm,
    element body height=3.4cm,
    element position=.55,
    element axial thickness=2mm
  }};
\end{tikzpicture}
\end{minted}

On \sty{sphere slice diagram}, \key{element position} is the signed axial
coordinate divided by the sphere radius and lies strictly between $-1$ and
$1$. On cylinder diagrams the same key runs from bottom to top in $[0,1]$.
On \sty{cone slice diagram} it runs from apex to base in $(0,1)$.
\key{element projection ratio} controls the apparent depth of the projected
circles without changing their physical radii.

For a pic named \texttt{S}, use \key{S-body} and \key{S-shell} or
\key{S-slice}. Every pic also provides \key{S-center} and
\key{S-formula-anchor}; cone pics add \key{S-apex} and \key{S-base}. The
sheet construction uses \key{S-body} and \key{S-element}. Override the
displayed expression with \key{element formula label}.

\subsubsection{Coordinates on projected rims}
Every integer from 0 to 100 is available. Sphere slices expose
\key{S-disk-rim-T}; cylinder shells expose \key{S-body-rim-T},
\key{S-shell-outer-rim-T} and \key{S-shell-inner-rim-T}.
Cylinder and cone slices expose \key{S-body-rim-T},
\key{S-slice-top-rim-T} and \key{S-slice-bottom-rim-T}.
Rims run counterclockwise from the rightmost ellipse point. Cylinder body
rims are upper circles; cone body rims are base circles. Cylinder and cone
pics also provide \key{S-height-T}, bottom to top along the physical axis.
The shell height marker excludes projected ellipse depth.

\begin{minted}{latex}
\fill (C-slice-top-rim-37) circle (1.5pt);
\draw[->] (C-height-0)--(C-height-100);
\end{minted}

These are pic coordinates. Child-node anchors use a dot, such as
\key{C-slice.center}. The slice placement box differs from the projected
rim. See \texttt{docs/elements.md} for the complete map and the differential
approximation limits, and \texttt{examples/elements-percentage-anchors.tex}
for transformed rim and centroid examples.

The reusable nodes are \sty{spherical shell}, \sty{hollow sphere},
\sty{rectangular element}, \sty{rectangular strip}, and
\sty{rectangular sheet}:

\begin{minted}{latex}
\node[spherical shell,show dimensions] (S) {};
\node[hollow sphere,element inner radius=8mm,
      element outer radius=2cm] (H) at (5,0) {};
\node[rectangular element,element width=8mm,
      element height=6mm,show dimensions] (dA) at (10,0) {};
\end{minted}

The spherical nodes expose the polar boundary anchors and numeric families.
Rectangular nodes expose their four corners and the families
\key{bottom-0..100}, \key{right-0..100}, \key{top-0..100}, and
\key{left-0..100}. Named rectangles record resolved \key{width} and
\key{height}. Use \key{show anchors}, \key{show keys}, or a card such as
\key{\textbackslash physicshelp\{cylinder slice diagram\}} inside the picture.
The labels use plain LaTeX $d\!x$, $d\!y$, and $d\!r$.

Dimension labels inherit the surrounding or per-node font. Dimension arrows
use native \key{>=latex}; physical strokes inherit the document line width.

Use \key{pattern=dots} for dots or \key{pattern=north east lines} for hatching.

Combine \key{pattern=horizontal lines} with \key{dashed} for dashed hatching.

A solid fill uses \key{pattern=none} and \key{fill=gray!20}.
For highlighted slice and shell pics, append these options to
\key{every solid element} with \key{/.append style}.

Projected circular bodies draw rear curves through
\sty{every solid hidden edge}. Visible front curves use the ordinary body
or dimension style. The font and pattern gallery is
\texttt{examples/elements-fonts.tex}.

\subsection{Labels, anchors, and resolved values}

\key{show dimensions} uses plain LaTeX labels: $r$, $d\!r$,
$d\!\theta$, $r\,d\!\theta$, and $2\pi r$. Set the radial labels with
\key{element radius label} and \key{element radial label}. Set the angular,
arc, and strip labels with \key{element angular label},
\key{element arc label}, and \key{element circumference label}.
Shared appearance hooks are \key{every element dimension} and
\key{every element label}; the combined pic also provides
\key{every element body}, \key{every element center}, and
\key{every differential ring diagram}.

The principal anchors are \key{inner-start}, \key{inner-mid},
\key{inner-end}, \key{outer-start}, \key{outer-mid}, \key{outer-end},
\key{start-mid}, \key{end-mid}, \key{center}, and the true area
\key{centroid}. Four numeric families---\key{inner-0..100},
\key{outer-0..100}, \key{start-0..100}, and \key{end-0..100}---sample every
boundary. A complete ring's \key{centroid} coincides with its centre.

Named polar elements record \key{inner radius}, \key{outer radius},
\key{radial thickness}, \key{mean radius}, \key{start angle},
\key{delta angle}, and \key{end angle}. An unwrapped ring also records
\key{circumference}. Query them with \key{\textbackslash geometryvalue}:

\begin{minted}{latex}
\node at (R.center)
  {$r=\geometryvalue{R}{mean radius}$};
\end{minted}

Use \key{show anchors}, \key{show keys}, or
\key{\textbackslash physicshelp\{polar element\}} to inspect the API inside the
picture. See \texttt{examples/elements-circular-differentials.tex} for the
complete standalone gallery.

\section{Fluid mechanics}\label{sec:fluids}
The separate \module{fluids} library provides eight native nodes and fourteen editable teaching
assemblies. These are geometric schematics: levels, curvature, and dimensions
are inputs, not computed fluid equilibria. Load the complete package with
\verb|\usepackage{tikzphysics}|. To load only this module:
\begin{minted}{latex}
\usepackage{tikz}
\usetikzlibrary{tikzphysics.fluids}
\end{minted}

\begin{minted}{latex}
\begin{tikzpicture}[font=\small]
  \node[fluid tank,
    fluid={width=4cm,height=3cm,left level=.85,right level=.55},
    pattern=north east lines,pattern color=gray,line width=.7pt
  ] (T) {};
  \draw[->] (T.right-surface) -- ++(1,0) node[right] {$a_x$};
\end{tikzpicture}
\end{minted}
\begin{center}
\begin{tikzpicture}
  \pic (T) {fluid tank diagram={fluid left level=.85,fluid right level=.55,fill=cyan!20}};
  \pic (M) at (6,0) {meniscus diagram};
  \pic (N) at (9,0) {meniscus diagram={fluid bend=-.15}};
\end{tikzpicture}
\end{center}

\subsection{Native nodes and patterns}
Use \verb|\node[fluid tank] (T) {};| for an individual object.
The native node styles are \sty{fluid tank}, \sty{fluid cylinder},
\sty{pressure element}, \sty{meniscus}, \sty{rotating fluid},
\sty{flow tube}, \sty{liquid ring}, and \sty{u tube}. They support standard
compass, base, and mid anchors, text, \key{anchor}, \key{minimum width},
\key{minimum height}, \key{inner sep}, \key{outer sep}, and the positioning
library. Native minimum sizes enlarge the frame; fluid dimensions set its
base size. Nodes are centred on their placement coordinate.

Use semantic node anchors such as \verb|(T.right-surface)|,
\verb|(P.inlet)|, and \verb|(R.liquid-start)| to attach ordinary paths.
Automatic connections use the nominal frame, circular for liquid rings.
Cylinder-node levels are measured between end-cap centres. U-tube nodes
show one liquid; the assembly adds the second liquid and interface labels.

Default liquid shading is a light dot pattern. It can be changed directly:
\begin{minted}{latex}
\node[fluid tank,pattern=north east lines,pattern color=gray] {};
\node[fluid tank,pattern=horizontal lines,dashed] at (4,0) {};
\node[fluid tank,fill=cyan!20] at (8,0) {}; % solid liquid
\node[fluid tank,pattern=none] at (12,0) {}; % outline only
\end{minted}
A later \key{fill} replaces a pattern; a later \key{pattern} selects a pattern.
Dashes affect outlines and may affect stroke-based patterns as in native PGF.
The fill and pattern handlers remain local to each fluid node. See
\texttt{examples/fluid-patterns.tex} for simultaneous patterns and ordinary
TikZ nodes. \texttt{examples/fluid-mechanics-nodes.tex} shows all eight nodes.

\subsection{Composition and native styling}
For a complete assembly, put geometry inside the explicit pic argument:
\begin{minted}{latex}
\pic (T) {fluid tank diagram={fluid width=4cm}};
\end{minted}
Use ordinary \key{at}, \key{rotate}, \key{scale}, and \key{transform shape}
for placement and transformations. Native \key{draw}, \key{fill},
\key{color}, \key{line width}, \key{opacity}, and \key{font} are supported.
Text and mathematics inherit the document fonts; default arrows and label
padding follow font size. Geometry remains in physical lengths.

The scoped spelling \verb|fluid={width=4cm}| and the collision-safe spelling
\verb|physics fluid width=4cm| mean the same thing. Every pic also has an
explicit \key{physics} alias, such as \key{physics fluid tank diagram}. Native global keys are
not redefined. Unitless lengths mean centimetres; levels are fractions of height.
A repeated preset can use \verb|every fluid tank/.append style={...}|.

Every pic named \key{F} exposes coordinates \key{F-origin}, \key{F-center},
\key{F-bottom}, \key{F-top}, \key{F-left}, and \key{F-right}. These describe
the nominal frame. Semantic coordinates such as \key{F-left-surface},
\key{F-large-piston}, \key{F-contact-left}, and \key{F-inlet} appear in the
feature reference. Use \verb|(F-surface)|, not node-anchor syntax.
\verb|\physicshelp{fluid tank diagram}| displays assembly defaults and coordinates. The shorter \key{fluid tank} help entry describes the node.
The \key{show anchors} overlay works on fluid nodes; it does not apply to pics. Where both interfaces exist, the explicit pic name ends in \key{diagram}, for example \key{fluid tank diagram}.

\subsection{Diagram families}
\begin{itemize}
\item Hydrostatics: \sty{u tube}, \sty{gas manometer}, \sty{hydraulic press},
\sty{fluid cylinder}, and \sty{fluid tank}. Unequal tank endpoint levels
represent an accelerating liquid; equal levels give a horizontal surface.
\item Pressure and rotation: \sty{pressure element}, \sty{rotating tube},
\sty{rotating fluid}, and \sty{liquid ring}. The rotating-vessel surface is
parabolic; its \key{fluid bend} is the wall-to-vertex rise divided by height.
\item Flow and buoyancy: \sty{flow tube} and \sty{buoyancy}. The outlet is
0.55 times the inlet height. Pressure-arrow lengths are schematic.
\item Interfaces: \sty{meniscus}, \sty{capillary}, and \sty{surface tension ring}.
Positive meniscus bend gives a concave surface; negative bend gives a convex
surface. The contact-angle arc is measured through the liquid.
\end{itemize}

\subsection{Labels, hooks, and geometry limits}
{\raggedright
Generic labels are \key{fluid body label}, \key{fluid left label},
\key{fluid right label}, and \key{fluid dimension label}. Named labels include
\key{fluid force label}, \key{fluid volume label}, \key{fluid pressure label},
\key{fluid pressure increment label}, \key{fluid angular velocity label},
\key{fluid position label}, \key{fluid horizontal axis label},
\key{fluid vertical axis label}, \key{fluid inlet velocity label},
\key{fluid outlet velocity label}, \key{fluid contact angle label},
\key{fluid rise label}, \key{fluid tension label},
\key{fluid circumference force label}, and \key{fluid radius label}.
Empty text suppresses a label. All accept arbitrary LaTeX.\par}

Style hooks are \key{every fluid outline}, \key{every fluid liquid},
\key{every fluid secondary liquid}, \key{every fluid label},
\key{every fluid arrow}, and \key{every fluid dimension}; each also has an
\key{every physics fluid} alias. For example:
\begin{minted}{latex}
\tikzset{every fluid arrow/.append style={>={Stealth[length=.7em]}},
  every fluid label/.append style={font=\footnotesize}}
\end{minted}

U-tube levels must be above the bend, and tube width below one third of both
frame dimensions. Hydraulic piston heights must exceed tube width, which
must also be below 0.3 times frame width. The rotating-tube section must fit
inside its length. The rotating vessel requires nonnegative bend and
\key{level+bend} at most one. Meniscus level plus or minus absolute bend must
stay in $[0,1]$. Capillary rise requires nonnegative bend and
\key{left level - 0.75*bend} at least the reservoir level. The capillary height
annotation measures to the contact line. Ring thickness must be below half
the diameter, with sweep in $(0,360]$. Invalid geometry raises a package error.

The complete usage guide is \texttt{docs/fluids.md}. Copy-ready sources:
\begin{itemize}
\item \texttt{examples/fluid-mechanics-gallery.tex}
\item \texttt{examples/fluid-mechanics-reference-scenes.tex}
\end{itemize}
The latter covers all thirteen reference compositions. The generated single-file Overleaf
package includes the module automatically.

\section{Optical components}

The \module{optics} library provides curved and plane mirrors, symmetric and asymmetric lenses, slabs,
and prisms. They remain ordinary
TikZ nodes, so rotation, scaling, styling, naming, and anchor-based composition
work in the usual way.

\begin{center}
\begin{tikzpicture}[font=\footnotesize,scale=0.72,every node/.append style={transform shape}]
  \begin{scope}[xshift=0cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[concave-mirror, mirror radius=4, mirror thickness=0.22,
          mirror aperture angle=24] (OM1) at (0,0) {};
    \node[below=5pt] at (OM1.south) {\sty{concave-mirror}};
  \end{scope}
  \begin{scope}[xshift=5.4cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[convex-mirror, mirror radius=4, mirror thickness=0.22,
          mirror aperture angle=24] (OM2) at (0,0) {};
    \node[below=5pt] at (OM2.south) {\sty{convex-mirror}};
  \end{scope}
  \begin{scope}[xshift=10.8cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[convex-lens, convex lens radius=4, convex lens thickness=0.18,
          convex lens aperture angle=22] (OC) at (0,0) {};
    \node[below=5pt] at (OC.south) {\sty{convex-lens}};
  \end{scope}
  \begin{scope}[xshift=0cm,yshift=-5cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[concave-lens, concave lens radius=4, concave lens thickness=0.18,
          concave lens aperture angle=22] (OD) at (0,0) {};
    \node[below=5pt] at (OD.south) {\sty{concave-lens}};
  \end{scope}
  \begin{scope}[xshift=5.4cm,yshift=-5cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[slab, minimum width=1cm, minimum height=2.8cm] (OS) at (0,0) {};
    \node[below=5pt] at (OS.south) {\sty{slab}};
  \end{scope}
  \begin{scope}[xshift=10.8cm,yshift=-5cm]
    \draw[->,physicsgray] (-1.7,0) -- (1.7,0);
    \node[prism, prism width=2.8, prism apex angle=60] (OP) at (0,0) {};
    \node[below=5pt] at (OP.south) {\sty{prism}};
  \end{scope}
\end{tikzpicture}
\end{center}

\begin{tabularx}{\linewidth}{@{}KKD@{}}
\toprule
Short style & Collision-safe style & Geometry \\
\midrule
concave-mirror & physicsconcavemirror & Concave reflecting surface \\
convex-mirror & physicsconvexmirror & Convex reflecting surface \\
convex-lens & physicsconvexlens & Symmetric biconvex element \\
concave-lens & physicsconcavelens & Symmetric biconcave element \\
slab & physicsslab & Parallel rectangular faces \\
prism & physicsprism & Isosceles triangular cross-section \\
\bottomrule
\end{tabularx}

\subsection{Plane mirrors and asymmetric lenses}

Use \sty{plane-mirror}, \sty{plano-convex-lens}, \sty{plano-concave-lens},
\sty{positive-meniscus-lens}, or \sty{negative-meniscus-lens}.
Plane mirrors use \key{mirror height} (3 cm) and \key{mirror thickness}
(0.25 cm). The new lens variants use \key{lens height} (3 cm),
\key{lens thickness} (0.2 cm minimum material thickness), and
\key{lens front radius} / \key{lens back radius}. Plano lenses have a flat
front face and a curved back face of radius 5 cm. Meniscus defaults use
front/back radii 4/6 cm for positive and 6/4 cm for negative.
\key{lens radius} sets both radii; each curved radius must exceed half the
height. Height and thickness must be positive. Bare lengths are centimetres.
These keys apply to the new asymmetric variants; symmetric lenses keep
their existing keys. Use \key{xscale=-1} to reverse an element.

All new styles default to black outlines and white interiors; plane mirrors
use black hatching. Override ordinary TikZ drawing and filling keys in your
document when color is wanted.

All five new styles expose \key{surface-T}, \key{front-T}, \key{back-T},
\key{top-T}, and \key{bottom-T}, plus the existing numeric shorthand.
The primary surface is the front face; faces run bottom to top, top caps
right to left, and bottom caps left to right. See
\path{examples/optics-variants.tex} and \path{docs/optics-anchors.md}.


\begin{center}
\begin{tikzpicture}[font=\footnotesize]
 \node[plane-mirror,mirror height=2] (VM) {};
 \node[plano-convex-lens,lens height=2] (VC) at (2.8,0) {};
 \node[plano-concave-lens,lens height=2] (VD) at (5.6,0) {};
 \node[positive-meniscus-lens,lens height=2] (VP) at (8.4,0) {};
 \node[negative-meniscus-lens,lens height=2] (VN) at (11.2,0) {};
 \foreach \n/\label in {VM/Plane mirror,VC/Plano-convex,VD/Plano-concave,VP/Positive meniscus,VN/Negative meniscus}{
  \node[below=8pt] at (\n.south) {\label};
  \foreach \t in {0,25,50,75,100}{
   \fill[black] (\n.front-\t) circle (1pt);
   \fill[black] (\n.back-\t) circle (1pt);
  }
 }
\end{tikzpicture}
\end{center}
Black samples mark both optical faces.
For unequal radii the same percentage need not select the same height:
each arc interpolates its own angle. The endpoints and midpoint align.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Family & Direction and meaning \\
\midrule
surface-T, front-T & Bottom to top on the front face. \\
back-T & Bottom to top on the back face. \\
top-T & Back-top to front-top (right to left before reflection). \\
bottom-T & Front-bottom to back-bottom (left to right before reflection). \\
0 through 100 & Short form of surface-T. \\
\bottomrule
\end{tabularx}

\begin{minted}{latex}
\node[plane-mirror,mirror height=3,mirror thickness=.15] (M) {};
\node[plano-concave-lens,lens height=3,lens radius=5,
      lens thickness=.25,xscale=-1] (L) at (4,0) {};
\draw[->] (L.surface-50) -- (M.surface-50);
\end{minted}
This connects chosen attachment points; ray refraction and focal lengths
are not calculated. Meniscus names describe their default geometry;
custom radii can change which region is thicker. For half-height $h$ and
radius $R$, each face has sag $R-\sqrt{R^2-h^2}$. The thickness key spaces
the faces sufficiently to preserve the requested minimum at axis or rim.

The named \key{front-mid}, \key{back-mid}, \key{front-top},
\key{front-bottom}, \key{back-top}, \key{back-bottom}, \key{surface-mid},
\key{surface-top}, \key{surface-bottom}, and \key{vertex} anchors complement
the percentage families. The node centre lies halfway between the on-axis
vertices. Use physical face anchors for accurate attachments; automatic
border intersections use a bounding approximation.

\begin{minted}{latex}
\node[plano-concave-lens,show anchors,show keys,
  physics debug/anchor families={surface,back,top,bottom},
  physics debug/anchor samples={0,25,50,75,100}] (L) {};
\end{minted}
Every new style has an \key{every <style>} hook and a collision-safe
\texttt{physics...} name, for example \sty{physicsplanoconcavelens}.
The aliases \sty{plano-convex}, \sty{plano-concave}, \sty{biconvex-lens},
and \sty{biconcave-lens} are also available. Reference cards use canonical
names. For example:
\begin{minted}{latex}
\physicshelp{plano-concave-lens}
\end{minted}

For Overleaf, replace the project-local \path{tikzphysics.sty} with
\path{output/overleaf/tikzphysics.sty}. It contains every module and the
reference catalogue; sibling library files are unnecessary. The updated
starter and optics examples are included in the current upload ZIP. These
local additions are independent of CTAN and TeX Live publication.

\subsection{Percentage attachment families}

Every optical shape provides \key{surface-0} through \key{surface-100}.
For mirrors this is the reflecting face, for lenses and slabs the front face,
and for prisms the left (entry) face. Optical arcs run bottom to top by angle;
the prism entry face retains its apex-to-base-left direction. Prism
\key{entry-T} and \key{exit-T} alias \key{left-T} and \key{right-T}, respectively.
The exit face runs from base-right to apex.

Mirrors, lenses, and slabs provide \key{top-T} from right to left and
\key{bottom-T} from left to right. Mirror and lens caps span the edge thickness. All families accept integer percentages
0 through 100 and transform with the node. Existing numeric shorthand and
named anchors retain their meanings. See \path{docs/optics-anchors.md} and
\path{examples/optics-percentage-anchors.tex} for the complete direction table
and gallery.

\subsection{Concave and convex mirrors}

\sty{concave-mirror} and \sty{convex-mirror} are reflected variants of one
spherical-mirror cross-section. The hatched side represents the backing; the
solid arc is the reflecting surface.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Key & Meaning and default \\
\midrule
mirror radius & Radius of the reflecting surface; default \texttt{5cm}. \\
mirror thickness & On-axis backing thickness; default \texttt{0.25cm}. \\
mirror aperture angle & Reflecting-surface half-angle; default 30 degrees. \\
\bottomrule
\end{tabularx}

The aperture angle must be strictly between 0 and 90 degrees. Named anchors
include \key{surface-mid}, \key{surface-top}, \key{surface-bottom},
\key{back-mid}, \key{back-top}, \key{back-bottom}, \key{vertex},
\key{top}, and \key{bottom}. The families \key{surface-0..100} and
\key{back-0..100} run from bottom to top.

Collision-safe aliases add the \key{physics} prefix:
\begin{itemize}
  \item \key{physics mirror radius};
  \item \key{physics mirror thickness};
  \item \key{physics mirror aperture angle}.
\end{itemize}

\Needspace{14\baselineskip}
\begin{minted}{latex}
\documentclass[tikz, border=6mm]{standalone}
\usepackage{tikzphysics}
\begin{document}
\begin{tikzpicture}
  \node[concave-mirror, mirror radius=5cm,
        mirror aperture angle=28] (M1) at (0,0) {};
  \node[convex-mirror, mirror radius=5cm,
        mirror aperture angle=28] (M2) at (5,0) {};
  \draw[->] (-2,0.7) -- (M1.surface-70);
  \draw[->] (3,0.7) -- (M2.surface-70);
\end{tikzpicture}
\end{document}
\end{minted}

\subsection{Convex and concave lenses}

\sty{convex-lens} draws a symmetric biconvex element, while
\sty{concave-lens} draws a symmetric biconcave element.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Key & Meaning and default \\
\midrule
convex lens radius & Radius of both optical surfaces; default \texttt{5cm}. \\
convex lens thickness & Material thickness at the top and bottom caps; default
  \texttt{0.2cm}. \\
convex lens aperture angle & Half-angle of both surfaces; default 25 degrees. \\
concave lens radius & Radius of both optical surfaces; default \texttt{5cm}. \\
concave lens thickness & Material thickness on the optical axis; default
  \texttt{0.2cm}. \\
concave lens aperture angle & Half-angle of both surfaces; default 25 degrees. \\
\bottomrule
\end{tabularx}

The aperture angle must be strictly between 0 and 90 degrees. Named anchors
include \key{front-mid}, \key{back-mid}, \key{front-top},
\key{front-bottom}, \key{back-top}, \key{back-bottom}, \key{top}, and
\key{bottom}. The arc families \key{front-0..100} and \key{back-0..100} run
from bottom to top. Collision-safe keys add the \key{physics} prefix, for
example \key{physics convex lens radius} and
\key{physics concave lens radius}.

\subsection{Slab}

\sty{slab} uses native \key{minimum width} and \key{minimum height}; the
unit-aware conveniences \key{slab width} and \key{slab height} set the same
requirements. Defaults are \texttt{1.2cm} by \texttt{3cm}. The shape is an
unfilled outline, so ray paths remain visible through it.

Named anchors are \key{front}, \key{back}, \key{front-top},
\key{front-bottom}, \key{back-top}, \key{back-bottom}, \key{top}, and
\key{bottom}. Numeric families \key{front-0..100} and \key{back-0..100} run
bottom to top; \key{top-0..100} and \key{bottom-0..100} cover the caps.

\subsection{Prism}

\sty{prism} is an isosceles triangle. Use native \key{minimum width} and
\key{minimum height}, or the unit-aware \key{prism width} and
\key{prism height}. Defaults are \texttt{3cm} by \texttt{2.6cm}. If
\key{prism apex angle} is supplied, it is authoritative and the height is
derived from the width; the angle must be strictly between 0 and 180 degrees.
The prism is also an unfilled outline.

Named anchors are \key{apex}, \key{base-left}, \key{base-right},
\key{base-mid}, \key{left-mid}, \key{right-mid}, \key{entry-mid},
\key{exit-mid}, and \key{centroid}. Numeric families are
\key{base-0..100}, \key{left-0..100}, and \key{right-0..100}.

\subsection{Short numeric anchors}

Each optical shape also exposes its primary ray-entry surface directly as
\key{.0} through \key{.100}. Thus \key{(L.50)} is the midpoint and
\key{(L.80)} is a point near the top of the primary surface.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Shape & Meaning of \key{(name.T)} for $T=0\ldots100$ \\
\midrule
concave-mirror / convex-mirror & Same as \key{surface-T} \\
convex-lens / concave-lens & Same as \key{front-T} \\
slab & Same as \key{front-T} \\
prism & Same as \key{left-T} \\
\bottomrule
\end{tabularx}

Explicit family names can mark corresponding points, for example
\key{(L.80) -- (L.back-80)}; that segment is not generally a physical ray.

\subsection{Complete copy-paste ray diagram}

For the fixed ratio $n_{\mathrm{lens}}/n_{\mathrm{air}}=1.50$, the following
Snell-law construction bends each non-axial ray at both interfaces. The axial
ray stays straight because it meets both vertices normally.

\Needspace{20\baselineskip}
\begin{minted}{latex}
\documentclass[tikz, border=6mm]{standalone}
\usepackage{tikzphysics}

\begin{document}
\begin{tikzpicture}[ray/.style={red!75!black, very thick, ->}]
  \node[convex-lens, convex lens radius=3cm,
        convex lens thickness=0.2cm,
        convex lens aperture angle=25] (L) at (0,0) {};
  \coordinate (Xlow) at ($(L.center)+(0.29194,-0.72588)$);
  \coordinate (Xhigh) at ($(L.center)+(0.29194,0.72588)$);
  \coordinate (F) at (2.93841,0);
  \draw[densely dashed, gray] (-3.5,0) -- (3.5,0);
  \fill (F) circle (1.2pt) node[below] {$F$};
  \draw[ray] ($(L.20)+(-3,0)$) -- (L.20) -- (Xlow) -- (F);
  \draw[ray] ($(L.50)+(-3,0)$) -- (L.50) -- (L.back-50) -- (F);
  \draw[ray] ($(L.80)+(-3,0)$) -- (L.80) -- (Xhigh) -- (F);
\end{tikzpicture}
\end{document}
\end{minted}

\begin{center}
\begin{tikzpicture}[scale=0.72,every node/.append style={transform shape},
  ray/.style={red!75!black, very thick, ->},
  extension/.style={red!55!black, densely dashed}]
  \begin{scope}
    \node[convex-lens, convex lens radius=3cm, convex lens thickness=0.2cm,
          convex lens aperture angle=25] (RL) at (0,0) {};
    \coordinate (RLlow) at ($(RL.center)+(0.29194,-0.72588)$);
    \coordinate (RLhigh) at ($(RL.center)+(0.29194,0.72588)$);
    \coordinate (RF) at (2.93841,0);
    \draw[densely dashed,physicsgray] (-3.5,0) -- (3.5,0);
    \fill (RF) circle (1.2pt) node[below] {$F$};
    \draw[ray] ($(RL.20)+(-3,0)$) -- (RL.20) -- (RLlow) -- (RF);
    \draw[ray] ($(RL.50)+(-3,0)$) -- (RL.50) -- (RL.back-50) -- (RF);
    \draw[ray] ($(RL.80)+(-3,0)$) -- (RL.80) -- (RLhigh) -- (RF);
    \node[font=\small\bfseries] at (0,1.65) {Converging, $n=1.50$};
  \end{scope}
  \begin{scope}[xshift=8.5cm]
    \node[concave-lens, concave lens radius=3cm, concave lens thickness=0.2cm,
          concave lens aperture angle=25] (RD) at (0,0) {};
    \coordinate (RDlow) at ($(RD.center)+(0.21232,-0.81319)$);
    \coordinate (RDhigh) at ($(RD.center)+(0.21232,0.81319)$);
    \coordinate (RDF) at (-2.54285,0);
    \draw[densely dashed,physicsgray] (-3.5,0) -- (3.5,0);
    \fill (RDF) circle (1.2pt) node[below] {$F$};
    \draw[extension] (RDF) -- (RDlow);
    \draw[extension] (RDF) -- (RDhigh);
    \draw[ray] ($(RD.20)+(-3,0)$) -- (RD.20) -- (RDlow)
      -- ($(RDF)!2.25!(RDlow)$);
    \draw[ray] ($(RD.50)+(-3,0)$) -- (RD.50) -- (RD.back-50) -- (3.4,0);
    \draw[ray] ($(RD.80)+(-3,0)$) -- (RD.80) -- (RDhigh)
      -- ($(RDF)!2.25!(RDhigh)$);
    \node[font=\small\bfseries] at (0,1.65) {Diverging, $n=1.50$};
  \end{scope}
\end{tikzpicture}
\end{center}

\physicsnote{The package supplies geometry and anchors, not automatic ray
tracing. These coordinates are valid only for the stated lens and index;
recalculate them after changing either. The complete four-panel source is
\path{examples/optics-complete-ray-diagrams.tex}.}

\clearpage
% -----------------------------------------------------------------------------
\section{Native components, tracks, and waves}\label{sec:components}

The following additions are ordinary named nodes. They retain black outlines
and unfilled interiors by default; document-level TikZ styling remains
available. Every component has an \key{every <style>} hook, a collision-safe
\texttt{physics...node} name, a reference card, and integer percentage
families from 0 through 100. Geometry keys also accept a \texttt{physics}
prefix. Bare lengths are centimetres; explicit TeX units are respected.
Dimensions are independent of node text and \key{minimum width}; place
long labels externally.

\subsection{Mechanical connections}

\sty{beam} is a finite-thickness rectangular rod; \sty{rod node} is an alias.
The existing \verb|\draw[rod]| path is unchanged. Use \key{beam length}
(default 3 cm) and \key{beam thickness} (0.25 cm). Its \key{axis-T} runs
left to right; \key{bottom-T}, \key{right-T}, \key{top-T}, and \key{left-T}
run counterclockwise around the outline. \key{start} and \key{end} are the
axis endpoints.

\sty{damper} draws an open dashpot housing, rod, and piston. It accepts
\key{damper length} (3 cm), \key{damper width} (0.7 cm), and
\key{damper position} (0.5, strictly between 0 and 1). The position controls
visual stroke, not a force law. \key{piston-T} runs bottom to top and
\key{axis-T} left to right.

\sty{compound pulley} is a stepped wheel with two concentric drums on one
axle. \key{compound pulley radius} defaults to 1 cm and
\key{compound pulley inner radius} to 0.55 cm, with inner radius smaller
than outer. Both \key{rim-T} and \key{inner-rim-T} start at the rightmost
point and run counterclockwise. This node does not automatically route a
block-and-tackle rope; the existing \key{over pulley} routing remains for
ordinary circular pulley nodes.

\sty{physical pendulum} is a uniform bar with an explicit pivot. Its length
and width default to 3 cm and 0.45 cm; \key{physical pendulum pivot} is a
fraction from the top, default 0.1. Its \key{axis-T} runs top to bottom.
Use \key{anchor=pivot} and \key{rotate} to suspend it at a chosen point.
\key{mass-center} marks the geometric centre.

\begin{minted}{latex}
\node[beam,beam length=4] (B) {};
\node[damper,anchor=start,damper position=.7] (D) at (B.end) {};
\node[physical pendulum,anchor=pivot,rotate=25,
      physical pendulum length=2] (P) at (B.start) {};
\end{minted}

\subsection{Fluid apparatus nodes}

\sty{piston cylinder} provides an open cylinder, piston and rod.
\key{piston cylinder width} and \key{piston cylinder height} default to
1.8 cm and 3 cm. \key{piston position} defaults to 0.65 of the height from
the bottom and must lie strictly between 0.1 and 0.9. \key{piston-T} spans
the lower contact face from left to right; \key{rod-end} locates the rod tip.

\sty{capillary tube} uses \key{capillary width} (0.5 cm),
\key{capillary height} (3 cm), \key{capillary level} (0.6), and
\key{capillary sag} (0.12 cm). Positive sag gives a concave liquid boundary,
negative sag a convex one, and zero sag a flat one. Its magnitude must be
less than both the liquid height and remaining headroom. \key{surface-T}
runs left to right by horizontal position. Capillary rise is supplied by
the author, not calculated from material properties.

\sty{nozzle} and \sty{venturi} have smooth cosine-profile walls. Use the
style name as the key prefix for \texttt{length} (4 cm),
\texttt{diameter} (1.4 cm), and \texttt{throat diameter} (0.55 cm).
The throat diameter must be positive and no larger than the inlet diameter.
The nozzle throat is at its outlet; the Venturi throat is at its midpoint.
Both wall families run inlet to outlet by axial position; \key{inlet-T},
\key{outlet-T}, and \key{throat-T} run bottom to top. \key{axis-T} follows
the centreline. These nodes do not calculate speed or pressure.

\sty{layered tank} has width 3 cm, height 2.5 cm, interface fraction 0.35,
and liquid level 0.75. Keys use the \texttt{layered tank} prefix.
The interface must lie strictly below the level, both between zero and one.
\key{interface-T} and \key{surface-T} run left to right; \key{lower-center}
and \key{upper-center} locate labels in the two liquids.

\begin{minted}{latex}
\node[layered tank,layered tank interface=.3,
      layered tank level=.8] (T) {};
\node at (T.lower-center) {$\rho_1$};
\node at (T.upper-center) {$\rho_2$};
\node[venturi,venturi throat diameter=.35,rotate=15] (V) at (6,0) {};
\end{minted}

\subsection{Projected solids and shells}

\sty{solid cylinder}, \sty{solid cone}, \sty{solid frustum},
\sty{cylindrical shell}, and \sty{conical shell} use their style name as the
prefix for \texttt{radius} (1 cm), \texttt{height} (2.5 cm), and
\texttt{depth} (0.25). Depth is the ellipse compression ratio, strictly
between zero and one. These are wireframe projections; both halves of a rim
are visible. Keep \key{fill=none}; this is not an occlusion-aware 3D renderer.

Frustum and conical-shell \texttt{top ratio} defaults to 0.5 and must be
strictly between zero and one. Shell \texttt{thickness} defaults to 0.2 cm
and must be smaller than the base radius. A conical shell is a hollow
frustum whose inner and outer top radii scale by the same ratio; it does
not represent constant normal-wall thickness.

\key{bottom-rim-T}, \key{top-rim-T}, and shell \key{inner-bottom-rim-T} /
\key{inner-top-rim-T} use ellipse angle, starting at the right and running
counterclockwise. \key{axis-T} and the right-silhouette \key{generator-T}
run bottom to top. On a cone, the top rim collapses to the apex.
\sty{hemisphere} instead has \key{hemisphere radius} (1.2 cm) and
\key{hemisphere depth} (0.25); its \key{meridian-T} follows the dome from
left to right and \key{axis-T} runs from the base centre to the apex.

\subsection{Connected tracks and contact guides}

\sty{track} consists of horizontal entry, straight incline, and horizontal
exit, each occupying one third of the horizontal length. \key{track length}
defaults to 4 cm and \key{track rise} to 1 cm; zero rise is allowed.
\key{surface-T} advances by total path distance. At a corner, the tangent
uses the outgoing section. \key{start} and \key{end} join separate nodes.

\sty{circular bowl} follows the lower semicircle from left to right;
\sty{loop track} starts at the bottom and runs counterclockwise around the
full circle. Both radii default to 1.4 cm. Their percentages are arc-length
fractions. The loop's start and end coincide.

All three tracks provide \key{tangent-before-T}, \key{tangent-after-T},
and \key{normal-T}: points 0.2 cm from contact. The normal points to the
left of travel, into the circular track. Rotation and uniform scaling
preserve perpendicularity; nonuniform scaling generally does not.

Keys \texttt{rough start} and \texttt{rough end}, prefixed by the track's
style name, select an ordered interval from 0 to 100. Equal values mean
smooth; a nonzero interval is hatched at both ends and at intervals no
larger than five percentage points. Hatching does not set a friction law.

\begin{minted}{latex}
\node[track,track rough start=20,track rough end=80] (T) {};
\node[track,track length=3,track rise=0,anchor=start] (U) at (T.end) {};
\draw[->] (T.surface-50) -- (T.normal-50);
\end{minted}

\subsection{Waves and acoustic modes}

The new \module{waves} library loads with the package. To load it independently:
\begin{minted}{latex}
\usetikzlibrary{tikzphysics.waves}
\end{minted}
All wave nodes expose
\key{axis-T} left to right and \key{curve-T} on the drawn snapshot.
\key{wave length} means total drawn length, default 4 cm; amplitude is
0.4 cm. Dimensions are positive.

\sty{transverse wave} has \key{wave cycles} (2, in $(0,100]$) and
\key{wave phase} (0 degrees). \sty{standing wave} instead has
\key{standing wave lobes} (3, an integer from 1 to 100), counting
half-wavelength loops between fixed ends.
\sty{longitudinal wave} is a variable-spacing schematic spring:
\key{wave coils} defaults to 16 and is an integer from 1 to 100;
cycles are integer. \key{wave compression} defaults to 0.65 and lies in
$[0,1)$, ensuring the longitudinal coordinate never reverses.

\sty{open pipe} is open at both ends; \sty{closed pipe} is closed at the
left. \key{pipe length} is 4 cm, \key{pipe width} 0.8 cm, and
\key{pipe mode} an integer from 1 to 50, default 1. The curve shows
\emph{displacement}, not pressure: open ends are antinodes and closed ends
are nodes. Mode $m$ represents harmonic $m$ for an open pipe and $2m-1$
for a closed pipe. The displacement amplitude is 35 percent of the width.

\begin{tabularx}{\linewidth}{@{}DDD@{}}
\toprule
Pattern & Node indices & Antinode indices \\
\midrule
Standing wave, $n$ lobes & $0,\ldots,n$ & $0,\ldots,n-1$ \\
Open pipe, mode $m$ & $0,\ldots,m-1$ & $0,\ldots,m$ \\
Closed pipe, mode $m$ & $0,\ldots,m-1$ & $0,\ldots,m-1$ \\
\bottomrule
\end{tabularx}
The anchors \key{node-N} and \key{antinode-N} are indexed axis positions,
not percentage families or displacement peaks. Out-of-range indices raise
a package error. No frequency, wave speed, or time evolution is calculated.

\begin{minted}{latex}
\node[closed pipe,pipe mode=2,pipe length=6] (P) {};
\foreach \i in {0,1}{
  \fill (P.node-\i) circle(2pt);
  \draw (P.antinode-\i) circle(2pt);
}
\end{minted}
\begin{center}
\begin{tikzpicture}[font=\small]
 \node[closed pipe,pipe mode=2,pipe length=6] (P) {};
 \foreach \i in {0,1}{\fill (P.node-\i) circle(2pt);\draw (P.antinode-\i) circle(2pt);}
 \node[below=12pt] at (P.south) {Closed pipe: third-harmonic displacement};
\end{tikzpicture}
\end{center}

\subsection{Verification, examples, and the single-file runtime}

All new nodes support \key{show anchors}, \key{show keys}, and
\verb|\physicshelp|. Their physical diagrams default to black and white;
debug overlays use the shared diagnostic styles. Automatic border
intersections use bounding rectangles, so use physical families for exact
attachments. The saved geometry belongs to each node, independently of
subsequent key changes.

\path{docs/native-components.md} lists every key and default, direction,
physical limitation, and valid input range. Editable example sources are:
\begin{itemize}
\item \path{examples/native-components.tex}: all 23 styles.
\item \path{examples/native-component-scenes.tex}: connections and wave modes.
\end{itemize}
The generated Overleaf runtime includes all new shapes and the waves
library. Numerical regressions run through \texttt{l3build check};
\path{scripts/verify_components.py} verifies invalid-input diagnostics.


\section{Thermodynamics}\label{sec:thermodynamics}
The \module{thermodynamics} library loads with the package and is included in
its single-file Overleaf runtime. It provides reservoirs, gas chambers, thermal
walls, heat engines and refrigerators, five pressure--volume processes, and
rectangular and Carnot cycles, plus a shared PV axes frame. Physical diagrams default to black and white.
For the complete parameter tables and equations, see \texttt{docs/thermodynamics.md};
the companion three-page gallery is \texttt{docs/thermodynamics.pdf}.
The composition gallery is \path{docs/thermodynamics-scenes.pdf}.

\subsection{Apparatus and energy flow}
Use \texttt{thermal reservoir}, \texttt{gas chamber}, \texttt{thermal wall},
\texttt{heat engine}, and \texttt{refrigerator} as named nodes.
Aliases include \texttt{hot reservoir}, \texttt{cold reservoir},
\texttt{conducting wall}, \texttt{insulated wall}, and \texttt{heat pump}. The \texttt{heat pump diagram} pic aliases the
refrigerator schematic. Automatic engine connections and diagonal compass
anchors meet its circular boundary.
Rectangular boundary families run counterclockwise: bottom left to right,
right bottom to top, top right to left, and left top to bottom.
Each family accepts integer percentages from 0 to 100.
Engine rim percentages run counterclockwise from the rightmost point.
Devices expose \texttt{hot}, \texttt{cold}, \texttt{work}, \texttt{heat-in},
and \texttt{heat-out} ports. Reservoirs, chambers and walls expose heat ports
at their four face midpoints.

\begin{center}
\begin{tikzpicture}[>=latex,font=\small]
\pic (E) {heat engine diagram};
\pic (R) at (7,0) {refrigerator diagram};
\end{tikzpicture}
\end{center}
The pics provide named reservoir/device nodes and directed heat/work arrows.
The flow arrows use \texttt{>=latex} arrowheads. Labels denote positive magnitudes; arrows distinguish input and output.
A named pic \texttt{E} exports \texttt{E-hot}, \texttt{E-cold},
\texttt{E-device}, \texttt{E-origin}, and \texttt{E-work}.
Customize labels with the \texttt{thermo hot label}, \texttt{thermo cold label},
and heat/work label keys; set spacing with \texttt{thermo diagram separation}
and \texttt{thermo diagram work length}. Style hooks are
\texttt{every thermo flow} and \texttt{every thermo label}.
Each pic exports \texttt{heat-hot-0..100}, \texttt{heat-cold-0..100}, and
\texttt{work-0..100} coordinate families, following each energy arrow from tail
to head. For example, \texttt{(E-heat-hot-50)} is its heat-flow midpoint.
Use the hyphen spelling for pic coordinates and a dot for native node anchors.
Refrigerator and heat-pump families follow their reversed heat/work flow directions.


\subsection{Pressure--volume processes and cycles}
Axis keys \texttt{pv width} and \texttt{pv height} are drawing lengths;
\texttt{pv max volume} and \texttt{pv max pressure} are positive numbers.
Pressure and volume use consistent author-chosen units, supplied in axis labels.
The \texttt{origin} anchor is physical zero at the lower left, whereas the node
center is the drawing center. Axis families run right and up from zero.

The five process nodes are \texttt{isothermal process}, \texttt{isobaric process},
\texttt{isochoric process}, \texttt{adiabatic process}, and
\texttt{polytropic process}. Set \texttt{pv start volume},
\texttt{pv start pressure}, and \texttt{pv end volume}; the isochoric node uses
\texttt{pv end pressure} instead. Curves obey
\(P=P_0(V_0/V)^n\), with \(n=1,0,\gamma\), or the chosen polytropic exponent;
the isochoric curve instead keeps volume constant. The adiabatic relation assumes
a reversible ideal-gas process. Process percentages interpolate volume, or
pressure for the isochoric case, rather than arc length or time. Compression
is supported. The \texttt{start} and \texttt{end} anchors identify the endpoints.

The \texttt{rectangular cycle} uses strictly ordered low/high pressure and volume
keys, with clockwise branches \texttt{AB}, \texttt{BC}, \texttt{CD}, \texttt{DA}.
The \texttt{carnot cycle} derives all four states from start volume, hot constant
\(P_A V_A\), cold/hot absolute-temperature ratio, expansion ratio and gamma.
Its \texttt{hot}, \texttt{expansion}, \texttt{cold}, and \texttt{compression}
percentage families follow the two isotherms and two adiabats. Both cycle nodes
provide \texttt{state-A} through \texttt{state-D}. Curves and anchors share the
same equations, and all four Carnot branches close at those states.

Dimensions must be positive and states must fit the axis limits. Gamma must
exceed one, Carnot expansion must exceed one, and its temperature ratio must
lie strictly between zero and one. Use moderate numerical scales for PGF
arithmetic. The module draws educational geometry; it does not calculate
heat, work integrals, entropy, efficiency, phase changes or real-gas properties.
Labels, ticks and process direction arrows are supplied by the author.


\subsection{Shared axes and state projections}
Use \texttt{pv diagram} for an empty axes frame. Process and cycle nodes accept
\texttt{pv show axes=false} to omit their own axes while retaining their geometry
and every anchor. The default is true. Position overlays at the frame center
with identical width, height and pressure/volume limits.

\begin{center}
\begin{tikzpicture}[>=latex,pv width=6cm,pv height=4cm,font=\small]
\node[pv diagram] (F) {};
\node[isobaric process,pv show axes=false] (B) at (F.center) {};
\node[isothermal process,pv show axes=false,dashed] (I) at (F.center) {};
\node[adiabatic process,pv show axes=false,densely dotted,thick] (A) at (F.center) {};
\node[above] at (F.pressure-end) {$P$};
\node[right] at (F.volume-end) {$V$};
\draw[densely dashed,thin] (I.start-pressure)--(I.start)--(I.start-volume);
\foreach \n/\label in {B/isobaric,I/isothermal,A/adiabatic}{
\fill (\n.end) circle (1.3pt);
\node[right] at (\n.end) {\label};}
\end{tikzpicture}
\end{center}
\begin{minted}{latex}
\begin{tikzpicture}[>=latex,pv width=6cm,pv height=4cm]
  \node[pv diagram] (F) {};
  \node[isothermal process,pv show axes=false] (I) at (F.center) {};
  \node[adiabatic process,pv show axes=false,dashed] (A) at (F.center) {};
  \draw[densely dotted] (I.start-pressure)--(I.start)--(I.start-volume);
\end{tikzpicture}
\end{minted}
Process nodes expose \texttt{start-pressure}, \texttt{end-pressure},
\texttt{start-volume}, and \texttt{end-volume}. Cycle states expose
\texttt{state-A-pressure} and \texttt{state-A-volume}, with corresponding anchors
for B, C and D. These projections transform with their own node.
For a rotated or scaled pic whose child shapes and labels should transform,
include the standard TikZ \texttt{transform shape} option.

Dimensions are explicit: text and minimum-size keys do not enlarge the apparatus
or plots. Enlarge the module's dimension keys for long labels. Ordinary TikZ
styles provide document-level line and color changes. The composition gallery
shows overlays, compression, circular connections, heat pumps and projections.
Impossible process pressures and Carnot extents are checked in logarithmic form
before powers are evaluated, to provide useful axis-limit errors.


\clearpage
\section{Thermal physics and heat transfer}\label{sec:thermalphysics}
The \module{thermalphysics} library provides eight native nodes for thermal
apparatus. It loads with the package and the single-file Overleaf runtime.
For selective loading after TikZ, use:
\begin{minted}{latex}
\usetikzlibrary{tikzphysics.thermalphysics}
% Equivalent selective loader:
\usetikzlibrary{tikzphysics.heattransfer}
\end{minted}
Every node supports saved per-instance dimensions, rotation and scaling,
ordinary TikZ styles, and an \texttt{every <component name>} hook. Physical
geometry is black and white by default, and built-in heat-flow arrows use
\texttt{latex} tips, equivalent to the TikZ \texttt{>=latex} convention.
The complete key tables, conventions and equations are in
\path{docs/thermalphysics.md}. The component and composition galleries are
\path{docs/thermalphysics.pdf} and \path{docs/thermalphysics-scenes.pdf}.

\subsection{Conduction, convection and radiation}
\texttt{conduction slab} draws one material; \texttt{composite wall} draws two,
with a configurable thickness split and interface percentages from bottom to top.
Both expose counterclockwise boundary families and a left-to-right axis.
\texttt{cooling fin} has a base and one thin extension, with root, tip and
base-contact anchors. Attach multiple fins to percentages on a slab's face.
Heat rates, conductivity and fin temperature profiles are author annotations.

\begin{center}
\begin{tikzpicture}[>=latex,font=\small]
\node[composite wall] (C) {};
\node at (C.layer-1-center) {$k_1$};
\node at (C.layer-2-center) {$k_2$};
\node[left] at (C.heat-left) {$T_1$};
\node[right] at (C.heat-right) {$T_2$};
\node[radiating body] (R) at (6,0) {$T$};
\end{tikzpicture}
\end{center}
\texttt{convection surface} draws a plate and schematic heat arrows into the
fluid. Set \texttt{thermal flow direction=-1} to reverse the arrows for a cooled
plate. Surface percentages run left to right, and flow percentages follow the
central arrow from tail to head. The \texttt{radiating body} node provides
emission or absorption arrows with the same direction key, a circular rim family,
and a percentage family along the horizontal ray. Radiation bodies can physically
emit and absorb simultaneously; the schematic illustrates the chosen direction.
No coefficient, emissivity, view factor or heat flux is inferred from geometry.

\subsection{Thermometers, calorimetry and expansion}
\texttt{thermometer} supplies bulb, stem and liquid-column geometry.
Level is a fraction of usable stem height, with an always-filled bulb. The scale,
column, bulb outline, stem sides and cap expose integer percentage families.
The bulb family follows the exposed arc counterclockwise from left stem join
through the bottom to right stem join. Set \texttt{thermal liquid color} to
customize the column; its default is black. Calibration is supplied by the author.

\texttt{calorimeter} provides a double-wall cup, lid and liquid surface with
named liquid/headspace centers. Insulation sets geometric spacing. Place a
thermometer with \texttt{anchor=bulb-center} at a liquid coordinate;
\texttt{fill=white} masks vessel lines through its glass outline.
Liquid level and the thermometer column are independent inputs.
\begin{minted}{latex}
\begin{tikzpicture}[>=latex]
  \node[calorimeter,calorimeter width=4cm] (C) {};
  \node[thermometer,fill=white,anchor=bulb-center]
    (T) at ($(C.liquid-center)+(.7,0)$) {};
\end{tikzpicture}
\end{minted}

\texttt{expansion rod} draws original and changed rods with a common left origin.
The original rod is below. The ratio is changed/original length, so values below
one show contraction. \texttt{original-0..100} and \texttt{expanded-0..100} run
left to right, with explicit start/end anchors. The ratio is supplied directly;
material coefficients and temperature changes are author annotations.

All lengths are positive. Composite split lies strictly between zero and one;
flow direction is 1 or -1. Fin, thermometer and insulation dimensions are checked
before dependent geometry is calculated. Thermometer level accepts endpoints;
calorimeter level is strictly between zero and one. Expansion ratio lies in
\((0,3]\). These are schematic educational apparatus, with explicit native sizes
and percentage positions; labels and thermal balances belong to the document.

\section{Shared tools}

\subsection{Percentage anchors: a beginner's guide}

A percentage anchor names a point partway along one particular edge, arc, or
contact surface. It removes the need to calculate coordinates manually. The
general spelling is

\begin{center}
  \key{(node-name.family-number)}
\end{center}

For example, \key{(W.slope-25)} means: use node \key{W}, choose its
\key{slope} edge, then travel 25 percent from that family's documented start
towards its end. The number is an integer from 0 to 100; write \key{25}, not
\key{25\%}. The three landmarks worth memorising are:

\begin{center}
\begin{tabular}{@{}cl@{}}
\key{family-0} & start of the family \\
\key{family-50} & halfway along the family \\
\key{family-100} & end of the family
\end{tabular}
\end{center}

The family direction matters. On a wedge, \key{slope-0} is the top vertex and
\key{slope-100} is the lower foot, so \key{slope-25} lies near the top rather
than near the foot.

\begin{center}
\begin{tikzpicture}[font=\footnotesize]
  \node[wedge, wedge width=6, wedge angle=30] (PW) at (0,0) {};
  \foreach \t in {0,25,50,75,100}{
    \fill[physicsblue] (PW.slope-\t) circle (1.6pt);
    \node[fill=white,inner sep=1pt]
      at ($(PW.slope-\t)+(0,0.34)$) {\key{\t}};
  }
  \draw[->,physicsblue,thick]
    ($(PW.slope-0)+(0,0.95)$) --
    node[above,sloped,fill=white,inner sep=1pt]{increasing $T$}
    ($(PW.slope-100)+(0,0.95)$);
\end{tikzpicture}
\end{center}

\subsubsection*{Using a percentage anchor}

The node must first have a name. Then use the anchor anywhere TikZ accepts a
coordinate:

\Needspace{17\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}
  \node[wedge, wedge width=6cm, wedge angle=30] (W) at (0,0) {};

  % Put the block midpoint on the middle of the slope.
  % anchor=south makes the block's bottom touch that point.
  \node[block, minimum width=1cm, minimum height=0.7cm,
        rotate=30, anchor=south]
    (B) at (W.slope-50) {$m$};

  % Mark a point 25 percent of the way from the top to the foot.
  \fill[red] (W.slope-25) circle (1.5pt);

  % Draw between two percentage anchors.
  \draw[blue, very thick] (W.base-20) -- (W.slope-80);
\end{tikzpicture}
\end{minted}

Changing the wedge width or angle moves all three points automatically. The
number describes progress along the selected family, not an $x$ coordinate,
$y$ coordinate, distance in centimetres, or angle around the node.

\subsubsection*{Which way does the percentage increase?}

Use 0 as the start and 100 as the arrowhead in the table below. Explicit family
names are recommended in teaching material because they state both the surface
and its direction.

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Family & Direction from 0 to 100 \\
\midrule
\key{surface-T} on a platform or ground & left to right across the top contact face \\
\key{surface-T} on a ceiling & left to right across the underside \\
\key{surface-T} on a wall-left or wall-right & bottom to top on the contact face \\
\key{bottom-T} on a platform & left to right across the underside \\
\key{left-T}, \key{right-T} on a rectangular surface & bottom to top \\
\key{wall-surface-T}, \key{wall-back-T} on a platform & wall root towards its free tip \\
\key{base-T} on a wedge & \key{bl} to \key{br} \\
\key{right-T} on a wedge & \key{br} to \key{top} \\
\key{slope-T} on a wedge & \key{top} to \key{bl} \\
\key{surface-T} on a ramp & \key{surface-start} to \key{surface-end}, following the complete contact path \\
\key{curve-T} on a curved ramp & start to end of the circular portion only \\
\key{surface-T}, \key{front-T}, \key{back-T} in optics & bottom to top \\
\key{base-T} on a prism & \key{base-left} to \key{base-right} \\
\key{left-T} on a prism & \key{apex} to \key{base-left} \\
\key{right-T} on a prism & \key{base-right} to \key{apex} \\
\bottomrule
\end{tabularx}

Fluid free-surface families run from left to right. On a U tube,
\key{left-surface-T} and \key{right-surface-T} independently cover the
liquid in each arm; \key{surface-T} selects the left arm. Block boundaries
follow bottom left-to-right, right bottom-to-top, top right-to-left,
and left top-to-bottom. Mechanics \key{rim-T} starts at the rightmost point
and runs counterclockwise: 25 is north, 50 west, and 75 south.
Projected cylinders provide a left-to-right \key{surface-T} diameter and
an elliptical \key{surface-rim-T}. Flow tubes expose vertical \key{inlet-T}
and \key{outlet-T} faces and a curved \key{axis-T}. Cubic curves use their
curve parameter; each family definition appears in the reference below.

For a multi-part ramp, the percentage follows distance along the complete
contact path. Consequently \key{surface-50} is halfway by path length; it need
not be the floor-to-incline joint or the visual centre of the node. On a
circular family the percentage follows the arc.

\subsubsection*{Short form \key{(name.T)}}

Ramps and optical shapes also provide a short form such as \key{(R.50)} or
\key{(L.80)}. It selects one documented primary surface:

\begin{tabularx}{\linewidth}{@{}KD@{}}
\toprule
Shape & Meaning of \key{(name.T)} \\
\midrule
straight or curved ramp & \key{surface-T} \\
concave or convex mirror & \key{surface-T} \\
convex or concave lens & \key{front-T} \\
slab & \key{front-T} \\
prism & \key{left-T} \\
\bottomrule
\end{tabularx}

Thus \key{(L.80)} and \key{(L.front-80)} are the same point. Platforms and
wedges intentionally require the explicit family name, such as
\key{(P.surface-50)} or \key{(W.slope-50)}. This also avoids confusion with
ordinary TikZ numeric border anchors, where a number can mean an angle around a
node rather than a percentage.

The complete annotated source is
\path{examples/percentage-anchors-beginner.tex}; the more exhaustive edge
gallery is \path{examples/surface-numeric-anchors.tex}.

\clearpage
\subsection{Combining x and y coordinates}

TikZ's native projection operators solve a common mechanics-diagram problem:
take the horizontal position from one anchor and the vertical position from
another. They avoid measured offsets and continue working when either object
moves or changes size.

\begin{center}
\begin{tabular}{@{}cl@{}}
\key{(A |- B)} & x-coordinate from A, y-coordinate from B \\
\key{(A -| B)} & x-coordinate from B, y-coordinate from A
\end{tabular}
\end{center}

Suppose block \key{B} must connect horizontally to the vertical wall of ramp
\key{R}. Use the wall anchor only as the x source and \key{B.west} as the y
source:

\Needspace{9\baselineskip}
\begin{minted}{latex}
\node[ramp, minimum width=8.6cm, ramp run=2.6cm,
      ramp rise=1.5cm] (R) at (0,0) {};
\node[block, minimum width=1cm, minimum height=0.75cm,
      anchor=south] (B) at (R.floor-mid) {$m$};

\coordinate (A) at (R.wall-mid |- B.west);
\draw[spring] (A) -- (B.west);
\end{minted}

Both endpoints now have exactly the same y-coordinate, so the spring or line is
horizontal by construction. The same recipe works with an upward platform
wall:

\Needspace{6\baselineskip}
\begin{minted}{latex}
\node[platform-left-up, minimum width=6cm] (P) at (0,0) {};
\node[block, anchor=south] (B) at (P.surface-75) {$m$};
\coordinate (A) at (P.wall-surface-50 |- B.west);
\draw[spring] (A) -- (B.west);
\end{minted}

For a right upward wall, use \key{B.east} and a right-wall anchor instead. This
projection is exact for vertical walls. For an angled wall it keeps the chosen
anchor's x-coordinate; finding the geometric intersection with an arbitrary
sloping wall instead requires TikZ's \key{intersections} library.

See \path{examples/coordinate-projection.tex} for both complete diagrams.


\subsection{Explore keys and anchors inside TikZ}\label{sec:debug}
Add \key{show anchors} or \key{show keys} to a node, named or unnamed. Both keys
accept \key{true}/\key{false}; a bare key means true. The original
\key{physics debug/anchors}, \key{physics debug/keys}, and
\key{physics debug/all} forms remain supported.
The overlays work on every native physics node, including the eight fluid
nodes. Paths and pics use \key{\textbackslash physicshelp\{name\}} cards.
\Needspace{5\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}
  \node[wedge,show anchors,show keys] (W) {};
\end{tikzpicture}
\end{minted}
\key{show keys} is a complete feature reference, labelled as
\emph{defaults}, not a dump of live node values. It lists geometry keys,
size aliases, all named anchors, percentage families, and common TikZ
styling options. Arbitrary user-defined TikZ keys cannot be enumerated by
the package. The full PGF/TikZ manual remains the reference for generic keys.

\begin{tabularx}{\linewidth}{@{}p{.25\linewidth}X@{}}
\toprule
Object type & In-picture discovery \\
\midrule
Node, such as \key{wedge} or \key{fluid tank} & Add \key{show anchors,show keys} to its node options. \\
Path, such as \key{spring} & Use \key{\textbackslash physicshelp\{spring\}}. \\
Pic, such as \key{fluid tank diagram} & Use \key{\textbackslash physicshelp\{fluid tank diagram\}}; its \key{(F-surface)} coordinate is not a node anchor. \\
\bottomrule
\end{tabularx}

Use \key{\textbackslash physicshelp\{index\}} to list every feature.
Display a reference without constructing a shape:
\Needspace{5\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}
  \physicshelp{spring}
\end{tikzpicture}
\end{minted}
\key{\textbackslash physicshelp[<node options>]\{<feature>\}} accepts every
public feature name, including paths and pics. You can place a card with
\key{xshift}, \key{yshift}, \key{anchor}, or normal \key{at} node options.
Use \key{\textbackslash tikzphysicshelp} for the collision-safe command name.
The reference cards also work when loading only one feature module.
A card can describe another module's feature, but you must load that module
before drawing it.
For complete rendered examples, compile
\path{examples/debug-feature-tour.tex}. Its pages cover a platform, wedge,
curved ramp, fluid tank, mirror, Cartesian element, path, and pic. The
companion \path{docs/debug-overlays.md} explains all debug options and links
the detailed surface, wedge, ramp, and fluid/mechanics anchor galleries.
The latter is \path{examples/fluid-mechanics-anchor-coverage.tex}.

\Needspace{8\baselineskip}
\begin{minted}{latex}
% Inspect a ramp's floor, arc, and back wall.
\node[curved-ramp,show anchors,show keys,
  physics debug/anchor list={surface-start,curve-start,curve-end},
  physics debug/anchor families={floor,curve,back},
  physics debug/anchor samples={0,50,100}] (R) {};

% A native fluid node uses the same overlays.
\node[fluid tank,show anchors,show keys,
  physics debug/anchor list={surface,left-surface,right-surface},
  physics debug/anchor families={surface,bottom,left,right},
  physics debug/anchor samples={0,50,100}]
  (F) at (10,0) {};
\end{minted}

\subsubsection*{Choose points without covering the diagram}
\Needspace{6\baselineskip}
\begin{minted}{latex}
\node[wedge,show anchors,
  physics debug/anchor list={bl,br,top},
  physics debug/anchor families={surface},
  physics debug/anchor samples={0,25,50,75,100}] (W) {};
\end{minted}
\key{anchor list=auto} is the default and enumerates all named anchors in a
table. One numbered marker is placed at each distinct position; multiple
anchors at that position share the same number in the table.
An explicit comma-separated list replaces that selection. Families add the
chosen samples; for example \key{surface} plus \key{50} adds
\key{surface-50}. You may leave the named list empty to inspect only families.
To inspect all points of one family, use
\key{anchor samples=\{0,1,...,100\}}. You can select every family with
\key{anchor families=all}; most diagrams are clearer with a few samples. The reference
always lists the full family ranges. Family names and samples must exist
on that object; unknown anchors receive the normal PGF error.
Coincident points share one label with multiple reference numbers.
\begin{center}
\begin{tikzpicture}
  \node[wedge,wedge angle=30,show anchors,
    physics debug/anchor list={bl,br,top},
    physics debug/anchor families={surface},
    physics debug/anchor samples={0,50,100}] (W) {};
\end{tikzpicture}
\end{center}

\subsubsection*{Scope settings and move panels}
\Needspace{6\baselineskip}
\begin{minted}{latex}
\begin{tikzpicture}[show anchors]
  \node[block] (A) {};
  \node[block,show anchors=false] (B) at (4,0) {};
\end{tikzpicture}
\end{minted}
Options are captured for each object, so local false overrides, fonts, and
colours remain associated with that object. Debug drawings do not recursively
acquire debug overlays. Explicit unique node names are needed only when later
commands refer to the object's anchors.

\begin{tabularx}{\linewidth}{@{}p{.44\linewidth}D@{}}
\toprule
Key under \key{physics debug/} & Default and effect \\
\midrule
\key{anchors}, \key{keys}, \key{all} & false; bare form enables the overlay. \\
\key{anchor list} & auto; all named anchors, or a comma-separated selection. \\
\key{anchor families} & Empty; selected percentage families, or all. \\
\key{anchor samples} & 0,25,50,75,100. \\
\key{anchor dot color}, \key{anchor dot radius} & red, 1.2pt. \\
\key{anchor label color}, \key{anchor label font} & red!80!black, scriptsize typewriter. \\
\key{key label color}, \key{key label font} & gray, tiny typewriter. \\
\key{anchor legend xshift}, \key{anchor legend yshift} & 0pt from the object's centre, -4mm below the lowest displayed anchor. \\
\key{key panel xshift}, \key{key panel yshift} & 0pt, 4mm above the highest named anchor or displayed marker. \\
\bottomrule
\end{tabularx}
\par\smallskip
Panels deliberately enlarge the picture's bounding box. For a complex
system, inspect one object at a time or move its reference card beside the
system. Disable overlays for the final diagram. The examples
\texttt{debug-explorer.tex} and \texttt{debug-scoped.tex} are complete documents.

\subsection{Troubleshooting and geometry limits}\label{sec:troubleshooting}
\begin{description}
  \item[My default size did not apply.] Put the style first and the size after
  it, or set \key{every block}. Built-in style values follow ordinary option order.
  \item[The block is on a vertical wedge edge.] Use \key{surface-T} for physical
  contact. The older \key{slope-T} name follows a fixed CCW edge and is not
  the incline in every wedge mode.
  \item[My block is not rotated with its surface.] Use the tangent-before/after
  path with \key{sloped}. Local scalar geometry values do not include an
  independent node transformation.
  \item[An automatic line ends outside the shape.] Irregular shapes still
  inherit rectangular automatic border behaviour. Use explicit contact anchors;
  true outline intersections for all irregular bodies are future work.
  \item[Scaling makes a normal or rope wrong.] Nonuniform scaling changes
  circles to ellipses and does not preserve perpendicularity. Keep physical
  constructions rigid or uniformly scaled. Use \key{transform shape} when
  scaling the entire node geometry with a scope.
  \item[Long text does not fit an irregular shape.] Package geometry dimensions
  define its body; do not assume native text-driven minimum-size growth.
  Place labels in separate nodes. Blocks and circular primitives use standard
  TikZ shapes and can grow to fit text.
  \item[What does a bare number mean?] Convenience lengths use centimetres;
  native sizing keys should receive explicit units. Angles are degrees.
  \item[Is a numeric anchor an angle?] On a pulley or disk, yes. On ramps and
  optical shapes, integer .0 through .100 are retained percentage shortcuts.
  Explicit family names avoid ambiguity.
  \item[Does the package solve the physics?] No. Forces, constraints, motion,
  optical exit points, and physically compatible placements are supplied by you.
\end{description}

% -----------------------------------------------------------------------------
\section{Installation and development}

The installed drawing package requires only LaTeX2e and PGF/TikZ; using it in
a document does not require shell escape or an external executable. The source
manual uses Fourier and \texttt{minted}, so building \texttt{tikzphysics.pdf}
also requires those packages and shell escape for syntax highlighting.

For manual installation, place \texttt{tikzphysics.sty} and every
\texttt{tikzlibrarytikzphysics*.code.tex} file in a directory searched by TeX.
For a one-file Overleaf upload, run the bundle command shown below and upload
only \texttt{output/overleaf/tikzphysics.sty}. The generated file contains all
runtime modules and the in-picture feature catalog.

The source distribution uses \texttt{l3build}:

\Needspace{5\baselineskip}
\begin{minted}{bash}
l3build check   # run coordinate and anchor regression tests
l3build doc     # build tikzphysics.pdf (shell escape is configured)
l3build ctan    # create the CTAN and TDS archives
python3 scripts/build_overleaf_bundle.py  # one-file Overleaf package
python3 scripts/verify_components.py     # invalid-input diagnostics
\end{minted}

Standalone examples are stored in \texttt{examples/}. The command-line helper
\texttt{tikzphysics-help} prints a compact key and anchor reference.

% -----------------------------------------------------------------------------
\section{Complete feature reference}\label{sec:reference}
Each entry lists built-in defaults, anchors, and available percentage families.
Use explicit family names in new diagrams. The same declarations generate
\texttt{docs/reference.md} and the in-picture \texttt{\textbackslash physicshelp}
cards. Common TikZ keys are additional to the geometry keys shown here;
see the earlier sections for sizing and transformation behaviour.
% BEGIN GENERATED REFERENCE
\subsection{platform-left (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 5cm\\
\texttt{minimum height} & 2cm\\
\texttt{strip width} & 0.25cm\\
\texttt{wall angle} & -90 degrees\\
\texttt{wall inset} & 0cm\\
\texttt{wall drop} & 0cm\\
\texttt{pulley edge} & off; preset uses 0.5cm inset and drop\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} platform width = minimum width; platform depth = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, surface, pulley-center, wall-root, floor-center, wall-center, text\par
\textbf{Families:} bottom-0..100, right-0..100, surface-0..100, left-0..100, transition-0..100, wall-surface-0..100, wall-back-0..100, wall-base-0..100, wall-tip-0..100\par
surface runs left to right across the floor; bottom, left, and right cover its other edges. wall-surface and wall-back run from root to tip; wall-base and wall-tip span the end caps. transition runs from pulley-center to wall-root. Upward walls require zero inset and drop. Use 50 for any edge midpoint.\par

\subsection{platform-right (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 5cm\\
\texttt{minimum height} & 2cm\\
\texttt{strip width} & 0.25cm\\
\texttt{wall angle} & -90 degrees\\
\texttt{wall inset} & 0cm\\
\texttt{wall drop} & 0cm\\
\texttt{pulley edge} & off; preset uses 0.5cm inset and drop\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} platform width = minimum width; platform depth = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, surface, pulley-center, wall-root, floor-center, wall-center, text\par
\textbf{Families:} bottom-0..100, right-0..100, surface-0..100, left-0..100, transition-0..100, wall-surface-0..100, wall-back-0..100, wall-base-0..100, wall-tip-0..100\par
surface runs left to right across the floor; bottom, left, and right cover its other edges. wall-surface and wall-back run from root to tip; wall-base and wall-tip span the end caps. transition runs from pulley-center to wall-root. Upward walls require zero inset and drop. Use 50 for any edge midpoint.\par

\subsection{platform (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 5cm\\
\texttt{minimum height} & 2cm\\
\texttt{strip width} & 0.25cm\\
\texttt{wall angle} & -90 degrees\\
\texttt{left wall angle} & -90 degrees\\
\texttt{right wall angle} & -90 degrees\\
\texttt{wall inset} & 0cm\\
\texttt{left wall inset} & 0cm\\
\texttt{right wall inset} & 0cm\\
\texttt{wall drop} & 0cm\\
\texttt{left wall drop} & 0cm\\
\texttt{right wall drop} & 0cm\\
\texttt{pulley edge} & off; shared preset uses 0.5cm inset and drop\\
\texttt{left pulley edge} & off; left-side preset uses 0.5cm inset and drop\\
\texttt{right pulley edge} & off; right-side preset uses 0.5cm inset and drop\\
\texttt{pulley edges} & off; both-side alias of pulley edge\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} platform width = minimum width; platform depth = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, surface, left-pulley-center, right-pulley-center, left-wall-root, right-wall-root, floor-center, left-wall-center, right-wall-center, text\par
\textbf{Families:} bottom-0..100, right-0..100, surface-0..100, left-0..100, left-transition-0..100, right-transition-0..100, left-wall-surface-0..100, left-wall-back-0..100, left-wall-base-0..100, left-wall-tip-0..100, right-wall-surface-0..100, right-wall-back-0..100, right-wall-base-0..100, right-wall-tip-0..100\par
surface runs left to right across the floor. Each wall has surface, back, base, and tip families with left-wall or right-wall prefixes; each transition runs from its pulley-center to wall-root. Upward walls require zero inset and drop. Use 50 for any edge midpoint.\par

\subsection{wedge (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 4cm\\
\texttt{wedge height} & derived\\
\texttt{wedge angle} & 30 degrees\\
\texttt{wedge right angle at} & br\\
\texttt{wedge top inset} & 0cm\\
\texttt{wedge top drop} & 0cm\\
\texttt{pulley edge} & off; preset uses 0.5cm inset and 1cm drop\\
\texttt{surface guide length} & 0.5cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} wedge width = minimum width.\par
\textbf{Anchors:} surface-start, surface-end, center, north, south, east, west, north east, north west, south east, south west, bl, br, top, pulley-center, wall-root, transition-mid, base-mid, right-mid, slope-mid, slope-right-mid, centroid, mid, text\par
\textbf{Families:} base-0..100, right-0..100, slope-0..100, transition-0..100, surface-0..100, tangent-before-0..100, tangent-after-0..100, normal-0..100, right-surface-0..100, right-tangent-before-0..100, right-tangent-after-0..100, right-normal-0..100\par
base, right, and slope follow the outline counterclockwise from bl. surface runs left to right on the primary usable incline; in top mode right-surface selects the second incline. right-mid equals right-50; slope-mid equals surface-50. A pulley edge is supported in br and bl modes, and its centroid follows the filled four-point body. Directions and normals are local to the node.\par

\subsection{ground (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 6cm\\
\texttt{minimum height} & 0.3cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} ground width = minimum width; ground depth = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top-left, top-right, bottom-left, bottom-right, surface, text\par
\textbf{Families:} bottom-0..100, right-0..100, surface-0..100, left-0..100\par
surface runs left to right on the top contact face; bottom, left, and right cover the other edges. Use 50 for an edge midpoint.\par

\subsection{ceiling (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 2cm\\
\texttt{minimum height} & 0.3cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} ceiling width = minimum width; ceiling depth = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top-left, top-right, bottom-left, bottom-right, surface, text\par
\textbf{Families:} surface-0..100, right-0..100, top-0..100, left-0..100\par
surface runs left to right on the underside; top, left, and right cover the other edges. Use 50 for an edge midpoint.\par

\subsection{wall-left (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 0.3cm\\
\texttt{minimum height} & 3cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} wall thickness = minimum width; wall height = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top-left, top-right, bottom-left, bottom-right, surface, text\par
\textbf{Families:} bottom-0..100, surface-0..100, top-0..100, left-0..100\par
surface runs bottom to top on the right contact face; top, bottom, and left cover the other edges. Use 50 for an edge midpoint.\par

\subsection{wall-right (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 0.3cm\\
\texttt{minimum height} & 3cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} wall thickness = minimum width; wall height = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top-left, top-right, bottom-left, bottom-right, surface, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, surface-0..100\par
surface runs bottom to top on the left contact face; top, bottom, and right cover the other edges. Use 50 for an edge midpoint.\par

\subsection{ramp (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 8.6cm\\
\texttt{ramp run} & 2.6cm\\
\texttt{ramp rise} & derived\\
\texttt{ramp angle} & 30\\
\texttt{ramp depth} & 0.25cm\\
\texttt{ramp wall height} & 1.5cm\\
\texttt{ramp wall width} & 0.25cm\\
\texttt{ramp direction} & right\\
\texttt{ramp guide length} & 0.5cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, surface-start, surface-mid, surface-end, floor-start, floor-mid, floor-end, ramp-foot, ramp-mid, ramp-top, wall-top, wall-mid, wall-bottom, base-start, base-end, angle-baseline, angle-label, angle-first, angle-second, text\par
\textbf{Families:} floor-0..100, incline-0..100, wall-surface-0..100, wall-back-0..100, wall-tip-0..100, base-0..100, end-0..100, surface-0..100, tangent-before-0..100, tangent-after-0..100, normal-0..100; legacy .0..100 shorthand also available\par
surface follows floor plus incline by distance; floor and incline select each component. wall-surface, wall-back, wall-tip, base, and end cover the remaining outline. At the sharp joint the tangent uses the incline side.\par

\subsection{curved-ramp (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{curved ramp floor length} & 3.75cm\\
\texttt{curved ramp radius} & 4cm\\
\texttt{curved ramp angle} & 90\\
\texttt{curved ramp back extension} & 1cm\\
\texttt{ramp depth} & 0.25cm\\
\texttt{ramp direction} & right\\
\texttt{ramp guide length} & 0.5cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, surface-start, surface-mid, surface-end, curve-center, curve-start, curve-mid, curve-end, floor-start, floor-mid, floor-end, base-start, base-end, back-top, back-bottom, text\par
\textbf{Families:} floor-0..100, start-0..100, base-0..100, back-0..100, top-0..100, surface-0..100, curve-0..100, tangent-before-0..100, tangent-after-0..100, normal-0..100, curve-tangent-before-0..100, curve-tangent-after-0..100, curve-normal-0..100; legacy .0..100 shorthand also available\par
surface follows floor plus arc by distance; curve follows the arc only. floor, start, base, back, and top cover the remaining boundary.\par

\subsection{track (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{track length} & 4cm\\
\texttt{track rise} & 1cm\\
\texttt{track rough start} & 0\\
\texttt{track rough end} & 0\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, joint-left, joint-right, text\par
\textbf{Families:} surface-0..100, tangent-before-0..100, tangent-after-0..100, normal-0..100\par
surface is distance along the three joined straight segments, left to right. At joints tangent uses the outgoing section. Connect another node with anchor=start at the preceding end. Tangent and inward/left-normal guide points are 0.2 cm from contact. Optional rough interval is a percentage range marked with hatching.\par

\subsection{circular bowl (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{circular bowl radius} & 1.4cm\\
\texttt{circular bowl rough start} & 0\\
\texttt{circular bowl rough end} & 0\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, text\par
\textbf{Families:} surface-0..100, tangent-before-0..100, tangent-after-0..100, normal-0..100\par
surface follows the lower semicircle left to right. Tangent and inward/left-normal guide points are 0.2 cm from contact. Optional rough interval is a percentage range marked with hatching.\par

\subsection{loop track (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{loop track radius} & 1.4cm\\
\texttt{loop track rough start} & 0\\
\texttt{loop track rough end} & 0\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, text\par
\textbf{Families:} surface-0..100, tangent-before-0..100, tangent-after-0..100, normal-0..100\par
surface starts at the bottom and runs counterclockwise around the full loop. Tangent and inward/left-normal guide points are 0.2 cm from contact. Optional rough interval is a percentage range marked with hatching.\par

\subsection{block (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 1cm\\
\texttt{minimum height} & 1cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} block width = minimum width; block height = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base, base east, base west, mid, mid east, mid west, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100; Bare numeric anchors remain angles in degrees, as in ordinary TikZ.\par
bottom, right, top, left follow the boundary counterclockwise. Use 0 for an edge start, 50 for its midpoint, 100 for its end.\par

\subsection{pulley (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum size} & 1cm\\
\texttt{pulley axle radius} & 1.5pt\\
\texttt{pulley axle color} & black\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} pulley diameter = minimum size.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base, base east, base west, mid, mid east, mid west, text\par
\textbf{Families:} rim-0..100; Bare numeric anchors remain angles in degrees, as in ordinary TikZ.\par
rim starts at the rightmost point and runs counterclockwise around the circle. 25 is north, 50 west, 75 south, and 100 returns to the start.\par

\subsection{particle (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum size} & 3mm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base, base east, base west, mid, mid east, mid west, text\par
\textbf{Families:} rim-0..100; Bare numeric anchors remain angles in degrees, as in ordinary TikZ.\par
rim starts at the rightmost point and runs counterclockwise around the circle. 25 is north, 50 west, 75 south, and 100 returns to the start.\par

\subsection{disk (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum size} & 15mm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base, base east, base west, mid, mid east, mid west, text\par
\textbf{Families:} rim-0..100; Bare numeric anchors remain angles in degrees, as in ordinary TikZ.\par
rim starts at the rightmost point and runs counterclockwise around the circle. 25 is north, 50 west, 75 south, and 100 returns to the start.\par

\subsection{ring (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum size} & 15mm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base, base east, base west, mid, mid east, mid west, text\par
\textbf{Families:} rim-0..100; Bare numeric anchors remain angles in degrees, as in ordinary TikZ.\par
rim starts at the rightmost point and runs counterclockwise around the circle. 25 is north, 50 west, 75 south, and 100 returns to the start.\par

\subsection{spring (node and path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 3cm (node)\\
\texttt{minimum height} & 0pt (node)\\
\texttt{pre length} & 5pt\\
\texttt{post length} & 5pt\\
\texttt{amplitude} & 4.5pt\\
\texttt{segment length} & 4.5pt\\
\texttt{aspect} & 0.5\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} spring length = minimum width.\par
\textbf{Anchors:} center, start, end, coil-start, coil-end, north, south, east, west, north east, south west, north west, south east, text\par
\textbf{Families:} axis-0..100\par
Use draw[spring] (A)--(B) for a two-point connection, or node[spring] (S) {} for a positioned coil. Node length defaults to 3cm; spring length and minimum width set its length. start/end are exact axis attachments, coil-start/coil-end delimit the leads, and axis-0..100 samples the straight axis, not the coil wire. show anchors/show keys apply to nodes; physicshelp{spring} describes both forms. Lead lengths may be zero; their sum must be smaller than the node length. amplitude and segment length must be positive.\par

\subsection{rope (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & inherited\\
\texttt{over pulley} & required node name\\
\texttt{string route} & surface-right\\
\texttt{string start solution} & 2\\
\texttt{string end solution} & 1\\
\texttt{string wrap} & clockwise\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par
Use draw[rope] (A) to[over pulley=P] (B). Endpoints must lie outside a circular pulley. Labels on to sit on the final straight segment. shortest changes wrap only, not the tangent pair.\par

\subsection{force (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & inherited\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par

\subsection{velocity (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & inherited\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par

\subsection{acceleration (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & inherited\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par

\subsection{torque (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & inherited\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par

\subsection{rod (path)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{line width} & inherited\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} No private anchors; use path endpoints and nodes along the path.\par

\subsection{pin-support (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{support size} & 6mm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} pivot, base, left, right\par
Use pic (S) {pin-support}; anchors are coordinates (S-pivot), (S-base), (S-left), (S-right).\par

\subsection{roller-support (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{support size} & 6mm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} pivot, base, left, right\par
Use pic (S) {roller-support}; anchors are coordinates (S-pivot), (S-base), (S-left), (S-right).\par

\subsection{pendulum (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pendulum length} & 2cm\\
\texttt{pendulum angle} & 30 degrees\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} pivot, bob (node)\par
Use pic (P) {pendulum}. Angle is measured from downward vertical; positive swings right. Length is pivot to bob centre. Use (P-pivot) and (P-bob.center).\par

\subsection{beam (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{beam length} & 3cm\\
\texttt{beam thickness} & .25cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, pivot, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100, axis-0..100\par
axis runs left to right; boundary families run counterclockwise. rod node preserves the existing rod path style.\par

\subsection{damper (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{damper length} & 3cm\\
\texttt{damper width} & .7cm\\
\texttt{damper position} & .5\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, piston, text\par
\textbf{Families:} axis-0..100, piston-0..100, top-0..100, bottom-0..100\par
piston runs bottom to top; position is a visual stroke fraction, not a force law.\par

\subsection{compound pulley (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{compound pulley radius} & 1cm\\
\texttt{compound pulley inner radius} & .55cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, axle, text\par
\textbf{Families:} rim-0..100, inner-rim-0..100\par
Two concentric drums share one axle. Both rims start at the rightmost point and run counterclockwise. This is a stepped pulley, not an automatically routed tackle.\par

\subsection{physical pendulum (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{physical pendulum length} & 3cm\\
\texttt{physical pendulum width} & .45cm\\
\texttt{physical pendulum pivot} & .1\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, pivot, mass-center, tip, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100, axis-0..100\par
Uniform rigid bar. axis runs top to bottom; pivot is a fraction from the top. Use anchor=pivot and rotate to suspend it.\par

\subsection{polar element (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element inner radius} & 1.8cm\\
\texttt{element outer radius} & 2cm\\
\texttt{element radial thickness} & derived\\
\texttt{element start angle} & 30 degrees\\
\texttt{element delta angle} & 30 degrees\\
\texttt{element dimension offset} & 4mm\\
\texttt{element radius label} & r\\
\texttt{element radial label} & dr\\
\texttt{element angular label} & d theta\\
\texttt{element arc label} & r d theta\\
\texttt{show dimensions} & off\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, text, north, south, east, west, north east, north west, south east, south west, centroid, inner-start, inner-mid, inner-end, outer-start, outer-mid, outer-end, start-mid, end-mid\par
\textbf{Families:} inner-0..100, outer-0..100, start-0..100, end-0..100\par
An annular sector from inner-start to outer-end. Set inner radius to zero for a sector or delta angle to 360 degrees for a full ring.\par

\subsection{differential sector (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element inner radius} & 0cm\\
\texttt{element outer radius} & 2cm\\
\texttt{element radial thickness} & derived\\
\texttt{element start angle} & 30 degrees\\
\texttt{element delta angle} & 30 degrees\\
\texttt{element dimension offset} & 4mm\\
\texttt{element radius label} & r\\
\texttt{element angular label} & d theta\\
\texttt{element arc label} & r d theta\\
\texttt{show dimensions} & off\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, text, north, south, east, west, north east, north west, south east, south west, centroid, inner-start, inner-mid, inner-end, outer-start, outer-mid, outer-end, start-mid, end-mid\par
\textbf{Families:} inner-0..100, outer-0..100, start-0..100, end-0..100\par
A polar-element preset with zero inner radius. The outer arc represents r d theta and numeric families follow every boundary.\par

\subsection{differential ring (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element inner radius} & 1.8cm\\
\texttt{element outer radius} & 2cm\\
\texttt{element radial thickness} & derived\\
\texttt{element delta angle} & 360 degrees\\
\texttt{element radius label} & r\\
\texttt{element radial label} & dr\\
\texttt{show dimensions} & off\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, text, north, south, east, west, north east, north west, south east, south west, centroid, inner-start, inner-mid, inner-end, outer-start, outer-mid, outer-end, start-mid, end-mid\par
\textbf{Families:} inner-0..100, outer-0..100, start-0..100, end-0..100\par
A polar-element preset with a 360-degree sweep. Use source element on an unwrapped ring to copy its radii.\par

\subsection{unwrapped ring (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element inner radius} & 1.8cm\\
\texttt{element outer radius} & 2cm\\
\texttt{element radial thickness} & derived\\
\texttt{source element} & optional named element\\
\texttt{element circumference label} & 2 pi r\\
\texttt{element radial label} & dr\\
\texttt{show dimensions} & off\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, text, centroid, north, south, east, west, north east, north west, south east, south west, top-left, top-right, bottom-left, bottom-right\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par
A differential approximation with width 2 pi times the inner reference radius and height equal to the radial thickness. source element copies both radii from a named polar element.\par

\subsection{spherical shell (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element inner radius} & 1cm\\
\texttt{element outer radius} & derived\\
\texttt{element radial thickness} & 1.5mm\\
\texttt{element delta angle} & 360 degrees\\
\texttt{element radius label} & r\\
\texttt{element radial label} & dr\\
\texttt{show dimensions} & off\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, text, north, south, east, west, north east, north west, south east, south west, centroid, inner-start, inner-mid, inner-end, outer-start, outer-mid, outer-end, start-mid, end-mid\par
\textbf{Families:} inner-0..100, outer-0..100, start-0..100, end-0..100\par
A concentric differential shell shown in section. Its full-sweep anchors and radial geometry match the spherical-shell construction.\par

\subsection{hollow sphere (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element inner radius} & 1cm\\
\texttt{element outer radius} & 2cm\\
\texttt{element radial thickness} & derived\\
\texttt{element delta angle} & 360 degrees\\
\texttt{element cavity radius label} & a\\
\texttt{element body radius label} & R\\
\texttt{show dimensions} & off\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, text, north, south, east, west, north east, north west, south east, south west, centroid, inner-start, inner-mid, inner-end, outer-start, outer-mid, outer-end, start-mid, end-mid\par
\textbf{Families:} inner-0..100, outer-0..100, start-0..100, end-0..100\par
A finite spherical wall shown in section, with independent inner and outer radii.\par

\subsection{rectangular element (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element width} & 8mm\\
\texttt{element height} & 6mm\\
\texttt{element width label} & dx\\
\texttt{element height label} & dy\\
\texttt{show dimensions} & off\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, text, centroid, north, south, east, west, north east, north west, south east, south west, top-left, top-right, bottom-left, bottom-right\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par
A Cartesian differential area with independent width and height, complete boundary anchors, and optional dimension labels.\par

\subsection{rectangular strip (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element width} & 4cm\\
\texttt{element height} & 2mm\\
\texttt{element width label} & b\\
\texttt{element height label} & dx\\
\texttt{show dimensions} & off\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, text, centroid, north, south, east, west, north east, north west, south east, south west, top-left, top-right, bottom-left, bottom-right\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par
A full-width strip preset. Change its width and differential thickness independently.\par

\subsection{rectangular sheet (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element width} & 5cm\\
\texttt{element height} & 3cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, text, centroid, north, south, east, west, north east, north west, south east, south west, top-left, top-right, bottom-left, bottom-right\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par
A finite unshaded sheet node used alone or as the body in a sheet element diagram.\par

\subsection{differential ring diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element inner radius} & 1cm\\
\texttt{element outer radius} & 1.2cm\\
\texttt{element radial thickness} & derived\\
\texttt{element body radius} & 2cm\\
\texttt{element diagram gap} & 5mm\\
\texttt{element center dot radius} & 1.2pt\\
\texttt{show dimensions} & on for both parts\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, body-north, body-south, body-east, body-west, ring (node), strip (node)\par
Use pic (D) {differential ring diagram={...}}. It keeps the body circle, ring, centre mark, and unwrapped strip together. Components are (D-ring) and (D-strip).\par

\subsection{sphere shell diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element body radius} & 2cm\\
\texttt{element inner radius} & 1cm\\
\texttt{element radial thickness} & 1.5mm\\
\texttt{element formula label} & dV = 4 pi r squared dr\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, body (node), shell (node), formula-anchor\par
A solid sphere with a highlighted spherical shell. Components are (S-body) and (S-shell); (S-center) marks the common centre.\par

\subsection{sphere slice diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element body radius} & 2cm\\
\texttt{element axial thickness} & 2mm\\
\texttt{element position} & 0.35 in (-1\\
\texttt{element projection ratio} & 0.24\\
\texttt{element axial label} & dx\\
\texttt{element formula label} & dV = pi y squared dx\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, body (node), slice (node), formula-anchor\par
\textbf{Families:} disk-rim-0..100\par
A solid sphere with a projected disk slice at a signed normalized axial position. Components are (S-body) and (S-slice).\par

\subsection{hollow sphere diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element inner radius} & 9mm\\
\texttt{element outer radius} & 2cm\\
\texttt{element cavity radius label} & a\\
\texttt{element body radius label} & R\\
\texttt{element formula label} & V = 4 pi over 3 times (R cubed - a cubed)\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, body-north, body-south, wall (node), formula-anchor\par
A hollow sphere in section. Component (H-wall) exposes the inner and outer boundaries.\par

\subsection{cylinder shell diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element body radius} & 1.6cm\\
\texttt{element body height} & 3.4cm\\
\texttt{element inner radius} & 9mm\\
\texttt{element radial thickness} & 1.5mm\\
\texttt{element projection ratio} & 0.25\\
\texttt{element formula label} & dV = 2 pi r h dr\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, body (node), shell or slice (node), formula-anchor\par
\textbf{Families:} body-rim-0..100, shell-outer-rim-0..100, shell-inner-rim-0..100, height-0..100\par
A projected cylinder with a radial cylindrical shell. Components are (C-body) and (C-shell).\par

\subsection{cylinder slice diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element body radius} & 1.6cm\\
\texttt{element body height} & 3.4cm\\
\texttt{element axial thickness} & 2mm\\
\texttt{element position} & 0.55\\
\texttt{element projection ratio} & 0.25\\
\texttt{element axial label} & dz\\
\texttt{element formula label} & dV = pi R squared dz\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, body (node), shell or slice (node), formula-anchor\par
\textbf{Families:} body-rim-0..100, slice-top-rim-0..100, slice-bottom-rim-0..100, height-0..100\par
A projected cylinder with an axial disk slice. Components are (C-body) and (C-slice).\par

\subsection{cone slice diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element body radius} & 1.8cm\\
\texttt{element body height} & 4cm\\
\texttt{element axial thickness} & 2mm\\
\texttt{element position} & 0.58 from apex\\
\texttt{element projection ratio} & 0.24\\
\texttt{element axial label} & dx\\
\texttt{element formula label} & dV = pi r(x) squared dx\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, apex, base, body (node), slice (node), formula-anchor\par
\textbf{Families:} body-rim-0..100, slice-top-rim-0..100, slice-bottom-rim-0..100, height-0..100\par
A projected cone with a thin disk slice. element position is measured from apex to base. Components are (K-body) and (K-slice).\par

\subsection{sheet element diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{element body width} & 5cm\\
\texttt{element body height} & 3cm\\
\texttt{element width} & 8mm\\
\texttt{element height} & 6mm\\
\texttt{element position} & 0.58\\
\texttt{element transverse position} & 0.58\\
\texttt{element formula label} & dA = dx dy\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, body (node), element (node), formula-anchor\par
A rectangular sheet with a named Cartesian element. Components are (A-body) and (A-element).\par

\subsection{solid cylinder (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{solid cylinder radius} & 1cm\\
\texttt{solid cylinder height} & 2.5cm\\
\texttt{solid cylinder depth} & .25\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base-center, top-center, text\par
\textbf{Families:} axis-0..100, bottom-rim-0..100, top-rim-0..100, generator-0..100\par
Projected wireframe: rims start at the right and run counterclockwise; axis and right generator run bottom to top. Depth is ellipse compression, not a 3D camera.\par

\subsection{solid cone (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{solid cone radius} & 1cm\\
\texttt{solid cone height} & 2.5cm\\
\texttt{solid cone depth} & .25\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base-center, top-center, apex, text\par
\textbf{Families:} axis-0..100, bottom-rim-0..100, top-rim-0..100, generator-0..100\par
Projected wireframe: rims start at the right and run counterclockwise; axis and right generator run bottom to top. Depth is ellipse compression, not a 3D camera.\par

\subsection{solid frustum (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{solid frustum radius} & 1cm\\
\texttt{solid frustum height} & 2.5cm\\
\texttt{solid frustum depth} & .25\\
\texttt{solid frustum top ratio} & .5\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base-center, top-center, text\par
\textbf{Families:} axis-0..100, bottom-rim-0..100, top-rim-0..100, generator-0..100\par
Projected wireframe: rims start at the right and run counterclockwise; axis and right generator run bottom to top. Depth is ellipse compression, not a 3D camera.\par

\subsection{cylindrical shell (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{cylindrical shell radius} & 1cm\\
\texttt{cylindrical shell height} & 2.5cm\\
\texttt{cylindrical shell depth} & .25\\
\texttt{cylindrical shell thickness} & .2cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base-center, top-center, text\par
\textbf{Families:} axis-0..100, bottom-rim-0..100, top-rim-0..100, generator-0..100, inner-bottom-rim-0..100, inner-top-rim-0..100\par
Projected wireframe: rims start at the right and run counterclockwise; axis and right generator run bottom to top. Depth is ellipse compression, not a 3D camera.\par

\subsection{conical shell (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{conical shell radius} & 1cm\\
\texttt{conical shell height} & 2.5cm\\
\texttt{conical shell depth} & .25\\
\texttt{conical shell top ratio} & .5\\
\texttt{conical shell thickness} & .2cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base-center, top-center, text\par
\textbf{Families:} axis-0..100, bottom-rim-0..100, top-rim-0..100, generator-0..100, inner-bottom-rim-0..100, inner-top-rim-0..100\par
Projected wireframe: rims start at the right and run counterclockwise; axis and right generator run bottom to top. Depth is ellipse compression, not a 3D camera. Conical shell is a hollow frustum; thickness is radial at the base and scales with top ratio.\par

\subsection{hemisphere (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{hemisphere radius} & 1.2cm\\
\texttt{hemisphere depth} & .25\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, base-center, apex, text\par
\textbf{Families:} rim-0..100, meridian-0..100, axis-0..100\par
Upper hemisphere in wireframe projection; meridian runs left to right over the dome, rim counterclockwise, axis from base centre to apex.\par

\subsection{u tube diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 2cm\\
\texttt{fluid height} & 4cm\\
\texttt{fluid tube width} & .3cm\\
\texttt{fluid left level} & .75\\
\texttt{fluid right level} & .55\\
\texttt{fluid level} & .65\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, left-surface, right-surface, interface, upper-surface\par
Two-liquid U tube. level adds a second liquid only above left level. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{gas manometer (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 1.8cm\\
\texttt{fluid height} & 3.8cm\\
\texttt{fluid tube width} & .3cm\\
\texttt{fluid left level} & .45\\
\texttt{fluid right level} & .8\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, left-surface, right-surface, gas\par
Gas reservoir connected to a U tube. body label names the gas. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{hydraulic press (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 4cm\\
\texttt{fluid height} & 3.5cm\\
\texttt{fluid tube width} & .3cm\\
\texttt{fluid left level} & .4\\
\texttt{fluid right level} & .8\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, large-piston, small-piston\par
Large piston width is 0.32 times width; tube width sets the small piston. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{fluid cylinder diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 1.6cm\\
\texttt{fluid height} & 3.2cm\\
\texttt{fluid level} & .65\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, surface\par
Projected cylinder with an elliptical liquid surface. width is the diameter. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{fluid tank diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 3cm\\
\texttt{fluid height} & 3cm\\
\texttt{fluid left level} & .7\\
\texttt{fluid right level} & .7\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, left-surface, right-surface, surface\par
Open vessel. Equal endpoint levels give a horizontal free surface. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{pressure element diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 2cm\\
\texttt{fluid height} & .65cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right\par
Projected horizontal fluid element with inward pressure forces. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{rotating tube (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 5cm\\
\texttt{fluid height} & .5cm\\
\texttt{fluid tube width} & .3cm\\
\texttt{fluid level} & .48\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, element-left, element-right\par
Horizontal tube with a differential section. level locates its left face along width. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{rotating fluid diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 3cm\\
\texttt{fluid height} & 3.5cm\\
\texttt{fluid level} & .5\\
\texttt{fluid bend} & .35\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, vertex, rim-surface\par
Parabolic surface. level is the vertex height; bend is the wall-to-vertex rise divided by height. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{buoyancy (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 3cm\\
\texttt{fluid height} & 3cm\\
\texttt{fluid left level} & .8\\
\texttt{fluid right level} & .8\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, left-surface, right-surface, surface, body\par
Immersed body with schematic inward pressure arrows. Arrow lengths do not encode pressure magnitude. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{flow tube diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 5cm\\
\texttt{fluid height} & 1.3cm\\
\texttt{fluid bend} & .45\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, inlet, outlet\par
Curved flow tube; outlet height is 0.55 times inlet height. bend controls vertical curvature. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{meniscus diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 1.2cm\\
\texttt{fluid height} & 2.7cm\\
\texttt{fluid level} & .7\\
\texttt{fluid bend} & .2\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, contact-left, contact-right, surface\par
Positive bend is concave; negative bend is convex. Contact angle is measured through the liquid. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{capillary (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 4cm\\
\texttt{fluid height} & 3cm\\
\texttt{fluid level} & .35\\
\texttt{fluid left level} & .7\\
\texttt{fluid bend} & .12\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, contact-left, contact-right, reservoir\par
Capillary rise. level is the reservoir surface and left level is the contact-line height. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{surface tension ring (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 3cm\\
\texttt{fluid height} & 1cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right\par
Projected circular contact line. width and height are the ellipse diameters. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{liquid ring diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 3.5cm\\
\texttt{fluid tube width} & .4cm\\
\texttt{fluid angle} & 225\\
\texttt{fluid sweep} & 70\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, center, bottom, top, left, right, liquid-start, liquid-end\par
Annular liquid sector. width is outer diameter, tube width is radial thickness. Angles use degrees counterclockwise from right. Use (F-origin), (F-center), and the listed (F-...) coordinates; these are pic coordinates, not node anchors.\par

\subsection{fluid tank (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 3cm\\
\texttt{fluid height} & 3cm\\
\texttt{fluid left level} & .7\\
\texttt{fluid right level} & .7\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, left-surface, right-surface, surface, text, base, base east, base west, mid, mid east, mid west\par
\textbf{Families:} surface-0..100, bottom-0..100, right-0..100, left-0..100, bottom-left-0..100, bottom-right-0..100\par
surface runs left to right. bottom, right, left and the two rounded bottom corners follow the drawn outline counterclockwise.\par

\subsection{meniscus (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 1.2cm\\
\texttt{fluid height} & 2.7cm\\
\texttt{fluid level} & .7\\
\texttt{fluid bend} & .2\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, left-surface, right-surface, surface, text, base, base east, base west, mid, mid east, mid west\par
\textbf{Families:} surface-0..100, bottom-0..100, right-0..100, left-0..100\par
surface follows the cubic liquid boundary from left to right. bottom, right and left follow the vessel boundary counterclockwise.\par

\subsection{rotating fluid (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 3cm\\
\texttt{fluid height} & 3.5cm\\
\texttt{fluid level} & .5\\
\texttt{fluid bend} & .35\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, left-surface, right-surface, surface, text, base, base east, base west, mid, mid east, mid west\par
\textbf{Families:} surface-0..100, bottom-0..100, right-0..100, left-0..100\par
surface follows the parabola from left to right. bottom, right and left follow the vessel boundary counterclockwise.\par

\subsection{fluid cylinder (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 1.6cm\\
\texttt{fluid height} & 3.2cm\\
\texttt{fluid level} & .65\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, left-surface, right-surface, surface, text, base, base east, base west, mid, mid east, mid west\par
\textbf{Families:} surface-0..100, surface-rim-0..100, top-0..100, bottom-0..100, right-0..100, left-0..100\par
surface is the left-to-right diameter of the liquid ellipse; surface-rim, top and bottom are full ellipse boundaries, starting at the rightmost point and running counterclockwise. left and right cover the straight walls.\par

\subsection{pressure element (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 2cm\\
\texttt{fluid height} & .65cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, inlet, outlet, text, base, base east, base west, mid, mid east, mid west\par
\textbf{Families:} inlet-0..100, outlet-0..100, inlet-rim-0..100, outlet-rim-0..100, axis-0..100, top-0..100, bottom-0..100\par
inlet and outlet run bottom to top across their projected faces. inlet-rim and outlet-rim run counterclockwise from the rightmost point. axis joins their centres left to right; top and bottom cover the straight outline.\par

\subsection{flow tube (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 5cm\\
\texttt{fluid height} & 1.3cm\\
\texttt{fluid bend} & .45\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, inlet, outlet, text, base, base east, base west, mid, mid east, mid west\par
\textbf{Families:} inlet-0..100, outlet-0..100, axis-0..100, bottom-0..100, top-0..100\par
inlet and outlet run bottom to top; axis follows their curved midline left to right. bottom runs left to right, top right to left on the actual cubic outline. Curve percentages use the cubic parameter.\par

\subsection{liquid ring (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 3.5cm\\
\texttt{fluid tube width} & .4cm\\
\texttt{fluid angle} & 225\\
\texttt{fluid sweep} & 70\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, liquid-start, liquid-end, text, base, base east, base west, mid, mid east, mid west\par
\textbf{Families:} outer-0..100, inner-0..100, liquid-0..100, start-0..100, end-0..100\par
outer and inner run counterclockwise from the rightmost point. liquid follows the filled sector centreline from liquid-start to liquid-end; start and end run radially from inner to outer boundary.\par

\subsection{u tube (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fluid width} & 2cm\\
\texttt{fluid height} & 4cm\\
\texttt{fluid tube width} & .3cm\\
\texttt{fluid left level} & .75\\
\texttt{fluid right level} & .55\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, left-surface, right-surface, surface, text, base, base east, base west, mid, mid east, mid west\par
\textbf{Families:} surface-0..100, left-surface-0..100, right-surface-0..100, outer-0..100, inner-0..100\par
left-surface and right-surface independently run left to right across the liquid in each arm. surface selects the left arm, never the empty gap. outer and inner follow the U outline by distance from the left lip down through the bend to the right lip.\par

\subsection{piston cylinder (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{piston cylinder width} & 1.8cm\\
\texttt{piston cylinder height} & 3cm\\
\texttt{piston position} & .65\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, piston, rod-end, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100, piston-0..100, axis-0..100, wall-left-0..100, wall-right-0..100\par
Piston family is the lower gas-contact face, left to right; position is measured from the bottom. Cylinder top is open.\par

\subsection{capillary tube (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{capillary width} & .5cm\\
\texttt{capillary height} & 3cm\\
\texttt{capillary level} & .6\\
\texttt{capillary sag} & .12cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, surface, text\par
\textbf{Families:} surface-0..100, wall-left-0..100, wall-right-0..100, axis-0..100\par
surface runs left to right by horizontal position. Positive sag gives a concave meniscus; negative sag a convex meniscus. Heights are illustrative, not computed from surface tension.\par

\subsection{nozzle (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{nozzle length} & 4cm\\
\texttt{nozzle diameter} & 1.4cm\\
\texttt{nozzle throat diameter} & .55cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, inlet, outlet, throat, text\par
\textbf{Families:} axis-0..100, top-0..100, bottom-0..100, inlet-0..100, outlet-0..100, throat-0..100\par
Wall families run inlet to outlet by axial position. Cross-sections run bottom to top. Cosine profiles join smoothly; flow is not solved.\par

\subsection{venturi (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{venturi length} & 4cm\\
\texttt{venturi diameter} & 1.4cm\\
\texttt{venturi throat diameter} & .55cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, inlet, outlet, throat, text\par
\textbf{Families:} axis-0..100, top-0..100, bottom-0..100, inlet-0..100, outlet-0..100, throat-0..100\par
Wall families run inlet to outlet by axial position. Cross-sections run bottom to top. Cosine profiles join smoothly; flow is not solved.\par

\subsection{layered tank (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{layered tank width} & 3cm\\
\texttt{layered tank height} & 2.5cm\\
\texttt{layered tank interface} & .35\\
\texttt{layered tank level} & .75\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, lower-center, upper-center, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100, interface-0..100, surface-0..100\par
Two liquid layers; interface and surface run left to right. Separate centre anchors support density labels without color.\par

\subsection{concave-mirror (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{mirror radius} & 5cm\\
\texttt{mirror thickness} & 0.25cm\\
\texttt{mirror aperture angle} & 30 degrees\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, vertex, arc-mid, surface-mid, front-mid, back-mid, front-top, front-bottom, surface-top, surface-bottom, back-top, back-bottom, top, bottom, text\par
\textbf{Families:} surface-0..100, front-0..100, back-0..100, top-0..100, bottom-0..100; legacy .0..100 shorthand also available\par

\subsection{convex-mirror (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{mirror radius} & 5cm\\
\texttt{mirror thickness} & 0.25cm\\
\texttt{mirror aperture angle} & 30 degrees\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, vertex, arc-mid, surface-mid, front-mid, back-mid, front-top, front-bottom, surface-top, surface-bottom, back-top, back-bottom, top, bottom, text\par
\textbf{Families:} surface-0..100, front-0..100, back-0..100, top-0..100, bottom-0..100; legacy .0..100 shorthand also available\par

\subsection{convex-lens (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{convex lens radius} & 5cm\\
\texttt{convex lens thickness} & 0.2cm\\
\texttt{convex lens aperture angle} & 25 degrees\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, front-mid, back-mid, front-top, front-bottom, back-top, back-bottom, top, bottom, text\par
\textbf{Families:} front-0..100, back-0..100, surface-0..100, top-0..100, bottom-0..100; legacy .0..100 shorthand also available\par

\subsection{concave-lens (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{concave lens radius} & 5cm\\
\texttt{concave lens thickness} & 0.2cm\\
\texttt{concave lens aperture angle} & 25 degrees\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, front-mid, back-mid, front-top, front-bottom, back-top, back-bottom, top, bottom, text\par
\textbf{Families:} front-0..100, back-0..100, surface-0..100, top-0..100, bottom-0..100; legacy .0..100 shorthand also available\par

\subsection{slab (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 1.2cm\\
\texttt{minimum height} & 3cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} slab width = minimum width; slab height = minimum height.\par
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, front, back, front-top, front-bottom, back-top, back-bottom, top, bottom, text\par
\textbf{Families:} front-0..100, back-0..100, top-0..100, bottom-0..100, surface-0..100; legacy .0..100 shorthand also available\par

\subsection{prism (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{minimum width} & 3cm\\
\texttt{minimum height} & 2.6cm\\
\texttt{prism apex angle} & derived\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Size aliases:} prism width = minimum width; prism height = minimum height.\par
\textbf{Anchors:} center, centroid, north, south, east, west, north east, north west, south east, south west, apex, base-left, base-right, base-mid, left-mid, right-mid, entry-mid, exit-mid, text\par
\textbf{Families:} base-0..100, right-0..100, left-0..100, surface-0..100, entry-0..100, exit-0..100; legacy .0..100 shorthand also available\par

\subsection{plane-mirror (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{mirror height} & 3cm\\
\texttt{mirror thickness} & 0.25cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top, bottom, front-mid, surface-mid, vertex, back-mid, front-top, front-bottom, surface-top, surface-bottom, back-top, back-bottom, text\par
\textbf{Families:} surface-0..100, front-0..100, back-0..100, top-0..100, bottom-0..100; legacy .0..100 shorthand also available\par

\subsection{plano-convex-lens (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{lens height} & 3cm\\
\texttt{lens thickness} & 0.2cm\\
\texttt{lens front radius} & 5cm\\
\texttt{lens back radius} & 5cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top, bottom, front-mid, surface-mid, vertex, back-mid, front-top, front-bottom, surface-top, surface-bottom, back-top, back-bottom, text\par
\textbf{Families:} surface-0..100, front-0..100, back-0..100, top-0..100, bottom-0..100; legacy .0..100 shorthand also available\par

\subsection{plano-concave-lens (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{lens height} & 3cm\\
\texttt{lens thickness} & 0.2cm\\
\texttt{lens front radius} & 5cm\\
\texttt{lens back radius} & 5cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top, bottom, front-mid, surface-mid, vertex, back-mid, front-top, front-bottom, surface-top, surface-bottom, back-top, back-bottom, text\par
\textbf{Families:} surface-0..100, front-0..100, back-0..100, top-0..100, bottom-0..100; legacy .0..100 shorthand also available\par

\subsection{positive-meniscus-lens (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{lens height} & 3cm\\
\texttt{lens thickness} & 0.2cm\\
\texttt{lens front radius} & 4cm\\
\texttt{lens back radius} & 6cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top, bottom, front-mid, surface-mid, vertex, back-mid, front-top, front-bottom, surface-top, surface-bottom, back-top, back-bottom, text\par
\textbf{Families:} surface-0..100, front-0..100, back-0..100, top-0..100, bottom-0..100; legacy .0..100 shorthand also available\par

\subsection{negative-meniscus-lens (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{lens height} & 3cm\\
\texttt{lens thickness} & 0.2cm\\
\texttt{lens front radius} & 6cm\\
\texttt{lens back radius} & 4cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, top, bottom, front-mid, surface-mid, vertex, back-mid, front-top, front-bottom, surface-top, surface-bottom, back-top, back-bottom, text\par
\textbf{Families:} surface-0..100, front-0..100, back-0..100, top-0..100, bottom-0..100; legacy .0..100 shorthand also available\par

\subsection{transverse wave (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{wave length} & 4cm\\
\texttt{wave amplitude} & .4cm\\
\texttt{wave cycles} & 2\\
\texttt{wave phase} & 0\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, text\par
\textbf{Families:} axis-0..100, curve-0..100\par
Axis runs left to right; curve is a snapshot, not a time simulation.\par

\subsection{standing wave (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{wave length} & 4cm\\
\texttt{wave amplitude} & .4cm\\
\texttt{standing wave lobes} & 3\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, text\par
\textbf{Families:} axis-0..100, curve-0..100\par
Axis runs left to right; curve is a snapshot, not a time simulation. Fixed endpoints. lobes controls half-wavelengths; node-N indexes 0..lobes and antinode-N indexes 0..lobes-1 on the axis.\par

\subsection{longitudinal wave (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{wave length} & 4cm\\
\texttt{wave amplitude} & .4cm\\
\texttt{wave cycles} & 2\\
\texttt{wave coils} & 16\\
\texttt{wave compression} & .65\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, text\par
\textbf{Families:} axis-0..100, curve-0..100\par
Axis runs left to right; curve is a snapshot, not a time simulation. curve follows a schematic variable-spacing spring; compression below 1 prevents reversal of the longitudinal coordinate.\par

\subsection{open pipe (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pipe length} & 4cm\\
\texttt{pipe width} & .8cm\\
\texttt{pipe mode} & 1\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, text\par
\textbf{Families:} axis-0..100, curve-0..100, top-0..100, bottom-0..100\par
Displacement pattern: open ends are antinodes, the closed left end is a node. mode selects harmonics; closed-pipe harmonics are odd. node-N and antinode-N are zero-based ordinal locations on the axis, not percentages.\par

\subsection{closed pipe (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pipe length} & 4cm\\
\texttt{pipe width} & .8cm\\
\texttt{pipe mode} & 1\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, text\par
\textbf{Families:} axis-0..100, curve-0..100, top-0..100, bottom-0..100\par
Displacement pattern: open ends are antinodes, the closed left end is a node. mode selects harmonics; closed-pipe harmonics are odd. node-N and antinode-N are zero-based ordinal locations on the axis, not percentages.\par

\subsection{thermal reservoir (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{reservoir width} & 3cm\\
\texttt{reservoir height} & .8cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, heat-left, heat-right, heat-top, heat-bottom, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par
Physical boundaries run counterclockwise from bottom-left. Heat ports lie at face midpoints. Geometry is schematic; text and temperatures are supplied by the author.\par

\subsection{gas chamber (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{chamber width} & 2.4cm\\
\texttt{chamber height} & 1.8cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, heat-left, heat-right, heat-top, heat-bottom, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par
Physical boundaries run counterclockwise from bottom-left. Heat ports lie at face midpoints. Geometry is schematic; text and temperatures are supplied by the author.\par

\subsection{thermal wall (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{thermal wall width} & .3cm\\
\texttt{thermal wall height} & 2cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, heat-left, heat-right, heat-top, heat-bottom, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par
Physical boundaries run counterclockwise from bottom-left. Heat ports lie at face midpoints. Geometry is schematic; text and temperatures are supplied by the author.\par

\subsection{heat engine (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{thermal device size} & 1.2cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, hot, cold, work, heat-in, heat-out, text\par
\textbf{Families:} rim-0..100\par
hot is the upper port, cold the lower port, work the right port. heat-in and heat-out follow the device role. Arrow directions are supplied by the named diagram pic or by the author.\par

\subsection{refrigerator (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{thermal device size} & 1.2cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, hot, cold, work, heat-in, heat-out, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100\par
hot is the upper port, cold the lower port, work the right port. heat-in and heat-out follow the device role. Arrow directions are supplied by the named diagram pic or by the author.\par

\subsection{isothermal process (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pv width} & 4cm\\
\texttt{pv height} & 3cm\\
\texttt{pv max volume} & 4\\
\texttt{pv max pressure} & 4\\
\texttt{pv start volume} & 1\\
\texttt{pv start pressure} & 3\\
\texttt{pv end volume} & 3\\
\texttt{pv show axes} & true\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, start-volume, end-volume, start-pressure, end-pressure, origin, volume-end, pressure-end, text\par
\textbf{Families:} process-0..100, volume-axis-0..100, pressure-axis-0..100\par
process advances linearly in volume from the start to end state; compression is supported. PV values are unitless numbers in consistent author-chosen units. Axis maxima must contain both endpoints. No heat or work integral is computed.\par

\subsection{isobaric process (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pv width} & 4cm\\
\texttt{pv height} & 3cm\\
\texttt{pv max volume} & 4\\
\texttt{pv max pressure} & 4\\
\texttt{pv start volume} & 1\\
\texttt{pv start pressure} & 3\\
\texttt{pv end volume} & 3\\
\texttt{pv show axes} & true\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, start-volume, end-volume, start-pressure, end-pressure, origin, volume-end, pressure-end, text\par
\textbf{Families:} process-0..100, volume-axis-0..100, pressure-axis-0..100\par
process advances linearly in volume from the start to end state; compression is supported. PV values are unitless numbers in consistent author-chosen units. Axis maxima must contain both endpoints. No heat or work integral is computed.\par

\subsection{isochoric process (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pv width} & 4cm\\
\texttt{pv height} & 3cm\\
\texttt{pv max volume} & 4\\
\texttt{pv max pressure} & 4\\
\texttt{pv start volume} & 1\\
\texttt{pv start pressure} & 3\\
\texttt{pv end pressure} & 1.5\\
\texttt{pv show axes} & true\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, start-volume, end-volume, start-pressure, end-pressure, origin, volume-end, pressure-end, text\par
\textbf{Families:} process-0..100, volume-axis-0..100, pressure-axis-0..100\par
process advances linearly in pressure at fixed volume. PV values are unitless numbers in consistent author-chosen units. Axis maxima must contain both endpoints. No heat or work integral is computed.\par

\subsection{adiabatic process (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pv width} & 4cm\\
\texttt{pv height} & 3cm\\
\texttt{pv max volume} & 4\\
\texttt{pv max pressure} & 4\\
\texttt{pv start volume} & 1\\
\texttt{pv start pressure} & 3\\
\texttt{pv end volume} & 3\\
\texttt{pv gamma} & 1.4\\
\texttt{pv show axes} & true\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, start-volume, end-volume, start-pressure, end-pressure, origin, volume-end, pressure-end, text\par
\textbf{Families:} process-0..100, volume-axis-0..100, pressure-axis-0..100\par
process advances linearly in volume from the start to end state; compression is supported. PV values are unitless numbers in consistent author-chosen units. Axis maxima must contain both endpoints. No heat or work integral is computed. This is the reversible ideal-gas relation pressure times volume to the gamma power is constant with gamma > 1.\par

\subsection{polytropic process (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pv width} & 4cm\\
\texttt{pv height} & 3cm\\
\texttt{pv max volume} & 4\\
\texttt{pv max pressure} & 4\\
\texttt{pv start volume} & 1\\
\texttt{pv start pressure} & 3\\
\texttt{pv end volume} & 3\\
\texttt{pv exponent} & 1.2\\
\texttt{pv show axes} & true\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, start, end, start-volume, end-volume, start-pressure, end-pressure, origin, volume-end, pressure-end, text\par
\textbf{Families:} process-0..100, volume-axis-0..100, pressure-axis-0..100\par
process advances linearly in volume from the start to end state; compression is supported. PV values are unitless numbers in consistent author-chosen units. Axis maxima must contain both endpoints. No heat or work integral is computed.\par

\subsection{rectangular cycle (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pv width} & 4cm\\
\texttt{pv height} & 3cm\\
\texttt{pv max volume} & 4\\
\texttt{pv max pressure} & 4\\
\texttt{pv low volume} & 1\\
\texttt{pv high volume} & 3\\
\texttt{pv low pressure} & 1\\
\texttt{pv high pressure} & 3\\
\texttt{pv show axes} & true\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, state-A, state-B, state-C, state-D, state-A-volume, state-A-pressure, state-B-volume, state-B-pressure, state-C-volume, state-C-pressure, state-D-volume, state-D-pressure, origin, volume-end, pressure-end, text\par
\textbf{Families:} AB-0..100, BC-0..100, CD-0..100, DA-0..100, volume-axis-0..100, pressure-axis-0..100\par
Clockwise A-B-C-D cycle. Branch percentages are linear in the changing coordinate. A is low-volume low-pressure; B high-pressure; C high-volume high-pressure; D low-pressure.\par

\subsection{carnot cycle (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pv width} & 4cm\\
\texttt{pv height} & 3cm\\
\texttt{pv max volume} & 4\\
\texttt{pv max pressure} & 4\\
\texttt{pv start volume} & 1\\
\texttt{carnot hot constant} & 3\\
\texttt{carnot temperature ratio} & .75\\
\texttt{carnot expansion ratio} & 1.5\\
\texttt{pv gamma} & 1.4\\
\texttt{pv show axes} & true\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, state-A, state-B, state-C, state-D, state-A-volume, state-A-pressure, state-B-volume, state-B-pressure, state-C-volume, state-C-pressure, state-D-volume, state-D-pressure, origin, volume-end, pressure-end, text\par
\textbf{Families:} hot-0..100, expansion-0..100, cold-0..100, compression-0..100, volume-axis-0..100, pressure-axis-0..100\par
Reversible ideal-gas Carnot cycle: hot A-B isotherm, B-C adiabatic expansion, cold C-D isotherm, D-A adiabatic compression. Cold/hot is an absolute-temperature ratio; hot constant is P\_A V\_A. Branch percentages interpolate volume, not arc length. States are derived to close exactly.\par

\subsection{pv diagram (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{pv width} & 4cm\\
\texttt{pv height} & 3cm\\
\texttt{pv max volume} & 4\\
\texttt{pv max pressure} & 4\\
\texttt{pv show axes} & true\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, origin, volume-end, pressure-end, text\par
\textbf{Families:} volume-axis-0..100, pressure-axis-0..100\par
Empty PV axes frame. Overlay process nodes at the same center with matching axis keys and pv show axes=false; the axes and projection anchors remain available.\par

\subsection{heat engine diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{thermo diagram separation} & 2cm\\
\texttt{thermo diagram work length} & 1.5cm\\
\texttt{reservoir width} & 3cm\\
\texttt{reservoir height} & .8cm\\
\texttt{thermal device size} & 1.2cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, hot (node), cold (node), device (node), work\par
\textbf{Families:} heat-hot-0..100, heat-cold-0..100, work-0..100\par
Heat enters from the hot reservoir, part leaves as work, and the remainder reaches the cold reservoir. Named child nodes use the pic prefix. Flow coordinate families heat-hot, heat-cold and work run from arrow tail to head; use the pic prefix and integer percentages.\par

\subsection{refrigerator diagram (pic)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{thermo diagram separation} & 2cm\\
\texttt{thermo diagram work length} & 1.5cm\\
\texttt{reservoir width} & 3cm\\
\texttt{reservoir height} & .8cm\\
\texttt{thermal device size} & 1.2cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} origin, hot (node), cold (node), device (node), work\par
\textbf{Families:} heat-hot-0..100, heat-cold-0..100, work-0..100\par
Work enters the device, heat is absorbed from the cold reservoir, and heat is rejected to the hot reservoir. Labels are magnitudes supplied by the author.\par

\subsection{conduction slab (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{conduction width} & 3cm\\
\texttt{conduction height} & 2cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, heat-left, heat-right, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100, axis-0..100\par
Boundary families run counterclockwise; axis runs left to right. Heat flux and temperatures are author annotations; no conductivity law is solved.\par

\subsection{composite wall (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{composite width} & 3cm\\
\texttt{composite height} & 2cm\\
\texttt{composite split} & .45\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, heat-left, heat-right, layer-1-center, layer-2-center, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100, axis-0..100, interface-0..100\par
Boundary families run counterclockwise; axis runs left to right. Heat flux and temperatures are author annotations; no conductivity law is solved.\par

\subsection{convection surface (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{thermal plate width} & 3.6cm\\
\texttt{thermal plate thickness} & .25cm\\
\texttt{thermal fluid height} & 1.2cm\\
\texttt{thermal flow direction} & 1\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, plate-center, fluid-center, heat-start, heat-end, text\par
\textbf{Families:} surface-0..100, bottom-0..100, right-0..100, left-0..100, flow-0..100\par
surface runs left to right on the plate-fluid interface. flow follows the central schematic heat-transfer arrow, outward for +1 and inward for -1. Arrow lengths do not encode h or heat flux.\par

\subsection{cooling fin (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{fin length} & 3cm\\
\texttt{fin base height} & 1cm\\
\texttt{fin base thickness} & .25cm\\
\texttt{fin thickness} & .18cm\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, root, tip, heat-left, text\par
\textbf{Families:} base-0..100, axis-0..100, fin-bottom-0..100, fin-tip-0..100, fin-top-0..100\par
One extended fin attached to a base. axis runs root to tip; fin boundary follows bottom, tip and top counterclockwise. Fin length includes base thickness. Temperatures and distributed convection are author annotations.\par

\subsection{radiating body (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{radiation radius} & .65cm\\
\texttt{radiation ray length} & .8cm\\
\texttt{thermal flow direction} & 1\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, heat-start, heat-end, text\par
\textbf{Families:} rim-0..100, ray-0..100\par
rim runs counterclockwise from the rightmost point. ray follows the rightward emission arrow or the inward absorption arrow. Rays are schematic and do not solve a Stefan-Boltzmann balance.\par

\subsection{thermometer (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{thermometer height} & 3.2cm\\
\texttt{thermometer bulb radius} & .32cm\\
\texttt{thermometer stem width} & .18cm\\
\texttt{thermometer level} & .6\\
\texttt{thermal liquid color} & black\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, bulb-center, liquid-top, scale-start, scale-end, text\par
\textbf{Families:} scale-0..100, column-0..100, bulb-0..100, stem-right-0..100, cap-0..100, stem-left-0..100\par
level is a geometric stem fraction, not a calibrated temperature. scale runs from bulb top toward stem cap; column runs from bulb centre to liquid-top. bulb follows the exposed outline counterclockwise from the left stem join through the bottom to the right stem join. Stem sides and cap expose the remaining boundary.\par

\subsection{calorimeter (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{calorimeter width} & 3cm\\
\texttt{calorimeter height} & 2.6cm\\
\texttt{calorimeter insulation} & .25cm\\
\texttt{calorimeter level} & .55\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, liquid-center, headspace-center, liquid-left, liquid-right, text\par
\textbf{Families:} bottom-0..100, right-0..100, top-0..100, left-0..100, lid-0..100, surface-0..100, inner-bottom-0..100\par
Double-wall calorimeter with schematic insulation spacing and a liquid surface. Boundary families run counterclockwise; lid and surface run left to right. No heat capacity or mixing temperature is computed.\par

\subsection{expansion rod (node)}
\begin{tabularx}{\linewidth}{@{}p{.45\linewidth}X@{}}
\toprule Key & Default \\
\midrule
\texttt{expansion rod length} & 3cm\\
\texttt{expansion rod thickness} & .16cm\\
\texttt{expansion separation} & .65cm\\
\texttt{thermal expansion ratio} & 1.1\\
\bottomrule\end{tabularx}\par\smallskip
\textbf{Anchors:} center, north, south, east, west, north east, north west, south east, south west, original-start, original-end, expanded-start, expanded-end, text\par
\textbf{Families:} original-0..100, expanded-0..100\par
Original rod is below; changed rod above. Both families run left to right along their axes with a shared left reference. Ratio sets changed/original length; values below one show contraction. Strain is supplied by the author.\par

% END GENERATED REFERENCE

\section{License}

Copyright \textcopyright\ 2026 Vaibhav Blayer.

This work may be distributed and/or modified under the conditions of the
LaTeX Project Public License, either version 1.3c or (at your option) any later
version. This work has LPPL maintenance status ``maintained''. The Current
Maintainer is Vaibhav Blayer.

\end{document}
