sdocs-dev 1.0.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.
@@ -0,0 +1,112 @@
1
+ :root {
2
+ --bg: #F7F5F2;
3
+ --bg-surface: #F1EDE8;
4
+ --bg-panel: #EDE8E2;
5
+ --bg-panel-deep: #E7E2DB;
6
+ --bg-input: #FFFFFF;
7
+ --bg-hover: #E8E3DD;
8
+ --bg-active: #E2DDD6;
9
+
10
+ --border: #D4CFC9;
11
+ --border-subtle: #DDD9D3;
12
+ --border-strong: #C5BFB8;
13
+
14
+ --text: #1C1917;
15
+ --text-2: #57534E;
16
+ --text-3: #A8A29E;
17
+ --text-inv: #FAFAF9;
18
+
19
+ --accent: #2563EB;
20
+ --accent-light: #EEF2FF;
21
+ --accent-text: #1D4ED8;
22
+
23
+ --radius-sm: 4px;
24
+ --radius: 6px;
25
+ --radius-md: 8px;
26
+ --radius-lg: 10px;
27
+
28
+ --shadow-sm: 0 1px 2px rgba(28,25,23,.06);
29
+ --shadow: 0 2px 6px rgba(28,25,23,.08), 0 1px 2px rgba(28,25,23,.04);
30
+ --shadow-md: 0 4px 12px rgba(28,25,23,.10), 0 2px 4px rgba(28,25,23,.06);
31
+
32
+ --font-ui: 'Inter', system-ui, -apple-system, sans-serif;
33
+
34
+ --md-h2-border: #EDE8E2;
35
+ --md-toc-border: #E7E2DB;
36
+ --md-pre-border: #E7E2DB;
37
+ --md-bq-bg: #F7F5F2;
38
+ --md-hr-border: #EDE8E2;
39
+ --md-table-border: #E2DDD6;
40
+ --md-table-header-bg: #F4F1ED;
41
+ --md-table-even-bg: #FAFAF8;
42
+ --md-copy-btn-border: rgba(0,0,0,0.12);
43
+ --md-copy-btn-hover: rgba(0,0,0,0.05);
44
+ }
45
+
46
+ /* ═══════════════════════════════════════════════════
47
+ DARK THEME
48
+ ═══════════════════════════════════════════════════ */
49
+ html[data-theme="dark"] {
50
+ --bg: #1C1A17;
51
+ --bg-surface: #252320;
52
+ --bg-panel: #211F1D;
53
+ --bg-panel-deep: #1A1816;
54
+ --bg-input: #2C2926;
55
+ --bg-hover: #32302C;
56
+ --bg-active: #3A3733;
57
+
58
+ --border: #3D3935;
59
+ --border-subtle: #332F2B;
60
+ --border-strong: #4A453F;
61
+
62
+ --text: #E7E5E2;
63
+ --text-2: #A8A29E;
64
+ --text-3: #6B6560;
65
+ --text-inv: #1C1917;
66
+
67
+ --accent: #3B82F6;
68
+ --accent-light: #1E293B;
69
+ --accent-text: #60A5FA;
70
+
71
+ --shadow-sm: 0 1px 2px rgba(0,0,0,.20);
72
+ --shadow: 0 2px 6px rgba(0,0,0,.25), 0 1px 2px rgba(0,0,0,.15);
73
+ --shadow-md: 0 4px 12px rgba(0,0,0,.35), 0 2px 4px rgba(0,0,0,.20);
74
+
75
+ --md-h2-border: #3D3935;
76
+ --md-toc-border: #3D3935;
77
+ --md-pre-border: #3D3935;
78
+ --md-bq-bg: #252320;
79
+ --md-hr-border: #3D3935;
80
+ --md-table-border: #3D3935;
81
+ --md-table-header-bg: #2C2926;
82
+ --md-table-even-bg: #242220;
83
+ --md-copy-btn-border: rgba(255,255,255,0.12);
84
+ --md-copy-btn-hover: rgba(255,255,255,0.06);
85
+ }
86
+ html[data-theme="dark"] :is(#rendered, #write) {
87
+ --md-color: #e7e5e2;
88
+ --md-code-bg: #1a1816;
89
+ --md-code-color: #b8a99a;
90
+ --md-pre-bg: #1a1816;
91
+ --md-link-color: #60a5fa;
92
+ --md-bq-color: #a8a29e;
93
+ }
94
+ html[data-theme="dark"] .control-row select {
95
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%236B6560' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
96
+ }
97
+
98
+ /* Theme transitions */
99
+ body,
100
+ #left,
101
+ #right,
102
+ #export-panel,
103
+ #statusbar,
104
+ #content-area,
105
+ #left-toolbar,
106
+ #right-header,
107
+ #export-panel-header,
108
+ .panel-header,
109
+ .sub-header,
110
+ #raw {
111
+ transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
112
+ }
@@ -0,0 +1,128 @@
1
+ /* ═══════════════════════════════════════════════════
2
+ WRITE MODE
3
+ ═══════════════════════════════════════════════════ */
4
+
5
+ /* ── Write div ── */
6
+ #write {
7
+ display: none;
8
+ outline: none;
9
+ min-height: 100%;
10
+ cursor: text;
11
+ }
12
+ #write:empty::before {
13
+ content: 'Start typing\2026';
14
+ color: var(--text-3);
15
+ pointer-events: none;
16
+ }
17
+
18
+ /* ── Write toolbar ── */
19
+ #write-toolbar {
20
+ display: none;
21
+ align-items: center;
22
+ gap: 2px;
23
+ height: 0;
24
+ opacity: 0;
25
+ padding: 0 12px;
26
+ background: var(--bg);
27
+ border-bottom: 1px solid transparent;
28
+ flex-shrink: 0;
29
+ overflow: hidden;
30
+ transition: height .3s cubic-bezier(.4,0,.2,1),
31
+ opacity .22s ease,
32
+ border-color .3s ease,
33
+ padding .3s cubic-bezier(.4,0,.2,1);
34
+ }
35
+ body.write-mode #write-toolbar {
36
+ position: relative;
37
+ display: flex;
38
+ justify-content: center;
39
+ height: 34px;
40
+ opacity: 1;
41
+ border-bottom-color: var(--border-subtle);
42
+ padding: 0 12px;
43
+ overflow-x: auto;
44
+ overflow-y: hidden;
45
+ -webkit-overflow-scrolling: touch;
46
+ scrollbar-width: none;
47
+ }
48
+ body.write-mode #write-toolbar::-webkit-scrollbar {
49
+ display: none;
50
+ }
51
+
52
+ .write-tb-btn {
53
+ position: relative;
54
+ display: inline-flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ min-width: 28px;
58
+ width: 28px;
59
+ height: 26px;
60
+ flex-shrink: 0;
61
+ border: none;
62
+ background: none;
63
+ color: var(--text-2);
64
+ cursor: pointer;
65
+ border-radius: var(--radius-sm);
66
+ padding: 0;
67
+ font-size: 12px;
68
+ font-family: var(--font-ui);
69
+ font-weight: 600;
70
+ transition: color .12s, background .12s;
71
+ }
72
+ .write-tb-btn:hover {
73
+ color: var(--text);
74
+ background: var(--bg-hover);
75
+ }
76
+ .write-tb-btn.active {
77
+ color: var(--text);
78
+ background: var(--bg-input);
79
+ box-shadow: var(--shadow-sm);
80
+ }
81
+ .write-tb-btn code {
82
+ font-size: 11px;
83
+ font-family: 'JetBrains Mono', monospace;
84
+ background: none;
85
+ padding: 0;
86
+ color: inherit;
87
+ }
88
+
89
+ .write-tb-sep {
90
+ width: 1px;
91
+ height: 16px;
92
+ background: var(--border);
93
+ margin: 6px 0;
94
+ flex-shrink: 0;
95
+ }
96
+
97
+ /* ── Tooltips ── */
98
+ .write-tb-btn[data-tip]::after {
99
+ content: attr(data-tip);
100
+ position: absolute;
101
+ bottom: calc(100% + 6px);
102
+ left: 50%;
103
+ transform: translateX(-50%);
104
+ padding: 3px 8px;
105
+ background: var(--text);
106
+ color: var(--bg);
107
+ font-size: 11px;
108
+ font-weight: 500;
109
+ white-space: nowrap;
110
+ border-radius: 4px;
111
+ pointer-events: none;
112
+ opacity: 0;
113
+ transition: opacity .15s ease;
114
+ }
115
+ .write-tb-btn[data-tip]:hover::after {
116
+ opacity: 1;
117
+ }
118
+
119
+ /* ── Visibility rules ── */
120
+ body.write-mode #write {
121
+ display: block;
122
+ }
123
+ body.write-mode #rendered {
124
+ display: none;
125
+ }
126
+ body.write-mode #raw {
127
+ display: none;
128
+ }
@@ -0,0 +1,129 @@
1
+ ---
2
+ styles:
3
+ fontFamily: "Inter"
4
+ baseFontSize: 16
5
+ lineHeight: 1.75
6
+ headers: { fontFamily: "inherit", scale: 1, marginBottom: 0.4 }
7
+ h1: { fontSize: 2.1, fontWeight: 700 }
8
+ h2: { fontSize: 1.55, fontWeight: 600 }
9
+ h3: { fontSize: 1.2, fontWeight: 600 }
10
+ h4: { fontSize: 1, fontWeight: 600 }
11
+ p: { lineHeight: 1.75, marginBottom: 1.1 }
12
+ link: { color: "#2563eb", decoration: "underline" }
13
+ code: { font: "JetBrains Mono", background: "#f4f1ed", color: "#6b21a8" }
14
+ blockquote: { borderColor: "#2563eb", borderWidth: 3, fontSize: 1, color: "#6b6560" }
15
+ list: { spacing: 0.3, indent: 1.6 }
16
+ ---
17
+ # Say hello to SmallDocs: A markdown-first replacement for Word & GDocs
18
+
19
+ If you're working with agents, a document written in markdown is <ins>officially</ins>* 407 times more useful than a document locked inside a `.docx` or `.gdoc` file format. Because of this, I believe Word and GDocs' days are numbered. (*I am the official.)
20
+
21
+ However, all is not well. While markdown is great for agents, it's a bit annoying for humans. Quickly and elegantly reading a `.md` file requires you to open your code editor and enter "preview" mode. Sharing a markdown file requires you to actually send the file to someone. They then have to download it and find the least annoying way to read it.
22
+
23
+ SmallDocs is an [open source](https://github.com/JoshInLisbon/SDocs) attempt at something different. It lets you (or your agent) easily, elegantly and privately **read**, **share**, **format** and **export** `.md` files.
24
+
25
+ Reading a `.md` file in SmallDocs feels just like this (you're reading markdown right now). And creating a SmallDoc for a `.md` file (+ automatically opening your browser to read it) is as simple as:
26
+
27
+ ```
28
+ # npm i sdocs-dev
29
+ sdoc README.md
30
+ ```
31
+
32
+ ## How SmallDocs work
33
+
34
+ ### Formatting
35
+
36
+ SDocs adds basic styling to markdown files. You write your content in regular markdown and the styles live in a metadata block at the top of the file.
37
+
38
+ That metadata block is called [YAML front matter](https://jekyllrb.com/docs/front-matter/). It's a convention that started with [Jekyll](https://jekyllrb.com/) (the static site generator) back in 2008 and has since been adopted by [Hugo](https://gohugo.io/), [Gatsby](https://www.gatsbyjs.com/), [Obsidian](https://obsidian.md/), and most of the markdown ecosystem. It looks like a block of key-value pairs between two `---` lines at the top of your file:
39
+
40
+ ```yaml
41
+ ---
42
+ title: My Document
43
+ author: Someone
44
+ ---
45
+ ```
46
+
47
+ SDocs uses a `styles:` key with CSS properties written beneath it in YAML:
48
+
49
+ ```yaml
50
+ ---
51
+ styles:
52
+ fontFamily: Lora
53
+ baseFontSize: 17
54
+ color: "#1a1a2e"
55
+ h1: { fontSize: 2.3, color: "#c0392b", fontWeight: 700 }
56
+ p: { lineHeight: 1.9, marginBottom: 1.2 }
57
+ ---
58
+ ```
59
+
60
+ (Click "**Raw**" — top left — to see the front matter for this file. See all available properties [here](https://sdocs.dev) or by running `npm i sdocs-dev; sdoc schema`.)
61
+
62
+ When a `Styled .md` file is rendered in the SmallDocs interface the specified styles are applied. If a plain `.md` file is rendered the default styles are applied.
63
+
64
+ ### URLs
65
+
66
+ The URL format for SmallDocs is:
67
+
68
+ ```
69
+ https://sdocs.dev/#md={compressed & encoded .md}
70
+ ```
71
+
72
+ Your entire document (content and styles) lives in the URL hash.
73
+
74
+ To keep URLs as short as possible, SmallDocs compresses your markdown using [deflate](https://en.wikipedia.org/wiki/Deflate) (a standard compression algorithm built into every browser) and then encodes the result with [base64url](https://en.wikipedia.org/wiki/Base64#URL_applications) (a URL-safe variant of base64 that avoids characters like `+`, `/`, and `=` which would otherwise need percent-encoding).
75
+
76
+ The `mode` parameter controls which view opens. Valid values are `read` (clean reading view, style panel hidden), `style` (style panel visible), and `raw` (raw markdown editor). When sharing a link for someone to read, use `mode=read`:
77
+
78
+ ```
79
+ https://sdocs.dev/#md=...&mode=read
80
+ ```
81
+
82
+ You can also link directly to a section using the `sec` parameter. Click any heading's link icon to copy its section URL:
83
+
84
+ ```
85
+ https://sdocs.dev/#md=...&sec=url-formatting
86
+ ```
87
+
88
+ The `sec` value is the heading text slugified (lowercased, spaces become hyphens, special characters stripped). The page will scroll to that section on load.
89
+
90
+ ### Privacy
91
+
92
+ Your document never hits the SDocs server. This layer of privacy is built into how HTTP works. The hash fragment (everything after the `#` in a URL) is never sent to the server by the browser. It always stays entirely client-side:
93
+
94
+ > "The fragment is not sent to the server when the URI is requested; it is processed by the client" - [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Fragment)
95
+
96
+ The [sdocs.dev](https://sdocs.dev) site is purely a rendering space. JavaScript reads `window.location.hash`, decompresses and decodes the content, and renders your `.md` locally. The server is about 60 lines of Node.js that serves static files — no database, no logging, no analytics.
97
+
98
+ ### Auto-save
99
+
100
+ Because the URL includes your full document and dynamically updates via JavaScript, every change you make is instantly preserved in the URL. This works when you're offline.
101
+
102
+ ### Drag & drop
103
+
104
+ Drag any `.md` file onto the editor to SmallDoc it instantly.
105
+
106
+ ### Exports
107
+
108
+ SmallDocs can export your document in four formats:
109
+
110
+ - **Raw .md** — your markdown content with all front matter stripped. Plain markdown, compatible with anything.
111
+ - **PDF** — a styled PDF generated from the rendered view via the browser's print engine.
112
+ - **Word (.docx)** — a styled Word document generated from the rendered HTML.
113
+ - **Styled .md** — your markdown with the `styles:` front matter block included. This is the format SmallDocs reads back in, so your formatting is preserved.
114
+
115
+ ### Small opinionated things
116
+
117
+ SmallDocs has opinions. We do some things which might not work for everyone but hopefully make the general `.md` experience better for most.
118
+
119
+ We welcome your opinions. Raise an issue on GitHub or make a pull request if you want something to change.
120
+
121
+ #### Collapsed headers
122
+
123
+ SmallDocs loads with all headers collapsed. This is done because it makes it easy to get an overview of the whole document.
124
+
125
+ If you expand a parent, all of its children expand too.
126
+
127
+ #### Copy & paste
128
+
129
+ Every header has its own copy and paste button. This copies its content and all of its children's content. At the moment this is the fastest way to get SmallDoc content into your agent's context, but we're looking for novel ideas to make this better.