/** * Every page, server-rendered, script-free. The oracle speaks in a serif and * keeps its bookkeeping in a sans — the voice and the ledger should not look * like the same thing. */ import { calibrate, verdictOnItself, type Calibration } from "./oracle.ts"; import type { Filter, Row } from "./db.ts"; export const escape = (s: string): string => s.replace( /[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c] ?? c, ); const STYLE = ` :root { color-scheme: light dark; --ink: light-dark(#1b1a17, #ece7dd); --dim: light-dark(#6b665c, #9a9387); --rule: light-dark(#1b1a1722, #ece7dd22); --ground: light-dark(#faf7f1, #16151a); font: 17px/1.6 system-ui, sans-serif; } * { box-sizing: border-box; } body { max-width: 44rem; margin: 0 auto; padding: 2rem 1rem 4rem; background: var(--ground); color: var(--ink); } a { color: inherit; } h1 { font: 600 1.5rem/1.2 ui-serif, Georgia, serif; letter-spacing: .02em; margin: 0; } h1 a { text-decoration: none; } .sub { color: var(--dim); margin: .25rem 0 2rem; font-size: .95rem; } .stance { font: 400 1.6rem/1.35 ui-serif, Georgia, serif; margin: .5rem 0 1rem; } .auspice { font: italic 400 1.05rem/1.5 ui-serif, Georgia, serif; color: var(--dim); } .label { font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); } form.ask { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 2rem; } input[type=text] { flex: 1 1 14rem; min-height: 48px; padding: .7rem .9rem; font: inherit; color: var(--ink); background: transparent; border: 1px solid var(--rule); border-radius: .6rem; } button { min-height: 48px; padding: .7rem 1.1rem; font: inherit; cursor: pointer; border: 1px solid var(--rule); border-radius: .6rem; background: var(--ink); color: var(--ground); } button.quiet { background: transparent; color: var(--ink); } .meter { height: 6px; border-radius: 999px; background: var(--rule); overflow: hidden; margin: .4rem 0 1rem; } .meter div { height: 100%; background: var(--ink); } .card { border-top: 1px solid var(--rule); padding: 1.1rem 0; } .card p { margin: .3rem 0; } .q { font-weight: 600; } .row { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; } .tag { font-size: .78rem; padding: .15rem .5rem; border: 1px solid var(--rule); border-radius: 999px; color: var(--dim); } .tag.right { color: light-dark(#166534, #86efac); } .tag.wrong { color: light-dark(#9f1239, #fda4af); } footer { margin-top: 3rem; color: var(--dim); font-size: .85rem; border-top: 1px solid var(--rule); padding-top: 1rem; } nav { display: flex; gap: .75rem; flex-wrap: wrap; margin-bottom: 1.5rem; font-size: .9rem; } ul { padding: 0; margin: 0; list-style: none; } `; interface Chrome { env: string; pull: string | undefined; commit: string; ssh: string | undefined; } function where(chrome: Chrome): string { return chrome.env === "preview" ? `preview of pull #${chrome.pull ?? "?"}` : chrome.env; } function layout(chrome: Chrome, title: string, body: string): string { return ` ${escape(title)}

the oracle

Ask once. It answers with conviction, never twice differently, and keeps score of how often it was right.

${body} `; } function meter(confidence: number): string { return `
`; } function outcomeTag(row: Row): string { if (row.outcome === "right") return `judged right`; if (row.outcome === "wrong") return `judged wrong`; return `unjudged`; } function card(row: Row): string { return `
  • ${escape(row.question)}

    ${escape(row.stance)}

    ${row.confidence}% sure${outcomeTag(row)}${ row.asked_count > 1 ? `asked ${row.asked_count}×` : "" }

  • `; } function calibrationBlock(c: Calibration): string { const line = escape(verdictOnItself(c)); if (c.accuracy === undefined) return `

    its record

    ${line}

    `; return `

    its record

    ${line}

    ${meter(c.accuracy)}

    ${c.right} right of ${c.judged}claimed ${c.claimed}%${ (c.gap ?? 0) > 0 ? `overconfident by ${c.gap}` : (c.gap ?? 0) < 0 ? `modest by ${-(c.gap ?? 0)}` : "square" }

    `; } export function homePage( chrome: Chrome, rows: readonly Row[], scores: readonly { confidence: number; outcome: string }[], ): string { const recent = rows.length === 0 ? `

    No one has asked it anything yet. Be the first; it has been waiting.

    ` : `

    lately

    `; return layout( chrome, "the oracle", `
    ${calibrationBlock(calibrate(scores))} ${recent} `, ); } export function verdictPage(chrome: Chrome, row: Row): string { return layout( chrome, `${row.question} — the oracle`, `

    you asked

    ${escape(row.question)}

    ${escape(row.stance)}

    ${meter(row.confidence)}

    ${row.confidence}% sure${outcomeTag(row)}${ row.asked_count > 1 ? `asked ${row.asked_count}×` : "" }${escape(row.asked_at)}

    the sign it read

    ${escape(row.auspice)}

    how did it turn out?

    ${row.outcome === "unjudged" ? "" : ``}
    `, ); } export function ledgerPage(chrome: Chrome, rows: readonly Row[], filter: Filter): string { const tab = (f: Filter, label: string): string => f === filter ? `${label}` : `${label}`; return layout( chrome, "the ledger — the oracle", ` ${rows.length === 0 ? `

    Nothing here.

    ` : ``}`, ); } export function notFoundPage(chrome: Chrome): string { return layout( chrome, "not found — the oracle", `

    There is no such verdict.

    It may never have been asked, or you may have invented the number.

    `, ); }