ghostwriter-muse-pages 17.0.0 → 18.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.
Files changed (3) hide show
  1. package/build_pages.py +2 -2
  2. package/kit.js +16 -5
  3. 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.5" # this builder's own version
24
- KIT_VERSION = "17.0.0" # the exact version of the page code every page loads
23
+ BUILDER = "0.9.6" # this builder's own version
24
+ KIT_VERSION = "18.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",
package/kit.js CHANGED
@@ -1,7 +1,7 @@
1
- /* GhostWriter & the Muse: the book's pages. Page kit 17.0.0. */
1
+ /* GhostWriter & the Muse: the book's pages. Page kit 18.0.0. */
2
2
  (function(){
3
3
  if (window.GW_KIT) return;
4
- window.GW_KIT = "17.0.0";
4
+ window.GW_KIT = "18.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
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}\nbody:not(.kbd) button:focus-visible,body:not(.kbd) a:focus-visible,body:not(.kbd) summary:focus-visible,body:not(.kbd) [tabindex]:focus-visible{outline:none}\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{gap:8px}\n.verchip.due .vl{color:var(--amber);border:1px solid var(--amber-line);background:var(--amber-wash);border-radius:999px;padding:0 8px;line-height:1.55;font-weight:600}\n.verchip.due .vl::before{content:none}\n.verchip.due:hover .vl{border-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);
@@ -217,18 +217,26 @@ const deepenSay = (c, title) => "For my book: " + c.head + ', "' + title + '", n
217
217
  /* What's new: short notes the ghostwriter leaves in state.news when something changed. They show on the Overview until the author
218
218
  presses Got it. An ordinary note goes quiet after two weeks; a note about a newer plugin stays until the ghostwriter takes it away. */
219
219
  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) {}
220
+ /* The browser alone forgets: a page shown again inside Claude often starts with empty browser storage, and the note came back.
221
+ So a note put away is also kept in the page's own storage (the collection "seen", one small document per note), which travels
222
+ with the page. Until that list has arrived (or the page learns it has no storage), a live page shows no notes, so a note already put away never flashes back. */
223
+ let newsKept = new Set(), newsReady = false;
224
+ setTimeout(() => { if (!newsReady) { newsReady = true; try { if (page() === "overview") render(); } catch (e) {} } }, 4000);
220
225
  function newsList(s){
221
226
  const now = Date.now(), ok = x => x && typeof x === "object" && /^[a-z0-9][a-z0-9.-]{0,39}$/.test(String(x.id || "")) && typeof x.text === "string" && x.text.trim() && /^\d{4}-\d{2}-\d{2}$/.test(String(x.date || ""));
222
- return (Array.isArray(s && s.news) ? s.news : []).filter(ok).filter(x => !newsSeen.has(x.id))
227
+ return (Array.isArray(s && s.news) ? s.news : []).filter(ok).filter(x => !newsSeen.has(String(x.id)) && !newsKept.has(String(x.id)))
223
228
  .filter(x => x.kind === "plugin" || now - new Date(x.date + "T12:00:00").getTime() < 14.5 * 864e5).slice(0, 3);
224
229
  }
225
230
  function newsBlock(s){
231
+ if (!FILES && !newsReady) return "";
226
232
  const list = newsList(s); if (!list.length) return "";
227
233
  return '<section class="news" aria-label="What is new">' + list.map((x, i) => { const plug = x.kind === "plugin";
228
234
  return '<div class="newsitem' + (plug ? ' plug' : '') + '"><div class="newshead"><span class="label ' + (plug ? 'amber' : 'green') + '">' + (plug ? 'Plugin update' : "What's new") + '</span><span class="fine num">' + fmtDate(x.date) + '</span><button class="ibtn" data-act="newsdone" data-id="' + esc(x.id) + '" id="newsdone-' + i + '">Got it</button></div><p>' + esc(x.text.trim().slice(0, 400)) + '</p>' +
229
235
  (plug ? '<div><a class="ibtn go" id="newslink-' + i + '" href="' + UPDATE + '" target="_blank" rel="noopener">Update the plugin</a></div>' : '') + '</div>'; }).join("") + '</section>';
230
236
  }
231
- function newsDone(id){ newsSeen.add(String(id)); try { localStorage.setItem("gw-news", JSON.stringify(Array.from(newsSeen).slice(-40))); } catch (e) {} render(); const h = document.querySelector(".pagehead h1"); if (h) { h.setAttribute("tabindex", "-1"); h.focus({preventScroll:true}); } }
237
+ function newsDone(id){ newsSeen.add(String(id)); try { localStorage.setItem("gw-news", JSON.stringify(Array.from(newsSeen).slice(-40))); } catch (e) {}
238
+ if (db) { try { const w = db.doc("seen/" + docId("news", id)).set({type: "news", id: String(id), at: new Date().toISOString()}); if (w && w.catch) w.catch(() => {}); } catch (e) {} }
239
+ render(); const h = document.querySelector(".pagehead h1"); if (h) { h.setAttribute("tabindex", "-1"); h.focus({preventScroll:true}); } }
232
240
  const HELPLINE = 'You can ask your ghostwriter anything in your conversation in Claude, including how these pages work. You can also talk instead of type: use the microphone in Claude and tell your story out loud.';
233
241
  function statusChip(d){ return d.status === "confirmed" ? '<span class="chip green">Confirmed' + (d.confirmed ? ' ' + fmtDate(d.confirmed) : '') + '</span>' : '<span class="chip amber">Draft, waiting for your yes</span>'; }
234
242
  function lineItem(pageName, prefix, it){
@@ -897,7 +905,7 @@ if (FILES && /^#story-[a-z0-9-]+$/.test(location.hash || "")) { focusStory = loc
897
905
  (async function connect(){
898
906
  let ns = null;
899
907
  try { ns = (window.claude && window.claude.use) ? await window.claude.use("db") : null; } catch (e) { ns = null; }
900
- if (!ns) { if (!state) { mode = "empty"; render(); } return; }
908
+ if (!ns) { newsReady = true; if (!state) mode = "empty"; render(); return; }
901
909
  db = ns;
902
910
  (async () => { try { sampler = await window.claude.use("sample"); } catch (e) { sampler = null; } if (sampler) render(); })();
903
911
  const gone = () => { if (!state) { mode = "empty"; render(); } };
@@ -924,6 +932,9 @@ if (FILES && /^#story-[a-z0-9-]+$/.test(location.hash || "")) { focusStory = loc
924
932
  if (cpick && cpick.id) coverPick = cpick; else if (coverPick && !coverPick.local) coverPick = null;
925
933
  render();
926
934
  }, () => {});
935
+ db.collection("seen").onSnapshot(q => { const next = new Set(); q.docs.forEach(d => { const v = d.data(); if (v && v.type === "news" && v.id != null) next.add(String(v.id)); }); newsKept = next; newsReady = true; if (page() === "overview") render(); },
936
+ () => { if (!newsReady) { newsReady = true; if (page() === "overview") render(); } });
937
+ setTimeout(() => { if (!newsReady) { newsReady = true; if (page() === "overview") render(); } }, 2500);
927
938
  db.collection("activity").onSnapshot(q => { log = q.docs.map(d => d.data() || {}).filter(x => x.what && x.by !== "ghostwriter").sort((a, b) => String(b.at || "").localeCompare(String(a.at || ""))).slice(0, 8); if (page() === "overview") render(); }, () => {});
928
939
  })();
929
940
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghostwriter-muse-pages",
3
- "version": "17.0.0",
3
+ "version": "18.0.0",
4
4
  "description": "The page code for GhostWriter & the Muse book pages. Loaded by a book's own page; not meant to be used on its own.",
5
5
  "main": "kit.js",
6
6
  "files": [