Two snakes build the mark: the red l slides in from the top left and the f from the top right. Then it bends into ten moods and comes back to the glider.
It takes the page's text colour, so it works in light and dark mode. Red always marks the point of frustration.
Pick one to jump the hero there. The lap carries on from it.
<!-- once, anywhere --> <script src="/js/frustrated-logo.min.js" defer></script> <!-- in the header; the static SVG inside shows until the script loads, and without JS --> <a href="/" class="brand"> <frustrated-logo size="40"><img src="/frustrated-labs-mark-auto.svg" width="40" height="40" alt=""></frustrated-logo> Frustrated Labs </a> /* the ink follows the text colour; the accent is a custom property */ frustrated-logo { color: var(--text); --fl-accent: #FF4433; } // a mood on cue, for example on a 404 page document.querySelector('frustrated-logo').goTo('gritted');
| size | A px number or any CSS length. Default 48px. Plain CSS width and height work too. |
| theme | auto (default) takes the text colour. light and dark force ink or paper. system follows the device setting. |
| accent | The red. Default #FF4433, or set --fl-accent in CSS. |
| mode | loop (default) · hover rests on Methuselah and plays while pointed at · once plays one lap, then rests · static never moves. |
| intro | none starts with the mark already built. By default the two snakes build it when the logo first appears. |
| state | Holds one mood with its small idle motion: methuselah palindrome hashbang fstar homekey prompt gritted vein sikku infinity atom. |
| sequence | Your own order or subset, space separated, for example "methuselah sikku infinity". |
| speed · paused | A time multiplier (default 1), and a switch that stops the clock. |
| label | Accessible name. Default "Frustrated Labs". |
| JS | play() · pause() · goTo(id) · seek(ms) · .state · .states · .duration, and a statechange event with detail.state. |
With reduced motion turned on, visitors see the static mark. Logos that are offscreen or in a background tab stop drawing, and every logo on a page shares one animation clock.