inkpen 0.7.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 (95) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.rubocop.yml +8 -0
  4. data/.yardopts +11 -0
  5. data/CLAUDE.md +141 -0
  6. data/README.md +409 -0
  7. data/Rakefile +19 -0
  8. data/app/assets/javascripts/inkpen/controllers/editor_controller.js +2050 -0
  9. data/app/assets/javascripts/inkpen/controllers/sticky_toolbar_controller.js +667 -0
  10. data/app/assets/javascripts/inkpen/controllers/toolbar_controller.js +693 -0
  11. data/app/assets/javascripts/inkpen/export/html.js +637 -0
  12. data/app/assets/javascripts/inkpen/export/index.js +30 -0
  13. data/app/assets/javascripts/inkpen/export/markdown.js +697 -0
  14. data/app/assets/javascripts/inkpen/export/pdf.js +372 -0
  15. data/app/assets/javascripts/inkpen/extensions/advanced_table.js +640 -0
  16. data/app/assets/javascripts/inkpen/extensions/block_commands.js +300 -0
  17. data/app/assets/javascripts/inkpen/extensions/block_gutter.js +338 -0
  18. data/app/assets/javascripts/inkpen/extensions/callout.js +303 -0
  19. data/app/assets/javascripts/inkpen/extensions/columns.js +403 -0
  20. data/app/assets/javascripts/inkpen/extensions/database.js +990 -0
  21. data/app/assets/javascripts/inkpen/extensions/document_section.js +352 -0
  22. data/app/assets/javascripts/inkpen/extensions/drag_handle.js +407 -0
  23. data/app/assets/javascripts/inkpen/extensions/embed.js +629 -0
  24. data/app/assets/javascripts/inkpen/extensions/enhanced_image.js +566 -0
  25. data/app/assets/javascripts/inkpen/extensions/export_commands.js +271 -0
  26. data/app/assets/javascripts/inkpen/extensions/file_attachment.js +593 -0
  27. data/app/assets/javascripts/inkpen/extensions/inkpen_table/index.js +58 -0
  28. data/app/assets/javascripts/inkpen/extensions/inkpen_table/inkpen_table.js +638 -0
  29. data/app/assets/javascripts/inkpen/extensions/inkpen_table/inkpen_table_cell.js +100 -0
  30. data/app/assets/javascripts/inkpen/extensions/inkpen_table/inkpen_table_header.js +100 -0
  31. data/app/assets/javascripts/inkpen/extensions/inkpen_table/table_constants.js +152 -0
  32. data/app/assets/javascripts/inkpen/extensions/inkpen_table/table_helpers.js +254 -0
  33. data/app/assets/javascripts/inkpen/extensions/inkpen_table/table_menu.js +282 -0
  34. data/app/assets/javascripts/inkpen/extensions/preformatted.js +239 -0
  35. data/app/assets/javascripts/inkpen/extensions/section.js +281 -0
  36. data/app/assets/javascripts/inkpen/extensions/section_title.js +126 -0
  37. data/app/assets/javascripts/inkpen/extensions/slash_commands.js +439 -0
  38. data/app/assets/javascripts/inkpen/extensions/table_of_contents.js +474 -0
  39. data/app/assets/javascripts/inkpen/extensions/toggle_block.js +332 -0
  40. data/app/assets/javascripts/inkpen/index.js +87 -0
  41. data/app/assets/stylesheets/inkpen/advanced_table.css +514 -0
  42. data/app/assets/stylesheets/inkpen/animations.css +626 -0
  43. data/app/assets/stylesheets/inkpen/block_gutter.css +265 -0
  44. data/app/assets/stylesheets/inkpen/callout.css +359 -0
  45. data/app/assets/stylesheets/inkpen/columns.css +314 -0
  46. data/app/assets/stylesheets/inkpen/database.css +658 -0
  47. data/app/assets/stylesheets/inkpen/document_section.css +305 -0
  48. data/app/assets/stylesheets/inkpen/drag_drop.css +220 -0
  49. data/app/assets/stylesheets/inkpen/editor.css +652 -0
  50. data/app/assets/stylesheets/inkpen/embed.css +468 -0
  51. data/app/assets/stylesheets/inkpen/enhanced_image.css +453 -0
  52. data/app/assets/stylesheets/inkpen/export.css +499 -0
  53. data/app/assets/stylesheets/inkpen/file_attachment.css +347 -0
  54. data/app/assets/stylesheets/inkpen/footnotes.css +136 -0
  55. data/app/assets/stylesheets/inkpen/inkpen_table.css +608 -0
  56. data/app/assets/stylesheets/inkpen/preformatted.css +215 -0
  57. data/app/assets/stylesheets/inkpen/search_replace.css +58 -0
  58. data/app/assets/stylesheets/inkpen/section.css +236 -0
  59. data/app/assets/stylesheets/inkpen/slash_menu.css +252 -0
  60. data/app/assets/stylesheets/inkpen/sticky_toolbar.css +314 -0
  61. data/app/assets/stylesheets/inkpen/toc.css +386 -0
  62. data/app/assets/stylesheets/inkpen/toggle.css +260 -0
  63. data/app/helpers/inkpen/editor_helper.rb +114 -0
  64. data/app/views/inkpen/_editor.html.erb +139 -0
  65. data/config/importmap.rb +170 -0
  66. data/docs/.DS_Store +0 -0
  67. data/docs/CHANGELOG.md +571 -0
  68. data/docs/FEATURES.md +436 -0
  69. data/docs/ROADMAP.md +3029 -0
  70. data/docs/VISION.md +235 -0
  71. data/docs/extensions/INKPEN_TABLE.md +482 -0
  72. data/docs/thinking/CORRECTED_NO_VUE.md +756 -0
  73. data/docs/thinking/EXECUTIVE_SUMMARY.md +403 -0
  74. data/docs/thinking/INKPEN_CODE_SAMPLES.md +1479 -0
  75. data/docs/thinking/INKPEN_MASTER_GUIDE.md +891 -0
  76. data/docs/thinking/README_START_HERE.md +341 -0
  77. data/lib/inkpen/configuration.rb +175 -0
  78. data/lib/inkpen/editor.rb +204 -0
  79. data/lib/inkpen/engine.rb +32 -0
  80. data/lib/inkpen/extensions/base.rb +109 -0
  81. data/lib/inkpen/extensions/code_block_syntax.rb +177 -0
  82. data/lib/inkpen/extensions/document_section.rb +111 -0
  83. data/lib/inkpen/extensions/forced_document.rb +183 -0
  84. data/lib/inkpen/extensions/mention.rb +155 -0
  85. data/lib/inkpen/extensions/preformatted.rb +111 -0
  86. data/lib/inkpen/extensions/section.rb +139 -0
  87. data/lib/inkpen/extensions/slash_commands.rb +100 -0
  88. data/lib/inkpen/extensions/table.rb +182 -0
  89. data/lib/inkpen/extensions/task_list.rb +145 -0
  90. data/lib/inkpen/sticky_toolbar.rb +157 -0
  91. data/lib/inkpen/toolbar.rb +145 -0
  92. data/lib/inkpen/version.rb +5 -0
  93. data/lib/inkpen.rb +101 -0
  94. data/sig/inkpen.rbs +4 -0
  95. metadata +165 -0
@@ -0,0 +1,265 @@
1
+ /* ==========================================================================
2
+ Block Gutter Styles
3
+ ==========================================================================
4
+
5
+ Left-side gutter with drag handles and plus buttons for each block.
6
+ Similar to Notion/Editor.js block handles.
7
+
8
+ @since 0.3.1
9
+ ========================================================================== */
10
+
11
+ /* ==========================================================================
12
+ Gutter Container
13
+ ========================================================================== */
14
+
15
+ .inkpen-block-gutter-container {
16
+ position: absolute;
17
+ top: 0;
18
+ left: 0;
19
+ width: 3rem;
20
+ height: 100%;
21
+ pointer-events: none;
22
+ z-index: 10;
23
+ }
24
+
25
+ /* ==========================================================================
26
+ Individual Gutter
27
+ ========================================================================== */
28
+
29
+ .inkpen-block-gutter {
30
+ position: absolute;
31
+ left: 0;
32
+ display: flex;
33
+ align-items: center;
34
+ gap: 0.125rem;
35
+ padding: 0.25rem;
36
+ opacity: 0;
37
+ pointer-events: auto;
38
+ transition: opacity 150ms ease;
39
+ transform: translateX(0);
40
+ }
41
+
42
+ /* Show on hover or when visible class is applied */
43
+ .inkpen-block-gutter.is-visible,
44
+ .inkpen-block-gutter:hover {
45
+ opacity: 1;
46
+ }
47
+
48
+ /* Hide during drag unless it's the dragged element */
49
+ .is-block-dragging .inkpen-block-gutter:not(.is-dragging) {
50
+ opacity: 0.3;
51
+ }
52
+
53
+ .inkpen-block-gutter.is-dragging {
54
+ opacity: 1;
55
+ }
56
+
57
+ /* ==========================================================================
58
+ Buttons (Drag Handle & Plus)
59
+ ========================================================================== */
60
+
61
+ .inkpen-block-gutter__drag,
62
+ .inkpen-block-gutter__plus {
63
+ display: flex;
64
+ align-items: center;
65
+ justify-content: center;
66
+ width: 1.25rem;
67
+ height: 1.25rem;
68
+ padding: 0;
69
+ background: transparent;
70
+ border: none;
71
+ border-radius: 0.25rem;
72
+ color: var(--inkpen-color-text-muted, #9ca3af);
73
+ cursor: pointer;
74
+ transition: background-color 100ms ease, color 100ms ease, transform 100ms ease;
75
+ outline: none;
76
+ }
77
+
78
+ .inkpen-block-gutter__drag:hover,
79
+ .inkpen-block-gutter__plus:hover {
80
+ background: var(--inkpen-color-selection, rgba(59, 130, 246, 0.1));
81
+ color: var(--inkpen-color-text, #374151);
82
+ }
83
+
84
+ .inkpen-block-gutter__drag:focus-visible,
85
+ .inkpen-block-gutter__plus:focus-visible {
86
+ outline: 2px solid var(--inkpen-color-primary, #3b82f6);
87
+ outline-offset: 1px;
88
+ }
89
+
90
+ /* Drag Handle */
91
+ .inkpen-block-gutter__drag {
92
+ cursor: grab;
93
+ }
94
+
95
+ .inkpen-block-gutter__drag:active {
96
+ cursor: grabbing;
97
+ transform: scale(1.1);
98
+ }
99
+
100
+ .inkpen-block-gutter__drag svg {
101
+ width: 14px;
102
+ height: 14px;
103
+ }
104
+
105
+ /* Plus Button */
106
+ .inkpen-block-gutter__plus:hover {
107
+ background: var(--inkpen-color-primary, #3b82f6);
108
+ color: white;
109
+ }
110
+
111
+ .inkpen-block-gutter__plus:active {
112
+ transform: scale(0.95);
113
+ }
114
+
115
+ .inkpen-block-gutter__plus svg {
116
+ width: 12px;
117
+ height: 12px;
118
+ }
119
+
120
+ /* ==========================================================================
121
+ Editor Adjustments
122
+ ========================================================================== */
123
+
124
+ /* Add left padding to make room for gutter */
125
+ .inkpen-editor__content.has-gutter {
126
+ padding-left: 3rem;
127
+ }
128
+
129
+ /* ==========================================================================
130
+ Drag State
131
+ ========================================================================== */
132
+
133
+ .is-block-dragging {
134
+ cursor: grabbing !important;
135
+ }
136
+
137
+ .is-block-dragging * {
138
+ cursor: grabbing !important;
139
+ }
140
+
141
+ /* Drop indicator line */
142
+ .inkpen-drop-indicator {
143
+ position: absolute;
144
+ left: 0;
145
+ right: 0;
146
+ height: 3px;
147
+ background: var(--inkpen-color-primary, #3b82f6);
148
+ border-radius: 1.5px;
149
+ pointer-events: none;
150
+ z-index: 100;
151
+ }
152
+
153
+ .inkpen-drop-indicator::before,
154
+ .inkpen-drop-indicator::after {
155
+ content: '';
156
+ position: absolute;
157
+ top: 50%;
158
+ width: 8px;
159
+ height: 8px;
160
+ background: var(--inkpen-color-primary, #3b82f6);
161
+ border-radius: 50%;
162
+ transform: translateY(-50%);
163
+ }
164
+
165
+ .inkpen-drop-indicator::before {
166
+ left: -4px;
167
+ }
168
+
169
+ .inkpen-drop-indicator::after {
170
+ right: -4px;
171
+ }
172
+
173
+ /* ==========================================================================
174
+ Dark Mode
175
+ ========================================================================== */
176
+
177
+ @media (prefers-color-scheme: dark) {
178
+ .inkpen-block-gutter__drag,
179
+ .inkpen-block-gutter__plus {
180
+ color: var(--inkpen-color-text-muted, #6b7280);
181
+ }
182
+
183
+ .inkpen-block-gutter__drag:hover,
184
+ .inkpen-block-gutter__plus:hover {
185
+ background: var(--inkpen-color-selection, rgba(59, 130, 246, 0.2));
186
+ color: var(--inkpen-color-text, #e5e7eb);
187
+ }
188
+ }
189
+
190
+ /* ==========================================================================
191
+ Animations
192
+ ========================================================================== */
193
+
194
+ @keyframes inkpen-gutter-fade-in {
195
+ from {
196
+ opacity: 0;
197
+ transform: translateX(-4px);
198
+ }
199
+ to {
200
+ opacity: 1;
201
+ transform: translateX(0);
202
+ }
203
+ }
204
+
205
+ .inkpen-block-gutter.is-visible {
206
+ animation: inkpen-gutter-fade-in 150ms ease-out;
207
+ }
208
+
209
+ /* ==========================================================================
210
+ Mobile / Touch
211
+ ========================================================================== */
212
+
213
+ @media (max-width: 768px) {
214
+ .inkpen-block-gutter-container {
215
+ width: 2.5rem;
216
+ }
217
+
218
+ .inkpen-block-gutter {
219
+ padding: 0.125rem;
220
+ }
221
+
222
+ .inkpen-block-gutter__drag,
223
+ .inkpen-block-gutter__plus {
224
+ width: 1.5rem;
225
+ height: 1.5rem;
226
+ }
227
+
228
+ /* Always show gutters on mobile (no hover) */
229
+ .inkpen-block-gutter {
230
+ opacity: 0.5;
231
+ }
232
+
233
+ .inkpen-block-gutter:active {
234
+ opacity: 1;
235
+ }
236
+ }
237
+
238
+ /* ==========================================================================
239
+ Print
240
+ ========================================================================== */
241
+
242
+ @media print {
243
+ .inkpen-block-gutter-container {
244
+ display: none;
245
+ }
246
+ }
247
+
248
+ /* ==========================================================================
249
+ Reduced Motion
250
+ ========================================================================== */
251
+
252
+ @media (prefers-reduced-motion: reduce) {
253
+ .inkpen-block-gutter {
254
+ transition: none;
255
+ }
256
+
257
+ .inkpen-block-gutter.is-visible {
258
+ animation: none;
259
+ }
260
+
261
+ .inkpen-block-gutter__drag,
262
+ .inkpen-block-gutter__plus {
263
+ transition: none;
264
+ }
265
+ }
@@ -0,0 +1,359 @@
1
+ /**
2
+ * Callout Block Styles for Inkpen Editor
3
+ *
4
+ * Highlighted blocks for tips, warnings, notes, etc.
5
+ *
6
+ * @since 0.3.3
7
+ */
8
+
9
+ /* ==========================================================================
10
+ CSS Custom Properties
11
+ ========================================================================== */
12
+
13
+ :root {
14
+ /* Base callout */
15
+ --inkpen-callout-radius: 6px;
16
+ --inkpen-callout-padding: 1rem;
17
+ --inkpen-callout-border-width: 4px;
18
+ --inkpen-callout-icon-size: 1.5rem;
19
+ --inkpen-callout-gap: 0.75rem;
20
+
21
+ /* Info (blue) */
22
+ --inkpen-callout-info-bg: #eff6ff;
23
+ --inkpen-callout-info-border: #3b82f6;
24
+ --inkpen-callout-info-text: #1e40af;
25
+
26
+ /* Warning (amber) */
27
+ --inkpen-callout-warning-bg: #fffbeb;
28
+ --inkpen-callout-warning-border: #f59e0b;
29
+ --inkpen-callout-warning-text: #92400e;
30
+
31
+ /* Tip (green) */
32
+ --inkpen-callout-tip-bg: #ecfdf5;
33
+ --inkpen-callout-tip-border: #10b981;
34
+ --inkpen-callout-tip-text: #065f46;
35
+
36
+ /* Note (gray) */
37
+ --inkpen-callout-note-bg: #f9fafb;
38
+ --inkpen-callout-note-border: #6b7280;
39
+ --inkpen-callout-note-text: #374151;
40
+
41
+ /* Success (emerald) */
42
+ --inkpen-callout-success-bg: #ecfdf5;
43
+ --inkpen-callout-success-border: #059669;
44
+ --inkpen-callout-success-text: #065f46;
45
+
46
+ /* Error (red) */
47
+ --inkpen-callout-error-bg: #fef2f2;
48
+ --inkpen-callout-error-border: #ef4444;
49
+ --inkpen-callout-error-text: #991b1b;
50
+ }
51
+
52
+ /* Dark mode */
53
+ [data-theme="dark"],
54
+ .dark {
55
+ /* Info */
56
+ --inkpen-callout-info-bg: rgba(59, 130, 246, 0.15);
57
+ --inkpen-callout-info-border: #60a5fa;
58
+ --inkpen-callout-info-text: #93c5fd;
59
+
60
+ /* Warning */
61
+ --inkpen-callout-warning-bg: rgba(245, 158, 11, 0.15);
62
+ --inkpen-callout-warning-border: #fbbf24;
63
+ --inkpen-callout-warning-text: #fcd34d;
64
+
65
+ /* Tip */
66
+ --inkpen-callout-tip-bg: rgba(16, 185, 129, 0.15);
67
+ --inkpen-callout-tip-border: #34d399;
68
+ --inkpen-callout-tip-text: #6ee7b7;
69
+
70
+ /* Note */
71
+ --inkpen-callout-note-bg: rgba(107, 114, 128, 0.15);
72
+ --inkpen-callout-note-border: #9ca3af;
73
+ --inkpen-callout-note-text: #d1d5db;
74
+
75
+ /* Success */
76
+ --inkpen-callout-success-bg: rgba(5, 150, 105, 0.15);
77
+ --inkpen-callout-success-border: #34d399;
78
+ --inkpen-callout-success-text: #6ee7b7;
79
+
80
+ /* Error */
81
+ --inkpen-callout-error-bg: rgba(239, 68, 68, 0.15);
82
+ --inkpen-callout-error-border: #f87171;
83
+ --inkpen-callout-error-text: #fca5a5;
84
+ }
85
+
86
+ /* ==========================================================================
87
+ Base Callout
88
+ ========================================================================== */
89
+
90
+ .inkpen-callout {
91
+ display: flex;
92
+ gap: var(--inkpen-callout-gap);
93
+ margin: 1rem 0;
94
+ padding: var(--inkpen-callout-padding);
95
+ border-radius: var(--inkpen-callout-radius);
96
+ border-left: var(--inkpen-callout-border-width) solid;
97
+ }
98
+
99
+ /* ==========================================================================
100
+ Icon
101
+ ========================================================================== */
102
+
103
+ .inkpen-callout__icon {
104
+ flex-shrink: 0;
105
+ display: flex;
106
+ align-items: flex-start;
107
+ justify-content: center;
108
+ padding-top: 0.125rem;
109
+ }
110
+
111
+ .inkpen-callout__emoji {
112
+ font-size: var(--inkpen-callout-icon-size);
113
+ line-height: 1;
114
+ }
115
+
116
+ /* Clickable icon for type change */
117
+ .inkpen-callout__icon[style*="cursor: pointer"]:hover {
118
+ opacity: 0.8;
119
+ }
120
+
121
+ /* ==========================================================================
122
+ Content
123
+ ========================================================================== */
124
+
125
+ .inkpen-callout__content {
126
+ flex: 1;
127
+ min-width: 0;
128
+ }
129
+
130
+ .inkpen-callout__content > * + * {
131
+ margin-top: 0.5rem;
132
+ }
133
+
134
+ /* First paragraph styling */
135
+ .inkpen-callout__content > p:first-child {
136
+ font-weight: 500;
137
+ }
138
+
139
+ /* ==========================================================================
140
+ Type Variants
141
+ ========================================================================== */
142
+
143
+ /* Info */
144
+ .inkpen-callout--info {
145
+ background: var(--inkpen-callout-info-bg);
146
+ border-left-color: var(--inkpen-callout-info-border);
147
+ color: var(--inkpen-callout-info-text);
148
+ }
149
+
150
+ /* Warning */
151
+ .inkpen-callout--warning {
152
+ background: var(--inkpen-callout-warning-bg);
153
+ border-left-color: var(--inkpen-callout-warning-border);
154
+ color: var(--inkpen-callout-warning-text);
155
+ }
156
+
157
+ /* Tip */
158
+ .inkpen-callout--tip {
159
+ background: var(--inkpen-callout-tip-bg);
160
+ border-left-color: var(--inkpen-callout-tip-border);
161
+ color: var(--inkpen-callout-tip-text);
162
+ }
163
+
164
+ /* Note */
165
+ .inkpen-callout--note {
166
+ background: var(--inkpen-callout-note-bg);
167
+ border-left-color: var(--inkpen-callout-note-border);
168
+ color: var(--inkpen-callout-note-text);
169
+ }
170
+
171
+ /* Success */
172
+ .inkpen-callout--success {
173
+ background: var(--inkpen-callout-success-bg);
174
+ border-left-color: var(--inkpen-callout-success-border);
175
+ color: var(--inkpen-callout-success-text);
176
+ }
177
+
178
+ /* Error */
179
+ .inkpen-callout--error {
180
+ background: var(--inkpen-callout-error-bg);
181
+ border-left-color: var(--inkpen-callout-error-border);
182
+ color: var(--inkpen-callout-error-text);
183
+ }
184
+
185
+ /* ==========================================================================
186
+ Type Selector Dropdown
187
+ ========================================================================== */
188
+
189
+ .inkpen-callout-selector {
190
+ display: flex;
191
+ flex-direction: column;
192
+ min-width: 140px;
193
+ padding: 0.25rem;
194
+ background: #ffffff;
195
+ border: 1px solid #e5e7eb;
196
+ border-radius: 8px;
197
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
198
+ animation: inkpen-callout-selector-enter 100ms ease-out;
199
+ }
200
+
201
+ @keyframes inkpen-callout-selector-enter {
202
+ from {
203
+ opacity: 0;
204
+ transform: translateY(-4px);
205
+ }
206
+ to {
207
+ opacity: 1;
208
+ transform: translateY(0);
209
+ }
210
+ }
211
+
212
+ .inkpen-callout-selector__item {
213
+ display: flex;
214
+ align-items: center;
215
+ gap: 0.5rem;
216
+ padding: 0.5rem 0.75rem;
217
+ background: transparent;
218
+ border: none;
219
+ border-radius: 6px;
220
+ cursor: pointer;
221
+ text-align: left;
222
+ transition: background 100ms ease;
223
+ }
224
+
225
+ .inkpen-callout-selector__item:hover {
226
+ background: #f3f4f6;
227
+ }
228
+
229
+ .inkpen-callout-selector__item.is-active {
230
+ background: #eff6ff;
231
+ }
232
+
233
+ .inkpen-callout-selector__emoji {
234
+ font-size: 1.125rem;
235
+ width: 1.5rem;
236
+ text-align: center;
237
+ }
238
+
239
+ .inkpen-callout-selector__label {
240
+ font-size: 0.875rem;
241
+ font-weight: 500;
242
+ color: #374151;
243
+ }
244
+
245
+ /* Dark mode selector */
246
+ [data-theme="dark"] .inkpen-callout-selector,
247
+ .dark .inkpen-callout-selector {
248
+ background: #1f2937;
249
+ border-color: #374151;
250
+ }
251
+
252
+ [data-theme="dark"] .inkpen-callout-selector__item:hover,
253
+ .dark .inkpen-callout-selector__item:hover {
254
+ background: #374151;
255
+ }
256
+
257
+ [data-theme="dark"] .inkpen-callout-selector__item.is-active,
258
+ .dark .inkpen-callout-selector__item.is-active {
259
+ background: rgba(59, 130, 246, 0.2);
260
+ }
261
+
262
+ [data-theme="dark"] .inkpen-callout-selector__label,
263
+ .dark .inkpen-callout-selector__label {
264
+ color: #e5e7eb;
265
+ }
266
+
267
+ /* ==========================================================================
268
+ Focus States
269
+ ========================================================================== */
270
+
271
+ .inkpen-callout:focus-within {
272
+ outline: 2px solid var(--inkpen-color-primary, #3b82f6);
273
+ outline-offset: 2px;
274
+ }
275
+
276
+ /* ==========================================================================
277
+ Nested Elements
278
+ ========================================================================== */
279
+
280
+ /* Links inside callouts */
281
+ .inkpen-callout a {
282
+ color: inherit;
283
+ text-decoration: underline;
284
+ text-underline-offset: 2px;
285
+ }
286
+
287
+ .inkpen-callout a:hover {
288
+ opacity: 0.8;
289
+ }
290
+
291
+ /* Code inside callouts */
292
+ .inkpen-callout code {
293
+ background: rgba(0, 0, 0, 0.1);
294
+ padding: 0.125rem 0.375rem;
295
+ border-radius: 4px;
296
+ font-size: 0.875em;
297
+ }
298
+
299
+ [data-theme="dark"] .inkpen-callout code,
300
+ .dark .inkpen-callout code {
301
+ background: rgba(255, 255, 255, 0.1);
302
+ }
303
+
304
+ /* Lists inside callouts */
305
+ .inkpen-callout ul,
306
+ .inkpen-callout ol {
307
+ margin: 0.5rem 0;
308
+ padding-left: 1.5rem;
309
+ }
310
+
311
+ /* ==========================================================================
312
+ Mobile Optimizations
313
+ ========================================================================== */
314
+
315
+ @media (max-width: 768px) {
316
+ .inkpen-callout {
317
+ padding: 0.875rem;
318
+ }
319
+
320
+ .inkpen-callout__emoji {
321
+ font-size: 1.25rem;
322
+ }
323
+
324
+ .inkpen-callout-selector {
325
+ position: fixed !important;
326
+ left: 1rem !important;
327
+ right: 1rem !important;
328
+ bottom: 1rem !important;
329
+ top: auto !important;
330
+ max-width: none;
331
+ border-radius: 12px;
332
+ }
333
+ }
334
+
335
+ /* ==========================================================================
336
+ Reduced Motion
337
+ ========================================================================== */
338
+
339
+ @media (prefers-reduced-motion: reduce) {
340
+ .inkpen-callout-selector {
341
+ animation: none;
342
+ }
343
+ }
344
+
345
+ /* ==========================================================================
346
+ Print Styles
347
+ ========================================================================== */
348
+
349
+ @media print {
350
+ .inkpen-callout {
351
+ border: 1px solid;
352
+ border-left-width: var(--inkpen-callout-border-width);
353
+ page-break-inside: avoid;
354
+ }
355
+
356
+ .inkpen-callout-selector {
357
+ display: none;
358
+ }
359
+ }