/* ── Tool motion ───────────────────────────────────────────────────────────
 *
 * The animated diagram on each tool page, and the same drawing again behind
 * each card on the tools directory.
 *
 * PROVENANCE. This system — the `tm-*` class vocabulary, the per-tool
 * variants and their keyframes — comes from floi.dev, used with the owner's
 * permission, granted to the operator of this site. It is not our work and
 * this note is the reason it can stay.
 *
 * Taking it rather than inventing a parallel one was the right call: the set
 * is coherent in a way thirty separately-drawn diagrams would not be, and the
 * alternative on offer was another thirty vague sketches.
 *
 * WHAT WE CHANGED. Only the tokens. The rules below reference a palette by
 * names this site does not use, so the block immediately after this maps them
 * onto ours — scoped to `.tm` so nothing leaks into the rest of the page.
 */

.tm {
  /* How long one full cycle of every animation takes. */
  --tm-cycle: 6s;
  --ease: cubic-bezier(.4, 0, .2, 1);

  --surface: var(--panel);
  --surface-inset: var(--sunken);
  --track-display: var(--sunken);
  /* --border: var(--line); the host owns this name */
  --border-strong: var(--line-strong);
  /* --text: var(--fg); the host owns this name */
  --text-muted: var(--muted);
  --text-subtle: var(--faint);
  /* --on-accent: var(--accent-fg); the host owns this name */
  --accent-soft: color-mix(in srgb, var(--accent) 14%, transparent);
  --success: var(--ok);
  /* Three names the diagrams ask for that nothing defined. An SVG
     presentation attribute given an undefined var() does not fall back — it
     computes to `fill: none`, so the shape is still in the DOM, still
     animating, and completely invisible. Three diagrams were drawing nothing
     where a pill, a line of code and a veil should have been, silently.
     Mapped here beside the names they belong with rather than at the three
     call sites, so the next diagram to use one already works. */
  --success-soft: color-mix(in srgb, var(--ok) 14%, transparent);
  --accent-text: var(--accent);
  --bg-subtle: var(--panel);
  --warning: var(--bad);
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-display: inherit;
}

/* The diagrams are decorative: the heading and the sentence carry the page. */
@media (prefers-reduced-motion: reduce) {
  .tm * { animation: none !important; }
}

@keyframes tm-type{0%,2%{transform:scaleX(0)}18%,92%{transform:scaleX(1)}93%,to{transform:scaleX(0)}}
@keyframes tm-caret-run{0%,2%{transform:translate(0)}18%,92%{transform:translate(146px)}93%,to{transform:translate(0)}}
@keyframes tm-blink{0%,50%{opacity:1}51%,to{opacity:0}}
@keyframes tm-press{0%,19%{transform:none}21%{transform:scale(.93)}25%,to{transform:none}}
@keyframes tm-pop{0%,24%{opacity:0;transform:translateY(6px)scale(.94)}32%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:translateY(6px)scale(.94)}}
@keyframes tm-save{0%,40%{opacity:0;transform:scale(.7)}46%,55%{opacity:1;transform:scale(1)}58%,to{opacity:0;transform:scale(1)}}
@keyframes tm-arrow-dip{0%,46%{transform:translateY(-1.5px)}51%{transform:translateY(2px)}55%,to{transform:translateY(-1.5px)}}
@keyframes tm-thumbs-done{0%,56%{opacity:0;transform:scale(.7)}62%{opacity:1;transform:scale(1.08)}66%,90%{opacity:1;transform:scale(1)}95%,to{opacity:0;transform:scale(1)}}
@keyframes tm-thumbs-draw{0%,58%{stroke-dashoffset:14px}66%,to{stroke-dashoffset:0}}
@keyframes tm-ctl{0%,26%{opacity:1}34%,88%{opacity:0}96%,to{opacity:1}}
@keyframes tm-progress{0%{transform:scaleX(.08)}32%{transform:scaleX(.64)}44%,to{transform:scaleX(.08)}}
@keyframes tm-cursor{0%{opacity:1;transform:translate(150px,96px)}10%{opacity:1;transform:translate(161px,103px)}20%{opacity:1;transform:translate(150px,96px)}30%{opacity:1;transform:translate(232px,150px)}34%,95%{opacity:0;transform:translate(232px,150px)}96%,to{opacity:1;transform:translate(150px,96px)}}
@keyframes tm-brackets{0%,36%{opacity:0;transform:scale(1.08)}42%,52%{opacity:1;transform:scale(1)}58%,to{opacity:0;transform:scale(1)}}
@keyframes tm-flash{0%,38%{opacity:0}42%,50%{opacity:1}56%,to{opacity:0}}
@keyframes tm-shot-still{0%,48%{opacity:0;transform:translate(-24px,-18px)scale(.88)}58%,88%{opacity:1;transform:none}95%,to{opacity:0;transform:translate(-24px,-18px)scale(.88)}}
@keyframes tm-shot-done{0%,60%{opacity:0;transform:scale(.6)}68%{opacity:1;transform:scale(1.08)}72%,to{opacity:1;transform:scale(1)}}
@keyframes tm-shot-draw{0%,62%{stroke-dashoffset:14px}72%,to{stroke-dashoffset:0}}
@keyframes tm-ball-step{to{transform:translate(96px)}}
@keyframes tm-head-step{to{transform:translate(288px)}}
@keyframes tm-count-step{to{transform:translateY(-84px)}}
@keyframes tm-key-dip{0%{transform:translateY(1.5px)}30%,to{transform:translateY(0)}}
@keyframes tm-key-press{0%,21%{opacity:1}22%,to{opacity:0}}
@keyframes tm-note-pulse{0%{opacity:1}45%,to{opacity:.35}}
@keyframes tm-march{to{stroke-dashoffset:-24px}}
@keyframes tm-drop{0%,18%{opacity:1}30%,88%{opacity:0}96%,to{opacity:1}}
@keyframes tm-drop-hit{0%,18%{opacity:0}22%{opacity:1}30%,to{opacity:0}}
@keyframes tm-file-drop{0%{opacity:0;animation-timing-function:cubic-bezier(.5,0,.85,.4);transform:translateY(-52px)scale(.9)}8%{opacity:1}20%{opacity:1;transform:translateY(0)scale(1)}23%{transform:translateY(0)scale(.94)}27%{transform:none}32%,to{opacity:0;transform:none}}
@keyframes tm-video{0%,22%{opacity:0}30%,88%{opacity:1}95%,to{opacity:0}}
@keyframes tm-scrub{0%,30%{transform:translate(0)}50%,to{transform:translate(150px)}}
@keyframes tm-file-still{0%,52%{opacity:0;transform:translate(-30px,12px)scale(.85)}62%,88%{opacity:1;transform:none}95%,to{opacity:0;transform:translate(-30px,12px)scale(.85)}}
@keyframes tm-file-done{0%,64%{opacity:0;transform:scale(.6)}72%{opacity:1;transform:scale(1.08)}76%,to{opacity:1;transform:scale(1)}}
@keyframes tm-file-draw{0%,66%{stroke-dashoffset:14px}76%,to{stroke-dashoffset:0}}
@keyframes tm-count-type{0%,2%{transform:scaleX(0)}26%,92%{transform:scaleX(1)}93%,to{transform:scaleX(0)}}
@keyframes tm-count-scan{0%,28%{opacity:0;transform:translateY(0)}32%{opacity:1;transform:translateY(4px)}42%{opacity:1;transform:translateY(144px)}46%,to{opacity:0;transform:translateY(144px)}}
@keyframes tm-count-stat{0%,44%{opacity:0;transform:translate(9px)scale(.94)}52%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:translate(9px)scale(.94)}}
@keyframes tm-count-roll{0%,52%{transform:translateY(0)}57%{transform:translateY(-19px)}62%{transform:translateY(-38px)}67%,to{transform:translateY(-57px)}}
@keyframes tm-case-in{0%{opacity:0;transform:translate(-5px)}10%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:translate(-5px)}}
@keyframes tm-case-chip{0%,18%{opacity:0;transform:translateY(5px)}27%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:translateY(5px)}}
@keyframes tm-case-picked{0%,33%{opacity:0;transform:scale(.94)}42%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:scale(.94)}}
@keyframes tm-case-out{0%,48%{opacity:0;transform:translateY(8px)}58%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:translateY(8px)}}
@keyframes tm-count-fade{0%,44%{opacity:0}52%,90%{opacity:1}95%,to{opacity:0}}
@keyframes tm-json-paste{0%,2%{transform:scaleX(0)}16%,to{transform:scaleX(1)}}
@keyframes tm-json-clear{0%,26%{opacity:1}32%,to{opacity:0}}
@keyframes tm-json-scan{0%,28%{opacity:0;transform:translateY(0)}33%{opacity:1;transform:translateY(4px)}44%{opacity:1;transform:translateY(148px)}48%,to{opacity:0;transform:translateY(148px)}}
@keyframes tm-json-line{0%,36%{opacity:0;transform:translate(-5px)}44%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:translate(-5px)}}
@keyframes tm-json-card{0%,46%{opacity:0;transform:translate(9px)scale(.96)}54%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:translate(9px)scale(.96)}}
@keyframes tm-json-row{0%,52%{opacity:0;transform:translate(7px)}60%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:translate(7px)}}
@keyframes tm-json-done{0%,62%{opacity:0;transform:scale(.6)}70%{opacity:1;transform:scale(1.08)}74%,90%{opacity:1;transform:scale(1)}95%,to{opacity:0;transform:scale(.6)}}
@keyframes tm-json-draw{0%,64%{stroke-dashoffset:14px}74%,to{stroke-dashoffset:0}}
@keyframes tm-csv-head{0%,24%{opacity:0}30%,90%{opacity:1}95%,to{opacity:0}}
@keyframes tm-csv-row{0%,3%{opacity:0;transform:translate(-6px)}13%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:translate(-6px)}}
@keyframes tm-csv-scan{0%,24%{opacity:0;transform:translateY(0)}29%{opacity:1;transform:translateY(4px)}40%{opacity:1;transform:translateY(148px)}44%,to{opacity:0;transform:translateY(148px)}}
@keyframes tm-csv-card{0%,46%{opacity:0;transform:translate(9px)scale(.96)}54%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:translate(9px)scale(.96)}}
@keyframes tm-csv-out{0%,52%{opacity:0;transform:translate(7px)}60%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:translate(7px)}}
@keyframes tm-grad-wipe{0%,30%{transform:translate(0)}52%,92%{transform:translate(150px)}to{transform:translate(0)}}
@keyframes tm-grad-stop{0%,4%{opacity:0;transform:translateY(-9px)}16%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:translateY(-9px)}}
@keyframes tm-grad-card{0%,50%{opacity:0;transform:translate(9px)scale(.96)}58%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:translate(9px)scale(.96)}}
@keyframes tm-grad-line{0%,56%{opacity:0;transform:translate(7px)}64%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:translate(7px)}}
@keyframes tm-fc-row{0%,3%{opacity:0;transform:translate(-6px)}13%,91%{opacity:1;transform:none}96%,to{opacity:0;transform:translate(-6px)}}
@keyframes tm-fc-scan{0%,22%{opacity:0;transform:translateY(0)}27%{opacity:1;transform:translateY(4px)}38%{opacity:1;transform:translateY(148px)}42%,to{opacity:0;transform:translateY(148px)}}
@keyframes tm-fc-deck{0%,40%{opacity:0;transform:translate(10px)scale(.95)}48%,91%{opacity:1;transform:none}96%,to{opacity:0;transform:translate(10px)scale(.95)}}
@keyframes tm-fc-card{0%,40%{opacity:0;transform:translate(10px)scale(.95)}48%,91%{opacity:1;transform:none}96%,to{opacity:0;transform:translate(10px)scale(.95)}}
@keyframes tm-fc-front{0%,46%{opacity:1;transform:scaleX(1)}62%,to{opacity:0;transform:scaleX(0)}}
@keyframes tm-fc-back{0%,62%{opacity:0;transform:scaleX(0)}70%,to{opacity:1;transform:scaleX(1)}}
@keyframes tm-fc-press{0%,53%{opacity:0}56%,61%{opacity:1}65%,to{opacity:0}}
@keyframes tm-cv-in{0%,3%{opacity:0;transform:translate(-10px)}14%,90%{opacity:1;transform:none}96%,to{opacity:0;transform:translate(-10px)}}
@keyframes tm-cv-draw{0%,46%{stroke-dashoffset:52px}58%,92%{stroke-dashoffset:0}to{stroke-dashoffset:52px}}
@keyframes tm-cv-out{0%,56%{opacity:0;transform:translate(9px)scale(.96)}66%,90%{opacity:1;transform:none}96%,to{opacity:0;transform:translate(9px)scale(.96)}}
@keyframes tm-cv-done{0%,72%{opacity:0;transform:scale(.6)}78%{opacity:1;transform:scale(1.1)}82%,90%{opacity:1;transform:scale(1)}96%,to{opacity:0;transform:scale(1)}}
@keyframes tm-cv-tick{0%,74%{stroke-dashoffset:16px}82%,to{stroke-dashoffset:0}}
@keyframes tm-cv-pill{0%,34%{transform:translate(-68px)}46%,92%{transform:none}to{transform:translate(-68px)}}
@keyframes tm-cv-lit-a{0%,34%{opacity:1}44%,92%{opacity:0}to{opacity:1}}
@keyframes tm-cv-lit-b{0%,36%{opacity:0}46%,92%{opacity:1}to{opacity:0}}
@keyframes tm-cp-div{0%,10%{opacity:0;transform:translate(-69px)}20%{opacity:1;transform:translate(-69px)}44%{opacity:1;transform:translate(60px)}58%,92%{opacity:1;transform:none}to{opacity:0;transform:translate(-69px)}}
@keyframes tm-cp-bar{0%,46%{transform:scaleX(1)}64%,92%{transform:scaleX(.21)}to{transform:scaleX(1)}}
@keyframes tm-cp-read{0%,50%{opacity:0;transform:translateY(3px)}64%,92%{opacity:1;transform:none}to{opacity:0;transform:translateY(3px)}}
@keyframes tm-cp-thumb{0%,16%{transform:translate(75px)}46%,92%{transform:none}to{transform:translate(75px)}}
@keyframes tm-cp-tick{0%,62%{stroke-dashoffset:14px}74%,92%{stroke-dashoffset:0}to{stroke-dashoffset:14px}}
@keyframes tm-cp-done{0%,58%{opacity:0;transform:scale(.8)}70%,92%{opacity:1;transform:none}to{opacity:0;transform:scale(.8)}}
@keyframes tm-rz-pic{0%,36%{transform:scale(1)}54%,92%{transform:scale(.55)}to{transform:scale(1)}}
@keyframes tm-rz-ghost{0%,38%{opacity:0}56%,92%{opacity:1}to{opacity:0}}
@keyframes tm-rz-typed{0%,12%{opacity:0;transform:translateY(4px)}22%,92%{opacity:1;transform:none}to{opacity:0;transform:translateY(4px)}}
@keyframes tm-rz-derived{0%,24%{opacity:0}32%,92%{opacity:1}to{opacity:0}}
@keyframes tm-rz-read{0%,58%{opacity:0;transform:translate(8px)}68%,92%{opacity:1;transform:none}to{opacity:0;transform:translate(8px)}}
@keyframes tm-rz-done{0%,70%{opacity:0;transform:scale(.6)}76%{opacity:1;transform:scale(1.1)}80%,92%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(1)}}
@keyframes tm-rz-tick{0%,72%{stroke-dashoffset:16px}80%,to{stroke-dashoffset:0}}
@keyframes tm-uuid-pick{0%,4%{transform:scale(.97)}12%,to{transform:none}}
@keyframes tm-uuid-write{0%,16%{opacity:0;transform:translateY(5px)}30%,90%{opacity:1;transform:none}96%,to{opacity:0;transform:translateY(5px)}}
@keyframes tm-uuid-land{0%,54%{opacity:0;transform:translateY(7px)scale(.94)}62%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:translateY(7px)scale(.94)}}
@keyframes tm-uuid-done{0%,70%{opacity:0;transform:scale(.8)}78%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:scale(.8)}}
@keyframes tm-lorem-dial{0%,6%{transform:translateY(0)}10%{transform:translateY(-22px)}14%,to{transform:translateY(-44px)}}
@keyframes tm-lorem-caret{0%,16%{opacity:1}20%,to{opacity:0}}
@keyframes tm-lorem-write{0%,18%{transform:scaleX(0)}46%,92%{transform:scaleX(1)}93%,to{transform:scaleX(0)}}
@keyframes tm-lorem-land{0%,56%{opacity:0;transform:translateY(7px)scale(.94)}64%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:translateY(7px)scale(.94)}}
@keyframes tm-lorem-done{0%,70%{opacity:0;transform:scale(.8)}78%,90%{opacity:1;transform:none}95%,to{opacity:0;transform:scale(.8)}}
@keyframes tm-qr-type{0%,2%{transform:scaleX(0)}20%,92%{transform:scaleX(1)}98%,to{transform:scaleX(0)}}
@keyframes tm-qr-caret{0%,2%{transform:translate(0)}20%,92%{transform:translate(70px)}98%,to{transform:translate(0)}}
@keyframes tm-qr-land{0%,22%{opacity:0;transform:scale(.55)}32%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:scale(.55)}}
@keyframes tm-qr-fill{0%,32%{opacity:0;transform:scale(.4)}44%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:scale(.4)}}
@keyframes tm-qr-out{0%,58%{opacity:0;transform:translateY(7px)}68%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:translateY(7px)}}
@keyframes tm-qr-done{0%,74%{opacity:0;transform:scale(.8)}82%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:scale(.8)}}
@keyframes tm-cut-trace{0%,16%{stroke-dashoffset:340px;opacity:0}20%{opacity:1}40%,92%{stroke-dashoffset:0;opacity:1}98%,to{stroke-dashoffset:340px;opacity:0}}
@keyframes tm-cut-lift{0%,20%{opacity:1}40%,92%{opacity:.55}98%,to{opacity:1}}
@keyframes tm-cut-arrow{0%,42%{opacity:0;transform:translate(-6px)}52%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:translate(-6px)}}
@keyframes tm-cut-checks{0%,50%{opacity:0}60%,92%{opacity:1}98%,to{opacity:0}}
@keyframes tm-cut-result{0%,58%{opacity:0;transform:scale(.9)}68%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:scale(.9)}}
@keyframes tm-cut-done{0%,74%{opacity:0;transform:scale(.8)}82%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:scale(.8)}}
@keyframes tm-type-in{0%{opacity:0}5%,92%{opacity:1}98%,to{opacity:0}}
@keyframes tm-type-wipe1{0%,5%{transform:translate(0)}32%,92%{transform:translate(204px)}98%,to{transform:translate(0)}}
@keyframes tm-type-wipe2{0%,33%{transform:translate(0)}58%,92%{transform:translate(194px)}98%,to{transform:translate(0)}}
@keyframes tm-type-caret{0%,5%{transform:translate(0)}32%,33%{transform:translate(200px)}34%{transform:translateY(20px)}58%,92%{transform:translate(190px,20px)}98%,to{transform:translate(0)}}
@keyframes tm-type-wrong{0%,20%{opacity:0}23%,92%{opacity:1}98%,to{opacity:0}}
@keyframes tm-type-out{0%,58%{opacity:0;transform:translateY(10px)}66%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:translateY(10px)}}
@keyframes tm-pom-pick{0%,3%{opacity:0;transform:translate(-6px)}12%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:translate(-6px)}}
@keyframes tm-pom-on{0%,15%{opacity:0}20%,to{opacity:1}}
@keyframes tm-pom-dial{0%,16%{opacity:0;transform:scale(.94)}24%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:scale(.94)}}
@keyframes tm-pom-ring{0%,24%{stroke-dashoffset:0}58%{stroke-dashoffset:264px}64%,to{stroke-dashoffset:0}}
@keyframes tm-pom-time-a{0%,23%{opacity:0}24%,38%{opacity:1}39%,to{opacity:0}}
@keyframes tm-pom-time-b{0%,38%{opacity:0}39%,59%{opacity:1}60%,to{opacity:0}}
@keyframes tm-pom-time-c{0%,59%{opacity:0}60%,to{opacity:1}}
@keyframes tm-pom-mode-a{0%,23%{opacity:0}24%,59%{opacity:1}60%,to{opacity:0}}
@keyframes tm-pom-out{0%,16%{opacity:0;transform:translate(8px)}24%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:translate(8px)}}
@keyframes tm-pom-done{0%,59%{opacity:0;transform:scale(.4)}66%,to{opacity:1;transform:none}}
@keyframes tm-pad-write{0%,4%{transform:scaleX(0)}20%,88%{transform:scaleX(1)}96%,to{transform:scaleX(0)}}
@keyframes tm-pad-caret{0%,2%{opacity:0}4%{opacity:1}8%{opacity:0}12%{opacity:1}16%{opacity:0}20%{opacity:1}24%,to{opacity:0}}
@keyframes tm-pad-pop{0%,26%{opacity:0;transform:scale(.85)}34%,92%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.85)}}
@keyframes tm-pad-fade{0%,40%{opacity:0}52%,92%{opacity:1}to{opacity:0}}
@keyframes tm-tr-code{0%{opacity:0;transform:scale(.9)}10%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:scale(.9)}}
@keyframes tm-tr-phone{0%,14%{opacity:0;transform:translate(12px)}26%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:translate(12px)}}
@keyframes tm-tr-draw{0%,26%{stroke-dashoffset:150px;opacity:0}30%{opacity:1}46%,92%{stroke-dashoffset:0;opacity:1}98%,to{stroke-dashoffset:150px;opacity:0}}
@keyframes tm-tr-march{to{stroke-dashoffset:-18px}}
@keyframes tm-tr-fly{0%,46%{offset-distance:0%;opacity:0}50%{opacity:1}70%{offset-distance:100%;opacity:1}72%,to{offset-distance:100%;opacity:0}}
@keyframes tm-tr-land{0%,62%{opacity:0;transform:translate(8px)}72%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:translate(8px)}}
@keyframes tm-tr-done{0%,78%{opacity:0;transform:scale(.8)}86%,92%{opacity:1;transform:none}98%,to{opacity:0;transform:scale(.8)}}
@keyframes tm-tr-veil-l{0%,12%{transform:scaleX(.02)}38%,93%{transform:none}to{transform:scaleX(.02)}}
@keyframes tm-tr-veil-r{0%,12%{transform:scaleX(.02)}44%,93%{transform:none}to{transform:scaleX(.02)}}
@keyframes tm-tr-hl{0%,12%{transform:translate(-62px)}38%,93%{transform:none}to{transform:translate(-62px)}}
@keyframes tm-tr-hr{0%,12%{transform:translate(66px)}44%,93%{transform:none}to{transform:translate(66px)}}
@keyframes tm-tr-out{0%,50%{opacity:0;transform:translateY(-16px)scale(.96)}66%,93%{opacity:1;transform:none}to{opacity:0;transform:translateY(-16px)scale(.96)}}
@keyframes tm-tr-tick{0%,68%{stroke-dashoffset:14px}80%,95%{stroke-dashoffset:0}to{stroke-dashoffset:14px}}
@keyframes tm-pd-shot{0%,8%{opacity:0;transform:translate(-16px)}24%,to{opacity:1;transform:none}}
@keyframes tm-pd-cross{0%,32%{opacity:0;transform:translate(-8px)}46%,to{opacity:1;transform:none}}
@keyframes tm-pd-doc{0%,46%{opacity:0;transform:translate(10px)scale(.94)}62%,to{opacity:1;transform:none}}
@keyframes tm-pd-back{0%,54%{opacity:0}70%,to{opacity:1}}
@keyframes tm-pd-tick{0%,70%{stroke-dashoffset:14px}82%,96%{stroke-dashoffset:0}to{stroke-dashoffset:14px}}
@keyframes tm-pd-chip{0%,74%{opacity:0}86%,to{opacity:1}}
@keyframes tm-sg-in{0%,6%{opacity:0;transform:translate(-14px)}20%,to{opacity:1;transform:none}}
@keyframes tm-sg-cross{0%,26%{opacity:0;transform:translate(-8px)}40%,to{opacity:1;transform:none}}
@keyframes tm-sg-out{0%,40%{opacity:0;transform:translate(10px)scale(.94)}54%,to{opacity:1;transform:none}}
@keyframes tm-sg-ink{0%,56%{stroke-dashoffset:118px}76%,to{stroke-dashoffset:0}}
@keyframes tm-sg-tick{0%,78%{stroke-dashoffset:14px}88%,to{stroke-dashoffset:0}}
@keyframes tm-sg-chip{0%,82%{opacity:0}92%,to{opacity:1}}
@keyframes tm-ocr-beam{0%,14%{opacity:0;transform:translateY(0)}18%{opacity:.28}44%{opacity:.28}48%,to{opacity:0;transform:translateY(102px)}}
@keyframes tm-ocr-box{0%,16%{opacity:0}26%{opacity:1}to{opacity:1}}
@keyframes tm-ocr-line{0%,46%{opacity:0;transform:scaleX(.2)}60%{opacity:1;transform:scaleX(1)}to{opacity:1;transform:scaleX(1)}}
@keyframes tm-ocr-mark{0%,64%{opacity:0}74%{opacity:1}to{opacity:1}}
@keyframes tm-ocr-done{0%,78%{opacity:0}88%{opacity:1}to{opacity:1}}
@keyframes tm-tbi-trace{0%,16%{stroke-dashoffset:100px;opacity:1}34%{stroke-dashoffset:0;opacity:1}46%{stroke-dashoffset:0;opacity:1}56%,to{stroke-dashoffset:0;opacity:0}}
@keyframes tm-tbi-word{0%,42%{opacity:0;transform:scaleX(.05)}56%{opacity:1;transform:scaleX(1)}to{opacity:1;transform:scaleX(1)}}
@keyframes tm-tbi-figb{0%,58%{opacity:0;transform:translateY(7px)scale(.97)}72%{opacity:1;transform:translateY(0)scale(1)}to{opacity:1;transform:translateY(0)scale(1)}}
@keyframes tm-tbi-done{0%,80%{opacity:0}90%{opacity:1}to{opacity:1}}
@keyframes tm-pi-source{0%,8%{opacity:0;transform:translateY(8px)}20%,90%{opacity:1;transform:translateY(0)}to{opacity:0}}
@keyframes tm-pi-page{0%,35%{opacity:0;transform:translate(-20px)}58%,90%{opacity:1;transform:translate(0)}to{opacity:0}}
@keyframes tm-pi-arrow{0%,23%{opacity:0}35%,90%{opacity:1}to{opacity:0}}
@keyframes tm-sp-doc{0%,5%{opacity:0;transform:translate(-12px)}16%,44%{opacity:1;transform:translate(0)}58%,to{opacity:0;transform:translate(8px)}}
@keyframes tm-sp-blade{0%,20%{opacity:0;transform:translateY(-26px)}34%,46%{opacity:1;transform:translateY(0)}60%,to{opacity:0;transform:translateY(16px)}}
@keyframes tm-sp-out{0%,48%{opacity:0;transform:translate(-30px)scale(.92)}64%,92%{opacity:1;transform:translate(0)scale(1)}to{opacity:0}}
@keyframes tm-mg-in{0%,6%{opacity:0;transform:translateY(10px)}18%,52%{opacity:1;transform:translateY(0)}74%,to{opacity:0;transform:translateY(-6px)}}
@keyframes tm-mg-page{0%,30%{opacity:0;transform:translate(-46px,6px)scale(.9)}56%,92%{opacity:1;transform:translate(0)scale(1)}to{opacity:0}}
@keyframes tm-mg-out{0%,48%{opacity:0}62%,92%{opacity:1}to{opacity:0}}
@keyframes tm-tts-source{0%,5%{opacity:0;transform:translate(-10px)}18%,76%{opacity:1;transform:translate(0)}90%,to{opacity:1}}
@keyframes tm-tts-arrow{0%,28%{opacity:0;stroke-dasharray:5 5;stroke-dashoffset:16px}40%,82%{opacity:1;stroke-dashoffset:0}94%,to{opacity:1}}
@keyframes tm-tts-result{0%,43%{opacity:0;transform:translate(-9px)scale(.97)}58%,to{opacity:1;transform:translate(0)scale(1)}}
@keyframes tm-tts-wave{0%,53%{opacity:0;transform:scaleY(.2)}64%,to{opacity:1;transform:scaleY(1)}}

.tm{width:100%;height:auto}
.tm *{transform-box:fill-box;transform-origin:50%}
.tm .tm-inset{transform-box:view-box;transform-origin:0 0}
.tm-panel{fill:var(--surface);stroke:var(--border-strong);stroke-width:1.25px}
.tm-outline{fill:none;stroke:var(--border-strong);stroke-width:1.25px}
.tm-solid{fill:var(--text)}
.tm-knockout{fill:var(--surface)}
.tm-accent,.tm-ball,.tm-fill{fill:var(--accent)}
.tm-chip{fill:var(--surface);stroke:var(--border);stroke-width:1px}
.tm-track,.tm-hill{fill:var(--surface-inset)}
.tm-sun{fill:var(--border-strong)}
.tm-ground{stroke:var(--border-strong);stroke-width:1.25px}
.tm-cell-dot{fill:var(--border-strong)}
.tm-ticks line{stroke:var(--border-strong);stroke-width:1px}
.tm-drop{stroke:var(--border-strong);stroke-width:2px;stroke-dasharray:7 5}
.tm-brackets path{stroke:var(--accent);stroke-width:2px;stroke-linecap:round;stroke-linejoin:round}
.tm-cursor{fill:var(--text);stroke:var(--surface);stroke-width:1.5px;stroke-linejoin:round}
.tm-arrow{stroke:var(--on-accent);stroke-width:1.75px;stroke-linecap:round;stroke-linejoin:round}
.tm-badge{fill:var(--surface);stroke:var(--success);stroke-width:1.5px}
.tm-tick{stroke:var(--success);stroke-width:2px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:14;stroke-dashoffset:0}
.tm-url{fill:var(--text-subtle)}
.tm-caret{fill:var(--accent);transform:translate(146px)}
.tm-label{font-family:var(--font-mono);text-anchor:middle;fill:var(--text-subtle);font-size:8px;font-weight:500}
.tm-label--on-accent{fill:var(--on-accent);letter-spacing:.06em;font-size:8.5px}
.tm-label--chip{fill:var(--text-muted);font-size:7.5px}
.tm-keycap{font-family:var(--font-mono);text-anchor:middle;fill:var(--text);font-size:15px;font-weight:500}
.tm-keycap--on-accent{fill:var(--on-accent)}
.tm--thumbs{--tm-cycle:6.4s}
.tm-url{transform-origin:0;animation:tm-type var(--tm-cycle) var(--ease) infinite}
.tm-caret{animation:tm-caret-run var(--tm-cycle) var(--ease) infinite, tm-blink .8s steps(1, end) infinite}
.tm-get{animation:tm-press var(--tm-cycle) var(--ease) infinite}
.tm-pop{animation:tm-pop var(--tm-cycle) var(--ease) infinite backwards}
.tm-pop--2{animation-delay:.12s}
.tm-pop--3{animation-delay:.24s}
.tm-save{opacity:0;animation:tm-save var(--tm-cycle) var(--ease) infinite}
.tm-save .tm-arrow{animation:tm-arrow-dip var(--tm-cycle) var(--ease) infinite}
.tm--thumbs .tm-done{animation:tm-thumbs-done var(--tm-cycle) var(--ease) infinite}
.tm--thumbs .tm-tick{animation:tm-thumbs-draw var(--tm-cycle) var(--ease) infinite}
.tm--shot{--tm-cycle:7s}
.tm-ctl{animation:tm-ctl var(--tm-cycle) var(--ease) infinite}
.tm--shot .tm-fill{transform-origin:0;animation:tm-progress var(--tm-cycle) linear infinite;transform:scaleX(.55)}
.tm-cursor{opacity:0;animation:tm-cursor var(--tm-cycle) var(--ease) infinite;transform:translate(232px,150px)}
.tm-brackets{opacity:0;animation:tm-brackets var(--tm-cycle) var(--ease) infinite}
.tm-flash{fill:none;stroke:var(--accent);stroke-width:2px;opacity:0;animation:tm-flash var(--tm-cycle) var(--ease) infinite}
.tm--shot .tm-still{animation:tm-shot-still var(--tm-cycle) var(--ease) infinite}
.tm--shot .tm-done{animation:tm-shot-done var(--tm-cycle) var(--ease) infinite}
.tm--shot .tm-tick{animation:tm-shot-draw var(--tm-cycle) var(--ease) infinite}
.tm--step{--tm-cycle:4.8s}
.tm-ball{animation:tm-ball-step var(--tm-cycle) steps(6, end) infinite}
.tm-head{fill:var(--accent-soft);stroke:var(--accent);stroke-width:1.75px;animation:tm-head-step var(--tm-cycle) steps(6, end) infinite}
.tm-count{animation:tm-count-step var(--tm-cycle) steps(6, end) infinite}
.tm-key--fwd{animation:tm-key-dip .8s var(--ease) infinite}
.tm-keypress{opacity:0;animation:.8s step-end infinite tm-key-press}
.tm--step .tm-label--note{text-anchor:start;animation:tm-note-pulse .8s var(--ease) infinite}
.tm--file{--tm-cycle:7s}
.tm-drop{opacity:0;animation:tm-march 1.4s linear infinite, tm-drop var(--tm-cycle) var(--ease) infinite}
.tm-drop-hit{fill:none;stroke:var(--accent);stroke-width:2px;stroke-dasharray:7 5;opacity:0;animation:tm-march 1.4s linear infinite, tm-drop-hit var(--tm-cycle) var(--ease) infinite}
.tm-filecard{opacity:0;animation:tm-file-drop var(--tm-cycle) linear infinite}
.tm-video{animation:tm-video var(--tm-cycle) var(--ease) infinite}
.tm-scrub{fill:var(--accent);animation:tm-scrub var(--tm-cycle) var(--ease) infinite;transform:translate(150px)}
.tm--file .tm-still{animation:tm-file-still var(--tm-cycle) var(--ease) infinite}
.tm--file .tm-done{animation:tm-file-done var(--tm-cycle) var(--ease) infinite}
.tm--file .tm-tick{animation:tm-file-draw var(--tm-cycle) var(--ease) infinite}
.tm--count{--tm-cycle:6.6s}
.tm-scan{fill:var(--accent);opacity:0;animation:tm-count-scan var(--tm-cycle) var(--ease) infinite}
.tm-stat-num{font-family:var(--font-display);letter-spacing:var(--track-display);text-anchor:middle;fill:var(--text);font-size:15px;font-weight:700}
.tm-stat-num--on-accent{fill:var(--on-accent)}
.tm-line{fill:var(--surface-inset);transform-origin:0;animation:tm-count-type var(--tm-cycle) var(--ease) infinite backwards}
.tm-line--2{animation-delay:45ms}
.tm-line--3{animation-delay:90ms}
.tm-line--4{animation-delay:.135s}
.tm-line--5{animation-delay:.18s}
.tm-line--6{animation-delay:.225s}
.tm-line--7{animation-delay:.27s}
.tm-line--8{animation-delay:.315s}
.tm-stat{animation:tm-count-stat var(--tm-cycle) var(--ease) infinite backwards}
.tm-stat--2{animation-delay:.1s}
.tm-stat--3{animation-delay:.2s}
.tm-roll{animation:tm-count-roll var(--tm-cycle) steps(1, end) infinite;transform:translateY(-57px)}
.tm--case{--tm-cycle:6.4s}
.tm-case-text{font-family:var(--font-mono);text-anchor:start;fill:var(--text);animation:tm-uuid-write var(--tm-cycle) var(--ease) infinite backwards;font-size:13px;font-weight:500}
.tm-case-in{fill:var(--text-muted);animation:tm-case-in var(--tm-cycle) var(--ease) infinite}
.tm-case-chip{animation:tm-case-chip var(--tm-cycle) var(--ease) infinite backwards}
.tm-case-chip--2{animation-delay:60ms}
.tm-case-chip--3{animation-delay:.12s}
.tm-case-picked{animation:tm-case-picked var(--tm-cycle) var(--ease) infinite}
.tm-case-out{animation:tm-case-out var(--tm-cycle) var(--ease) infinite}
.tm-rollfade{animation:tm-count-fade var(--tm-cycle) var(--ease) infinite}
.tm--json{--tm-cycle:6.8s}
.tm-code{fill:var(--surface-inset)}
.tm-json-caret{fill:var(--text-subtle)}
.tm-json-flat{opacity:0;animation:tm-json-clear var(--tm-cycle) var(--ease) infinite}
.tm-json-flat rect{transform-origin:0;animation:tm-json-paste var(--tm-cycle) var(--ease) infinite backwards}
.tm-json-flat rect:nth-child(2){animation-delay:60ms}
.tm-json-flat rect:nth-child(3){animation-delay:.12s}
.tm-json-scan{fill:var(--accent);opacity:0;animation:tm-json-scan var(--tm-cycle) var(--ease) infinite}
.tm-json-line{animation:tm-json-line var(--tm-cycle) var(--ease) infinite backwards}
.tm-json-line--2{animation-delay:40ms}
.tm-json-line--3{animation-delay:80ms}
.tm-json-line--4{animation-delay:.12s}
.tm-json-line--5{animation-delay:.16s}
.tm-json-line--6{animation-delay:.2s}
.tm-json-line--7{animation-delay:.24s}
.tm-json-line--8{animation-delay:.28s}
.tm-json-card{animation:tm-json-card var(--tm-cycle) var(--ease) infinite}
.tm-json-row{animation:tm-json-row var(--tm-cycle) var(--ease) infinite backwards}
.tm-json-row--2{animation-delay:70ms}
.tm-json-row--3{animation-delay:.14s}
.tm-json-row--4{animation-delay:.21s}
.tm--json .tm-done{animation:tm-json-done var(--tm-cycle) var(--ease) infinite}
.tm--json .tm-tick{animation:tm-json-draw var(--tm-cycle) var(--ease) infinite}
.tm--csv{--tm-cycle:7s}
.tm-csv-key,.tm-csv-comma{fill:var(--text-subtle)}
.tm-csv-head{fill:var(--accent-soft);stroke:var(--accent);stroke-width:1px;animation:tm-csv-head var(--tm-cycle) var(--ease) infinite}
.tm-csv-row{animation:tm-csv-row var(--tm-cycle) var(--ease) infinite backwards}
.tm-csv-row--2{animation-delay:60ms}
.tm-csv-row--3{animation-delay:.12s}
.tm-csv-row--4{animation-delay:.18s}
.tm-csv-row--5{animation-delay:.24s}
.tm-csv-scan{fill:var(--accent);opacity:0;animation:tm-csv-scan var(--tm-cycle) var(--ease) infinite}
.tm-csv-card{animation:tm-csv-card var(--tm-cycle) var(--ease) infinite}
.tm-csv-out{animation:tm-csv-out var(--tm-cycle) var(--ease) infinite backwards}
.tm-csv-out--2{animation-delay:60ms}
.tm-csv-out--3{animation-delay:.12s}
.tm-csv-out--4{animation-delay:.18s}
.tm-csv-out--5{animation-delay:.24s}
.tm--csv .tm-done{animation:tm-json-done var(--tm-cycle) var(--ease) infinite}
.tm--csv .tm-tick{animation:tm-json-draw var(--tm-cycle) var(--ease) infinite}
.tm--grad{--tm-cycle:7.2s}
.tm-grad-a{stop-color:var(--surface-inset)}
.tm-grad-b{stop-color:var(--border-strong)}
.tm-grad-c{stop-color:var(--text)}
.tm-grad-band{fill:url(#tm-grad-ramp)}
.tm-grad-wipe{fill:var(--surface);animation:tm-grad-wipe var(--tm-cycle) var(--ease) infinite;transform:translate(150px)}
.tm-grad-stop{animation:tm-grad-stop var(--tm-cycle) var(--ease) infinite backwards}
.tm-grad-stop--2{animation-delay:90ms}
.tm-grad-stop--3{animation-delay:.18s}
.tm-grad-eye{fill:var(--text-subtle)}
.tm-grad-sel{fill:var(--surface);stroke:var(--accent);stroke-width:2px}
.tm-grad-arrow{stroke:var(--text);stroke-width:1.6px;stroke-linecap:round}
.tm-grad-prop{fill:var(--text-subtle)}
.tm-grad-card{animation:tm-grad-card var(--tm-cycle) var(--ease) infinite}
.tm-grad-line{animation:tm-grad-line var(--tm-cycle) var(--ease) infinite backwards}
.tm-grad-line--2{animation-delay:60ms}
.tm-grad-line--3{animation-delay:.12s}
.tm-grad-line--4{animation-delay:.18s}
.tm-grad-line--5{animation-delay:.24s}
.tm-grad-line--6{animation-delay:.3s}
.tm--grad .tm-done{animation:tm-json-done var(--tm-cycle) var(--ease) infinite}
.tm--grad .tm-tick{animation:tm-json-draw var(--tm-cycle) var(--ease) infinite}
.tm--fc{--tm-cycle:7.6s}
.tm-fc-term{fill:var(--text-subtle)}
.tm-fc-sep{fill:var(--border-strong)}
.tm-fc-row{animation:tm-fc-row var(--tm-cycle) var(--ease) infinite backwards}
.tm-fc-row--2{animation-delay:60ms}
.tm-fc-row--3{animation-delay:.12s}
.tm-fc-row--4{animation-delay:.18s}
.tm-fc-row--5{animation-delay:.24s}
.tm-fc-scan{fill:var(--accent);opacity:0;animation:tm-fc-scan var(--tm-cycle) var(--ease) infinite}
.tm-fc-deck{animation:tm-fc-deck var(--tm-cycle) var(--ease) infinite}
.tm-fc-card{animation:tm-fc-card var(--tm-cycle) var(--ease) infinite backwards;animation-delay:80ms}
.tm-fc-front{opacity:0;animation:tm-fc-front var(--tm-cycle) var(--ease) infinite;transform:scaleX(0)}
.tm-fc-back{animation:tm-fc-back var(--tm-cycle) var(--ease) infinite}
.tm-fc-key{animation:tm-fc-deck var(--tm-cycle) var(--ease) infinite}
.tm-fc-keypress{opacity:0;animation:tm-fc-press var(--tm-cycle) var(--ease) infinite}
.tm--fc .tm-done{animation:tm-json-done var(--tm-cycle) var(--ease) infinite}
.tm--fc .tm-tick{animation:tm-json-draw var(--tm-cycle) var(--ease) infinite}
.tm--convert{--tm-cycle:7s}
.tm-cv-in{animation:tm-cv-in var(--tm-cycle) var(--ease) infinite}
.tm-cv-arrow{stroke:var(--border-strong);stroke-width:2px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:52;animation:tm-cv-draw var(--tm-cycle) var(--ease) infinite}
.tm-cv-arrow--head{animation-delay:.14s;animation-fill-mode:backwards}
.tm-cv-out{animation:tm-cv-out var(--tm-cycle) var(--ease) infinite}
.tm-cv-done{animation:tm-cv-done var(--tm-cycle) var(--ease) infinite}
.tm-cv-tick{stroke:var(--success);stroke-width:2.2px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:16;animation:tm-cv-tick var(--tm-cycle) var(--ease) infinite}
.tm-cv-pill{fill:var(--accent);animation:tm-cv-pill var(--tm-cycle) var(--ease) infinite}
.tm-cv-lit{animation:var(--tm-cycle) var(--ease) infinite}
.tm-cv-lit--a{opacity:0;animation-name:tm-cv-lit-a}
.tm-cv-lit--b{animation-name:tm-cv-lit-b}
.tm--compress{--tm-cycle:7s}
.tm-cp-line{stroke:var(--text);stroke-width:1.5px}
.tm-cp-grip{fill:var(--text)}
.tm-cp-chev{stroke:var(--surface);stroke-width:1.4px;stroke-linecap:round;stroke-linejoin:round}
.tm-cp-div{animation:tm-cp-div var(--tm-cycle) var(--ease) infinite}
.tm-cp-barbefore{fill:var(--border-strong)}
.tm-cp-barafter{fill:var(--accent);transform-origin:0;animation:tm-cp-bar var(--tm-cycle) var(--ease) infinite;transform:scaleX(.21)}
.tm-cp-read{animation:tm-cp-read var(--tm-cycle) var(--ease) infinite}
.tm-cp-rail{stroke:var(--border-strong);stroke-width:2px;stroke-linecap:round}
.tm-cp-thumb{fill:var(--accent);animation:tm-cp-thumb var(--tm-cycle) var(--ease) infinite}
.tm-cp-tick{stroke:var(--success);stroke-width:2px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:14;stroke-dashoffset:0;animation:tm-cp-tick var(--tm-cycle) var(--ease) infinite}
.tm-cp-done{animation:tm-cp-done var(--tm-cycle) var(--ease) infinite}
.tm--resize{--tm-cycle:7s}
.tm-rz-pic{animation:tm-rz-pic var(--tm-cycle) var(--ease) infinite;transform:scale(.55)}
.tm-rz-ghost{stroke:var(--border-strong);stroke-width:1.5px;stroke-dasharray:4 4;animation:tm-rz-ghost var(--tm-cycle) var(--ease) infinite}
.tm-rz-field{fill:var(--accent)}
.tm-rz-typed{animation:tm-rz-typed var(--tm-cycle) var(--ease) infinite}
.tm-rz-derived{animation:tm-rz-derived var(--tm-cycle) var(--ease) infinite}
.tm-rz-read{animation:tm-rz-read var(--tm-cycle) var(--ease) infinite}
.tm-rz-done{animation:tm-rz-done var(--tm-cycle) var(--ease) infinite}
.tm-rz-tick{stroke:var(--success);stroke-width:2.2px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:16;animation:tm-rz-tick var(--tm-cycle) var(--ease) infinite}
.tm--uuid{--tm-cycle:6.6s}
.tm-uuid-hex{font-family:var(--font-mono);text-anchor:start;fill:var(--text);font-size:8px;font-weight:500}
.tm-uuid-ring{fill:none;stroke:var(--accent);stroke-width:1.75px}
.tm-uuid-pick{animation:tm-uuid-pick var(--tm-cycle) var(--ease) infinite}
.tm-uuid-hex--2{animation-delay:70ms}
.tm-uuid-hex--3{animation-delay:.14s}
.tm-uuid-hex--4{animation-delay:.21s}
.tm-uuid-hex--5{animation-delay:.28s}
.tm-uuid-out,.tm-uuid-copy{animation:tm-uuid-land var(--tm-cycle) var(--ease) infinite backwards}
.tm-uuid-copy{animation-delay:.12s}
.tm--uuid .tm-done{animation:tm-uuid-done var(--tm-cycle) var(--ease) infinite}
.tm--lorem{--tm-cycle:6.8s}
.tm-lorem-dial{animation:tm-lorem-dial var(--tm-cycle) steps(1, end) infinite;transform:translateY(-44px)}
.tm-lorem-caret{fill:var(--accent);opacity:0;animation:tm-lorem-caret var(--tm-cycle) var(--ease) infinite}
.tm-lorem-seg{fill:none;stroke:var(--border-strong);stroke-width:1.25px}
.tm-lorem-line{fill:var(--surface-inset);transform-origin:0;animation:tm-lorem-write var(--tm-cycle) var(--ease) infinite backwards}
.tm-lorem-line--2{animation-delay:55ms}
.tm-lorem-line--3{animation-delay:.11s}
.tm-lorem-line--4{animation-delay:.19s}
.tm-lorem-line--5{animation-delay:.245s}
.tm-lorem-line--6{animation-delay:.3s}
.tm-lorem-line--7{animation-delay:.38s}
.tm-lorem-out,.tm-lorem-copy{animation:tm-lorem-land var(--tm-cycle) var(--ease) infinite backwards}
.tm-lorem-copy{animation-delay:.12s}
.tm--lorem .tm-done{animation:tm-lorem-done var(--tm-cycle) var(--ease) infinite}
.tm--qr{--tm-cycle:7s}
.tm-qr-url{fill:var(--text-subtle);transform-origin:0;animation:tm-qr-type var(--tm-cycle) var(--ease) infinite}
.tm-qr-caret{fill:var(--accent);animation:tm-qr-caret var(--tm-cycle) var(--ease) infinite, tm-blink .875s steps(1, end) infinite;transform:translate(70px)}
.tm-qr-chip--on{fill:var(--surface-inset);stroke:var(--border-strong)}
.tm-qr-finder{animation:tm-qr-land var(--tm-cycle) var(--ease) infinite backwards}
.tm-qr-finder--2{animation-delay:90ms}
.tm-qr-finder--3{animation-delay:.18s}
.tm-qr-m{animation:tm-qr-fill var(--tm-cycle) var(--ease) infinite backwards}
.tm-qr-m--1{animation-delay:20ms}
.tm-qr-m--2{animation-delay:40ms}
.tm-qr-m--3{animation-delay:60ms}
.tm-qr-m--4{animation-delay:80ms}
.tm-qr-m--5{animation-delay:.1s}
.tm-qr-m--6{animation-delay:.12s}
.tm-qr-m--7{animation-delay:.14s}
.tm-qr-m--8{animation-delay:.16s}
.tm-qr-m--9{animation-delay:.18s}
.tm-qr-m--10{animation-delay:.2s}
.tm-qr-m--11{animation-delay:.22s}
.tm-qr-m--12{animation-delay:.24s}
.tm-qr-m--13{animation-delay:.26s}
.tm-qr-m--14{animation-delay:.28s}
.tm-qr-m--15{animation-delay:.3s}
.tm-qr-m--16{animation-delay:.32s}
.tm-qr-m--17{animation-delay:.34s}
.tm-qr-m--18{animation-delay:.36s}
.tm-qr-m--19{animation-delay:.38s}
.tm-qr-m--20{animation-delay:.4s}
.tm-qr-m--21{animation-delay:.42s}
.tm-qr-m--22{animation-delay:.44s}
.tm-qr-m--23{animation-delay:.46s}
.tm-qr-m--24{animation-delay:.48s}
.tm-qr-out{animation:tm-qr-out var(--tm-cycle) var(--ease) infinite backwards}
.tm-qr-out--2{animation-delay:.11s}
.tm--qr .tm-qr-done{animation:tm-qr-done var(--tm-cycle) var(--ease) infinite}
.tm--cutout{--tm-cycle:7s}
.tm-cut-outline{fill:none;stroke:var(--accent);stroke-width:2px;stroke-linejoin:round;stroke-dasharray:6 4;animation:tm-cut-trace var(--tm-cycle) var(--ease) infinite}
.tm-cut-subject{animation:tm-cut-lift var(--tm-cycle) var(--ease) infinite}
.tm-cut-shaft,.tm-cut-head{stroke:var(--border-strong);stroke-width:2px;stroke-linecap:round;stroke-linejoin:round;fill:none}
.tm-cut-arrow{animation:tm-cut-arrow var(--tm-cycle) var(--ease) infinite}
.tm-cut-check{fill:var(--surface-inset)}
.tm-cut-checks{animation:tm-cut-checks var(--tm-cycle) var(--ease) infinite}
.tm-cut-result{animation:tm-cut-result var(--tm-cycle) var(--ease) infinite}
.tm--cutout .tm-cut-done{animation:tm-cut-done var(--tm-cycle) var(--ease) infinite}
.tm--typing{--tm-cycle:7.2s}
.tm-type-bar{fill:var(--surface-inset);animation:tm-type-in var(--tm-cycle) var(--ease) infinite}
.tm-type-wipe--1{animation:tm-type-wipe1 var(--tm-cycle) var(--ease) infinite;transform:translate(204px)}
.tm-type-wipe--2{animation:tm-type-wipe2 var(--tm-cycle) var(--ease) infinite;transform:translate(194px)}
.tm-type-caret{fill:var(--accent);animation:tm-type-caret var(--tm-cycle) var(--ease) infinite;transform:translate(190px,20px)}
.tm-type-wrong{fill:var(--warning);animation:tm-type-wrong var(--tm-cycle) var(--ease) infinite}
.tm-type-out{animation:tm-type-out var(--tm-cycle) var(--ease) infinite}
.tm-type-wpm{font-family:var(--font-display);letter-spacing:var(--track-display);fill:var(--text);font-size:30px;font-weight:700}
.tm-type-unit{font-family:var(--font-mono);fill:var(--text-subtle);font-size:8px;font-weight:500}
.tm-type-cap{fill:var(--surface-inset)}
.tm--pom{--tm-cycle:8s}
.tm-pom-pick{animation:tm-pom-pick var(--tm-cycle) var(--ease) infinite backwards}
.tm-pom-pick--2{animation-delay:70ms}
.tm-pom-pick--3{animation-delay:.14s}
.tm-pom-on{animation:tm-pom-on var(--tm-cycle) var(--ease) infinite}
.tm-pom-dial{animation:tm-pom-dial var(--tm-cycle) var(--ease) infinite backwards;animation-delay:.1s}
.tm-pom-track{stroke:var(--surface-inset);stroke-width:9px}
.tm-pom-ring{stroke:var(--accent);stroke-width:9px;stroke-linecap:round;stroke-dasharray:264;stroke-dashoffset:0;animation:tm-pom-ring var(--tm-cycle) linear infinite;transform:rotate(-90deg)}
.tm-pom-time{font-family:var(--font-mono);text-anchor:middle;fill:var(--text);font-size:21px;font-weight:600}
.tm-pom-time--a{opacity:0;animation:tm-pom-time-a var(--tm-cycle) steps(1, end) infinite}
.tm-pom-time--b{opacity:0;animation:tm-pom-time-b var(--tm-cycle) steps(1, end) infinite}
.tm-pom-time--c{animation:tm-pom-time-c var(--tm-cycle) steps(1, end) infinite}
.tm-pom-mode--a{opacity:0;animation:tm-pom-mode-a var(--tm-cycle) steps(1, end) infinite}
.tm-pom-mode--b{animation:tm-pom-time-c var(--tm-cycle) steps(1, end) infinite}
.tm-pom-out{animation:tm-pom-out var(--tm-cycle) var(--ease) infinite backwards;animation-delay:.18s}
.tm-pom-dot{fill:var(--surface-inset);stroke:var(--border);stroke-width:1px}
.tm-pom-done{animation:tm-pom-done var(--tm-cycle) var(--ease) infinite}
.tm-pom-clock{fill:var(--text);font-size:10px;font-weight:600}
.tm--pad .tm-line{fill:var(--surface-inset);transform-origin:0;animation:tm-pad-write 8s var(--ease) infinite backwards}
.tm--pad .tm-pad-line--2{animation-delay:.28s}
.tm--pad .tm-pad-line--3{animation-delay:.56s}
.tm--pad .tm-pad-line--4{animation-delay:.84s}
.tm--pad .tm-pad-line--5{animation-delay:1.12s}
.tm--pad .tm-pad-line--6{animation-delay:1.4s}
.tm--pad .tm-pad-caret{fill:var(--accent);opacity:0;animation:8s step-end infinite tm-pad-caret}
.tm--pad .tm-pad-pill{fill:var(--success-soft);stroke:var(--success);stroke-width:1.25px}
.tm--pad .tm-pad-tick{fill:none;stroke:var(--success);stroke-width:2px;stroke-linecap:round;stroke-linejoin:round}
.tm--pad .tm-pad-saved{fill:var(--success);text-anchor:middle}
.tm--pad .tm-pad-save{animation:tm-pad-pop 8s var(--ease) infinite}
.tm--pad .tm-pad-arrow{fill:none;stroke:var(--border-strong);stroke-width:1.5px;stroke-linecap:round;stroke-linejoin:round;animation:tm-pad-fade 8s var(--ease) infinite}
.tm--pad .tm-pad-return{animation:tm-pad-fade 8s var(--ease) infinite}
.tm--pad .tm-pad-back{fill:var(--on-accent);opacity:.55}
.is-workspace :is(.tm,.hm,.cg-svg),.is-workspace :is(.tm,.hm,.cg-svg) *{animation-play-state:paused}
@media (prefers-reduced-motion:reduce){:is(.tm,.hm,.cg-svg),:is(.tm,.hm,.cg-svg) *{animation:none!important}}
.tm-tr-code{font-family:var(--font-mono);letter-spacing:.04em;text-anchor:middle;fill:var(--accent-text);font-size:22px;font-weight:600}
.tm-tr-link{stroke:var(--accent);stroke-width:1.75px;stroke-dasharray:5 4}
.tm-tr-file{fill:var(--surface-inset)}
.tm-tr-pkt{opacity:0}
@media (prefers-reduced-motion:no-preference){.tm--transfer .tm-tr-code{animation:tm-tr-code var(--tm-cycle) var(--ease) infinite}.tm--transfer .tm-tr-phone{animation:tm-tr-phone var(--tm-cycle) var(--ease) infinite backwards}.tm--transfer .tm-tr-link{animation:tm-tr-draw var(--tm-cycle) var(--ease) infinite backwards, tm-tr-march 1.1s linear infinite}.tm--transfer .tm-tr-pkt{offset-path:path("M140 76C172 44 214 44 242 74");offset-rotate:0deg;animation:tm-tr-fly var(--tm-cycle) var(--ease) infinite backwards}.tm--transfer .tm-tr-pkt--2{animation-delay:.13s}.tm--transfer .tm-tr-pkt--3{animation-delay:.26s}.tm--transfer .tm-tr-file{animation:tm-tr-land var(--tm-cycle) var(--ease) infinite backwards}.tm--transfer .tm-tr-file--2{animation-delay:.13s}.tm--transfer .tm-tr-file--3{animation-delay:.26s}.tm--transfer .tm-tr-done{animation:tm-tr-done var(--tm-cycle) var(--ease) infinite}}
.tm--trim{--tm-cycle:7s}
.tm-tr-bar{fill:var(--border-strong)}
.tm-tr-bar--in{fill:var(--text)}
.tm-tr-veil{fill:var(--bg-subtle);opacity:.82}
.tm-tr-veil--l{transform-origin:0;animation:tm-tr-veil-l var(--tm-cycle) var(--ease) infinite}
.tm-tr-veil--r{transform-origin:100%;animation:tm-tr-veil-r var(--tm-cycle) var(--ease) infinite}
.tm-tr-edge{stroke:var(--accent);stroke-width:1.75px}
.tm-tr-grip{fill:var(--accent)}
.tm-tr-hl{animation:tm-tr-hl var(--tm-cycle) var(--ease) infinite}
.tm-tr-hr{animation:tm-tr-hr var(--tm-cycle) var(--ease) infinite}
.tm-tr-out{animation:tm-tr-out var(--tm-cycle) var(--ease) infinite}
.tm-tr-done .tm-tick{animation:tm-tr-tick var(--tm-cycle) var(--ease) infinite}
.tm--pdf{--tm-cycle:7.2s}
.tm-pd-shot{animation:tm-pd-shot var(--tm-cycle) var(--ease) infinite;animation-fill-mode:backwards}
.tm-pd-shot--2{animation-delay:.16s}
.tm-pd-shot--3{animation-delay:.32s}
.tm-pd-rail{stroke:var(--border-strong);stroke-width:1.5px;stroke-linecap:round}
.tm-pd-head{stroke:var(--border-strong);stroke-width:1.75px;stroke-linecap:round;stroke-linejoin:round;fill:none}
.tm-pd-cross{animation:tm-pd-cross var(--tm-cycle) var(--ease) infinite}
.tm-pd-doc{animation:tm-pd-doc var(--tm-cycle) var(--ease) infinite}
.tm-pd-back{animation:tm-pd-back var(--tm-cycle) var(--ease) infinite;animation-fill-mode:backwards}
.tm-pd-back--1{animation-delay:.12s}
.tm-pd-back--2{animation-delay:.24s}
.tm-pd-line{stroke:var(--border-strong);stroke-width:2px;stroke-linecap:round}
.tm-pd-done .tm-tick{animation:tm-pd-tick var(--tm-cycle) var(--ease) infinite}
.tm-pd-chip{animation:tm-pd-chip var(--tm-cycle) var(--ease) infinite}
.tm--sign{--tm-cycle:7s}
.tm-sg-line{stroke:var(--border-strong);stroke-width:2px;stroke-linecap:round}
.tm-sg-rule{stroke:var(--border-strong);stroke-width:1.5px;stroke-linecap:round}
.tm-sg-in .tm-sg-rule{stroke-dasharray:4 4}
.tm-sg-in{animation:tm-sg-in var(--tm-cycle) var(--ease) infinite}
.tm-sg-rail{stroke:var(--border-strong);stroke-width:1.5px;stroke-linecap:round}
.tm-sg-head{stroke:var(--border-strong);stroke-width:1.75px;stroke-linecap:round;stroke-linejoin:round;fill:none}
.tm-sg-cross{animation:tm-sg-cross var(--tm-cycle) var(--ease) infinite}
.tm-sg-out{animation:tm-sg-out var(--tm-cycle) var(--ease) infinite}
.tm-sg-ink{stroke:var(--accent);stroke-width:2.25px;stroke-linecap:round;stroke-linejoin:round;fill:none;stroke-dasharray:118;stroke-dashoffset:0;animation:tm-sg-ink var(--tm-cycle) var(--ease) infinite}
.tm-sg-done .tm-tick{animation:tm-sg-tick var(--tm-cycle) var(--ease) infinite}
.tm-sg-chip{animation:tm-sg-chip var(--tm-cycle) var(--ease) infinite}
.tm--ocr{--tm-cycle:7.6s}
.tm-ocr-ink rect{fill:var(--surface-inset)}
.tm-ocr-beam{fill:var(--accent);opacity:0;animation:tm-ocr-beam var(--tm-cycle) linear infinite}
.tm-ocr-box{fill:color-mix(in oklab, var(--accent) 12%, transparent);stroke:color-mix(in oklab, var(--accent) 55%, transparent);stroke-width:1px;animation:tm-ocr-box var(--tm-cycle) ease-out infinite backwards;animation-delay:calc(var(--i) * .2s)}
.tm-ocr-box--doubt{fill:color-mix(in oklab, var(--warning) 20%, transparent);stroke:color-mix(in oklab, var(--warning) 75%, transparent)}
.tm-ocr-line{fill:var(--text-subtle);animation:tm-ocr-line var(--tm-cycle) ease-out infinite backwards;animation-delay:calc(var(--i) * .18s);transform-origin:0}
.tm-ocr-line--doubt{fill:color-mix(in oklab, var(--warning) 55%, var(--text-subtle))}
.tm-ocr-mark{animation:tm-ocr-mark var(--tm-cycle) ease-out infinite}
.tm-ocr-squiggle{stroke:var(--warning);stroke-width:1.4px;stroke-linecap:round;fill:none}
.tm--ocr .tm-done{animation:tm-ocr-done var(--tm-cycle) ease-out infinite}
.tm--behind{--tm-cycle:7.2s}
.tm-tbi-horizon{stroke:var(--border);stroke-width:1.25px}
.tm-tbi-figa{fill:var(--surface-inset)}
.tm-tbi-trace circle,.tm-tbi-trace path{fill:none;stroke:var(--accent);stroke-width:1.6px;stroke-dasharray:100;stroke-dashoffset:0;opacity:0;animation:tm-tbi-trace var(--tm-cycle) ease-in-out infinite}
.tm-tbi-word rect{fill:var(--accent);transform-origin:0;animation:tm-tbi-word var(--tm-cycle) ease-out infinite backwards;animation-delay:calc(var(--i) * .16s)}
.tm-tbi-figb{fill:var(--surface-inset);stroke:var(--border-strong);stroke-width:1.25px;animation:tm-tbi-figb var(--tm-cycle) var(--ease) infinite}
.tm--behind .tm-done{animation:tm-tbi-done var(--tm-cycle) ease-out infinite}
.tm-pi-source{animation:6s ease-in-out infinite tm-pi-source}
.tm-pi-page{animation:6s ease-in-out infinite backwards tm-pi-page;animation-delay:calc(var(--pi-i) * .18s)}
.tm-pi-arrow{animation:6s ease-in-out infinite tm-pi-arrow}
@media (prefers-reduced-motion:reduce){.tm-pi-source,.tm-pi-page,.tm-pi-arrow{animation:none}}
.tm-sp-doc{animation:6s ease-in-out infinite backwards tm-sp-doc}
.tm-sp-blade{animation:6s ease-in-out infinite backwards tm-sp-blade}
.tm-sp-out{animation:6s ease-in-out infinite backwards tm-sp-out;animation-delay:calc(var(--sp-i) * .14s)}
@media (prefers-reduced-motion:reduce){.tm-sp-doc,.tm-sp-blade,.tm-sp-out{animation:none}}
.tm-mg-in{animation:6s ease-in-out infinite backwards tm-mg-in;animation-delay:calc(var(--mg-i) * .16s)}
.tm-mg-page{animation:6s ease-in-out infinite backwards tm-mg-page;animation-delay:calc(var(--mg-i) * .13s)}
.tm-mg-out{animation:6s ease-in-out infinite tm-mg-out}
@media (prefers-reduced-motion:reduce){.tm-mg-in,.tm-mg-page,.tm-mg-out{animation:none}}
.tm-tts-source{animation:tm-tts-source 7s var(--ease) infinite backwards}
.tm-tts-arrow{animation:tm-tts-arrow 7s var(--ease) infinite backwards}
.tm-tts-result{animation:tm-tts-result 7s var(--ease) infinite backwards}
.tm-tts-wave path{animation:tm-tts-wave 7s var(--ease) infinite backwards;animation-delay:calc(var(--tm-i,0) * 40ms)}
@media (prefers-reduced-motion:reduce){.tm-tts-source,.tm-tts-arrow,.tm-tts-result,.tm-tts-wave path{animation:none}}
/* ── Eleven tools he does not have ────────────────────────────────────────
 *
 * The rest of this file is his system, reused with permission. These are ours
 * because the tools are ours — he has no colour tools, no calculators, no
 * line sorter and no regex tester — so there was nothing to adapt and the
 * diagrams had to be designed from what each tool actually does.
 *
 * Same conventions throughout: one --tm-cycle per variant, var(--ease) for
 * anything that moves a distance, steps() for anything that ticks, and every
 * animation switched off under prefers-reduced-motion at the end.
 *
 * The rule each one follows: show the thing that makes the tool worth using,
 * not the file going in and coming out. A colour converter that shows a file
 * arriving has explained nothing.
 */

/* Colour converter: one colour, three ways of writing it down. */
.tm--hex{--tm-cycle:6s}
@keyframes tm-hex-note{0%,10%{opacity:0;transform:translateX(-6px)}22%,92%{opacity:1;transform:none}97%,to{opacity:0}}
@keyframes tm-hex-swatch{0%,6%{opacity:0;transform:scale(.9)}18%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:scale(.9)}}
.tm-hex-swatch{transform-origin:center;animation:tm-hex-swatch var(--tm-cycle) var(--ease) infinite}
.tm-hex-note{animation:tm-hex-note var(--tm-cycle) var(--ease) infinite backwards;animation-delay:calc(var(--i) * .5s)}

/* Contrast: the number, and whether it passes. */
.tm--ratio{--tm-cycle:6.4s}
@keyframes tm-ratio-bg{0%,12%{fill:var(--surface-inset)}40%,92%{fill:var(--text)}97%,to{fill:var(--surface-inset)}}
@keyframes tm-ratio-fg{0%,12%{fill:var(--border-strong)}40%,92%{fill:var(--surface)}97%,to{fill:var(--border-strong)}}
@keyframes tm-ratio-pass{0%,46%{opacity:0;transform:scale(.8)}58%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:scale(.8)}}
.tm-ratio-bg{animation:tm-ratio-bg var(--tm-cycle) var(--ease) infinite}
.tm-ratio-fg{animation:tm-ratio-fg var(--tm-cycle) var(--ease) infinite}
.tm-ratio-pass{transform-origin:center;animation:tm-ratio-pass var(--tm-cycle) var(--ease) infinite}

/* Palette: one colour becomes a set. */
.tm--fan{--tm-cycle:6.6s}
@keyframes tm-fan-out{0%,14%{opacity:0;transform:translateX(-26px) scale(.8)}34%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:translateX(-26px) scale(.8)}}
.tm-fan{transform-origin:center;animation:tm-fan-out var(--tm-cycle) var(--ease) infinite backwards;animation-delay:calc(var(--i) * .13s)}

/* Colour extractor: the colours lift out of the picture. */
.tm--pick{--tm-cycle:6.8s}
@keyframes tm-pick-lift{0%,20%{opacity:0;transform:translateY(-14px) scale(.7)}42%,92%{opacity:1;transform:none}97%,to{opacity:0}}
.tm-pick{transform-origin:center;animation:tm-pick-lift var(--tm-cycle) var(--ease) infinite backwards;animation-delay:calc(var(--i) * .15s)}

/* Line sorter: the lines reorder, and the duplicate goes. */
.tm--sort{--tm-cycle:6.4s}
@keyframes tm-sort-move{0%,22%{transform:translateY(var(--from))}46%,92%{transform:translateY(0)}97%,to{transform:translateY(var(--from))}}
@keyframes tm-sort-drop{0%,56%{opacity:1}72%,92%{opacity:.18}97%,to{opacity:1}}
.tm-sort-row{animation:tm-sort-move var(--tm-cycle) var(--ease) infinite}
.tm-sort-dupe{animation:tm-sort-drop var(--tm-cycle) var(--ease) infinite}

/* Regex: the matches land on the text. */
.tm--match{--tm-cycle:6s}
@keyframes tm-match-hit{0%,26%{opacity:0;transform:scaleX(0)}42%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:scaleX(0)}}
.tm-match{transform-origin:left;animation:tm-match-hit var(--tm-cycle) var(--ease) infinite backwards;animation-delay:calc(var(--i) * .18s)}

/* GIF: the frames cycle, and the file gets small enough to post. */
.tm--gif{--tm-cycle:5.4s}
@keyframes tm-gif-frame{0%,100%{opacity:0}}
.tm-gif-frame{opacity:0;animation:tm-gif-show var(--tm-cycle) steps(1,end) infinite;animation-delay:calc(var(--i) * .45s)}
@keyframes tm-gif-show{0%,14%{opacity:1}15%,to{opacity:0}}
@keyframes tm-gif-size{0%,40%{opacity:0;transform:translateY(6px)}54%,92%{opacity:1;transform:none}97%,to{opacity:0}}
.tm-gif-size{animation:tm-gif-size var(--tm-cycle) var(--ease) infinite}

/* Percentage: three questions, asked one at a time. */
.tm--pct{--tm-cycle:7.2s}
@keyframes tm-pct-row{0%,8%{opacity:.28}18%,30%{opacity:1}40%,to{opacity:.28}}
.tm-pct-row{animation:tm-pct-row var(--tm-cycle) var(--ease) infinite;animation-delay:calc(var(--i) * 2.4s)}

/* Calculator: an expression, typed, then its answer. */
.tm--calc{--tm-cycle:6.2s}
@keyframes tm-calc-answer{0%,50%{opacity:0;transform:translateY(-6px)}62%,92%{opacity:1;transform:none}97%,to{opacity:0}}
.tm-calc-answer{animation:tm-calc-answer var(--tm-cycle) var(--ease) infinite}

/* Units: the one everybody gets wrong. */
.tm--unit{--tm-cycle:6.6s}
@keyframes tm-unit-swap{0%,30%{opacity:0;transform:translateX(10px)}44%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:translateX(10px)}}
.tm-unit-out{animation:tm-unit-swap var(--tm-cycle) var(--ease) infinite}

/* Patterns: one tile, repeated into a field. */
.tm--tile{--tm-cycle:7s}
@keyframes tm-tile-in{0%,10%{opacity:0;transform:scale(.6)}30%,92%{opacity:1;transform:none}97%,to{opacity:0;transform:scale(.6)}}
.tm-tile{transform-origin:center;animation:tm-tile-in var(--tm-cycle) var(--ease) infinite backwards;animation-delay:calc(var(--i) * .07s)}

/* Derived tones for the colour tools.
 *
 * In classes rather than fill attributes, which is how his are written and
 * not merely a style preference: an SVG presentation attribute is parsed
 * strictly and rejects color-mix(), computing to `fill: none` — the shape
 * disappears in silence. In a stylesheet the same value resolves.
 *
 * Derived from the accent rather than picked, because a palette generator
 * derives its colours from one base, and five unrelated hues would
 * misrepresent the tool as much as they clash with every other diagram.
 */
.tm-tone-1{fill:color-mix(in oklch, var(--accent) 80%, var(--text))}
.tm-tone-2{fill:color-mix(in oklch, var(--accent) 55%, var(--surface))}
.tm-tone-3{fill:color-mix(in oklch, var(--accent) 35%, var(--surface))}
.tm-tone-4{fill:color-mix(in oklch, var(--accent) 18%, var(--surface))}
.tm-tone-deep{fill:color-mix(in oklch, var(--accent) 70%, var(--text))}

@media (prefers-reduced-motion:reduce){
  .tm-hex-swatch,.tm-hex-note,.tm-ratio-bg,.tm-ratio-fg,.tm-ratio-pass,
  .tm-fan,.tm-pick,.tm-sort-row,.tm-sort-dupe,.tm-match,.tm-gif-frame,
  .tm-gif-size,.tm-pct-row,.tm-calc-answer,.tm-unit-out,.tm-tile{animation:none}
  .tm-gif-frame{opacity:1}
}
