@telepath-computer/television 0.1.84 → 0.1.85
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/dist/cli.cjs +83 -137
- package/dist/skills/{television/artifact-types/calendar.md → artifact-calendar/SKILL.md} +20 -12
- package/dist/skills/artifact-calendar/calendar.css +1 -0
- package/dist/skills/artifact-calendar/calendar.js +716 -0
- package/dist/skills/{television/html-house-style.md → artifact-calendar/house-style.md} +7 -7
- package/dist/skills/{television/artifact-types/table.md → artifact-table/SKILL.md} +4 -1
- package/dist/skills/artifact-table/house-style.md +67 -0
- package/dist/skills/television/SKILL.md +428 -12
- package/dist/web/assets/index-D3-COwxd.js +522 -0
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
- package/dist/skills/television/.skill-manifest.json +0 -29
- package/dist/skills/television/artifact-workflow.md +0 -285
- package/dist/skills/television/cli-capabilities.md +0 -145
- package/dist/web/assets/index-BfzWRMnk.js +0 -522
package/dist/cli.cjs
CHANGED
|
@@ -50093,18 +50093,10 @@ function findCardIDInNode(node, artifactID) {
|
|
|
50093
50093
|
var import_meta = {};
|
|
50094
50094
|
var DAEMON_NAME = "com.television.server";
|
|
50095
50095
|
var MAX_PORT = 65535;
|
|
50096
|
-
var HELP_POINTER = "
|
|
50096
|
+
var HELP_POINTER = "Television guidance is split across bundled skills. For screens, lifecycle work, and the `tv` CLI, read the `television` skill. For artifact authoring, use `tv skills install` or `tv skills show`, then let the matching `artifact-*` skill guide the output.";
|
|
50097
50097
|
var CLIDirectiveError = class extends Error {
|
|
50098
50098
|
name = "CLIDirectiveError";
|
|
50099
50099
|
};
|
|
50100
|
-
var CLISilentExitError = class extends Error {
|
|
50101
|
-
name = "CLISilentExitError";
|
|
50102
|
-
silentExitCode;
|
|
50103
|
-
constructor(silentExitCode = 1) {
|
|
50104
|
-
super("");
|
|
50105
|
-
this.silentExitCode = silentExitCode;
|
|
50106
|
-
}
|
|
50107
|
-
};
|
|
50108
50100
|
function writeJSON(output, value) {
|
|
50109
50101
|
output.write(`${JSON.stringify(value)}
|
|
50110
50102
|
`);
|
|
@@ -50131,8 +50123,8 @@ function resolveVercelSkillsInstallerBin() {
|
|
|
50131
50123
|
return localRequire.resolve("skills/bin/cli.mjs");
|
|
50132
50124
|
}
|
|
50133
50125
|
function readCLIVersion() {
|
|
50134
|
-
if ("0.1.
|
|
50135
|
-
return "0.1.
|
|
50126
|
+
if ("0.1.85".length > 0) {
|
|
50127
|
+
return "0.1.85";
|
|
50136
50128
|
}
|
|
50137
50129
|
const devPackageJsonPath = import_node_path7.default.join(getDevPackageDir(), "package.json");
|
|
50138
50130
|
if (!(0, import_node_fs4.existsSync)(devPackageJsonPath)) {
|
|
@@ -50140,123 +50132,80 @@ function readCLIVersion() {
|
|
|
50140
50132
|
}
|
|
50141
50133
|
return JSON.parse((0, import_node_fs4.readFileSync)(devPackageJsonPath, "utf8")).version;
|
|
50142
50134
|
}
|
|
50143
|
-
|
|
50144
|
-
|
|
50145
|
-
|
|
50146
|
-
|
|
50147
|
-
|
|
50148
|
-
|
|
50149
|
-
|
|
50150
|
-
|
|
50151
|
-
|
|
50152
|
-
}
|
|
50153
|
-
|
|
50154
|
-
const
|
|
50155
|
-
|
|
50135
|
+
var FRONTMATTER_DELIMITER = "---\n";
|
|
50136
|
+
var FRONTMATTER_DELIMITER_LENGTH = FRONTMATTER_DELIMITER.length;
|
|
50137
|
+
function splitFrontmatter(text) {
|
|
50138
|
+
if (!text.startsWith(FRONTMATTER_DELIMITER)) {
|
|
50139
|
+
return { frontmatter: {}, body: text };
|
|
50140
|
+
}
|
|
50141
|
+
const closing = text.indexOf("\n---", FRONTMATTER_DELIMITER_LENGTH);
|
|
50142
|
+
if (closing === -1) {
|
|
50143
|
+
return { frontmatter: {}, body: text };
|
|
50144
|
+
}
|
|
50145
|
+
const block = text.slice(FRONTMATTER_DELIMITER_LENGTH, closing);
|
|
50146
|
+
const after = text.slice(closing + FRONTMATTER_DELIMITER_LENGTH);
|
|
50147
|
+
const body = after.startsWith("\n") ? after.slice(1) : after;
|
|
50148
|
+
const frontmatter = {};
|
|
50149
|
+
for (const rawLine of block.split("\n")) {
|
|
50150
|
+
const line = rawLine.trim();
|
|
50151
|
+
if (line === "" || line.startsWith("#")) continue;
|
|
50152
|
+
const colon = line.indexOf(":");
|
|
50153
|
+
if (colon === -1) continue;
|
|
50154
|
+
const key = line.slice(0, colon).trim();
|
|
50155
|
+
let value = line.slice(colon + 1).trim();
|
|
50156
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
50157
|
+
value = value.slice(1, -1);
|
|
50158
|
+
}
|
|
50159
|
+
frontmatter[key] = value;
|
|
50160
|
+
}
|
|
50161
|
+
return { frontmatter, body };
|
|
50162
|
+
}
|
|
50163
|
+
function readBundledSkill(skillRoot) {
|
|
50164
|
+
const skillMarkdownPath = import_node_path7.default.join(skillRoot, "SKILL.md");
|
|
50165
|
+
if (!(0, import_node_fs4.existsSync)(skillMarkdownPath)) {
|
|
50166
|
+
throw new Error(`Bundled skill is missing SKILL.md at ${skillMarkdownPath}.`);
|
|
50167
|
+
}
|
|
50168
|
+
const markdown = (0, import_node_fs4.readFileSync)(skillMarkdownPath, "utf8");
|
|
50169
|
+
const { frontmatter } = splitFrontmatter(markdown);
|
|
50170
|
+
const name = frontmatter.name?.trim();
|
|
50171
|
+
const description = frontmatter.description?.trim();
|
|
50172
|
+
if (!name || !description) {
|
|
50173
|
+
throw new Error(`Bundled skill has invalid frontmatter at ${skillMarkdownPath}.`);
|
|
50174
|
+
}
|
|
50175
|
+
return { name, description, markdown, root: skillRoot };
|
|
50176
|
+
}
|
|
50177
|
+
function listBundledSkills(collectionRoot) {
|
|
50178
|
+
return (0, import_node_fs4.readdirSync)(collectionRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => readBundledSkill(import_node_path7.default.join(collectionRoot, entry.name))).sort((a, b) => a.name.localeCompare(b.name));
|
|
50179
|
+
}
|
|
50180
|
+
function resolveBundledSkill(collectionRoot, skillName) {
|
|
50181
|
+
const skillRoot = import_node_path7.default.join(collectionRoot, skillName);
|
|
50182
|
+
if (!(0, import_node_fs4.existsSync)(skillRoot)) {
|
|
50183
|
+
throw createDirectiveError(`tv skills show could not find bundled skill \`${skillName}\`.`);
|
|
50184
|
+
}
|
|
50185
|
+
return readBundledSkill(skillRoot);
|
|
50156
50186
|
}
|
|
50157
50187
|
function buildAgentHelpNote() {
|
|
50158
50188
|
return [
|
|
50159
50189
|
"",
|
|
50160
50190
|
"Agent workflow note:",
|
|
50161
|
-
"
|
|
50162
|
-
"
|
|
50163
|
-
"
|
|
50164
|
-
"
|
|
50165
|
-
" Key relative paths (arguments to `tv skills show`):",
|
|
50166
|
-
" SKILL.md \u2014 mental model and artifact-vs-chat decision",
|
|
50167
|
-
" cli-capabilities.md \u2014 commands, focus, screen placement",
|
|
50168
|
-
" artifact-workflow.md \u2014 artifact lifecycle",
|
|
50169
|
-
" html-house-style.md \u2014 HTML artifact authoring",
|
|
50170
|
-
" Known artifact-type relative paths:",
|
|
50171
|
-
formatArtifactTypeDocsList()
|
|
50191
|
+
" Television guidance is split across bundled skills.",
|
|
50192
|
+
" For screens, lifecycle work, and the `tv` CLI, read `television`.",
|
|
50193
|
+
" For artifact authoring, install or inspect the bundled skills with `tv skills install` or `tv skills show`.",
|
|
50194
|
+
" Then use the matching `artifact-*` skill, such as `artifact-calendar` or `artifact-table`."
|
|
50172
50195
|
].join("\n");
|
|
50173
50196
|
}
|
|
50174
50197
|
function buildArtifactWorkflowHelpNote(includeHTMLNote) {
|
|
50175
50198
|
const lines = [
|
|
50176
50199
|
"",
|
|
50177
50200
|
"Agent note:",
|
|
50178
|
-
"
|
|
50179
|
-
" If the skill is not installed, read it with `tv skills show artifact-workflow.md`."
|
|
50201
|
+
" For Television lifecycle work, read `television`."
|
|
50180
50202
|
];
|
|
50181
50203
|
if (includeHTMLNote) {
|
|
50182
|
-
lines.push(
|
|
50183
|
-
|
|
50184
|
-
);
|
|
50185
|
-
lines.push(" Known artifact-type relative paths (arguments to `tv skills show`):");
|
|
50186
|
-
lines.push(formatArtifactTypeDocsList());
|
|
50204
|
+
lines.push(" For artifact authoring, install or inspect the bundled skills with `tv skills install` or `tv skills show`.");
|
|
50205
|
+
lines.push(" Then use the matching `artifact-*` skill, such as `artifact-calendar` or `artifact-table`.");
|
|
50187
50206
|
}
|
|
50188
50207
|
return lines.join("\n");
|
|
50189
50208
|
}
|
|
50190
|
-
function getBundledTelevisionSkillRoot(bundledTelevisionSkillsCollectionRoot) {
|
|
50191
|
-
return import_node_path7.default.join(bundledTelevisionSkillsCollectionRoot, "television");
|
|
50192
|
-
}
|
|
50193
|
-
function readSkillManifest(skillRoot) {
|
|
50194
|
-
const empty = { version: void 0, descriptions: /* @__PURE__ */ new Map() };
|
|
50195
|
-
const manifestPath = import_node_path7.default.join(skillRoot, ".skill-manifest.json");
|
|
50196
|
-
if (!(0, import_node_fs4.existsSync)(manifestPath)) return empty;
|
|
50197
|
-
try {
|
|
50198
|
-
const raw = (0, import_node_fs4.readFileSync)(manifestPath, "utf8");
|
|
50199
|
-
const parsed = JSON.parse(raw);
|
|
50200
|
-
if (typeof parsed !== "object" || parsed === null) return empty;
|
|
50201
|
-
const root = parsed;
|
|
50202
|
-
const version2 = typeof root.version === "string" ? root.version : void 0;
|
|
50203
|
-
const files = Array.isArray(root.files) ? root.files : [];
|
|
50204
|
-
const entries = [];
|
|
50205
|
-
for (const entry of files) {
|
|
50206
|
-
if (typeof entry === "object" && entry !== null && typeof entry.path === "string" && typeof entry.description === "string") {
|
|
50207
|
-
entries.push([entry.path, entry.description]);
|
|
50208
|
-
}
|
|
50209
|
-
}
|
|
50210
|
-
return { version: version2, descriptions: new Map(entries) };
|
|
50211
|
-
} catch {
|
|
50212
|
-
return empty;
|
|
50213
|
-
}
|
|
50214
|
-
}
|
|
50215
|
-
function listSkillFiles(skillRoot, prefix = "") {
|
|
50216
|
-
const entries = (0, import_node_fs4.readdirSync)(skillRoot, { withFileTypes: true }).filter((entry) => !entry.name.startsWith(".")).sort((a, b) => a.name.localeCompare(b.name));
|
|
50217
|
-
const files = [];
|
|
50218
|
-
for (const entry of entries) {
|
|
50219
|
-
const relativePath = prefix === "" ? entry.name : import_node_path7.default.posix.join(prefix, entry.name);
|
|
50220
|
-
const absolutePath = import_node_path7.default.join(skillRoot, entry.name);
|
|
50221
|
-
if (entry.isDirectory()) {
|
|
50222
|
-
files.push(...listSkillFiles(absolutePath, relativePath));
|
|
50223
|
-
continue;
|
|
50224
|
-
}
|
|
50225
|
-
files.push(relativePath);
|
|
50226
|
-
}
|
|
50227
|
-
return files;
|
|
50228
|
-
}
|
|
50229
|
-
function resolveSkillFilePath(skillRoot, relativePath) {
|
|
50230
|
-
const normalized = import_node_path7.default.posix.normalize(relativePath);
|
|
50231
|
-
if (normalized.startsWith("../") || normalized === ".." || import_node_path7.default.isAbsolute(relativePath)) {
|
|
50232
|
-
return { kind: "invalid-path" };
|
|
50233
|
-
}
|
|
50234
|
-
const resolved = import_node_path7.default.join(skillRoot, normalized);
|
|
50235
|
-
const relativeResolved = import_node_path7.default.relative(skillRoot, resolved);
|
|
50236
|
-
if (relativeResolved.startsWith("..") || import_node_path7.default.isAbsolute(relativeResolved)) {
|
|
50237
|
-
return { kind: "invalid-path" };
|
|
50238
|
-
}
|
|
50239
|
-
if (!(0, import_node_fs4.existsSync)(resolved)) {
|
|
50240
|
-
return { kind: "not-found" };
|
|
50241
|
-
}
|
|
50242
|
-
return { kind: "ok", absolutePath: resolved };
|
|
50243
|
-
}
|
|
50244
|
-
function writeSkillListing(stdout, skillRoot) {
|
|
50245
|
-
const manifest = readSkillManifest(skillRoot);
|
|
50246
|
-
if (manifest.version !== void 0) {
|
|
50247
|
-
writeLine(stdout, `Television skill content version: ${manifest.version}`);
|
|
50248
|
-
writeLine(stdout, "");
|
|
50249
|
-
}
|
|
50250
|
-
writeLine(stdout, "Relative paths inside the bundled `television` skill:");
|
|
50251
|
-
writeLine(stdout, "");
|
|
50252
|
-
for (const file2 of listSkillFiles(skillRoot)) {
|
|
50253
|
-
const description = manifest.descriptions.get(file2);
|
|
50254
|
-
writeLine(stdout, description ? `${file2} \u2014 ${description}` : file2);
|
|
50255
|
-
}
|
|
50256
|
-
writeLine(stdout, "");
|
|
50257
|
-
writeLine(stdout, `Television skill root: ${skillRoot}`);
|
|
50258
|
-
writeLine(stdout, "To read one file directly: tv skills show <relative-path>");
|
|
50259
|
-
}
|
|
50260
50209
|
function commandNameFromArgv(argv) {
|
|
50261
50210
|
const commandName = argv.find((value) => !value.startsWith("-"));
|
|
50262
50211
|
return commandName ?? "tv";
|
|
@@ -50317,7 +50266,7 @@ function resolveBundledSkillsRoot() {
|
|
|
50317
50266
|
if (builtPath && (0, import_node_fs4.existsSync)(builtPath)) {
|
|
50318
50267
|
return builtPath;
|
|
50319
50268
|
}
|
|
50320
|
-
const devPath = import_node_path7.default.resolve(getDevPackageDir(), "../skills/dist
|
|
50269
|
+
const devPath = import_node_path7.default.resolve(getDevPackageDir(), "../skills/dist");
|
|
50321
50270
|
return (0, import_node_fs4.existsSync)(devPath) ? devPath : void 0;
|
|
50322
50271
|
}
|
|
50323
50272
|
function isInTempDirectory(inputPath) {
|
|
@@ -50777,11 +50726,11 @@ If you wish to display temporary content to the user, use an internal artifact i
|
|
|
50777
50726
|
const result = await client.viewer.focus(focusInput);
|
|
50778
50727
|
writeLine(env.stdout, `Focused artifact ${result.artifactID} on screen ${result.screenID}.`);
|
|
50779
50728
|
});
|
|
50780
|
-
const skillsCommand = program2.command("skills").description("
|
|
50729
|
+
const skillsCommand = program2.command("skills").description("Manage the bundled Television skills").addHelpText("after", [
|
|
50781
50730
|
"",
|
|
50782
|
-
"This command group manages the bundled
|
|
50783
|
-
"`tv skills install` installs or reinstalls
|
|
50784
|
-
"`tv skills show` lists bundled skill
|
|
50731
|
+
"This command group manages the bundled Television skill collection.",
|
|
50732
|
+
"`tv skills install` installs or reinstalls every bundled Television skill globally through the `skills` package.",
|
|
50733
|
+
"`tv skills show` lists each bundled skill or prints one SKILL.md directly, which is useful for agents that need the content without running the interactive installer."
|
|
50785
50734
|
].join("\n"));
|
|
50786
50735
|
skillsCommand.command("path").description("Print the bundled Television skills collection root").action(() => {
|
|
50787
50736
|
const bundledTelevisionSkillsCollectionRoot = env.resolveBundledSkillsRoot();
|
|
@@ -50790,36 +50739,36 @@ If you wish to display temporary content to the user, use an internal artifact i
|
|
|
50790
50739
|
}
|
|
50791
50740
|
writeLine(env.stdout, bundledTelevisionSkillsCollectionRoot);
|
|
50792
50741
|
});
|
|
50793
|
-
skillsCommand.command("install").description("Install or reinstall
|
|
50742
|
+
skillsCommand.command("install").description("Install or reinstall all bundled Television skills globally").allowUnknownOption(true).action(async function() {
|
|
50794
50743
|
const bundledTelevisionSkillsCollectionRoot = env.resolveBundledSkillsRoot();
|
|
50795
50744
|
if (!bundledTelevisionSkillsCollectionRoot) {
|
|
50796
50745
|
throw new Error("Could not resolve the bundled Television skills root.");
|
|
50797
50746
|
}
|
|
50798
50747
|
await env.runSkillsInstaller(["add", bundledTelevisionSkillsCollectionRoot, "--global"]);
|
|
50799
50748
|
});
|
|
50800
|
-
skillsCommand.command("show").description("List bundled Television
|
|
50749
|
+
skillsCommand.command("show").description("List bundled Television skills or print one SKILL.md by name").argument("[skill]", "Bundled skill name").action((skillName) => {
|
|
50801
50750
|
const bundledTelevisionSkillsCollectionRoot = env.resolveBundledSkillsRoot();
|
|
50802
50751
|
if (!bundledTelevisionSkillsCollectionRoot) {
|
|
50803
50752
|
throw new Error("Could not resolve the bundled Television skills root.");
|
|
50804
50753
|
}
|
|
50805
|
-
|
|
50806
|
-
|
|
50807
|
-
|
|
50808
|
-
|
|
50809
|
-
|
|
50810
|
-
|
|
50754
|
+
if (skillName === void 0) {
|
|
50755
|
+
const bundledSkills = listBundledSkills(bundledTelevisionSkillsCollectionRoot);
|
|
50756
|
+
bundledSkills.forEach((skill2, index) => {
|
|
50757
|
+
writeLine(env.stdout, `${skill2.name} \u2014 ${skill2.description}`);
|
|
50758
|
+
writeLine(env.stdout, ` ${skill2.root}`);
|
|
50759
|
+
if (index < bundledSkills.length - 1) {
|
|
50760
|
+
writeLine(env.stdout, "");
|
|
50761
|
+
}
|
|
50762
|
+
});
|
|
50811
50763
|
return;
|
|
50812
50764
|
}
|
|
50813
|
-
const
|
|
50814
|
-
|
|
50815
|
-
|
|
50816
|
-
|
|
50765
|
+
const skill = resolveBundledSkill(bundledTelevisionSkillsCollectionRoot, skillName);
|
|
50766
|
+
writeLine(env.stdout, `Path: ${skill.root}`);
|
|
50767
|
+
writeLine(env.stdout, "---");
|
|
50768
|
+
env.stdout.write(skill.markdown);
|
|
50769
|
+
if (!skill.markdown.endsWith("\n")) {
|
|
50770
|
+
writeLine(env.stdout, "");
|
|
50817
50771
|
}
|
|
50818
|
-
const preamble = result.kind === "invalid-path" ? `tv skills show: "${relativePath}" is not a relative path inside the bundled television skill.` : `tv skills show: no bundled Television skill file at "${relativePath}".`;
|
|
50819
|
-
writeLine(env.stdout, preamble);
|
|
50820
|
-
writeLine(env.stdout, "");
|
|
50821
|
-
writeSkillListing(env.stdout, skillRoot);
|
|
50822
|
-
throw new CLISilentExitError(1);
|
|
50823
50772
|
});
|
|
50824
50773
|
program2.command("stop").description("Stop the Television system service").action(async () => {
|
|
50825
50774
|
const daemon = env.createDaemon();
|
|
@@ -50862,9 +50811,6 @@ async function runCLI(argv, environment = {}) {
|
|
|
50862
50811
|
await program2.parseAsync(argv, { from: "user" });
|
|
50863
50812
|
return 0;
|
|
50864
50813
|
} catch (error48) {
|
|
50865
|
-
if (error48 instanceof CLISilentExitError) {
|
|
50866
|
-
return error48.silentExitCode;
|
|
50867
|
-
}
|
|
50868
50814
|
if (error48 instanceof Error && "exitCode" in error48) {
|
|
50869
50815
|
const commanderError = error48;
|
|
50870
50816
|
if (commanderError.exitCode === 0) return 0;
|
|
@@ -1,29 +1,37 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
2
|
+
name: artifact-calendar
|
|
3
|
+
description: Author self-contained HTML calendar artifacts using the bundled calendar-week elements and copied calendar assets.
|
|
3
4
|
---
|
|
4
5
|
|
|
5
6
|
# Authoring a calendar week
|
|
6
7
|
|
|
8
|
+
Before authoring the artifact, read `house-style.md` in this skill folder.
|
|
9
|
+
|
|
7
10
|
A working-week calendar with a generated header strip, all-day band, time axis,
|
|
8
11
|
and timed event grid. The agent only authors a single `<calendar-week>` plus
|
|
9
12
|
flat sibling `<calendar-event>` children. The component renders the rest.
|
|
10
13
|
|
|
11
14
|
## Required assets
|
|
12
15
|
|
|
13
|
-
Every calendar artifact must
|
|
14
|
-
calendar
|
|
16
|
+
Every calendar artifact must be self-contained. Read `calendar.css` and
|
|
17
|
+
`calendar.js` from this skill folder and carry them into the artifact output
|
|
18
|
+
instead of referencing `/skills/artifact-calendar/...` URLs.
|
|
19
|
+
|
|
20
|
+
For a Television internal artifact bundle, copy both files into the artifact's
|
|
21
|
+
`public/` directory and reference them relatively:
|
|
15
22
|
|
|
16
23
|
```html
|
|
17
24
|
<link rel="stylesheet" href="/canonical/v1/styles.css" />
|
|
18
|
-
<link rel="stylesheet" href="
|
|
19
|
-
<script type="module" src="
|
|
25
|
+
<link rel="stylesheet" href="./calendar.css" />
|
|
26
|
+
<script type="module" src="./calendar.js"></script>
|
|
20
27
|
```
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
For a standalone single-file HTML artifact, inline the contents of
|
|
30
|
+
`calendar.css` and `calendar.js` directly into `<style>` and
|
|
31
|
+
`<script type="module">` tags so the output stays self-contained.
|
|
32
|
+
|
|
33
|
+
`calendar.js` registers the custom elements. `calendar.css` provides the
|
|
34
|
+
calendar-specific chrome styling. Do not reimplement those elements yourself.
|
|
27
35
|
|
|
28
36
|
## Markup contract
|
|
29
37
|
|
|
@@ -119,8 +127,8 @@ Those are internal chrome and CSS targets created by `<calendar-week>`.
|
|
|
119
127
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
120
128
|
<title>Team Week</title>
|
|
121
129
|
<link rel="stylesheet" href="/canonical/v1/styles.css" />
|
|
122
|
-
<link rel="stylesheet" href="
|
|
123
|
-
<script type="module" src="
|
|
130
|
+
<link rel="stylesheet" href="./calendar.css" />
|
|
131
|
+
<script type="module" src="./calendar.js"></script>
|
|
124
132
|
<style>
|
|
125
133
|
html, body { margin: 0; min-height: 100vh; }
|
|
126
134
|
calendar-week { height: 100vh; }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
calendar-event{display:contents}calendar-event .event-block{pointer-events:none;z-index:2}calendar-event .event-block-inner{background:var(--event-bg-timed, var(--neutral-100));border-left:3px solid var(--event-border-color, var(--neutral-300));border-radius:4px;box-shadow:inset 0 0 0 .5px var(--neutral-200)}calendar-grid calendar-event .event-block{grid-column:calc(var(--day-index) + 1);grid-row:1 / -1;position:relative;z-index:0}calendar-grid calendar-event .event-block-inner{position:absolute;top:calc(var(--y-start) * 100%);height:calc((var(--y-end) - var(--y-start)) * 100%);left:calc(2px + var(--cascade-depth, 0) * 6px);right:2px;padding:var(--space-4) var(--space-8);overflow:hidden;pointer-events:auto;z-index:calc(1 + var(--cascade-depth, 0))}calendar-allday calendar-event .event-block{grid-column:calc(var(--day-start) + 1) / span var(--day-span);grid-row:var(--lane-index);padding:2px}calendar-allday calendar-event .event-block-inner{background:var(--event-bg-all-day, var(--event-bg-timed, var(--neutral-100)));border-left:var( --event-all-day-border, 3px solid var(--event-border-color, var(--neutral-300)) );padding:1px var(--space-8);display:flex;align-items:center;pointer-events:auto}calendar-event[color=red]{--event-bg-timed: var(--red-100);--event-bg-all-day: var(--red-200);--event-border-color: var(--red-500);--event-all-day-border: none}calendar-event[color=orange]{--event-bg-timed: var(--orange-100);--event-bg-all-day: var(--orange-200);--event-border-color: var(--orange-500);--event-all-day-border: none}calendar-event[color=yellow]{--event-bg-timed: var(--yellow-100);--event-bg-all-day: var(--yellow-200);--event-border-color: var(--yellow-500);--event-all-day-border: none}calendar-event[color=green]{--event-bg-timed: var(--green-100);--event-bg-all-day: var(--green-200);--event-border-color: var(--green-500);--event-all-day-border: none}calendar-event[color=blue]{--event-bg-timed: var(--blue-100);--event-bg-all-day: var(--blue-200);--event-border-color: var(--blue-500);--event-all-day-border: none}calendar-event[color=purple]{--event-bg-timed: var(--purple-100);--event-bg-all-day: var(--purple-200);--event-border-color: var(--purple-500);--event-all-day-border: none}calendar-event h3{margin:0;font-size:var(--text-sm);font-weight:600;color:var(--color-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}calendar-time-axis{display:contents}calendar-time-axis .hour-label{grid-column:time-left / days-start;grid-row-start:calc(var(--hour-index) + 1);align-self:start;padding:var(--space-2) var(--space-8);font-size:round(calc(var(--text-sm) / var(--text-scale)),1px);color:var(--color-text-muted);text-align:right;white-space:nowrap;transform:translateY(-50%)}calendar-time-axis .hour-label[data-hour="0"]{visibility:hidden;width:0;height:0;padding:0;overflow:hidden}calendar-week{display:grid;grid-template-columns:[time-left] auto [days-start] repeat(var(--day-count, 0),minmax(0,1fr)) [days-end];grid-template-rows:[headers] auto [allday] auto [hours-start] repeat(var(--hour-count, 0),minmax(var(--hour-min-height, 4rem),1fr)) [hours-end];width:100%;height:100%;overflow:auto;background:var(--color-surface);font-family:inherit;color:var(--color-text)}calendar-week>calendar-headers,calendar-week>calendar-allday,calendar-week>calendar-grid{display:grid;grid-column:1 / -1;grid-template-columns:subgrid;min-width:0}calendar-week>calendar-headers{grid-row:headers / allday;position:sticky;top:0;z-index:3;background:var(--color-surface);border-top:.5px solid var(--color-border);border-bottom:1px solid var(--color-border)}calendar-headers>calendar-day{grid-column:calc(var(--day-index) + 1);display:flex;align-items:baseline;gap:var(--space-2);padding:var(--space-12);font-size:var(--text-sm);border-left:.5px solid var(--color-border-muted)}calendar-headers>calendar-day:last-of-type{border-right:.5px solid var(--color-border-muted)}calendar-headers>calendar-day .weekday{text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-muted)}calendar-headers>calendar-day .date-num{color:var(--color-text)}calendar-week>calendar-allday{grid-row:allday / hours-start;grid-template-rows:repeat(var(--allday-lane-count, 1),auto);position:sticky;top:var(--headers-height, 0px);z-index:2;border-bottom:1px solid var(--color-border);background:var(--color-surface)}calendar-allday>calendar-cell{grid-column:calc(var(--day-index) + 1);grid-row:1;border-left:.5px solid var(--color-border-muted)}calendar-allday>calendar-cell:last-of-type{border-right:.5px solid var(--color-border-muted)}calendar-week>calendar-grid{grid-row:hours-start / hours-end;grid-template-rows:subgrid;position:relative}calendar-grid>calendar-column{grid-column:calc(var(--day-index) + 1);grid-row:1 / -1;border-left:.5px solid var(--color-border-muted);background-image:repeating-linear-gradient(to bottom,transparent 0,transparent calc(100% / var(--hour-count) - .5px),var(--color-border-muted) calc(100% / var(--hour-count) - .5px),var(--color-border-muted) calc(100% / var(--hour-count)))}calendar-grid>calendar-column:last-of-type{border-right:.5px solid var(--color-border-muted)}calendar-grid>.start-hour-marker{grid-column:2;grid-row-start:calc(var(--start-hour) + 1);width:0;height:0}calendar-grid>.now-line-faint,calendar-grid>.now-line{grid-row:1 / -1;position:relative;pointer-events:none;z-index:1}calendar-grid>.now-line-faint{grid-column:2 / -1}calendar-grid>.now-line{grid-column:calc(var(--day-index) + 1)}calendar-grid>.now-line-faint:before,calendar-grid>.now-line:before{content:"";position:absolute;left:0;right:0;top:calc(var(--y-fraction) * 100%);height:1px;transform:translateY(-.5px)}calendar-grid>.now-line-faint:before{background:#e7202240}calendar-grid>.now-line:before{background:#e72022}calendar-grid>.now-line:after{content:"";position:absolute;left:0;top:calc(var(--y-fraction) * 100%);width:.5rem;height:.5rem;border-radius:50%;background:#e72022;transform:translate(-50%,-50%)}
|