ghostwriter-muse-pages 15.0.0 → 16.0.0
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/build_pages.py +19 -4
- package/kit.js +27 -16
- package/package.json +1 -1
package/build_pages.py
CHANGED
|
@@ -20,8 +20,8 @@ Every page it writes is a few lines that load the page code, at one exact versio
|
|
|
20
20
|
"""
|
|
21
21
|
import argparse, json, os, re, sys
|
|
22
22
|
|
|
23
|
-
BUILDER = "0.9.
|
|
24
|
-
KIT_VERSION = "
|
|
23
|
+
BUILDER = "0.9.4" # this builder's own version
|
|
24
|
+
KIT_VERSION = "16.0.0" # the exact version of the page code every page loads
|
|
25
25
|
KIT_URL = "https://cdn.jsdelivr.net/npm/ghostwriter-muse-pages@" + KIT_VERSION + "/kit.js"
|
|
26
26
|
FONTS_URL = "https://fonts.googleapis.com/css2?family=Caveat:wght@600;700&family=Inter:wght@400;500;600&family=Lora:ital,wght@0,400;0,500;0,600;1,400&display=swap"
|
|
27
27
|
GHOSTWRITERS = {"lawrence", "kenji", "saira", "octavio", "zora", "boo", "imani", "indigo", "idris", "ryu", "marcus-aurelius", "frederick-douglass", "jane-austen",
|
|
@@ -29,7 +29,7 @@ GHOSTWRITERS = {"lawrence", "kenji", "saira", "octavio", "zora", "boo", "imani",
|
|
|
29
29
|
PAGES = {"overview": "Overview.html", "setup": "Setup.html", "voice": "Voice.html", "stories": "Stories.html", "notes": "Notes.html", "outline": "Outline.html", "manuscript": "Manuscript.html", "cover": "Cover.html", "ghostwriter": "Ghostwriter.html"}
|
|
30
30
|
STAGE_COUNT = 10
|
|
31
31
|
PAGE_KIT = int(KIT_VERSION.split(".")[0]) # the page version written beside the live link in START-HERE.md
|
|
32
|
-
STORY_FIELDS = {"home": "home", "role": "role", "when": "when", "narrative": "narrative", "how it ended": "ended", "teaching point": "point", "people": "people",
|
|
32
|
+
STORY_FIELDS = {"home": "home", "role": "role", "when": "when", "narrative": "narrative", "how it ended": "ended", "what it meant": "meant", "teaching point": "point", "people": "people",
|
|
33
33
|
"facts that must not change": "facts", "source": "source", "strength": "strength", "told": "told"}
|
|
34
34
|
FIELD = re.compile(r"^([A-Z][A-Za-z0-9'’ /&()-]{1,47}?)\s*:\s*(.*)$")
|
|
35
35
|
LISTITEM = re.compile(r"^(?:[-*•]|\d+[.)])\s+(.*)$")
|
|
@@ -90,12 +90,21 @@ def check(book):
|
|
|
90
90
|
if "title" not in c or ("n" not in c and "label" not in c):
|
|
91
91
|
fail('each outline chapter needs a title and either n (a number) or label (for example "Introduction").')
|
|
92
92
|
c["key"] = ("ch-%02d" % c["n"]) if "n" in c and "label" not in c else slug(c["label"])
|
|
93
|
+
# how much of the author's own material the chapter has to stand on: ready, thin, or empty
|
|
94
|
+
if "depth" in c and c["depth"] not in ("ready", "thin", "empty"):
|
|
95
|
+
DEPTH_NOTES.append('outline: "%s" has depth "%s". Use ready, thin, or empty. It was left out.' % (c["title"], c["depth"]))
|
|
96
|
+
c.pop("depth")
|
|
97
|
+
if "needs" in c:
|
|
98
|
+
c["needs"] = re.sub(r"\s+", " ", str(c["needs"])).strip()[:300]
|
|
99
|
+
if not c["needs"] or c.get("depth") not in ("thin", "empty"):
|
|
100
|
+
c.pop("needs")
|
|
93
101
|
for s in c.get("sections", []):
|
|
94
102
|
if "num" not in s or "title" not in s:
|
|
95
103
|
fail('each outline section needs num (for example "3.2") and title.')
|
|
96
104
|
return state, outline
|
|
97
105
|
|
|
98
106
|
|
|
107
|
+
DEPTH_NOTES = []
|
|
99
108
|
INLINE_MARKER = re.compile(r"\[(AUTHOR TO CONFIRM|STORY NEEDED):")
|
|
100
109
|
|
|
101
110
|
|
|
@@ -369,7 +378,7 @@ def read_stories(plan, problems):
|
|
|
369
378
|
story[name] = val
|
|
370
379
|
if "(proposed" in json.dumps(story).lower():
|
|
371
380
|
story["proposed"] = True
|
|
372
|
-
for name in ("when", "narrative", "ended"):
|
|
381
|
+
for name in ("when", "narrative", "ended", "meant"):
|
|
373
382
|
if name in story:
|
|
374
383
|
story[name] = untag(story[name])
|
|
375
384
|
items.append(story)
|
|
@@ -655,6 +664,7 @@ def main():
|
|
|
655
664
|
state["ghostwriter"] = "lawrence"
|
|
656
665
|
version = read_version(book_dir, state, notes)
|
|
657
666
|
news = read_news(state, notes)
|
|
667
|
+
notes.extend(DEPTH_NOTES)
|
|
658
668
|
title = state["title"].replace("&", "&").replace("<", "").replace(">", "")
|
|
659
669
|
|
|
660
670
|
# 1. The pages for the book folder: one small file per page, carrying the book's data with it.
|
|
@@ -682,6 +692,11 @@ def main():
|
|
|
682
692
|
if "pluginLatest" in version:
|
|
683
693
|
print(" a newer plugin is named (%s): the version line says so, and the Overview should carry a plugin note" % version["pluginLatest"])
|
|
684
694
|
print(" what's new notes on the Overview: %d%s" % (len(news), (" (" + ", ".join(n["id"] for n in news) + ")") if news else ""))
|
|
695
|
+
weighed = [c for c in (outline or {}).get("chapters", []) if c.get("depth")]
|
|
696
|
+
if weighed:
|
|
697
|
+
print(" chapters weighed: %d ready, %d thin, %d empty" % tuple(sum(1 for c in weighed if c["depth"] == d) for d in ("ready", "thin", "empty")))
|
|
698
|
+
if stories:
|
|
699
|
+
print(" stories with what they meant to the author: %d of %d" % (sum(1 for s in stories["items"] if s.get("meant")), len(stories["items"])))
|
|
685
700
|
for c in (outline or {}).get("chapters", []):
|
|
686
701
|
ch = manuscript.get(c["key"])
|
|
687
702
|
w = sum(s["words"] for s in ch["sections"]) if ch else 0
|
package/kit.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/* GhostWriter & the Muse: the book's pages. Page kit
|
|
1
|
+
/* GhostWriter & the Muse: the book's pages. Page kit 16.0.0. */
|
|
2
2
|
(function(){
|
|
3
3
|
if (window.GW_KIT) return;
|
|
4
|
-
window.GW_KIT = "
|
|
4
|
+
window.GW_KIT = "16.0.0";
|
|
5
5
|
const CFG = window.GW_PAGE || {};
|
|
6
6
|
if (!document.querySelector('link[href*="fonts.googleapis.com"]')) { const l = document.createElement('link'); l.rel = 'stylesheet'; l.href = "https://fonts.googleapis.com/css2?family=Caveat:wght@600;700&family=Inter:wght@400;500;600&family=Lora:ital,wght@0,400;0,500;0,600;1,400&display=swap"; document.head.appendChild(l); }
|
|
7
|
-
const st = document.createElement('style'); st.textContent = "\n/* Layout: eight separate pages behind one top bar (Overview, Book Setup, Voice, Stories, Notes, Outline, Manuscript, Ghostwriter). Every item can be edited in place. The book's own prose appears as paper on the dark desk, and what the author has shared appears as sticky notes pinned to it. */\n:root{\n color-scheme:dark;\n --bg:hsl(0 0% 2%); --card:hsl(0 0% 4%); --raise:hsl(0 0% 8%); --line:hsl(0 0% 15%);\n --fg:hsl(0 0% 98%); --soft:hsl(0 0% 84%); --muted:hsl(0 0% 64%);\n --green:hsl(152 69% 50%); --green-ink:hsl(0 0% 5%); --green-wash:hsl(152 69% 50% / .10); --green-line:hsl(152 69% 50% / .38);\n --amber:hsl(38 92% 62%); --amber-wash:hsl(38 92% 62% / .10); --amber-line:hsl(38 92% 62% / .40);\n --paper:hsl(40 33% 94%); --paper-ink:hsl(30 10% 12%); --paper-muted:hsl(30 8% 38%); --paper-note:hsl(38 80% 86%); --paper-line:hsl(30 12% 72%);\n --n-story:hsl(50 96% 72%); --n-person:hsl(338 88% 83%); --n-place:hsl(200 86% 79%); --n-idea:hsl(96 60% 74%); --n-fact:hsl(26 95% 75%); --n-line:hsl(268 78% 85%); --n-wish:hsl(40 33% 94%);\n --hand:'Caveat','Segoe Print','Bradley Hand',cursive;\n --serif:'Lora',Georgia,'Times New Roman',serif;\n --sans:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;\n --r:8px;\n}\n*{box-sizing:border-box}\nbody{margin:0;background:var(--bg);color:var(--fg);font-family:var(--sans);font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased}\nbutton{font:inherit;color:inherit;cursor:pointer}\na{color:var(--green)}\n:focus-visible{outline:2px solid var(--green);outline-offset:2px;border-radius:4px}\n.wrap{max-width:1120px;margin-inline:auto;padding-inline:clamp(16px,4vw,32px)}\nh1,h2,h3,h4{font-family:var(--serif);font-weight:600;letter-spacing:-.01em;text-wrap:balance;margin:0}\nh2{font-size:22px} h3{font-size:18px;font-weight:500}\np{margin:0}\n.muted{color:var(--muted)} .fine{font-size:12px;color:var(--muted)} .num{font-variant-numeric:tabular-nums}\n.label{font-size:11px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}\n.label.green{color:var(--green)} .label.amber{color:var(--amber)}\n\n.bar{position:sticky;top:env(safe-area-inset-top,0px);z-index:20;background:var(--bg);border-bottom:1px solid var(--line)}\n.bar .wrap{display:flex;align-items:center;gap:8px 24px;flex-wrap:wrap;padding-block:10px}\n.brand{display:flex;align-items:center;gap:10px;font-family:var(--serif);font-weight:600;font-size:17px;white-space:nowrap;margin-right:auto}\n.bcol{display:grid;justify-items:start;line-height:1.25}\n.verchip{display:inline-flex;align-items:center;gap:6px;font-family:var(--sans);font-size:11px;font-weight:500;line-height:1.3;letter-spacing:.01em;padding:1px 0;border:0;background:transparent;color:var(--muted);white-space:nowrap}\n.verchip:hover{color:var(--fg)}\n.verchip:hover .num{text-decoration:underline;text-underline-offset:2px}\n.verchip i{width:6px;height:6px;border-radius:50%;background:var(--green);flex:none}\n.verchip .vl{color:var(--green)}\n.verchip.due i{background:var(--amber)}\n.verchip.due .vl{color:var(--amber)}\n.label.amber{color:var(--amber)}\na.btn{text-decoration:none}\n.news{display:grid;gap:10px}\n.newsitem{display:grid;gap:8px;border:1px solid var(--green-line);background:var(--green-wash);border-radius:var(--r);padding:14px 16px;min-width:0;max-width:72ch}\n.newsitem.plug{border-color:var(--amber-line);background:var(--amber-wash)}\n.newsitem p{margin:0;font-size:15px;line-height:1.5;color:var(--fg)}\n.newshead{display:flex;gap:10px;align-items:center;flex-wrap:wrap}\n.newshead .ibtn{margin-left:auto}\n.newsitem .ibtn{margin-top:0;text-decoration:none;display:inline-flex;align-items:center}\n.verchip .vl::before{content:\"·\";color:var(--muted);margin-right:6px}\n.verlist{margin:0;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px 18px;border-top:1px solid var(--line);padding-top:14px;font-size:14px}\n.verlist dt{color:var(--muted)}\n.verlist dd{margin:0;text-align:right;font-variant-numeric:tabular-nums}\n.brand svg{width:18px;height:18px;color:var(--green);flex:none}\n.brand .amp{color:var(--green);opacity:.75}\n.tabs{display:flex;gap:2px;overflow-x:auto;max-width:100%;min-width:0}\n.tabs a{color:var(--muted);text-decoration:none;font-size:14px;font-weight:500;padding:7px 11px;border-radius:999px;white-space:nowrap}\n.tabs a:hover{color:var(--fg);background:var(--raise)}\n.tabs a[aria-current=\"page\"]{color:var(--green-ink);background:var(--green);font-weight:600}\n\n.page{padding-block:36px 72px;display:grid;gap:36px}\n.pagehead{display:grid;gap:10px}\n.pagehead h1{font-size:clamp(1.9rem,4.6vw,3rem);line-height:1.08}\n.pagehead .sub{font-family:var(--serif);font-style:italic;color:var(--soft);font-size:clamp(1rem,2vw,1.15rem);max-width:52ch}\n.chips{display:flex;gap:8px;flex-wrap:wrap;align-items:center}\n.chip{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:500;padding:3px 10px;border-radius:999px;border:1px solid var(--line);color:var(--soft);white-space:nowrap}\n.chip.green{border-color:var(--green-line);background:var(--green-wash);color:var(--green)}\n.chip.amber{border-color:var(--amber-line);background:var(--amber-wash);color:var(--amber)}\n.btn{background:var(--green);color:var(--green-ink);border:1px solid var(--green);border-radius:6px;padding:9px 16px;font-weight:600;font-size:14px}\n.btn:hover{filter:brightness(1.08)}\n.btn.ghost{background:transparent;color:var(--soft);border-color:var(--line);font-weight:500}\n.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}\n\n/* Overview */\n.btn{display:inline-flex;align-items:center;gap:8px}\n.btn svg{width:16px;height:16px;flex:none}\n.btn.soft{background:var(--green-wash);color:var(--green);border-color:var(--green-line)}\n.btn.soft:hover{background:var(--green);color:var(--green-ink);filter:none}\n.journey{display:flex;flex-wrap:wrap;gap:18px 28px}\n.jphase{flex:1 1 0;min-width:190px;display:grid;gap:10px;align-content:start}\n.jhead{display:flex;justify-content:space-between;align-items:baseline;gap:10px}\n.jgrid{display:grid;grid-template-columns:repeat(var(--n),minmax(0,1fr));gap:8px 4px;align-items:start}\n.jgrid i{height:6px;border-radius:999px;background:var(--line)}\n.jgrid i.done{background:var(--green);opacity:.55}\n.jgrid i.current{background:var(--green)}\n.jgrid i.waiting{background:var(--amber)}\n.jgrid span{font-size:12px;line-height:1.3;color:var(--muted);text-align:center;padding-inline:3px;min-width:0;overflow-wrap:break-word}\n.jgrid span.done{color:var(--soft)}\n.jgrid span.current{color:var(--green);font-weight:600}\n.jgrid span.waiting{color:var(--amber)}\n.jgrid small{display:block;font-size:11px;opacity:.85}\n.nextcard{display:grid;gap:14px;border:1px solid var(--green-line);background:var(--green-wash);border-radius:12px;padding:clamp(18px,3vw,26px)}\n.nexttext{font-family:var(--serif);font-size:clamp(1.15rem,2.2vw,1.4rem);line-height:1.35;max-width:36em}\n.sayrow{display:flex;gap:12px 20px;align-items:center;justify-content:space-between;flex-wrap:wrap;border-top:1px solid var(--green-line);padding-top:14px}\n.sayrow > div{min-width:0;display:grid;gap:2px}\n.say{font-family:var(--serif);font-size:17px;color:var(--fg)}\n.waithelp{max-width:62ch;font-size:14px}\n.pmsg{border-left:2px solid var(--green-line);padding-left:12px;color:var(--soft);white-space:pre-wrap;overflow-wrap:anywhere;font-size:14px;line-height:1.55}\n.waithelp b{color:var(--soft);font-weight:600}\n.wlist{list-style:none;margin:0;padding:0;display:grid;gap:12px}\n.witem{display:grid;gap:10px;border:1px solid var(--line);background:var(--card);border-radius:var(--r);padding:16px 18px;min-width:0}\n.witem.need{border-color:var(--amber-line)}\n.wmeta{display:flex;gap:6px 10px;align-items:center;flex-wrap:wrap}\n.witem .ask{font-family:var(--serif);font-size:17px;line-height:1.4}\n.sayings{display:flex;flex-wrap:wrap;gap:8px}\n.sayings .chip{white-space:normal;font-size:13px;padding:5px 12px;background:transparent;text-align:left}\n.sayings .chip:hover{border-color:var(--green-line);color:var(--green)}\n.stats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--r);overflow:hidden}\n.stat{background:var(--card);padding:14px;display:grid;gap:6px;align-content:start;min-width:0}\n.stat .v{font-family:var(--serif);font-size:24px;font-weight:600;line-height:1}\n.stat .v small{font-family:var(--sans);font-size:12px;font-weight:400;color:var(--muted);margin-left:6px}\n.meter{height:6px;border-radius:999px;background:var(--line);overflow:hidden}\n.meter i{display:block;height:100%;border-radius:999px;background:var(--green);min-width:2px}\n.cols{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);gap:40px}\n.stack{display:grid;gap:32px;align-content:start;min-width:0}\n.block{display:grid;gap:14px;min-width:0}\n.notyet{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:28px 44px;align-items:start;border-top:1px solid var(--line);padding-top:30px}\n.nytext{display:grid;gap:12px;min-width:0}\n.nywhere{font-family:var(--serif);font-size:19px;line-height:1.45;max-width:40ch}\n.nytext .muted{max-width:54ch}\n.nysteps{display:grid;grid-template-columns:repeat(10,minmax(0,1fr));gap:5px;max-width:400px;margin-top:10px;padding:3px}\n.nysteps i,.nykey i{height:6px;border-radius:999px;background:var(--line)}\n.nysteps i.done{background:var(--green);opacity:.5}\n.nysteps i.now,.nykey i.now{background:var(--green)}\n.nysteps i.here,.nykey i.here{box-shadow:0 0 0 2px var(--bg),0 0 0 3.5px var(--n-place)}\n.nykey{display:flex;gap:8px 22px;flex-wrap:wrap;padding-left:3px}\n.nykey span{display:inline-flex;align-items:center;gap:9px}\n.nykey i{display:inline-block;width:16px;flex:none}\n.head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap}\n.wait{display:grid;gap:0;border-top:1px solid var(--line)}\n.wait > div{padding:12px 0;border-bottom:1px solid var(--line);display:grid;gap:2px}\n.wait .ask{font-family:var(--serif);font-size:16px}\ndetails summary{cursor:pointer;font-size:13px;color:var(--muted);list-style:none;padding:10px 0}\ndetails summary::-webkit-details-marker{display:none}\ndetails summary::before{content:\"+ \";color:var(--green)}\ndetails[open] summary::before{content:\"− \"}\n.inchat{border:1px solid var(--green-line);background:var(--green-wash);border-radius:var(--r);padding:12px 14px;font-size:14px;color:var(--soft)}\n.mini{display:grid;grid-template-columns:84px minmax(0,1fr);gap:14px;align-items:center;border:1px solid var(--line);border-radius:var(--r);background:var(--card);padding:12px}\n.mini img{width:84px;border-radius:6px;display:block}\n.mini .name{font-family:var(--serif);font-size:19px;font-weight:600}\n.chrow{display:grid;gap:6px;padding:12px 0;border-bottom:1px solid var(--line)}\n.chrow:first-child{border-top:1px solid var(--line)}\n.chrow .t{font-family:var(--serif);font-size:16px}\n.chrow .t span{color:var(--green);opacity:.7;margin-right:8px}\n.log{display:grid;grid-template-columns:auto minmax(0,1fr);gap:6px 14px;font-size:13px}\n.log .d{color:var(--muted);white-space:nowrap}\n\n/* Outline */\n.thesis{font-family:var(--serif);font-size:clamp(1.15rem,2.4vw,1.5rem);line-height:1.4;max-width:34em}\n.facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 40px}\n.facts div{display:grid;gap:4px;align-content:start}\n.facts p{color:var(--soft)}\n.och{border-top:1px solid var(--line);padding-top:24px;display:grid;gap:14px}\n.och .top{display:flex;gap:12px;align-items:baseline;justify-content:space-between;flex-wrap:wrap}\n.och h2 span{color:var(--green);opacity:.7;margin-right:10px}\n.och .brief{color:var(--soft);max-width:68ch}\n.osec{display:grid;grid-template-columns:44px minmax(0,1fr);gap:4px 12px;padding:14px 0;border-top:1px solid var(--line)}\n.osec .n{font-family:var(--serif);color:var(--green);opacity:.75}\n.osec .body{display:grid;gap:6px;min-width:0}\n.osec ul{margin:0;padding-left:18px;color:var(--soft);display:grid;gap:4px;font-size:14px}\n.osec details summary{padding:2px 0}\n\n/* Manuscript */\n.ms{display:grid;grid-template-columns:260px minmax(0,1fr);gap:40px;align-items:start}\n.toc{position:sticky;top:calc(env(safe-area-inset-top,0px) + 76px);display:grid;gap:18px}\n.tocch{display:grid;gap:8px}\n.tocch button{background:none;border:0;padding:0;text-align:left;font-family:var(--serif);font-size:16px;color:var(--soft)}\n.tocch button[aria-pressed=\"true\"]{color:var(--fg);font-weight:600}\n.tocch button span{color:var(--green);opacity:.7;margin-right:8px}\n.tocsec{display:grid;grid-template-columns:10px minmax(0,1fr);gap:8px;align-items:baseline;font-size:13px;color:var(--muted);padding-left:2px}\n.dot{width:8px;height:8px;border-radius:50%;border:1.5px solid var(--muted);display:inline-block}\n.dot.written{background:var(--green);border-color:var(--green)}\n.dot.gaps{background:var(--amber);border-color:var(--amber)}\n.legend{display:flex;gap:16px;flex-wrap:wrap;font-size:12px;color:var(--muted)}\n.legend span{display:inline-flex;gap:6px;align-items:center}\n.sheet{background:var(--paper);color:var(--paper-ink);border-radius:3px;max-width:680px;padding:clamp(28px,7vw,64px) clamp(22px,7vw,64px);font-family:var(--serif);font-size:17px;line-height:1.72;box-shadow:0 30px 80px hsl(0 0% 0% / .6)}\n.sheet .ch{font-family:var(--sans);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--paper-muted);text-align:center}\n.sheet h3{font-size:28px;font-weight:600;text-align:center;margin:10px 0 6px;color:var(--paper-ink)}\n.sheet h4{font-size:18px;margin:34px 0 10px}\n.sheet p{text-indent:1.4em}\n.sheet h3 + p,.sheet h4 + p,.sheet .note + p,.sheet .device p{text-indent:0}\n.sheet .note{font-family:var(--sans);font-size:13px;line-height:1.5;background:var(--paper-note);border-radius:4px;padding:10px 12px;margin:14px 0}\n.sheet .note b{display:block;font-size:10px;letter-spacing:.1em;text-transform:uppercase;margin-bottom:2px}\n.sheet .unwritten{font-family:var(--sans);font-size:14px;line-height:1.5;border:1.5px dashed var(--paper-line);border-radius:4px;padding:14px 16px;color:var(--paper-muted)}\n.sheet .unwritten b{display:block;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--paper-ink);margin-bottom:4px}\n.sheet .device{border-top:1px solid var(--paper-line);margin-top:34px;padding-top:6px}\n.sheet .device p{margin-top:8px}\n.sheet blockquote{margin:14px 1.4em;font-style:italic}\n.sheet .li{text-indent:0;padding-left:1.4em}\n.sheet h5{font-family:var(--serif);font-size:17px;font-weight:600;margin:22px 0 6px}\n.sheet h5 + p,.sheet blockquote + p{text-indent:0}\n\n/* Notes */\n.kinds{display:flex;gap:8px;flex-wrap:wrap}\n.kind{display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:500;padding:6px 12px;border-radius:999px;border:1px solid var(--line);background:transparent;color:var(--soft)}\n.kind i{width:11px;height:11px;border-radius:2px;background:var(--k);display:block;flex:none}\n.kind:hover{border-color:var(--muted)}\n.kind[aria-pressed=\"true\"]{border-color:var(--fg);color:var(--fg);background:var(--raise)}\n.kind .num{color:var(--muted)}\n.tools{display:flex;gap:10px 16px;flex-wrap:wrap;align-items:center}\n.tools label{display:inline-flex;gap:8px;align-items:center;font-size:13px;color:var(--muted);min-width:0}\n.tools select,.tools input{font:inherit;font-size:14px;color:var(--fg);background:var(--card);border:1px solid var(--line);border-radius:6px;padding:7px 10px;min-width:0;max-width:100%}\n.tools input{width:min(240px,100%)}\n.tools input::placeholder{color:var(--muted)}\n.group{display:grid;gap:16px}\n.group + .group{margin-top:20px}\n.board{display:grid;grid-template-columns:repeat(auto-fill,minmax(204px,1fr));gap:24px 20px;align-items:start}\n.sticky{--k:var(--n-story);--tilt:0deg;background:var(--k) linear-gradient(hsl(0 0% 0% / .07),hsl(0 0% 0% / 0) 22px);color:var(--paper-ink);padding:16px 16px 12px;min-height:196px;display:grid;grid-template-rows:auto auto 1fr auto;gap:7px;border-radius:2px;box-shadow:0 1px 0 hsl(0 0% 100% / .25) inset,0 16px 22px -10px hsl(0 0% 0% / .8);transform:rotate(var(--tilt));transition:transform .18s ease;min-width:0}\n.sticky:hover{transform:rotate(0deg) translateY(-3px)}\n.sticky .k{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;opacity:.62}\n.sticky .t{font-family:var(--hand);font-size:25px;font-weight:700;line-height:1.02;text-wrap:balance;overflow-wrap:anywhere}\n.sticky .x{font-size:13.5px;line-height:1.45;overflow-wrap:anywhere}\n.sticky .f{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap;font-size:11px;padding-top:6px;opacity:.78}\n.sticky .loose{border:1px dashed currentColor;border-radius:999px;padding:1px 8px}\n@keyframes land{from{opacity:0;transform:translateY(-18px) rotate(var(--tilt)) scale(1.05)}to{opacity:1;transform:rotate(var(--tilt))}}\n.sticky.fresh{animation:land .5s ease-out}\n.sticky .ed{font-size:11px;font-weight:600;font-style:italic;line-height:1.35}\n.sticky .acts{display:flex;gap:5px;flex-wrap:wrap;padding-top:8px;border-top:1px solid hsl(0 0% 0% / .14)}\n.nact{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:600;line-height:1.2;white-space:nowrap;color:var(--paper-ink);background:hsl(0 0% 100% / .38);border:1px solid hsl(0 0% 0% / .2);border-radius:999px;padding:5px 10px;flex:1 1 auto;justify-content:center}\n.nact:hover{background:hsl(0 0% 100% / .78)}\n.nact:focus-visible{outline-color:var(--paper-ink);border-radius:999px}\n@media (prefers-reduced-motion:reduce){.sticky{transition:none}.sticky.fresh{animation:none}}\n.pins{display:grid;gap:8px}\n.pin{display:grid;grid-template-columns:11px minmax(0,1fr);gap:10px;align-items:baseline;font-family:var(--serif);font-size:15px;color:var(--soft)}\n.pin i{width:11px;height:11px;border-radius:2px;background:var(--k);display:block}\n\n/* Notes: ways to look */\n.views{display:inline-flex;gap:2px;padding:3px;border:1px solid var(--line);border-radius:999px;background:var(--card);justify-self:start;max-width:100%}\n.view{border:0;background:transparent;color:var(--muted);font-size:14px;font-weight:500;padding:7px 16px;border-radius:999px;white-space:nowrap}\n.view:hover{color:var(--fg)}\n.view[aria-pressed=\"true\"]{background:var(--fg);color:var(--bg);font-weight:600}\n.gwrap{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:24px;align-items:start}\n.graph{position:relative;border:1px solid var(--line);border-radius:var(--r);background:radial-gradient(120% 90% at 50% 40%,var(--raise),var(--card) 70%);overflow:hidden;min-width:0}\n.graph canvas{display:block;width:100%;height:min(68vh,600px);min-height:380px;touch-action:pan-y;cursor:grab}\n.graph canvas:active{cursor:grabbing}\n.ghint{position:absolute;left:14px;right:14px;bottom:10px;pointer-events:none}\n.gside{display:grid;gap:14px;align-content:start;min-width:0}\n.gside .sticky{min-height:0}\n.glist{display:grid;gap:6px}\n.glink{display:grid;grid-template-columns:11px minmax(0,1fr);gap:10px;align-items:baseline;text-align:left;background:transparent;border:1px solid var(--line);border-radius:6px;padding:8px 10px;font-size:14px;color:var(--soft)}\n.glink:hover{border-color:var(--muted);color:var(--fg)}\n.glink i{width:11px;height:11px;border-radius:2px;background:var(--k);display:block}\n.tl{border-left:2px solid var(--line);margin-left:6px;padding-left:26px;display:grid;gap:30px}\n.tly{display:grid;gap:16px;position:relative}\n.tly::before{content:\"\";position:absolute;left:-34px;top:9px;width:14px;height:14px;border-radius:50%;background:var(--green);box-shadow:0 0 0 4px var(--bg)}\n.tlyear{font-size:28px;line-height:1}\n.tli{display:grid;gap:8px;align-content:start;min-width:0}\n.tlwhen{font-size:12px;color:var(--muted);min-height:18px}\n.tlwrap{display:grid;gap:28px}\n.tlwrap .group + .group,.tlwrap .group{margin-top:0}\n.tlgap{font-size:12px;color:var(--muted);font-style:italic}\n\n/* Ghostwriter */\n.spot{display:grid;grid-template-columns:220px minmax(0,1fr);gap:28px;align-items:center;border:1px solid var(--green-line);background:var(--green-wash);border-radius:var(--r);padding:22px}\n.spot img{width:100%;border-radius:6px;display:block}\n.spot .info{display:grid;gap:10px;min-width:0}\n.spot .name{font-family:var(--serif);font-size:30px;font-weight:600;line-height:1.1}\n.quote{font-family:var(--serif);font-style:italic;color:var(--soft);font-size:17px}\n.grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px}\n.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:0;text-align:left;overflow:hidden;display:grid;align-content:start}\n.card:hover{border-color:var(--green-line)}\n.card[aria-pressed=\"true\"]{border-color:var(--green)}\n.card img{width:100%;aspect-ratio:4/5;object-fit:cover;display:block}\n.card span{display:block;padding:10px 12px 0;font-family:var(--serif);font-weight:600;font-size:15px}\n.card small{display:block;padding:2px 12px 12px;color:var(--muted);font-size:12px;line-height:1.4}\n@keyframes drift{0%{transform:perspective(1200px) translate3d(0,0,0) rotate(0)}18%{transform:perspective(1200px) translate3d(-4px,-5px,3px) rotate(.6deg)}35%{transform:perspective(1200px) translate3d(3px,-8px,-4px) rotate(-.4deg)}52%{transform:perspective(1200px) translate3d(-6px,-3px,5px) rotate(.8deg)}68%{transform:perspective(1200px) translate3d(5px,-6px,-3px) rotate(-.7deg)}84%{transform:perspective(1200px) translate3d(-3px,-4px,4px) rotate(.3deg)}100%{transform:perspective(1200px) translate3d(0,0,0) rotate(0)}}\n.drift{animation:drift 14s ease-in-out infinite;will-change:transform}\n@media (prefers-reduced-motion:reduce){.drift{animation:none}}\n\n.modal{position:fixed;inset:0;z-index:40;background:hsl(0 0% 0% / .68);display:grid;place-items:center;padding:16px}\n.modal[hidden]{display:none}\n.popup{width:100%;max-width:560px;max-height:100%;overflow:auto;background:var(--raise);border:1px solid var(--green-line);border-radius:12px;padding:clamp(18px,4vw,26px);display:grid;gap:12px;box-shadow:0 30px 80px hsl(0 0% 0% / .7)}\n.popup h2{font-size:21px;line-height:1.25}\n.popup.wide{max-width:820px}\n.modal:not(.manual) #copytext,.modal:not(.manual) #copybtn{display:none}\n.popup pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-family:var(--sans);font-size:14px;line-height:1.5;background:var(--bg);border:1px solid var(--line);border-radius:6px;padding:12px 14px;max-height:40vh;overflow:auto}\n.modal:not(.manual) #copystate::before{content:\"\";display:inline-block;width:10px;height:6px;border-left:2px solid var(--green);border-bottom:2px solid var(--green);transform:rotate(-45deg) translateY(-3px);margin-right:8px}\n.modal.manual #copystate{color:var(--amber)}\n.fld{display:grid;gap:6px;font-size:12px;font-weight:600;letter-spacing:.04em;color:var(--muted)}\n.fld input,.fld textarea{font:inherit;font-size:15px;font-weight:400;letter-spacing:0;line-height:1.5;color:var(--fg);background:var(--bg);border:1px solid var(--line);border-radius:6px;padding:10px 12px;width:100%;resize:vertical}\n#noteerr{color:var(--amber)}\n\n/* Items: anything on a page the author can edit */\n.item{display:grid;gap:8px;min-width:0;align-content:start}\n.item .v{color:var(--soft);white-space:pre-wrap;overflow-wrap:anywhere}\n.item .v.big{font-family:var(--serif);font-size:clamp(1.1rem,2.2vw,1.4rem);line-height:1.45;color:var(--fg);max-width:36em}\n.item ul{margin:0;padding-left:18px;color:var(--soft);display:grid;gap:4px}\n.item blockquote{margin:0;padding-left:14px;border-left:2px solid var(--green-line);font-family:var(--serif);font-style:italic;color:var(--soft)}\n.acts2{display:flex;gap:6px;flex-wrap:wrap;align-items:center}\n.ibtn{font-size:12px;font-weight:600;line-height:1.2;white-space:nowrap;color:var(--soft);background:transparent;border:1px solid var(--line);border-radius:999px;padding:6px 12px}\n.ibtn:hover{border-color:var(--green-line);color:var(--green)}\n.ibtn.go{border-color:var(--green-line);color:var(--green);background:var(--green-wash)}\n.ibtn svg{width:13px;height:13px;vertical-align:-2px;margin-right:6px}\n.story .end .ibtn{margin-top:8px}\n.edtag{font-size:11px;font-weight:600;color:var(--green);white-space:nowrap}\n.edtag.local{color:var(--amber)}\n.hero2{display:grid;gap:22px;border:1px solid var(--line);background:var(--card);border-radius:12px;padding:clamp(18px,3vw,28px)}\n.hero2 .ttl{font-family:var(--serif);font-weight:600;font-size:clamp(1.7rem,4vw,2.6rem);line-height:1.1;overflow-wrap:anywhere}\n.hero2 .sub2{font-family:var(--serif);font-style:italic;color:var(--soft);font-size:clamp(1.05rem,2vw,1.25rem)}\n.hero2 .by{font-size:16px;color:var(--soft)}\n.facts2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:30px 40px}\n.sugs{display:grid;gap:8px;border:1px dashed var(--green-line);border-radius:var(--r);padding:12px 14px}\n.sug{display:flex;gap:10px;align-items:baseline;justify-content:space-between;flex-wrap:wrap}\n.sug span{font-family:var(--serif);font-size:16px;min-width:0;overflow-wrap:anywhere}\n.storygrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}\n.story{display:grid;gap:10px;align-content:start;border:1px solid var(--line);border-top:3px solid var(--n-story);background:var(--card);border-radius:12px;padding:18px 20px;min-width:0}\n.story h3{font-size:20px;font-weight:600}\n.story .nar{color:var(--soft);white-space:pre-wrap;overflow-wrap:anywhere}\n.story .end{border-left:2px solid var(--green-line);padding-left:12px;color:var(--soft);display:grid;gap:2px}\n.story .end.need{border-left-color:var(--amber-line)}\n.story details p{font-size:13px;color:var(--soft);margin-bottom:8px}\n.witem.first{border-color:var(--green-line);background:var(--green-wash)}\n.witem .ans{border-left:2px solid var(--green-line);padding-left:12px;color:var(--soft);white-space:pre-wrap;overflow-wrap:anywhere;font-size:14px}\n.tip{display:none;font-size:13px;color:var(--fg);background:hsl(200 86% 79% / .10);border:1px solid hsl(200 86% 79% / .45);border-radius:var(--r);padding:9px 12px;max-width:64ch}\n.tip b{color:var(--n-place);font-weight:600}\nbody.helpon .tip{display:block}\n.helpbtn{flex:none;width:34px;height:34px;border-radius:50%;border:1px solid var(--line);background:transparent;color:var(--soft);font-weight:600;font-size:15px;display:inline-grid;place-items:center}\n.helpbtn:hover{border-color:var(--green-line);color:var(--green)}\n.helpbtn[aria-pressed=\"true\"]{background:var(--n-place);border-color:var(--n-place);color:var(--green-ink)}\n.toast{position:fixed;left:50%;bottom:calc(env(safe-area-inset-bottom,0px) + 20px);transform:translateX(-50%);z-index:50;background:var(--green);color:var(--green-ink);font-weight:600;font-size:14px;border-radius:999px;padding:9px 18px;box-shadow:0 10px 30px hsl(0 0% 0% / .6);max-width:calc(100% - 32px)}\n.talk{display:grid;gap:8px;max-height:36vh;overflow:auto}\n.talk:empty{display:none}\n.talk div{border-radius:10px;padding:9px 12px;max-width:90%;overflow-wrap:anywhere;white-space:pre-wrap;font-size:14px}\n.talk .me{justify-self:end;background:var(--bg);border:1px solid var(--line)}\n.talk .gw{justify-self:start;background:var(--green-wash);border:1px solid var(--green-line)}\n.talk .gw b{display:block;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--green);margin-bottom:3px}\n.about{border-left:3px solid var(--green);background:var(--bg);border-radius:0 6px 6px 0;padding:8px 12px;font-size:14px;color:var(--soft);max-height:20vh;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere}\n#editfields{display:grid;gap:12px}\n#editerr,#talkstate.warn{color:var(--amber)}\n.och .acts2,.osec .acts2{margin-top:2px}\n.sheet .secdisc{margin:2px 0 14px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}\n.sheet .secdisc .edtag{color:var(--paper-ink);border-color:var(--paper-line)}\n.sheet h4 .snum{font-family:var(--sans);font-size:12px;font-weight:600;color:var(--paper-muted);margin-right:10px;letter-spacing:.04em}\n.sheet .secdisc .ibtn{color:var(--paper-muted);border-color:var(--paper-line)}\n.sheet .secdisc .ibtn:hover{color:var(--paper-ink);border-color:var(--paper-ink)}\n.sheet .note .ibtn,.sheet .unwritten .ibtn{color:var(--paper-ink);border-color:var(--paper-line);background:transparent;margin-top:10px;font-family:var(--sans)}\n.sheet .note .ibtn:hover,.sheet .unwritten .ibtn:hover{border-color:var(--paper-ink)}\n.doclink{display:flex;gap:12px 18px;align-items:center;justify-content:space-between;flex-wrap:wrap;border:1px solid var(--green-line);background:var(--green-wash);border-radius:var(--r);padding:14px 16px}\n\n@media (max-width:860px){\n .facts2,.storygrid{grid-template-columns:minmax(0,1fr)}\n .gwrap{grid-template-columns:minmax(0,1fr)}\n .graph canvas{height:420px}\n .cols,.ms{grid-template-columns:minmax(0,1fr)}\n .jphase{min-width:100%}\n .facts{grid-template-columns:minmax(0,1fr)}\n .toc{position:static}\n .spot{grid-template-columns:minmax(0,1fr)}\n .spot img{max-width:180px}\n .grid{grid-template-columns:repeat(2,minmax(0,1fr))}\n .tabs a{padding:7px 10px;font-size:13px}\n .helpbtn{order:2}\n .tabs{order:3;flex:1 1 100%}\n .notyet{grid-template-columns:minmax(0,1fr)}\n}\n@media (max-width:520px){\n .jgrid span{font-size:11px;padding-inline:1px}\n .sayrow .btn,.witem .btn{width:100%;justify-content:center}\n .board{grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 12px}\n .sticky{min-height:156px;padding:12px 12px 10px}\n .nact{padding:8px 10px}\n .sticky .t{font-size:22px}\n .sticky .x{font-size:13px}\n .tools label{flex:1 1 100%}\n .tools select,.tools input{flex:1;width:auto}\n .view{padding:7px 12px}\n .tl{padding-left:20px}\n .tly::before{left:-28px}\n}\n/* ---- The cover ---- */\n.cv{position:relative;aspect-ratio:2/3;width:100%;container-type:inline-size;overflow:hidden;border-radius:3px;background:var(--paper,#F3EBDD);color:var(--ink,#1F3B2D);text-align:left;line-height:1.2;box-shadow:0 30px 70px hsl(0 0% 0% / .75),inset 0 0 0 1px hsl(0 0% 100% / .04)}\n.cv::after{content:\"\";position:absolute;inset:0 auto 0 0;width:2.2cqw;background:linear-gradient(90deg,hsl(0 0% 0% / .22),transparent);pointer-events:none}\n.cv .cvl{display:block;width:max-content;white-space:nowrap}\n.cvtitle{font-family:var(--tf);font-weight:var(--tw,600);line-height:var(--tlh,1);letter-spacing:var(--tls,0);font-size:12cqw}\n.cv.caps .cvtitle{text-transform:uppercase}\n.cvsub{text-wrap:balance;overflow-wrap:anywhere}\n.cvauthor{font-size:3.5cqw;white-space:nowrap}\n.cvmotif svg{display:block;width:100%;height:100%;overflow:visible}\n.cv-paper .cvtop{position:absolute;left:9cqw;right:9cqw;top:10cqw}\n.cv-paper .cvsub{font-family:var(--xf);font-weight:500;line-height:1.3;margin-top:5cqw;max-width:78cqw;color:color-mix(in srgb,var(--ink) 80%,var(--paper))}\n.cv-paper .cvmotif{position:absolute;left:9cqw;width:82cqw;bottom:24cqw;height:24cqw}\n.cv-paper .cvauthor{position:absolute;left:9cqw;right:9cqw;bottom:9cqw;font-family:var(--xf);font-weight:600;letter-spacing:.22em;text-transform:uppercase}\n.cv-bold .cvmotif{position:absolute;left:0;top:0;width:100cqw;height:66cqw}\n.cv-bold .cvbase{position:absolute;left:8cqw;right:8cqw;bottom:8cqw;display:flex;flex-direction:column}\n.cv-bold .cvrule{width:18cqw;height:1cqw;background:var(--accent);margin:5cqw 0 6cqw;flex:none}\n.cv-bold .cvsub{font-family:var(--xf);font-weight:500;line-height:1.32;max-width:78cqw}\n.cv-bold .cvauthor{margin-top:7cqw;font-family:var(--xf);font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:var(--accent)}\n.cv-quiet{text-align:center;background:radial-gradient(120% 80% at 60% 62%,color-mix(in srgb,var(--paper) 90%,var(--ink)) 0,var(--paper) 70%)}\n.cv-quiet .cvl,.cv-over .cvl{margin-inline:auto}\n.cv-quiet .cvtop{position:absolute;left:7cqw;right:7cqw;top:11cqw}\n.cv-quiet .cvsub{font-family:var(--xf);font-weight:500;letter-spacing:.2em;text-transform:uppercase;line-height:1.8;margin-top:4cqw;color:color-mix(in srgb,var(--ink) 72%,var(--paper))}\n.cv-quiet .cvmotif{position:absolute;left:0;top:50cqw;width:100cqw;height:86cqw}\n.cv-quiet .cvauthor{position:absolute;left:7cqw;right:7cqw;bottom:8cqw;font-family:var(--tf);font-weight:600;letter-spacing:.14em;text-transform:uppercase;font-size:5cqw}\n.cv-own{aspect-ratio:auto;background:hsl(0 0% 7%)}\n.cv-own img{display:block;width:100%;height:auto}\n.cv-over{aspect-ratio:2/3;text-align:center}\n.cv-over img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}\n.cv-over .cvscrim{position:absolute;inset:0;background:linear-gradient(180deg,var(--shade) 0,transparent 46%,transparent 74%,var(--shade) 100%)}\n.cv-over .cvtop{position:absolute;left:8cqw;right:8cqw;top:10cqw}\n.cv-over .cvsub{font-family:var(--xf);font-weight:500;line-height:1.4;margin-top:4cqw}\n.cv-over .cvauthor{position:absolute;left:8cqw;right:8cqw;bottom:8cqw;font-family:var(--xf);font-weight:600;letter-spacing:.2em;text-transform:uppercase}\n.cv-wait{display:grid;place-items:center;background:var(--card);color:var(--muted);border:1px dashed var(--line);box-shadow:none;text-align:center;font-size:13px;padding:12px}\n.cv-wait::after{display:none}\n.concepts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(20px,3vw,36px);align-items:start}\n.cc{display:grid;gap:18px;min-width:0}\n.cwrap{padding:26px 30px;border:1px solid var(--line);border-radius:var(--r);background:radial-gradient(90% 70% at 50% 40%,hsl(0 0% 9%),var(--card))}\n.cc.picked .cwrap,.cwrap.picked{border-color:var(--green);box-shadow:0 0 0 1px var(--green)}\n.cwrap.own{max-width:300px}\n.cmeta{display:grid;gap:10px}\n.cmeta h3,.cown h3{font-size:21px;font-weight:600}\n.clook{display:flex;gap:12px;align-items:center;flex-wrap:wrap}\n.csws{display:inline-flex;gap:5px}\n.csws i{width:18px;height:18px;border-radius:50%;box-shadow:inset 0 0 0 1px hsl(0 0% 100% / .14)}\n.csect{display:grid;gap:22px;border-top:1px solid var(--line);padding-top:32px}\n.cintro{display:grid;gap:8px;max-width:68ch}\n.cintro p{color:var(--soft)}\n.cother{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);gap:clamp(24px,4vw,48px);align-items:start}\n.cown{display:grid;gap:16px;align-content:start;min-width:0}\n.cslot{aspect-ratio:2/3;width:min(100%,250px);border:1.5px dashed var(--green-line);border-radius:6px;background:var(--green-wash);display:grid;place-content:center;justify-items:center;gap:10px;text-align:center;padding:18px;color:var(--soft)}\n.cslot svg{width:30px;height:30px;color:var(--green)}\n.cslot b{font-family:var(--serif);font-size:17px;font-weight:600;color:var(--fg)}\n.csteps{list-style:none;margin:0;padding:0;display:grid;gap:10px;counter-reset:cs}\n.csteps li{counter-increment:cs;display:grid;grid-template-columns:26px minmax(0,1fr);gap:10px;color:var(--soft)}\n.csteps li::before{content:counter(cs);width:22px;height:22px;border-radius:50%;border:1px solid var(--green-line);color:var(--green);font-size:12px;font-weight:600;display:grid;place-items:center;margin-top:1px}\n.cback{gap:14px}\n.cback .chl{font-family:var(--serif);font-size:26px;line-height:1.25;font-weight:600;color:var(--fg);max-width:30ch}\n.cback p{color:var(--soft);max-width:62ch}\n.cback .cbio{border-left:2px solid var(--green-line);padding-left:14px;color:var(--muted);font-size:14px}\n.ovhero{display:grid;grid-template-columns:auto minmax(0,1fr);gap:clamp(22px,4vw,44px);align-items:center}\n.ovcover{display:grid;gap:10px;justify-items:center;width:clamp(150px,17vw,208px);text-decoration:none;color:inherit}\n.ovcover .cv{box-shadow:0 22px 50px hsl(0 0% 0% / .7),0 0 0 1px hsl(0 0% 100% / .06);transform:rotate(-1.2deg)}\n.ovcover u{color:var(--green);text-underline-offset:3px}\n.notyet>.cown{border-left:1px solid var(--line);padding-left:clamp(20px,3vw,44px)}\n@media (max-width:900px){.concepts,.cother{grid-template-columns:minmax(0,1fr)}.cwrap{padding:22px clamp(30px,14vw,90px)}.cwrap.own{padding:22px 30px}.notyet>.cown{border-left:0;padding-left:0}}\n@media (max-width:640px){.ovhero{grid-template-columns:minmax(0,1fr);justify-items:start}.ovcover{width:150px}}\n"; document.head.appendChild(st);
|
|
7
|
+
const st = document.createElement('style'); st.textContent = "\n/* Layout: eight separate pages behind one top bar (Overview, Book Setup, Voice, Stories, Notes, Outline, Manuscript, Ghostwriter). Every item can be edited in place. The book's own prose appears as paper on the dark desk, and what the author has shared appears as sticky notes pinned to it. */\n:root{\n color-scheme:dark;\n --bg:hsl(0 0% 2%); --card:hsl(0 0% 4%); --raise:hsl(0 0% 8%); --line:hsl(0 0% 15%);\n --fg:hsl(0 0% 98%); --soft:hsl(0 0% 84%); --muted:hsl(0 0% 64%);\n --green:hsl(152 69% 50%); --green-ink:hsl(0 0% 5%); --green-wash:hsl(152 69% 50% / .10); --green-line:hsl(152 69% 50% / .38);\n --amber:hsl(38 92% 62%); --amber-wash:hsl(38 92% 62% / .10); --amber-line:hsl(38 92% 62% / .40);\n --paper:hsl(40 33% 94%); --paper-ink:hsl(30 10% 12%); --paper-muted:hsl(30 8% 38%); --paper-note:hsl(38 80% 86%); --paper-line:hsl(30 12% 72%);\n --n-story:hsl(50 96% 72%); --n-person:hsl(338 88% 83%); --n-place:hsl(200 86% 79%); --n-idea:hsl(96 60% 74%); --n-fact:hsl(26 95% 75%); --n-line:hsl(268 78% 85%); --n-wish:hsl(40 33% 94%);\n --hand:'Caveat','Segoe Print','Bradley Hand',cursive;\n --serif:'Lora',Georgia,'Times New Roman',serif;\n --sans:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;\n --r:8px;\n}\n*{box-sizing:border-box}\nbody{margin:0;background:var(--bg);color:var(--fg);font-family:var(--sans);font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased}\nbutton{font:inherit;color:inherit;cursor:pointer}\na{color:var(--green)}\n:focus-visible{outline:2px solid var(--green);outline-offset:2px;border-radius:4px}\n.wrap{max-width:1120px;margin-inline:auto;padding-inline:clamp(16px,4vw,32px)}\nh1,h2,h3,h4{font-family:var(--serif);font-weight:600;letter-spacing:-.01em;text-wrap:balance;margin:0}\nh2{font-size:22px} h3{font-size:18px;font-weight:500}\np{margin:0}\n.muted{color:var(--muted)} .fine{font-size:12px;color:var(--muted)} .num{font-variant-numeric:tabular-nums}\n.label{font-size:11px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}\n.label.green{color:var(--green)} .label.amber{color:var(--amber)}\n\n.bar{position:sticky;top:env(safe-area-inset-top,0px);z-index:20;background:var(--bg);border-bottom:1px solid var(--line)}\n.bar .wrap{display:flex;align-items:center;gap:8px 24px;flex-wrap:wrap;padding-block:10px}\n.brand{display:flex;align-items:center;gap:10px;font-family:var(--serif);font-weight:600;font-size:17px;white-space:nowrap;margin-right:auto}\n.bcol{display:grid;justify-items:start;line-height:1.25}\n.verchip{display:inline-flex;align-items:center;gap:6px;font-family:var(--sans);font-size:11px;font-weight:500;line-height:1.3;letter-spacing:.01em;padding:1px 0;border:0;background:transparent;color:var(--muted);white-space:nowrap}\n.verchip:hover{color:var(--fg)}\n.verchip:hover .num{text-decoration:underline;text-underline-offset:2px}\n.verchip i{width:6px;height:6px;border-radius:50%;background:var(--green);flex:none}\n.verchip .vl{color:var(--green)}\n.verchip.due i{background:var(--amber)}\n.verchip.due .vl{color:var(--amber)}\n.label.amber{color:var(--amber)}\na.btn{text-decoration:none}\n.news{display:grid;gap:10px}\n.newsitem{display:grid;gap:8px;border:1px solid var(--green-line);background:var(--green-wash);border-radius:var(--r);padding:14px 16px;min-width:0;max-width:72ch}\n.newsitem.plug{border-color:var(--amber-line);background:var(--amber-wash)}\n.newsitem p{margin:0;font-size:15px;line-height:1.5;color:var(--fg)}\n.newshead{display:flex;gap:10px;align-items:center;flex-wrap:wrap}\n.newshead .ibtn{margin-left:auto}\n.newsitem .ibtn{margin-top:0;text-decoration:none;display:inline-flex;align-items:center}\n.verchip .vl::before{content:\"·\";color:var(--muted);margin-right:6px}\n.verlist{margin:0;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px 18px;border-top:1px solid var(--line);padding-top:14px;font-size:14px}\n.verlist dt{color:var(--muted)}\n.verlist dd{margin:0;text-align:right;font-variant-numeric:tabular-nums}\n.brand svg{width:18px;height:18px;color:var(--green);flex:none}\n.brand .amp{color:var(--green);opacity:.75}\n.tabs{display:flex;gap:2px;overflow-x:auto;max-width:100%;min-width:0}\n.tabs a{color:var(--muted);text-decoration:none;font-size:14px;font-weight:500;padding:7px 11px;border-radius:999px;white-space:nowrap}\n.tabs a:hover{color:var(--fg);background:var(--raise)}\n.tabs a[aria-current=\"page\"]{color:var(--green-ink);background:var(--green);font-weight:600}\n\n.page{padding-block:36px 72px;display:grid;gap:36px}\n.pagehead{display:grid;gap:10px}\n.pagehead h1{font-size:clamp(1.9rem,4.6vw,3rem);line-height:1.08}\n.pagehead .sub{font-family:var(--serif);font-style:italic;color:var(--soft);font-size:clamp(1rem,2vw,1.15rem);max-width:52ch}\n.chips{display:flex;gap:8px;flex-wrap:wrap;align-items:center}\n.chip{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:500;padding:3px 10px;border-radius:999px;border:1px solid var(--line);color:var(--soft);white-space:nowrap}\n.chip.green{border-color:var(--green-line);background:var(--green-wash);color:var(--green)}\n.chip.amber{border-color:var(--amber-line);background:var(--amber-wash);color:var(--amber)}\n.btn{background:var(--green);color:var(--green-ink);border:1px solid var(--green);border-radius:6px;padding:9px 16px;font-weight:600;font-size:14px}\n.btn:hover{filter:brightness(1.08)}\n.btn.ghost{background:transparent;color:var(--soft);border-color:var(--line);font-weight:500}\n.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}\n\n/* Overview */\n.btn{display:inline-flex;align-items:center;gap:8px}\n.btn svg{width:16px;height:16px;flex:none}\n.btn.soft{background:var(--green-wash);color:var(--green);border-color:var(--green-line)}\n.btn.soft:hover{background:var(--green);color:var(--green-ink);filter:none}\n.journey{display:flex;flex-wrap:wrap;gap:18px 28px}\n.jphase{flex:1 1 0;min-width:190px;display:grid;gap:10px;align-content:start}\n.jhead{display:flex;justify-content:space-between;align-items:baseline;gap:10px}\n.jgrid{display:grid;grid-template-columns:repeat(var(--n),minmax(0,1fr));gap:8px 4px;align-items:start}\n.jgrid i{height:6px;border-radius:999px;background:var(--line)}\n.jgrid i.done{background:var(--green);opacity:.55}\n.jgrid i.current{background:var(--green)}\n.jgrid i.waiting{background:var(--amber)}\n.jgrid span{font-size:12px;line-height:1.3;color:var(--muted);text-align:center;padding-inline:3px;min-width:0;overflow-wrap:break-word}\n.jgrid span.done{color:var(--soft)}\n.jgrid span.current{color:var(--green);font-weight:600}\n.jgrid span.waiting{color:var(--amber)}\n.jgrid small{display:block;font-size:11px;opacity:.85}\n.nextcard{display:grid;gap:14px;border:1px solid var(--green-line);background:var(--green-wash);border-radius:12px;padding:clamp(18px,3vw,26px)}\n.nexttext{font-family:var(--serif);font-size:clamp(1.15rem,2.2vw,1.4rem);line-height:1.35;max-width:36em}\n.sayrow{display:flex;gap:12px 20px;align-items:center;justify-content:space-between;flex-wrap:wrap;border-top:1px solid var(--green-line);padding-top:14px}\n.sayrow > div{min-width:0;display:grid;gap:2px}\n.say{font-family:var(--serif);font-size:17px;color:var(--fg)}\n.waithelp{max-width:62ch;font-size:14px}\n.pmsg{border-left:2px solid var(--green-line);padding-left:12px;color:var(--soft);white-space:pre-wrap;overflow-wrap:anywhere;font-size:14px;line-height:1.55}\n.waithelp b{color:var(--soft);font-weight:600}\n.wlist{list-style:none;margin:0;padding:0;display:grid;gap:12px}\n.witem{display:grid;gap:10px;border:1px solid var(--line);background:var(--card);border-radius:var(--r);padding:16px 18px;min-width:0}\n.witem.need{border-color:var(--amber-line)}\n.wmeta{display:flex;gap:6px 10px;align-items:center;flex-wrap:wrap}\n.witem .ask{font-family:var(--serif);font-size:17px;line-height:1.4}\n.sayings{display:flex;flex-wrap:wrap;gap:8px}\n.sayings .chip{white-space:normal;font-size:13px;padding:5px 12px;background:transparent;text-align:left}\n.sayings .chip:hover{border-color:var(--green-line);color:var(--green)}\n.stats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--r);overflow:hidden}\n.stat{background:var(--card);padding:14px;display:grid;gap:6px;align-content:start;min-width:0}\n.stat .v{font-family:var(--serif);font-size:24px;font-weight:600;line-height:1}\n.stat .v small{font-family:var(--sans);font-size:12px;font-weight:400;color:var(--muted);margin-left:6px}\n.meter{height:6px;border-radius:999px;background:var(--line);overflow:hidden}\n.meter i{display:block;height:100%;border-radius:999px;background:var(--green);min-width:2px}\n.cols{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);gap:40px}\n.stack{display:grid;gap:32px;align-content:start;min-width:0}\n.block{display:grid;gap:14px;min-width:0}\n.notyet{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:28px 44px;align-items:start;border-top:1px solid var(--line);padding-top:30px}\n.nytext{display:grid;gap:12px;min-width:0}\n.nywhere{font-family:var(--serif);font-size:19px;line-height:1.45;max-width:40ch}\n.nytext .muted{max-width:54ch}\n.nysteps{display:grid;grid-template-columns:repeat(10,minmax(0,1fr));gap:5px;max-width:400px;margin-top:10px;padding:3px}\n.nysteps i,.nykey i{height:6px;border-radius:999px;background:var(--line)}\n.nysteps i.done{background:var(--green);opacity:.5}\n.nysteps i.now,.nykey i.now{background:var(--green)}\n.nysteps i.here,.nykey i.here{box-shadow:0 0 0 2px var(--bg),0 0 0 3.5px var(--n-place)}\n.nykey{display:flex;gap:8px 22px;flex-wrap:wrap;padding-left:3px}\n.nykey span{display:inline-flex;align-items:center;gap:9px}\n.nykey i{display:inline-block;width:16px;flex:none}\n.head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap}\n.wait{display:grid;gap:0;border-top:1px solid var(--line)}\n.wait > div{padding:12px 0;border-bottom:1px solid var(--line);display:grid;gap:2px}\n.wait .ask{font-family:var(--serif);font-size:16px}\ndetails summary{cursor:pointer;font-size:13px;color:var(--muted);list-style:none;padding:10px 0}\ndetails summary::-webkit-details-marker{display:none}\ndetails summary::before{content:\"+ \";color:var(--green)}\ndetails[open] summary::before{content:\"− \"}\n.inchat{border:1px solid var(--green-line);background:var(--green-wash);border-radius:var(--r);padding:12px 14px;font-size:14px;color:var(--soft)}\n.mini{display:grid;grid-template-columns:84px minmax(0,1fr);gap:14px;align-items:center;border:1px solid var(--line);border-radius:var(--r);background:var(--card);padding:12px}\n.mini img{width:84px;border-radius:6px;display:block}\n.mini .name{font-family:var(--serif);font-size:19px;font-weight:600}\n.chrow{display:grid;gap:6px;padding:12px 0;border-bottom:1px solid var(--line)}\n.chrow:first-child{border-top:1px solid var(--line)}\n.chrow .t{font-family:var(--serif);font-size:16px}\n.chrow .t span{color:var(--green);opacity:.7;margin-right:8px}\n.log{display:grid;grid-template-columns:auto minmax(0,1fr);gap:6px 14px;font-size:13px}\n.log .d{color:var(--muted);white-space:nowrap}\n\n/* Outline */\n.thesis{font-family:var(--serif);font-size:clamp(1.15rem,2.4vw,1.5rem);line-height:1.4;max-width:34em}\n.facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 40px}\n.facts div{display:grid;gap:4px;align-content:start}\n.facts p{color:var(--soft)}\n.och{border-top:1px solid var(--line);padding-top:24px;display:grid;gap:14px}\n.och .top{display:flex;gap:12px;align-items:baseline;justify-content:space-between;flex-wrap:wrap}\n.och h2 span{color:var(--green);opacity:.7;margin-right:10px}\n.och .brief{color:var(--soft);max-width:68ch}\n.osec{display:grid;grid-template-columns:44px minmax(0,1fr);gap:4px 12px;padding:14px 0;border-top:1px solid var(--line)}\n.osec .n{font-family:var(--serif);color:var(--green);opacity:.75}\n.osec .body{display:grid;gap:6px;min-width:0}\n.osec ul{margin:0;padding-left:18px;color:var(--soft);display:grid;gap:4px;font-size:14px}\n.osec details summary{padding:2px 0}\n\n/* Manuscript */\n.ms{display:grid;grid-template-columns:260px minmax(0,1fr);gap:40px;align-items:start}\n.toc{position:sticky;top:calc(env(safe-area-inset-top,0px) + 76px);display:grid;gap:18px}\n.tocch{display:grid;gap:8px}\n.tocch button{background:none;border:0;padding:0;text-align:left;font-family:var(--serif);font-size:16px;color:var(--soft)}\n.tocch button[aria-pressed=\"true\"]{color:var(--fg);font-weight:600}\n.tocch button span{color:var(--green);opacity:.7;margin-right:8px}\n.tocsec{display:grid;grid-template-columns:10px minmax(0,1fr);gap:8px;align-items:baseline;font-size:13px;color:var(--muted);padding-left:2px}\n.dot{width:8px;height:8px;border-radius:50%;border:1.5px solid var(--muted);display:inline-block}\n.dot.written{background:var(--green);border-color:var(--green)}\n.dot.gaps{background:var(--amber);border-color:var(--amber)}\n.legend{display:flex;gap:16px;flex-wrap:wrap;font-size:12px;color:var(--muted)}\n.legend span{display:inline-flex;gap:6px;align-items:center}\n.sheet{background:var(--paper);color:var(--paper-ink);border-radius:3px;max-width:680px;padding:clamp(28px,7vw,64px) clamp(22px,7vw,64px);font-family:var(--serif);font-size:17px;line-height:1.72;box-shadow:0 30px 80px hsl(0 0% 0% / .6)}\n.sheet .ch{font-family:var(--sans);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--paper-muted);text-align:center}\n.sheet h3{font-size:28px;font-weight:600;text-align:center;margin:10px 0 6px;color:var(--paper-ink)}\n.sheet h4{font-size:18px;margin:34px 0 10px}\n.sheet p{text-indent:1.4em}\n.sheet h3 + p,.sheet h4 + p,.sheet .note + p,.sheet .device p{text-indent:0}\n.sheet .note{font-family:var(--sans);font-size:13px;line-height:1.5;background:var(--paper-note);border-radius:4px;padding:10px 12px;margin:14px 0}\n.sheet .note b{display:block;font-size:10px;letter-spacing:.1em;text-transform:uppercase;margin-bottom:2px}\n.sheet .unwritten{font-family:var(--sans);font-size:14px;line-height:1.5;border:1.5px dashed var(--paper-line);border-radius:4px;padding:14px 16px;color:var(--paper-muted)}\n.sheet .unwritten b{display:block;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--paper-ink);margin-bottom:4px}\n.sheet .device{border-top:1px solid var(--paper-line);margin-top:34px;padding-top:6px}\n.sheet .device p{margin-top:8px}\n.sheet blockquote{margin:14px 1.4em;font-style:italic}\n.sheet .li{text-indent:0;padding-left:1.4em}\n.sheet h5{font-family:var(--serif);font-size:17px;font-weight:600;margin:22px 0 6px}\n.sheet h5 + p,.sheet blockquote + p{text-indent:0}\n\n/* Notes */\n.kinds{display:flex;gap:8px;flex-wrap:wrap}\n.kind{display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:500;padding:6px 12px;border-radius:999px;border:1px solid var(--line);background:transparent;color:var(--soft)}\n.kind i{width:11px;height:11px;border-radius:2px;background:var(--k);display:block;flex:none}\n.kind:hover{border-color:var(--muted)}\n.kind[aria-pressed=\"true\"]{border-color:var(--fg);color:var(--fg);background:var(--raise)}\n.kind .num{color:var(--muted)}\n.tools{display:flex;gap:10px 16px;flex-wrap:wrap;align-items:center}\n.tools label{display:inline-flex;gap:8px;align-items:center;font-size:13px;color:var(--muted);min-width:0}\n.tools select,.tools input{font:inherit;font-size:14px;color:var(--fg);background:var(--card);border:1px solid var(--line);border-radius:6px;padding:7px 10px;min-width:0;max-width:100%}\n.tools input{width:min(240px,100%)}\n.tools input::placeholder{color:var(--muted)}\n.group{display:grid;gap:16px}\n.group + .group{margin-top:20px}\n.board{display:grid;grid-template-columns:repeat(auto-fill,minmax(204px,1fr));gap:24px 20px;align-items:start}\n.sticky{--k:var(--n-story);--tilt:0deg;background:var(--k) linear-gradient(hsl(0 0% 0% / .07),hsl(0 0% 0% / 0) 22px);color:var(--paper-ink);padding:16px 16px 12px;min-height:196px;display:grid;grid-template-rows:auto auto 1fr auto;gap:7px;border-radius:2px;box-shadow:0 1px 0 hsl(0 0% 100% / .25) inset,0 16px 22px -10px hsl(0 0% 0% / .8);transform:rotate(var(--tilt));transition:transform .18s ease;min-width:0}\n.sticky:hover{transform:rotate(0deg) translateY(-3px)}\n.sticky .k{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;opacity:.62}\n.sticky .t{font-family:var(--hand);font-size:25px;font-weight:700;line-height:1.02;text-wrap:balance;overflow-wrap:anywhere}\n.sticky .x{font-size:13.5px;line-height:1.45;overflow-wrap:anywhere}\n.sticky .f{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap;font-size:11px;padding-top:6px;opacity:.78}\n.sticky .loose{border:1px dashed currentColor;border-radius:999px;padding:1px 8px}\n@keyframes land{from{opacity:0;transform:translateY(-18px) rotate(var(--tilt)) scale(1.05)}to{opacity:1;transform:rotate(var(--tilt))}}\n.sticky.fresh{animation:land .5s ease-out}\n.sticky .ed{font-size:11px;font-weight:600;font-style:italic;line-height:1.35}\n.sticky .acts{display:flex;gap:5px;flex-wrap:wrap;padding-top:8px;border-top:1px solid hsl(0 0% 0% / .14)}\n.nact{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:600;line-height:1.2;white-space:nowrap;color:var(--paper-ink);background:hsl(0 0% 100% / .38);border:1px solid hsl(0 0% 0% / .2);border-radius:999px;padding:5px 10px;flex:1 1 auto;justify-content:center}\n.nact:hover{background:hsl(0 0% 100% / .78)}\n.nact:focus-visible{outline-color:var(--paper-ink);border-radius:999px}\n@media (prefers-reduced-motion:reduce){.sticky{transition:none}.sticky.fresh{animation:none}}\n.pins{display:grid;gap:8px}\n.pin{display:grid;grid-template-columns:11px minmax(0,1fr);gap:10px;align-items:baseline;font-family:var(--serif);font-size:15px;color:var(--soft)}\n.pin i{width:11px;height:11px;border-radius:2px;background:var(--k);display:block}\n\n/* Notes: ways to look */\n.views{display:inline-flex;gap:2px;padding:3px;border:1px solid var(--line);border-radius:999px;background:var(--card);justify-self:start;max-width:100%}\n.view{border:0;background:transparent;color:var(--muted);font-size:14px;font-weight:500;padding:7px 16px;border-radius:999px;white-space:nowrap}\n.view:hover{color:var(--fg)}\n.view[aria-pressed=\"true\"]{background:var(--fg);color:var(--bg);font-weight:600}\n.gwrap{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:24px;align-items:start}\n.graph{position:relative;border:1px solid var(--line);border-radius:var(--r);background:radial-gradient(120% 90% at 50% 40%,var(--raise),var(--card) 70%);overflow:hidden;min-width:0}\n.graph canvas{display:block;width:100%;height:min(68vh,600px);min-height:380px;touch-action:pan-y;cursor:grab}\n.graph canvas:active{cursor:grabbing}\n.ghint{position:absolute;left:14px;right:14px;bottom:10px;pointer-events:none}\n.gside{display:grid;gap:14px;align-content:start;min-width:0}\n.gside .sticky{min-height:0}\n.glist{display:grid;gap:6px}\n.glink{display:grid;grid-template-columns:11px minmax(0,1fr);gap:10px;align-items:baseline;text-align:left;background:transparent;border:1px solid var(--line);border-radius:6px;padding:8px 10px;font-size:14px;color:var(--soft)}\n.glink:hover{border-color:var(--muted);color:var(--fg)}\n.glink i{width:11px;height:11px;border-radius:2px;background:var(--k);display:block}\n.tl{border-left:2px solid var(--line);margin-left:6px;padding-left:26px;display:grid;gap:30px}\n.tly{display:grid;gap:16px;position:relative}\n.tly::before{content:\"\";position:absolute;left:-34px;top:9px;width:14px;height:14px;border-radius:50%;background:var(--green);box-shadow:0 0 0 4px var(--bg)}\n.tlyear{font-size:28px;line-height:1}\n.tli{display:grid;gap:8px;align-content:start;min-width:0}\n.tlwhen{font-size:12px;color:var(--muted);min-height:18px}\n.tlwrap{display:grid;gap:28px}\n.tlwrap .group + .group,.tlwrap .group{margin-top:0}\n.tlgap{font-size:12px;color:var(--muted);font-style:italic}\n\n/* Ghostwriter */\n.spot{display:grid;grid-template-columns:220px minmax(0,1fr);gap:28px;align-items:center;border:1px solid var(--green-line);background:var(--green-wash);border-radius:var(--r);padding:22px}\n.spot img{width:100%;border-radius:6px;display:block}\n.spot .info{display:grid;gap:10px;min-width:0}\n.spot .name{font-family:var(--serif);font-size:30px;font-weight:600;line-height:1.1}\n.quote{font-family:var(--serif);font-style:italic;color:var(--soft);font-size:17px}\n.grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px}\n.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:0;text-align:left;overflow:hidden;display:grid;align-content:start}\n.card:hover{border-color:var(--green-line)}\n.card[aria-pressed=\"true\"]{border-color:var(--green)}\n.card img{width:100%;aspect-ratio:4/5;object-fit:cover;display:block}\n.card span{display:block;padding:10px 12px 0;font-family:var(--serif);font-weight:600;font-size:15px}\n.card small{display:block;padding:2px 12px 12px;color:var(--muted);font-size:12px;line-height:1.4}\n@keyframes drift{0%{transform:perspective(1200px) translate3d(0,0,0) rotate(0)}18%{transform:perspective(1200px) translate3d(-4px,-5px,3px) rotate(.6deg)}35%{transform:perspective(1200px) translate3d(3px,-8px,-4px) rotate(-.4deg)}52%{transform:perspective(1200px) translate3d(-6px,-3px,5px) rotate(.8deg)}68%{transform:perspective(1200px) translate3d(5px,-6px,-3px) rotate(-.7deg)}84%{transform:perspective(1200px) translate3d(-3px,-4px,4px) rotate(.3deg)}100%{transform:perspective(1200px) translate3d(0,0,0) rotate(0)}}\n.drift{animation:drift 14s ease-in-out infinite;will-change:transform}\n@media (prefers-reduced-motion:reduce){.drift{animation:none}}\n\n.modal{position:fixed;inset:0;z-index:40;background:hsl(0 0% 0% / .68);display:grid;place-items:center;padding:16px}\n.modal[hidden]{display:none}\n.popup{width:100%;max-width:560px;max-height:100%;overflow:auto;background:var(--raise);border:1px solid var(--green-line);border-radius:12px;padding:clamp(18px,4vw,26px);display:grid;gap:12px;box-shadow:0 30px 80px hsl(0 0% 0% / .7)}\n.popup h2{font-size:21px;line-height:1.25}\n.popup.wide{max-width:820px}\n.modal:not(.manual) #copytext,.modal:not(.manual) #copybtn{display:none}\n.popup pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-family:var(--sans);font-size:14px;line-height:1.5;background:var(--bg);border:1px solid var(--line);border-radius:6px;padding:12px 14px;max-height:40vh;overflow:auto}\n.modal:not(.manual) #copystate::before{content:\"\";display:inline-block;width:10px;height:6px;border-left:2px solid var(--green);border-bottom:2px solid var(--green);transform:rotate(-45deg) translateY(-3px);margin-right:8px}\n.modal.manual #copystate{color:var(--amber)}\n.fld{display:grid;gap:6px;font-size:12px;font-weight:600;letter-spacing:.04em;color:var(--muted)}\n.fld input,.fld textarea{font:inherit;font-size:15px;font-weight:400;letter-spacing:0;line-height:1.5;color:var(--fg);background:var(--bg);border:1px solid var(--line);border-radius:6px;padding:10px 12px;width:100%;resize:vertical}\n#noteerr{color:var(--amber)}\n\n/* Items: anything on a page the author can edit */\n.item{display:grid;gap:8px;min-width:0;align-content:start}\n.item .v{color:var(--soft);white-space:pre-wrap;overflow-wrap:anywhere}\n.item .v.big{font-family:var(--serif);font-size:clamp(1.1rem,2.2vw,1.4rem);line-height:1.45;color:var(--fg);max-width:36em}\n.item ul{margin:0;padding-left:18px;color:var(--soft);display:grid;gap:4px}\n.item blockquote{margin:0;padding-left:14px;border-left:2px solid var(--green-line);font-family:var(--serif);font-style:italic;color:var(--soft)}\n.acts2{display:flex;gap:6px;flex-wrap:wrap;align-items:center}\n.ibtn{font-size:12px;font-weight:600;line-height:1.2;white-space:nowrap;color:var(--soft);background:transparent;border:1px solid var(--line);border-radius:999px;padding:6px 12px}\n.ibtn:hover{border-color:var(--green-line);color:var(--green)}\n.ibtn.go{border-color:var(--green-line);color:var(--green);background:var(--green-wash)}\n.ibtn svg{width:13px;height:13px;vertical-align:-2px;margin-right:6px}\n.story .end .ibtn{margin-top:8px}\n.edtag{font-size:11px;font-weight:600;color:var(--green);white-space:nowrap}\n.edtag.local{color:var(--amber)}\n.hero2{display:grid;gap:22px;border:1px solid var(--line);background:var(--card);border-radius:12px;padding:clamp(18px,3vw,28px)}\n.hero2 .ttl{font-family:var(--serif);font-weight:600;font-size:clamp(1.7rem,4vw,2.6rem);line-height:1.1;overflow-wrap:anywhere}\n.hero2 .sub2{font-family:var(--serif);font-style:italic;color:var(--soft);font-size:clamp(1.05rem,2vw,1.25rem)}\n.hero2 .by{font-size:16px;color:var(--soft)}\n.facts2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:30px 40px}\n.sugs{display:grid;gap:8px;border:1px dashed var(--green-line);border-radius:var(--r);padding:12px 14px}\n.sug{display:flex;gap:10px;align-items:baseline;justify-content:space-between;flex-wrap:wrap}\n.sug span{font-family:var(--serif);font-size:16px;min-width:0;overflow-wrap:anywhere}\n.storygrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}\n.story{display:grid;gap:10px;align-content:start;border:1px solid var(--line);border-top:3px solid var(--n-story);background:var(--card);border-radius:12px;padding:18px 20px;min-width:0}\n.story h3{font-size:20px;font-weight:600}\n.story .nar{color:var(--soft);white-space:pre-wrap;overflow-wrap:anywhere}\n.story .end{border-left:2px solid var(--green-line);padding-left:12px;color:var(--soft);display:grid;gap:2px}\n.story .end.need{border-left-color:var(--amber-line)}\n.story{scroll-margin-top:90px;outline:none}\n.story.lit{border-color:var(--green);box-shadow:0 0 0 3px var(--green-wash)}\na.golink{text-decoration:none;cursor:pointer}\na.chip.golink{color:var(--fg)}\na.chip.golink::after{content:\"\\203A\";color:var(--green);font-weight:600}\na.chip.golink:hover,a.chip.golink:focus-visible{border-color:var(--green-line);color:var(--green)}\na.inlink{color:var(--green);text-decoration:underline;text-underline-offset:2px}\n.deepen{display:grid;gap:8px;border:1px solid var(--amber-line);background:var(--amber-wash);border-radius:var(--r);padding:12px 14px;font-size:14px;color:var(--soft);max-width:72ch}\n.deepen .ibtn{margin-top:0}\n.story details p{font-size:13px;color:var(--soft);margin-bottom:8px}\n.witem.first{border-color:var(--green-line);background:var(--green-wash)}\n.witem .ans{border-left:2px solid var(--green-line);padding-left:12px;color:var(--soft);white-space:pre-wrap;overflow-wrap:anywhere;font-size:14px}\n.tip{display:none;font-size:13px;color:var(--fg);background:hsl(200 86% 79% / .10);border:1px solid hsl(200 86% 79% / .45);border-radius:var(--r);padding:9px 12px;max-width:64ch}\n.tip b{color:var(--n-place);font-weight:600}\nbody.helpon .tip{display:block}\n.helpbtn{flex:none;width:34px;height:34px;border-radius:50%;border:1px solid var(--line);background:transparent;color:var(--soft);font-weight:600;font-size:15px;display:inline-grid;place-items:center}\n.helpbtn:hover{border-color:var(--green-line);color:var(--green)}\n.helpbtn[aria-pressed=\"true\"]{background:var(--n-place);border-color:var(--n-place);color:var(--green-ink)}\n.toast{position:fixed;left:50%;bottom:calc(env(safe-area-inset-bottom,0px) + 20px);transform:translateX(-50%);z-index:50;background:var(--green);color:var(--green-ink);font-weight:600;font-size:14px;border-radius:999px;padding:9px 18px;box-shadow:0 10px 30px hsl(0 0% 0% / .6);max-width:calc(100% - 32px)}\n.talk{display:grid;gap:8px;max-height:36vh;overflow:auto}\n.talk:empty{display:none}\n.talk div{border-radius:10px;padding:9px 12px;max-width:90%;overflow-wrap:anywhere;white-space:pre-wrap;font-size:14px}\n.talk .me{justify-self:end;background:var(--bg);border:1px solid var(--line)}\n.talk .gw{justify-self:start;background:var(--green-wash);border:1px solid var(--green-line)}\n.talk .gw b{display:block;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--green);margin-bottom:3px}\n.about{border-left:3px solid var(--green);background:var(--bg);border-radius:0 6px 6px 0;padding:8px 12px;font-size:14px;color:var(--soft);max-height:20vh;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere}\n#editfields{display:grid;gap:12px}\n#editerr,#talkstate.warn{color:var(--amber)}\n.och .acts2,.osec .acts2{margin-top:2px}\n.sheet .secdisc{margin:2px 0 14px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}\n.sheet .secdisc .edtag{color:var(--paper-ink);border-color:var(--paper-line)}\n.sheet h4 .snum{font-family:var(--sans);font-size:12px;font-weight:600;color:var(--paper-muted);margin-right:10px;letter-spacing:.04em}\n.sheet .secdisc .ibtn{color:var(--paper-muted);border-color:var(--paper-line)}\n.sheet .secdisc .ibtn:hover{color:var(--paper-ink);border-color:var(--paper-ink)}\n.sheet .note .ibtn,.sheet .unwritten .ibtn{color:var(--paper-ink);border-color:var(--paper-line);background:transparent;margin-top:10px;font-family:var(--sans)}\n.sheet .note .ibtn:hover,.sheet .unwritten .ibtn:hover{border-color:var(--paper-ink)}\n.doclink{display:flex;gap:12px 18px;align-items:center;justify-content:space-between;flex-wrap:wrap;border:1px solid var(--green-line);background:var(--green-wash);border-radius:var(--r);padding:14px 16px}\n\n@media (max-width:860px){\n .facts2,.storygrid{grid-template-columns:minmax(0,1fr)}\n .gwrap{grid-template-columns:minmax(0,1fr)}\n .graph canvas{height:420px}\n .cols,.ms{grid-template-columns:minmax(0,1fr)}\n .jphase{min-width:100%}\n .facts{grid-template-columns:minmax(0,1fr)}\n .toc{position:static}\n .spot{grid-template-columns:minmax(0,1fr)}\n .spot img{max-width:180px}\n .grid{grid-template-columns:repeat(2,minmax(0,1fr))}\n .tabs a{padding:7px 10px;font-size:13px}\n .helpbtn{order:2}\n .tabs{order:3;flex:1 1 100%}\n .notyet{grid-template-columns:minmax(0,1fr)}\n}\n@media (max-width:520px){\n .jgrid span{font-size:11px;padding-inline:1px}\n .sayrow .btn,.witem .btn{width:100%;justify-content:center}\n .board{grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 12px}\n .sticky{min-height:156px;padding:12px 12px 10px}\n .nact{padding:8px 10px}\n .sticky .t{font-size:22px}\n .sticky .x{font-size:13px}\n .tools label{flex:1 1 100%}\n .tools select,.tools input{flex:1;width:auto}\n .view{padding:7px 12px}\n .tl{padding-left:20px}\n .tly::before{left:-28px}\n}\n/* ---- The cover ---- */\n.cv{position:relative;aspect-ratio:2/3;width:100%;container-type:inline-size;overflow:hidden;border-radius:3px;background:var(--paper,#F3EBDD);color:var(--ink,#1F3B2D);text-align:left;line-height:1.2;box-shadow:0 30px 70px hsl(0 0% 0% / .75),inset 0 0 0 1px hsl(0 0% 100% / .04)}\n.cv::after{content:\"\";position:absolute;inset:0 auto 0 0;width:2.2cqw;background:linear-gradient(90deg,hsl(0 0% 0% / .22),transparent);pointer-events:none}\n.cv .cvl{display:block;width:max-content;white-space:nowrap}\n.cvtitle{font-family:var(--tf);font-weight:var(--tw,600);line-height:var(--tlh,1);letter-spacing:var(--tls,0);font-size:12cqw}\n.cv.caps .cvtitle{text-transform:uppercase}\n.cvsub{text-wrap:balance;overflow-wrap:anywhere}\n.cvauthor{font-size:3.5cqw;white-space:nowrap}\n.cvmotif svg{display:block;width:100%;height:100%;overflow:visible}\n.cv-paper .cvtop{position:absolute;left:9cqw;right:9cqw;top:10cqw}\n.cv-paper .cvsub{font-family:var(--xf);font-weight:500;line-height:1.3;margin-top:5cqw;max-width:78cqw;color:color-mix(in srgb,var(--ink) 80%,var(--paper))}\n.cv-paper .cvmotif{position:absolute;left:9cqw;width:82cqw;bottom:24cqw;height:24cqw}\n.cv-paper .cvauthor{position:absolute;left:9cqw;right:9cqw;bottom:9cqw;font-family:var(--xf);font-weight:600;letter-spacing:.22em;text-transform:uppercase}\n.cv-bold .cvmotif{position:absolute;left:0;top:0;width:100cqw;height:66cqw}\n.cv-bold .cvbase{position:absolute;left:8cqw;right:8cqw;bottom:8cqw;display:flex;flex-direction:column}\n.cv-bold .cvrule{width:18cqw;height:1cqw;background:var(--accent);margin:5cqw 0 6cqw;flex:none}\n.cv-bold .cvsub{font-family:var(--xf);font-weight:500;line-height:1.32;max-width:78cqw}\n.cv-bold .cvauthor{margin-top:7cqw;font-family:var(--xf);font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:var(--accent)}\n.cv-quiet{text-align:center;background:radial-gradient(120% 80% at 60% 62%,color-mix(in srgb,var(--paper) 90%,var(--ink)) 0,var(--paper) 70%)}\n.cv-quiet .cvl,.cv-over .cvl{margin-inline:auto}\n.cv-quiet .cvtop{position:absolute;left:7cqw;right:7cqw;top:11cqw}\n.cv-quiet .cvsub{font-family:var(--xf);font-weight:500;letter-spacing:.2em;text-transform:uppercase;line-height:1.8;margin-top:4cqw;color:color-mix(in srgb,var(--ink) 72%,var(--paper))}\n.cv-quiet .cvmotif{position:absolute;left:0;top:50cqw;width:100cqw;height:86cqw}\n.cv-quiet .cvauthor{position:absolute;left:7cqw;right:7cqw;bottom:8cqw;font-family:var(--tf);font-weight:600;letter-spacing:.14em;text-transform:uppercase;font-size:5cqw}\n.cv-own{aspect-ratio:auto;background:hsl(0 0% 7%)}\n.cv-own img{display:block;width:100%;height:auto}\n.cv-over{aspect-ratio:2/3;text-align:center}\n.cv-over img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}\n.cv-over .cvscrim{position:absolute;inset:0;background:linear-gradient(180deg,var(--shade) 0,transparent 46%,transparent 74%,var(--shade) 100%)}\n.cv-over .cvtop{position:absolute;left:8cqw;right:8cqw;top:10cqw}\n.cv-over .cvsub{font-family:var(--xf);font-weight:500;line-height:1.4;margin-top:4cqw}\n.cv-over .cvauthor{position:absolute;left:8cqw;right:8cqw;bottom:8cqw;font-family:var(--xf);font-weight:600;letter-spacing:.2em;text-transform:uppercase}\n.cv-wait{display:grid;place-items:center;background:var(--card);color:var(--muted);border:1px dashed var(--line);box-shadow:none;text-align:center;font-size:13px;padding:12px}\n.cv-wait::after{display:none}\n.concepts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(20px,3vw,36px);align-items:start}\n.cc{display:grid;gap:18px;min-width:0}\n.cwrap{padding:26px 30px;border:1px solid var(--line);border-radius:var(--r);background:radial-gradient(90% 70% at 50% 40%,hsl(0 0% 9%),var(--card))}\n.cc.picked .cwrap,.cwrap.picked{border-color:var(--green);box-shadow:0 0 0 1px var(--green)}\n.cwrap.own{max-width:300px}\n.cmeta{display:grid;gap:10px}\n.cmeta h3,.cown h3{font-size:21px;font-weight:600}\n.clook{display:flex;gap:12px;align-items:center;flex-wrap:wrap}\n.csws{display:inline-flex;gap:5px}\n.csws i{width:18px;height:18px;border-radius:50%;box-shadow:inset 0 0 0 1px hsl(0 0% 100% / .14)}\n.csect{display:grid;gap:22px;border-top:1px solid var(--line);padding-top:32px}\n.cintro{display:grid;gap:8px;max-width:68ch}\n.cintro p{color:var(--soft)}\n.cother{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);gap:clamp(24px,4vw,48px);align-items:start}\n.cown{display:grid;gap:16px;align-content:start;min-width:0}\n.cslot{aspect-ratio:2/3;width:min(100%,250px);border:1.5px dashed var(--green-line);border-radius:6px;background:var(--green-wash);display:grid;place-content:center;justify-items:center;gap:10px;text-align:center;padding:18px;color:var(--soft)}\n.cslot svg{width:30px;height:30px;color:var(--green)}\n.cslot b{font-family:var(--serif);font-size:17px;font-weight:600;color:var(--fg)}\n.csteps{list-style:none;margin:0;padding:0;display:grid;gap:10px;counter-reset:cs}\n.csteps li{counter-increment:cs;display:grid;grid-template-columns:26px minmax(0,1fr);gap:10px;color:var(--soft)}\n.csteps li::before{content:counter(cs);width:22px;height:22px;border-radius:50%;border:1px solid var(--green-line);color:var(--green);font-size:12px;font-weight:600;display:grid;place-items:center;margin-top:1px}\n.cback{gap:14px}\n.cback .chl{font-family:var(--serif);font-size:26px;line-height:1.25;font-weight:600;color:var(--fg);max-width:30ch}\n.cback p{color:var(--soft);max-width:62ch}\n.cback .cbio{border-left:2px solid var(--green-line);padding-left:14px;color:var(--muted);font-size:14px}\n.ovhero{display:grid;grid-template-columns:auto minmax(0,1fr);gap:clamp(22px,4vw,44px);align-items:center}\n.ovcover{display:grid;gap:10px;justify-items:center;width:clamp(150px,17vw,208px);text-decoration:none;color:inherit}\n.ovcover .cv{box-shadow:0 22px 50px hsl(0 0% 0% / .7),0 0 0 1px hsl(0 0% 100% / .06);transform:rotate(-1.2deg)}\n.ovcover u{color:var(--green);text-underline-offset:3px}\n.notyet>.cown{border-left:1px solid var(--line);padding-left:clamp(20px,3vw,44px)}\n@media (max-width:900px){.concepts,.cother{grid-template-columns:minmax(0,1fr)}.cwrap{padding:22px clamp(30px,14vw,90px)}.cwrap.own{padding:22px 30px}.notyet>.cown{border-left:0;padding-left:0}}\n@media (max-width:640px){.ovhero{grid-template-columns:minmax(0,1fr);justify-items:start}.ovcover{width:150px}}\n"; document.head.appendChild(st);
|
|
8
8
|
const boot = document.getElementById('gw-boot'); if (boot) boot.remove();
|
|
9
9
|
document.body.insertAdjacentHTML('beforeend', "<header class=\"bar\"><div class=\"wrap\">\n <div class=\"brand\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M10 3l1.9 5.1L17 10l-5.1 1.9L10 17l-1.9-5.1L3 10l5.1-1.9z\"/><path d=\"M19 14l.8 2.2L22 17l-2.2.8L19 20l-.8-2.2L16 17l2.2-.8z\"/></svg><div class=\"bcol\"><span>GhostWriter <span class=\"amp\">&</span> the Muse</span><button class=\"verchip\" id=\"verbtn\" data-act=\"version\" aria-haspopup=\"dialog\" hidden></button></div></div>\n <nav class=\"tabs\" id=\"tabs\" aria-label=\"Pages\"></nav>\n <button class=\"helpbtn\" id=\"helpbtn\" data-act=\"help\" aria-pressed=\"false\" aria-label=\"Show or hide help on this page\" title=\"Help\">?</button>\n</div></header>\n<main id=\"app\" class=\"wrap\"></main>\n<div id=\"copybox\" class=\"modal\" hidden><div class=\"popup\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"copytitle\" aria-describedby=\"copyhint\">\n <div class=\"label green\" id=\"copystate\">Copied to your clipboard</div>\n <h2 id=\"copytitle\">Now paste it into your conversation with your ghostwriter</h2>\n <p class=\"muted\" id=\"copyhint\"></p>\n <pre id=\"copytext\" tabindex=\"0\"></pre>\n <div class=\"row\"><button class=\"btn\" data-act=\"closecopy\" id=\"closebtn\">Done</button><button class=\"btn ghost\" data-act=\"copy\" id=\"copybtn\">Copy again</button></div>\n</div></div>\n\n<div id=\"verbox\" class=\"modal\" hidden><div class=\"popup\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"vertitle\" aria-describedby=\"verhint\">\n <div class=\"label green\" id=\"verstate\"></div>\n <h2 id=\"vertitle\"></h2>\n <p class=\"muted\" id=\"verhint\"></p>\n <dl class=\"verlist\" id=\"verlist\"></dl>\n <div class=\"row\"><button class=\"btn\" data-act=\"verclose\" id=\"verclose\">Done</button><a class=\"btn ghost\" id=\"verlink\" target=\"_blank\" rel=\"noopener\" hidden>Open the setup page</a></div>\n</div></div>\n\n<div id=\"notebox\" class=\"modal\" hidden><div class=\"popup\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"notehead\">\n <div class=\"label green\" id=\"notekind\"></div>\n <h2 id=\"notehead\">Edit this note</h2>\n <label class=\"fld\" for=\"notetitle\">Title<input id=\"notetitle\" type=\"text\" maxlength=\"120\" autocomplete=\"off\"></label>\n <label class=\"fld\" for=\"notetext\">In your words<textarea id=\"notetext\" rows=\"7\" maxlength=\"4000\"></textarea></label>\n <p class=\"fine\" id=\"notehint\"></p>\n <p class=\"fine\" id=\"noteerr\" hidden></p>\n <div class=\"row\"><button class=\"btn\" data-act=\"nsave\" id=\"notesave\">Save</button><button class=\"btn ghost\" data-act=\"nclose\" id=\"notecancel\">Cancel</button></div>\n</div></div>\n\n<div id=\"editbox\" class=\"modal\" hidden><div class=\"popup\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"edithead\">\n <div class=\"label green\" id=\"editpage\"></div>\n <h2 id=\"edithead\"></h2>\n <div id=\"editfields\"></div>\n <p class=\"fine\" id=\"edithint\"></p>\n <p class=\"fine\" id=\"editerr\" hidden></p>\n <div class=\"row\"><button class=\"btn\" data-act=\"esave\" id=\"editsave\">Save</button><button class=\"btn ghost\" data-act=\"eclose\" id=\"editcancel\">Cancel</button></div>\n</div></div>\n\n<div id=\"toast\" class=\"toast\" role=\"status\" hidden></div>\n");
|
|
10
10
|
|
|
@@ -205,6 +205,14 @@ function acts(ref, extra){
|
|
|
205
205
|
return '<span class="acts2">' + (it.noEdit ? '' : '<button class="ibtn" data-act="iedit" data-ref="' + esc(ref) + '" id="ie-' + domId(ref) + '">' + (it.editWord || 'Edit') + '</button>') + (extra || '') + '</span>';
|
|
206
206
|
}
|
|
207
207
|
const tip = t => '<p class="tip"><b>How this works.</b> ' + t + '</p>';
|
|
208
|
+
/* Wherever a story is named, its name opens that story on the Stories page, where the author can read and edit it. */
|
|
209
|
+
let focusStory = null;
|
|
210
|
+
const storyKey = title => { const want = String(title || "").trim().toLowerCase(), hit = ((stories && stories.items) || []).find(x => String(x.title || "").trim().toLowerCase() === want); return hit ? hit.key : ""; };
|
|
211
|
+
const storyLink = (title, id, cls, lead) => { const k = storyKey(title); return k ? '<a class="' + cls + ' golink" href="' + href("stories") + (FILES ? "#story-" + k : "") + '" data-act="gostory" data-key="' + esc(k) + '" id="' + id + '" title="Open this story on your Stories page">' + (lead || "") + esc(title) + '</a>' : '<span class="' + cls + '">' + (lead || "") + esc(title) + '</span>'; };
|
|
212
|
+
function goStory(){ if (!focusStory) return; const el = document.getElementById("story-" + focusStory); focusStory = null; if (!el) return; el.scrollIntoView({block: "center"}); el.classList.add("lit"); el.focus({preventScroll: true}); setTimeout(() => el.classList.remove("lit"), 2600); }
|
|
213
|
+
/* A chapter the ghostwriter has marked as needing more from the author, with a ready message to start filling it. */
|
|
214
|
+
const DEPTH = {thin: "Needs more from you", empty: "Nothing of yours here yet"};
|
|
215
|
+
const deepenSay = (c, title) => "For my book: " + c.head + ', "' + title + '", needs more from me before it is written.' + (c.needs ? "\n\nWhat would help most: " + c.needs : "") + "\n\nAsk me one question at a time to draw it out: what happened, what it meant to me, and what I would tell the reader. I will answer in my own words.";
|
|
208
216
|
/* What's new: short notes the ghostwriter leaves in state.news when something changed. They show on the Overview until the author
|
|
209
217
|
presses Got it. An ordinary note goes quiet after two weeks; a note about a newer plugin stays until the ghostwriter takes it away. */
|
|
210
218
|
let newsSeen = new Set(); try { const kept = JSON.parse(localStorage.getItem("gw-news") || "[]"); if (Array.isArray(kept)) kept.forEach(x => newsSeen.add(String(x))); } catch (e) {}
|
|
@@ -249,7 +257,7 @@ function setupPage(){
|
|
|
249
257
|
const xs = setup.items.map(it => lineItem("Book Setup", "setup", it)), by = k => xs.find(x => x.it.key === k), t = by("title"), s = by("subtitle"), a = by("author"), rest = xs.filter(x => !["title","subtitle","author"].includes(x.it.key));
|
|
250
258
|
const head = (x, label) => '<div class="head"><div class="label">' + label + '</div><div class="chips">' + edTag(x.ref) + '</div></div>';
|
|
251
259
|
return '<div class="pagehead"><div class="chips">' + statusChip(setup) + yesBtn(setup.status !== "confirmed", "Book Setup", "setup") + (mode === "snapshot" ? '<span class="chip">Saved copy</span>' : '') + '</div><h1>Book Setup</h1><p class="sub">What the book is, who it is for, and what it promises.</p></div>' +
|
|
252
|
-
tip('Every line here came from what you told your ghostwriter, or is your ghostwriter\'s first guess. Press <b>Edit</b> to change any line yourself. It is saved
|
|
260
|
+
tip('Every line here came from what you told your ghostwriter, or is your ghostwriter\'s first guess. Press <b>Edit</b> to change any line yourself. It is saved here, and your ghostwriter carries it through the book the next time you write in your conversation. ' + HELPLINE) +
|
|
253
261
|
'<div class="hero2">' +
|
|
254
262
|
(t ? '<div class="item">' + head(t, "Working title") + '<div class="ttl">' + esc(t.value) + '</div>' + acts(t.ref) + '</div>' : '') +
|
|
255
263
|
(s ? '<div class="item">' + head(s, "Subtitle") + '<div class="sub2">' + (s.value ? esc(s.value) : 'No subtitle yet') + '</div>' + acts(s.ref, sampler ? '<button class="ibtn go" data-act="suggest" data-k="subtitle" id="sug-subtitle">Suggest three subtitles</button>' : '') + sugHTML(s.ref) + '</div>' : '') +
|
|
@@ -272,9 +280,9 @@ function voicePage(){
|
|
|
272
280
|
|
|
273
281
|
function storyItem(st){
|
|
274
282
|
const f = (name, label, shown, long) => { const ref = st.ref + "/" + name, base = st[name] || ""; return {ref, label, shown, value: nowVal(ref, base), base, long, rows: name === "narrative" ? 8 : 4}; };
|
|
275
|
-
const fields = [f("title", "Story title", "Title"), f("when", "When", "When it happened, as you would say it"), f("narrative", "Narrative", "What happened", true), f("ended", "How it ended", "How it ended", true)];
|
|
276
|
-
const v = {title: fields[0].value, when: fields[1].value, narrative: fields[2].value, ended: fields[3].value};
|
|
277
|
-
reg({ref: st.ref, page: "Stories", label: "Story: " + st.title, shown: v.title, what: 'the story "' + v.title + '"', text: v.narrative + (v.ended ? "\n\nHow it ended: " + v.ended : ""), fields});
|
|
283
|
+
const fields = [f("title", "Story title", "Title"), f("when", "When", "When it happened, as you would say it"), f("narrative", "Narrative", "What happened", true), f("ended", "How it ended", "How it ended", true), f("meant", "What it meant", "What it meant to you", true)];
|
|
284
|
+
const v = {title: fields[0].value, when: fields[1].value, narrative: fields[2].value, ended: fields[3].value, meant: fields[4].value};
|
|
285
|
+
reg({ref: st.ref, page: "Stories", label: "Story: " + st.title, shown: v.title, what: 'the story "' + v.title + '"', text: v.narrative + (v.ended ? "\n\nHow it ended: " + v.ended : "") + (v.meant ? "\n\nWhat it meant: " + v.meant : ""), fields});
|
|
278
286
|
return {v, changed: fields.some(x => over[x.ref]), local: fields.some(x => over[x.ref] && over[x.ref].local)};
|
|
279
287
|
}
|
|
280
288
|
function storiesPage(){
|
|
@@ -283,16 +291,17 @@ function storiesPage(){
|
|
|
283
291
|
return notYet("stories", "Stories", "The real stories your book is built on.", "Each story you tell your ghostwriter lands here in your words, with how it ended and where it lives in the book. You can tell one out loud: use the microphone in Claude." + (sn ? ' Your <a href="' + href("notes") + '">notes board</a> already holds ' + n(sn) + (sn === 1 ? ' story note. Tell it in full and it lands here.' : ' story notes. Tell one in full and it lands here.') : '')); }
|
|
284
292
|
const told = list.filter(x => x.told).length;
|
|
285
293
|
const card = st => { const x = storyItem(st), v = x.v;
|
|
286
|
-
return '<article class="story"><div class="head"><div class="chips">' + (STRENGTH[String(st.strength || "").toLowerCase()] ? '<span class="chip">' + STRENGTH[String(st.strength).toLowerCase()] + '</span>' : '') + '<span class="chip">' + (v.when ? esc(v.when) : 'No date yet') + '</span>' + (st.told ? '<span class="chip green">Told in the book</span>' : '<span class="chip">Not told yet</span>') + '</div>' + (x.changed ? '<span class="edtag' + (x.local ? ' local' : '') + '">' + (x.local ? 'Changed here, not saved yet' : 'Changed by you') + '</span>' : '') + '</div>' +
|
|
294
|
+
return '<article class="story" id="story-' + esc(st.key || domId(st.ref)) + '" tabindex="-1"><div class="head"><div class="chips">' + (STRENGTH[String(st.strength || "").toLowerCase()] ? '<span class="chip">' + STRENGTH[String(st.strength).toLowerCase()] + '</span>' : '') + '<span class="chip">' + (v.when ? esc(v.when) : 'No date yet') + '</span>' + (st.told ? '<span class="chip green">Told in the book</span>' : '<span class="chip">Not told yet</span>') + '</div>' + (x.changed ? '<span class="edtag' + (x.local ? ' local' : '') + '">' + (x.local ? 'Changed here, not saved yet' : 'Changed by you') + '</span>' : '') + '</div>' +
|
|
287
295
|
'<h3>' + esc(v.title) + '</h3><p class="nar">' + esc(v.narrative) + '</p>' +
|
|
288
296
|
(v.ended ? '<div class="end"><div class="label">How it ended</div><div>' + esc(v.ended) + '</div></div>' : '<div class="end need"><div class="label amber">How it ended</div><div>Your ghostwriter still needs this from you. Press Edit to add it, or tell it in your conversation.</div><div>' + copyBtn('For my book: here is how the story "' + v.title + '" ended:', "endcopy-" + domId(st.ref), "Copy a prompt to tell the ending") + '</div></div>') +
|
|
297
|
+
(v.meant ? '<div class="end meant"><div class="label">What it meant to you</div><div>' + esc(v.meant) + '</div></div>' : '<div class="end need meant"><div class="label amber">What it meant to you</div><div>What you felt, what changed, what you see in it now. Only you can say, and it is what makes the story yours. Press Edit to add it, or tell it in your conversation.</div><div>' + copyBtn('For my book: here is what the story "' + v.title + '" meant to me:', "meantcopy-" + domId(st.ref), "Copy a prompt to say what it meant") + '</div></div>') +
|
|
289
298
|
(st.home ? '<p class="fine">Lives in ' + esc(st.home) + (st.role ? ' · ' + esc(st.role) : '') + '</p>' : '') +
|
|
290
299
|
(st.point || st.people || st.facts ? '<details><summary>What it shows, who is in it, and the facts that must not change</summary>' + (st.point ? '<p><b>What it shows.</b> ' + esc(st.point) + '</p>' : '') + (st.people ? '<p><b>Who is in it.</b> ' + esc(st.people) + '</p>' : '') + (st.facts ? '<p><b>Facts that must not change.</b> ' + esc(st.facts) + '</p>' : '') + '</details>' : '') +
|
|
291
300
|
acts(st.ref) + '</article>'; };
|
|
292
301
|
const need = ({c, s}) => { const say = storySay(s);
|
|
293
302
|
return '<li class="witem need"><div class="wmeta"><span class="chip amber">Needs a real story</span><span class="fine">' + esc(c.head) + ', section ' + esc(s.num) + '</span></div><p class="ask">' + esc(s.title) + '</p><p class="muted">' + esc(s.purpose || "") + '</p><div><button class="btn ghost" data-act="prompt" data-i="' + regP(say) + '" id="needcopy-' + domId(s.num) + '">' + COPYICON + 'Copy a prompt for this story</button></div></li>'; };
|
|
294
303
|
return '<div class="pagehead"><div class="chips">' + (list.length ? '<span class="chip green num">' + n(list.length) + (list.length === 1 ? ' story' : ' stories') + '</span><span class="chip num">' + n(told) + ' told in the book</span>' : '') + (needs.length ? '<span class="chip amber num">' + n(needs.length) + ' still needed</span>' : '') + (stories ? statusChip(stories) + yesBtn(list.length && stories.status !== "confirmed", "story bank", "stories") : '') + (mode === "snapshot" ? '<span class="chip">Saved copy</span>' : '') + '</div><h1>Stories</h1><p class="sub">The real stories your book is built on, in your words.</p></div>' +
|
|
295
|
-
tip('Each card is a story you told. Press <b>Edit</b> to fix a title, a date, or what
|
|
304
|
+
tip('Each card is a story you told. Press <b>Edit</b> to fix a title, a date, what happened, how it ended, or what it meant to you. To add to a story, tell your ghostwriter in your conversation. Your ghostwriter never invents a detail, so a gap here is a question for you. ' + HELPLINE) +
|
|
296
305
|
(list.length ? '<div class="storygrid">' + list.map(card).join("") + '</div>' : '') +
|
|
297
306
|
(needs.length ? '<section class="block"><div class="head"><h2>Sections still waiting for a story</h2></div><p class="muted waithelp">These parts of the outline need something that really happened to you. Gaps are fine; you do not have to fill them all today.</p><ul class="wlist">' + needs.map(need).join("") + '</ul></section>' : '');
|
|
298
307
|
}
|
|
@@ -307,7 +316,7 @@ function openEdit(ref){
|
|
|
307
316
|
document.querySelector("#editbox .popup").classList.toggle("wide", !!it.wide);
|
|
308
317
|
document.getElementById("editfields").innerHTML = it.fields.map((f, i) => '<label class="fld" for="ef-' + i + '">' + esc(f.shown || f.label) + (f.long ? '<textarea id="ef-' + i + '" rows="' + (f.rows || 6) + '" maxlength="' + (f.max || 6000) + '"></textarea>' : '<input id="ef-' + i + '" type="text" maxlength="300" autocomplete="off">') + '</label>').join("");
|
|
309
318
|
it.fields.forEach((f, i) => { document.getElementById("ef-" + i).value = f.value; });
|
|
310
|
-
document.getElementById("edithint").textContent = db ? (it.hint || "Saved here
|
|
319
|
+
document.getElementById("edithint").textContent = db ? (it.hint || "Saved here. Your ghostwriter folds it into the book the next time you write in your conversation.") : "This copy of the page cannot save. You will get a message to paste to your ghostwriter, who makes the change.";
|
|
311
320
|
document.getElementById("editerr").hidden = true; document.getElementById("editbox").hidden = false;
|
|
312
321
|
document.getElementById("ef-0").focus({preventScroll: true});
|
|
313
322
|
}
|
|
@@ -529,8 +538,8 @@ function outlinePage(){
|
|
|
529
538
|
tip('This is the order your book argues in. Press <b>Edit</b> on a chapter or a section to change its title or what it is for. Each section has a number, like 1.2, that you can use with your ghostwriter: "look at 1.2". To add, drop, or move a chapter, tell your ghostwriter in your conversation. ' + HELPLINE) +
|
|
530
539
|
'<div class="block"><div class="label green">The claim this book makes</div><p class="thesis">' + esc(o.thesis) + '</p><p class="fine">To change this, go to <a href="' + href("setup") + '">Book Setup</a>.</p></div>' +
|
|
531
540
|
'<div class="facts">' + fact("Written for", o.audience) + fact("The promise", o.promise) + fact("Every chapter carries", o.device) + fact("Length", o.length) + fact("Point of view", o.pointOfView) + '</div>' +
|
|
532
|
-
m.chs.map(c => { const x = chapter(c); return '<div class="och"><div class="top"><h2>' + tagSpan(c) + esc(x.title) + '</h2><div class="chips">' + (x.changed ? changedTag : '') + '<span class="chip' + (c.words ? ' green' : '') + '">' + (c.words ? esc(c.status || "Drafting") : 'Not started') + '</span
|
|
533
|
-
c.secs.filter(s => !s.implicit).map(s => { const y = section(s); return '<div class="osec"><div class="n num">' + esc(s.num) + '</div><div class="body"><h3>' + esc(y.title) + '</h3><p class="muted">' + esc(y.purpose) + '</p><details><summary>What it has to cover</summary><ul>' + (s.beats || []).map(b => '<li>' + esc(b) + '</li>').join("") + '</ul></details><div class="row">' + (s.story ?
|
|
541
|
+
m.chs.map(c => { const x = chapter(c); return '<div class="och"><div class="top"><h2>' + tagSpan(c) + esc(x.title) + '</h2><div class="chips">' + (x.changed ? changedTag : '') + '<span class="chip' + (c.words ? ' green' : '') + '">' + (c.words ? esc(c.status || "Drafting") : 'Not started') + '</span>' + (DEPTH[c.depth] ? '<span class="chip amber">' + DEPTH[c.depth] + '</span>' : c.depth === "ready" && !c.words ? '<span class="chip">Ready to write</span>' : '') + '</div></div><p class="brief">' + esc(x.brief) + '</p>' + (DEPTH[c.depth] ? '<div class="deepen"><div>' + (c.needs ? '<b>What would help most.</b> ' + esc(c.needs) : 'Your ghostwriter has little of yours for this chapter yet: what happened, what it meant to you, what you would tell the reader.') + '</div><div>' + copyBtn(deepenSay(c, x.title), "deepen-" + domId(c.key), "Copy a prompt to add to this chapter") + '</div></div>' : '') + '<p class="fine">' + (c.leaves ? esc(c.leaves) + ' · ' : '') + 'About ' + n(c.target) + ' words</p>' + acts(x.ref) + '<div>' +
|
|
542
|
+
c.secs.filter(s => !s.implicit).map(s => { const y = section(s); return '<div class="osec"><div class="n num">' + esc(s.num) + '</div><div class="body"><h3>' + esc(y.title) + '</h3><p class="muted">' + esc(y.purpose) + '</p><details><summary>What it has to cover</summary><ul>' + (s.beats || []).map(b => '<li>' + esc(b) + '</li>').join("") + '</ul></details><div class="row">' + (s.story ? storyLink(s.story, "opill-" + domId(s.num), "chip", "Story: ") : s.needsStory ? '<span class="chip amber">Needs a real story</span>' : '') + '<span class="fine">' + STATUS[s.state] + '</span>' + (y.changed ? changedTag : '') + '</div>' + acts(y.ref, !s.story && s.needsStory ? copyBtn(storySay({num: s.num, title: y.title, purpose: y.purpose}), "ostory-" + domId(s.num), "Copy a prompt for this story") : '') + '</div></div>'; }).join("") + '</div></div>'; }).join("");
|
|
534
543
|
}
|
|
535
544
|
|
|
536
545
|
/* Prose travels as plain lines: a paragraph, "> " a quoted line, "- " a list line, "### " a small heading, "[STORY NEEDED: ...]" a gap. */
|
|
@@ -554,7 +563,7 @@ function manuscriptPage(){
|
|
|
554
563
|
const doc = state && /^https:\/\/claude\.ai\//.test(String(state.manuscriptDoc || "")) ? String(state.manuscriptDoc) : "";
|
|
555
564
|
const sec = (t, num, title, implicit) => { const ref = "manuscript/" + cur.key + "/" + (num || "all"), base = proseSource(t), value = nowVal(ref, base);
|
|
556
565
|
reg({ref, page: "Manuscript", label: cur.head + (implicit ? "" : ", section " + (/^extra-/.test(num) ? "" : num + " ") + '"' + title + '"'), shown: implicit ? cur.title : (/^extra-/.test(num) ? "" : num + " ") + title, wide: true,
|
|
557
|
-
hint: "Saved here
|
|
566
|
+
hint: "Saved here. Your ghostwriter keeps your words exactly as you leave them, the next time you write in your conversation. A line in [SQUARE BRACKETS] is a gap waiting for you: replace it with what really happened, or leave it.",
|
|
558
567
|
fields: [{ref, label: "Text", shown: "The words of this section. Leave a blank line between paragraphs.", value, base, long: true, rows: 18, max: 60000}]});
|
|
559
568
|
const where = cur.head + (implicit || /^extra-/.test(num) ? (implicit ? "" : ', "' + title + '"') : ", section " + num + ', "' + title + '"');
|
|
560
569
|
return {ref, html: blocks(over[ref] ? {blocks: proseBlocks(value)} : t, where, ref) + '<div class="secdisc">' + edTag(ref) + acts(ref) + '</div>'}; };
|
|
@@ -566,7 +575,7 @@ function manuscriptPage(){
|
|
|
566
575
|
(doc ? '<div class="doclink"><div><div class="label green">Your manuscript document</div><div class="muted">Edit the chapters like any document. It also saves as Word or PDF.</div></div><a class="btn" href="' + esc(doc) + '" target="_blank" rel="noopener">Open your manuscript</a></div>' : '') +
|
|
567
576
|
'<div class="ms"><aside class="toc" aria-label="Chapters">' + m.chs.map(c => '<div class="tocch"><button data-act="chapter" data-k="' + esc(c.key) + '" id="toc-' + esc(c.key) + '" aria-pressed="' + (c.key === cur.key) + '">' + tagSpan(c) + esc(c.title) + '</button>' + c.secs.map(s => '<div class="tocsec">' + dot(s.state) + '<span>' + (s.implicit ? '' : '<span class="num">' + esc(s.num) + '</span> ' + esc(s.title) + ' · ') + '<span class="num">' + (s.words ? n(s.words) + ' words' : 'not yet') + '</span></span></div>').join("") + '</div>').join("") + '</aside>' +
|
|
568
577
|
'<article class="sheet"><div class="ch">' + esc(cur.head) + '</div><h3>' + esc(cur.title) + '</h3>' +
|
|
569
|
-
cur.secs.map(s => (s.implicit ? '' : '<h4><span class="snum num">' + esc(s.num) + '</span>' + esc(s.title) + '</h4>') + (s.text && s.words ? sec(s.text, s.num, s.title, s.implicit).html : '<div class="unwritten"><b>Not written yet</b>' + esc(s.purpose) + (s.needsStory && !s.story ? ' Waiting on a real story from you.<div>' + copyBtn(storySay(s), "mstory-" + domId(s.num), "Copy a prompt for this story", "ibtn") + '</div>' : s.story ? ' Its story is ready: ' +
|
|
578
|
+
cur.secs.map(s => (s.implicit ? '' : '<h4><span class="snum num">' + esc(s.num) + '</span>' + esc(s.title) + '</h4>') + (s.text && s.words ? sec(s.text, s.num, s.title, s.implicit).html : '<div class="unwritten"><b>Not written yet</b>' + esc(s.purpose) + (s.needsStory && !s.story ? ' Waiting on a real story from you.<div>' + copyBtn(storySay(s), "mstory-" + domId(s.num), "Copy a prompt for this story", "ibtn") + '</div>' : s.story ? ' Its story is ready: ' + storyLink(s.story, "mpill-" + domId(s.num), "inlink") + '.' : '') + '</div>')).join("") +
|
|
570
579
|
cur.extra.map(t => '<div class="device"><h4>' + esc(t.title) + '</h4>' + sec(t, t.num, t.title, false).html + '</div>').join("") +
|
|
571
580
|
'</article></div>';
|
|
572
581
|
}
|
|
@@ -808,7 +817,7 @@ function openNote(k){
|
|
|
808
817
|
const x = noteBy(k); if (!x) return; const e = edits[x.n] || x; editing = x.n;
|
|
809
818
|
const kd = kindOf(x); document.getElementById("notekind").textContent = "Note " + x.n + " · " + (KINDS.find(z => z[0] === kd) || KINDS[3])[2];
|
|
810
819
|
document.getElementById("notetitle").value = e.title || ""; document.getElementById("notetext").value = e.text || "";
|
|
811
|
-
document.getElementById("notehint").textContent = db ? "Saved here
|
|
820
|
+
document.getElementById("notehint").textContent = db ? "Saved here. Your ghostwriter folds it into the book the next time you write in your conversation." : "This copy of the page cannot save. You will get a message to paste to your ghostwriter, who makes the change.";
|
|
812
821
|
document.getElementById("noteerr").hidden = true; document.getElementById("notebox").hidden = false;
|
|
813
822
|
document.getElementById("notetitle").focus({preventScroll:true});
|
|
814
823
|
}
|
|
@@ -855,6 +864,7 @@ document.addEventListener("click", e => {
|
|
|
855
864
|
else if (act === "version") openVersion();
|
|
856
865
|
else if (act === "verclose") closeVersion();
|
|
857
866
|
else if (act === "newsdone") newsDone(b.dataset.id);
|
|
867
|
+
else if (act === "gostory") { focusStory = b.dataset.key; if (!FILES && page() === "stories") { e.preventDefault(); goStory(); } }
|
|
858
868
|
else if (act === "nsave") saveNote();
|
|
859
869
|
else if (act === "nclose") closeNote();
|
|
860
870
|
else if (act === "waitall") { waitAll = !waitAll; render(); const el = document.getElementById("waitall"); if (el) el.focus({preventScroll:true}); }
|
|
@@ -876,9 +886,10 @@ document.addEventListener("keydown", e => {
|
|
|
876
886
|
document.addEventListener("pointerdown", e => { downOn = e.target; }, true);
|
|
877
887
|
document.getElementById("editbox").addEventListener("click", e => { if (e.target.id === "editbox" && downOn === e.target) closeEdit(); });
|
|
878
888
|
try { if (localStorage.getItem("gw-help") === "1") setHelp(true); } catch (e) {}
|
|
879
|
-
window.addEventListener("hashchange", () => { if (edit) closeEdit(); if (!document.getElementById("copybox").hidden) closeCopy(); closeVersion(); render(); window.scrollTo(0, 0); });
|
|
889
|
+
window.addEventListener("hashchange", () => { if (edit) closeEdit(); if (!document.getElementById("copybox").hidden) closeCopy(); closeVersion(); render(); window.scrollTo(0, 0); goStory(); });
|
|
880
890
|
|
|
881
891
|
render();
|
|
892
|
+
if (FILES && /^#story-[a-z0-9-]+$/.test(location.hash || "")) { focusStory = location.hash.slice(7); goStory(); }
|
|
882
893
|
(async function connect(){
|
|
883
894
|
let ns = null;
|
|
884
895
|
try { ns = (window.claude && window.claude.use) ? await window.claude.use("db") : null; } catch (e) { ns = null; }
|
package/package.json
CHANGED