@nervur-org/dock 0.3.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/GETTING_STARTED.md +128 -0
- package/LICENSE +202 -0
- package/NOTICE +6 -0
- package/README.md +37 -0
- package/api/quo-api.md +196 -0
- package/api/route.ts +227 -0
- package/beings/GLOSSARY.md +118 -0
- package/beings/WORLDS.md +567 -0
- package/beings/avatar.ts +101 -0
- package/beings/carry.ts +159 -0
- package/beings/clock.ts +552 -0
- package/beings/courier.ts +107 -0
- package/beings/desk.ts +128 -0
- package/beings/doorbell.ts +129 -0
- package/beings/envoy.ts +218 -0
- package/beings/index.ts +16 -0
- package/beings/join.ts +51 -0
- package/beings/link.ts +104 -0
- package/beings/look.ts +139 -0
- package/beings/porter.ts +43 -0
- package/beings/presence.ts +39 -0
- package/beings/quo-app-bells.md +280 -0
- package/beings/quo-dock.md +1942 -0
- package/beings/setup.ts +45 -0
- package/beings/side.ts +60 -0
- package/beings/user.ts +459 -0
- package/beings/way.ts +65 -0
- package/cli/bundles.ts +20 -0
- package/cli/client.ts +73 -0
- package/cli/daemon.ts +581 -0
- package/cli/estate/Caddyfile +33 -0
- package/cli/estate/quo.service +35 -0
- package/cli/estate/systems.quo.plist +44 -0
- package/cli/estate.ts +48 -0
- package/cli/folder.ts +27 -0
- package/cli/oauth.ts +32 -0
- package/cli/pilot.ts +38 -0
- package/cli/quo-dock.md +1942 -0
- package/cli/quo.ts +203 -0
- package/cli/stand.ts +160 -0
- package/dist/api/route.d.ts +21 -0
- package/dist/api/route.js +193 -0
- package/dist/beings/avatar.d.ts +32 -0
- package/dist/beings/avatar.js +100 -0
- package/dist/beings/carry.d.ts +12 -0
- package/dist/beings/carry.js +174 -0
- package/dist/beings/clock.d.ts +161 -0
- package/dist/beings/clock.js +528 -0
- package/dist/beings/courier.d.ts +50 -0
- package/dist/beings/courier.js +96 -0
- package/dist/beings/desk.d.ts +53 -0
- package/dist/beings/desk.js +135 -0
- package/dist/beings/doorbell.d.ts +78 -0
- package/dist/beings/doorbell.js +133 -0
- package/dist/beings/envoy.d.ts +54 -0
- package/dist/beings/envoy.js +211 -0
- package/dist/beings/index.d.ts +14 -0
- package/dist/beings/index.js +16 -0
- package/dist/beings/join.d.ts +15 -0
- package/dist/beings/join.js +42 -0
- package/dist/beings/link.d.ts +14 -0
- package/dist/beings/link.js +91 -0
- package/dist/beings/look.d.ts +30 -0
- package/dist/beings/look.js +104 -0
- package/dist/beings/porter.d.ts +14 -0
- package/dist/beings/porter.js +41 -0
- package/dist/beings/presence.d.ts +8 -0
- package/dist/beings/presence.js +21 -0
- package/dist/beings/setup.d.ts +3 -0
- package/dist/beings/setup.js +39 -0
- package/dist/beings/side.d.ts +32 -0
- package/dist/beings/side.js +37 -0
- package/dist/beings/user.d.ts +315 -0
- package/dist/beings/user.js +462 -0
- package/dist/beings/way.d.ts +19 -0
- package/dist/beings/way.js +28 -0
- package/dist/cli/bundles.d.ts +5 -0
- package/dist/cli/bundles.js +17 -0
- package/dist/cli/client.d.ts +15 -0
- package/dist/cli/client.js +58 -0
- package/dist/cli/daemon.d.ts +50 -0
- package/dist/cli/daemon.js +584 -0
- package/dist/cli/estate/Caddyfile +33 -0
- package/dist/cli/estate/quo.service +35 -0
- package/dist/cli/estate/systems.quo.plist +44 -0
- package/dist/cli/estate.d.ts +5 -0
- package/dist/cli/estate.js +50 -0
- package/dist/cli/folder.d.ts +2 -0
- package/dist/cli/folder.js +25 -0
- package/dist/cli/oauth.d.ts +2 -0
- package/dist/cli/oauth.js +32 -0
- package/dist/cli/pilot.d.ts +5 -0
- package/dist/cli/pilot.js +22 -0
- package/dist/cli/quo.d.ts +2 -0
- package/dist/cli/quo.js +201 -0
- package/dist/cli/stand.d.ts +37 -0
- package/dist/cli/stand.js +110 -0
- package/dist/dock/agents.d.ts +102 -0
- package/dist/dock/agents.js +105 -0
- package/dist/dock/apns.d.ts +27 -0
- package/dist/dock/apns.js +98 -0
- package/dist/dock/console.d.ts +6 -0
- package/dist/dock/console.js +20 -0
- package/dist/dock/dialers.d.ts +56 -0
- package/dist/dock/dialers.js +75 -0
- package/dist/dock/faculty.d.ts +24 -0
- package/dist/dock/faculty.js +142 -0
- package/dist/dock/fcm.d.ts +13 -0
- package/dist/dock/fcm.js +77 -0
- package/dist/dock/grants.d.ts +41 -0
- package/dist/dock/grants.js +99 -0
- package/dist/dock/http2.d.ts +4 -0
- package/dist/dock/http2.js +68 -0
- package/dist/dock/index.d.ts +41 -0
- package/dist/dock/index.js +113 -0
- package/dist/dock/local.d.ts +13 -0
- package/dist/dock/local.js +44 -0
- package/dist/dock/location.d.ts +19 -0
- package/dist/dock/location.js +11 -0
- package/dist/dock/notifications.d.ts +38 -0
- package/dist/dock/notifications.js +60 -0
- package/dist/dock/push.d.ts +79 -0
- package/dist/dock/push.js +132 -0
- package/dist/dock/service.d.ts +4 -0
- package/dist/dock/service.js +107 -0
- package/dist/dock/timer.d.ts +52 -0
- package/dist/dock/timer.js +149 -0
- package/dist/dock/webpush.d.ts +12 -0
- package/dist/dock/webpush.js +144 -0
- package/dist/harbor/browser.d.ts +15 -0
- package/dist/harbor/browser.js +82 -0
- package/dist/harbor/capacitor.d.ts +28 -0
- package/dist/harbor/capacitor.js +218 -0
- package/dist/harbor/disk.d.ts +27 -0
- package/dist/harbor/disk.js +249 -0
- package/dist/harbor/edge/alarm.d.ts +10 -0
- package/dist/harbor/edge/alarm.js +38 -0
- package/dist/harbor/edge/edge.d.ts +54 -0
- package/dist/harbor/edge/edge.js +370 -0
- package/dist/harbor/edge/exercise.d.ts +7 -0
- package/dist/harbor/edge/exercise.js +232 -0
- package/dist/harbor/edge/given.d.ts +26 -0
- package/dist/harbor/edge/given.js +42 -0
- package/dist/harbor/edge/platform.d.ts +39 -0
- package/dist/harbor/edge/storage.d.ts +30 -0
- package/dist/harbor/edge/storage.js +180 -0
- package/dist/harbor/edge/worker.d.ts +17 -0
- package/dist/harbor/edge/worker.js +67 -0
- package/dist/harbor/files.d.ts +15 -0
- package/dist/harbor/files.js +220 -0
- package/dist/harbor/http.d.ts +19 -0
- package/dist/harbor/http.js +177 -0
- package/dist/harbor/idb.d.ts +15 -0
- package/dist/harbor/idb.js +0 -0
- package/dist/harbor/quo.d.ts +10 -0
- package/dist/harbor/quo.js +42 -0
- package/dist/harbor/resolve.d.ts +16 -0
- package/dist/harbor/resolve.js +17 -0
- package/dist/harbor/seal.d.ts +3 -0
- package/dist/harbor/seal.js +25 -0
- package/dist/harbor/sealed.d.ts +35 -0
- package/dist/harbor/sealed.js +162 -0
- package/dist/harbor/tauri.d.ts +16 -0
- package/dist/harbor/tauri.js +59 -0
- package/dist/harbor/ward.d.ts +9 -0
- package/dist/harbor/ward.js +15 -0
- package/dist/human/app.d.ts +32 -0
- package/dist/human/app.js +527 -0
- package/dist/human/apps.d.ts +10 -0
- package/dist/human/apps.js +29 -0
- package/dist/human/dom.d.ts +2 -0
- package/dist/human/dom.js +15 -0
- package/dist/human/door.d.ts +19 -0
- package/dist/human/door.js +92 -0
- package/dist/human/guest.d.ts +3 -0
- package/dist/human/guest.js +33 -0
- package/dist/human/html.d.ts +55 -0
- package/dist/human/html.js +451 -0
- package/dist/human/local.d.ts +7 -0
- package/dist/human/local.js +10 -0
- package/dist/human/mark.d.ts +8 -0
- package/dist/human/mark.js +47 -0
- package/dist/human/move.d.ts +17 -0
- package/dist/human/move.js +90 -0
- package/dist/human/screen.d.ts +19 -0
- package/dist/human/screen.js +119 -0
- package/dist/human/style.d.ts +2 -0
- package/dist/human/style.js +60 -0
- package/dist/human/tab.bundle.txt +4775 -0
- package/dist/human/tab.d.ts +15 -0
- package/dist/human/tab.js +409 -0
- package/dist/human/tree.d.ts +50 -0
- package/dist/human/tree.js +157 -0
- package/dist/human/wake.d.ts +34 -0
- package/dist/human/wake.js +179 -0
- package/dist/human/web.d.ts +33 -0
- package/dist/human/web.js +184 -0
- package/dist/human/worker.bundle.txt +3868 -0
- package/dist/human/worker.d.ts +1 -0
- package/dist/human/worker.js +81 -0
- package/dist/human/worlds.d.ts +24 -0
- package/dist/human/worlds.js +99 -0
- package/dist/mcp/agent.d.ts +10 -0
- package/dist/mcp/agent.js +78 -0
- package/dist/mcp/allow.d.ts +20 -0
- package/dist/mcp/allow.js +88 -0
- package/dist/mcp/http.d.ts +27 -0
- package/dist/mcp/http.js +92 -0
- package/dist/mcp/oauth.d.ts +91 -0
- package/dist/mcp/oauth.js +241 -0
- package/dist/mcp/route.d.ts +15 -0
- package/dist/mcp/route.js +42 -0
- package/dist/mcp/runner.d.ts +45 -0
- package/dist/mcp/runner.js +99 -0
- package/dist/mcp/server.d.ts +11 -0
- package/dist/mcp/server.js +102 -0
- package/dock/agents.ts +121 -0
- package/dock/apns.ts +138 -0
- package/dock/console.ts +23 -0
- package/dock/dialers.ts +85 -0
- package/dock/faculty.ts +148 -0
- package/dock/fcm.ts +103 -0
- package/dock/grants.ts +111 -0
- package/dock/http2.ts +70 -0
- package/dock/index.ts +133 -0
- package/dock/local.ts +48 -0
- package/dock/location.ts +22 -0
- package/dock/notifications.ts +67 -0
- package/dock/push.ts +161 -0
- package/dock/quo-app-bells.md +280 -0
- package/dock/quo-dock.md +1942 -0
- package/dock/service.ts +100 -0
- package/dock/timer.ts +174 -0
- package/dock/webpush.ts +182 -0
- package/harbor/browser.ts +97 -0
- package/harbor/capacitor.ts +223 -0
- package/harbor/disk.ts +237 -0
- package/harbor/edge/alarm.ts +48 -0
- package/harbor/edge/edge.ts +407 -0
- package/harbor/edge/exercise.ts +241 -0
- package/harbor/edge/given.ts +106 -0
- package/harbor/edge/platform.d.ts +39 -0
- package/harbor/edge/storage.ts +179 -0
- package/harbor/edge/text.d.ts +15 -0
- package/harbor/edge/worker.ts +70 -0
- package/harbor/edge/wrangler.toml +30 -0
- package/harbor/files.ts +221 -0
- package/harbor/http.ts +188 -0
- package/harbor/idb.ts +0 -0
- package/harbor/quo-harbor.md +850 -0
- package/harbor/quo.ts +44 -0
- package/harbor/resolve.ts +31 -0
- package/harbor/seal.ts +26 -0
- package/harbor/sealed.ts +183 -0
- package/harbor/tauri.ts +79 -0
- package/harbor/ward.ts +28 -0
- package/human/app.ts +580 -0
- package/human/apps.ts +47 -0
- package/human/dom.ts +21 -0
- package/human/door.ts +113 -0
- package/human/guest.ts +34 -0
- package/human/html.ts +490 -0
- package/human/local.ts +30 -0
- package/human/mark.ts +53 -0
- package/human/move.ts +122 -0
- package/human/quo-human.md +1042 -0
- package/human/screen.ts +136 -0
- package/human/style.ts +63 -0
- package/human/tab.bundle.txt +4775 -0
- package/human/tab.ts +446 -0
- package/human/tree.ts +217 -0
- package/human/wake.ts +191 -0
- package/human/web.ts +259 -0
- package/human/worker.bundle.txt +3868 -0
- package/human/worker.ts +124 -0
- package/human/worlds.ts +127 -0
- package/mcp/agent.ts +94 -0
- package/mcp/allow.ts +131 -0
- package/mcp/http.ts +92 -0
- package/mcp/oauth.ts +270 -0
- package/mcp/quo-mcp.md +343 -0
- package/mcp/route.ts +45 -0
- package/mcp/runner.ts +136 -0
- package/mcp/server.ts +101 -0
- package/package.json +121 -0
package/human/screen.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// The human side: one avatar, one surface. The surface is the least a
|
|
3
|
+
// screen can be: it shows a page and hands back a submitted form, and that
|
|
4
|
+
// is all this side asks of a terrain. A DOM is one surface; a test is
|
|
5
|
+
// another. The side keeps the model, speaks it as a page after every change
|
|
6
|
+
// through `html.ts`, calls the avatar when a form comes back, and re-asks
|
|
7
|
+
// her describe after each call, so a digest that moved is a page that
|
|
8
|
+
// moved. A push is appended and shown the moment it lands.
|
|
9
|
+
import { digest } from '@nervur-org/nervur';
|
|
10
|
+
import type { Blueprint, JsonObject } from '@nervur-org/nervur';
|
|
11
|
+
import { word, type Serving, type Subject } from '../beings/side.ts';
|
|
12
|
+
import { isInvitation } from '@nervur-org/nervur';
|
|
13
|
+
import type { Invitation } from '@nervur-org/nervur';
|
|
14
|
+
import { page, values, hintFor, mine, asks, standing, stands, type Model, type Raw } from './html.ts';
|
|
15
|
+
import { sanitiseTree, answersIn } from './tree.ts';
|
|
16
|
+
import { groups, sanitise } from '../beings/look.ts';
|
|
17
|
+
import { isSilence, isWord } from '@nervur-org/nervur';
|
|
18
|
+
|
|
19
|
+
export type Surface = {
|
|
20
|
+
show(html: string): void;
|
|
21
|
+
// The surface calls this when a form is submitted: the ask's name and
|
|
22
|
+
// the fields as strings. Set once by the side.
|
|
23
|
+
onSubmit: ((ask: string, raw: Raw) => void) | undefined;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// `after` runs after every ask the side makes, a submitted form, her
|
|
27
|
+
// describe, her look and the read-only asks run on open alike, as it does
|
|
28
|
+
// for the model side: every ask rotates her keys, and a harbor that must
|
|
29
|
+
// write what the ward changed hooks it. A side that saved only after a form
|
|
30
|
+
// would bring her back from a reload with a stale count, and the far door
|
|
31
|
+
// would refuse her. `admit` is what to do
|
|
32
|
+
// with an answer that is an invitation: a guest at a world's door is let in
|
|
33
|
+
// by it, and a side with no `admit` shows it as any answer. `focus` is one
|
|
34
|
+
// standing she carries shown as the whole page, the page at
|
|
35
|
+
// `web./<ward>/<being>`, and `at` the world's page address the sections and a
|
|
36
|
+
// focused page link to.
|
|
37
|
+
// `ended` is called when her describe says the relation is over, so a shell
|
|
38
|
+
// can offer the one act left, leaving. It is told and never obeyed: the
|
|
39
|
+
// shell decides what to put in front of the human, and nothing here drops a
|
|
40
|
+
// ward.
|
|
41
|
+
export type Options = { after?: () => Promise<void>; notice?: string; admit?: (invitation: Invitation) => Promise<void>; focus?: string; at?: string; ended?: () => Promise<void> };
|
|
42
|
+
export async function screenSide(avatar: Subject, surface: Surface, options: Options = {}): Promise<Serving & { model: Model; refresh(): Promise<void> }> {
|
|
43
|
+
const after = options.after ?? (async () => {});
|
|
44
|
+
const notice = options.notice ?? '';
|
|
45
|
+
const model: Model = { blueprint: null, look: {}, tree: null, pages: {}, notice, standing: 'in', answers: {}, pushes: [], ...(options.focus !== undefined ? { focus: options.focus } : {}), ...(options.at !== undefined ? { at: options.at } : {}) };
|
|
46
|
+
let seen: string | null = null;
|
|
47
|
+
const show = () => surface.show(page(model));
|
|
48
|
+
|
|
49
|
+
// Her describe, again: the page follows the digest.
|
|
50
|
+
const refresh = async () => {
|
|
51
|
+
const bp = await avatar.tools();
|
|
52
|
+
if ('error' in bp && !('asks' in bp)) {
|
|
53
|
+
// the last page she gave stays, with the answers under it, and the
|
|
54
|
+
// notice says where the human stands now: her relation ended, the
|
|
55
|
+
// world away for the moment, or her own error, told apart because
|
|
56
|
+
// only one of the three is over
|
|
57
|
+
model.standing = standing(bp.error);
|
|
58
|
+
model.notice = stands(bp.error);
|
|
59
|
+
if (model.standing === 'ended') await options.ended?.();
|
|
60
|
+
} else {
|
|
61
|
+
model.standing = 'in';
|
|
62
|
+
const d = await digest(bp as Blueprint);
|
|
63
|
+
const moved = d !== seen;
|
|
64
|
+
if (moved) {
|
|
65
|
+
seen = d;
|
|
66
|
+
model.blueprint = bp as Blueprint;
|
|
67
|
+
for (const k of Object.keys(model.answers)) if (!(bp as Blueprint).asks.some((a) => a.name === k)) delete model.answers[k];
|
|
68
|
+
// her look, once per digest: how she wants her page painted, and what each ask is
|
|
69
|
+
if ((bp as Blueprint).asks.some((a) => a.name === 'look')) {
|
|
70
|
+
const l = await avatar.call('look');
|
|
71
|
+
model.look = isSilence(l) || isWord(l) ? {} : sanitise(l);
|
|
72
|
+
} else model.look = {};
|
|
73
|
+
}
|
|
74
|
+
// her page, after every ask: a tree of values from what she holds now, or nothing and her asks
|
|
75
|
+
// are forms. A cell moved is a page moved, and her describe need not have; so the answers the
|
|
76
|
+
// page shows are run again with it, and the page never stands more than one ask behind her
|
|
77
|
+
const trees = () => [model.tree ? answersIn(model.tree) : [], ...Object.entries(model.pages).map(([id, t]) => (t ? answersIn(t).map((n) => `${id}-${n}`) : []))].flat();
|
|
78
|
+
const shows = new Set(trees());
|
|
79
|
+
const tree = async (name: string) => {
|
|
80
|
+
const t = await avatar.call(name);
|
|
81
|
+
return isSilence(t) || isWord(t) ? null : sanitiseTree(t);
|
|
82
|
+
};
|
|
83
|
+
model.tree = (bp as Blueprint).asks.some((a) => a.name === 'page') ? await tree('page') : null;
|
|
84
|
+
// and the page of every standing she carries, the same way, painted in that standing's section;
|
|
85
|
+
// a name a carried page uses is one of that standing's asks, carried, and nothing else
|
|
86
|
+
model.pages = {};
|
|
87
|
+
for (const [id, g] of Object.entries(groups(bp as Blueprint))) if (typeof g.page === 'string' && (bp as Blueprint).asks.some((a) => a.name === g.page)) model.pages[id] = await tree(g.page);
|
|
88
|
+
const wanted = new Set(trees());
|
|
89
|
+
for (const n of shows) if (wanted.has(n)) delete model.answers[n];
|
|
90
|
+
// a read-only ask that needs nothing typed is run on her behalf once per digest, and one her page
|
|
91
|
+
// shows the answer of after every ask, so the page opens and stays with what it shows
|
|
92
|
+
for (const a of (bp as Blueprint).asks) {
|
|
93
|
+
// What the side fills for itself is not something a human has to
|
|
94
|
+
// type, so an ask whose only required argument is the moment has
|
|
95
|
+
// nothing left to ask and runs like one with no arguments at all.
|
|
96
|
+
const needs = asks(a).length > 0;
|
|
97
|
+
const run = wanted.has(a.name) || (moved && hintFor(bp as Blueprint, model.look, a.name).readOnly);
|
|
98
|
+
if (run && !needs && !(a.name in model.answers)) model.answers[a.name] = word(await avatar.call(a.name, mine(a)));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
await after();
|
|
102
|
+
show();
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
surface.onSubmit = (name, raw) => void submit(name, raw);
|
|
106
|
+
const submit = async (name: string, raw: Raw) => {
|
|
107
|
+
const ask = model.blueprint?.asks.find((a) => a.name === name);
|
|
108
|
+
if (!ask) return;
|
|
109
|
+
const v = values(ask, raw);
|
|
110
|
+
if ('error' in v) {
|
|
111
|
+
model.answers[name] = { word: 'error', value: { error: v.error } };
|
|
112
|
+
return show();
|
|
113
|
+
}
|
|
114
|
+
const out = await avatar.call(name, v.args);
|
|
115
|
+
await after();
|
|
116
|
+
if (options.admit && isInvitation(out)) return options.admit(out);
|
|
117
|
+
model.answers[name] = word(out);
|
|
118
|
+
await refresh();
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const ear = (object: JsonObject) => {
|
|
122
|
+
model.pushes.push(object);
|
|
123
|
+
show();
|
|
124
|
+
};
|
|
125
|
+
avatar.ears.add(ear);
|
|
126
|
+
|
|
127
|
+
await refresh();
|
|
128
|
+
return {
|
|
129
|
+
model,
|
|
130
|
+
refresh,
|
|
131
|
+
close: async () => {
|
|
132
|
+
avatar.ears.delete(ear);
|
|
133
|
+
surface.onSubmit = undefined;
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
package/human/style.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// The stylesheet: the kit, and then what the screen alone has.
|
|
3
|
+
//
|
|
4
|
+
// One stylesheet for every screen there is, whatever carries it: the web
|
|
5
|
+
// route serves it beside the tab's bundle, and the desk app's window
|
|
6
|
+
// carries it in its own. A screen that looked like another product on
|
|
7
|
+
// another terrain would be two designs to keep and one of them always
|
|
8
|
+
// behind. It is one string and not four files because a screen builds its
|
|
9
|
+
// own page and has nowhere to put a link.
|
|
10
|
+
//
|
|
11
|
+
// The kit brings the tokens, its own light and dark face, the reset, the
|
|
12
|
+
// baseline, the bare controls and every piece a page is made of. The
|
|
13
|
+
// painter emits those pieces and nothing else, so what follows is small:
|
|
14
|
+
// the page's one column, and the few things the shells alone have, the
|
|
15
|
+
// door, a local being's section, moving a world, the daemon's state line.
|
|
16
|
+
// Nothing below mints a colour or a size; every one is a slot or a scale,
|
|
17
|
+
// so a face swapped for another swaps the screen with it. A far being's
|
|
18
|
+
// look sets the kit's slots on her own section, and the kit does the rest.
|
|
19
|
+
import { CSS as KIT, TOKENS, BASE, COMPONENTS } from '@nervur-org/ui/css';
|
|
20
|
+
|
|
21
|
+
const SCREEN = [
|
|
22
|
+
// One column that is a phone first and a desk after: the same page, more
|
|
23
|
+
// air. The insets are the phone's: an app fills the screen, corners and
|
|
24
|
+
// camera and all, so the first line of the page would otherwise sit under
|
|
25
|
+
// the clock. `env()` is zero everywhere else, so a tab and a window are
|
|
26
|
+
// laid out by the gutter alone.
|
|
27
|
+
'body{max-width:var(--nv-page-w-md);margin-inline:auto;padding-inline:calc(var(--nv-page-gutter) + env(safe-area-inset-left)) calc(var(--nv-page-gutter) + env(safe-area-inset-right));padding-block:env(safe-area-inset-top) calc(var(--nv-space-8) + env(safe-area-inset-bottom))}',
|
|
28
|
+
'main{display:flex;flex-direction:column;gap:var(--nv-space-4)}',
|
|
29
|
+
// a subsection holding a form and the answer under it, and the sections
|
|
30
|
+
// of one being's page after another
|
|
31
|
+
'main>.nv-stack>section+section,main>.nv-stack>section+.nv-standing,main>.nv-stack>.nv-standing+section{margin-block-start:var(--nv-space-3)}',
|
|
32
|
+
// a far being's logo beside her name, and the way to her own page
|
|
33
|
+
'img.logo{height:var(--nv-icon-lg)}a.open,a.back{text-decoration:none;font-weight:var(--nv-weight-medium)}a.back::before{content:"\\2190 "}',
|
|
34
|
+
// A place the side vouches for reads as a place to go. One it will not
|
|
35
|
+
// vouch for reads as what it is, an address the human may copy and weigh,
|
|
36
|
+
// and it is deliberately not underlined and not the accent: it must never
|
|
37
|
+
// look like something the page is willing to stand behind. A link that
|
|
38
|
+
// leaves the world wears the origin it goes to, out of the anchor's own
|
|
39
|
+
// data, so a human reads where she is going on the page rather than in a
|
|
40
|
+
// status bar she may never look at.
|
|
41
|
+
'a.link.out::after{content:" \\2197 " attr(data-origin);font-size:var(--nv-text-sm);color:var(--nv-color-fg-muted)}span.link.away{border:1px dashed var(--nv-color-border-strong)}',
|
|
42
|
+
// a being of the world running in the tab: her own section under the far page
|
|
43
|
+
'section.local{border-block-start:1px solid var(--nv-color-border);margin-block:var(--nv-space-5) 0;padding-block-start:var(--nv-space-3)}',
|
|
44
|
+
// moving a world to another device, and leaving one: quiet, at the foot
|
|
45
|
+
// of the page, and the offer wrapping rather than running off the side,
|
|
46
|
+
// since it is one long word
|
|
47
|
+
'.move,section.held{display:flex;flex-direction:column;gap:var(--nv-space-2);align-items:flex-start;border-block-start:1px solid var(--nv-color-border);margin-block:var(--nv-space-7) 0;padding-block-start:var(--nv-space-3);font-size:var(--nv-text-sm);color:var(--nv-color-fg-muted)}.move .invitation,section.held .invitation{font-family:var(--nv-font-mono);font-size:var(--nv-text-xs);overflow-wrap:anywhere}',
|
|
48
|
+
'section.held .worlds{display:flex;flex-wrap:wrap;gap:var(--nv-space-2)}',
|
|
49
|
+
// a foot the shell hid stays hidden: a class that lays it out would otherwise beat the attribute
|
|
50
|
+
'.move[hidden],section.held[hidden]{display:none}',
|
|
51
|
+
// the door page: one thing on air, vertically centred in the window
|
|
52
|
+
'main[data-door]{min-height:70vh;justify-content:center}main[data-door] .nv-picture{width:var(--nv-space-7);height:var(--nv-space-7);color:var(--nv-color-accent)}',
|
|
53
|
+
// the desk window: the state of the daemon behind the page, a line, and nothing when all is well
|
|
54
|
+
'p.state:empty{display:none}',
|
|
55
|
+
].join('');
|
|
56
|
+
|
|
57
|
+
export const CSS = `${KIT}\n${SCREEN}`;
|
|
58
|
+
|
|
59
|
+
// The same screen for a world that wears a design of its own: the kit
|
|
60
|
+
// without its own face, since the kit's contract says a surface loads the
|
|
61
|
+
// default face or a design's and never both, and the design's stylesheet
|
|
62
|
+
// is linked after it by the route that serves it.
|
|
63
|
+
export const BARE = `${TOKENS}\n${BASE}\n${COMPONENTS}\n${SCREEN}`;
|