ljg-library: Viewfinder Library Borrow Card
One book, forged into a 2050 Library Borrow Card. The cover, author, and book details serve as its identity; the core is to fully, fluently, and clearly articulate the book's unique "Viewfinder" (the way it lets you see the world through a new lens), then bring this set of ideas to life with a hand-drawn illustration. Half a year after closing the book, a glance at this card will bring back that "lens" the book gave you—this is tangible proof that your reading wasn't in vain.
The illustration block uses a hand-drawn explanatory style with white background and black ink,
featuring the ink portrait of Ji Gang himself (
, created by cutting out his avatar). The complete design process is documented in
~/.claude/PAI/MEMORY/WORK/ljg-oneliner-design/ISA.md
.
Constraints
Output is a visual file (PNG), not applicable to Org-mode / Denote / ASCII-only specifications.
Soul: Viewfinder Extraction + Hand-drawn Illustration
The appearance of the card is just the shell; the real essence lies in whether you can extract the book's unique way of seeing the world, articulate it fully, fluently, and clearly, then bring the idea to life with a hand-drawn illustration. If this step fails, the entire card degenerates into a Douban Reading card.
First Principle: Express ideas fully, fluently, and clearly. Cancel all word constraints like "condense into one sentence"—it's more important to explain this "lens" thoroughly than to make it short.
Before execution,
first Read : The first part follows six steps (Question → Zero Point → Displacement → Frame Establishment → Elaboration → Verification) to produce the Viewfinder (main clause
+ elaboration
); the second part turns the Viewfinder idea into a scene—
the protagonist is the embedded ink portrait of Ji Gang (
, placed in the scene as "you"), with illustrations + faceless crowds + annotations on the right to visualize the actions (
, reuse the
components and overall skeleton from it).
Input Flexibility: Ji Gang often has already thought through the idea (he wants to forge a card right after reading). If the idea is provided, use it directly (only step 6 verification + illustration creation); if not, follow the full extraction process.
Visual Specifications
Before generating HTML,
first Read —it contains all details like light glass card specifications, two color schemes (dynamic card accent color vs. white background black ink for illustration board), fonts, illustration board (Ji Gang's ink portrait as protagonist) specifications, and pitfalls to avoid. This is the baseline for visual quality.
Process
Input: Book title (or Book title + pre-thought Viewfinder idea)
↓
1. Retrieve real cover + book details from weread (see "Material Acquisition" below)
2. Capture author's avatar from the web
3. Extract main color from cover → dynamic accent color for card (python assets/extract_color.py <cover>)
4. Extract Viewfinder: main clause {{FRAME}} + elaboration {{EXP}} (fully, fluently, clearly; verify if provided by user, otherwise follow the six steps in extraction.md)
5. Create hand-drawn illustration SVG {{SKETCH_SVG}}: embed protagonist's ink portrait assets/ljg-portrait.png + illustrations + faceless crowds + annotations (reuse defs + skeleton from extraction.md, change metaphor but keep protagonist)
6. Fill placeholder variables in assets/library_template.html
7. Render (capture.js, fullpage adaptive height)
8. Self-inspect by reading (including zooming in on the illustration board) → deliver the file path
Material Acquisition (Critical, follow this fallback order)
Cover + Book Details (weread)
Ji Gang uses WeChat Reading. Use the
API of the weread skill (first Read
~/.claude/skills/weread/search.md
):
bash
curl -s -X POST "https://i.weread.qq.com/api/agent/gateway" \
-H "Authorization: Bearer $WEREAD_API_KEY" -H "Content-Type: application/json" \
-d '{"api_name":"/store/search","keyword":"<书名>","scope":10,"skill_version":"1.0.3"}'
- The
results[].books[].bookInfo
field in the response (each result group corresponds to one book) contains title / author / translator / cover / publisher
.
- The cover URL with prefix is a thumbnail (70×100, will be blurry). Replace with to get high-resolution (285×411):
.../cover/942/635942/t7_635942.jpg
. Include -H "Referer: https://weread.qq.com/"
when downloading.
- If weread is unavailable → search for Douban cover online (web-access / markdown-proxy) → if still not found, use CSS placeholder for book cover.
Author's Avatar (web)
Wikipedia original images are the most reliable. Retrieve the original image URL directly via Wikipedia API:
bash
curl -s -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)" \
"https://en.wikipedia.org/w/api.php?action=query&titles=<英文名>&prop=pageimages&piprop=original&format=json"
# After getting .original.source, download with UA:
curl -sL -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)" -o /tmp/lib_avatar.jpg "<original-url>"
- Pitfall: If the specific size in the thumb path () is not cached, it will return an HTML error page. Use the original image path (remove and size segment), and must include User-Agent (Wikimedia blocks requests without UA).
- If no avatar is found → omit the avatar (the author line in the template will not display the avatar), do not block the process.
Protagonist's Ink Portrait (Ready)
The protagonist of the illustration board is Ji Gang himself, and the asset
(black ink line art on transparent background, becomes white background ink portrait when placed on white board) is already generated and reused fixedly, no need to recreate it every time. If the original avatar is updated, recreate it: read head.png with PIL, map dark ink pixels with
to
, make others transparent, and crop the transparent edges.
Dynamic Accent Color for Card
bash
python3 assets/extract_color.py /tmp/lib_cover.jpg
# Output example: #c43d30
Extract the most prominent
color from the cover as the card's accent color (automatically changes with the book: red cover → red card, blue cover → blue card). The script defaults to selecting the "most frequent color"—if the cover has a large area of beige/grey background, it will select a dull background color;
in this case, reorder by "saturation × frequency" and select a vibrant color from real pixels (do not hardcode it). Note: This is only the card body color; the illustration board uses fixed white background
+ ink
, do not modify.
Template Variables (library_template.html)
| Variable | Content |
|---|
| Hex code of the card's dynamic accent color (e.g., , extracted from cover) |
| Absolute path of the cover |
| Complete avatar <img class="avatar" src="file://…">
(fill empty string if no avatar, the author line will automatically omit the avatar) |
| | Book title (Chinese / English / Subtitle) |
| 3-4 topic tags (core concepts of the book), each wrapped in <span class="tag">…</span>
|
| | Author's Chinese name / "English name · Publisher Year" |
| Main clause of Viewfinder: clearly point out the claim of changing the lens, highlight keywords with <span class="hl">…</span>
using the card's accent color |
| Elaboration of Viewfinder: fully, fluently, and clearly explain this lens, highlight keywords with <span class="hl">…</span>
as well |
| Name of the illustration board (English + Chinese, e.g., ) |
| Full hand-drawn illustration (white background black ink, featuring the embedded ink portrait of Ji Gang, see the second part of extraction.md) |
Rendering
bash
node ~/.claude/skills/ljg-card/assets/capture.js \
/tmp/ljg_library_{name}.html ~/Downloads/{name}.png 1080 1440 fullpage
Reuse capture.js from ljg-card (playwright is already installed in ljg-card/node_modules).
Must use —the card height adapts to content, no bottom blank space. Local cover/avatar/protagonist's ink portrait referenced via
can be rendered directly.
Delivery
- Read and visually inspect the output PNG, and zoom in on the illustration board (verify cover/avatar loading ✓, Viewfinder is fully and fluently explained ✓, card color is coordinated ✓, Ji Gang's ink portrait is clear as protagonist, faceless crowds provide contrast ✓, hand-drawn ink lines and annotations are clear ✓, no blank space on the right ✓).
- Report the file path + a brief explanation of the Viewfinder extraction.
Gotchas (Must Avoid)
- Cover Size: The weread cover with prefix is a 70×100 thumbnail, which will definitely be blurry. Replace with to get 285×411 high-resolution image, include when downloading.
- Avatar Thumb Trap: The Wikimedia path will return an HTML error page if the specific size is not cached. Use the original image path + User-Agent.
- Protagonist is the embedded ink portrait of Ji Gang, not hand-drawn: Use
<image href="…/assets/ljg-portrait.png">
to ensure vividness and pixel-level consistency; hand-drawn figures are neither similar to him nor consistent, so they are abandoned.
- Illustration board is handwritten SVG: Wrap lines/graphics with to create hand-drawn jitter; never apply filter to text/annotations/protagonist's ink portrait (it will blur). Reuse components + skeleton from extraction.md.
- Faceless crowds vs. real-faced protagonist: Use faceless small ink figures for crowds, only the protagonist has a real face—this contrast creates "you vs. a group of people", do not draw faces for crowds.
- Illustration board uses only two colors: white background and black ink: White background + ink . Do not mix the two color schemes: card's dynamic color is extracted from cover, not hardcoded; illustration board uses fixed white + ink, hardcoded.
- Viewfinder is cognitive shift, not summary: Main clause "It's not X, it's actually Y" + elaboration to fully explain the mechanism, not "This book talks about...". Acceptance criterion: A glance with a calm mind brings back that "lens".