diff --git a/trailer.html b/trailer.html
index 728dcaa..8799970 100644
--- a/trailer.html
+++ b/trailer.html
@@ -60,6 +60,16 @@
border-radius:999px;padding:0 6px}
.vobadge{color:var(--muted);font-size:11px;border:1px solid var(--line);
border-radius:999px;padding:0 6px}
+ .spine{border:1px solid var(--line);border-radius:10px;padding:14px 16px;margin:0 0 14px}
+ .spine h4{margin:0 0 8px;font-size:15px}
+ .spine .eng{font-size:14px;border-left:2px solid var(--accent);padding-left:11px;margin:0 0 12px}
+ .spine .kv{font-size:13px;margin:3px 0;color:var(--muted)}
+ .spine .kv b{color:var(--ink);font-weight:600}
+ .spine h5{margin:12px 0 4px;font-size:12px;letter-spacing:.06em;text-transform:uppercase;
+ color:var(--muted)}
+ .spine ul{margin:0;padding-left:18px;font-size:13px}
+ .spine details{margin-top:10px}
+ .spine summary{cursor:pointer;color:var(--muted);font-size:13px}
.gaps{border:1px solid var(--accent);border-radius:10px;padding:14px 16px;margin:0 0 14px}
.gaps h4{margin:0 0 4px;font-size:15px;color:var(--accent)}
.gaps .verdict{font-size:14px;margin:0 0 10px}
@@ -214,7 +224,8 @@
return;
}
if (meta.state === "writing") {
- pane.innerHTML = '
Working. Reading the whole book takes a few minutes.
';
+ pane.innerHTML = 'Working. It reads the whole book, works out what the '
+ + 'story is, and then writes the trailer from that. Several minutes.
';
return;
}
var r = await api("get_draft", { draft_id: id });
@@ -224,6 +235,43 @@
pane.innerHTML = paneHtml(meta, r.draft);
}
+ // The story the writer committed to before writing a shot. This is where a
+ // misreading of the book is visible and cheap to fix; by the time it is
+ // twenty-six shots and a storyboard, it is neither.
+ function spineHtml() {
+ var sp = PKG.spine;
+ if (!sp || typeof sp !== "object") return "";
+ var p = sp.protagonist || {};
+ function ul(items) {
+ return (!items || !items.length) ? ""
+ : '' + items.map(function (x) {
+ return '- ' + esc(typeof x === "string" ? x : JSON.stringify(x)) + '
';
+ }).join("") + '
';
+ }
+ var beats = (sp.beats || []).map(function (b) {
+ return '' + esc(b.what || "")
+ + (b.is_ending ? ' (the ending)' : '')
+ + (b.why_it_matters ? ' ' + esc(b.why_it_matters) + '' : '')
+ + ''; }).join("");
+
+ return 'The story, as the writer worked it out from the book
'
+ + (sp.the_engine ? '
' + esc(sp.the_engine) + '
' : '')
+ + (p.who ? '
who ' + esc(p.who) + '
' : '')
+ + (p.wants ? '
wants ' + esc(p.wants) + '
' : '')
+ + (p.obstacle ? '
in the way ' + esc(p.obstacle) + '
' : '')
+ + (p.cost ? '
cost ' + esc(p.cost) + '
' : '')
+ + (sp.what_a_viewer_must_understand && sp.what_a_viewer_must_understand.length
+ ? '
A viewer must come away knowing
' + ul(sp.what_a_viewer_must_understand) : '')
+ + (sp.moments_to_dramatise && sp.moments_to_dramatise.length
+ ? '
Must be shown, not narrated
' + ul(sp.moments_to_dramatise) : '')
+ + (sp.premise ? '
the premise in full
'
+ + esc(sp.premise) + '
' : '')
+ + (beats ? '
the beats of the book
' + beats + '
' : '')
+ + (sp.withhold ? '
what the trailer is withholding
'
+ + esc(sp.withhold) + '
' : '')
+ + '
';
+ }
+
function barHtml(meta) {
var shots = (PKG.shots || []), cast = (PKG.characters || []);
var undrawn = shots.filter(function (s) { return !s.opening_url; }).length;
@@ -273,7 +321,6 @@
return out.join("");
}
- // What readers understood, and what the writer says it failed to say.
function reviewsHtml(meta) {
var mine = REVIEWS.filter(function (r) {
return r.subject === meta.writer && Number(r.iteration) === Number(meta.iteration); });
@@ -359,7 +406,7 @@
shots.forEach(function (s) { body += shotHtml(s, voice) + insertHtml(s.id); });
return head + probs + '' + barHtml(meta) + '
'
- + reviewsHtml(meta) + castHtml + body;
+ + spineHtml() + reviewsHtml(meta) + castHtml + body;
}
function insertHtml(after) {
@@ -456,11 +503,10 @@
+ '';
}
- async function act(name, payload, msg) {
+ async function act(name, payload) {
var r = await api(name, payload);
if (!r.ok) { showMsg("msg", r.error || "That did not work."); return null; }
hideMsg("msg");
- if (msg) showMsg("msg", msg(r), "ok");
return r;
}