Back to demoTHIS THEME’S OWN COMPONENT BOOKID

Sanak / DESIGN & COMPONENTS

Sanak
Made of its own parts.

The thick laminated menu book that lies on a family restaurant’s table, made readable on a screen. It keeps what makes it a book — a cover, chapters with tabs, a page number in the corner, a ribbon — and adds what paper cannot: an address for every page and a list view. The curl is the book’s own gesture, offered on request; the page underneath is always the real, readable page.

01 / Palette & type

A sambal-orange cover with a diagonal laminate gloss and a three-tier rantang mark, cream pages with rounded outer corners and a faint sheen, kecap-black ink, egg-yolk, blue and cream chapter tabs, a blue ribbon with a V-cut tail, dotted leaders to a blank price. Drawings are flat line art made for the study; there are no food photographs.

Sambal-orange cover#dc6224
Kecap ink#1f1a17
Ribbon blue#24519a
Laminated page#fff8ec
Egg-yolk tab#f2c64b
Cream tab#ead8b6

Rokkitt 700, a narrow geometric slab serif, sets the wordmark, chapter titles, dish names, codes, page numbers and the folio — the voice of a printed menu read across a table, narrow enough to keep a long dish name on one line. DM Sans carries descriptions, controls and notes. Zilla Slab 700 stays a recorded fallback that is not used.

02 / Composition & behavior

Two pages and a design book. The menu book shows the closed cover beside its contents, then two pages side by side from 1024px wide (a 1120px spread) and one page below that, under chapter tabs on the top edge; the book’s controls sit in the nameplate. Every page keeps one size, so a turn never moves the page around it. How to use is a column of numbered steps.

By default pages change at once, with no animation. After Open the book in 3D a page curls round a cylinder under the pointer or finger, with shade on the roll and a shadow beside it, and finishes or falls back within 0.45s; buttons, arrows and tabs play the same curl. Frames are drawn only while a sheet moves. With reduced motion 3D is not offered, and switching it on closes 3D.

Each page is an article with a heading; dishes are a list; the blank price is read as “Price not filled in”; heat has a word, never colour alone. Chapter tabs are a navigation with aria-current; the status line announces the pages and chapter; ←/→ work only while the book has focus. The canvas is hidden from assistive technology and holds no content of its own. List view shows every page for screen readers, find in page and zoom.

03 / Controls, including the edges

Two pages and a design book. The menu book shows the closed cover beside its contents, then two pages side by side from 1024px wide (a 1120px spread) and one page below that, under chapter tabs on the top edge; the book’s controls sit in the nameplate. Every page keeps one size, so a turn never moves the page around it. How to use is a column of numbered steps.

Component inventory (scroll to inspect)

  1. 01
    A laminated book with chapter tabs

    Two pages and a design book. The menu book shows the closed cover beside its contents, then two pages side by side from 1024px wide (a 1120px spread) and one page below that, under chapter tabs on the top edge; the book’s controls sit in the nameplate. Every page keeps one size, so a turn never moves the page around it. How to use is a column of numbered steps.

  2. 02
    A link for every page (?page=)

    Each page is an article with a heading; dishes are a list; the blank price is read as “Price not filled in”; heat has a word, never colour alone. Chapter tabs are a navigation with aria-current; the status line announces the pages and chapter; ←/→ work only while the book has focus. The canvas is hidden from assistive technology and holds no content of its own. List view shows every page for screen readers, find in page and zoom.

  3. 03
    One ribbon kept in this browser

    A static bilingual Next.js demo. Every page is in the HTML; ?page= is read in the browser. The 3D curl is the installed Three.js, imported only on request: the sheet is a 64 × 48 grid bent on the CPU, its faces painted into canvas textures from the laid-out pages (word boxes, styles, borders, inline SVG), and the part still lying flat stays the DOM page, clipped at the fold. One ribbon is kept as { version: 1, ribbon } under collection-sanak-menu-v1, at most 256 bytes, validated with zod/mini.

  4. 04
    Page curl in 3D, only on request

    A static bilingual Next.js demo. Every page is in the HTML; ?page= is read in the browser. The 3D curl is the installed Three.js, imported only on request: the sheet is a 64 × 48 grid bent on the CPU, its faces painted into canvas textures from the laid-out pages (word boxes, styles, borders, inline SVG), and the part still lying flat stays the DOM page, clipped at the fold. One ribbon is kept as { version: 1, ribbon } under collection-sanak-menu-v1, at most 256 bytes, validated with zod/mini.

  5. 05
    List view and a print of every page

    A static bilingual Next.js demo. Every page is in the HTML; ?page= is read in the browser. The 3D curl is the installed Three.js, imported only on request: the sheet is a 64 × 48 grid bent on the CPU, its faces painted into canvas textures from the laid-out pages (word boxes, styles, borders, inline SVG), and the part still lying flat stays the DOM page, clipped at the fold. One ribbon is kept as { version: 1, ribbon } under collection-sanak-menu-v1, at most 256 bytes, validated with zod/mini.

  6. 06
    Own component and state book

    A static bilingual Next.js demo. Every page is in the HTML; ?page= is read in the browser. The 3D curl is the installed Three.js, imported only on request: the sheet is a 64 × 48 grid bent on the CPU, its faces painted into canvas textures from the laid-out pages (word boxes, styles, borders, inline SVG), and the part still lying flat stays the DOM page, clipped at the fold. One ribbon is kept as { version: 1, ribbon } under collection-sanak-menu-v1, at most 256 bytes, validated with zod/mini.

  7. 07
    Local brand personalization

    A static bilingual Next.js demo. Every page is in the HTML; ?page= is read in the browser. The 3D curl is the installed Three.js, imported only on request: the sheet is a 64 × 48 grid bent on the CPU, its faces painted into canvas textures from the laid-out pages (word boxes, styles, borders, inline SVG), and the part still lying flat stays the DOM page, clipped at the fold. One ribbon is kept as { version: 1, ribbon } under collection-sanak-menu-v1, at most 256 bytes, validated with zod/mini.

  8. 08
    Select, tooltip & scroll area

    Keyboard behavior is shared; this theme owns the popup colors, border, radius, type and focus.

  9. 09
    Export & limits

    Fictional design study. Sanak, its dishes and descriptions are illustrative; prices are left blank on purpose, nothing is ordered, and nothing is said about halal status, nutrition or availability. The 3D curl was checked in desktop and phone emulation (Chromium and WebKit), not on a real phone.

READ THE DESIGN

Why it is arranged this way.

The capture shows the implemented opening. Notes connect its composition to the working experience and its mobile behavior.

Actual website capture. Follow the numbered notes.
  1. 01

    A book, not a slideshow

    The closed sambal-orange cover with its contents beside it opens on laminated pages: two at a time from 1024px, one on a phone. Every page is in the HTML and has its own ?page= link; without JavaScript the book is a list.

  2. 02

    Chapters on the top edge

    Four laminated tabs stand on the top edge in the chapters’ colours; the open chapter is lifted and outlined (aria-current). A tab adds a step to the history, so Back returns to the chapter before.

  3. 03

    No price is invented

    Each dish has a code, a Rokkitt name, a dotted leader and “Rp —”, read aloud as “Price not filled in”. Heat is chillies with a word. The 3D curl, on request, bends the sheet over the real page underneath.

04 / Form & feedback contract

A local preparation note. Try an empty submission, correct it, then export your actual input.

10–1,000 characters. Kept in this page.

Your prepared note will appear here.

05 / Actual working components

Activate the full workspace when you want to inspect it. Its interaction code loads on demand.