- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환 - Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용 - pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관) - worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md) - D:\Rhino-MCP 경로 참조를 새 위치로 치환 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
46 lines
3.2 KiB
Python
46 lines
3.2 KiB
Python
"""Build web/static/prism.css from the design mockup's pier.css (2026-10-16): the Prism tokens (:root) plus the component rules
|
|
(card, strip, banner, badge, button, field, table, key-value, list, scroll, chip ...) with every selector scoped under `.prism`, so the
|
|
new stage-B screens use Prism while the old screens keep their look until stage D.
|
|
Skipped from the mockup: global resets (body, a, headings), the app shell (.app/.top/.rail/.main/...), the modal scrim.
|
|
usage: python tools/make_prism_css.py"""
|
|
import re
|
|
from pathlib import Path
|
|
|
|
APP = Path(__file__).resolve().parents[1]
|
|
SRC = APP.parents[1] / "DOC" / "01_기획" / "웹앱디자인시안" / "시안" / "pier.css"
|
|
OUT = APP / "web" / "static" / "prism.css"
|
|
START = "/* scope, card, strip, banner */"
|
|
SKIP_PREFIX = (".scrim", ".modal") # app-shell overlays are not used in the web app
|
|
|
|
|
|
def scope(selector):
|
|
parts = [p.strip() for p in selector.split(",")]
|
|
return ", ".join(f".prism {p}" if not p.startswith("@") else p for p in parts)
|
|
|
|
|
|
css = SRC.read_text(encoding="utf-8")
|
|
root = css[:css.index("* { box-sizing")]
|
|
comp = css[css.index(".eyebrow {"):css.index(START)] + css[css.index(START):] # layout helpers (.row .muted .grid3 ...) + components
|
|
comp = comp.replace("@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }", "")
|
|
rules = re.findall(r"([^{}/]+)\{([^{}]*)\}", re.sub(r"/\*.*?\*/", "", comp, flags=re.S))
|
|
out = ["/* generated by tools/make_prism_css.py from DOC/01_기획/웹앱디자인시안/시안/pier.css — do not edit by hand */",
|
|
'@font-face { font-family: "Pretendard"; src: url("fonts/PretendardVariable.woff2") format("woff2-variations"); font-weight: 45 920; font-display: swap; }',
|
|
root.strip(),
|
|
".prism { font-family: var(--prism-font); font-size: var(--prism-type-body-sm); line-height: var(--prism-lh-body); color: var(--prism-text-body);"
|
|
" font-variant-numeric: tabular-nums; margin: var(--prism-space-200) 0; }", # the page itself is the canvas (prism-app.css)
|
|
".prism * { box-sizing: border-box; }",
|
|
".prism a { color: var(--prism-text-heading); }",
|
|
".prism h1, .prism h2, .prism h3, .prism p, .prism dl, .prism dd, .prism ol, .prism ul { margin: 0; padding: 0; }",
|
|
".prism h2 { font-size: var(--prism-type-title-sm); line-height: var(--prism-lh-title); font-weight: 500; color: var(--prism-text-heading); }",
|
|
".prism h3 { font-size: var(--prism-type-body-lg); font-weight: 700; color: var(--prism-text-heading); }",
|
|
".prism textarea { height: auto; min-height: 5rem; width: 100%; font-family: var(--prism-font); }", # base.html sets a 480 px textarea for the JSON editor
|
|
".prism :focus-visible { outline: var(--prism-focus-ring) solid var(--prism-comp-line-strong); outline-offset: var(--prism-focus-offset); }",
|
|
]
|
|
for sel, body in rules:
|
|
sel = sel.strip()
|
|
if not sel or sel.startswith(SKIP_PREFIX) or sel.startswith("@"):
|
|
continue
|
|
out.append(f"{scope(sel)} {{{body.strip()}}}")
|
|
OUT.write_text("\n".join(out) + "\n", encoding="utf-8")
|
|
print("written", OUT, len(rules), "rules read")
|