NEMAWASHI LAB

Reveal Chips

CSS

An inline circled chip that opens a paper note without leaving the paragraph. The note renders inside a <p>, so its contents are phrasing content only -- spans and inline svg, no divs -- which is why the root diagram is drawn as raw paths rather than laid out. Hover peeks the note, a click pins it, Escape or an outside pointerdown closes it. A layout effect measures the popover against the viewport and writes a --shift custom property, so a chip near either edge slides its note back into view while the arrow stays put over the chip. The chip animates its own SRIF axis from 100 to 420 as it opens, so the circled word grows serifs while the note appears.

Nemawashi is a business design studio in Tokyo. Before code, we tend the — people aligned, viability proven. Then we ship. Fast.

We practice . Alignment before execution: stakeholders on one page, the business case proven in numbers. Then the loop runs — rough sketches become working wireframes in code, a design system grows in the same codebase. Human hands craft the screens that matter. AI carries the rest to production.

hover a circled word, click to pin

Source

RevealChips.tsx91 lines
"use client";

import { useState } from "react";
import Reveal from "@/components/Reveal";
import { RootsDetail, AugmentedDetail } from "@/components/RevealDetails";
import { paras, type Lang, type Seg } from "@/content/copy";
import ScrambleLink from "../ScrambleLink";

/* The inline reveal chip as the site uses it: a circled word inside running
   prose that peeks its note on hover and pins it on click. The note is phrasing
   content only (spans + svg) because it lives inside a <p>, and it shifts
   itself back into the viewport when it would overflow. Copy comes straight
   from content/copy.ts, so both chips (根回し and Augmented Design) carry their
   real notes in both languages. */

const [intro, practice] = paras;

const face = (lang: Lang) =>
  lang === "jp"
    ? "font-[family-name:var(--mincho)] [font-variation-settings:normal] tracking-[0.04em] leading-[1.95]"
    : "font-[family-name:var(--flux)] leading-[1.75]";

function renderSeg(seg: Seg, i: number, lang: Lang) {
  if (seg.t === "reveal") {
    return (
      <Reveal key={i} label={seg[lang]}>
        {seg.id === "roots" ? (
          <RootsDetail lang={lang} />
        ) : (
          <AugmentedDetail lang={lang} />
        )}
      </Reveal>
    );
  }
  return <span key={i}>{seg[lang]}</span>;
}

export default function RevealChips() {
  const [lang, setLang] = useState<Lang>("en");

  return (
    <div
      className="fixed inset-0 flex flex-col items-center justify-center overflow-y-auto px-8 py-10"
      style={{ background: "var(--paper)", color: "var(--ink)" }}
    >
      {/* lab-keep: the chips are <button>s carrying the effect, so the preview
          recorder's chrome-hiding rule has to leave them alone (lab.css) */}
      <div className={`lab-keep max-w-[58ch] ${face(lang)}`}>
        <p className="text-[clamp(15px,1.5vw,19px)]">
          {intro.segs.map((seg, i) => renderSeg(seg, i, lang))}
        </p>
        <p className="mt-6 text-[clamp(12px,1.15vw,14px)] opacity-70">
          {practice.segs.map((seg, i) => renderSeg(seg, i, lang))}
        </p>
      </div>

      <div className="mt-9 flex items-center gap-3 text-[11px] tracking-[0.1em] uppercase">
        {(["en", "jp"] as const).map((l) => (
          <button
            key={l}
            onClick={() => setLang(l)}
            style={{
              color: lang === l ? "var(--ink)" : "var(--faint)",
              fontFamily: "var(--flux)",
              fontVariationSettings: '"wght" 400, "SRIF" 100',
            }}
          >
            {l === "en" ? "EN" : "日本語"}
          </button>
        ))}
        <span
          className="ml-4 normal-case tracking-[0.04em]"
          style={{ color: "var(--faint)", fontFamily: "var(--flux)" }}
        >
          hover a circled word, click to pin
        </span>
      </div>

      <div className="fixed bottom-6 left-6 z-10">
        <ScrambleLink
          from="REVEAL CHIPS"
          to="← LAB"
          href="/lab"
          className="text-[11px] tracking-[0.1em] text-foreground/30 uppercase hover:text-foreground/60 transition-colors"
          style={{ fontVariationSettings: "'wght' 400, 'SRIF' 100" }}
        />
      </div>
    </div>
  );
}

NEMAWASHI — Kotaro Abe