@kadal/theme-folio 0.0.0-stage → 0.4.1

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.
Files changed (5) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +66 -2
  3. package/index.tsx +115 -0
  4. package/package.json +106 -4
  5. package/style.css +729 -0
package/README.md CHANGED
@@ -1,3 +1,67 @@
1
- # Temporary Holding Version
1
+ # @kadal/theme-folio
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **Folio**, a theme for [Kadal Deck](https://deck.kadal.cc). An editorial theme for essays and keynotes. Warm paper and ink, Playfair Display for the display lines, Newsreader for reading text, IBM Plex Mono for code; one oxblood accent and a gilt second. Generous margins, a measure kept to reading length, booktabs tables, an asterism for a rule, small capitals for labels, a fleuron over a section.
4
+
5
+ ![Folio: the cover, a content slide, code and the theme's own layout](./screenshot.jpg)
6
+
7
+ ## Use it
8
+
9
+ ```bash
10
+ npm install @kadal/theme-folio
11
+ ```
12
+
13
+ ```yaml
14
+ ---
15
+ theme: folio
16
+ themeConfig: # all optional
17
+ paper: "#f6f0e4"
18
+ accent: "#9b2c1c"
19
+ accentDark: "#e8957c"
20
+ ---
21
+ ```
22
+
23
+ The deck plugin brings the stylesheet and the module in; nothing to import. The prebuilt shell (the hosted builder, published decks) bundles this theme already. Schemes: light and dark. Fonts: Playfair Display (headings), Newsreader (text, `--deck-serif-font`), IBM Plex Mono (code), loaded through the theme's `config.fonts`. Code colours: Shiki's gruvbox-light-soft / gruvbox-dark-soft. To show it beside other themes in the theme menu (<kbd>T</kbd>), list it: `themes: [folio, minimal]`.
24
+
25
+ ## themeConfig
26
+
27
+ Every key arrives on the deck root as a CSS variable (`accentDark` → `--theme-accent-dark`); the theme reads them with fallbacks, so set only what you change.
28
+
29
+ | key | type | default | what it does |
30
+ | --- | --- | --- | --- |
31
+ | `paper` | colour | `#f6f0e4` | The light page's colour. |
32
+ | `accent` | colour | `#9b2c1c` | The light scheme's accent (oxblood). |
33
+ | `accentDark` | colour | `#e8957c` | The dark scheme's accent. Without it, a set `accent` is lifted towards white. |
34
+
35
+ ## Layouts
36
+
37
+ Every built-in layout is styled (`default`, `center`, `cover`, `intro`, `section`, `end`, `fact`, `quote`, `statement`, `full`, `two-cols`, `two-cols-header`, `image`, `image-left`, `image-right`, `iframe`, `iframe-left`, `iframe-right`), and the theme adds:
38
+
39
+ | layout | what |
40
+ | --- | --- |
41
+ | `pull-quote` | The line that carries the piece, between an accent rule and a hairline; `by:` sets the attribution. |
42
+ | `essay` | One column at reading measure with a drop cap; an `::aside::` slot becomes a note in the margin. |
43
+ | `chapter` | A chapter opener: "Chapter" and its roman numeral (counted from the deck's chapter slides, or `n:`; `label:` changes the word), the title, and an epigraph if the slide has a blockquote. |
44
+
45
+ ## Components
46
+
47
+ | component | what |
48
+ | --- | --- |
49
+ | `<Byline author date place />` | Author, date and place between two hairlines, in small capitals. |
50
+ | `<Lede>…</Lede>` | The opening paragraph, larger, with a drop cap. |
51
+
52
+ ## Preview
53
+
54
+ `preview/deck.mdx` walks through every layout and component (`theme: ../`). In this repository:
55
+
56
+ ```bash
57
+ bun run --filter @kadal/theme-folio dev # the preview deck, live
58
+ node tools/theme-shots.mjs folio # screenshots in light and dark, contrast and overflow checks
59
+ ```
60
+
61
+ ## Accessibility and print
62
+
63
+ Body and muted text meet WCAG AA (4.5:1) on the page and on cards in every scheme the theme draws (checked by `tools/theme-shots.mjs`). Anything that moves stands still under `prefers-reduced-motion` and on a still copy; printed pages and exports drop shadows and glows.
64
+
65
+ ## Licence
66
+
67
+ AGPL-3.0-or-later, like the engine (see LICENSE); a commercial licence is available — see [LICENSING](https://github.com/kadalcc/deck/blob/main/LICENSING.md).
package/index.tsx ADDED
@@ -0,0 +1,115 @@
1
+ import type { ReactNode } from "react";
2
+
3
+ import { type LayoutProps, useDeck, useSlideOptional } from "@kadal/deck";
4
+
5
+ /**
6
+ * ─────────────────────────────────────────────────────────────────────────────
7
+ * Folio's module: the layouts an essay or a keynote reaches for, and two pieces of furniture.
8
+ *
9
+ * layout: pull-quote the line that carries the piece, between an accent rule and a hairline;
10
+ * `by:` sets the attribution
11
+ * layout: essay one column at reading measure with a drop cap; `::aside::` is a note
12
+ * in the margin
13
+ * layout: chapter a chapter opener: "Chapter" and its roman numeral (counted, or `n:`),
14
+ * the title, and an epigraph if the slide has a blockquote
15
+ * <Byline> author, date and place between two hairlines, in small capitals
16
+ * <Lede> the opening paragraph, larger, with a drop cap
17
+ * ─────────────────────────────────────────────────────────────────────────────
18
+ */
19
+
20
+ const str = (v: unknown) => (typeof v === "string" && v.trim() ? v.trim() : null);
21
+
22
+ function PullQuote({ children, frontmatter }: LayoutProps) {
23
+ const by = str(frontmatter.by);
24
+ return (
25
+ <div className="deck-layout deck-layout-pull-quote">
26
+ <figure className="folio-pull">
27
+ {children}
28
+ {by ? <figcaption className="folio-pull-by">{by}</figcaption> : null}
29
+ </figure>
30
+ </div>
31
+ );
32
+ }
33
+
34
+ function Essay({ children }: LayoutProps) {
35
+ return <div className="deck-layout deck-layout-essay">{children}</div>;
36
+ }
37
+
38
+ const ROMAN: Array<[number, string]> = [
39
+ [1000, "M"],
40
+ [900, "CM"],
41
+ [500, "D"],
42
+ [400, "CD"],
43
+ [100, "C"],
44
+ [90, "XC"],
45
+ [50, "L"],
46
+ [40, "XL"],
47
+ [10, "X"],
48
+ [9, "IX"],
49
+ [5, "V"],
50
+ [4, "IV"],
51
+ [1, "I"],
52
+ ];
53
+ function roman(n: number): string {
54
+ let out = "";
55
+ let left = Math.max(1, Math.floor(n));
56
+ for (const [v, s] of ROMAN)
57
+ while (left >= v) {
58
+ out += s;
59
+ left -= v;
60
+ }
61
+ return out;
62
+ }
63
+
64
+ function Chapter({ children, frontmatter }: LayoutProps) {
65
+ const deck = useDeck();
66
+ const index = useSlideOptional()?.meta.index ?? 0;
67
+ const counted = deck.manifest.slides.filter(
68
+ (s) => s.index <= index && s.frontmatter.layout === "chapter",
69
+ ).length;
70
+ const given = frontmatter.n == null ? "" : String(frontmatter.n).trim();
71
+ const numeral = given ? (/^\d+$/.test(given) ? roman(Number(given)) : given) : roman(counted);
72
+ return (
73
+ <div className="deck-layout deck-layout-chapter">
74
+ <div className="folio-chapter-number">
75
+ {str(frontmatter.label) ?? "Chapter"}
76
+ <b>{numeral}</b>
77
+ </div>
78
+ {children}
79
+ </div>
80
+ );
81
+ }
82
+
83
+ function Byline({
84
+ author,
85
+ date,
86
+ place,
87
+ children,
88
+ }: {
89
+ author?: string;
90
+ date?: string;
91
+ place?: string;
92
+ children?: ReactNode;
93
+ }) {
94
+ return (
95
+ <div className="folio-byline">
96
+ {author ? (
97
+ <span>
98
+ By <b>{author}</b>
99
+ </span>
100
+ ) : null}
101
+ {date ? <span>{date}</span> : null}
102
+ {place ? <span>{place}</span> : null}
103
+ {children}
104
+ </div>
105
+ );
106
+ }
107
+
108
+ function Lede({ children }: { children?: ReactNode }) {
109
+ return <div className="folio-lede">{children}</div>;
110
+ }
111
+
112
+ export default {
113
+ layouts: { "pull-quote": PullQuote, essay: Essay, chapter: Chapter },
114
+ components: { Byline, Lede },
115
+ };
package/package.json CHANGED
@@ -1,6 +1,108 @@
1
1
  {
2
2
  "name": "@kadal/theme-folio",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.4.1",
4
+ "description": "Folio, a theme for Kadal Deck (@kadal/deck). An editorial serif theme for essays and keynotes: warm paper, a high-contrast display serif, generous whitespace.",
5
+ "keywords": [
6
+ "kadal-theme",
7
+ "kadal-deck",
8
+ "presentation",
9
+ "slides",
10
+ "theme",
11
+ "editorial",
12
+ "serif",
13
+ "essay",
14
+ "keynote"
15
+ ],
16
+ "homepage": "https://deck.kadal.cc/docs/",
17
+ "funding": {
18
+ "type": "github",
19
+ "url": "https://github.com/sponsors/pmithunish"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/kadalcc/deck.git",
24
+ "directory": "packages/theme-folio"
25
+ },
26
+ "bugs": {
27
+ "url": "https://github.com/kadalcc/deck/issues"
28
+ },
29
+ "license": "AGPL-3.0-or-later",
30
+ "author": "Mithunish Prabhakaran <pmithunish@gmail.com>",
31
+ "type": "module",
32
+ "sideEffects": [
33
+ "*.css"
34
+ ],
35
+ "files": [
36
+ "style.css",
37
+ "index.tsx",
38
+ "README.md",
39
+ "LICENSE"
40
+ ],
41
+ "exports": {
42
+ ".": "./index.tsx",
43
+ "./style.css": "./style.css",
44
+ "./package.json": "./package.json"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public",
48
+ "provenance": true
49
+ },
50
+ "kadal": {
51
+ "theme": {
52
+ "name": "folio",
53
+ "title": "Folio",
54
+ "description": "An editorial serif theme for essays and keynotes: warm paper, a high-contrast display serif, generous whitespace.",
55
+ "colorScheme": "both",
56
+ "config": {
57
+ "transition": "fade",
58
+ "fonts": {
59
+ "heading": "Playfair Display, Georgia, serif",
60
+ "serif": "Newsreader, Georgia",
61
+ "mono": "IBM Plex Mono",
62
+ "local": [
63
+ "Georgia"
64
+ ],
65
+ "weights": "400,500,600,700",
66
+ "italic": true
67
+ }
68
+ },
69
+ "themeConfig": {
70
+ "paper": "#f6f0e4"
71
+ },
72
+ "shiki": {
73
+ "light": "gruvbox-light-soft",
74
+ "dark": "gruvbox-dark-soft"
75
+ },
76
+ "defaults": {},
77
+ "layouts": [
78
+ "pull-quote",
79
+ "essay",
80
+ "chapter"
81
+ ],
82
+ "components": [
83
+ "Byline",
84
+ "Lede"
85
+ ]
86
+ }
87
+ },
88
+ "scripts": {
89
+ "dev": "kadal-deck dev -C preview",
90
+ "check": "kadal-deck check -C preview",
91
+ "typecheck": "tsc --noEmit",
92
+ "test": "bun test"
93
+ },
94
+ "peerDependencies": {
95
+ "@kadal/deck": "^0.4.1",
96
+ "react": "^19.2.0"
97
+ },
98
+ "devDependencies": {
99
+ "@kadal/deck": "workspace:*",
100
+ "@types/react": "^19.2.0",
101
+ "@types/react-dom": "^19.2.0",
102
+ "@vitejs/plugin-react": "^6.0.2",
103
+ "react": "^19.2.7",
104
+ "react-dom": "^19.2.7",
105
+ "typescript": "^6.0.3",
106
+ "vite": "^8.0.16"
107
+ }
108
+ }