Components / Japan / Hanko

Hanko beta

A vermillion seal that stamps: the shu-iro signature for approvals, authorship and things that are done.

Preview

Release note — Design Tokens v1.4

The token set is frozen for the spring release. Accent ramps, spacing and the vermillion core are final; parts built against v1.4 need no changes.

Approved — Mara SatoDesign lead · Nov 2, 2026
型

It stamps when it arrives. Click the seal to press it again.

<div class="k-seal-doc">
  <h3>Release note — Design Tokens v1.4</h3>
  <p>The token set is frozen for the spring release. Accent ramps, spacing and the vermillion core are final; parts built against v1.4 need no changes.</p>
  <div class="k-seal-row">
    <div class="k-seal-meta"><b>Approved — Mara Sato</b><span>Design lead · Nov 2, 2026</span></div>
    <span class="k-seal" data-seal role="img" aria-label="Seal of approval" title="Press again"><span class="k-seal-face">型</span></span>
  </div>
</div>
<p style="font-size:12.5px;color:var(--k-ink-3);margin-top:9px">It stamps when it arrives. Click the seal to press it again.</p>
/* KATA Hanko — the seal, in shu-iro. */
.k-seal-doc{font-family:var(--k-font);color:var(--k-ink);border:1px solid var(--k-line);border-radius:14px;padding:20px;background:var(--k-bg);max-width:480px}
.k-seal-doc h3{font-size:15px;font-weight:650}
.k-seal-doc p{font-size:13px;line-height:1.75;color:var(--k-ink-2);margin-top:5px}
.k-seal-row{display:flex;align-items:center;gap:16px;margin-top:16px;padding-top:16px;border-top:1px solid var(--k-line)}
.k-seal-meta b{display:block;font-size:13.5px}
.k-seal-meta span{font-size:12px;color:var(--k-ink-3)}
.k-seal{position:relative;margin-inline-start:auto;width:56px;height:56px;flex:none;cursor:pointer}
.k-seal::after{content:"";position:absolute;inset:0;border:2px solid var(--k-core);border-radius:12px;opacity:0}
.k-seal-face{position:absolute;inset:0;background:var(--k-core);color:var(--k-on-color);border-radius:9px 11px 10px 12px;display:flex;align-items:center;justify-content:center;font-family:"Hiragino Mincho ProN","YuMincho",serif;font-size:29px;font-weight:600;transform:rotate(-3deg)}
.k-seal.stamp .k-seal-face{animation:k-seal-in .5s cubic-bezier(.2,1.6,.4,1)}
.k-seal.stamp::after{animation:k-seal-ring .55s ease-out}
@keyframes k-seal-in{0%{transform:scale(2.1) rotate(-13deg);opacity:0}55%{transform:scale(.94) rotate(-2.2deg);opacity:1}78%{transform:scale(1.03) rotate(-3.2deg)}100%{transform:scale(1) rotate(-3deg)}}
@keyframes k-seal-ring{0%{transform:scale(.7);opacity:.55}100%{transform:scale(1.55);opacity:0}}
@media (prefers-reduced-motion:reduce){.k-seal.stamp .k-seal-face,.k-seal.stamp::after{animation:none}}
// KATA Hanko — stamps on arrival; click presses it again.
document.querySelectorAll('[data-seal]').forEach(function (seal) {
  function stamp() {
    seal.classList.remove('stamp');
    void seal.offsetWidth;
    seal.classList.add('stamp');
  }
  seal.addEventListener('click', stamp);
  if ('IntersectionObserver' in window) {
    var io = new IntersectionObserver(function (es) { if (es[0].isIntersecting) { setTimeout(stamp, 300); io.disconnect(); } }, { threshold: .5 });
    io.observe(seal);
  } else { stamp(); }
});

Installation

CLI

node kata-ui.mjs add hanko

Writes the part’s CSS and JS into your project. New to the CLI? See the CLI doc.

Manual

  1. Load tokens.css once, before any part.
  2. Copy the CSS tab into your stylesheet.
  3. Copy the HTML where it belongs. The part has a script — include it after the markup; it initializes itself.

Usage

The seal is cast in shu-iro — the same vermillion reserved for the mark and the live center of controls — because a hanko is exactly that: a signature with weight. It stamps in when it arrives (scale, a breath of overshoot, an ink ring that fades) and re-stamps on click. Use it where a human means it: approvals, signed releases, the end of a document that is finished.

Accessibility

The approval itself is stated in words beside the seal ("Approved — Mara Sato, Nov 2") — the stamp is the signature, not the record. The stamp-in is a transform only and is skipped under prefers-reduced-motion, where the seal simply sits, already pressed.

Anatomy

The public surface of this part, read from its own source. Class names are the API — the CSS tab above is the full contract.

.k-seal-docclass
.k-seal-rowclass
.k-seal-metaclass
.k-sealclass
.k-seal-faceclass
.stampclass
data-sealdata hook
aria-labelARIA

Related parts