mdeck 2.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/CHANGELOG.md +259 -0
- package/LICENSE +21 -0
- package/README.md +156 -0
- package/assets/base.css +196 -0
- package/assets/extensions/layouts/chapter/extension.toml +26 -0
- package/assets/extensions/layouts/chapter/layout.jsx +21 -0
- package/assets/extensions/layouts/chapter/starter.md +8 -0
- package/assets/extensions/layouts/focus/extension.toml +8 -0
- package/assets/extensions/layouts/focus/layout.jsx +10 -0
- package/assets/extensions/layouts/focus/starter.md +4 -0
- package/assets/extensions/layouts/full-bleed-image/extension.toml +31 -0
- package/assets/extensions/layouts/full-bleed-image/layout.jsx +19 -0
- package/assets/extensions/layouts/full-bleed-image/starter.md +6 -0
- package/assets/extensions/layouts/generic/extension.toml +8 -0
- package/assets/extensions/layouts/generic/layout.jsx +8 -0
- package/assets/extensions/layouts/generic/starter.md +4 -0
- package/assets/extensions/layouts/image-text/extension.toml +25 -0
- package/assets/extensions/layouts/image-text/layout.jsx +17 -0
- package/assets/extensions/layouts/image-text/starter.md +6 -0
- package/assets/extensions/layouts/split/extension.toml +25 -0
- package/assets/extensions/layouts/split/layout.jsx +19 -0
- package/assets/extensions/layouts/split/starter.md +14 -0
- package/assets/extensions/layouts/title/extension.toml +26 -0
- package/assets/extensions/layouts/title/layout.jsx +14 -0
- package/assets/extensions/layouts/title/starter.md +5 -0
- package/assets/extensions/palettes/brand/extension.toml +29 -0
- package/assets/extensions/palettes/cobalt/extension.toml +27 -0
- package/assets/extensions/palettes/ember/extension.toml +27 -0
- package/assets/extensions/palettes/forest/extension.toml +27 -0
- package/assets/extensions/palettes/graphite/extension.toml +27 -0
- package/assets/extensions/palettes/lagoon/extension.toml +27 -0
- package/assets/extensions/palettes/neon/extension.toml +27 -0
- package/assets/extensions/palettes/nordic/extension.toml +27 -0
- package/assets/extensions/palettes/pastel/extension.toml +30 -0
- package/assets/extensions/palettes/phosphor/extension.toml +27 -0
- package/assets/extensions/palettes/swiss/extension.toml +27 -0
- package/assets/extensions/palettes/terra/extension.toml +27 -0
- package/assets/extensions/themes/academic/extension.toml +53 -0
- package/assets/extensions/themes/academic/styles.css +631 -0
- package/assets/extensions/themes/aurora/extension.toml +37 -0
- package/assets/extensions/themes/aurora/styles.css +644 -0
- package/assets/extensions/themes/duet/extension.toml +46 -0
- package/assets/extensions/themes/duet/styles.css +573 -0
- package/assets/extensions/themes/editorial/extension.toml +46 -0
- package/assets/extensions/themes/editorial/styles.css +574 -0
- package/assets/extensions/themes/fhnw/extension.toml +61 -0
- package/assets/extensions/themes/fhnw/styles.css +604 -0
- package/assets/extensions/themes/neue/extension.toml +46 -0
- package/assets/extensions/themes/neue/styles.css +489 -0
- package/assets/extensions/themes/sketch/extension.toml +48 -0
- package/assets/extensions/themes/sketch/styles.css +633 -0
- package/assets/extensions/themes/terminal/extension.toml +38 -0
- package/assets/extensions/themes/terminal/styles.css +550 -0
- package/assets/logo/avatar.png +0 -0
- package/assets/logo/logo-dark.svg +10 -0
- package/assets/logo/logo-light.svg +10 -0
- package/assets/logo/mark.svg +15 -0
- package/bin/mdeck.js +2 -0
- package/docs/README.md +8 -0
- package/docs/reference/authoring.md +795 -0
- package/docs/reference/claude-skill.md +96 -0
- package/docs/reference/extensions.md +250 -0
- package/docs/reference/layouts.md +153 -0
- package/docs/reference/palettes.md +106 -0
- package/docs/reference/structured-slides.md +120 -0
- package/docs/reference/themes.md +133 -0
- package/docs/site/assets/favicon.svg +15 -0
- package/docs/site/assets/github-logo.svg +1 -0
- package/docs/site/assets/site.css +162 -0
- package/docs/site/assets/site.js +123 -0
- package/docs/site/build.js +148 -0
- package/docs/site/content/appearance.md +203 -0
- package/docs/site/content/audience.md +178 -0
- package/docs/site/content/commands.md +153 -0
- package/docs/site/content/components.md +134 -0
- package/docs/site/content/drawing.md +72 -0
- package/docs/site/content/editing.md +59 -0
- package/docs/site/content/getting-started.md +103 -0
- package/docs/site/content/layouts.md +126 -0
- package/docs/site/content/media.md +107 -0
- package/docs/site/content/more-content.md +130 -0
- package/docs/site/content/presenting.md +93 -0
- package/docs/site/content/reusable-layouts.md +74 -0
- package/docs/site/content/sharing.md +88 -0
- package/docs/site/content/theme-authoring.md +144 -0
- package/docs/site/content/theme-repository.md +76 -0
- package/docs/site/content/troubleshooting.md +92 -0
- package/docs/site/content/views.md +56 -0
- package/docs/site/content/welcome.md +71 -0
- package/docs/site/content/writing.md +121 -0
- package/docs/site/examples/first-talk.md +88 -0
- package/docs/site/examples/notebook.svg +58 -0
- package/docs/site/images/themes/academic-dark.webp +0 -0
- package/docs/site/images/themes/academic-light.webp +0 -0
- package/docs/site/images/themes/academic.webp +0 -0
- package/docs/site/images/themes/aurora-dark.webp +0 -0
- package/docs/site/images/themes/aurora-light.webp +0 -0
- package/docs/site/images/themes/aurora.webp +0 -0
- package/docs/site/images/themes/duet-dark.webp +0 -0
- package/docs/site/images/themes/duet-light.webp +0 -0
- package/docs/site/images/themes/duet.webp +0 -0
- package/docs/site/images/themes/editorial-dark.webp +0 -0
- package/docs/site/images/themes/editorial-light.webp +0 -0
- package/docs/site/images/themes/editorial.webp +0 -0
- package/docs/site/images/themes/fhnw.webp +0 -0
- package/docs/site/images/themes/neue-dark.webp +0 -0
- package/docs/site/images/themes/neue-light.webp +0 -0
- package/docs/site/images/themes/neue.webp +0 -0
- package/docs/site/images/themes/sketch-dark.webp +0 -0
- package/docs/site/images/themes/sketch-light.webp +0 -0
- package/docs/site/images/themes/sketch.webp +0 -0
- package/docs/site/images/themes/terminal-dark.webp +0 -0
- package/docs/site/images/themes/terminal-light.webp +0 -0
- package/docs/site/images/themes/terminal.webp +0 -0
- package/docs/site/package.json +9 -0
- package/docs/site/pages.js +27 -0
- package/docs/site/server.js +58 -0
- package/examples/custom-layouts/extensions/comparison/extension.toml +35 -0
- package/examples/custom-layouts/extensions/comparison/layout.jsx +15 -0
- package/examples/custom-layouts/extensions/comparison/starter.md +17 -0
- package/examples/custom-layouts/extensions/comparison/styles.css +4 -0
- package/examples/custom-layouts/slides.md +60 -0
- package/examples/poll/slides.md +127 -0
- package/examples/python/.mdeck-backups/slides.drawings-2026-10-06T08-36-47Z.json +19 -0
- package/examples/python/.mdeck-backups/slides.drawings-2026-10-06T11-27-30Z.json +6 -0
- package/examples/python/slides.drawings.json +6 -0
- package/examples/python/slides.md +493 -0
- package/examples/showcase/.mdeck-backups/slides.drawings-2026-10-06T08-08-30Z.json +10 -0
- package/examples/showcase/.mdeck-backups/slides.drawings-2026-10-06T11-41-35Z.json +13 -0
- package/examples/showcase/img/image.jpg +0 -0
- package/examples/showcase/img/mdeck.svg +66 -0
- package/examples/showcase/slides.drawings.json +11 -0
- package/examples/showcase/slides.md +427 -0
- package/package.json +75 -0
- package/skills/write-slides/SKILL.md +144 -0
- package/src/build/check.js +49 -0
- package/src/build/chrome.js +130 -0
- package/src/build/components.js +44 -0
- package/src/build/config.js +61 -0
- package/src/build/drawings.js +14 -0
- package/src/build/editorPlugin.js +272 -0
- package/src/build/editorServer.js +36 -0
- package/src/build/fonts.js +84 -0
- package/src/build/homePlugin.js +208 -0
- package/src/build/inkPlugin.js +192 -0
- package/src/build/ownWrites.js +18 -0
- package/src/build/pairing.js +81 -0
- package/src/build/pdf.js +34 -0
- package/src/build/relayAccess.js +85 -0
- package/src/build/slidesPlugin.js +371 -0
- package/src/build/themeCheck.js +151 -0
- package/src/build/tunnelClient.js +184 -0
- package/src/cli/args.js +76 -0
- package/src/cli/index.js +758 -0
- package/src/cli/migrate.js +123 -0
- package/src/cli/skill.js +40 -0
- package/src/cli/themes.js +140 -0
- package/src/components/CodeBlock.jsx +168 -0
- package/src/components/ConnectedViews.jsx +25 -0
- package/src/components/Icon.jsx +8 -0
- package/src/components/Poll.jsx +67 -0
- package/src/components/QrCode.jsx +29 -0
- package/src/components/QrCodeTag.jsx +27 -0
- package/src/components/Question.jsx +28 -0
- package/src/components/Scale.jsx +47 -0
- package/src/components/VideoPlayer.jsx +108 -0
- package/src/components/WordCloud.jsx +106 -0
- package/src/components/activity.jsx +35 -0
- package/src/components/callout.css +78 -0
- package/src/components/code-block.css +123 -0
- package/src/components/columns.css +11 -0
- package/src/components/poll.css +81 -0
- package/src/components/video-player.css +14 -0
- package/src/core/devPath.js +4 -0
- package/src/core/editDeck.js +230 -0
- package/src/core/icons.js +69 -0
- package/src/core/ink.js +221 -0
- package/src/core/labels.js +144 -0
- package/src/core/outline.js +33 -0
- package/src/core/parseSlides.js +152 -0
- package/src/core/source.js +137 -0
- package/src/core/urls.js +34 -0
- package/src/core/validateDeck.js +139 -0
- package/src/editor/api.js +67 -0
- package/src/editor/components/App.jsx +75 -0
- package/src/editor/components/ConflictBanner.jsx +10 -0
- package/src/editor/components/DeckSettings.jsx +108 -0
- package/src/editor/components/DesignApp.jsx +252 -0
- package/src/editor/components/Diagnostics.jsx +10 -0
- package/src/editor/components/ExtensionEditor.jsx +66 -0
- package/src/editor/components/ExtensionForms.jsx +134 -0
- package/src/editor/components/ExtensionsPanel.jsx +114 -0
- package/src/editor/components/Field.jsx +24 -0
- package/src/editor/components/Inspector.jsx +36 -0
- package/src/editor/components/LayoutPicker.jsx +23 -0
- package/src/editor/components/LayoutSelect.jsx +25 -0
- package/src/editor/components/LookThumbnail.jsx +8 -0
- package/src/editor/components/MetaFields.jsx +24 -0
- package/src/editor/components/Outline.jsx +28 -0
- package/src/editor/components/PalettePicker.jsx +32 -0
- package/src/editor/components/Preview.jsx +63 -0
- package/src/editor/components/PropsForm.jsx +46 -0
- package/src/editor/components/RawSlideEditor.jsx +9 -0
- package/src/editor/components/RegionEditor.jsx +15 -0
- package/src/editor/components/Resizer.jsx +18 -0
- package/src/editor/designLink.js +19 -0
- package/src/editor/editor.css +139 -0
- package/src/editor/extensions.js +86 -0
- package/src/editor/keyboard.js +21 -0
- package/src/editor/model.js +38 -0
- package/src/editor/sampleDeck.js +165 -0
- package/src/editor/saveQueue.js +47 -0
- package/src/editor/schema.js +36 -0
- package/src/editor/state.js +92 -0
- package/src/editor/useDeckDocument.js +67 -0
- package/src/extensions/appearance.js +79 -0
- package/src/extensions/contrast.js +57 -0
- package/src/extensions/discover.js +126 -0
- package/src/extensions/manifest.js +209 -0
- package/src/extensions/packs.js +268 -0
- package/src/extensions/tokens.js +25 -0
- package/src/home/Home.jsx +362 -0
- package/src/home/home.css +148 -0
- package/src/layouts/layoutApi.jsx +205 -0
- package/src/layouts/layoutProps.js +30 -0
- package/src/layouts/renderSlide.jsx +17 -0
- package/src/live/answer/answer.css +34 -0
- package/src/live/answer/answer.html +14 -0
- package/src/live/answer/answer.js +130 -0
- package/src/live/client.js +290 -0
- package/src/live/code.js +19 -0
- package/src/live/follow.js +17 -0
- package/src/live/pairing.js +34 -0
- package/src/live/presence.js +33 -0
- package/src/live/roomTag.js +38 -0
- package/src/live/rooms.js +249 -0
- package/src/live/server.js +82 -0
- package/src/live/tunnel.js +180 -0
- package/src/paths.js +9 -0
- package/src/runtime/ReaderView.jsx +193 -0
- package/src/runtime/SlideErrorBoundary.jsx +28 -0
- package/src/runtime/chrome.jsx +55 -0
- package/src/runtime/deck-stage.js +1533 -0
- package/src/runtime/design.html +12 -0
- package/src/runtime/design.jsx +5 -0
- package/src/runtime/editor.html +12 -0
- package/src/runtime/editor.jsx +5 -0
- package/src/runtime/editorBridge.js +58 -0
- package/src/runtime/fit.js +149 -0
- package/src/runtime/home.html +13 -0
- package/src/runtime/home.jsx +5 -0
- package/src/runtime/index.html +15 -0
- package/src/runtime/ink/InkLayer.jsx +17 -0
- package/src/runtime/ink/Toolbar.jsx +145 -0
- package/src/runtime/ink/attach.js +69 -0
- package/src/runtime/ink/bus.js +126 -0
- package/src/runtime/ink/controller.js +132 -0
- package/src/runtime/ink/room.js +101 -0
- package/src/runtime/ink/select.js +124 -0
- package/src/runtime/ink/server.js +75 -0
- package/src/runtime/ink/store.js +55 -0
- package/src/runtime/ink/toolbar.css +79 -0
- package/src/runtime/main.jsx +863 -0
- package/src/runtime/markedSetup.js +147 -0
- package/src/runtime/reader.css +59 -0
- package/src/runtime/registry.jsx +26 -0
- package/src/runtime/syncOrder.js +32 -0
- package/src/runtime/themeLoader.js +68 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Work with an AI assistant
|
|
2
|
+
|
|
3
|
+
The usual way to make an mdeck presentation is to give an AI assistant the
|
|
4
|
+
material you already have (old slides, a PDF, a Word document, a paper, a page
|
|
5
|
+
of notes) and let it turn that into a deck. The content stays yours; the
|
|
6
|
+
assistant shapes it into slides, chooses layouts, writes speaker notes from
|
|
7
|
+
your text, and checks its work with mdeck.
|
|
8
|
+
|
|
9
|
+
mdeck ships a skill, `write-slides`, for this. It reads the mdeck reference
|
|
10
|
+
docs, asks the installed `mdeck` command which layouts, themes and palettes the
|
|
11
|
+
deck can use (including designs kept in the deck's `extensions/` folder),
|
|
12
|
+
writes the file, and runs `mdeck check` on the result.
|
|
13
|
+
|
|
14
|
+
The skill is written in the [Agent Skills](https://agentskills.io) format, a
|
|
15
|
+
`SKILL.md` file that Claude Code, OpenAI Codex and other assistants read
|
|
16
|
+
directly. For tools with their own conventions, `mdeck skill` writes the same
|
|
17
|
+
instructions in their format.
|
|
18
|
+
|
|
19
|
+
## Install it
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
mdeck skill # list the supported assistants
|
|
23
|
+
mdeck skill --install claude # Claude Code, personal (~/.claude/skills/)
|
|
24
|
+
mdeck skill --install codex # OpenAI Codex, personal (~/.codex/skills/)
|
|
25
|
+
mdeck skill --install cursor # Cursor rule in this project (.cursor/rules/)
|
|
26
|
+
mdeck skill --install copilot # GitHub Copilot prompt file (.github/prompts/)
|
|
27
|
+
mdeck skill --install gemini # Gemini CLI command (.gemini/commands/)
|
|
28
|
+
mdeck skill --install claude codex --project # into this project instead of your home folder
|
|
29
|
+
mdeck skill --print # the skill as text, for any other tool
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Run the command in the folder of the deck you are working on when installing
|
|
33
|
+
project-level files. Re-run it after updating mdeck to pick up changes.
|
|
34
|
+
|
|
35
|
+
## Start a deck
|
|
36
|
+
|
|
37
|
+
Copy your material into the talk's folder, open the assistant there, and say
|
|
38
|
+
what to make from it: for whom, how long, in which language, and how closely
|
|
39
|
+
to keep to the original.
|
|
40
|
+
|
|
41
|
+
```prompt
|
|
42
|
+
/write-slides Rebuild kinetics-2023.pptx as a 45-minute lecture for
|
|
43
|
+
second-year biology students, in German, FHNW theme. Keep the order
|
|
44
|
+
and the figures, split the crowded slides, and add what is new in
|
|
45
|
+
notes/2026-changes.md.
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
| Assistant | How to start |
|
|
49
|
+
|---|---|
|
|
50
|
+
| Claude Code, Gemini CLI | `/write-slides` followed by your request |
|
|
51
|
+
| Codex | Ask for slides; the skill is picked up by its description |
|
|
52
|
+
| Cursor | Mention `@write-slides` or ask for an mdeck deck |
|
|
53
|
+
| GitHub Copilot | Run the `write-slides` prompt from the prompt picker |
|
|
54
|
+
| Anything else | Paste the output of `mdeck skill --print` followed by your request |
|
|
55
|
+
|
|
56
|
+
The assistant writes a `.md` file named after the topic, checks it, and tells
|
|
57
|
+
you what it left out or added. Open the preview and leave it running while you
|
|
58
|
+
work; it reloads every time the file changes:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
mdeck run <deck>.md
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Change it by asking
|
|
65
|
+
|
|
66
|
+
Keep talking to the assistant and watch the slides follow:
|
|
67
|
+
|
|
68
|
+
```prompt
|
|
69
|
+
You dropped the comparison table from page 12 of the PDF. Put it back
|
|
70
|
+
after the methods slide, and turn "Why it matters" into a big statement.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The assistant can also make what would otherwise need CSS or JavaScript: a
|
|
74
|
+
colour palette, a theme, a slide layout, or an interactive component. They are
|
|
75
|
+
kept as small folders in `extensions/` or `components/` beside the slide file,
|
|
76
|
+
so they travel with the talk. For a theme or palette, it asks you to look at
|
|
77
|
+
the result with `mdeck design <deck>.md`, which shows it on a sample deck with
|
|
78
|
+
every kind of slide, light and dark, and lets you fine-tune colours, fonts and
|
|
79
|
+
sizes yourself.
|
|
80
|
+
|
|
81
|
+
For a word or a number, it is often faster to edit the file yourself; see
|
|
82
|
+
[Read and adjust your slides](writing.html).
|
|
83
|
+
|
|
84
|
+
## Check what it wrote
|
|
85
|
+
|
|
86
|
+
`mdeck check` finds missing pictures and settings mistakes. It does not know
|
|
87
|
+
whether the talk is right, or whether the text fits on each slide. Before
|
|
88
|
+
presenting, compare the deck with your material, look at every slide in the
|
|
89
|
+
preview, and try any polls with a phone.
|
|
90
|
+
|
|
91
|
+
## What the skill knows
|
|
92
|
+
|
|
93
|
+
It carries a short quick reference of the file format so it can work even
|
|
94
|
+
without the docs, finds the full reference docs in the repository or the
|
|
95
|
+
installed package, and prefers the live answers from `mdeck list layouts --json`
|
|
96
|
+
and `mdeck list` over its own memory.
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# Extensions: layouts, themes and palettes
|
|
2
|
+
|
|
3
|
+
mdeck can be extended in three ways, and all three follow the same rules.
|
|
4
|
+
|
|
5
|
+
- A **layout** is an arrangement for a slide: which content areas it has, which
|
|
6
|
+
settings it accepts, and how it is arranged. The built-in layouts such as
|
|
7
|
+
`title` and `split` are extensions too.
|
|
8
|
+
- A **theme** is the overall look: fonts, spacing, the slide frame and the
|
|
9
|
+
default colours. A deck picks one with `theme:`.
|
|
10
|
+
- A **palette** is a family of colours, light and dark, that repaints any
|
|
11
|
+
theme. A deck picks one with `palette:` and the variant with `appearance:`.
|
|
12
|
+
|
|
13
|
+
Every extension is a folder with an `extension.toml` file inside. The manifest
|
|
14
|
+
says which kind it is and describes its supporting files and settings. The
|
|
15
|
+
folder name is the identifier used in slide files.
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
extensions/
|
|
19
|
+
comparison/ a layout
|
|
20
|
+
extension.toml
|
|
21
|
+
layout.jsx
|
|
22
|
+
styles.css
|
|
23
|
+
starter.md
|
|
24
|
+
my-theme/ a theme
|
|
25
|
+
extension.toml
|
|
26
|
+
styles.css
|
|
27
|
+
my-colors/ a palette
|
|
28
|
+
extension.toml
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
mdeck looks in two places, in this order: its own built-in collection under
|
|
32
|
+
`assets/extensions/` and an `extensions/` folder beside the slide file. Inside
|
|
33
|
+
either place, a folder that contains `extension.toml` is an extension; any other
|
|
34
|
+
folder is simply a group and is searched further, so `extensions/colors/ocean/`
|
|
35
|
+
works just as well as `extensions/ocean/`. Identifiers must be unique within
|
|
36
|
+
their kind across both places. A local extension cannot quietly replace a
|
|
37
|
+
built-in one; a duplicate stops the command with a message naming both files.
|
|
38
|
+
|
|
39
|
+
The same registry backs `mdeck check`, `mdeck list`, `mdeck list layouts`,
|
|
40
|
+
the `mdeck new` wizard, the dev server and builds, so what a check accepts is
|
|
41
|
+
what a build can load.
|
|
42
|
+
|
|
43
|
+
## Shared settings
|
|
44
|
+
|
|
45
|
+
```toml
|
|
46
|
+
schema = 1 # manifest format version; always 1 for now
|
|
47
|
+
kind = "palette" # layout, theme or palette
|
|
48
|
+
id = "ocean" # must equal the folder name
|
|
49
|
+
title = "Ocean" # readable name shown in lists and controls
|
|
50
|
+
description = "Deep blue with a warm highlight." # optional
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- `id` uses lowercase letters, digits and hyphens and starts with a letter.
|
|
54
|
+
- Unknown settings are errors, so a typo is reported rather than ignored.
|
|
55
|
+
- File references are relative to the extension folder and may not leave it.
|
|
56
|
+
- Manifests are [TOML 1.0](https://toml.io/en/v1.0.0). CSS custom property
|
|
57
|
+
names start with dashes, so quote them as keys: `"--accent" = "#ff0000"`.
|
|
58
|
+
|
|
59
|
+
Problems are reported with the file, the setting and, for syntax errors, the
|
|
60
|
+
line and column:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
extensions/ocean/extension.toml: light.accent: token names look like "--accent"
|
|
64
|
+
extensions/ocean/extension.toml:7:12: incomplete declaration: value expected
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Palette
|
|
68
|
+
|
|
69
|
+
```toml
|
|
70
|
+
schema = 1
|
|
71
|
+
kind = "palette"
|
|
72
|
+
id = "ocean"
|
|
73
|
+
title = "Ocean"
|
|
74
|
+
description = "Deep blue with a warm highlight."
|
|
75
|
+
# theme = "my-theme" # only this theme may use it
|
|
76
|
+
|
|
77
|
+
[light]
|
|
78
|
+
"--bg" = "#f4f8fb"
|
|
79
|
+
"--surface" = "#e6eef4"
|
|
80
|
+
"--ink" = "#0b1d2a"
|
|
81
|
+
"--ink-soft" = "#22394a"
|
|
82
|
+
"--muted" = "#4f6474"
|
|
83
|
+
"--rule" = "#c9d7e2"
|
|
84
|
+
"--accent" = "#0a6aa8"
|
|
85
|
+
"--accent-2" = "#b45309"
|
|
86
|
+
"--on-accent" = "#ffffff"
|
|
87
|
+
|
|
88
|
+
[dark]
|
|
89
|
+
"--bg" = "#102030"
|
|
90
|
+
"--surface" = "#17293b"
|
|
91
|
+
"--ink" = "#eef4f8"
|
|
92
|
+
"--ink-soft" = "#c8d6e0"
|
|
93
|
+
"--muted" = "#8ea3b3"
|
|
94
|
+
"--rule" = "#24384b"
|
|
95
|
+
"--accent" = "#ffbd69"
|
|
96
|
+
"--accent-2" = "#7cc4ff"
|
|
97
|
+
"--on-accent" = "#102030"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`[light]` and `[dark]` each set all nine colours, the shared vocabulary every
|
|
101
|
+
theme uses; see [palettes](palettes.md) for what each one does. The deck's
|
|
102
|
+
`appearance` picks one for the slides; themes use the other for inverted
|
|
103
|
+
slides, as `--inverse-*`. The dark variant also gets dark code colours and an
|
|
104
|
+
inverted logo. `theme` makes the palette private to one theme.
|
|
105
|
+
|
|
106
|
+
## Layout
|
|
107
|
+
|
|
108
|
+
```toml
|
|
109
|
+
schema = 1
|
|
110
|
+
kind = "layout"
|
|
111
|
+
id = "comparison"
|
|
112
|
+
title = "Side-by-side comparison"
|
|
113
|
+
description = "Two options next to each other."
|
|
114
|
+
frame = "standard" # standard, title, chapter or none
|
|
115
|
+
|
|
116
|
+
[files]
|
|
117
|
+
layout = "layout.jsx" # default; may be omitted
|
|
118
|
+
styles = "styles.css" # optional; picked up automatically when present
|
|
119
|
+
starter = "starter.md" # optional; picked up automatically when present
|
|
120
|
+
|
|
121
|
+
[regions.body]
|
|
122
|
+
description = "Heading and introduction"
|
|
123
|
+
|
|
124
|
+
[regions.left]
|
|
125
|
+
required = true
|
|
126
|
+
|
|
127
|
+
[regions.right]
|
|
128
|
+
required = true
|
|
129
|
+
|
|
130
|
+
[properties.emphasis]
|
|
131
|
+
type = "string"
|
|
132
|
+
enum = ["none", "left", "right"]
|
|
133
|
+
default = "none"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`regions` must include `body`. `properties` describe values under a slide's
|
|
137
|
+
`props:` and support `type` (`string`, `number`, `integer`, `boolean`, `array`,
|
|
138
|
+
`object`), `default`, `enum`, `required`, `minimum`, `maximum`, `minItems`,
|
|
139
|
+
`maxItems`, `items`, plus `title` and `description` for editors. Nested
|
|
140
|
+
settings use TOML sub-tables:
|
|
141
|
+
|
|
142
|
+
```toml
|
|
143
|
+
[properties.ratio]
|
|
144
|
+
type = "array"
|
|
145
|
+
minItems = 2
|
|
146
|
+
maxItems = 2
|
|
147
|
+
default = [1, 1]
|
|
148
|
+
|
|
149
|
+
[properties.ratio.items]
|
|
150
|
+
type = "number"
|
|
151
|
+
minimum = 0.01
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The layout file is Preact JSX that imports from `mdeck/layout`. See
|
|
155
|
+
[layouts](layouts.md) for the renderer contract. Layout code runs as part
|
|
156
|
+
of the deck: it is trusted code, not sandboxed data.
|
|
157
|
+
|
|
158
|
+
## Theme
|
|
159
|
+
|
|
160
|
+
```toml
|
|
161
|
+
schema = 1
|
|
162
|
+
kind = "theme"
|
|
163
|
+
id = "my-theme"
|
|
164
|
+
title = "My theme"
|
|
165
|
+
description = "Calm sans-serif slides."
|
|
166
|
+
palette = "lagoon" # the default palette; colours come only from palettes
|
|
167
|
+
# palettes = ["lagoon"] # offer only these palettes
|
|
168
|
+
# appearance = "dark" # start dark
|
|
169
|
+
fonts = [
|
|
170
|
+
"https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap",
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
[files]
|
|
174
|
+
styles = "styles.css" # one stylesheet or a list of them
|
|
175
|
+
|
|
176
|
+
[tokens]
|
|
177
|
+
"--fs-body" = "34px"
|
|
178
|
+
"--font-body" = "\"Inter\", system-ui, sans-serif"
|
|
179
|
+
|
|
180
|
+
[params.fontBody]
|
|
181
|
+
token = "--font-body"
|
|
182
|
+
title = "Body font"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
- `palette` names the palette the theme uses unless the deck sets one. A theme
|
|
186
|
+
has no colours of its own; `tokens` may not set the nine palette colours.
|
|
187
|
+
- `palettes` limits the palettes a theme offers, for a corporate design; it
|
|
188
|
+
must include the default. Without it, every palette not private to another
|
|
189
|
+
theme is offered.
|
|
190
|
+
- `appearance = "dark"` makes the theme start dark.
|
|
191
|
+
- `tokens` are the theme's type, spacing and font values. mdeck generates the
|
|
192
|
+
`:root` block from them, so the stylesheet only contains rules.
|
|
193
|
+
- `params` name the settings authors may change under `params:` in the deck.
|
|
194
|
+
Each points at a token; its default is the token's value, so nothing is
|
|
195
|
+
written twice.
|
|
196
|
+
- `fonts` are stylesheet URLs. Normal builds load them; single files (`mdeck send`,
|
|
197
|
+
`--single-file`) and PDFs embed their Latin character sets, so they look the
|
|
198
|
+
same offline. The fallbacks named in the token values apply when a font
|
|
199
|
+
cannot be fetched.
|
|
200
|
+
|
|
201
|
+
Values are applied in this order: the palette's colours (the deck's variant,
|
|
202
|
+
and the other as `--inverse-*`), the theme's tokens, then deck `params`.
|
|
203
|
+
|
|
204
|
+
## Editing in the browser
|
|
205
|
+
|
|
206
|
+
`mdeck design my-talk.md` (also *Design themes* in `mdeck edit`) opens a
|
|
207
|
+
design page for themes and palettes: forms with a live preview on a sample
|
|
208
|
+
deck that has every built-in layout, or on the deck itself. `mdeck design
|
|
209
|
+
<folder>` does the same without a deck and writes to `<folder>/extensions/`.
|
|
210
|
+
Built-in extensions cannot be changed; copy one under a new id to change it.
|
|
211
|
+
New themes always start as a copy. Layouts are not edited there. The page
|
|
212
|
+
writes the same files described above.
|
|
213
|
+
|
|
214
|
+
## Installed extensions and packs
|
|
215
|
+
|
|
216
|
+
mdeck looks for extensions in three places, in this order: the built-in ones,
|
|
217
|
+
the user's folder (`~/.mdeck/extensions`, or `$MDECK_HOME/extensions`), and the
|
|
218
|
+
`extensions/` folder beside the deck. An id may appear only once, except that a
|
|
219
|
+
deck's own extension replaces a user one with the same id (with a warning).
|
|
220
|
+
`mdeck check` warns when a deck uses a theme or palette from the user's folder,
|
|
221
|
+
because the slide file then works only on that computer.
|
|
222
|
+
|
|
223
|
+
`mdeck themes install <pack>` copies a pack from the theme repository into the
|
|
224
|
+
deck's folder, or with `--global` into the user's. A pack is a folder with a
|
|
225
|
+
`pack.toml` (`schema`, `id`, `title`, `description`, `version`, `author`,
|
|
226
|
+
`license`, `homepage`, and `mdeck = ">=X.Y.Z"`, the oldest mdeck it works with)
|
|
227
|
+
and one folder per theme or palette, each holding only `extension.toml` and,
|
|
228
|
+
for a theme, `styles.css`. Theme fonts must come from `https://fonts.googleapis.com/`
|
|
229
|
+
or `https://fonts.bunny.net/`, and `styles.css` may contain neither `@import`
|
|
230
|
+
nor `url()` other than `data:` URLs. Each installed folder gets a
|
|
231
|
+
`.mdeck-pack.json` with the pack, its version, its source and a checksum of
|
|
232
|
+
every file; `update` and `remove` refuse to touch files changed since then
|
|
233
|
+
unless given `--force`.
|
|
234
|
+
|
|
235
|
+
The repository serves `index.json` (`{ schema: 1, packs: [...] }`, each with
|
|
236
|
+
its ids, `url`, `sha256` and `previews`) and one JSON file per pack version
|
|
237
|
+
holding the text of its files. `mdeck themes build <packs> -o <out> [--check]`
|
|
238
|
+
writes both from a folder of packs; `MDECK_THEMES_URL` points mdeck at another
|
|
239
|
+
index.
|
|
240
|
+
|
|
241
|
+
## Listing what is available
|
|
242
|
+
|
|
243
|
+
```sh
|
|
244
|
+
mdeck list my-talk.md
|
|
245
|
+
mdeck list my-talk.md --json
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The JSON form carries every manifest's title, description, tokens, parameters,
|
|
249
|
+
region requirements and property definitions, so other tools can build
|
|
250
|
+
controls from the same data mdeck uses.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# User-created slide layouts
|
|
2
|
+
|
|
3
|
+
Layouts define slide structure; themes supply typography and colors. Every
|
|
4
|
+
built-in layout and every deck-local layout uses the same registry, manifest,
|
|
5
|
+
property resolver, and slide frame. A local layout requires no framework edit.
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
my-talk/
|
|
9
|
+
slides.md
|
|
10
|
+
extensions/
|
|
11
|
+
comparison/
|
|
12
|
+
extension.toml
|
|
13
|
+
layout.jsx
|
|
14
|
+
styles.css optional
|
|
15
|
+
starter.md optional
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
A layout is one kind of [extension](extensions.md); themes and palettes use
|
|
19
|
+
the same folder and manifest rules. The folder name is the `layout:` value.
|
|
20
|
+
Names must be lowercase letters, digits and hyphens, beginning with a letter.
|
|
21
|
+
A local layout cannot use a built-in's name. Manifests are checked when
|
|
22
|
+
loading, building, listing or validating a deck. The dev server reloads when
|
|
23
|
+
extension files are changed, added or removed.
|
|
24
|
+
|
|
25
|
+
## Manifest
|
|
26
|
+
|
|
27
|
+
```toml
|
|
28
|
+
schema = 1
|
|
29
|
+
kind = "layout"
|
|
30
|
+
id = "comparison"
|
|
31
|
+
title = "Side-by-side comparison"
|
|
32
|
+
|
|
33
|
+
[regions.body]
|
|
34
|
+
description = "Shared heading"
|
|
35
|
+
|
|
36
|
+
[regions.left]
|
|
37
|
+
required = true
|
|
38
|
+
|
|
39
|
+
[regions.right]
|
|
40
|
+
required = true
|
|
41
|
+
|
|
42
|
+
[properties.emphasis]
|
|
43
|
+
type = "string"
|
|
44
|
+
enum = ["none", "left", "right"]
|
|
45
|
+
default = "none"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`regions` must include `body`, which contains unassigned slide Markdown.
|
|
49
|
+
Authors fill additional regions using `:::slot left`, etc. A region can declare
|
|
50
|
+
`required: true` and a human-readable `description`. Unknown region names and
|
|
51
|
+
missing required content are validation errors.
|
|
52
|
+
|
|
53
|
+
`properties` describes values under slide metadata `props:`. Supported types:
|
|
54
|
+
`string`, `number`, `integer`, `boolean`, `array`, `object`. The schema supports
|
|
55
|
+
`required`, `default`, `enum`, numeric `minimum`/`maximum`, array `items`
|
|
56
|
+
(a `[properties.name.items]` sub-table), `minItems`/`maxItems`, and `title`
|
|
57
|
+
and `description` for editors. This is a small schema subset, not full JSON Schema.
|
|
58
|
+
Defaults are copied for each slide. Unknown properties and invalid values are
|
|
59
|
+
errors. Built-ins also accept their legacy top-level properties such as `image:`.
|
|
60
|
+
|
|
61
|
+
An optional `frame` selects `standard` (default), `title`, `chapter`, or `none`.
|
|
62
|
+
The last omits header/footer chrome; it still retains the slide container,
|
|
63
|
+
footnotes, ID, and navigation behavior.
|
|
64
|
+
|
|
65
|
+
## Renderer
|
|
66
|
+
|
|
67
|
+
`layout.jsx` default-exports a Preact component. It renders the slide body:
|
|
68
|
+
|
|
69
|
+
```jsx
|
|
70
|
+
import { h } from 'preact'
|
|
71
|
+
import { MarkdownRegion } from 'mdeck/layout'
|
|
72
|
+
|
|
73
|
+
export default function Comparison({ regions, props }) {
|
|
74
|
+
return <div class="slide-body">
|
|
75
|
+
<MarkdownRegion region={regions.body} />
|
|
76
|
+
<div class="comparison-options">
|
|
77
|
+
<MarkdownRegion region={regions.left} />
|
|
78
|
+
<MarkdownRegion region={regions.right}
|
|
79
|
+
class={props.emphasis === 'right' ? 'is-emphasized' : ''} />
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The component receives `regions`, resolved typed `props`, slide `meta`, `id`,
|
|
86
|
+
default-body `content`, `deckConfig`, `index`, `total`, and `manifest`.
|
|
87
|
+
Use `preact/hooks` for interactive layouts. `MarkdownRegion` renders Markdown
|
|
88
|
+
and hydrates both built-in and deck-local components. It exposes a `data-region`
|
|
89
|
+
attribute for integrations. Footnotes are numbered across all regions and placed
|
|
90
|
+
in the shared frame.
|
|
91
|
+
|
|
92
|
+
For a picture from a property, render `<Picture src={props.image} alt={props.alt}
|
|
93
|
+
fit={props.fit} position={props.position} class="…" />` instead of an `<img>`.
|
|
94
|
+
It is an `<img>` for ordinary pictures; an SVG that uses the palette's colours
|
|
95
|
+
(`var(--accent)` …) is drawn inline so it follows the theme. `themedSvg(src)`
|
|
96
|
+
returns that SVG's markup, or nothing, for layouts that place it themselves.
|
|
97
|
+
|
|
98
|
+
The framework wraps the result in `SlideFrame`; do not add a second `<section>`
|
|
99
|
+
or frame in your renderer. `SlideFrame`, `MarkdownRegion`, and `HtmlContent` are
|
|
100
|
+
also exported from `mdeck/layout` for integrations, and so is `t(key)`, which
|
|
101
|
+
returns a word the audience sees in the deck's language (`t('slide.chapter')`
|
|
102
|
+
is "Chapter", or "Kapitel" with `lang: de`). The API import resolves
|
|
103
|
+
through mdeck's build plugin, including when the deck is outside the framework.
|
|
104
|
+
|
|
105
|
+
Keep CSS scoped to `.slide--comparison` and use theme variables:
|
|
106
|
+
|
|
107
|
+
```css
|
|
108
|
+
.slide--comparison .comparison-options {
|
|
109
|
+
display: grid;
|
|
110
|
+
grid-template-columns: 1fr 1fr;
|
|
111
|
+
gap: 40px;
|
|
112
|
+
}
|
|
113
|
+
.slide--comparison .is-emphasized { color: var(--accent); }
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
JSX imports of assets and dependencies follow the same build rules as deck-local
|
|
117
|
+
components. Layout CSS is included in both bundle and self-contained builds.
|
|
118
|
+
Local paths in Markdown images, media `src`, and `image:`/`props.image` are handled
|
|
119
|
+
by asset packaging. For other custom asset properties, import assets in JSX so
|
|
120
|
+
Vite can track them; arbitrary string properties are not treated as file paths.
|
|
121
|
+
Renderers must consume their declared regions; the framework validates the
|
|
122
|
+
manifest and authored values, but cannot prove what arbitrary JSX renders.
|
|
123
|
+
|
|
124
|
+
## Starters and discovery
|
|
125
|
+
|
|
126
|
+
`starter.md` is an editable slide preset. It should contain explicit `:::meta`
|
|
127
|
+
and placeholder region content, without a leading slide separator. `layout.jsx`,
|
|
128
|
+
`styles.css` and `starter.md` are picked up automatically from the layout
|
|
129
|
+
folder; use a `[files]` table in the manifest to point at different names.
|
|
130
|
+
`mdeck new` lists built-in and local starters found beside the requested output deck.
|
|
131
|
+
|
|
132
|
+
```sh
|
|
133
|
+
mdeck list layouts slides.md
|
|
134
|
+
mdeck list layouts slides.md --json
|
|
135
|
+
mdeck list layouts slides.md --starter comparison
|
|
136
|
+
mdeck list slides.md
|
|
137
|
+
mdeck check slides.md --strict
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The JSON listing is the serializable manifest registry, suitable for completion,
|
|
141
|
+
layout galleries, or future editor inspectors. Listing and validation do not
|
|
142
|
+
execute layout JSX. Packages and a visual editor are not implemented here.
|
|
143
|
+
|
|
144
|
+
Built-in layouts are ordinary layouts under the framework's
|
|
145
|
+
`assets/extensions/layouts/` folder and use the same `mdeck/layout`
|
|
146
|
+
import, so they double as worked examples.
|
|
147
|
+
|
|
148
|
+
See the runnable [custom layout example](../../examples/custom-layouts/slides.md):
|
|
149
|
+
|
|
150
|
+
```sh
|
|
151
|
+
mdeck run examples/custom-layouts/slides.md
|
|
152
|
+
mdeck build examples/custom-layouts/slides.md
|
|
153
|
+
```
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Palettes
|
|
2
|
+
|
|
3
|
+
A palette gives a deck its colours. It is the only place colours come from: themes set type, spacing and layout, and leave colour to the palette, so any palette fits any theme.
|
|
4
|
+
|
|
5
|
+
Every palette is a family with two variants, **light** and **dark**. A deck chooses the family with `palette:` and the variant with `appearance:`. Themes use the *other* variant for inverted slides, such as neue's statement slides, so those stay readable and in tune.
|
|
6
|
+
|
|
7
|
+
## Using a palette
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
---
|
|
11
|
+
theme: neue
|
|
12
|
+
palette: terra # optional; without it the theme's default palette
|
|
13
|
+
appearance: dark # optional: light or dark; without it the theme's default
|
|
14
|
+
---
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The presenter view and the reader view switch palette and light or dark without changing the file. Choose dark for a dark lecture hall, light for a bright seminar room.
|
|
18
|
+
|
|
19
|
+
## Built-in palettes
|
|
20
|
+
|
|
21
|
+
| Palette | Light | Dark |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `lagoon` | teal on warm stone, orange second accent | deep teal-black, bright teal |
|
|
24
|
+
| `swiss` | white, black and signal red | black, white and red |
|
|
25
|
+
| `cobalt` | ultramarine on white, vivid orange second accent | deep navy with a luminous blue |
|
|
26
|
+
| `nordic` | ice grey, deep navy and a cool steel blue | polar night with ice blue |
|
|
27
|
+
| `graphite` | black and white with a steel-blue accent | charcoal with light steel blue |
|
|
28
|
+
| `terra` | cream, deep navy and brick red | deep navy, cream and coral |
|
|
29
|
+
| `forest` | deep green with moss and ochre | forest night with light green |
|
|
30
|
+
| `ember` | sand and espresso with orange | dark brown with glowing orange |
|
|
31
|
+
| `neon` | white with violet and magenta | black with neon violet and pink |
|
|
32
|
+
| `phosphor` | a printout: near-black on paper, green and ochre | a terminal screen: phosphor green on black, amber |
|
|
33
|
+
| `pastel` | Catppuccin Latte: soft grey-blue paper, mauve and peach | Catppuccin Mocha: dusk blue with pastel mauve and peach |
|
|
34
|
+
|
|
35
|
+
`mdeck list palettes` lists them, with any of your own.
|
|
36
|
+
|
|
37
|
+
Each theme names a default: neue uses `swiss`, editorial `terra`, duet `cobalt`, aurora `neon`, terminal `phosphor` (dark), academic `nordic`, sketch `pastel`. The FHNW theme uses its own palette `brand` (FHNW yellow, black and white) and offers no other.
|
|
38
|
+
|
|
39
|
+
## Colours
|
|
40
|
+
|
|
41
|
+
Every variant sets all nine:
|
|
42
|
+
|
|
43
|
+
| Colour | Role |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `--bg` | Slide background |
|
|
46
|
+
| `--surface` | Raised surfaces: code blocks, image panes, cards |
|
|
47
|
+
| `--ink` | Headings and primary text |
|
|
48
|
+
| `--ink-soft` | Body text |
|
|
49
|
+
| `--muted` | Small labels: headers, footers, captions |
|
|
50
|
+
| `--rule` | Lines and dividers |
|
|
51
|
+
| `--accent` | The highlight: emphasis, markers, chapter slides |
|
|
52
|
+
| `--accent-2` | A second highlight for themes that pair two |
|
|
53
|
+
| `--on-accent` | Text set on the accent, such as a chapter slide's title |
|
|
54
|
+
|
|
55
|
+
Themes may mix them (for example a light tint of the accent), and read the other variant as `--inverse-bg`, `--inverse-ink`, `--inverse-accent` and so on.
|
|
56
|
+
|
|
57
|
+
## Making a palette
|
|
58
|
+
|
|
59
|
+
A palette is an [extension](extensions.md): a folder named after it with an `extension.toml`, in `extensions/` beside a deck.
|
|
60
|
+
|
|
61
|
+
```toml
|
|
62
|
+
schema = 1
|
|
63
|
+
kind = "palette"
|
|
64
|
+
id = "harbour"
|
|
65
|
+
title = "Harbour"
|
|
66
|
+
description = "Sea blue and rust on chalk white."
|
|
67
|
+
|
|
68
|
+
[light]
|
|
69
|
+
"--bg" = "#f7f9fa"
|
|
70
|
+
"--surface" = "#e9eef1"
|
|
71
|
+
"--ink" = "#0b1d2a"
|
|
72
|
+
"--ink-soft" = "#22394a"
|
|
73
|
+
"--muted" = "#4f6474"
|
|
74
|
+
"--rule" = "#c9d7e2"
|
|
75
|
+
"--accent" = "#0a6aa8"
|
|
76
|
+
"--accent-2" = "#b45309"
|
|
77
|
+
"--on-accent" = "#ffffff"
|
|
78
|
+
|
|
79
|
+
[dark]
|
|
80
|
+
"--bg" = "#0d1a24"
|
|
81
|
+
"--surface" = "#152635"
|
|
82
|
+
"--ink" = "#eef4f8"
|
|
83
|
+
"--ink-soft" = "#c8d6e0"
|
|
84
|
+
"--muted" = "#8ea3b3"
|
|
85
|
+
"--rule" = "#24384b"
|
|
86
|
+
"--accent" = "#5fb3f0"
|
|
87
|
+
"--accent-2" = "#f59e5b"
|
|
88
|
+
"--on-accent" = "#0d1a24"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Colour names start with dashes, so quote them as TOML keys. A dark variant also gets dark code colours and an inverted logo; set `--logo-filter` or the `--token-*` code colours in `[dark]` to change that.
|
|
92
|
+
|
|
93
|
+
`theme = "my-theme"` makes a palette private: only that theme offers it, as FHNW does with `brand`.
|
|
94
|
+
|
|
95
|
+
## Readability
|
|
96
|
+
|
|
97
|
+
`mdeck check` measures the contrast of your palette's colours and warns when they are too close to read from the back of a room:
|
|
98
|
+
|
|
99
|
+
| Pair | At least |
|
|
100
|
+
|---|---|
|
|
101
|
+
| text (`--ink`) on the background | 7 : 1 |
|
|
102
|
+
| body text and muted text on the background | 4.5 : 1 |
|
|
103
|
+
| both accents on the background | 3 : 1 (large type) |
|
|
104
|
+
| text on the accent | 3 : 1 |
|
|
105
|
+
|
|
106
|
+
The built-in palettes meet these in both variants. A private palette may use its accent only as a surface (FHNW's yellow), so its accents are not checked as text.
|