for-humanity 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +3 -3
- package/dist/browser.js +1 -1
- package/dist/cli.css +16 -14
- package/dist/cli.js +12 -4
- package/package.json +1 -1
- package/src/asset/font/ibm-plex-sans-kr/IBMPlexSansKR-Regular.woff2 +0 -0
- package/src/asset/font/ibm-plex-sans-kr/IBMPlexSansKR-SemiBold.woff2 +0 -0
- package/src/asset/font/ibm-plex-sans-kr/LICENSE.txt +93 -0
- package/src/asset/font/ibm-plex-sans-kr/ibm-plex-sans-kr.css +22 -0
- package/src/component/widget/navigation/_constant/navigation.ts +2 -2
- package/src/component/widget/navigation/wg-navigation.css +1 -1
- package/src/component/widget/prose/wg-prose.css +7 -1
- package/src/component/widget/shell/wg-shell.css +7 -11
- package/src/constant/font.ts +6 -1
- package/src/entry/cli/cli.ts +11 -4
- package/src/style/token.css +14 -10
- package/src/util/font/to-font-css.test.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.7.1 — 2026-10-11
|
|
6
|
+
|
|
7
|
+
- Set Hangul in body text, labels, inline code and the site name in bundled IBM Plex Sans KR, the source of Monoplex KR's Hangul, at its natural width; Latin stays in Monoplex KR, and code blocks and flowcharts keep two-cell Hangul for the grid.
|
|
8
|
+
- Tighten letter spacing to -0.03em for body text, labels and inline code, -0.04em for h2 and parts and -0.045em for h1; code blocks and flowcharts stay at 0 for the grid.
|
|
9
|
+
- Narrow the document navigation and outline sidebars from 240px to 200px and let the body fill the rest of a page up to 1920px instead of a 900px column, keeping the 32px gaps; show the outline from 1360px so the body stays about 800px or wider.
|
|
10
|
+
|
|
5
11
|
## 0.7.0 — 2026-10-06
|
|
6
12
|
|
|
7
13
|
- Replace Pretendard and JetBrains Mono with bundled Monoplex KR for body text, labels, code and flowcharts; align the flowchart grid to its 1:2 Latin–Hangul widths.
|
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ Write Markdown. Keep the context. Share a static site.
|
|
|
33
33
|
Node.js 22 or later and pnpm. Install the CLI in your document project:
|
|
34
34
|
|
|
35
35
|
```sh
|
|
36
|
-
pnpm add -D --save-exact for-humanity@0.7.
|
|
36
|
+
pnpm add -D --save-exact for-humanity@0.7.1
|
|
37
37
|
mkdir docs
|
|
38
38
|
```
|
|
39
39
|
|
|
@@ -52,7 +52,7 @@ pnpm exec for-humanity preview docs
|
|
|
52
52
|
|
|
53
53
|
If your Markdown files are in the project root, use `.` instead of `docs`. The root `README.md` becomes the home page; root `AGENTS.md` and `CLAUDE.md` stay out of the site.
|
|
54
54
|
|
|
55
|
-
Version `0.7.
|
|
55
|
+
Version `0.7.1` supports `dev`, `build` and `preview`. `init` is planned; see the [Roadmap](https://github.com/minu-ha/for-humanity/blob/main/templates/document/roadmap.md) and [Changelog](https://github.com/minu-ha/for-humanity/blob/main/CHANGELOG.md).
|
|
56
56
|
Cloudflare Pages can host the generated site. See [Deployment](https://github.com/minu-ha/for-humanity/blob/main/templates/document/deployment.md) for the build settings.
|
|
57
57
|
Set an optional public root `url` in the site configuration to generate `robots.txt` and `sitemap.xml`; projects without a URL emit neither file. See [Crawling](https://github.com/minu-ha/for-humanity/blob/main/templates/document/crawling.md).
|
|
58
58
|
|
|
@@ -75,7 +75,7 @@ pnpm preview # Preview the static site
|
|
|
75
75
|
pnpm build:pages # Add Cloudflare Pages headers and a 404 page
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
Changes pushed to `main` update the documentation site. A stable version tag such as `v0.7.
|
|
78
|
+
Changes pushed to `main` update the documentation site. A stable version tag such as `v0.7.1` runs checks, publishes the package to npm, then creates a GitHub Release with the same package file.
|
|
79
79
|
The npm README updates with each package release. See [Maintenance](https://github.com/minu-ha/for-humanity/blob/main/templates/document/maintenance.md#packaging-and-release) for the release steps.
|
|
80
80
|
|
|
81
81
|
## Make it yours
|
package/dist/browser.js
CHANGED
|
@@ -34,6 +34,6 @@ d.replaceWith(c.content)
|
|
|
34
34
|
${Math.max(0,Math.min(r.current.x+16,document.documentElement.clientWidth-s.width-16))}px,
|
|
35
35
|
${Math.max(0,Math.min(r.current.y+16,document.documentElement.clientHeight-s.height-16))}px,
|
|
36
36
|
0
|
|
37
|
-
)`,s.classList.add("wg_cursorFace__root--visible"))}))},c=s=>{if(!n.current?.matches||s.pointerType!=="mouse"){o();return}r.current.x=s.clientX,r.current.y=s.clientY,a()},f=()=>{t.current?.classList.contains("wg_cursorFace__root--visible")&&a()},u=()=>{if(t.current?.classList.contains("wg_cursorFace__root--visible"))try{sessionStorage.setItem(mt,JSON.stringify({x:r.current.x,y:r.current.y}))}catch{}},p=()=>{try{let s=sessionStorage.getItem(mt);if(sessionStorage.removeItem(mt),s===null||!n.current?.matches)return;let l=JSON.parse(s);typeof l=="object"&&l!==null&&"x"in l&&"y"in l&&typeof l.x=="number"&&typeof l.y=="number"&&Number.isFinite(l.x)&&Number.isFinite(l.y)&&(r.current.x=l.x,r.current.y=l.y,a())}catch{}};return I(()=>{if(!e.ready)return;let s=new AbortController,l=matchMedia("(hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference)");return n.current=l,p(),document.addEventListener("pointermove",c,{passive:!0,signal:s.signal}),document.addEventListener("pointerdown",c,{passive:!0,signal:s.signal}),document.documentElement.addEventListener("pointerleave",o,{signal:s.signal}),addEventListener("blur",o,{signal:s.signal}),addEventListener("resize",f,{signal:s.signal}),addEventListener("pagehide",u,{signal:s.signal}),addEventListener("pageshow",p,{signal:s.signal}),l.addEventListener("change",i,{signal:s.signal}),()=>{s.abort(),n.current=null,o()}},[e.ready]),g("img",{ref:e.ready?t:void 0,className:x("wg_cursorFace__root"),src:so,width:24,height:24,alt:"","aria-hidden":"true",draggable:!1,"data-cursor-face":""})};var fn="(width < 1024px)",pn="(width >=
|
|
37
|
+
)`,s.classList.add("wg_cursorFace__root--visible"))}))},c=s=>{if(!n.current?.matches||s.pointerType!=="mouse"){o();return}r.current.x=s.clientX,r.current.y=s.clientY,a()},f=()=>{t.current?.classList.contains("wg_cursorFace__root--visible")&&a()},u=()=>{if(t.current?.classList.contains("wg_cursorFace__root--visible"))try{sessionStorage.setItem(mt,JSON.stringify({x:r.current.x,y:r.current.y}))}catch{}},p=()=>{try{let s=sessionStorage.getItem(mt);if(sessionStorage.removeItem(mt),s===null||!n.current?.matches)return;let l=JSON.parse(s);typeof l=="object"&&l!==null&&"x"in l&&"y"in l&&typeof l.x=="number"&&typeof l.y=="number"&&Number.isFinite(l.x)&&Number.isFinite(l.y)&&(r.current.x=l.x,r.current.y=l.y,a())}catch{}};return I(()=>{if(!e.ready)return;let s=new AbortController,l=matchMedia("(hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference)");return n.current=l,p(),document.addEventListener("pointermove",c,{passive:!0,signal:s.signal}),document.addEventListener("pointerdown",c,{passive:!0,signal:s.signal}),document.documentElement.addEventListener("pointerleave",o,{signal:s.signal}),addEventListener("blur",o,{signal:s.signal}),addEventListener("resize",f,{signal:s.signal}),addEventListener("pagehide",u,{signal:s.signal}),addEventListener("pageshow",p,{signal:s.signal}),l.addEventListener("change",i,{signal:s.signal}),()=>{s.abort(),n.current=null,o()}},[e.ready]),g("img",{ref:e.ready?t:void 0,className:x("wg_cursorFace__root"),src:so,width:24,height:24,alt:"","aria-hidden":"true",draggable:!1,"data-cursor-face":""})};var fn="(width < 1024px)",pn="(width >= 1360px)";var uo=e=>{let t=document.querySelector("[data-navigation]"),n=document.querySelector('[data-navigation-scroll="documents"]'),r=document.querySelector('[data-navigation-scroll="outline"]');if(!(!t||!n||!r)){t.dataset.navigationLayout=e.layout;try{let o=sessionStorage.getItem(e.key),i=o===null?void 0:JSON.parse(o),a=typeof i=="object"&&i!==null&&"version"in i&&i.version===e.version&&"state"in i?e.toState(i.state):{positions:{}},c=sessionStorage.getItem(`${e.key}:${e.layout==="drawer"?"drawer":"desktop"}`),f=a.positions[e.layout]===void 0&&c!==null?e.toState({positions:{[e.layout]:JSON.parse(c)}}).positions[e.layout]:void 0,u=a.positions[e.layout]??f,p=[...t.querySelectorAll(".wg_navigationNav__root a[href]")].map(s=>`${s.pathname}:${s.textContent}`).join(`
|
|
38
38
|
`);if(u===void 0||u.navigation!==p)return;n.scrollTop=u.documents,u.pathname===location.pathname&&(r.scrollTop=u.outline)}catch{}}};var gt=e=>{let t=[...e.group.docs.map(n=>({kind:"document",key:`doc:${n.id}`,doc:n})),...e.group.groups.map(n=>({kind:"group",key:`group:${JSON.stringify(n.path)}`,group:n}))];return g("ul",{className:x("wg_navigationNavList__root"),"aria-label":e.group.name,children:t.map(n=>g("li",{className:x("wg_navigationNavList__item"),children:[n.kind==="document"&&g(R,{children:[g("a",{className:x("wg_navigationNavList__link",{"wg_navigationNavList__link--active":n.doc.active}),href:`/${n.doc.id}/`,title:n.doc.label,"aria-current":n.doc.active?"page":void 0,children:n.doc.name}),n.doc.children.length>0&&g(gt,{group:{name:n.doc.name,path:e.group.path,docs:n.doc.children,groups:[]}})]}),n.kind==="group"&&g(R,{children:[g("span",{className:x("wg_navigationNavList__branch"),children:n.group.name}),g(gt,{group:n.group})]})]},n.key))})};var lo="Document navigation",fo="Open navigation",po="Close navigation",mo="Navigation";var dn="On this page";var mn=e=>g("nav",{className:x("wg_navigationNav__root"),"aria-label":lo,children:g("div",{className:x("wg_navigationNav__docs"),children:e.groups.map(t=>g("section",{className:x("wg_navigationNav__docGroup"),"aria-label":t.name,children:[g("div",{className:x("wg_navigationNav__group"),children:t.name}),g(gt,{group:t})]},JSON.stringify(t.path)))})});var _t=e=>{let[t,n]=O({above:!1,below:!1}),r=E(0),o=()=>{if(r.current=0,e.portRef.current===null)return;let c=e.portRef.current.scrollTop>1,f=e.portRef.current.scrollHeight-e.portRef.current.clientHeight-e.portRef.current.scrollTop>1;n(u=>u.above===c&&u.below===f?u:{above:c,below:f})},i=()=>{r.current===0&&(r.current=requestAnimationFrame(o))},a=c=>{e.onScroll?.(),i()};return I(()=>{if(!e.ready||e.portRef.current===null)return;let c=new ResizeObserver(i);c.observe(e.portRef.current),e.portRef.current.firstElementChild!==null&&c.observe(e.portRef.current.firstElementChild);let f=!0;return addEventListener("pageshow",i),e.portRef.current.isConnected?o():queueMicrotask(()=>{f&&o()}),()=>{f=!1,c.disconnect(),removeEventListener("pageshow",i),cancelAnimationFrame(r.current),r.current=0}},[e.portRef,e.ready]),I(()=>{e.ready&&e.portRef.current?.isConnected&&o()},[e.children,e.ready]),g("div",{ref:e.ready?e.portRef:void 0,className:x("wg_navigation__scroll",e.kind==="documents"&&"wg_navigation__documents",e.kind==="outline"&&"wg_navigation__headings",e.ready&&"wg_navigation__scroll--ready",e.ready&&t.above&&"wg_navigation__scroll--above",e.ready&&t.below&&"wg_navigation__scroll--below"),"data-navigation-scroll":e.kind,onClick:e.onClick,onScroll:a,children:e.children})};var vt=e=>{if(!e)return null;try{return document.getElementById(decodeURIComponent(e.slice(1)))}catch(t){if(t instanceof URIError)return null;throw t}};var ho=e=>{let[t,n]=O();return I(()=>{let o=e.groups.flatMap(f=>f.sections).flatMap(f=>[f.heading,...f.subs.map(u=>u.heading)]),i={id:0},a=()=>{i.id=0;let f=o.flatMap(u=>{let p=vt(`#${u.slug}`);return p?.checkVisibility()?[{slug:u.slug,top:p.getBoundingClientRect().top-Number.parseFloat(getComputedStyle(p).scrollMarginTop)}]:[]});n(f.findLast(u=>u.top<=1)?.slug??f[0]?.slug)},c=()=>{i.id===0&&(i.id=requestAnimationFrame(a))};return addEventListener("scroll",c,{passive:!0}),addEventListener("resize",c),addEventListener("toggle",c,!0),addEventListener("pageshow",c),document.addEventListener("DOMContentLoaded",c),document.readyState!=="loading"&&a(),()=>{cancelAnimationFrame(i.id),removeEventListener("scroll",c),removeEventListener("resize",c),removeEventListener("toggle",c,!0),removeEventListener("pageshow",c),document.removeEventListener("DOMContentLoaded",c)}},[e.groups]),g("nav",{className:x("wg_navigationToc__root"),"aria-label":dn,children:[g("div",{className:x("wg_navigationToc__label"),children:dn}),e.groups.map(r=>g("div",{className:x("wg_navigationToc__groupSection",{"wg_navigationToc__groupSection--named":r.part!==void 0}),children:[r.part!==void 0&&g("div",{className:x("wg_navigationToc__group"),children:r.part}),g("ul",{className:x("wg_navigationToc__list"),children:r.sections.map(o=>g("li",{className:x("wg_navigationToc__item"),children:[g("a",{className:x("wg_navigationToc__link",{"wg_navigationToc__link--active":o.heading.slug===t}),href:`#${o.heading.slug}`,"data-toc-link":"","aria-current":o.heading.slug===t?"location":void 0,children:o.heading.text}),o.subs.length>0&&g("ul",{className:x("wg_navigationToc__sub"),children:o.subs.map(i=>g("li",{className:x("wg_navigationToc__subItem"),children:g("a",{className:x("wg_navigationToc__subLink",{"wg_navigationToc__subLink--active":i.heading.slug===t}),href:`#${i.heading.slug}`,"data-toc-sub-link":"","aria-current":i.heading.slug===t?"location":void 0,children:i.heading.text})},i.heading.slug))})]},o.heading.slug))})]},r.sections[0].heading.slug))]})};var yt="for-humanity:navigation-scroll";var xt=e=>{let t=r=>{if(!(typeof r!="object"||r===null||!("navigation"in r)||typeof r.navigation!="string"||!("pathname"in r)||typeof r.pathname!="string"||!("documents"in r)||typeof r.documents!="number"||!Number.isFinite(r.documents)||r.documents<0||!("outline"in r)||typeof r.outline!="number"||!Number.isFinite(r.outline)||r.outline<0))return{navigation:r.navigation,pathname:r.pathname,documents:r.documents,outline:r.outline}};if(typeof e!="object"||e===null||!("positions"in e)||typeof e.positions!="object"||e.positions===null)return{positions:{}};let n={wide:t("wide"in e.positions?e.positions.wide:void 0),desktop:t("desktop"in e.positions?e.positions.desktop:void 0),drawer:t("drawer"in e.positions?e.positions.drawer:void 0)};return{positions:Object.fromEntries(Object.entries(n).filter(r=>r[1]!==void 0))}};var ge=e=>{let t=vt(e);for(let n=t?.closest("details");n;n=n.parentElement?.closest("details"))n.open=!0;return t};var go=e=>{let[t,n]=O(()=>e.stores===void 0?"desktop":matchMedia(fn).matches?"drawer":matchMedia(pn).matches?"wide":"desktop"),[r,o]=O(!1),i=E(null),a=E(null),c=E(null),f=E(null),u=E(null),p=E(null),s=E(null),l=E(null),d=E(null),m=E(null),h=E(t),_=E(null),z=E(!0),w=()=>d.current===null||m.current===null?h.current:d.current.matches?"drawer":m.current.matches?"wide":"desktop",A=()=>h.current==="drawer"?c.current:i.current,v=()=>h.current==="drawer"?f.current:a.current,$=()=>{let b=A();if(b!==null)return[...b.querySelectorAll(".wg_navigationNav__root a[href]")].map(Z=>`${Z.pathname}:${Z.textContent}`).join(`
|
|
39
39
|
`)},y=()=>{let b=v();if(e.stores===void 0||b===null||u.current===null||z.current||h.current!==w()||h.current==="drawer"&&p.current?.open!==!0)return;let Z=$();if(Z===void 0)return;let j={navigation:Z,pathname:location.pathname,documents:b.scrollTop,outline:u.current.scrollTop};e.stores.scroll.setState(K=>({positions:{...K.positions,[h.current]:j}}))},P=()=>{h.current=w();let b=v(),Z=A();if(e.stores===void 0||b===null||u.current===null||Z===null||h.current==="drawer"&&p.current?.open!==!0)return;let j=$();if(j===void 0)return;let K=e.stores.scroll.getState().positions[h.current];b.scrollTop=0,u.current.scrollTop=0,K===void 0?uo({key:yt,version:1,layout:h.current,toState:xt}):K.navigation===j&&(b.scrollTop=K.documents,K.pathname===location.pathname&&(u.current.scrollTop=K.outline)),Z.dataset.navigationLayout=h.current,z.current=!1,y(),b.dispatchEvent(new Event("scroll")),u.current.dispatchEvent(new Event("scroll"))},L=b=>{p.current?.open!==!0&&(document.body.classList.remove("wg_shell__root--drawerOpen"),o(!1))},ce=()=>{y(),p.current?.close(),document.body.classList.remove("wg_shell__root--drawerOpen"),o(!1)},Q=b=>{w()!=="drawer"||p.current===null||p.current.open||(p.current.showModal(),document.body.classList.add("wg_shell__root--drawerOpen"),o(!0),P())},ze=b=>{ce()},V=b=>{b.preventDefault(),ce()},We=b=>{if(p.current===null||b.target!==p.current)return;let Z=p.current.getBoundingClientRect();(b.clientX<Z.left||b.clientX>Z.right||b.clientY<Z.top||b.clientY>Z.bottom)&&ce()},Ge=b=>{if(y(),p.current?.open!==!0||b.defaultPrevented||b.button!==0||b.metaKey||b.ctrlKey||b.shiftKey||b.altKey||!(b.target instanceof Element))return;let Z=b.target.closest("a[href]");if(!(!(Z instanceof HTMLAnchorElement)||Z.target!==""&&Z.target!=="_self"||Z.hasAttribute("download"))&&(ce(),Z.origin===location.origin&&Z.pathname===location.pathname&&Z.search===location.search&&Z.hash)){let j=ge(Z.hash);j!==null&&(j.tabIndex=-1,j.focus({preventScroll:!0}))}},ae=()=>{let b=w();b!==h.current&&(document.activeElement instanceof HTMLElement&&(_.current={navigation:document.activeElement.closest("[data-navigation]")!==null,drawer:document.activeElement===s.current||document.activeElement.closest("[data-navigation-drawer]")!==null,href:document.activeElement.getAttribute("href")}),b!=="drawer"&&ce(),z.current=!0,h.current=b,at(()=>n(b)))},yn=b=>{!b.persisted||e.stores===void 0||(z.current=!0,at(()=>e.stores?.scroll.persist.rehydrate()),ae(),P())};return I(()=>{if(e.stores!==void 0)return d.current=matchMedia(fn),m.current=matchMedia(pn),d.current.addEventListener("change",ae),m.current.addEventListener("change",ae),addEventListener("pagehide",y),addEventListener("pageshow",yn),()=>{d.current?.removeEventListener("change",ae),m.current?.removeEventListener("change",ae),d.current=null,m.current=null,removeEventListener("pagehide",y),removeEventListener("pageshow",yn),document.body.classList.remove("wg_shell__root--drawerOpen")}},[e.stores]),I(()=>{if(e.stores===void 0)return;let b=!0,Z=()=>{if(!b||(P(),_.current===null))return;let j=A();if(t==="drawer")_.current.navigation&&s.current?.focus({preventScroll:!0});else if(_.current.navigation&&j!==null){let K=_.current.href;[...j.querySelectorAll("a[href]")].find(So=>So.getAttribute("href")===K)?.focus({preventScroll:!0})}else _.current.drawer&&l.current?.focus({preventScroll:!0});_.current=null};return v()?.isConnected?Z():queueMicrotask(Z),()=>{b=!1}},[t,e.stores]),g(R,{children:[g("div",{className:x("wg_navigation__sidebar",e.stores!==void 0&&"wg_navigation__sidebar--navigationReady"),children:[g("div",{className:x("wg_navigation__brandRow"),children:[g("a",{ref:e.stores===void 0?void 0:l,className:x("wg_navigation__brand"),href:"/","aria-current":e.data.home?"page":void 0,children:e.data.title}),g("button",{ref:e.stores===void 0?void 0:s,className:x("wg_navigation__menuToggle",e.stores!==void 0&&t==="drawer"&&"wg_navigation__menuToggle--visible"),type:"button","aria-label":fo,"aria-controls":"fh-navigation-drawer","aria-expanded":String(r),"data-navigation-open":"",onClick:Q,children:g("svg",{className:x("wg_navigation__menuIcon"),viewBox:"0 0 24 24","aria-hidden":"true",focusable:"false",children:g("path",{d:"M4 6h16M4 12h16M4 18h16"})})})]}),t!=="drawer"&&g("div",{ref:e.stores===void 0?void 0:i,className:x("wg_navigation__navigation"),"data-navigation":"",children:g(_t,{portRef:a,kind:"documents",ready:e.stores!==void 0,onScroll:y,onClick:Ge,children:g(mn,{groups:e.data.groups})})})]}),g("aside",{className:x("wg_navigation__tocRail"),"data-navigation-rail":"",children:g("div",{className:x("wg_navigation__outline"),"data-navigation-outline":"",children:g(_t,{portRef:u,kind:"outline",ready:e.stores!==void 0,onScroll:y,onClick:Ge,children:e.data.outline.length>0&&g(ho,{groups:e.data.outline})})})}),g("dialog",{ref:e.stores===void 0?void 0:p,className:x("wg_navigation__drawer"),id:"fh-navigation-drawer","aria-labelledby":"fh-navigation-title","data-navigation-drawer":"",onClose:L,onCancel:V,onClick:We,children:[g("div",{className:x("wg_navigation__drawerHeader"),children:[g("h2",{className:x("wg_navigation__drawerTitle"),id:"fh-navigation-title",children:mo}),g("button",{className:x("wg_navigation__drawerClose"),type:"button","aria-label":po,"data-navigation-close":"",onClick:ze,children:g("svg",{className:x("wg_navigation__menuIcon"),viewBox:"0 0 24 24","aria-hidden":"true",focusable:"false",children:g("path",{d:"m6 6 12 12M18 6 6 18"})})})]}),g("div",{className:x("wg_navigation__drawerContent"),"data-navigation-content":"",children:t==="drawer"&&g("div",{ref:e.stores===void 0?void 0:c,className:x("wg_navigation__navigation"),"data-navigation":"",children:g(_t,{portRef:f,kind:"documents",ready:e.stores!==void 0,onScroll:y,onClick:Ge,children:g(mn,{groups:e.data.groups})})})})]})]})};var vo=e=>{let t=E(null),n=E(0),r=E(null),o=E(null),i=E(null),a=()=>{clearTimeout(n.current),n.current=0,r.current?.abort(),r.current=null,t.current?.classList.remove("wg_prose__headingText--highlighted"),t.current=null},c=m=>{m.target===document&&(clearTimeout(n.current),r.current?.abort(),r.current=null,n.current=window.setTimeout(a,3e3))},f=m=>{a(),t.current=m===null?null:m.querySelector(".wg_prose__headingText"),t.current!==null&&(t.current.classList.add("wg_prose__headingText--highlighted"),n.current=window.setTimeout(a,3e3),r.current=new AbortController,document.addEventListener("scrollend",c,{signal:r.current.signal}))},u=m=>{if(m.defaultPrevented||m.button!==0||m.metaKey||m.ctrlKey||m.shiftKey||m.altKey)return;let h=m.target instanceof Element?m.target.closest("a[href]"):null;if(h instanceof HTMLAnchorElement&&(h.target===""||h.target==="_self")&&!h.hasAttribute("download")&&h.origin===location.origin&&h.pathname===location.pathname&&h.search===location.search&&h.hash){let _=ge(h.hash);h.hash===location.hash&&f(_)}},p=()=>{let m=ge(location.hash);m?.scrollIntoView(),f(m)},s=()=>{i.current?.abort()},l=async()=>{let m=o.current,h=location.hash,_=ge(h);await document.fonts.ready,!(m===null||m.signal.aborted)&&(_!==null&&!i.current?.signal.aborted&&h===location.hash&&(_.scrollIntoView({behavior:"instant"}),f(_)),document.documentElement.style.removeProperty("scroll-behavior"))},d=()=>{ge(location.hash),document.readyState==="complete"&&l()};return I(()=>{let m=new AbortController;o.current=m,i.current=new AbortController,document.documentElement.style.scrollBehavior="auto",document.addEventListener("click",u,{signal:m.signal}),addEventListener("hashchange",p,{signal:m.signal}),addEventListener("load",l,{once:!0,signal:m.signal});for(let h of["wheel","touchmove","keydown","mousedown"])addEventListener(h,s,{once:!0,passive:!0,signal:m.signal});return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",d,{once:!0,signal:m.signal}):d(),()=>{m.abort(),o.current=null,i.current?.abort(),i.current=null,a(),document.documentElement.style.removeProperty("scroll-behavior")}},[]),nt(()=>{if(!e.reload||o.current===null)return;let m=new EventSource(io);return m.onmessage=()=>location.reload(),()=>m.close()},[e.reload]),g(R,{children:[g("div",{className:x("wg_shellControls__navigation"),children:g(go,{data:e.data,stores:e.stores})}),g(ao,{ready:e.stores!==void 0})]})};function _n(e,t){let n;try{n=e()}catch{return}return{getItem:o=>{var i;let a=f=>f===null?null:JSON.parse(f,t?.reviver),c=(i=n.getItem(o))!=null?i:null;return c instanceof Promise?c.then(a):a(c)},setItem:(o,i)=>n.setItem(o,JSON.stringify(i,t?.replacer)),removeItem:o=>n.removeItem(o)}}var gn=e=>t=>{try{let n=e(t);return n instanceof Promise?n:{then(r){return gn(r)(n)},catch(r){return this}}}catch(n){return{then(r){return this},catch(r){return gn(r)(n)}}}},us=(e,t)=>(n,r,o)=>{let i={storage:_n(()=>window.localStorage),partialize:_=>_,version:0,merge:(_,z)=>({...z,..._}),...t},a=!1,c=0,f=new Set,u=new Set,p=i.storage;if(!p)return e((..._)=>{console.warn(`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`),n(..._)},r,o);let s=()=>{let _=i.partialize({...r()});return p.setItem(i.name,{state:_,version:i.version})},l=o.setState;o.setState=(_,z)=>(l(_,z),s());let d=e((..._)=>(n(..._),s()),r,o);o.getInitialState=()=>d;let m,h=()=>{var _,z;if(!p)return;let w=++c;a=!1,f.forEach(v=>{var $;return v(($=r())!=null?$:d)});let A=((z=i.onRehydrateStorage)==null?void 0:z.call(i,(_=r())!=null?_:d))||void 0;return gn(p.getItem.bind(p))(i.name).then(v=>{if(v)if(typeof v.version=="number"&&v.version!==i.version){if(i.migrate){let $=i.migrate(v.state,v.version);return $ instanceof Promise?$.then(y=>[!0,y]):[!0,$]}console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return[!1,v.state];return[!1,void 0]}).then(v=>{var $;if(w!==c)return;let[y,P]=v;if(m=i.merge(P,($=r())!=null?$:d),n(m,!0),y)return s()}).then(()=>{w===c&&(A?.(r(),void 0),m=r(),a=!0,u.forEach(v=>v(m)))}).catch(v=>{w===c&&A?.(void 0,v)})};return o.persist={setOptions:_=>{i={...i,..._},_.storage&&(p=_.storage)},clearStorage:()=>{++c,p?.removeItem(i.name)},getOptions:()=>i,rehydrate:()=>h(),hasHydrated:()=>a,onHydrate:_=>(f.add(_),()=>{f.delete(_)}),onFinishHydration:_=>(u.add(_),()=>{u.delete(_)})},i.skipHydration||h(),m||d},yo=us;var xo=e=>{let t,n=new Set,r=(u,p)=>{let s=typeof u=="function"?u(t):u;if(!Object.is(s,t)){let l=t;t=p??(typeof s!="object"||s===null)?s:Object.assign({},t,s),n.forEach(d=>d(t,l))}},o=()=>t,c={setState:r,getState:o,getInitialState:()=>f,subscribe:u=>(n.add(u),()=>n.delete(u))},f=t=e(r,o,c);return c},bo=(e=>e?xo(e):xo);var wo=e=>{let t=n=>({getItem:r=>n().getItem(r),setItem:(r,o)=>{try{return n().setItem(r,o)}catch{}},removeItem:r=>{try{return n().removeItem(r)}catch{}}});return{scroll:bo()(yo(()=>({positions:{}}),{name:yt,version:1,storage:_n(()=>t(e.session)),merge:n=>xt(n),migrate:()=>({positions:{}})}))}};var vn=document.querySelector("[data-shell-browser-root]"),$o=document.getElementById("fh-navigation-data");if(vn!==null&&$o!==null)try{let e=JSON.parse($o.textContent),t=Fr.parse(e),n=wo({session:()=>sessionStorage});Jn(vn).render(g(vo,{data:t,stores:n,reload:vn.hasAttribute("data-shell-reload")}))}catch(e){console.error("for-humanity browser initialization failed",e)}})();
|
package/dist/cli.css
CHANGED
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
border-radius: var(--app-radius-inline);
|
|
107
107
|
background: var(--app-color-code);
|
|
108
108
|
color: var(--app-color-text-strong);
|
|
109
|
-
font-family:
|
|
109
|
+
font-family: inherit;
|
|
110
110
|
font-size: 1em;
|
|
111
111
|
}
|
|
112
112
|
& pre {
|
|
@@ -119,6 +119,7 @@
|
|
|
119
119
|
font-family: var(--app-font-mono);
|
|
120
120
|
font-size: var(--app-font-size-detail);
|
|
121
121
|
line-height: var(--app-line-height-code);
|
|
122
|
+
letter-spacing: 0;
|
|
122
123
|
}
|
|
123
124
|
& pre code {
|
|
124
125
|
padding: 0;
|
|
@@ -247,6 +248,7 @@
|
|
|
247
248
|
overflow-x: auto;
|
|
248
249
|
margin: var(--app-space-block) 0;
|
|
249
250
|
padding: var(--app-space-block) 0;
|
|
251
|
+
letter-spacing: 0;
|
|
250
252
|
& svg {
|
|
251
253
|
display: block;
|
|
252
254
|
max-width: 100%;
|
|
@@ -656,7 +658,7 @@
|
|
|
656
658
|
scrollbar-color: auto;
|
|
657
659
|
}
|
|
658
660
|
}
|
|
659
|
-
@media (width <
|
|
661
|
+
@media (width < 1360px) {
|
|
660
662
|
.wg_navigation__tocRail {
|
|
661
663
|
display: none;
|
|
662
664
|
}
|
|
@@ -745,7 +747,8 @@
|
|
|
745
747
|
"Monoplex KR",
|
|
746
748
|
ui-monospace,
|
|
747
749
|
monospace;
|
|
748
|
-
--app-font-
|
|
750
|
+
--app-font-body: "IBM Plex Sans KR", var(--app-font-mono);
|
|
751
|
+
--app-font-brand: "Architects Daughter", var(--app-font-body);
|
|
749
752
|
--app-font-size-group: 11px;
|
|
750
753
|
--app-font-size-detail: 12px;
|
|
751
754
|
--app-font-size-dense: 12px;
|
|
@@ -763,9 +766,10 @@
|
|
|
763
766
|
--app-line-height-tight: 1.4;
|
|
764
767
|
--app-line-height-code: 1.65;
|
|
765
768
|
--app-line-height-body: 1.7;
|
|
769
|
+
--app-letter-spacing-body: -0.03em;
|
|
766
770
|
--app-letter-spacing-brand: 0;
|
|
767
|
-
--app-letter-spacing-heading: -0.
|
|
768
|
-
--app-letter-spacing-title: -0.
|
|
771
|
+
--app-letter-spacing-heading: -0.04em;
|
|
772
|
+
--app-letter-spacing-title: -0.045em;
|
|
769
773
|
--app-space-inline: 6px;
|
|
770
774
|
--app-space-stack: 10px;
|
|
771
775
|
--app-space-block: 14px;
|
|
@@ -779,9 +783,8 @@
|
|
|
779
783
|
--app-space-gutter: 28px;
|
|
780
784
|
--app-space-column: 32px;
|
|
781
785
|
--app-space-sidebar-gap: 32px;
|
|
782
|
-
--app-size-sidebar:
|
|
783
|
-
--app-size-
|
|
784
|
-
--app-size-page: calc(var(--app-size-main) + (var(--app-size-sidebar) + var(--app-space-sidebar-gap) + var(--app-space-gutter)) * 2);
|
|
786
|
+
--app-size-sidebar: 200px;
|
|
787
|
+
--app-size-page: 1920px;
|
|
785
788
|
--app-size-brand: calc(var(--app-font-size-title) * var(--app-line-height-title) + var(--app-space-page-top) + var(--app-space-group));
|
|
786
789
|
--app-size-mobile-header: 56px;
|
|
787
790
|
--app-size-menu-button: 44px;
|
|
@@ -830,12 +833,13 @@
|
|
|
830
833
|
max-width: var(--app-size-page);
|
|
831
834
|
margin: 0 auto;
|
|
832
835
|
padding: 0 var(--app-space-gutter);
|
|
833
|
-
grid-template: "nav main outline" 1fr / calc(var(--app-size-sidebar) + var(--app-space-sidebar-gap)) minmax(0,
|
|
836
|
+
grid-template: "nav main outline" 1fr / calc(var(--app-size-sidebar) + var(--app-space-sidebar-gap)) minmax(0, 1fr) calc(var(--app-size-sidebar) + var(--app-space-sidebar-gap));
|
|
834
837
|
background: var(--app-color-ground);
|
|
835
838
|
color: var(--app-color-text);
|
|
836
|
-
font-family: var(--app-font-
|
|
839
|
+
font-family: var(--app-font-body);
|
|
837
840
|
font-size: var(--app-font-size-body);
|
|
838
841
|
line-height: var(--app-line-height-body);
|
|
842
|
+
letter-spacing: var(--app-letter-spacing-body);
|
|
839
843
|
word-break: keep-all;
|
|
840
844
|
overflow-wrap: break-word;
|
|
841
845
|
text-wrap: pretty;
|
|
@@ -850,19 +854,17 @@
|
|
|
850
854
|
.wg_shell__main {
|
|
851
855
|
grid-area: main;
|
|
852
856
|
min-width: 0;
|
|
853
|
-
max-width: var(--app-size-main);
|
|
854
857
|
border-inline: 1px solid var(--app-color-border-layout);
|
|
855
858
|
padding-block: var(--app-size-brand) calc(100vh - var(--app-space-anchor));
|
|
856
859
|
padding-inline: var(--app-space-column);
|
|
857
860
|
}
|
|
858
|
-
@media (width <
|
|
861
|
+
@media (width < 1360px) {
|
|
859
862
|
.wg_shell__root {
|
|
860
|
-
grid-template: "nav main
|
|
863
|
+
grid-template: "nav main" 1fr / calc(var(--app-size-sidebar) + var(--app-space-sidebar-gap)) minmax(0, 1fr);
|
|
861
864
|
}
|
|
862
865
|
}
|
|
863
866
|
@media (width < 1024px) {
|
|
864
867
|
.wg_shell__root {
|
|
865
|
-
max-width: calc(var(--app-size-main) + var(--app-space-gutter) * 2);
|
|
866
868
|
grid-template: "nav" auto "main" 1fr / minmax(0, 1fr);
|
|
867
869
|
}
|
|
868
870
|
.wg_shell__main {
|
package/dist/cli.js
CHANGED
|
@@ -67,6 +67,7 @@ var copy_error_asset = "\uC790\uC6D0\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uB2E4
|
|
|
67
67
|
|
|
68
68
|
// src/constant/font.ts
|
|
69
69
|
var font_mono_css = "src/asset/font/monoplex-kr/monoplex-kr.css";
|
|
70
|
+
var font_body_css = "src/asset/font/ibm-plex-sans-kr/ibm-plex-sans-kr.css";
|
|
70
71
|
var font_brand_css = "src/asset/font/architects-daughter/architects-daughter.css";
|
|
71
72
|
var font_display_strategy = "optional";
|
|
72
73
|
var font_hash_length = 12;
|
|
@@ -342,7 +343,7 @@ import { flushSync } from "hono/jsx/dom";
|
|
|
342
343
|
|
|
343
344
|
// src/component/widget/navigation/_constant/navigation.ts
|
|
344
345
|
var navigation_mobile_query = "(width < 1024px)";
|
|
345
|
-
var navigation_wide_query = "(width >=
|
|
346
|
+
var navigation_wide_query = "(width >= 1360px)";
|
|
346
347
|
|
|
347
348
|
// src/component/widget/navigation/_function/restore-navigation-scroll.ts
|
|
348
349
|
var restoreNavigationScroll = (options) => {
|
|
@@ -2055,11 +2056,18 @@ var main = async () => {
|
|
|
2055
2056
|
}
|
|
2056
2057
|
const siteConfig = parsedConfig.data;
|
|
2057
2058
|
const mono = toFontCss({ css: join4(kitRoot, font_mono_css), fontDir: asset_font_dir });
|
|
2059
|
+
const body = toFontCss({ css: join4(kitRoot, font_body_css), fontDir: asset_font_dir });
|
|
2058
2060
|
const brand = toFontCss({ css: join4(kitRoot, font_brand_css), fontDir: asset_font_dir });
|
|
2059
|
-
const fontCss = [mono.css, brand.css].join("\n");
|
|
2061
|
+
const fontCss = [mono.css, body.css, brand.css].join("\n");
|
|
2060
2062
|
const stylePath = toAssetPath({ path: asset_style_path, file: join4(kitRoot, "dist/cli.css") });
|
|
2061
2063
|
const browserScript = readFileSync3(join4(kitRoot, "dist/browser.js"), "utf8");
|
|
2062
|
-
const kitFiles = new Map([
|
|
2064
|
+
const kitFiles = new Map([
|
|
2065
|
+
[stylePath, join4(kitRoot, "dist/cli.css")],
|
|
2066
|
+
[asset_favicon_path, join4(kitRoot, "src/asset/favicon.svg")],
|
|
2067
|
+
...mono.files,
|
|
2068
|
+
...body.files,
|
|
2069
|
+
...brand.files
|
|
2070
|
+
]);
|
|
2063
2071
|
const files = new Map(kitFiles);
|
|
2064
2072
|
const processor = createProcessor({ site: siteConfig, root: docsRoot, files });
|
|
2065
2073
|
const [docs, home] = await Promise.all([
|
|
@@ -2071,7 +2079,7 @@ var main = async () => {
|
|
|
2071
2079
|
const app = createApp({
|
|
2072
2080
|
site: siteConfig,
|
|
2073
2081
|
store,
|
|
2074
|
-
assets: { stylePath, browserScript, fontCss, preload: [...brand.files.keys(), ...mono.files.keys()], reload: command === "dev" }
|
|
2082
|
+
assets: { stylePath, browserScript, fontCss, preload: [...brand.files.keys(), ...mono.files.keys(), ...body.files.keys()], reload: command === "dev" }
|
|
2075
2083
|
});
|
|
2076
2084
|
if (command === "build") {
|
|
2077
2085
|
await rm(outDir, { recursive: true, force: true });
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright © 2017 IBM Corp. with Reserved Font Name "Plex"
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
|
|
5
|
+
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* IBM Plex Sans KR 1.003 · npm @ibm/plex-sans-kr 1.1.0 · https://github.com/IBM/plex
|
|
3
|
+
* 배포 WOFF2(fonts/complete/woff2/hinted) 원본 그대로 · 라이선스는 옆의 LICENSE.txt
|
|
4
|
+
* 본문의 한글 음절·호환 자모만 담당 · Monoplex KR 한글과 같은 글자의 원래 폭
|
|
5
|
+
*/
|
|
6
|
+
@font-face {
|
|
7
|
+
font-family: "IBM Plex Sans KR";
|
|
8
|
+
font-style: normal;
|
|
9
|
+
font-display: swap;
|
|
10
|
+
font-weight: 400;
|
|
11
|
+
src: url(./IBMPlexSansKR-Regular.woff2) format("woff2");
|
|
12
|
+
unicode-range: U+3131-318E, U+AC00-D7A3;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@font-face {
|
|
16
|
+
font-family: "IBM Plex Sans KR";
|
|
17
|
+
font-style: normal;
|
|
18
|
+
font-display: swap;
|
|
19
|
+
font-weight: 600;
|
|
20
|
+
src: url(./IBMPlexSansKR-SemiBold.woff2) format("woff2");
|
|
21
|
+
unicode-range: U+3131-318E, U+AC00-D7A3;
|
|
22
|
+
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
export const navigation_mobile_query = "(width < 1024px)";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* 양쪽
|
|
7
|
+
* 양쪽 200px 탐색·간격 120px·최소 800px 본문과 스크롤바가 들어가는 3열 기준
|
|
8
8
|
*/
|
|
9
|
-
export const navigation_wide_query = "(width >=
|
|
9
|
+
export const navigation_wide_query = "(width >= 1360px)";
|
|
@@ -135,7 +135,9 @@
|
|
|
135
135
|
border-radius: var(--app-radius-inline);
|
|
136
136
|
background: var(--app-color-code);
|
|
137
137
|
color: var(--app-color-text-strong);
|
|
138
|
-
|
|
138
|
+
|
|
139
|
+
/* UA monospace 대신 부모 글꼴 · 문단은 본문 정책, 코드 블록은 pre의 고정폭·자간 0 */
|
|
140
|
+
font-family: inherit;
|
|
139
141
|
font-size: 1em;
|
|
140
142
|
}
|
|
141
143
|
|
|
@@ -150,6 +152,7 @@
|
|
|
150
152
|
font-family: var(--app-font-mono);
|
|
151
153
|
font-size: var(--app-font-size-detail);
|
|
152
154
|
line-height: var(--app-line-height-code);
|
|
155
|
+
letter-spacing: 0;
|
|
153
156
|
}
|
|
154
157
|
|
|
155
158
|
& pre code {
|
|
@@ -320,6 +323,9 @@
|
|
|
320
323
|
margin: var(--app-space-block) 0;
|
|
321
324
|
padding: var(--app-space-block) 0;
|
|
322
325
|
|
|
326
|
+
/* 라벨 위치는 자간 0의 격자로 계산 */
|
|
327
|
+
letter-spacing: 0;
|
|
328
|
+
|
|
323
329
|
/* stylelint-disable-next-line selector-disallowed-list -- 외부 렌더러 생성 SVG */
|
|
324
330
|
& svg {
|
|
325
331
|
display: block;
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* 넓은 화면은 같은 폭의 양쪽 탐색 · 좁은 화면은 문서 탐색만 표시
|
|
2
|
+
* 넓은 화면은 같은 폭의 양쪽 탐색 사이를 본문이 채움 · 좁은 화면은 문서 탐색만 표시
|
|
3
3
|
*/
|
|
4
4
|
.wg_shell__root {
|
|
5
5
|
display: grid;
|
|
6
6
|
max-width: var(--app-size-page);
|
|
7
7
|
margin: 0 auto;
|
|
8
8
|
padding: 0 var(--app-space-gutter);
|
|
9
|
-
grid-template: "nav main outline" 1fr / calc(var(--app-size-sidebar) + var(--app-space-sidebar-gap)) minmax(0, var(--app-size-
|
|
10
|
-
var(--app-size-sidebar) +
|
|
11
|
-
var(--app-space-sidebar-gap)
|
|
12
|
-
);
|
|
9
|
+
grid-template: "nav main outline" 1fr / calc(var(--app-size-sidebar) + var(--app-space-sidebar-gap)) minmax(0, 1fr) calc(var(--app-size-sidebar) + var(--app-space-sidebar-gap));
|
|
13
10
|
background: var(--app-color-ground);
|
|
14
11
|
color: var(--app-color-text);
|
|
15
|
-
font-family: var(--app-font-
|
|
12
|
+
font-family: var(--app-font-body);
|
|
16
13
|
font-size: var(--app-font-size-body);
|
|
17
14
|
line-height: var(--app-line-height-body);
|
|
15
|
+
letter-spacing: var(--app-letter-spacing-body);
|
|
18
16
|
|
|
19
17
|
/* 한국어 낱말 단위 줄바꿈 · 긴 식별자만 예외 */
|
|
20
18
|
word-break: keep-all;
|
|
@@ -35,7 +33,6 @@
|
|
|
35
33
|
.wg_shell__main {
|
|
36
34
|
grid-area: main;
|
|
37
35
|
min-width: 0;
|
|
38
|
-
max-width: var(--app-size-main);
|
|
39
36
|
border-inline: 1px solid var(--app-color-border-layout);
|
|
40
37
|
|
|
41
38
|
/* 문서 목록의 시작선 · 마지막 절도 읽는 선까지 이동 가능한 끝 여백 */
|
|
@@ -43,17 +40,16 @@
|
|
|
43
40
|
padding-inline: var(--app-space-column);
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
/*
|
|
47
|
-
@media (width <
|
|
43
|
+
/* 본문 최소 약 800px을 남기도록 목차 숨김 · 본문이 오른쪽 여백까지 채움 */
|
|
44
|
+
@media (width < 1360px) {
|
|
48
45
|
.wg_shell__root {
|
|
49
|
-
grid-template: "nav main
|
|
46
|
+
grid-template: "nav main" 1fr / calc(var(--app-size-sidebar) + var(--app-space-sidebar-gap)) minmax(0, 1fr);
|
|
50
47
|
}
|
|
51
48
|
}
|
|
52
49
|
|
|
53
50
|
/* 모바일의 브랜드·본문은 한 열 배치 */
|
|
54
51
|
@media (width < 1024px) {
|
|
55
52
|
.wg_shell__root {
|
|
56
|
-
max-width: calc(var(--app-size-main) + var(--app-space-gutter) * 2);
|
|
57
53
|
grid-template:
|
|
58
54
|
"nav" auto
|
|
59
55
|
"main" 1fr / minmax(0, 1fr);
|
package/src/constant/font.ts
CHANGED
|
@@ -4,10 +4,15 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* 본문 영문·코드·흐름도 글꼴 CSS · 패키지 기준 경로 · Regular·SemiBold 두 파일
|
|
8
8
|
*/
|
|
9
9
|
export const font_mono_css = "src/asset/font/monoplex-kr/monoplex-kr.css";
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* 본문 한글 글꼴 CSS · IBM Plex Sans KR Regular·SemiBold · 한글 unicode-range
|
|
13
|
+
*/
|
|
14
|
+
export const font_body_css = "src/asset/font/ibm-plex-sans-kr/ibm-plex-sans-kr.css";
|
|
15
|
+
|
|
11
16
|
/**
|
|
12
17
|
* 사이트 이름 글꼴 CSS · Architects Daughter Regular · 라틴 subset
|
|
13
18
|
*/
|
package/src/entry/cli/cli.ts
CHANGED
|
@@ -16,7 +16,7 @@ import {Hono} from "hono";
|
|
|
16
16
|
import {toSSG} from "hono/ssg";
|
|
17
17
|
import {asset_favicon_path, asset_font_dir, asset_media_extensions, asset_style_path} from "@/constant/asset";
|
|
18
18
|
import {copy_error_config, copy_error_prefix, copy_error_unknown_command} from "@/constant/copy";
|
|
19
|
-
import {font_brand_css, font_cache_control, font_mono_css} from "@/constant/font";
|
|
19
|
+
import {font_body_css, font_brand_css, font_cache_control, font_mono_css} from "@/constant/font";
|
|
20
20
|
import {site_config_absent} from "@/constant/site";
|
|
21
21
|
import {cli_config_file_name, cli_default_command, cli_default_docs_dir, cli_dev_port, cli_reload_delay_ms} from "@/entry/cli/_constant/cli";
|
|
22
22
|
import {crawling_reserved_roots} from "@/entry/cli/_constant/crawling";
|
|
@@ -78,12 +78,19 @@ const main = async () => {
|
|
|
78
78
|
const siteConfig = parsedConfig.data;
|
|
79
79
|
// 내장 @font-face와 파일 수집 · font-family는 token.css 소유
|
|
80
80
|
const mono = toFontCss({css: join(kitRoot, font_mono_css), fontDir: asset_font_dir});
|
|
81
|
+
const body = toFontCss({css: join(kitRoot, font_body_css), fontDir: asset_font_dir});
|
|
81
82
|
const brand = toFontCss({css: join(kitRoot, font_brand_css), fontDir: asset_font_dir});
|
|
82
83
|
|
|
83
|
-
const fontCss = [mono.css, brand.css].join("\n");
|
|
84
|
+
const fontCss = [mono.css, body.css, brand.css].join("\n");
|
|
84
85
|
const stylePath = toAssetPath({path: asset_style_path, file: join(kitRoot, "dist/cli.css")});
|
|
85
86
|
const browserScript = readFileSync(join(kitRoot, "dist/browser.js"), "utf8");
|
|
86
|
-
const kitFiles = new Map([
|
|
87
|
+
const kitFiles = new Map([
|
|
88
|
+
[stylePath, join(kitRoot, "dist/cli.css")],
|
|
89
|
+
[asset_favicon_path, join(kitRoot, "src/asset/favicon.svg")],
|
|
90
|
+
...mono.files,
|
|
91
|
+
...body.files,
|
|
92
|
+
...brand.files,
|
|
93
|
+
]);
|
|
87
94
|
const files = new Map(kitFiles);
|
|
88
95
|
const processor = createProcessor({site: siteConfig, root: docsRoot, files});
|
|
89
96
|
const [docs, home] = await Promise.all([
|
|
@@ -95,7 +102,7 @@ const main = async () => {
|
|
|
95
102
|
const app = createApp({
|
|
96
103
|
site: siteConfig,
|
|
97
104
|
store,
|
|
98
|
-
assets: {stylePath, browserScript, fontCss, preload: [...brand.files.keys(), ...mono.files.keys()], reload: command === "dev"},
|
|
105
|
+
assets: {stylePath, browserScript, fontCss, preload: [...brand.files.keys(), ...mono.files.keys(), ...body.files.keys()], reload: command === "dev"},
|
|
99
106
|
});
|
|
100
107
|
|
|
101
108
|
if (command === "build") {
|
package/src/style/token.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* 공통 토큰의 단일 출처 · --app-종류-쓰임
|
|
3
3
|
* 사용 기준: templates/document/design.md · 테마 분기는 color-scheme에 한정
|
|
4
|
-
* 폭 기준
|
|
4
|
+
* 폭 기준 1360px·1024px·640px · 양쪽 탐색과 본문 배치
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
:root {
|
|
@@ -48,11 +48,13 @@
|
|
|
48
48
|
|
|
49
49
|
/*
|
|
50
50
|
* 내장 글꼴 · CLI는 @font-face와 자원 URL 생성
|
|
51
|
-
*
|
|
52
|
-
* 영문 폭 0.528em = 흐름도 12px 격자의 6.336px · 한글은 정확히 2칸
|
|
51
|
+
* 본문·라벨·인라인 코드 한글 IBM Plex Sans KR·영문 Monoplex KR · 코드 블록·흐름도 Monoplex KR · 사이트 이름 Architects Daughter
|
|
52
|
+
* 영문 폭 0.528em = 흐름도 12px 격자의 6.336px · 코드 블록·흐름도의 한글은 정확히 2칸
|
|
53
|
+
* 본문 맨 앞의 IBM Plex Sans KR은 한글 unicode-range만 담당 · 영문·숫자·기호는 다음 순서의 Monoplex KR
|
|
53
54
|
*/
|
|
54
55
|
--app-font-mono: "Monoplex KR", ui-monospace, monospace;
|
|
55
|
-
--app-font-
|
|
56
|
+
--app-font-body: "IBM Plex Sans KR", var(--app-font-mono);
|
|
57
|
+
--app-font-brand: "Architects Daughter", var(--app-font-body);
|
|
56
58
|
|
|
57
59
|
/* 글자 크기 · 11px 비상호작용 묶음 · 12px 기본과 역할별 제목 크기 */
|
|
58
60
|
--app-font-size-group: 11px;
|
|
@@ -77,10 +79,11 @@
|
|
|
77
79
|
--app-line-height-code: 1.65;
|
|
78
80
|
--app-line-height-body: 1.7;
|
|
79
81
|
|
|
80
|
-
/* 자간 · 사이트 이름은 기본
|
|
82
|
+
/* 자간 · 본문·라벨·인라인 코드를 조이고 제목은 그보다 조금 더 · 사이트 이름은 기본 폭 · 코드 블록·흐름도는 격자를 위해 0 */
|
|
83
|
+
--app-letter-spacing-body: -0.03em;
|
|
81
84
|
--app-letter-spacing-brand: 0;
|
|
82
|
-
--app-letter-spacing-heading: -0.
|
|
83
|
-
--app-letter-spacing-title: -0.
|
|
85
|
+
--app-letter-spacing-heading: -0.04em;
|
|
86
|
+
--app-letter-spacing-title: -0.045em;
|
|
84
87
|
|
|
85
88
|
/* 공통 간격 · margin·padding·gap의 리듬 · 단독 보정은 지역 값 */
|
|
86
89
|
--app-space-inline: 6px;
|
|
@@ -100,9 +103,10 @@
|
|
|
100
103
|
--app-space-gutter: 28px;
|
|
101
104
|
--app-space-column: 32px;
|
|
102
105
|
--app-space-sidebar-gap: 32px;
|
|
103
|
-
--app-size-sidebar:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
--app-size-sidebar: 200px;
|
|
107
|
+
|
|
108
|
+
/* 페이지 최대 폭 · 본문은 사이드바·간격을 뺀 나머지 전체 */
|
|
109
|
+
--app-size-page: 1920px;
|
|
106
110
|
--app-size-brand: calc(var(--app-font-size-title) * var(--app-line-height-title) + var(--app-space-page-top) + var(--app-space-group));
|
|
107
111
|
--app-size-mobile-header: 56px;
|
|
108
112
|
--app-size-menu-button: 44px;
|
|
@@ -4,11 +4,11 @@ import {tmpdir} from "node:os";
|
|
|
4
4
|
import {join} from "node:path";
|
|
5
5
|
import {test} from "node:test";
|
|
6
6
|
import {asset_font_dir} from "@/constant/asset";
|
|
7
|
-
import {font_brand_css, font_mono_css} from "@/constant/font";
|
|
7
|
+
import {font_body_css, font_brand_css, font_mono_css} from "@/constant/font";
|
|
8
8
|
import {toFontCss} from "@/util/font/to-font-css";
|
|
9
9
|
|
|
10
10
|
test("bundled fonts prevent a late swap after fallback text is visible", () => {
|
|
11
|
-
for (const css of [font_mono_css, font_brand_css]) {
|
|
11
|
+
for (const css of [font_mono_css, font_body_css, font_brand_css]) {
|
|
12
12
|
const result = toFontCss({css: join(process.cwd(), css), fontDir: asset_font_dir});
|
|
13
13
|
|
|
14
14
|
assert.match(result.css, /font-display:\s*optional;/);
|