@telepath-computer/television 0.1.83 → 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 CHANGED
@@ -50093,7 +50093,7 @@ 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 = "Load/read the installed `television` skill. Start with `SKILL.md` for the mental model and the artifact-vs-chat decision. If the skill is not installed, you can use `tv skills install` (interactive, not agent-friendly) or `tv skills show` (agent-friendly, prints bundled skill files directly). For CLI commands, focus, and screen placement, read `cli-capabilities.md`. For artifact lifecycle work, read `artifact-workflow.md`. For HTML artifact work, also read `html-house-style.md` and the relevant `artifact-types/*.md` companion doc.";
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
  };
@@ -50123,8 +50123,8 @@ function resolveVercelSkillsInstallerBin() {
50123
50123
  return localRequire.resolve("skills/bin/cli.mjs");
50124
50124
  }
50125
50125
  function readCLIVersion() {
50126
- if ("0.1.83".length > 0) {
50127
- return "0.1.83";
50126
+ if ("0.1.85".length > 0) {
50127
+ return "0.1.85";
50128
50128
  }
50129
50129
  const devPackageJsonPath = import_node_path7.default.join(getDevPackageDir(), "package.json");
50130
50130
  if (!(0, import_node_fs4.existsSync)(devPackageJsonPath)) {
@@ -50132,101 +50132,80 @@ function readCLIVersion() {
50132
50132
  }
50133
50133
  return JSON.parse((0, import_node_fs4.readFileSync)(devPackageJsonPath, "utf8")).version;
50134
50134
  }
50135
- function listKnownArtifactTypeDocs() {
50136
- if ('["artifact-types/calendar.md","artifact-types/table.md"]'.length > 0) {
50137
- return JSON.parse('["artifact-types/calendar.md","artifact-types/table.md"]');
50138
- }
50139
- const televisionSkillsWorkspaceDir = import_node_path7.default.resolve(getDevPackageDir(), "../skills");
50140
- if (!(0, import_node_fs4.existsSync)(televisionSkillsWorkspaceDir)) {
50141
- return [];
50142
- }
50143
- return (0, import_node_fs4.readdirSync)(televisionSkillsWorkspaceDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && /^artifact-/.test(entry.name)).map((entry) => entry.name.slice("artifact-".length)).sort((a, b) => a.localeCompare(b)).map((slug) => `artifact-types/${slug}.md`);
50144
- }
50145
- function formatArtifactTypeDocsList() {
50146
- const docs = listKnownArtifactTypeDocs();
50147
- return docs.length > 0 ? docs.map((doc) => ` - ${doc}`).join("\n") : " - artifact-types/<name>.md";
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);
50148
50186
  }
50149
50187
  function buildAgentHelpNote() {
50150
50188
  return [
50151
50189
  "",
50152
50190
  "Agent workflow note:",
50153
- " Load/read the installed `television` skill before Television work.",
50154
- " `SKILL.md` carries the mental model and the artifact-vs-chat decision.",
50155
- " `cli-capabilities.md` covers commands, focus, and screen placement.",
50156
- " For artifact lifecycle work, read `artifact-workflow.md`.",
50157
- " For HTML artifacts, also read `html-house-style.md`.",
50158
- " Known artifact-type docs:",
50159
- formatArtifactTypeDocsList(),
50160
- " If the Television skill is not installed, you can use `tv skills install` (interactive) or `tv skills show` (agent-friendly, prints the bundled skill files directly)."
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`."
50161
50195
  ].join("\n");
50162
50196
  }
50163
50197
  function buildArtifactWorkflowHelpNote(includeHTMLNote) {
50164
50198
  const lines = [
50165
50199
  "",
50166
50200
  "Agent note:",
50167
- " If you are an agent doing artifact lifecycle work, load/read the `television` skill and `artifact-workflow.md`."
50201
+ " For Television lifecycle work, read `television`."
50168
50202
  ];
50169
50203
  if (includeHTMLNote) {
50170
- lines.push(" If you are authoring an HTML artifact, also read `html-house-style.md`.");
50171
- lines.push(" Known artifact-type docs:");
50172
- 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`.");
50173
50206
  }
50174
50207
  return lines.join("\n");
50175
50208
  }
50176
- function getBundledTelevisionSkillRoot(bundledTelevisionSkillsCollectionRoot) {
50177
- return import_node_path7.default.join(bundledTelevisionSkillsCollectionRoot, "television");
50178
- }
50179
- function readSkillManifest(skillRoot) {
50180
- const empty = { version: void 0, descriptions: /* @__PURE__ */ new Map() };
50181
- const manifestPath = import_node_path7.default.join(skillRoot, ".skill-manifest.json");
50182
- if (!(0, import_node_fs4.existsSync)(manifestPath)) return empty;
50183
- try {
50184
- const raw = (0, import_node_fs4.readFileSync)(manifestPath, "utf8");
50185
- const parsed = JSON.parse(raw);
50186
- if (typeof parsed !== "object" || parsed === null) return empty;
50187
- const root = parsed;
50188
- const version2 = typeof root.version === "string" ? root.version : void 0;
50189
- const files = Array.isArray(root.files) ? root.files : [];
50190
- const entries = [];
50191
- for (const entry of files) {
50192
- if (typeof entry === "object" && entry !== null && typeof entry.path === "string" && typeof entry.description === "string") {
50193
- entries.push([entry.path, entry.description]);
50194
- }
50195
- }
50196
- return { version: version2, descriptions: new Map(entries) };
50197
- } catch {
50198
- return empty;
50199
- }
50200
- }
50201
- function listSkillFiles(skillRoot, prefix = "") {
50202
- const entries = (0, import_node_fs4.readdirSync)(skillRoot, { withFileTypes: true }).filter((entry) => !entry.name.startsWith(".")).sort((a, b) => a.name.localeCompare(b.name));
50203
- const files = [];
50204
- for (const entry of entries) {
50205
- const relativePath = prefix === "" ? entry.name : import_node_path7.default.posix.join(prefix, entry.name);
50206
- const absolutePath = import_node_path7.default.join(skillRoot, entry.name);
50207
- if (entry.isDirectory()) {
50208
- files.push(...listSkillFiles(absolutePath, relativePath));
50209
- continue;
50210
- }
50211
- files.push(relativePath);
50212
- }
50213
- return files;
50214
- }
50215
- function resolveSkillFilePath(skillRoot, relativePath) {
50216
- const normalized = import_node_path7.default.posix.normalize(relativePath);
50217
- if (normalized.startsWith("../") || normalized === ".." || import_node_path7.default.isAbsolute(relativePath)) {
50218
- throw createDirectiveError("tv skills show requires a relative path within the television skill root.");
50219
- }
50220
- const resolved = import_node_path7.default.join(skillRoot, normalized);
50221
- const relativeResolved = import_node_path7.default.relative(skillRoot, resolved);
50222
- if (relativeResolved.startsWith("..") || import_node_path7.default.isAbsolute(relativeResolved)) {
50223
- throw createDirectiveError("tv skills show requires a relative path within the television skill root.");
50224
- }
50225
- if (!(0, import_node_fs4.existsSync)(resolved)) {
50226
- throw createDirectiveError(`tv skills show could not find ${relativePath} in the television skill.`);
50227
- }
50228
- return resolved;
50229
- }
50230
50209
  function commandNameFromArgv(argv) {
50231
50210
  const commandName = argv.find((value) => !value.startsWith("-"));
50232
50211
  return commandName ?? "tv";
@@ -50287,7 +50266,7 @@ function resolveBundledSkillsRoot() {
50287
50266
  if (builtPath && (0, import_node_fs4.existsSync)(builtPath)) {
50288
50267
  return builtPath;
50289
50268
  }
50290
- const devPath = import_node_path7.default.resolve(getDevPackageDir(), "../skills/dist/skills");
50269
+ const devPath = import_node_path7.default.resolve(getDevPackageDir(), "../skills/dist");
50291
50270
  return (0, import_node_fs4.existsSync)(devPath) ? devPath : void 0;
50292
50271
  }
50293
50272
  function isInTempDirectory(inputPath) {
@@ -50747,11 +50726,11 @@ If you wish to display temporary content to the user, use an internal artifact i
50747
50726
  const result = await client.viewer.focus(focusInput);
50748
50727
  writeLine(env.stdout, `Focused artifact ${result.artifactID} on screen ${result.screenID}.`);
50749
50728
  });
50750
- const skillsCommand = program2.command("skills").description("Install the bundled Television skill").addHelpText("after", [
50729
+ const skillsCommand = program2.command("skills").description("Manage the bundled Television skills").addHelpText("after", [
50751
50730
  "",
50752
- "This command group manages the bundled `television` skill.",
50753
- "`tv skills install` installs or reinstalls it globally through the `skills` package.",
50754
- "`tv skills show` lists bundled skill files or prints one directly, which is useful for agents that need the content without running the interactive installer."
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."
50755
50734
  ].join("\n"));
50756
50735
  skillsCommand.command("path").description("Print the bundled Television skills collection root").action(() => {
50757
50736
  const bundledTelevisionSkillsCollectionRoot = env.resolveBundledSkillsRoot();
@@ -50760,41 +50739,36 @@ If you wish to display temporary content to the user, use an internal artifact i
50760
50739
  }
50761
50740
  writeLine(env.stdout, bundledTelevisionSkillsCollectionRoot);
50762
50741
  });
50763
- skillsCommand.command("install").description("Install or reinstall the bundled Television skill globally").allowUnknownOption(true).action(async function() {
50742
+ skillsCommand.command("install").description("Install or reinstall all bundled Television skills globally").allowUnknownOption(true).action(async function() {
50764
50743
  const bundledTelevisionSkillsCollectionRoot = env.resolveBundledSkillsRoot();
50765
50744
  if (!bundledTelevisionSkillsCollectionRoot) {
50766
50745
  throw new Error("Could not resolve the bundled Television skills root.");
50767
50746
  }
50768
50747
  await env.runSkillsInstaller(["add", bundledTelevisionSkillsCollectionRoot, "--global"]);
50769
50748
  });
50770
- skillsCommand.command("show").description("List bundled Television skill files or print one by relative path").argument("[path]", "Relative path within the television skill root").action((relativePath) => {
50749
+ skillsCommand.command("show").description("List bundled Television skills or print one SKILL.md by name").argument("[skill]", "Bundled skill name").action((skillName) => {
50771
50750
  const bundledTelevisionSkillsCollectionRoot = env.resolveBundledSkillsRoot();
50772
50751
  if (!bundledTelevisionSkillsCollectionRoot) {
50773
50752
  throw new Error("Could not resolve the bundled Television skills root.");
50774
50753
  }
50775
- const skillRoot = getBundledTelevisionSkillRoot(bundledTelevisionSkillsCollectionRoot);
50776
- if (!(0, import_node_fs4.existsSync)(skillRoot)) {
50777
- throw new Error(`Could not resolve the bundled television skill root at ${skillRoot}.`);
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
+ });
50763
+ return;
50778
50764
  }
50779
- if (relativePath === void 0) {
50780
- const manifest = readSkillManifest(skillRoot);
50781
- if (manifest.version !== void 0) {
50782
- writeLine(env.stdout, `Television skill content version: ${manifest.version}`);
50783
- writeLine(env.stdout, "");
50784
- }
50785
- writeLine(env.stdout, "Relative paths inside the bundled `television` skill:");
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")) {
50786
50770
  writeLine(env.stdout, "");
50787
- for (const file2 of listSkillFiles(skillRoot)) {
50788
- const description = manifest.descriptions.get(file2);
50789
- writeLine(env.stdout, description ? `${file2} \u2014 ${description}` : file2);
50790
- }
50791
- writeLine(env.stdout, "");
50792
- writeLine(env.stdout, `Television skill root: ${skillRoot}`);
50793
- writeLine(env.stdout, "To read one file directly: tv skills show <relative-path>");
50794
- return;
50795
50771
  }
50796
- const filepath = resolveSkillFilePath(skillRoot, relativePath);
50797
- env.stdout.write((0, import_node_fs4.readFileSync)(filepath, "utf8"));
50798
50772
  });
50799
50773
  program2.command("stop").description("Stop the Television system service").action(async () => {
50800
50774
  const daemon = env.createDaemon();
@@ -1,29 +1,37 @@
1
1
  ---
2
- description: Authoring conventions for the calendar artifact kind.
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 load both the canonical stylesheet and the
14
- calendar element bundle:
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="/skills/artifact-calendar/calendar.css" />
19
- <script type="module" src="/skills/artifact-calendar/calendar.js"></script>
25
+ <link rel="stylesheet" href="./calendar.css" />
26
+ <script type="module" src="./calendar.js"></script>
20
27
  ```
21
28
 
22
- `/skills/artifact-calendar/calendar.js` and
23
- `/skills/artifact-calendar/calendar.css` are the built skill-local assets
24
- served by artifactory from the package's `dist/` output. They register the
25
- custom elements and provide the calendar-specific chrome styling. Do not
26
- inline or reimplement those elements yourself.
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="/skills/artifact-calendar/calendar.css" />
123
- <script type="module" src="/skills/artifact-calendar/calendar.js"></script>
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%)}