Skip to content

feat(ui): header toggles, section collapse, kiwi-brand colors#1

Open
kickthemoon0817 wants to merge 1 commit into
hletrd:mainfrom
kickthemoon0817:feat/ui-enhancements
Open

feat(ui): header toggles, section collapse, kiwi-brand colors#1
kickthemoon0817 wants to merge 1 commit into
hletrd:mainfrom
kickthemoon0817:feat/ui-enhancements

Conversation

@kickthemoon0817
Copy link
Copy Markdown

Summary

  • Add KO/EN segmented pill toggle and sun/moon theme toggle to header bar
  • Add section collapse/expand with chevron indicators on h2/h3 headings
  • Apply kiwi brand color to section numbering, footnote refs, and footnote section numbers
  • Add back-to-TOC links on section heading numbers, fix duplicate TOC numbering
  • Hide footnote backref arrows, add clickable numbered links in footnotes section
  • Fix inconsistent line spacing from external link icons and footnotes
  • Make header and title bar span full wrapper width
  • Port all changes to renderer template

Test plan

  • Open example HTML and verify header toggles (KO/EN, light/dark) animate correctly
  • Click section headings (h2 and h3) to verify collapse/expand works
  • Verify section numbers and footnote superscripts use kiwi brand color
  • Verify TOC entries are not duplicated (e.g. "1. ๊ฐœ์š”" not "1. 1. ๊ฐœ์š”")
  • Click section number links to verify they scroll back to TOC
  • Verify footnote backref arrows are hidden
  • Test renderer output matches example styling

๐Ÿค– Generated with Claude Code

โ€ฆck-links

- Add KO/EN segmented pill toggle and sun/moon theme toggle to header bar
- Add section collapse/expand with chevron indicators on h2/h3 headings
- Apply kiwi brand color to section numbering, footnote refs, and footnote section numbers
- Add back-to-TOC links on section heading numbers
- Fix duplicate numbering in TOC entries
- Fix inconsistent line spacing from external link icons and footnote superscripts
- Hide footnote backref arrows, add clickable numbered links in footnotes section
- Make header and title bar span full wrapper width
- Add emoji spacing in logo
- Port all changes to renderer template

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces significant UI and UX enhancements to the kiwi-paper documentation template, including a new header control bar with language (KO/EN) and theme (Light/Dark) toggles, and a dynamic section collapse feature for improved readability. The feedback focuses on resolving a state mismatch in the language toggle that causes flickering on page load, removing unnecessary !important CSS declarations to maintain stylesheet maintainability, and replacing brittle innerHTML manipulations with safer DOM methods to preserve existing heading structures. Additionally, it is recommended to move inline logo spacing to external CSS for better separation of concerns.

Comment on lines +776 to +777
<div class="seg-toggle-item active" data-val="en">EN</div>
<div class="seg-toggle-item" data-val="ko">KO</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

์–ธ์–ด ํ† ๊ธ€์˜ ์ดˆ๊ธฐ ์ƒํƒœ๊ฐ€ ์ผ๊ด€๋˜์ง€ ์•Š์•„ ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ ๊นœ๋นก์ž„(flicker)์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ HTML์—์„œ๋Š” 'EN'์ด ํ™œ์„ฑํ™” ์ƒํƒœ๋กœ ๋ Œ๋”๋ง๋˜์ง€๋งŒ, JavaScript(var currentLang = 'ko')์—์„œ๋Š” ํŽ˜์ด์ง€ ๋กœ๋“œ ์งํ›„ 'KO'๋กœ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ์ดˆ๊ธฐ ๋ Œ๋”๋ง ์‹œ์ ๋ถ€ํ„ฐ ์˜๋„ํ•œ ๊ธฐ๋ณธ ์–ธ์–ด(KO)๊ฐ€ ํ™œ์„ฑํ™”๋˜๋„๋ก HTML์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Suggested change
<div class="seg-toggle-item active" data-val="en">EN</div>
<div class="seg-toggle-item" data-val="ko">KO</div>
<div class="seg-toggle-item" data-val="en">EN</div>
<div class="seg-toggle-item active" data-val="ko">KO</div>

Comment thread renderer/src/template.mjs
Comment on lines +71 to +72
<div class="seg-toggle-item active" data-val="en">EN</div>
<div class="seg-toggle-item" data-val="ko">KO</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

์–ธ์–ด ํ† ๊ธ€์˜ ์ดˆ๊ธฐ ์ƒํƒœ๊ฐ€ ์ผ๊ด€๋˜์ง€ ์•Š์•„ ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ ๊นœ๋นก์ž„(flicker)์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ HTML์—์„œ๋Š” 'EN'์ด ํ™œ์„ฑํ™” ์ƒํƒœ๋กœ ๋ Œ๋”๋ง๋˜์ง€๋งŒ, JavaScript(var currentLang = 'ko')์—์„œ๋Š” ํŽ˜์ด์ง€ ๋กœ๋“œ ์งํ›„ 'KO'๋กœ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ์ดˆ๊ธฐ ๋ Œ๋”๋ง ์‹œ์ ๋ถ€ํ„ฐ ์˜๋„ํ•œ ๊ธฐ๋ณธ ์–ธ์–ด(KO)๊ฐ€ ํ™œ์„ฑํ™”๋˜๋„๋ก HTML์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Suggested change
<div class="seg-toggle-item active" data-val="en">EN</div>
<div class="seg-toggle-item" data-val="ko">KO</div>
<div class="seg-toggle-item" data-val="en">EN</div>
<div class="seg-toggle-item active" data-val="ko">KO</div>

.footnote-ref a { color: #0275d8; font-size: 12px; font-weight: normal; }
.footnote-backref { text-decoration: none; margin-left: 0.3em; color: var(--namu-brand); }
.footnote-ref a { color: var(--namu-brand); font-size: 12px; font-weight: normal; }
a[data-footnote-ref] { color: var(--namu-brand) !important; font-weight: 600; }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

!important ์„ ์–ธ์€ ๋ถˆํ•„์š”ํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. a[data-footnote-ref] ์„ ํƒ์ž๋Š” ์ด๋ฏธ ๋‹ค๋ฅธ ์Šคํƒ€์ผ์„ ์žฌ์ •์˜ํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•œ ๋ช…์‹œ์„ฑ์„ ๊ฐ€์ง€๋ฉฐ, ์Šคํƒ€์ผ์‹œํŠธ์—์„œ ๋‚˜์ค‘์— ์„ ์–ธ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์Šต๋‹ˆ๋‹ค. !important๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‚˜์ค‘์— CSS๋ฅผ ๋””๋ฒ„๊น…ํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ๋” ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Suggested change
a[data-footnote-ref] { color: var(--namu-brand) !important; font-weight: 600; }
a[data-footnote-ref] { color: var(--namu-brand); font-weight: 600; }

<button class="settings-toggle" aria-label="๋””์Šคํ”Œ๋ ˆ์ด ์„ค์ •" title="๋””์Šคํ”Œ๋ ˆ์ด ์„ค์ •">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
</button>
<a class="wiki-logo" href="#">๐Ÿฅ<span style="margin-left:0.35em"></span>kiwi-paper</a>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

๋กœ๊ณ ์˜ ์•„์ด์ฝ˜๊ณผ ํ…์ŠคํŠธ ์‚ฌ์ด์— ์—ฌ๋ฐฑ์„ ์ฃผ๊ธฐ ์œ„ํ•ด ์ธ๋ผ์ธ ์Šคํƒ€์ผ์ด ์ ์šฉ๋œ ๋นˆ <span> ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” CSS์™€ HTML์˜ ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ์›์น™์— ์–ด๊ธ‹๋‚˜๋ฉฐ, ์‹œ๋งจํ‹ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. CSS ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํƒ€์ผ์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”.

Comment thread renderer/src/template.mjs
<button class="settings-toggle" aria-label="๋””์Šคํ”Œ๋ ˆ์ด ์„ค์ •" title="๋””์Šคํ”Œ๋ ˆ์ด ์„ค์ •">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
</button>
<a class="wiki-logo" href="${navigation.index || '#'}">๐Ÿฅ<span style="margin-left:0.35em"></span>kiwi-paper</a>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

๋กœ๊ณ ์˜ ์•„์ด์ฝ˜๊ณผ ํ…์ŠคํŠธ ์‚ฌ์ด์— ์—ฌ๋ฐฑ์„ ์ฃผ๊ธฐ ์œ„ํ•ด ์ธ๋ผ์ธ ์Šคํƒ€์ผ์ด ์ ์šฉ๋œ ๋นˆ <span> ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” CSS์™€ HTML์˜ ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ์›์น™์— ์–ด๊ธ‹๋‚˜๋ฉฐ, ์‹œ๋งจํ‹ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. CSS ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํƒ€์ผ์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”.

Comment thread renderer/src/template.mjs
.footnote-ref a { color: var(--link-color); font-size: 12px; font-weight: normal; }
.footnote-backref { text-decoration: none; margin-left: 0.3em; color: var(--namu-brand); }
.footnote-ref a { color: var(--namu-brand); font-size: 12px; font-weight: normal; }
a[data-footnote-ref] { color: var(--namu-brand) !important; font-weight: 600; }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

!important ์„ ์–ธ์€ ๋ถˆํ•„์š”ํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. a[data-footnote-ref] ์„ ํƒ์ž๋Š” ์ด๋ฏธ ๋‹ค๋ฅธ ์Šคํƒ€์ผ์„ ์žฌ์ •์˜ํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•œ ๋ช…์‹œ์„ฑ์„ ๊ฐ€์ง€๋ฉฐ, ์Šคํƒ€์ผ์‹œํŠธ์—์„œ ๋‚˜์ค‘์— ์„ ์–ธ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์Šต๋‹ˆ๋‹ค. !important๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‚˜์ค‘์— CSS๋ฅผ ๋””๋ฒ„๊น…ํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ๋” ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Suggested change
a[data-footnote-ref] { color: var(--namu-brand) !important; font-weight: 600; }
a[data-footnote-ref] { color: var(--namu-brand); font-weight: 600; }

Comment thread renderer/src/template.mjs
Comment on lines +1285 to +1292
document.querySelectorAll('.wiki-article h2[id], .wiki-article h3[id]').forEach(function(h) {
var text = h.textContent;
var match = text.match(/^(\d+(\.\d+)*\.)\s*/);
if (!match) return;
var num = match[1];
var rest = text.slice(match[0].length);
h.innerHTML = '<a href="#toc">' + num + '</a> ' + rest;
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

innerHTML์„ ์‚ฌ์šฉํ•˜์—ฌ ์ œ๋ชฉ์„ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ์‹์€ ์ œ๋ชฉ์— <code> ํƒœ๊ทธ์™€ ๊ฐ™์€ ์ธ๋ผ์ธ HTML ์š”์†Œ๊ฐ€ ํฌํ•จ๋  ๊ฒฝ์šฐ ์ด๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์–ด ์ž ์žฌ์ ์œผ๋กœ ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค. textContent๋กœ ํ…์ŠคํŠธ๋ฅผ ๊ฐ€์ ธ์˜จ ๋’ค innerHTML๋กœ ์žฌ์ž‘์„ฑํ•˜๋ฉด ๊ธฐ์กด์˜ HTML ๊ตฌ์กฐ๊ฐ€ ์‚ฌ๋ผ์ง€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋” ์•ˆ์ •์ ์ธ ๋ฐฉ๋ฒ•์€ DOM ์กฐ์ž‘ ๋ฉ”์„œ๋“œ(์˜ˆ: insertBefore, createTextNode)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งํฌ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Suggested change
document.querySelectorAll('.wiki-article h2[id], .wiki-article h3[id]').forEach(function(h) {
var text = h.textContent;
var match = text.match(/^(\d+(\.\d+)*\.)\s*/);
if (!match) return;
var num = match[1];
var rest = text.slice(match[0].length);
h.innerHTML = '<a href="#toc">' + num + '</a> ' + rest;
});
document.querySelectorAll('.wiki-article h2[id], .wiki-article h3[id]').forEach(function(h) {
const firstNode = h.firstChild;
if (firstNode && firstNode.nodeType === Node.TEXT_NODE) {
const text = firstNode.nodeValue;
const match = text.match(/^(\d+(\.\d+)*\.)\s*/);
if (match) {
const num = match[1];
const restText = text.slice(match[0].length);
const link = document.createElement('a');
link.href = '#toc';
link.textContent = num;
h.insertBefore(link, firstNode);
firstNode.nodeValue = ' ' + restText.trimStart();
}
}
});

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3a3710bc5

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread renderer/src/template.mjs
Comment on lines +1295 to +1299
function setupCollapse(parent, headingSelector, stopTags) {
var headings = parent.querySelectorAll(headingSelector);
headings.forEach(function(h) {
var wrapper = document.createElement('div');
wrapper.className = 'section-content';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore folding updater after replacing section-fold logic

This change removes the old updateFolding implementation, but applyAll() still calls updateFolding() on startup and whenever settings are changed. In the renderer output, that produces a ReferenceError at runtime, so initial settings application is interrupted and later settings updates fail in the same path. Please either reintroduce a folding updater or remove that call and wire fold behavior into the new collapse flow.

Useful? React with ๐Ÿ‘ย / ๐Ÿ‘Ž.

Comment thread renderer/src/template.mjs
if (!match) return;
var num = match[1];
var rest = text.slice(match[0].length);
h.innerHTML = '<a href="#toc">' + num + '</a> ' + rest;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid injecting heading text via innerHTML for TOC links

Using h.textContent and then assigning h.innerHTML re-parses heading text as HTML, which strips existing inline formatting in headings and can turn escaped angle-bracket text into real elements. This is a content-integrity regression for headings containing code/emphasis or literal <...> text. Build the backlink with DOM nodes (anchor + text node) or escape the remainder before insertion.

Useful? React with ๐Ÿ‘ย / ๐Ÿ‘Ž.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant