CookbookHobbies and playNo. 56
A car restoration build bookparts, specifications and the decisions behind them
See it in know.sh
A disc brake caliper, in section
Drag the pedal and watch the pads close on the disc; switch between a floating and a fixed caliper, wear the pads down, and step through what happens from pedal to release. Clearances are drawn ten times larger than life; the figures assume a 4:1 pedal, a 22 mm master cylinder, a 0.4 pad coefficient and a 1,400 kg car.
<div class="brake">
<svg viewBox="0 0 660 330" role="img" aria-labelledby="brake-desc">
<desc id="brake-desc">Cross-section of a disc brake caliper beside a face-on view of the disc. The labels and figures below it describe the same state in words.</desc>
<defs>
<pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" class="hatch"/></pattern>
<pattern id="fluid" width="6" height="6" patternUnits="userSpaceOnUse"><circle cx="3" cy="3" r="1" class="dot"/></pattern>
<pattern id="friction" width="4" height="4" patternUnits="userSpaceOnUse"><rect width="4" height="4" class="grit"/><circle cx="1" cy="1" r=".8" class="dot"/><circle cx="3" cy="3" r=".8" class="dot"/></pattern>
<marker id="head" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0 10 5 0 10z" class="headfill"/></marker>
</defs>
<g data-part="bracket">
<rect x="150" y="10" width="300" height="8" class="fixed"/>
<line x1="170" y1="14" x2="430" y2="14" class="pin"/>
<text x="155" y="34" class="lab">Bracket and slide pins, bolted to the knuckle</text>
</g>
<g id="body" data-part="body">
<path id="bodyShape" class="body" fill="url(#hatch)"/>
</g>
<g data-part="fluid"><rect id="fluid" y="138" height="64" fill="url(#fluid)" class="fluidbox"/></g>
<g data-part="fluid"><path id="hose" class="hose"/></g>
<g data-part="piston"><rect id="pistonL" y="140" height="60" class="piston"/><rect id="pistonR" y="140" height="60" class="piston"/></g>
<g data-part="seal"><path id="sealL" class="seal"/><path id="sealR" class="seal"/></g>
<g data-part="pads">
<rect id="padInBack" y="112" width="6" height="116" class="backing"/>
<rect id="padIn" y="118" height="104" fill="url(#friction)" class="padface"/>
<rect id="padOutBack" y="112" width="6" height="116" class="backing"/>
<rect id="padOut" y="118" height="104" fill="url(#friction)" class="padface"/>
</g>
<g data-part="disc">
<rect x="318" y="60" width="24" height="230" class="disc"/>
<text x="330" y="310" text-anchor="middle" class="lab">Disc</text>
</g>
<g id="arrows" class="arrows">
<line id="clampIn" y1="170" y2="170" marker-end="url(#head)"/>
<line id="clampOut" y1="170" y2="170" marker-end="url(#head)"/>
</g>
<text x="200" y="92" class="lab">Caliper body</text>
<text x="372" y="256" class="lab">Pads</text>
<text x="36" y="306" class="lab">Inboard (car side)</text>
<text x="420" y="306" class="lab" text-anchor="end">Outboard</text>
<text x="40" y="258" class="lab">Piston and square seal</text>
<g transform="translate(560 170)">
<g id="rotor" data-part="disc">
<circle r="84" class="discface"/>
<circle r="30" class="hub"/>
<g id="vents"></g>
</g>
<path d="M-34 -96 A100 100 0 0 1 34 -96 L26 -70 A74 74 0 0 0 -26 -70 Z" class="padarc" fill="url(#friction)" data-part="pads"/>
<line id="frictionArrow" x1="-40" y1="-110" x2="40" y2="-110" marker-end="url(#head)" class="arrow"/>
<text y="120" text-anchor="middle" class="lab">Face on</text>
</g>
</svg>
<div class="controls">
<label>Pedal force <b id="pedalOut">0 N</b><input id="pedal" type="range" min="0" max="400" step="5" value="0"></label>
<label>Pad left <b id="wearOut">10 mm</b><input id="wear" type="range" min="2" max="10" step="0.5" value="10"></label>
<div class="switches">
<button type="button" id="kind" aria-pressed="false">Fixed caliper</button>
<button type="button" id="boost" aria-pressed="true">Booster on</button>
<button type="button" id="drive">Drive at 100 km/h</button>
</div>
</div>
<dl class="figures">
<div><dt>Line pressure</dt><dd id="pOut">0 bar</dd></div>
<div><dt>Clamp force</dt><dd id="fOut">0 kN</dd></div>
<div><dt>Friction at the pads</dt><dd id="frOut">0 kN</dd></div>
<div><dt>Brake torque, one wheel</dt><dd id="tOut">0 N·m</dd></div>
<div><dt>Car</dt><dd id="vOut">100 km/h</dd></div>
</dl>
<p class="say" id="say" aria-live="polite"></p>
<div class="walk">
<button type="button" id="prev">Back</button>
<span id="stepNo">Walk through</span>
<button type="button" id="next">Next</button>
</div>
<p class="step" id="stepText"></p>
</div>.brake svg { display: block; width: 100%; height: auto; }
.brake text { font: 400 11px var(--sans); fill: var(--ink-2); }
.lab { font-size: 11px; }
.hatch { stroke: var(--ink-3); stroke-width: 1; }
.dot { fill: var(--ink-2); }
.grit { fill: var(--wash); }
.headfill { fill: var(--ink); }
.fixed { fill: var(--wash); stroke: var(--ink); stroke-width: 1; }
.pin { stroke: var(--ink); stroke-width: 3; }
.body { stroke: var(--ink); stroke-width: 1.5; }
.fluidbox { stroke: none; }
.hose { fill: none; stroke: var(--ink); stroke-width: 6; }
.piston { fill: var(--paper); stroke: var(--ink); stroke-width: 1.5; }
.seal { fill: var(--ink); }
.backing { fill: var(--ink); }
.padface { stroke: var(--ink); stroke-width: 1; }
.disc { fill: var(--paper); stroke: var(--ink); stroke-width: 1.5; }
.discface { fill: var(--paper); stroke: var(--ink); stroke-width: 1.5; }
.hub { fill: var(--wash); stroke: var(--ink); stroke-width: 1; }
.vent { stroke: var(--ink-3); stroke-width: 1.5; }
.padarc { stroke: var(--ink); stroke-width: 1; }
.arrows line, .arrow { stroke: var(--ink); stroke-width: 2; }
[data-part] { transition: opacity 120ms; }
.brake.focus [data-part] { opacity: .22; }
.brake.focus [data-part].on { opacity: 1; }
.controls { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 24px; margin-top: 10px; font: 400 14px/1.3 var(--sans); }
.controls label { display: grid; gap: 4px; }
.controls b { font-weight: 600; font-variant-numeric: tabular-nums; }
.controls input { width: 100%; accent-color: var(--ink); }
.switches { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; }
button { font: 500 14px/1 var(--sans); color: var(--ink); background: var(--paper); border: 1px solid var(--ink); border-radius: 0; padding: 10px 12px; min-height: 40px; cursor: pointer; }
button[aria-pressed='true'] { background: var(--ink); color: var(--paper); }
button:focus-visible, input:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); gap: 0 18px; margin: 14px 0 0; border-top: 1px solid var(--ink); }
.figures div { padding: 7px 0; border-bottom: 1px solid var(--rule); }
.figures dt { font: 400 12.5px/1.3 var(--sans); color: var(--ink-3); }
.figures dd { margin: 2px 0 0; font: 400 20px/1.2 var(--serif); font-variant-numeric: tabular-nums; }
.say { min-height: 1.4em; margin: 8px 0 0; font: italic 400 16px/1.45 var(--serif); }
.walk { display: flex; align-items: center; gap: 12px; margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--rule); font: 400 13px var(--sans); color: var(--ink-3); }
.walk span { flex: 1; text-align: center; }
.step { min-height: 3em; margin: 8px 0 0; font: 400 16px/1.5 var(--serif); }
@media (max-width: 520px) { .controls { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { [data-part] { transition: none; } }(function () {
var $ = function (id) { return document.getElementById(id); };
var root = document.querySelector('.brake');
// Millimetres to drawing units; the running clearance is drawn ten times larger than life.
var MM = 2.2, CLEAR = 0.15 * 10 * MM, DISC_L = 318, DISC_R = 342, BACK = 6;
var PEDAL_RATIO = 4, BOOST = 3, MC_BORE = 22, MU = 0.4, R_EFF = 0.13, TYRE_R = 0.31, MASS = 1400, REAR_SHARE = 0.6, GRIP = 9.81;
var CALIPERS = {
floating: { name: 'floating', pistonBore: 54, pistons: 1 },
fixed: { name: 'fixed', pistonBore: 40, pistons: 2 }
};
var state = { pedal: 0, wear: 10, kind: 'floating', boost: true, v: 100, step: -1 };
var area = function (d) { return Math.PI * d * d / 4; };
function physics() {
var cal = CALIPERS[state.kind];
var force = state.pedal * PEDAL_RATIO * (state.boost ? BOOST : 1);
var p = force / area(MC_BORE); // N/mm² = MPa
var pistonArea = area(cal.pistonBore) * cal.pistons; // per side, mm²
var clamp = p > 0.05 ? p * pistonArea : 0; // N, on each pad
var friction = 2 * MU * clamp; // two faces
var torque = friction * R_EFF; // N·m
var decel = torque * 2 * (1 + REAR_SHARE) / (TYRE_R * MASS); // m/s², front pair plus a lighter rear pair
return { p: p, clamp: clamp, friction: friction, torque: torque, decel: decel, locked: decel > GRIP };
}
function layout(ph) {
var fixed = state.kind === 'fixed';
var pad = state.wear * MM, contact = ph.clamp > 0 ? 1 : 0, wearTake = (10 - state.wear) * MM;
var inFace = DISC_L - CLEAR * (1 - contact); // inner pad's friction face
var outFace = DISC_R + CLEAR * (1 - contact);
var padInX = inFace - pad, backInX = padInX - BACK;
var padOutX = outFace, backOutX = padOutX + pad;
// A floating body is pulled inboard by as much as the outer pad needs; a fixed body never moves.
var shift = fixed ? 0 : -(wearTake + CLEAR * contact);
$('padIn').setAttribute('x', padInX); $('padIn').setAttribute('width', pad);
$('padInBack').setAttribute('x', backInX);
$('padOut').setAttribute('x', padOutX); $('padOut').setAttribute('width', pad);
$('padOutBack').setAttribute('x', backOutX);
var leftWall = 175 + shift, rightWall = backOutX + BACK;
var pistonX = Math.min(leftWall + 40, backInX - 70);
$('pistonL').setAttribute('x', pistonX); $('pistonL').setAttribute('width', backInX - pistonX);
var fluidX = leftWall + 12, fluidW = Math.max(4, pistonX - fluidX);
$('fluid').setAttribute('x', fluidX); $('fluid').setAttribute('width', fluidW);
var body;
if (fixed) {
var rWall = backOutX + BACK + 70;
$('pistonR').style.display = '';
$('pistonR').setAttribute('x', backOutX + BACK); $('pistonR').setAttribute('width', rWall - 12 - (backOutX + BACK));
body = 'M' + leftWall + ' 100 H' + (backInX - 4) + ' V60 H' + (backOutX + BACK + 4) + ' V100 H' + rWall + ' V240 H' + (backOutX + BACK + 4) + ' V230 H' + (backOutX + BACK) + ' V110 H' + (backInX) + ' V230 H' + (backInX - 4) + ' V240 H' + leftWall + ' Z';
} else {
$('pistonR').style.display = 'none';
body = 'M' + leftWall + ' 100 H' + (backInX - 4) + ' V60 H' + (rightWall + 26) + ' V240 H' + rightWall + ' V112 H' + (backInX) + ' V230 H' + (backInX - 4) + ' V240 H' + leftWall + ' Z';
}
$('bodyShape').setAttribute('d', body);
var sealX = pistonX + 18, tilt = contact ? 4 : 0;
$('sealL').setAttribute('d', 'M' + sealX + ' 134 l8 ' + (-tilt) + ' v6 l-8 ' + tilt + ' z M' + sealX + ' 206 l8 ' + tilt + ' v-6 l-8 ' + (-tilt) + ' z');
$('sealR').setAttribute('d', fixed ? 'M' + (backOutX + BACK + 40) + ' 134 l-8 ' + (-tilt) + ' v6 l8 ' + tilt + ' z' : '');
$('hose').setAttribute('d', 'M20 170 H' + (fluidX + 2));
var len = Math.min(70, 8 + ph.clamp / 500);
var show = ph.clamp > 0 ? '' : 'none';
$('clampIn').style.display = show; $('clampOut').style.display = show;
$('clampIn').setAttribute('x1', backInX - len - 8); $('clampIn').setAttribute('x2', backInX - 6);
$('clampOut').setAttribute('x1', backOutX + BACK + len + 30); $('clampOut').setAttribute('x2', backOutX + BACK + 24);
$('frictionArrow').style.display = ph.clamp > 0 && state.v > 0 ? '' : 'none';
}
function fmt(n, d) { return n.toLocaleString('en-GB', { maximumFractionDigits: d, minimumFractionDigits: d }); }
function figures(ph) {
$('pedalOut').textContent = state.pedal + ' N';
$('wearOut').textContent = fmt(state.wear, 1).replace('.0', '') + ' mm';
$('pOut').textContent = fmt(ph.p * 10, 0) + ' bar';
$('fOut').textContent = fmt(ph.clamp / 1000, 1) + ' kN';
$('frOut').textContent = fmt(ph.friction / 1000, 1) + ' kN';
$('tOut').textContent = fmt(ph.torque, 0) + ' N·m';
$('vOut').textContent = fmt(state.v, 0) + ' km/h';
var msg = '';
if (state.v <= 0 && state.pedal > 0) msg = 'Stopped.';
else if (ph.locked && state.v > 0) msg = 'The brakes ask for ' + fmt(ph.decel / 9.81, 1) + ' g; the tyres give about 1 g. Without ABS the wheels lock and slide.';
else if (ph.clamp > 0) msg = 'Slowing at ' + fmt(ph.decel / 9.81, 2) + ' g.';
else if (state.v > 0) msg = 'Rolling. Press the pedal.';
$('say').textContent = msg;
}
var STEPS = [
['bracket', 'The bracket is bolted to the steering knuckle and never moves. The caliper body rides on two greased slide pins fixed to it.'],
['fluid', 'The pedal pushes the master cylinder. Brake fluid does not compress, so the pressure it makes arrives unchanged in the caliper bore: pressure equals force over the master cylinder\'s area.'],
['piston', 'That pressure acts on the piston\'s much larger face. Clamp force is pressure times piston area, which is where the hydraulic advantage comes from: a 54 mm piston has six times the area of a 22 mm master cylinder bore.'],
['body', 'In a floating caliper the piston pushes the inner pad onto the disc; the reaction slides the whole body inboard on its pins, pulling the outer pad against the other face. A fixed caliper has pistons on both sides and its body does not move.'],
['pads', 'Both pads rub the disc. Friction is twice (two faces) the pad coefficient times the clamp force, and braking torque is that friction times the effective radius, here 130 mm.'],
['seal', 'On release, the square-section seal, twisted as the piston moved, springs back and draws the piston a fraction of a millimetre away from the pad. That is the running clearance; as the pads wear the piston slides further through the seal, and the fluid in the bore makes up the difference.']
];
function showStep() {
var s = state.step;
root.classList.toggle('focus', s >= 0);
root.querySelectorAll('[data-part]').forEach(function (el) { el.classList.toggle('on', s >= 0 && el.getAttribute('data-part') === STEPS[s][0]); });
$('stepNo').textContent = s < 0 ? 'Walk through' : 'Step ' + (s + 1) + ' of ' + STEPS.length;
$('stepText').textContent = s < 0 ? '' : STEPS[s][1];
$('prev').disabled = s < 0; $('next').textContent = s === STEPS.length - 1 ? 'Done' : 'Next';
}
function render() { var ph = physics(); layout(ph); figures(ph); return ph; }
var angle = 0, last = 0;
(function vents() {
var g = $('vents'), out = '';
for (var i = 0; i < 12; i++) { var a = i * Math.PI / 6; out += '<line class="vent" x1="' + (Math.cos(a) * 42) + '" y1="' + (Math.sin(a) * 42) + '" x2="' + (Math.cos(a) * 76) + '" y2="' + (Math.sin(a) * 76) + '"/>'; }
g.innerHTML = out;
})();
function tick(t) {
var dt = Math.min(0.05, (t - last) / 1000 || 0); last = t;
var ph = physics();
if (state.v > 0 && ph.clamp > 0) state.v = Math.max(0, state.v - Math.min(ph.decel, GRIP) * dt * 3.6);
var omega = (state.v / 3.6) / TYRE_R; // rad/s
angle = (angle + omega * dt * 57.3 * 0.25) % 360; // drawn at a quarter speed, so it can be seen
$('rotor').setAttribute('transform', 'rotate(' + angle + ')');
figures(ph);
requestAnimationFrame(tick);
}
$('pedal').addEventListener('input', function (e) { state.pedal = Number(e.target.value); render(); });
$('wear').addEventListener('input', function (e) { state.wear = Number(e.target.value); render(); });
$('kind').addEventListener('click', function () { state.kind = state.kind === 'fixed' ? 'floating' : 'fixed'; this.setAttribute('aria-pressed', String(state.kind === 'fixed')); render(); });
$('boost').addEventListener('click', function () { state.boost = !state.boost; this.setAttribute('aria-pressed', String(state.boost)); this.textContent = state.boost ? 'Booster on' : 'Booster off'; render(); });
$('drive').addEventListener('click', function () { state.v = 100; render(); });
$('next').addEventListener('click', function () { state.step = state.step >= STEPS.length - 1 ? -1 : state.step + 1; showStep(); });
$('prev').addEventListener('click', function () { state.step = Math.max(-1, state.step - 1); showStep(); });
render(); showStep(); requestAnimationFrame(tick);
})();```element widget
{
"title": "A disc brake caliper, in section",
"caption": "Drag the pedal and watch the pads close on the disc; switch between a floating and a fixed caliper, wear the pads down, and step through what happens from pedal to release. Clearances are drawn ten times larger than life; the figures assume a 4:1 pedal, a 22 mm master cylinder, a 0.4 pad coefficient and a 1,400 kg car.",
"height": 720,
"html": "<div class=\"brake\">\n <svg viewBox=\"0 0 660 330\" role=\"img\" aria-labelledby=\"brake-desc\">\n <desc id=\"brake-desc\">Cross-section of a disc brake caliper beside a face-on view of the disc. The labels and figures below it describe the same state in words.</desc>\n <defs>\n <pattern id=\"hatch\" width=\"6\" height=\"6\" patternUnits=\"userSpaceOnUse\" patternTransform=\"rotate(45)\"><line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"6\" class=\"hatch\"/></pattern>\n <pattern id=\"fluid\" width=\"6\" height=\"6\" patternUnits=\"userSpaceOnUse\"><circle cx=\"3\" cy=\"3\" r=\"1\" class=\"dot\"/></pattern>\n <pattern id=\"friction\" width=\"4\" height=\"4\" patternUnits=\"userSpaceOnUse\"><rect width=\"4\" height=\"4\" class=\"grit\"/><circle cx=\"1\" cy=\"1\" r=\".8\" class=\"dot\"/><circle cx=\"3\" cy=\"3\" r=\".8\" class=\"dot\"/></pattern>\n <marker id=\"head\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 10 5 0 10z\" class=\"headfill\"/></marker>\n </defs>\n\n <g data-part=\"bracket\">\n <rect x=\"150\" y=\"10\" width=\"300\" height=\"8\" class=\"fixed\"/>\n <line x1=\"170\" y1=\"14\" x2=\"430\" y2=\"14\" class=\"pin\"/>\n <text x=\"155\" y=\"34\" class=\"lab\">Bracket and slide pins, bolted to the knuckle</text>\n </g>\n\n <g id=\"body\" data-part=\"body\">\n <path id=\"bodyShape\" class=\"body\" fill=\"url(#hatch)\"/>\n </g>\n\n <g data-part=\"fluid\"><rect id=\"fluid\" y=\"138\" height=\"64\" fill=\"url(#fluid)\" class=\"fluidbox\"/></g>\n <g data-part=\"fluid\"><path id=\"hose\" class=\"hose\"/></g>\n\n <g data-part=\"piston\"><rect id=\"pistonL\" y=\"140\" height=\"60\" class=\"piston\"/><rect id=\"pistonR\" y=\"140\" height=\"60\" class=\"piston\"/></g>\n <g data-part=\"seal\"><path id=\"sealL\" class=\"seal\"/><path id=\"sealR\" class=\"seal\"/></g>\n\n <g data-part=\"pads\">\n <rect id=\"padInBack\" y=\"112\" width=\"6\" height=\"116\" class=\"backing\"/>\n <rect id=\"padIn\" y=\"118\" height=\"104\" fill=\"url(#friction)\" class=\"padface\"/>\n <rect id=\"padOutBack\" y=\"112\" width=\"6\" height=\"116\" class=\"backing\"/>\n <rect id=\"padOut\" y=\"118\" height=\"104\" fill=\"url(#friction)\" class=\"padface\"/>\n </g>\n\n <g data-part=\"disc\">\n <rect x=\"318\" y=\"60\" width=\"24\" height=\"230\" class=\"disc\"/>\n <text x=\"330\" y=\"310\" text-anchor=\"middle\" class=\"lab\">Disc</text>\n </g>\n\n <g id=\"arrows\" class=\"arrows\">\n <line id=\"clampIn\" y1=\"170\" y2=\"170\" marker-end=\"url(#head)\"/>\n <line id=\"clampOut\" y1=\"170\" y2=\"170\" marker-end=\"url(#head)\"/>\n </g>\n\n <text x=\"200\" y=\"92\" class=\"lab\">Caliper body</text>\n <text x=\"372\" y=\"256\" class=\"lab\">Pads</text>\n <text x=\"36\" y=\"306\" class=\"lab\">Inboard (car side)</text>\n <text x=\"420\" y=\"306\" class=\"lab\" text-anchor=\"end\">Outboard</text>\n <text x=\"40\" y=\"258\" class=\"lab\">Piston and square seal</text>\n\n <g transform=\"translate(560 170)\">\n <g id=\"rotor\" data-part=\"disc\">\n <circle r=\"84\" class=\"discface\"/>\n <circle r=\"30\" class=\"hub\"/>\n <g id=\"vents\"></g>\n </g>\n <path d=\"M-34 -96 A100 100 0 0 1 34 -96 L26 -70 A74 74 0 0 0 -26 -70 Z\" class=\"padarc\" fill=\"url(#friction)\" data-part=\"pads\"/>\n <line id=\"frictionArrow\" x1=\"-40\" y1=\"-110\" x2=\"40\" y2=\"-110\" marker-end=\"url(#head)\" class=\"arrow\"/>\n <text y=\"120\" text-anchor=\"middle\" class=\"lab\">Face on</text>\n </g>\n </svg>\n\n <div class=\"controls\">\n <label>Pedal force <b id=\"pedalOut\">0 N</b><input id=\"pedal\" type=\"range\" min=\"0\" max=\"400\" step=\"5\" value=\"0\"></label>\n <label>Pad left <b id=\"wearOut\">10 mm</b><input id=\"wear\" type=\"range\" min=\"2\" max=\"10\" step=\"0.5\" value=\"10\"></label>\n <div class=\"switches\">\n <button type=\"button\" id=\"kind\" aria-pressed=\"false\">Fixed caliper</button>\n <button type=\"button\" id=\"boost\" aria-pressed=\"true\">Booster on</button>\n <button type=\"button\" id=\"drive\">Drive at 100 km/h</button>\n </div>\n </div>\n\n <dl class=\"figures\">\n <div><dt>Line pressure</dt><dd id=\"pOut\">0 bar</dd></div>\n <div><dt>Clamp force</dt><dd id=\"fOut\">0 kN</dd></div>\n <div><dt>Friction at the pads</dt><dd id=\"frOut\">0 kN</dd></div>\n <div><dt>Brake torque, one wheel</dt><dd id=\"tOut\">0 N·m</dd></div>\n <div><dt>Car</dt><dd id=\"vOut\">100 km/h</dd></div>\n </dl>\n <p class=\"say\" id=\"say\" aria-live=\"polite\"></p>\n\n <div class=\"walk\">\n <button type=\"button\" id=\"prev\">Back</button>\n <span id=\"stepNo\">Walk through</span>\n <button type=\"button\" id=\"next\">Next</button>\n </div>\n <p class=\"step\" id=\"stepText\"></p>\n</div>",
"css": ".brake svg { display: block; width: 100%; height: auto; }\n.brake text { font: 400 11px var(--sans); fill: var(--ink-2); }\n.lab { font-size: 11px; }\n.hatch { stroke: var(--ink-3); stroke-width: 1; }\n.dot { fill: var(--ink-2); }\n.grit { fill: var(--wash); }\n.headfill { fill: var(--ink); }\n.fixed { fill: var(--wash); stroke: var(--ink); stroke-width: 1; }\n.pin { stroke: var(--ink); stroke-width: 3; }\n.body { stroke: var(--ink); stroke-width: 1.5; }\n.fluidbox { stroke: none; }\n.hose { fill: none; stroke: var(--ink); stroke-width: 6; }\n.piston { fill: var(--paper); stroke: var(--ink); stroke-width: 1.5; }\n.seal { fill: var(--ink); }\n.backing { fill: var(--ink); }\n.padface { stroke: var(--ink); stroke-width: 1; }\n.disc { fill: var(--paper); stroke: var(--ink); stroke-width: 1.5; }\n.discface { fill: var(--paper); stroke: var(--ink); stroke-width: 1.5; }\n.hub { fill: var(--wash); stroke: var(--ink); stroke-width: 1; }\n.vent { stroke: var(--ink-3); stroke-width: 1.5; }\n.padarc { stroke: var(--ink); stroke-width: 1; }\n.arrows line, .arrow { stroke: var(--ink); stroke-width: 2; }\n[data-part] { transition: opacity 120ms; }\n.brake.focus [data-part] { opacity: .22; }\n.brake.focus [data-part].on { opacity: 1; }\n.controls { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 24px; margin-top: 10px; font: 400 14px/1.3 var(--sans); }\n.controls label { display: grid; gap: 4px; }\n.controls b { font-weight: 600; font-variant-numeric: tabular-nums; }\n.controls input { width: 100%; accent-color: var(--ink); }\n.switches { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; }\nbutton { font: 500 14px/1 var(--sans); color: var(--ink); background: var(--paper); border: 1px solid var(--ink); border-radius: 0; padding: 10px 12px; min-height: 40px; cursor: pointer; }\nbutton[aria-pressed='true'] { background: var(--ink); color: var(--paper); }\nbutton:focus-visible, input:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }\n.figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); gap: 0 18px; margin: 14px 0 0; border-top: 1px solid var(--ink); }\n.figures div { padding: 7px 0; border-bottom: 1px solid var(--rule); }\n.figures dt { font: 400 12.5px/1.3 var(--sans); color: var(--ink-3); }\n.figures dd { margin: 2px 0 0; font: 400 20px/1.2 var(--serif); font-variant-numeric: tabular-nums; }\n.say { min-height: 1.4em; margin: 8px 0 0; font: italic 400 16px/1.45 var(--serif); }\n.walk { display: flex; align-items: center; gap: 12px; margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--rule); font: 400 13px var(--sans); color: var(--ink-3); }\n.walk span { flex: 1; text-align: center; }\n.step { min-height: 3em; margin: 8px 0 0; font: 400 16px/1.5 var(--serif); }\n@media (max-width: 520px) { .controls { grid-template-columns: 1fr; } }\n@media (prefers-reduced-motion: reduce) { [data-part] { transition: none; } }",
"js": "(function () {\n var $ = function (id) { return document.getElementById(id); };\n var root = document.querySelector('.brake');\n\n // Millimetres to drawing units; the running clearance is drawn ten times larger than life.\n var MM = 2.2, CLEAR = 0.15 * 10 * MM, DISC_L = 318, DISC_R = 342, BACK = 6;\n var PEDAL_RATIO = 4, BOOST = 3, MC_BORE = 22, MU = 0.4, R_EFF = 0.13, TYRE_R = 0.31, MASS = 1400, REAR_SHARE = 0.6, GRIP = 9.81;\n var CALIPERS = {\n floating: { name: 'floating', pistonBore: 54, pistons: 1 },\n fixed: { name: 'fixed', pistonBore: 40, pistons: 2 }\n };\n var state = { pedal: 0, wear: 10, kind: 'floating', boost: true, v: 100, step: -1 };\n var area = function (d) { return Math.PI * d * d / 4; };\n\n function physics() {\n var cal = CALIPERS[state.kind];\n var force = state.pedal * PEDAL_RATIO * (state.boost ? BOOST : 1);\n var p = force / area(MC_BORE); // N/mm² = MPa\n var pistonArea = area(cal.pistonBore) * cal.pistons; // per side, mm²\n var clamp = p > 0.05 ? p * pistonArea : 0; // N, on each pad\n var friction = 2 * MU * clamp; // two faces\n var torque = friction * R_EFF; // N·m\n var decel = torque * 2 * (1 + REAR_SHARE) / (TYRE_R * MASS); // m/s², front pair plus a lighter rear pair\n return { p: p, clamp: clamp, friction: friction, torque: torque, decel: decel, locked: decel > GRIP };\n }\n\n function layout(ph) {\n var fixed = state.kind === 'fixed';\n var pad = state.wear * MM, contact = ph.clamp > 0 ? 1 : 0, wearTake = (10 - state.wear) * MM;\n var inFace = DISC_L - CLEAR * (1 - contact); // inner pad's friction face\n var outFace = DISC_R + CLEAR * (1 - contact);\n var padInX = inFace - pad, backInX = padInX - BACK;\n var padOutX = outFace, backOutX = padOutX + pad;\n // A floating body is pulled inboard by as much as the outer pad needs; a fixed body never moves.\n var shift = fixed ? 0 : -(wearTake + CLEAR * contact);\n $('padIn').setAttribute('x', padInX); $('padIn').setAttribute('width', pad);\n $('padInBack').setAttribute('x', backInX);\n $('padOut').setAttribute('x', padOutX); $('padOut').setAttribute('width', pad);\n $('padOutBack').setAttribute('x', backOutX);\n\n var leftWall = 175 + shift, rightWall = backOutX + BACK;\n var pistonX = Math.min(leftWall + 40, backInX - 70);\n $('pistonL').setAttribute('x', pistonX); $('pistonL').setAttribute('width', backInX - pistonX);\n var fluidX = leftWall + 12, fluidW = Math.max(4, pistonX - fluidX);\n $('fluid').setAttribute('x', fluidX); $('fluid').setAttribute('width', fluidW);\n\n var body;\n if (fixed) {\n var rWall = backOutX + BACK + 70;\n $('pistonR').style.display = '';\n $('pistonR').setAttribute('x', backOutX + BACK); $('pistonR').setAttribute('width', rWall - 12 - (backOutX + BACK));\n body = 'M' + leftWall + ' 100 H' + (backInX - 4) + ' V60 H' + (backOutX + BACK + 4) + ' V100 H' + rWall + ' V240 H' + (backOutX + BACK + 4) + ' V230 H' + (backOutX + BACK) + ' V110 H' + (backInX) + ' V230 H' + (backInX - 4) + ' V240 H' + leftWall + ' Z';\n } else {\n $('pistonR').style.display = 'none';\n body = 'M' + leftWall + ' 100 H' + (backInX - 4) + ' V60 H' + (rightWall + 26) + ' V240 H' + rightWall + ' V112 H' + (backInX) + ' V230 H' + (backInX - 4) + ' V240 H' + leftWall + ' Z';\n }\n $('bodyShape').setAttribute('d', body);\n var sealX = pistonX + 18, tilt = contact ? 4 : 0;\n $('sealL').setAttribute('d', 'M' + sealX + ' 134 l8 ' + (-tilt) + ' v6 l-8 ' + tilt + ' z M' + sealX + ' 206 l8 ' + tilt + ' v-6 l-8 ' + (-tilt) + ' z');\n $('sealR').setAttribute('d', fixed ? 'M' + (backOutX + BACK + 40) + ' 134 l-8 ' + (-tilt) + ' v6 l8 ' + tilt + ' z' : '');\n $('hose').setAttribute('d', 'M20 170 H' + (fluidX + 2));\n\n var len = Math.min(70, 8 + ph.clamp / 500);\n var show = ph.clamp > 0 ? '' : 'none';\n $('clampIn').style.display = show; $('clampOut').style.display = show;\n $('clampIn').setAttribute('x1', backInX - len - 8); $('clampIn').setAttribute('x2', backInX - 6);\n $('clampOut').setAttribute('x1', backOutX + BACK + len + 30); $('clampOut').setAttribute('x2', backOutX + BACK + 24);\n $('frictionArrow').style.display = ph.clamp > 0 && state.v > 0 ? '' : 'none';\n }\n\n function fmt(n, d) { return n.toLocaleString('en-GB', { maximumFractionDigits: d, minimumFractionDigits: d }); }\n\n function figures(ph) {\n $('pedalOut').textContent = state.pedal + ' N';\n $('wearOut').textContent = fmt(state.wear, 1).replace('.0', '') + ' mm';\n $('pOut').textContent = fmt(ph.p * 10, 0) + ' bar';\n $('fOut').textContent = fmt(ph.clamp / 1000, 1) + ' kN';\n $('frOut').textContent = fmt(ph.friction / 1000, 1) + ' kN';\n $('tOut').textContent = fmt(ph.torque, 0) + ' N·m';\n $('vOut').textContent = fmt(state.v, 0) + ' km/h';\n var msg = '';\n if (state.v <= 0 && state.pedal > 0) msg = 'Stopped.';\n else if (ph.locked && state.v > 0) msg = 'The brakes ask for ' + fmt(ph.decel / 9.81, 1) + ' g; the tyres give about 1 g. Without ABS the wheels lock and slide.';\n else if (ph.clamp > 0) msg = 'Slowing at ' + fmt(ph.decel / 9.81, 2) + ' g.';\n else if (state.v > 0) msg = 'Rolling. Press the pedal.';\n $('say').textContent = msg;\n }\n\n var STEPS = [\n ['bracket', 'The bracket is bolted to the steering knuckle and never moves. The caliper body rides on two greased slide pins fixed to it.'],\n ['fluid', 'The pedal pushes the master cylinder. Brake fluid does not compress, so the pressure it makes arrives unchanged in the caliper bore: pressure equals force over the master cylinder\\'s area.'],\n ['piston', 'That pressure acts on the piston\\'s much larger face. Clamp force is pressure times piston area, which is where the hydraulic advantage comes from: a 54 mm piston has six times the area of a 22 mm master cylinder bore.'],\n ['body', 'In a floating caliper the piston pushes the inner pad onto the disc; the reaction slides the whole body inboard on its pins, pulling the outer pad against the other face. A fixed caliper has pistons on both sides and its body does not move.'],\n ['pads', 'Both pads rub the disc. Friction is twice (two faces) the pad coefficient times the clamp force, and braking torque is that friction times the effective radius, here 130 mm.'],\n ['seal', 'On release, the square-section seal, twisted as the piston moved, springs back and draws the piston a fraction of a millimetre away from the pad. That is the running clearance; as the pads wear the piston slides further through the seal, and the fluid in the bore makes up the difference.']\n ];\n\n function showStep() {\n var s = state.step;\n root.classList.toggle('focus', s >= 0);\n root.querySelectorAll('[data-part]').forEach(function (el) { el.classList.toggle('on', s >= 0 && el.getAttribute('data-part') === STEPS[s][0]); });\n $('stepNo').textContent = s < 0 ? 'Walk through' : 'Step ' + (s + 1) + ' of ' + STEPS.length;\n $('stepText').textContent = s < 0 ? '' : STEPS[s][1];\n $('prev').disabled = s < 0; $('next').textContent = s === STEPS.length - 1 ? 'Done' : 'Next';\n }\n\n function render() { var ph = physics(); layout(ph); figures(ph); return ph; }\n\n var angle = 0, last = 0;\n (function vents() {\n var g = $('vents'), out = '';\n for (var i = 0; i < 12; i++) { var a = i * Math.PI / 6; out += '<line class=\"vent\" x1=\"' + (Math.cos(a) * 42) + '\" y1=\"' + (Math.sin(a) * 42) + '\" x2=\"' + (Math.cos(a) * 76) + '\" y2=\"' + (Math.sin(a) * 76) + '\"/>'; }\n g.innerHTML = out;\n })();\n\n function tick(t) {\n var dt = Math.min(0.05, (t - last) / 1000 || 0); last = t;\n var ph = physics();\n if (state.v > 0 && ph.clamp > 0) state.v = Math.max(0, state.v - Math.min(ph.decel, GRIP) * dt * 3.6);\n var omega = (state.v / 3.6) / TYRE_R; // rad/s\n angle = (angle + omega * dt * 57.3 * 0.25) % 360; // drawn at a quarter speed, so it can be seen\n $('rotor').setAttribute('transform', 'rotate(' + angle + ')');\n figures(ph);\n requestAnimationFrame(tick);\n }\n\n $('pedal').addEventListener('input', function (e) { state.pedal = Number(e.target.value); render(); });\n $('wear').addEventListener('input', function (e) { state.wear = Number(e.target.value); render(); });\n $('kind').addEventListener('click', function () { state.kind = state.kind === 'fixed' ? 'floating' : 'fixed'; this.setAttribute('aria-pressed', String(state.kind === 'fixed')); render(); });\n $('boost').addEventListener('click', function () { state.boost = !state.boost; this.setAttribute('aria-pressed', String(state.boost)); this.textContent = state.boost ? 'Booster on' : 'Booster off'; render(); });\n $('drive').addEventListener('click', function () { state.v = 100; render(); });\n $('next').addEventListener('click', function () { state.step = state.step >= STEPS.length - 1 ? -1 : state.step + 1; showStep(); });\n $('prev').addEventListener('click', function () { state.step = Math.max(-1, state.step - 1); showStep(); });\n\n render(); showStep(); requestAnimationFrame(tick);\n})();"
}
```1972 half-tonNo. 4
Brakes — from a pedal on the floor to the road test
11 sections, 3,480 words, about 15 minutes, filed 2 August, revised 21 September, 6 highlights.
Bought with the pedal on the floor. Front hoses cracked, rear drums scored, left rear wheel cylinder seized.
Brake parts, from to buy to fitted; high priority means the road test waits for it
Three columns. To buy: rear brake shoes and the rear shoe hardware kit, both high priority, and rear drums, low, only if they measure past the limit. Bought: the right rear wheel cylinder, order 4417, high, and spare bleeder screws on the same order, low, both on their way; and the brake fluid, bought over the counter and on the shelf, high. Fitted: the master cylinder, the front caliper seal kits, the three brake hoses and the left rear wheel cylinder.
- To buy
- Rear brake shoes, high priority
- Rear shoe hardware kit, high priority
- Rear drums, if past limit, low priority
- Bought
- Right rear wheel cylinder, ticket Order 4417, high priority
- Spare bleeder screws, ticket Order 4417, low priority
- Brake fluid, ticket On the shelf, high priority
- Fitted
- Master cylinder, ticket Order 4312
- Front caliper seal kits, ticket Order 4312
- Brake hoses, set of three, ticket Order 4390
- Left rear wheel cylinder, ticket Order 4371
```element kanban
{
"caption": "Brake parts, from to buy to fitted; high priority means the road test waits for it",
"description": "Three columns. To buy: rear brake shoes and the rear shoe hardware kit, both high priority, and rear drums, low, only if they measure past the limit. Bought: the right rear wheel cylinder, order 4417, high, and spare bleeder screws on the same order, low, both on their way; and the brake fluid, bought over the counter and on the shelf, high. Fitted: the master cylinder, the front caliper seal kits, the three brake hoses and the left rear wheel cylinder.",
"columns": [
{
"label": "To buy",
"cards": [
{
"label": "Rear brake shoes",
"priority": "high"
},
{
"label": "Rear shoe hardware kit",
"priority": "high"
},
{
"label": "Rear drums, if past limit",
"priority": "low"
}
]
},
{
"label": "Bought",
"cards": [
{
"label": "Right rear wheel cylinder",
"ticket": "Order 4417",
"priority": "high"
},
{
"label": "Spare bleeder screws",
"ticket": "Order 4417",
"priority": "low"
},
{
"label": "Brake fluid",
"ticket": "On the shelf",
"priority": "high"
}
]
},
{
"label": "Fitted",
"cards": [
{
"label": "Master cylinder",
"ticket": "Order 4312"
},
{
"label": "Front caliper seal kits",
"ticket": "Order 4312"
},
{
"label": "Brake hoses, set of three",
"ticket": "Order 4390"
},
{
"label": "Left rear wheel cylinder",
"ticket": "Order 4371"
}
]
}
]
}
```Original-type parts throughout, except the hoses. Every figure in this document is quoted from the factory service manual, with its section and page.
Sections
- 1Master cylinder — replaceEvidence, keyNew unit, bench-bled before fitting. Part number and supplier under Parts; fluid and pushrod check from the manual, section 5.
- 2Front calipers — rebuildEvidence, keySeals, boots and pistons; slides cleaned and greased. Mounting bolt torque quoted from the manual and highlighted once checked.
- 3Brake hoses — replace all threeDecisionReplaced rather than inspected: two were cracked, and the third was the same age.
- 4Left rear bleeder snapped offProblem, 1 noteSheared at the first quarter turn. Replaced the wheel cylinder instead of drilling it out.
- 5Rear drums — measure before machiningQuestionScored. Is there enough metal left? The maximum diameter is cast on the drum; check it against the manual.
- 6Old linings — treat as asbestosRisk, keyThe original shoes may contain asbestos. Wet-wiped, bagged, no compressed air.
and 5 more sections
How it works
Which master cylinder did you order, and why a new harness? Your assistant sorts the shoebox into a section per job, and puts the parts on a board from To buy to Fitted. You type the specifications from the manual. Then Claude Code lays out what is left, and the graph shows what the road test waits on.