oficina / memoria Public

Clone
git clone https://amadan.net/oficina/memoria

Plain git — no account needed to clone.

Download

Download this file

1{{define "layout"}}<!doctype html>
2{{/* layout — every page's document: the head, the estilo bar, <main>
3 and the footer.
4
5 The bar is estilo's (chrome.Bar, built once per request in
6 chrome.go), in place of the hand-made rst-page-header nav, which
7 wrapped onto two rows at 1440px (97px) with its open Help panel over
8 the Sources and Sign out buttons. estilo's is 52px at every width,
9 signed in or out, with the account always last in the same corner.
10
11 data-theme is written into the first bytes of the response, from the
12 Appearance cookie read server-side (chrome.Appearance), so there is
13 no flash. It is ABSENT for "system", and that is the mechanism:
14 theme.css's toggle is :root[data-theme="light"|"dark"], and with no
15 attribute the browser follows the operating system.
16
17 The <title> is built here and only here, "{part} · {part} · Memoria",
18 so no handler can drift from the suite's separator (spec §10). It
19 used to be written per page, and they said "—" and "·" by turns.
20
21 <meta charset> comes first, before anything that could be read as
22 text. The stylesheets are in the suite's fixed order: tokens, theme,
23 brand, then estilo's base, menu and chrome (and the door's sky), then
24 memoria.css, then the page's own (head). */}}
25<html lang="en"{{with .Frame.Theme}} data-theme="{{.}}"{{end}}>
26<head>
27<meta charset="utf-8">
28<meta name="viewport" content="width=device-width, initial-scale=1">
29<title>{{range .Frame.TitleParts}}{{.}} · {{end}}{{.Frame.Chrome.App.Name}}</title>
30<link rel="icon" type="image/png" sizes="32x32" href="{{asset "static/brand/icon-32.png"}}">
31<link rel="icon" type="image/svg+xml" href="{{asset "static/brand/icon.svg"}}">
32<link rel="apple-touch-icon" sizes="180x180" href="{{asset "static/brand/apple-touch-icon.png"}}">
33<link rel="stylesheet" href="/static/estilo/fonts/v1/fonts.css">
34<link rel="stylesheet" href="{{asset "static/tokens.css"}}">
35<link rel="stylesheet" href="{{asset "static/busy.css"}}">
36{{/* theme.css carries the palette. tokens.css only USES --rst-bg and
37 friends — it defines eleven tokens, none of them colours — so
38 without this link every colour resolves to initial and whole
39 shorthand declarations become invalid at computed-value time. The
40 rastrillo scaffold's layout omits it, which is a scaffold bug, not
41 a choice: the page does not go grey, individual rules vanish. */}}
42<link rel="stylesheet" href="{{asset "static/theme.css"}}">
43<link rel="stylesheet" href="{{asset "static/brand/brand.css"}}">
44<link rel="stylesheet" href="{{asset "static/base.css"}}">
45<link rel="stylesheet" href="{{asset "static/menu.css"}}">
46<link rel="stylesheet" href="{{asset "static/chrome.css"}}">
47<link rel="stylesheet" href="{{asset "static/sky.css"}}">
48<link rel="stylesheet" href="{{asset "static/memoria.css"}}">
49<script defer src="{{asset "static/rastrillo.js"}}"></script>
50<script defer src="{{asset "static/busy.js"}}"></script>
51{{/* chrome.js closes an open bar panel on Escape or an outside click.
52 Nothing depends on it. */}}
53<script defer src="{{asset "static/chrome.js"}}"></script>
54{{/* drop.js is inert on every page but the one carrying [rst-dropzone]:
55 it looks for the zone first and returns if there is none. It is
56 linked here rather than in index.html because the layout is where
57 scripts are linked, and it costs a querySelector to load it twice. */}}
58<script defer src="{{asset "static/drop.js"}}"></script>
59{{/* search.js is the same bargain, keyed on [rst-search]. It shares the
60 results region with drop.js and does not assume it owns it. */}}
61<script defer src="{{asset "static/search.js"}}"></script>
62{{iconAssets}}
63{{block "head" .}}{{end}}
64</head>
65<body>
66{{/* [estilo-shell] has no styling of its own; it is the wrapper a
67 full-height page would key its layout on. */}}
68<div estilo-shell>
69<a rst-skip href="#main">{{.Frame.Chrome.Labels.Skip}}</a>
70{{template "estilo-bar" .Frame.Chrome}}
71<main rst-page id="main">
72{{template "content" .}}
73</main>
74{{/* The footer is said only to somebody signed in: its count and its
75 egress claim are statements about searching (spec §9.2 retires the
76 claim from the sign-in page), and a visitor who cannot search has
77 nothing they are true or false about. */}}
78{{if .Frame.Signed}}{{block "footer" .}}<footer rst-page-footer>
79 {{/* An upload that never navigates cannot change the passage count,
80 so it carries rst-refresh and drop.js swaps it out of a re-fetch
81 of the page. On /add it is the only region that does. drop.js
82 aborts the whole swap if a named region is missing from the
83 answer, so the span is on every signed-in page.
84 The span wraps ONLY the count: the egress claim beside it is not
85 derived from anything and has no business travelling with it.
86
87 Both branches are inside the span, deliberately. Chunks is -1 when
88 the count could not be read at all, and the sentence for that is
89 the one thing here that must survive a refresh: a region that
90 carried only the number would refresh a failure into a confident
91 zero, which is the failure shape this app has already had once. */}}
92 <p rst-muted>
93 <span rst-refresh="passages">{{if lt .Chunks 0}}The passage count is unavailable.{{else}}{{.Chunks}} passage{{if ne .Chunks 1}}s{{end}} indexed.{{end}}</span>
94 {{/* The egress claim, and it depends on the model switch (§8.9). With
95 AI off the strong sentence is true and is stated. With AI on it is
96 FALSE: a search that asks for a postal address sends up to eight
97 passages to TensorX. The first build left the strong sentence on
98 every page while that happened; a review sent a passage and got
99 this footer back in the same response. */}}
100 {{if .ModelOn}}Search is lexical. <strong>AI is on:</strong> a search
101 that asks for a postal address sends up to eight of its passages to
102 TensorX, including while you type. No other document leaves this
103 instance.
104 {{else}}Search is lexical only — no assistant, and <strong>no document ever
105 leaves this instance</strong>.{{end}}
106 </p>
107</footer>{{end}}{{end}}
108</div>
109</body>
110</html>
111{{end}}
112