
The cookie banner
Consent, Transitions, SVG, Physics
NewFree
A console’s emergency access, behind glass: the button raises a pane of smoked glass that straightens on springs as the light runs across it, Cancel puts it back into the button, and Break glass brings a little hammer down: the glass cracks from where it is hit, holds a moment and falls in pieces that turn in depth and catch the light. The cracks are worked out at every blow and the pieces are copies of the dialog cut along them.
A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN. The React and Vue tabs hold the same demo as a ready component, which switches its animations off when it leaves the page.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The break-glass dialog</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/reddit-sans@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the break-glass dialog: Emergency access raises a pane of smoked glass that asks to break it. Cancel puts it
back; Break glass swings the hammer, the glass cracks from where it is hit and falls in pieces, and the
button becomes the emergency access with its countdown and End -->
<div class="slot" data-slot data-autoclic>
<button class="trigger" type="button" aria-haspopup="dialog" data-open>
<svg class="hammer" viewBox="0 0 24 24" aria-hidden="true"><path d="M12.3 3.3 18.6 9.6 19.5 13.9 15.2 13 8.9 6.7z"/><path d="M13.1 10.9 4.6 19.4"/></svg>
<span>Emergency access</span>
</button>
<div class="active" hidden data-active>
<svg class="active__icon" viewBox="0 0 24 24" aria-hidden="true"><rect x="5" y="10.5" width="14" height="10" rx="2.2"/><path d="M8.2 10.5V7.4a3.8 3.8 0 0 1 7.3-1.5M12 14.4v2.4"/></svg>
<span class="active__name">Admin access</span>
<span class="active__clock"><span class="sr">Time left </span><span data-clock></span></span>
<button class="active__end" type="button" data-end>End</button>
</div>
<span class="slot__pill" aria-hidden="true"></span>
</div>
</main>
<div class="layer" hidden data-layer>
<div class="layer__scrim" data-scrim></div>
<div class="pane" role="alertdialog" aria-modal="true" aria-labelledby="pane-title" aria-describedby="pane-text" tabindex="-1" data-pane>
<div class="glass" data-glass>
<div class="glass__icon" aria-hidden="true">
<svg viewBox="0 0 24 24"><path d="M12 3.4 18.8 6v5.6c0 4.1-2.8 7.4-6.8 8.9-4-1.5-6.8-4.8-6.8-8.9V6z"/><circle cx="12" cy="10.6" r="1.7"/><path d="M12 12.3v3"/></svg>
</div>
<h2 class="glass__title" id="pane-title">Break glass?</h2>
<p class="glass__text" id="pane-text">You’ll get full admin rights for <span data-minutes></span> minutes. Everything you do is recorded, and the security team is told straight away.</p>
<p class="glass__meta">
<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="8.2"/><path d="M12 7.6V12l2.9 1.8"/></svg>
<span>Ends on its own at <time data-ends></time></span>
</p>
<div class="glass__actions">
<button class="btn btn--quiet" type="button" data-cancel>Cancel</button>
<button class="btn btn--break" type="button" data-confirm>
<svg class="hammer" viewBox="0 0 24 24" aria-hidden="true" data-hammer><path d="M12.3 3.3 18.6 9.6 19.5 13.9 15.2 13 8.9 6.7z"/><path d="M13.1 10.9 4.6 19.4"/><circle class="hammer__tip" cx="19.2" cy="13.6" r="0.4" data-tip/></svg>
<span>Break glass</span>
</button>
</div>
<span class="glass__sheen" aria-hidden="true" data-sheen></span>
</div>
<div class="pane__shards" aria-hidden="true" data-shards></div>
<svg class="pane__cracks" aria-hidden="true" data-cracks></svg>
</div>
</div>
<p class="sr" aria-live="polite" data-live></p>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="script.js"></script>
</body>
</html>Change values, colours and text with the controls and watch the animation respond live. Or write in the code yourself. Then download the folder with your changes.
36 values to change
With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:
Take “The break-glass dialog” from Animorio and fit it into my siteThe dialog has four measures, its height, its scale and the two tilts rotateX and rotateY, and each is a damped spring, x'' = −ω²(x − target) − 2ζω·x', in steps of 1/240 of a second on GSAP’s ticker, with the step limited to 1/30. Opening, it starts 34 pixels lower, at 0.9 and tilted back 32 degrees: the tilt has ω = 7.2/RISE and ζ = 0.42, so it goes a little past and back, the height and scale ω = 8/RISE and ζ = 0.78. Closing, the targets become 26 pixels, 0.62 and 30 degrees, with ζ = 0.9 and the pane fading in PUT_AWAY seconds. When the springs are still the loop sleeps.
The reflection is a light diagonal band with mix-blend-mode: screen, inside the glass. It has no timing of its own: its place comes from the tilt, translateX = −130% + 12.5·rotateX − 8·rotateY, so it runs across the pane as it straightens, as it goes back into the button and when the blow makes it shudder, and at rest it stays outside. The button’s words fade before the glass is opaque, so they never show through it.
The blow is the hammer’s point (a spot marked in its drawing) once it has gone up to −40 degrees and down to 18. From there RAYS rays run out at slightly uneven angles, with a point on every ring and between two rings more points that stray by two pixels; the rings are RINGS, from 15 pixels to 84% of the distance to the farthest corner, at radii growing geometrically. A sector closes on a ring with a chance of 0.7 (always on the first, which makes the little pieces of the hit); if the arc is wider than 130 pixels it splits in two with a new ray starting there. Every arc that closes a sector closes a piece, then cut by the glass’s four sides with Sutherland and Hodgman.
In an SVG over the glass every crack is two strokes, a dark one and a light one half a pixel higher, with a different opacity for each crack, plus a few short hairlines branching off the rays. They draw with stroke-dashoffset: the rays at 2600 pixels a second, each from its own ring, the rings in 0.06 seconds when the crack reaches them. The pieces are cut along the same points, so the cracks and the broken words match.
Every piece is a copy of the glass (without ids or data-, its buttons out of the Tab order) cut with clip-path: polygon(), its transform-origin on its centroid, an SVG with only its broken edges and a light of its own. During HOLD they move by a whole pixel and change their light a little. Then they let go from the hit outwards, at 2200 pixels a second: a push of (50 + 260·nearness²)·BURST, a speed inwards of up to 640 pixels a second near the hit, spins on three axes, gravity GRAVITY. The piece’s normal, turned by rotateX and rotateY, against the vector halfway between lamp and eye, to the fiftieth power, gives the flash of its shine.
It is an alertdialog with aria-modal, aria-labelledby and aria-describedby: opening, the focus goes to Cancel, Tab goes round the two buttons, Escape puts it away, the button behind is inert; closing, the focus goes back to the button, or to End after the blow. The button turns red as the glass falls, and its words come once no piece is in front of it any more; the time left is rewritten only when the second changes, and at zero the access ends by itself. An aria-live region says so. A click from a script on the button’s frame (the library’s preview) opens, then once puts it away and once breaks it, and ends the access, going by the state and not by a fixed list.
| Name | File | Default | What it changes |
|---|---|---|---|
RISE | script.js | 0.62 | The seconds the pane takes to come up and settle. |
PUT_AWAY | script.js | 0.34 | The seconds Cancel takes to put the pane back into its button. |
RAYS | script.js | 11 | How many cracks run out from where the hammer lands. |
RINGS | script.js | 5 | How many rings of cracks go round the hit. |
HOLD | script.js | 0.4 | The seconds the cracked pane holds together before it falls. |
GRAVITY | script.js | 3200 | How fast the pieces fall, in pixels a second squared. |
BURST | script.js | 1 | How hard the blow throws the pieces: 0 they just drop, 2 twice as hard. |
DIM | script.js | 0.62 | How dark the page goes behind the glass, from 0 to 1. |
MINUTES | script.js | 60 | How many minutes the emergency access lasts. |
For actions that are rarely taken and should cost one more gesture: an emergency access, deleting an account or a project, shutting a service down, a factory reset. The breaking glass says it is not a confirmation like the others; for everyday confirmations there is the dialog from its button.
The pane takes the width of the screen less 16 pixels a side (358 at 390) and the explanation runs to three lines; the button stays 56 tall and the two on the glass 46. With a finger a tap opens, a tap outside puts it away, and the pieces fall past the bottom of the screen without scrolling it or spilling sideways.
The pane does not rise or tilt: the button’s words fade and the glass appears in its place with a fade, and leaves the same way. The hammer does not move; pressing Break glass the cracks appear all at once, already drawn, then the cracked glass fades and only after that does the access appear, with a fade too.
GSAP 3.15.0, Reddit Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 14 KB; the libraries: GSAP 28 KB.
Tested on 6 October 2026
Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.