markupr 2.1.8
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/.claude/commands/review-feedback.md +47 -0
- package/.eslintrc.json +35 -0
- package/.github/CODEOWNERS +16 -0
- package/.github/FUNDING.yml +1 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +56 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +54 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +89 -0
- package/.github/dependabot.yml +70 -0
- package/.github/workflows/ci.yml +184 -0
- package/.github/workflows/deploy-landing.yml +134 -0
- package/.github/workflows/nightly.yml +288 -0
- package/.github/workflows/release.yml +318 -0
- package/CHANGELOG.md +127 -0
- package/CLAUDE.md +137 -0
- package/CODE_OF_CONDUCT.md +9 -0
- package/CONTRIBUTING.md +390 -0
- package/LICENSE +21 -0
- package/PRODUCT_VISION.md +277 -0
- package/README.md +517 -0
- package/SECURITY.md +51 -0
- package/SIGNING_INSTRUCTIONS.md +284 -0
- package/assets/DMG_BACKGROUND_INSTRUCTIONS.md +130 -0
- package/assets/svg-source/dmg-background.svg +70 -0
- package/assets/svg-source/icon.svg +20 -0
- package/assets/svg-source/tray-icon-processing.svg +7 -0
- package/assets/svg-source/tray-icon-recording.svg +7 -0
- package/assets/svg-source/tray-icon.svg +6 -0
- package/assets/tray-complete.png +0 -0
- package/assets/tray-complete@2x.png +0 -0
- package/assets/tray-completeTemplate.png +0 -0
- package/assets/tray-completeTemplate@2x.png +0 -0
- package/assets/tray-error.png +0 -0
- package/assets/tray-error@2x.png +0 -0
- package/assets/tray-errorTemplate.png +0 -0
- package/assets/tray-errorTemplate@2x.png +0 -0
- package/assets/tray-icon-processing.png +0 -0
- package/assets/tray-icon-processing@2x.png +0 -0
- package/assets/tray-icon-processingTemplate.png +0 -0
- package/assets/tray-icon-processingTemplate@2x.png +0 -0
- package/assets/tray-icon-recording.png +0 -0
- package/assets/tray-icon-recording@2x.png +0 -0
- package/assets/tray-icon-recordingTemplate.png +0 -0
- package/assets/tray-icon-recordingTemplate@2x.png +0 -0
- package/assets/tray-icon.png +0 -0
- package/assets/tray-icon@2x.png +0 -0
- package/assets/tray-iconTemplate.png +0 -0
- package/assets/tray-iconTemplate@2x.png +0 -0
- package/assets/tray-idle.png +0 -0
- package/assets/tray-idle@2x.png +0 -0
- package/assets/tray-idleTemplate.png +0 -0
- package/assets/tray-idleTemplate@2x.png +0 -0
- package/assets/tray-processing-0.png +0 -0
- package/assets/tray-processing-0@2x.png +0 -0
- package/assets/tray-processing-0Template.png +0 -0
- package/assets/tray-processing-0Template@2x.png +0 -0
- package/assets/tray-processing-1.png +0 -0
- package/assets/tray-processing-1@2x.png +0 -0
- package/assets/tray-processing-1Template.png +0 -0
- package/assets/tray-processing-1Template@2x.png +0 -0
- package/assets/tray-processing-2.png +0 -0
- package/assets/tray-processing-2@2x.png +0 -0
- package/assets/tray-processing-2Template.png +0 -0
- package/assets/tray-processing-2Template@2x.png +0 -0
- package/assets/tray-processing-3.png +0 -0
- package/assets/tray-processing-3@2x.png +0 -0
- package/assets/tray-processing-3Template.png +0 -0
- package/assets/tray-processing-3Template@2x.png +0 -0
- package/assets/tray-processing.png +0 -0
- package/assets/tray-processing@2x.png +0 -0
- package/assets/tray-processingTemplate.png +0 -0
- package/assets/tray-processingTemplate@2x.png +0 -0
- package/assets/tray-recording.png +0 -0
- package/assets/tray-recording@2x.png +0 -0
- package/assets/tray-recordingTemplate.png +0 -0
- package/assets/tray-recordingTemplate@2x.png +0 -0
- package/build/DMG_BACKGROUND_SPEC.md +50 -0
- package/build/dmg-background.png +0 -0
- package/build/dmg-background@2x.png +0 -0
- package/build/entitlements.mac.inherit.plist +27 -0
- package/build/entitlements.mac.plist +41 -0
- package/build/favicon-16.png +0 -0
- package/build/favicon-180.png +0 -0
- package/build/favicon-192.png +0 -0
- package/build/favicon-32.png +0 -0
- package/build/favicon-48.png +0 -0
- package/build/favicon-512.png +0 -0
- package/build/favicon-64.png +0 -0
- package/build/icon-128.png +0 -0
- package/build/icon-16.png +0 -0
- package/build/icon-24.png +0 -0
- package/build/icon-256.png +0 -0
- package/build/icon-32.png +0 -0
- package/build/icon-48.png +0 -0
- package/build/icon-64.png +0 -0
- package/build/icon.icns +0 -0
- package/build/icon.ico +0 -0
- package/build/icon.iconset/icon_128x128.png +0 -0
- package/build/icon.iconset/icon_128x128@2x.png +0 -0
- package/build/icon.iconset/icon_16x16.png +0 -0
- package/build/icon.iconset/icon_16x16@2x.png +0 -0
- package/build/icon.iconset/icon_256x256.png +0 -0
- package/build/icon.iconset/icon_256x256@2x.png +0 -0
- package/build/icon.iconset/icon_32x32.png +0 -0
- package/build/icon.iconset/icon_32x32@2x.png +0 -0
- package/build/icon.iconset/icon_512x512.png +0 -0
- package/build/icon.iconset/icon_512x512@2x.png +0 -0
- package/build/icon.png +0 -0
- package/build/installer-header.bmp +0 -0
- package/build/installer-header.png +0 -0
- package/build/installer-sidebar.bmp +0 -0
- package/build/installer-sidebar.png +0 -0
- package/build/installer.nsh +45 -0
- package/build/overlay-processing.png +0 -0
- package/build/overlay-recording.png +0 -0
- package/build/toolbar-record.png +0 -0
- package/build/toolbar-screenshot.png +0 -0
- package/build/toolbar-settings.png +0 -0
- package/build/toolbar-stop.png +0 -0
- package/dist/main/index.mjs +12612 -0
- package/dist/preload/index.mjs +907 -0
- package/dist/renderer/assets/index-CCmUjl9K.js +19495 -0
- package/dist/renderer/assets/index-CUqz_Gs6.css +2270 -0
- package/dist/renderer/index.html +27 -0
- package/docs/AI_AGENT_QUICKSTART.md +42 -0
- package/docs/AI_PIPELINE_DESIGN.md +595 -0
- package/docs/API.md +514 -0
- package/docs/ARCHITECTURE.md +460 -0
- package/docs/CONFIGURATION.md +336 -0
- package/docs/DEVELOPMENT.md +508 -0
- package/docs/EXPORT_FORMATS.md +451 -0
- package/docs/GETTING_STARTED.md +236 -0
- package/docs/KEYBOARD_SHORTCUTS.md +334 -0
- package/docs/TROUBLESHOOTING.md +418 -0
- package/docs/landing/index.html +672 -0
- package/docs/landing/script.js +342 -0
- package/docs/landing/styles.css +1543 -0
- package/electron-builder.yml +140 -0
- package/electron.vite.config.ts +63 -0
- package/package.json +108 -0
- package/railway.json +12 -0
- package/scripts/build.mjs +51 -0
- package/scripts/generate-icons.mjs +314 -0
- package/scripts/generate-installer-images.cjs +253 -0
- package/scripts/generate-tray-icons.mjs +258 -0
- package/scripts/notarize.cjs +180 -0
- package/scripts/one-click-clean-test.sh +147 -0
- package/scripts/postinstall.mjs +36 -0
- package/scripts/setup-markupr.sh +55 -0
- package/setup +17 -0
- package/site/index.html +1835 -0
- package/site/package.json +11 -0
- package/site/railway.json +12 -0
- package/site/server.js +31 -0
- package/src/main/AutoUpdater.ts +392 -0
- package/src/main/CrashRecovery.ts +655 -0
- package/src/main/ErrorHandler.ts +703 -0
- package/src/main/HotkeyManager.ts +399 -0
- package/src/main/MenuManager.ts +529 -0
- package/src/main/PermissionManager.ts +420 -0
- package/src/main/SessionController.ts +1465 -0
- package/src/main/TrayManager.ts +540 -0
- package/src/main/ai/AIPipelineManager.ts +199 -0
- package/src/main/ai/ClaudeAnalyzer.ts +339 -0
- package/src/main/ai/ImageOptimizer.ts +176 -0
- package/src/main/ai/StructuredMarkdownBuilder.ts +379 -0
- package/src/main/ai/index.ts +16 -0
- package/src/main/ai/types.ts +258 -0
- package/src/main/analysis/ClarificationGenerator.ts +385 -0
- package/src/main/analysis/FeedbackAnalyzer.ts +531 -0
- package/src/main/analysis/index.ts +19 -0
- package/src/main/audio/AudioCapture.ts +978 -0
- package/src/main/audio/audioUtils.ts +100 -0
- package/src/main/audio/index.ts +20 -0
- package/src/main/capture/index.ts +1 -0
- package/src/main/index.ts +1693 -0
- package/src/main/ipc/captureHandlers.ts +272 -0
- package/src/main/ipc/index.ts +45 -0
- package/src/main/ipc/outputHandlers.ts +302 -0
- package/src/main/ipc/sessionHandlers.ts +56 -0
- package/src/main/ipc/settingsHandlers.ts +471 -0
- package/src/main/ipc/types.ts +56 -0
- package/src/main/ipc/windowHandlers.ts +277 -0
- package/src/main/output/ClipboardService.ts +369 -0
- package/src/main/output/ExportService.ts +539 -0
- package/src/main/output/FileManager.ts +416 -0
- package/src/main/output/MarkdownGenerator.ts +791 -0
- package/src/main/output/MarkdownPatcher.ts +299 -0
- package/src/main/output/index.ts +186 -0
- package/src/main/output/sessionAdapter.ts +207 -0
- package/src/main/output/templates/html-template.ts +553 -0
- package/src/main/pipeline/FrameExtractor.ts +330 -0
- package/src/main/pipeline/PostProcessor.ts +399 -0
- package/src/main/pipeline/TranscriptAnalyzer.ts +226 -0
- package/src/main/pipeline/index.ts +36 -0
- package/src/main/platform/WindowsTaskbar.ts +600 -0
- package/src/main/platform/index.ts +16 -0
- package/src/main/settings/SettingsManager.ts +730 -0
- package/src/main/settings/index.ts +19 -0
- package/src/main/transcription/ModelDownloadManager.ts +494 -0
- package/src/main/transcription/TierManager.ts +219 -0
- package/src/main/transcription/TranscriptionRecoveryService.ts +340 -0
- package/src/main/transcription/WhisperService.ts +748 -0
- package/src/main/transcription/index.ts +56 -0
- package/src/main/transcription/types.ts +135 -0
- package/src/main/windows/PopoverManager.ts +284 -0
- package/src/main/windows/TaskbarIntegration.ts +452 -0
- package/src/main/windows/index.ts +23 -0
- package/src/preload/index.ts +1047 -0
- package/src/renderer/App.tsx +515 -0
- package/src/renderer/AppWrapper.tsx +28 -0
- package/src/renderer/assets/logo-dark.svg +7 -0
- package/src/renderer/assets/logo.svg +7 -0
- package/src/renderer/audio/AudioCaptureRenderer.ts +454 -0
- package/src/renderer/capture/ScreenRecordingRenderer.ts +492 -0
- package/src/renderer/components/AnnotationOverlay.tsx +836 -0
- package/src/renderer/components/AudioWaveform.tsx +811 -0
- package/src/renderer/components/ClarificationQuestions.tsx +656 -0
- package/src/renderer/components/CountdownTimer.tsx +495 -0
- package/src/renderer/components/CrashRecoveryDialog.tsx +632 -0
- package/src/renderer/components/DonateButton.tsx +127 -0
- package/src/renderer/components/ErrorBoundary.tsx +308 -0
- package/src/renderer/components/ExportDialog.tsx +872 -0
- package/src/renderer/components/HotkeyHint.tsx +261 -0
- package/src/renderer/components/KeyboardShortcuts.tsx +787 -0
- package/src/renderer/components/ModelDownloadDialog.tsx +844 -0
- package/src/renderer/components/Onboarding.tsx +1830 -0
- package/src/renderer/components/ProcessingOverlay.tsx +157 -0
- package/src/renderer/components/RecordingOverlay.tsx +423 -0
- package/src/renderer/components/SessionHistory.tsx +1746 -0
- package/src/renderer/components/SessionReview.tsx +1321 -0
- package/src/renderer/components/SettingsPanel.tsx +217 -0
- package/src/renderer/components/Skeleton.tsx +347 -0
- package/src/renderer/components/StatusIndicator.tsx +86 -0
- package/src/renderer/components/ThemeProvider.tsx +429 -0
- package/src/renderer/components/Tooltip.tsx +370 -0
- package/src/renderer/components/TranscriptionPreview.tsx +183 -0
- package/src/renderer/components/TranscriptionTierSelector.tsx +640 -0
- package/src/renderer/components/UpdateNotification.tsx +377 -0
- package/src/renderer/components/WindowSelector.tsx +947 -0
- package/src/renderer/components/index.ts +99 -0
- package/src/renderer/components/primitives/ApiKeyInput.tsx +98 -0
- package/src/renderer/components/primitives/ColorPicker.tsx +65 -0
- package/src/renderer/components/primitives/DangerButton.tsx +45 -0
- package/src/renderer/components/primitives/DirectoryPicker.tsx +41 -0
- package/src/renderer/components/primitives/Dropdown.tsx +34 -0
- package/src/renderer/components/primitives/KeyRecorder.tsx +117 -0
- package/src/renderer/components/primitives/SettingsSection.tsx +32 -0
- package/src/renderer/components/primitives/Slider.tsx +43 -0
- package/src/renderer/components/primitives/Toggle.tsx +36 -0
- package/src/renderer/components/primitives/index.ts +10 -0
- package/src/renderer/components/settings/AdvancedTab.tsx +174 -0
- package/src/renderer/components/settings/AppearanceTab.tsx +77 -0
- package/src/renderer/components/settings/GeneralTab.tsx +40 -0
- package/src/renderer/components/settings/HotkeysTab.tsx +79 -0
- package/src/renderer/components/settings/RecordingTab.tsx +84 -0
- package/src/renderer/components/settings/index.ts +9 -0
- package/src/renderer/components/settings/settingsStyles.ts +673 -0
- package/src/renderer/components/settings/tabConfig.tsx +85 -0
- package/src/renderer/components/settings/useSettingsPanel.ts +447 -0
- package/src/renderer/contexts/ProcessingContext.tsx +227 -0
- package/src/renderer/contexts/RecordingContext.tsx +683 -0
- package/src/renderer/contexts/UIContext.tsx +326 -0
- package/src/renderer/contexts/index.ts +24 -0
- package/src/renderer/donateMessages.ts +69 -0
- package/src/renderer/hooks/index.ts +75 -0
- package/src/renderer/hooks/useAnimation.tsx +544 -0
- package/src/renderer/hooks/useTheme.ts +313 -0
- package/src/renderer/index.html +26 -0
- package/src/renderer/main.tsx +52 -0
- package/src/renderer/styles/animations.css +1093 -0
- package/src/renderer/styles/app-shell.css +662 -0
- package/src/renderer/styles/globals.css +515 -0
- package/src/renderer/styles/theme.ts +578 -0
- package/src/renderer/types/electron.d.ts +385 -0
- package/src/shared/hotkeys.ts +283 -0
- package/src/shared/types.ts +809 -0
- package/tests/clipboard.test.ts +228 -0
- package/tests/e2e/criticalPaths.test.ts +594 -0
- package/tests/feedbackAnalyzer.test.ts +303 -0
- package/tests/integration/sessionFlow.test.ts +583 -0
- package/tests/markdownGenerator.test.ts +418 -0
- package/tests/output.test.ts +96 -0
- package/tests/setup.ts +486 -0
- package/tests/unit/appIntegration.test.ts +676 -0
- package/tests/unit/appViewState.test.ts +281 -0
- package/tests/unit/audioIpcChannels.test.ts +17 -0
- package/tests/unit/exportService.test.ts +492 -0
- package/tests/unit/hotkeys.test.ts +92 -0
- package/tests/unit/navigationPreload.test.ts +94 -0
- package/tests/unit/onboardingFlow.test.ts +345 -0
- package/tests/unit/permissionManager.test.ts +175 -0
- package/tests/unit/permissionManagerExpanded.test.ts +296 -0
- package/tests/unit/screenRecordingRenderer.test.ts +368 -0
- package/tests/unit/sessionController.test.ts +515 -0
- package/tests/unit/tierManager.test.ts +61 -0
- package/tests/unit/tierManagerExpanded.test.ts +142 -0
- package/tests/unit/transcriptAnalyzer.test.ts +64 -0
- package/tsconfig.json +25 -0
- package/vitest.config.ts +46 -0
package/site/index.html
ADDED
|
@@ -0,0 +1,1835 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
markupR landing page.
|
|
3
|
+
Neo-brutalist structure, minimalist soul.
|
|
4
|
+
Thick borders because elements should look intentional.
|
|
5
|
+
Hard shadows because software should feel tactile.
|
|
6
|
+
System fonts because they're already on your machine.
|
|
7
|
+
Warm amber because cold blue is what everyone else picked.
|
|
8
|
+
No frameworks, no tracking, no cookies, no external requests.
|
|
9
|
+
The product is the thing that needs to be impressive — not the marketing page.
|
|
10
|
+
But if the marketing page is also impressive, that's fine too.
|
|
11
|
+
View the source: github.com/eddiesanjuan/markupr
|
|
12
|
+
-->
|
|
13
|
+
<!DOCTYPE html>
|
|
14
|
+
<html lang="en">
|
|
15
|
+
<head>
|
|
16
|
+
<meta charset="UTF-8">
|
|
17
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
18
|
+
<title>markupR — App feedback, made effortless</title>
|
|
19
|
+
<meta name="description" content="markupR records your screen while you talk, then assembles structured Markdown with the right screenshots at the right moments. Launch includes both BYOK open source mode and touchless premium mode with hosted keys.">
|
|
20
|
+
<meta name="theme-color" content="#0A0A0B" media="(prefers-color-scheme: dark)">
|
|
21
|
+
<meta name="theme-color" content="#FFFFFF" media="(prefers-color-scheme: light)">
|
|
22
|
+
<meta name="theme-color" content="#0A0A0B">
|
|
23
|
+
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>M</text></svg>">
|
|
24
|
+
<style>
|
|
25
|
+
/* ========================================
|
|
26
|
+
RESET
|
|
27
|
+
======================================== */
|
|
28
|
+
*, *::before, *::after {
|
|
29
|
+
margin: 0;
|
|
30
|
+
padding: 0;
|
|
31
|
+
box-sizing: border-box;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* ========================================
|
|
35
|
+
CUSTOM PROPERTIES — DARK MODE (default)
|
|
36
|
+
======================================== */
|
|
37
|
+
:root {
|
|
38
|
+
color-scheme: dark light;
|
|
39
|
+
|
|
40
|
+
/* Typography */
|
|
41
|
+
--font-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', Arial, sans-serif;
|
|
42
|
+
--font-mono: 'SF Mono', 'Fira Code', 'Cascadia Code', 'JetBrains Mono', ui-monospace, monospace;
|
|
43
|
+
|
|
44
|
+
/* Colors — Dark (default) */
|
|
45
|
+
--bg-primary: #0A0A0B;
|
|
46
|
+
--bg-secondary: #141415;
|
|
47
|
+
--bg-tertiary: #1E1E20;
|
|
48
|
+
--text-primary: #F5F5F5;
|
|
49
|
+
--text-secondary: #A0A0A0;
|
|
50
|
+
--text-tertiary: #666666;
|
|
51
|
+
--border: rgba(255, 255, 255, 0.08);
|
|
52
|
+
--border-strong: rgba(255, 255, 255, 0.16);
|
|
53
|
+
|
|
54
|
+
/* Accent — Warm Amber */
|
|
55
|
+
--accent: #F59E0B;
|
|
56
|
+
--accent-hover: #D97706;
|
|
57
|
+
|
|
58
|
+
/* Neo-brutalist shadows */
|
|
59
|
+
--shadow-sm: 2px 2px 0 rgba(255, 255, 255, 0.12);
|
|
60
|
+
--shadow-md: 4px 4px 0 rgba(255, 255, 255, 0.12);
|
|
61
|
+
--shadow-lg: 6px 6px 0 rgba(255, 255, 255, 0.12);
|
|
62
|
+
|
|
63
|
+
/* Syntax highlighting */
|
|
64
|
+
--syn-keyword: #C4B5FD;
|
|
65
|
+
--syn-string: #86EFAC;
|
|
66
|
+
--syn-function: #93C5FD;
|
|
67
|
+
--syn-comment: #525252;
|
|
68
|
+
--syn-operator: #F9A8D4;
|
|
69
|
+
--syn-default: #E5E5E5;
|
|
70
|
+
|
|
71
|
+
/* Spacing */
|
|
72
|
+
--section-gap: 160px;
|
|
73
|
+
--content-max: 720px;
|
|
74
|
+
--feature-max: 960px;
|
|
75
|
+
--side-pad: clamp(1.25rem, 5vw, 2.5rem);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* ========================================
|
|
79
|
+
LIGHT MODE (system preference override)
|
|
80
|
+
======================================== */
|
|
81
|
+
@media (prefers-color-scheme: light) {
|
|
82
|
+
:root {
|
|
83
|
+
--bg-primary: #FFFFFF;
|
|
84
|
+
--bg-secondary: #F8F8F8;
|
|
85
|
+
--bg-tertiary: #F0F0F0;
|
|
86
|
+
--text-primary: #0A0A0A;
|
|
87
|
+
--text-secondary: #525252;
|
|
88
|
+
--text-tertiary: #8B8B8B;
|
|
89
|
+
--border: rgba(0, 0, 0, 0.08);
|
|
90
|
+
--border-strong: rgba(0, 0, 0, 0.12);
|
|
91
|
+
|
|
92
|
+
--accent: #D97706;
|
|
93
|
+
--accent-hover: #B45309;
|
|
94
|
+
|
|
95
|
+
--shadow-sm: 2px 2px 0 var(--text-primary);
|
|
96
|
+
--shadow-md: 4px 4px 0 var(--text-primary);
|
|
97
|
+
--shadow-lg: 6px 6px 0 var(--text-primary);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* ========================================
|
|
102
|
+
BASE
|
|
103
|
+
======================================== */
|
|
104
|
+
html {
|
|
105
|
+
scroll-behavior: smooth;
|
|
106
|
+
-webkit-text-size-adjust: 100%;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@media (prefers-reduced-motion: reduce) {
|
|
110
|
+
html {
|
|
111
|
+
scroll-behavior: auto;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
body {
|
|
116
|
+
font-family: var(--font-sans);
|
|
117
|
+
font-size: 17px;
|
|
118
|
+
line-height: 1.65;
|
|
119
|
+
color: var(--text-secondary);
|
|
120
|
+
background-color: var(--bg-primary);
|
|
121
|
+
-webkit-font-smoothing: antialiased;
|
|
122
|
+
-moz-osx-font-smoothing: grayscale;
|
|
123
|
+
overflow-x: hidden;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
::selection {
|
|
127
|
+
background-color: var(--accent);
|
|
128
|
+
color: #FFFFFF;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
a {
|
|
132
|
+
color: var(--accent);
|
|
133
|
+
text-decoration: none;
|
|
134
|
+
transition: color 150ms ease;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
a:hover {
|
|
138
|
+
color: var(--accent-hover);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
img {
|
|
142
|
+
max-width: 100%;
|
|
143
|
+
display: block;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* ========================================
|
|
147
|
+
TYPOGRAPHY
|
|
148
|
+
======================================== */
|
|
149
|
+
h1, h2, h3, h4 {
|
|
150
|
+
color: var(--text-primary);
|
|
151
|
+
font-weight: 800;
|
|
152
|
+
text-wrap: balance;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.display {
|
|
156
|
+
font-size: clamp(36px, 7vw, 56px);
|
|
157
|
+
line-height: 1.05;
|
|
158
|
+
letter-spacing: -0.04em;
|
|
159
|
+
font-weight: 900;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
h2 {
|
|
163
|
+
font-size: clamp(28px, 4vw, 44px);
|
|
164
|
+
line-height: 1.1;
|
|
165
|
+
letter-spacing: -0.03em;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
h3 {
|
|
169
|
+
font-size: clamp(20px, 3vw, 24px);
|
|
170
|
+
line-height: 1.3;
|
|
171
|
+
letter-spacing: -0.01em;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.overline {
|
|
175
|
+
font-size: 12px;
|
|
176
|
+
line-height: 1.4;
|
|
177
|
+
font-weight: 600;
|
|
178
|
+
letter-spacing: 0.08em;
|
|
179
|
+
text-transform: uppercase;
|
|
180
|
+
color: var(--accent);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.body-lg {
|
|
184
|
+
font-size: clamp(17px, 2.5vw, 20px);
|
|
185
|
+
line-height: 1.6;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.body-sm {
|
|
189
|
+
font-size: 15px;
|
|
190
|
+
line-height: 1.6;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.caption {
|
|
194
|
+
font-size: 13px;
|
|
195
|
+
line-height: 1.5;
|
|
196
|
+
font-weight: 500;
|
|
197
|
+
letter-spacing: 0.02em;
|
|
198
|
+
color: var(--text-tertiary);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* ========================================
|
|
202
|
+
LAYOUT
|
|
203
|
+
======================================== */
|
|
204
|
+
.container {
|
|
205
|
+
max-width: var(--content-max);
|
|
206
|
+
margin: 0 auto;
|
|
207
|
+
padding-left: var(--side-pad);
|
|
208
|
+
padding-right: var(--side-pad);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.container--wide {
|
|
212
|
+
max-width: var(--feature-max);
|
|
213
|
+
margin: 0 auto;
|
|
214
|
+
padding-left: var(--side-pad);
|
|
215
|
+
padding-right: var(--side-pad);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
section {
|
|
219
|
+
padding-top: var(--section-gap);
|
|
220
|
+
padding-bottom: var(--section-gap);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
@media (max-width: 768px) {
|
|
224
|
+
:root {
|
|
225
|
+
--section-gap: 96px;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* Section dividers — visible bones */
|
|
230
|
+
.divider {
|
|
231
|
+
border: none;
|
|
232
|
+
height: 3px;
|
|
233
|
+
background: var(--text-primary);
|
|
234
|
+
margin: 0;
|
|
235
|
+
opacity: 0.12;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
@media (prefers-color-scheme: light) {
|
|
239
|
+
.divider {
|
|
240
|
+
opacity: 0.08;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* ========================================
|
|
245
|
+
WORDMARK
|
|
246
|
+
======================================== */
|
|
247
|
+
.wordmark {
|
|
248
|
+
font-family: var(--font-sans);
|
|
249
|
+
font-weight: 900;
|
|
250
|
+
font-size: 28px;
|
|
251
|
+
letter-spacing: -0.04em;
|
|
252
|
+
color: var(--text-primary);
|
|
253
|
+
display: inline-block;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.wordmark-r {
|
|
257
|
+
color: var(--accent);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/* ========================================
|
|
261
|
+
BUTTONS — Neo-Brutalist, Tactile
|
|
262
|
+
======================================== */
|
|
263
|
+
.btn {
|
|
264
|
+
display: inline-flex;
|
|
265
|
+
align-items: center;
|
|
266
|
+
gap: 8px;
|
|
267
|
+
padding: 14px 28px;
|
|
268
|
+
font-family: var(--font-sans);
|
|
269
|
+
font-size: 15px;
|
|
270
|
+
font-weight: 600;
|
|
271
|
+
line-height: 1;
|
|
272
|
+
border: 3px solid var(--text-primary);
|
|
273
|
+
border-radius: 4px;
|
|
274
|
+
cursor: pointer;
|
|
275
|
+
transition: transform 150ms ease-out, box-shadow 150ms ease-out, background-color 150ms ease;
|
|
276
|
+
text-decoration: none;
|
|
277
|
+
white-space: nowrap;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.btn--primary {
|
|
281
|
+
background: var(--text-primary);
|
|
282
|
+
color: var(--bg-primary);
|
|
283
|
+
box-shadow: var(--shadow-md);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.btn--primary:hover {
|
|
287
|
+
transform: translate(2px, 2px);
|
|
288
|
+
box-shadow: var(--shadow-sm);
|
|
289
|
+
color: var(--bg-primary);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.btn--primary:active {
|
|
293
|
+
transform: translate(4px, 4px);
|
|
294
|
+
box-shadow: none;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.btn--secondary {
|
|
298
|
+
background: var(--bg-primary);
|
|
299
|
+
color: var(--text-primary);
|
|
300
|
+
box-shadow: var(--shadow-md);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.btn--secondary:hover {
|
|
304
|
+
transform: translate(2px, 2px);
|
|
305
|
+
box-shadow: var(--shadow-sm);
|
|
306
|
+
color: var(--text-primary);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.btn--secondary:active {
|
|
310
|
+
transform: translate(4px, 4px);
|
|
311
|
+
box-shadow: none;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.btn--accent {
|
|
315
|
+
background: var(--accent);
|
|
316
|
+
color: #FFFFFF;
|
|
317
|
+
border-color: var(--text-primary);
|
|
318
|
+
box-shadow: var(--shadow-md);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.btn--accent:hover {
|
|
322
|
+
transform: translate(2px, 2px);
|
|
323
|
+
box-shadow: var(--shadow-sm);
|
|
324
|
+
background: var(--accent-hover);
|
|
325
|
+
color: #FFFFFF;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.btn--accent:active {
|
|
329
|
+
transform: translate(4px, 4px);
|
|
330
|
+
box-shadow: none;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.btn:focus-visible {
|
|
334
|
+
outline: 3px solid var(--accent);
|
|
335
|
+
outline-offset: 3px;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/* ========================================
|
|
339
|
+
KBD — Keyboard Shortcut Badges
|
|
340
|
+
======================================== */
|
|
341
|
+
kbd {
|
|
342
|
+
display: inline-flex;
|
|
343
|
+
align-items: center;
|
|
344
|
+
justify-content: center;
|
|
345
|
+
min-width: 32px;
|
|
346
|
+
padding: 4px 10px;
|
|
347
|
+
font-family: var(--font-mono);
|
|
348
|
+
font-size: 14px;
|
|
349
|
+
font-weight: 500;
|
|
350
|
+
color: var(--text-tertiary);
|
|
351
|
+
background: var(--bg-tertiary);
|
|
352
|
+
border: 2px solid var(--text-primary);
|
|
353
|
+
border-radius: 4px;
|
|
354
|
+
box-shadow: var(--shadow-sm);
|
|
355
|
+
line-height: 1.4;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.kbd-group {
|
|
359
|
+
display: inline-flex;
|
|
360
|
+
align-items: center;
|
|
361
|
+
gap: 6px;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.kbd-plus {
|
|
365
|
+
color: var(--text-tertiary);
|
|
366
|
+
font-size: 13px;
|
|
367
|
+
font-weight: 500;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/* ========================================
|
|
371
|
+
CARDS — Neo-Brutalist
|
|
372
|
+
======================================== */
|
|
373
|
+
.card {
|
|
374
|
+
background: var(--bg-secondary);
|
|
375
|
+
border: 3px solid var(--text-primary);
|
|
376
|
+
border-radius: 4px;
|
|
377
|
+
padding: 32px;
|
|
378
|
+
box-shadow: var(--shadow-lg);
|
|
379
|
+
transition: transform 150ms ease-out, box-shadow 150ms ease-out;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.card:hover {
|
|
383
|
+
transform: translate(2px, 2px);
|
|
384
|
+
box-shadow: var(--shadow-md);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/* ========================================
|
|
388
|
+
SCROLL REVEAL
|
|
389
|
+
======================================== */
|
|
390
|
+
.reveal {
|
|
391
|
+
opacity: 0;
|
|
392
|
+
transform: translateY(24px);
|
|
393
|
+
transition: opacity 500ms cubic-bezier(0.16, 1, 0.3, 1),
|
|
394
|
+
transform 500ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.reveal.visible {
|
|
398
|
+
opacity: 1;
|
|
399
|
+
transform: translateY(0);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.reveal-delay-1 { transition-delay: 75ms; }
|
|
403
|
+
.reveal-delay-2 { transition-delay: 150ms; }
|
|
404
|
+
.reveal-delay-3 { transition-delay: 225ms; }
|
|
405
|
+
.reveal-delay-4 { transition-delay: 300ms; }
|
|
406
|
+
|
|
407
|
+
@media (prefers-reduced-motion: reduce) {
|
|
408
|
+
.reveal {
|
|
409
|
+
opacity: 1;
|
|
410
|
+
transform: none;
|
|
411
|
+
transition: none;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/* ========================================
|
|
416
|
+
HERO
|
|
417
|
+
======================================== */
|
|
418
|
+
.hero {
|
|
419
|
+
min-height: 100dvh;
|
|
420
|
+
display: flex;
|
|
421
|
+
flex-direction: column;
|
|
422
|
+
align-items: center;
|
|
423
|
+
justify-content: center;
|
|
424
|
+
text-align: center;
|
|
425
|
+
padding: 96px var(--side-pad);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.hero__wordmark {
|
|
429
|
+
font-size: clamp(32px, 5vw, 40px);
|
|
430
|
+
margin-bottom: 32px;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.hero__headline {
|
|
434
|
+
max-width: 700px;
|
|
435
|
+
margin-bottom: 24px;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.hero__subtext {
|
|
439
|
+
max-width: 560px;
|
|
440
|
+
margin-bottom: 48px;
|
|
441
|
+
color: var(--text-secondary);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.hero__ctas {
|
|
445
|
+
display: flex;
|
|
446
|
+
flex-wrap: wrap;
|
|
447
|
+
gap: 16px;
|
|
448
|
+
justify-content: center;
|
|
449
|
+
margin-bottom: 32px;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.hero__support-note {
|
|
453
|
+
margin: 0 0 28px;
|
|
454
|
+
max-width: 560px;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
.hero__shortcut {
|
|
458
|
+
display: flex;
|
|
459
|
+
align-items: center;
|
|
460
|
+
gap: 12px;
|
|
461
|
+
color: var(--text-tertiary);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.hero__shortcut-label {
|
|
465
|
+
font-size: 13px;
|
|
466
|
+
font-weight: 500;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
@media (max-width: 480px) {
|
|
470
|
+
.hero__ctas {
|
|
471
|
+
flex-direction: column;
|
|
472
|
+
align-items: center;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
.hero__ctas .btn {
|
|
476
|
+
width: 100%;
|
|
477
|
+
justify-content: center;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/* ========================================
|
|
482
|
+
CORE LOOP
|
|
483
|
+
======================================== */
|
|
484
|
+
.loop {
|
|
485
|
+
background: var(--bg-secondary);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.loop__grid {
|
|
489
|
+
display: grid;
|
|
490
|
+
grid-template-columns: repeat(3, 1fr);
|
|
491
|
+
gap: 24px;
|
|
492
|
+
max-width: var(--feature-max);
|
|
493
|
+
margin: 0 auto;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.loop__step {
|
|
497
|
+
text-align: center;
|
|
498
|
+
position: relative;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
.loop__icon-box {
|
|
502
|
+
width: 72px;
|
|
503
|
+
height: 72px;
|
|
504
|
+
margin: 0 auto 16px;
|
|
505
|
+
display: flex;
|
|
506
|
+
align-items: center;
|
|
507
|
+
justify-content: center;
|
|
508
|
+
border: 3px solid var(--text-primary);
|
|
509
|
+
border-radius: 4px;
|
|
510
|
+
box-shadow: var(--shadow-md);
|
|
511
|
+
background: var(--bg-primary);
|
|
512
|
+
color: var(--text-primary);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
.loop__icon-box svg {
|
|
516
|
+
width: 28px;
|
|
517
|
+
height: 28px;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
.loop__label {
|
|
521
|
+
font-family: var(--font-mono);
|
|
522
|
+
font-size: 15px;
|
|
523
|
+
font-weight: 600;
|
|
524
|
+
color: var(--text-primary);
|
|
525
|
+
margin-bottom: 8px;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.loop__desc {
|
|
529
|
+
font-size: 14px;
|
|
530
|
+
line-height: 1.5;
|
|
531
|
+
color: var(--text-tertiary);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/* "you" vs "markupR" role labels */
|
|
535
|
+
.loop__role {
|
|
536
|
+
font-family: var(--font-mono);
|
|
537
|
+
font-size: 11px;
|
|
538
|
+
font-weight: 700;
|
|
539
|
+
letter-spacing: 0.06em;
|
|
540
|
+
text-transform: uppercase;
|
|
541
|
+
margin-bottom: 12px;
|
|
542
|
+
height: 20px;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.loop__role--you {
|
|
546
|
+
color: var(--accent);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
.loop__role--auto {
|
|
550
|
+
color: var(--text-tertiary);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/* Dim automatic steps */
|
|
554
|
+
.loop__step--auto .loop__icon-box {
|
|
555
|
+
opacity: 0.45;
|
|
556
|
+
border-style: dashed;
|
|
557
|
+
box-shadow: none;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
.loop__step--auto .loop__label {
|
|
561
|
+
color: var(--text-secondary);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/* Arrow between steps */
|
|
565
|
+
.loop__step:not(:last-child)::after {
|
|
566
|
+
content: '';
|
|
567
|
+
position: absolute;
|
|
568
|
+
top: 56px; /* shifted down to account for role label */
|
|
569
|
+
right: -14px;
|
|
570
|
+
width: 8px;
|
|
571
|
+
height: 8px;
|
|
572
|
+
border-right: 3px solid var(--text-primary);
|
|
573
|
+
border-bottom: 3px solid var(--text-primary);
|
|
574
|
+
transform: rotate(-45deg);
|
|
575
|
+
opacity: 0.3;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/* The actual workflow — keystrokes */
|
|
579
|
+
.keystroke-flow {
|
|
580
|
+
max-width: var(--feature-max);
|
|
581
|
+
margin: 56px auto 0;
|
|
582
|
+
display: flex;
|
|
583
|
+
align-items: center;
|
|
584
|
+
justify-content: center;
|
|
585
|
+
gap: 0;
|
|
586
|
+
flex-wrap: wrap;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.keystroke-flow__step {
|
|
590
|
+
display: flex;
|
|
591
|
+
flex-direction: column;
|
|
592
|
+
align-items: center;
|
|
593
|
+
gap: 10px;
|
|
594
|
+
padding: 0 clamp(12px, 3vw, 32px);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.keystroke-flow__keys {
|
|
598
|
+
font-family: var(--font-mono);
|
|
599
|
+
font-size: clamp(18px, 3.5vw, 28px);
|
|
600
|
+
font-weight: 700;
|
|
601
|
+
color: var(--text-primary);
|
|
602
|
+
letter-spacing: -0.02em;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
.keystroke-flow__label {
|
|
606
|
+
font-size: 13px;
|
|
607
|
+
font-weight: 500;
|
|
608
|
+
color: var(--text-tertiary);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
.keystroke-flow__arrow {
|
|
612
|
+
font-size: clamp(18px, 3vw, 24px);
|
|
613
|
+
color: var(--text-tertiary);
|
|
614
|
+
opacity: 0.4;
|
|
615
|
+
padding: 0 4px;
|
|
616
|
+
margin-top: -20px; /* align with keys, not labels */
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
.keystroke-flow__ellipsis {
|
|
620
|
+
font-family: var(--font-mono);
|
|
621
|
+
font-size: clamp(18px, 3.5vw, 28px);
|
|
622
|
+
font-weight: 700;
|
|
623
|
+
color: var(--text-tertiary);
|
|
624
|
+
letter-spacing: 0.15em;
|
|
625
|
+
padding: 0 clamp(4px, 1.5vw, 12px);
|
|
626
|
+
margin-top: -20px;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
@media (max-width: 640px) {
|
|
630
|
+
.loop__grid {
|
|
631
|
+
grid-template-columns: 1fr 1fr;
|
|
632
|
+
gap: 32px;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
.loop__step:not(:last-child)::after {
|
|
636
|
+
display: none;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
@media (max-width: 400px) {
|
|
641
|
+
.loop__grid {
|
|
642
|
+
grid-template-columns: 1fr;
|
|
643
|
+
gap: 40px;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
.loop__role {
|
|
647
|
+
height: auto;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
@media (max-width: 480px) {
|
|
652
|
+
.keystroke-flow {
|
|
653
|
+
gap: 8px 0;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/* ========================================
|
|
658
|
+
QUICK VISUAL WALKTHROUGH
|
|
659
|
+
======================================== */
|
|
660
|
+
.quickwalk {
|
|
661
|
+
background: var(--bg-primary);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
.quickwalk__panel {
|
|
665
|
+
border: 3px solid var(--text-primary);
|
|
666
|
+
border-radius: 4px;
|
|
667
|
+
background: var(--bg-secondary);
|
|
668
|
+
box-shadow: var(--shadow-lg);
|
|
669
|
+
padding: clamp(20px, 4vw, 32px);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
.quickwalk__layout {
|
|
673
|
+
display: grid;
|
|
674
|
+
grid-template-columns: 1.3fr 1fr;
|
|
675
|
+
gap: clamp(20px, 3.5vw, 36px);
|
|
676
|
+
align-items: stretch;
|
|
677
|
+
max-width: var(--feature-max);
|
|
678
|
+
margin: 0 auto;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
.quickwalk__sim {
|
|
682
|
+
display: flex;
|
|
683
|
+
flex-direction: column;
|
|
684
|
+
gap: 18px;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
.quickwalk__status {
|
|
688
|
+
display: flex;
|
|
689
|
+
align-items: center;
|
|
690
|
+
gap: 10px;
|
|
691
|
+
font-family: var(--font-mono);
|
|
692
|
+
font-size: 13px;
|
|
693
|
+
color: var(--text-secondary);
|
|
694
|
+
border-bottom: 2px solid var(--border);
|
|
695
|
+
padding-bottom: 12px;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.quickwalk__status-dot {
|
|
699
|
+
width: 10px;
|
|
700
|
+
height: 10px;
|
|
701
|
+
border-radius: 50%;
|
|
702
|
+
background: #ef4444;
|
|
703
|
+
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.2);
|
|
704
|
+
animation: quickwalk-recording-pulse 1200ms ease-in-out infinite;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
.quickwalk__status-time {
|
|
708
|
+
margin-left: auto;
|
|
709
|
+
color: var(--text-tertiary);
|
|
710
|
+
letter-spacing: 0.02em;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
.quickwalk__pipeline {
|
|
714
|
+
display: grid;
|
|
715
|
+
grid-template-columns: auto minmax(60px, 1fr) auto minmax(60px, 1fr) auto;
|
|
716
|
+
align-items: center;
|
|
717
|
+
gap: 8px;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
.quickwalk__node {
|
|
721
|
+
border: 2px solid var(--border-strong);
|
|
722
|
+
border-radius: 4px;
|
|
723
|
+
padding: 10px 12px;
|
|
724
|
+
text-align: center;
|
|
725
|
+
font-family: var(--font-mono);
|
|
726
|
+
font-size: 12px;
|
|
727
|
+
font-weight: 700;
|
|
728
|
+
letter-spacing: 0.02em;
|
|
729
|
+
color: var(--text-secondary);
|
|
730
|
+
background: var(--bg-primary);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
.quickwalk__node--capture {
|
|
734
|
+
animation: quickwalk-node-cycle 6s ease-in-out infinite;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
.quickwalk__node--align {
|
|
738
|
+
animation: quickwalk-node-cycle 6s ease-in-out 2s infinite;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
.quickwalk__node--report {
|
|
742
|
+
animation: quickwalk-node-cycle 6s ease-in-out 4s infinite;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
.quickwalk__pipe {
|
|
746
|
+
position: relative;
|
|
747
|
+
height: 2px;
|
|
748
|
+
background: var(--border-strong);
|
|
749
|
+
overflow: hidden;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
.quickwalk__pulse {
|
|
753
|
+
position: absolute;
|
|
754
|
+
inset: -2px auto -2px 0;
|
|
755
|
+
width: 28px;
|
|
756
|
+
background: linear-gradient(90deg, transparent 0%, var(--accent) 45%, transparent 100%);
|
|
757
|
+
transform: translateX(-120%);
|
|
758
|
+
animation: quickwalk-flow 3s linear infinite;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
.quickwalk__pulse--delay {
|
|
762
|
+
animation-delay: 1.5s;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
.quickwalk__caption {
|
|
766
|
+
font-size: 14px;
|
|
767
|
+
color: var(--text-secondary);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
.quickwalk__result {
|
|
771
|
+
display: flex;
|
|
772
|
+
flex-direction: column;
|
|
773
|
+
justify-content: center;
|
|
774
|
+
gap: 10px;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
.quickwalk__report {
|
|
778
|
+
border: 2px solid var(--border-strong);
|
|
779
|
+
border-radius: 4px;
|
|
780
|
+
background: var(--bg-primary);
|
|
781
|
+
padding: 14px;
|
|
782
|
+
min-height: 170px;
|
|
783
|
+
display: flex;
|
|
784
|
+
flex-direction: column;
|
|
785
|
+
gap: 10px;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
.quickwalk__line {
|
|
789
|
+
height: 10px;
|
|
790
|
+
border-radius: 2px;
|
|
791
|
+
background: rgba(255, 255, 255, 0.12);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
.quickwalk__line--title {
|
|
795
|
+
width: 74%;
|
|
796
|
+
height: 12px;
|
|
797
|
+
background: rgba(245, 158, 11, 0.45);
|
|
798
|
+
animation: quickwalk-line-cycle 6s ease-in-out infinite;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
.quickwalk__line--full {
|
|
802
|
+
width: 100%;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
.quickwalk__line--mid {
|
|
806
|
+
width: 86%;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
.quickwalk__line--short {
|
|
810
|
+
width: 58%;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
.quickwalk__image {
|
|
814
|
+
margin-top: 2px;
|
|
815
|
+
width: 100%;
|
|
816
|
+
height: 48px;
|
|
817
|
+
border: 2px solid var(--border-strong);
|
|
818
|
+
border-radius: 3px;
|
|
819
|
+
background:
|
|
820
|
+
linear-gradient(135deg, rgba(245, 158, 11, 0.18), rgba(245, 158, 11, 0.05)),
|
|
821
|
+
repeating-linear-gradient(
|
|
822
|
+
-45deg,
|
|
823
|
+
rgba(255, 255, 255, 0.08) 0px,
|
|
824
|
+
rgba(255, 255, 255, 0.08) 8px,
|
|
825
|
+
transparent 8px,
|
|
826
|
+
transparent 16px
|
|
827
|
+
);
|
|
828
|
+
animation: quickwalk-line-cycle 6s ease-in-out 4s infinite;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
.quickwalk__paste {
|
|
832
|
+
font-family: var(--font-mono);
|
|
833
|
+
font-size: 12px;
|
|
834
|
+
color: var(--text-tertiary);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
@keyframes quickwalk-recording-pulse {
|
|
838
|
+
0%, 100% { opacity: 0.55; }
|
|
839
|
+
50% { opacity: 1; }
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
@keyframes quickwalk-flow {
|
|
843
|
+
0% { transform: translateX(-130%); opacity: 0; }
|
|
844
|
+
15% { opacity: 1; }
|
|
845
|
+
100% { transform: translateX(240%); opacity: 0; }
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
@keyframes quickwalk-node-cycle {
|
|
849
|
+
0%, 100% {
|
|
850
|
+
border-color: var(--border-strong);
|
|
851
|
+
color: var(--text-secondary);
|
|
852
|
+
box-shadow: none;
|
|
853
|
+
}
|
|
854
|
+
10%, 36% {
|
|
855
|
+
border-color: var(--accent);
|
|
856
|
+
color: var(--text-primary);
|
|
857
|
+
box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.18);
|
|
858
|
+
}
|
|
859
|
+
50% {
|
|
860
|
+
border-color: var(--border-strong);
|
|
861
|
+
color: var(--text-secondary);
|
|
862
|
+
box-shadow: none;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
@keyframes quickwalk-line-cycle {
|
|
867
|
+
0%, 100% { opacity: 0.35; }
|
|
868
|
+
16%, 44% { opacity: 1; }
|
|
869
|
+
58% { opacity: 0.4; }
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
@media (max-width: 840px) {
|
|
873
|
+
.quickwalk__layout {
|
|
874
|
+
grid-template-columns: 1fr;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
@media (max-width: 640px) {
|
|
879
|
+
.quickwalk__pipeline {
|
|
880
|
+
grid-template-columns: 1fr;
|
|
881
|
+
gap: 10px;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
.quickwalk__pipe {
|
|
885
|
+
height: 12px;
|
|
886
|
+
width: 2px;
|
|
887
|
+
margin: 0 auto;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
.quickwalk__pulse {
|
|
891
|
+
inset: 0;
|
|
892
|
+
width: 2px;
|
|
893
|
+
height: 20px;
|
|
894
|
+
background: linear-gradient(180deg, transparent 0%, var(--accent) 45%, transparent 100%);
|
|
895
|
+
transform: translateY(-130%);
|
|
896
|
+
animation-name: quickwalk-flow-mobile;
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
@keyframes quickwalk-flow-mobile {
|
|
901
|
+
0% { transform: translateY(-130%); opacity: 0; }
|
|
902
|
+
15% { opacity: 1; }
|
|
903
|
+
100% { transform: translateY(240%); opacity: 0; }
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
@media (prefers-reduced-motion: reduce) {
|
|
907
|
+
.quickwalk__status-dot,
|
|
908
|
+
.quickwalk__node,
|
|
909
|
+
.quickwalk__pulse,
|
|
910
|
+
.quickwalk__line--title,
|
|
911
|
+
.quickwalk__image {
|
|
912
|
+
animation: none !important;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/* ========================================
|
|
917
|
+
WHY IT MATTERS
|
|
918
|
+
======================================== */
|
|
919
|
+
.why__grid {
|
|
920
|
+
display: grid;
|
|
921
|
+
grid-template-columns: 1fr;
|
|
922
|
+
gap: 32px;
|
|
923
|
+
max-width: var(--feature-max);
|
|
924
|
+
margin: 0 auto;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
@media (min-width: 768px) {
|
|
928
|
+
.why__grid {
|
|
929
|
+
grid-template-columns: 1fr 1fr 1fr;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
.why__card h3 {
|
|
934
|
+
margin-bottom: 16px;
|
|
935
|
+
font-size: clamp(18px, 2.5vw, 22px);
|
|
936
|
+
line-height: 1.25;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
.why__card p {
|
|
940
|
+
font-size: 15px;
|
|
941
|
+
line-height: 1.65;
|
|
942
|
+
color: var(--text-secondary);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
/* ========================================
|
|
946
|
+
UNDER THE HOOD
|
|
947
|
+
======================================== */
|
|
948
|
+
.tech {
|
|
949
|
+
background: var(--bg-secondary);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
.tech__content {
|
|
953
|
+
display: grid;
|
|
954
|
+
grid-template-columns: 1fr;
|
|
955
|
+
gap: 64px;
|
|
956
|
+
max-width: var(--feature-max);
|
|
957
|
+
margin: 0 auto;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
@media (min-width: 768px) {
|
|
961
|
+
.tech__content {
|
|
962
|
+
grid-template-columns: 1fr 1fr;
|
|
963
|
+
gap: 48px;
|
|
964
|
+
align-items: start;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
.tech__bullets {
|
|
969
|
+
list-style: none;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
.tech__bullets li {
|
|
973
|
+
padding: 16px 0;
|
|
974
|
+
border-bottom: 2px solid var(--border);
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
.tech__bullets li:first-child {
|
|
978
|
+
padding-top: 0;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
.tech__bullets strong {
|
|
982
|
+
color: var(--text-primary);
|
|
983
|
+
font-weight: 700;
|
|
984
|
+
display: block;
|
|
985
|
+
margin-bottom: 4px;
|
|
986
|
+
font-size: 15px;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
.tech__bullets span {
|
|
990
|
+
font-size: 15px;
|
|
991
|
+
line-height: 1.6;
|
|
992
|
+
color: var(--text-secondary);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
/* Code Block — Neo-Brutalist */
|
|
996
|
+
.code-block {
|
|
997
|
+
background: #0A0A0B;
|
|
998
|
+
border: 3px solid var(--text-primary);
|
|
999
|
+
border-radius: 4px;
|
|
1000
|
+
box-shadow: var(--shadow-lg);
|
|
1001
|
+
overflow: hidden;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
.code-block__header {
|
|
1005
|
+
display: flex;
|
|
1006
|
+
align-items: center;
|
|
1007
|
+
gap: 8px;
|
|
1008
|
+
padding: 12px 20px;
|
|
1009
|
+
border-bottom: 2px solid rgba(255, 255, 255, 0.08);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
.code-block__dot {
|
|
1013
|
+
width: 10px;
|
|
1014
|
+
height: 10px;
|
|
1015
|
+
border-radius: 50%;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
.code-block__dot--red { background: #FF5F57; }
|
|
1019
|
+
.code-block__dot--yellow { background: #FEBC2E; }
|
|
1020
|
+
.code-block__dot--green { background: #28C840; }
|
|
1021
|
+
|
|
1022
|
+
.code-block__title {
|
|
1023
|
+
font-family: var(--font-mono);
|
|
1024
|
+
font-size: 12px;
|
|
1025
|
+
color: #666;
|
|
1026
|
+
margin-left: 8px;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
.code-block pre {
|
|
1030
|
+
padding: 24px 20px;
|
|
1031
|
+
overflow-x: auto;
|
|
1032
|
+
font-family: var(--font-mono);
|
|
1033
|
+
font-size: 13px;
|
|
1034
|
+
line-height: 1.7;
|
|
1035
|
+
color: var(--syn-default);
|
|
1036
|
+
-webkit-overflow-scrolling: touch;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
.code-block pre code {
|
|
1040
|
+
font-family: inherit;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
.syn-kw { color: var(--syn-keyword); }
|
|
1044
|
+
.syn-str { color: var(--syn-string); }
|
|
1045
|
+
.syn-fn { color: var(--syn-function); }
|
|
1046
|
+
.syn-cm { color: var(--syn-comment); }
|
|
1047
|
+
.syn-op { color: var(--syn-operator); }
|
|
1048
|
+
|
|
1049
|
+
/* ========================================
|
|
1050
|
+
PREMIUM TEASER
|
|
1051
|
+
======================================== */
|
|
1052
|
+
.premium__features {
|
|
1053
|
+
display: grid;
|
|
1054
|
+
grid-template-columns: 1fr;
|
|
1055
|
+
gap: 24px;
|
|
1056
|
+
max-width: var(--feature-max);
|
|
1057
|
+
margin: 48px auto 0;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
@media (min-width: 768px) {
|
|
1061
|
+
.premium__features {
|
|
1062
|
+
grid-template-columns: 1fr 1fr 1fr;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
.premium__card h3 {
|
|
1067
|
+
margin-bottom: 12px;
|
|
1068
|
+
font-size: 18px;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
.premium__card p {
|
|
1072
|
+
font-size: 15px;
|
|
1073
|
+
line-height: 1.6;
|
|
1074
|
+
color: var(--text-secondary);
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
.premium__cta {
|
|
1078
|
+
max-width: 640px;
|
|
1079
|
+
margin: 48px auto 0;
|
|
1080
|
+
display: flex;
|
|
1081
|
+
flex-wrap: wrap;
|
|
1082
|
+
justify-content: center;
|
|
1083
|
+
gap: 16px;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
.premium__note {
|
|
1087
|
+
margin-top: 18px;
|
|
1088
|
+
text-align: center;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
@media (max-width: 480px) {
|
|
1092
|
+
.premium__cta .btn {
|
|
1093
|
+
width: 100%;
|
|
1094
|
+
justify-content: center;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
/* ========================================
|
|
1099
|
+
FOOTER
|
|
1100
|
+
======================================== */
|
|
1101
|
+
.footer {
|
|
1102
|
+
padding: 48px var(--side-pad);
|
|
1103
|
+
text-align: center;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
.footer__divider {
|
|
1107
|
+
height: 3px;
|
|
1108
|
+
background: var(--text-primary);
|
|
1109
|
+
opacity: 0.12;
|
|
1110
|
+
margin-bottom: 48px;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
@media (prefers-color-scheme: light) {
|
|
1114
|
+
.footer__divider {
|
|
1115
|
+
opacity: 0.08;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
.footer__links {
|
|
1120
|
+
display: flex;
|
|
1121
|
+
justify-content: center;
|
|
1122
|
+
gap: 32px;
|
|
1123
|
+
flex-wrap: wrap;
|
|
1124
|
+
margin-bottom: 24px;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
.footer__link {
|
|
1128
|
+
display: inline-flex;
|
|
1129
|
+
align-items: center;
|
|
1130
|
+
gap: 8px;
|
|
1131
|
+
font-size: 15px;
|
|
1132
|
+
font-weight: 500;
|
|
1133
|
+
color: var(--text-secondary);
|
|
1134
|
+
transition: color 150ms ease;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
.footer__link:hover {
|
|
1138
|
+
color: var(--text-primary);
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
.footer__link:focus-visible {
|
|
1142
|
+
outline: 2px solid var(--accent);
|
|
1143
|
+
outline-offset: 4px;
|
|
1144
|
+
border-radius: 4px;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
.footer__link svg {
|
|
1148
|
+
width: 18px;
|
|
1149
|
+
height: 18px;
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
.footer__link--button {
|
|
1153
|
+
border: 0;
|
|
1154
|
+
background: transparent;
|
|
1155
|
+
padding: 0;
|
|
1156
|
+
cursor: pointer;
|
|
1157
|
+
font: inherit;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
.footer__link--button:focus-visible {
|
|
1161
|
+
outline: 2px solid var(--accent);
|
|
1162
|
+
outline-offset: 4px;
|
|
1163
|
+
border-radius: 4px;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
.footer__license {
|
|
1167
|
+
font-size: 14px;
|
|
1168
|
+
color: var(--text-tertiary);
|
|
1169
|
+
margin-bottom: 8px;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
.footer__built {
|
|
1173
|
+
font-size: 14px;
|
|
1174
|
+
color: var(--text-tertiary);
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
.footer__support {
|
|
1178
|
+
font-size: 14px;
|
|
1179
|
+
color: var(--text-tertiary);
|
|
1180
|
+
margin-top: 8px;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
/* ========================================
|
|
1184
|
+
DONATE MODAL
|
|
1185
|
+
======================================== */
|
|
1186
|
+
body.donate-modal-open {
|
|
1187
|
+
overflow: hidden;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
.donate-modal {
|
|
1191
|
+
position: fixed;
|
|
1192
|
+
inset: 0;
|
|
1193
|
+
z-index: 2000;
|
|
1194
|
+
display: none;
|
|
1195
|
+
align-items: center;
|
|
1196
|
+
justify-content: center;
|
|
1197
|
+
padding: 24px;
|
|
1198
|
+
background: rgba(5, 6, 9, 0.72);
|
|
1199
|
+
backdrop-filter: blur(10px);
|
|
1200
|
+
-webkit-backdrop-filter: blur(10px);
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
.donate-modal.is-open {
|
|
1204
|
+
display: flex;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
.donate-modal__panel {
|
|
1208
|
+
width: min(520px, 100%);
|
|
1209
|
+
background: linear-gradient(180deg, rgba(24, 29, 39, 0.95), rgba(14, 18, 26, 0.95));
|
|
1210
|
+
border: 1px solid rgba(255, 255, 255, 0.16);
|
|
1211
|
+
border-radius: 16px;
|
|
1212
|
+
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.45);
|
|
1213
|
+
padding: 26px;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
.donate-modal__header {
|
|
1217
|
+
display: flex;
|
|
1218
|
+
align-items: center;
|
|
1219
|
+
justify-content: space-between;
|
|
1220
|
+
gap: 16px;
|
|
1221
|
+
margin-bottom: 10px;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
.donate-modal__title {
|
|
1225
|
+
font-size: 24px;
|
|
1226
|
+
line-height: 1.15;
|
|
1227
|
+
letter-spacing: -0.01em;
|
|
1228
|
+
color: var(--text-primary);
|
|
1229
|
+
margin: 0;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
.donate-modal__close {
|
|
1233
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
1234
|
+
background: rgba(255, 255, 255, 0.06);
|
|
1235
|
+
color: var(--text-secondary);
|
|
1236
|
+
border-radius: 999px;
|
|
1237
|
+
width: 32px;
|
|
1238
|
+
height: 32px;
|
|
1239
|
+
font-size: 20px;
|
|
1240
|
+
line-height: 1;
|
|
1241
|
+
cursor: pointer;
|
|
1242
|
+
transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
.donate-modal__close:hover {
|
|
1246
|
+
background: rgba(255, 255, 255, 0.14);
|
|
1247
|
+
color: var(--text-primary);
|
|
1248
|
+
border-color: rgba(255, 255, 255, 0.35);
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
.donate-modal__text {
|
|
1252
|
+
margin: 0 0 18px 0;
|
|
1253
|
+
color: var(--text-secondary);
|
|
1254
|
+
font-size: 15px;
|
|
1255
|
+
line-height: 1.55;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
.donate-amounts {
|
|
1259
|
+
display: grid;
|
|
1260
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
1261
|
+
gap: 10px;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
.donate-amount {
|
|
1265
|
+
border: 1px solid rgba(255, 255, 255, 0.18);
|
|
1266
|
+
background: rgba(255, 255, 255, 0.05);
|
|
1267
|
+
color: var(--text-primary);
|
|
1268
|
+
border-radius: 12px;
|
|
1269
|
+
padding: 13px 10px;
|
|
1270
|
+
font-size: 15px;
|
|
1271
|
+
font-weight: 700;
|
|
1272
|
+
letter-spacing: 0.01em;
|
|
1273
|
+
cursor: pointer;
|
|
1274
|
+
transition: border-color 140ms ease, background 140ms ease, transform 140ms ease;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
.donate-amount:hover {
|
|
1278
|
+
border-color: rgba(255, 255, 255, 0.36);
|
|
1279
|
+
background: rgba(255, 255, 255, 0.1);
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
.donate-amount.is-selected {
|
|
1283
|
+
border-color: rgba(245, 158, 11, 0.92);
|
|
1284
|
+
background: rgba(245, 158, 11, 0.17);
|
|
1285
|
+
color: #fff4da;
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
.donate-modal__meta {
|
|
1289
|
+
margin-top: 12px;
|
|
1290
|
+
color: var(--text-tertiary);
|
|
1291
|
+
font-size: 13px;
|
|
1292
|
+
line-height: 1.5;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
.donate-modal__actions {
|
|
1296
|
+
margin-top: 18px;
|
|
1297
|
+
display: flex;
|
|
1298
|
+
gap: 10px;
|
|
1299
|
+
flex-wrap: wrap;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
.donate-modal__actions .btn {
|
|
1303
|
+
border-radius: 10px;
|
|
1304
|
+
min-height: 44px;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
.donate-modal__ghost {
|
|
1308
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
1309
|
+
background: rgba(255, 255, 255, 0.05);
|
|
1310
|
+
color: var(--text-secondary);
|
|
1311
|
+
border-radius: 10px;
|
|
1312
|
+
padding: 0 16px;
|
|
1313
|
+
font-size: 14px;
|
|
1314
|
+
font-weight: 600;
|
|
1315
|
+
cursor: pointer;
|
|
1316
|
+
min-height: 44px;
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
.donate-modal__ghost:hover {
|
|
1320
|
+
color: var(--text-primary);
|
|
1321
|
+
border-color: rgba(255, 255, 255, 0.34);
|
|
1322
|
+
background: rgba(255, 255, 255, 0.1);
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
@media (max-width: 640px) {
|
|
1326
|
+
.donate-modal__panel {
|
|
1327
|
+
padding: 22px 18px;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
.donate-amounts {
|
|
1331
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
.donate-modal__actions .btn,
|
|
1335
|
+
.donate-modal__ghost {
|
|
1336
|
+
width: 100%;
|
|
1337
|
+
justify-content: center;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
/* ========================================
|
|
1342
|
+
SECTION HEADERS (centered)
|
|
1343
|
+
======================================== */
|
|
1344
|
+
.section-header {
|
|
1345
|
+
text-align: center;
|
|
1346
|
+
margin-bottom: 48px;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
.section-header .overline {
|
|
1350
|
+
margin-bottom: 16px;
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
.section-header h2 {
|
|
1354
|
+
margin-bottom: 16px;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
.section-header p {
|
|
1358
|
+
max-width: 540px;
|
|
1359
|
+
margin: 0 auto;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
/* ========================================
|
|
1363
|
+
UTILITIES
|
|
1364
|
+
======================================== */
|
|
1365
|
+
.text-center { text-align: center; }
|
|
1366
|
+
.text-left { text-align: left; }
|
|
1367
|
+
.mt-0 { margin-top: 0; }
|
|
1368
|
+
</style>
|
|
1369
|
+
</head>
|
|
1370
|
+
<body>
|
|
1371
|
+
|
|
1372
|
+
<!-- ==========================================
|
|
1373
|
+
HERO
|
|
1374
|
+
========================================== -->
|
|
1375
|
+
<section class="hero" aria-label="Hero">
|
|
1376
|
+
<div class="wordmark hero__wordmark" aria-label="markupR">
|
|
1377
|
+
markup<span class="wordmark-r">R</span>
|
|
1378
|
+
</div>
|
|
1379
|
+
|
|
1380
|
+
<h1 class="display hero__headline">
|
|
1381
|
+
You found the bug.<br>markup<span class="wordmark-r">R</span> writes it up.
|
|
1382
|
+
</h1>
|
|
1383
|
+
|
|
1384
|
+
<p class="body-lg hero__subtext">
|
|
1385
|
+
AI writes your code. You still have to review it. markupR records your screen while you talk through what you see, then assembles a structured Markdown document your AI agent can act on immediately.
|
|
1386
|
+
</p>
|
|
1387
|
+
|
|
1388
|
+
<div class="hero__ctas">
|
|
1389
|
+
<a href="https://github.com/eddiesanjuan/markupr/releases/latest" class="btn btn--primary" target="_blank" rel="noopener noreferrer">
|
|
1390
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 2a10 10 0 0 0-3.16 19.5l.9-3.5h4.52l.9 3.5A10 10 0 0 0 12 2Z"/><path d="M12 2v7"/><path d="M8 9h8"/></svg>
|
|
1391
|
+
Download for macOS
|
|
1392
|
+
</a>
|
|
1393
|
+
<a href="https://github.com/eddiesanjuan/markupr" class="btn btn--secondary" target="_blank" rel="noopener noreferrer">
|
|
1394
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/></svg>
|
|
1395
|
+
View on GitHub
|
|
1396
|
+
</a>
|
|
1397
|
+
<button type="button" class="btn btn--secondary" data-donate-open>
|
|
1398
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78L12 21.23l8.84-8.84a5.5 5.5 0 0 0 0-7.78Z"/></svg>
|
|
1399
|
+
Support Development
|
|
1400
|
+
</button>
|
|
1401
|
+
</div>
|
|
1402
|
+
|
|
1403
|
+
<p class="caption hero__support-note">
|
|
1404
|
+
If markupr saves you a debugging session, chip in a small donation to keep shipping updates fast.
|
|
1405
|
+
</p>
|
|
1406
|
+
|
|
1407
|
+
<div class="hero__shortcut">
|
|
1408
|
+
<span class="hero__shortcut-label">Start with</span>
|
|
1409
|
+
<div class="kbd-group">
|
|
1410
|
+
<kbd>⌘</kbd>
|
|
1411
|
+
<span class="kbd-plus">+</span>
|
|
1412
|
+
<kbd>⇧</kbd>
|
|
1413
|
+
<span class="kbd-plus">+</span>
|
|
1414
|
+
<kbd>F</kbd>
|
|
1415
|
+
</div>
|
|
1416
|
+
</div>
|
|
1417
|
+
</section>
|
|
1418
|
+
|
|
1419
|
+
<!-- ==========================================
|
|
1420
|
+
QUICK VISUAL WALKTHROUGH
|
|
1421
|
+
========================================== -->
|
|
1422
|
+
<section class="quickwalk" aria-label="Quick visual walkthrough">
|
|
1423
|
+
<div class="container--wide">
|
|
1424
|
+
<div class="section-header reveal">
|
|
1425
|
+
<p class="overline">Quick visual walkthrough</p>
|
|
1426
|
+
<h2>See the full flow in a few seconds.</h2>
|
|
1427
|
+
<p class="body-sm" style="max-width: 620px; margin-top: 14px;">
|
|
1428
|
+
You record and mark shots. After you stop, markupR runs AI alignment on narration + frames and generates a clean report your agent can use.
|
|
1429
|
+
</p>
|
|
1430
|
+
</div>
|
|
1431
|
+
|
|
1432
|
+
<div class="quickwalk__layout">
|
|
1433
|
+
<div class="quickwalk__panel quickwalk__sim reveal reveal-delay-1" aria-label="Animated capture to report pipeline">
|
|
1434
|
+
<div class="quickwalk__status">
|
|
1435
|
+
<span class="quickwalk__status-dot" aria-hidden="true"></span>
|
|
1436
|
+
<span>Session active: recording + manual shot marks</span>
|
|
1437
|
+
<span class="quickwalk__status-time">00:42</span>
|
|
1438
|
+
</div>
|
|
1439
|
+
|
|
1440
|
+
<div class="quickwalk__pipeline" aria-hidden="true">
|
|
1441
|
+
<div class="quickwalk__node quickwalk__node--capture">Capture</div>
|
|
1442
|
+
<div class="quickwalk__pipe"><span class="quickwalk__pulse"></span></div>
|
|
1443
|
+
<div class="quickwalk__node quickwalk__node--align">AI Aligns</div>
|
|
1444
|
+
<div class="quickwalk__pipe"><span class="quickwalk__pulse quickwalk__pulse--delay"></span></div>
|
|
1445
|
+
<div class="quickwalk__node quickwalk__node--report">Report Ready</div>
|
|
1446
|
+
</div>
|
|
1447
|
+
|
|
1448
|
+
<p class="quickwalk__caption">
|
|
1449
|
+
Shot markers confirm instantly while you narrate. Assembly happens after stop.
|
|
1450
|
+
</p>
|
|
1451
|
+
</div>
|
|
1452
|
+
|
|
1453
|
+
<div class="quickwalk__panel quickwalk__result reveal reveal-delay-2">
|
|
1454
|
+
<div class="quickwalk__report" aria-hidden="true">
|
|
1455
|
+
<div class="quickwalk__line quickwalk__line--title"></div>
|
|
1456
|
+
<div class="quickwalk__line quickwalk__line--full"></div>
|
|
1457
|
+
<div class="quickwalk__line quickwalk__line--mid"></div>
|
|
1458
|
+
<div class="quickwalk__line quickwalk__line--short"></div>
|
|
1459
|
+
<div class="quickwalk__image"></div>
|
|
1460
|
+
</div>
|
|
1461
|
+
<p class="quickwalk__paste">Output: AI-readable markdown ready to paste into GitHub, Linear, Slack, or your coding agent.</p>
|
|
1462
|
+
</div>
|
|
1463
|
+
</div>
|
|
1464
|
+
</div>
|
|
1465
|
+
</section>
|
|
1466
|
+
|
|
1467
|
+
<hr class="divider" aria-hidden="true">
|
|
1468
|
+
|
|
1469
|
+
<!-- ==========================================
|
|
1470
|
+
CORE LOOP
|
|
1471
|
+
========================================== -->
|
|
1472
|
+
<section class="loop" aria-label="How it works">
|
|
1473
|
+
<div class="container--wide">
|
|
1474
|
+
<div class="section-header reveal">
|
|
1475
|
+
<p class="overline">How it works</p>
|
|
1476
|
+
<h2>Three steps from bug to AI-ready report.</h2>
|
|
1477
|
+
</div>
|
|
1478
|
+
|
|
1479
|
+
<div class="loop__grid">
|
|
1480
|
+
<!-- Step 1 -->
|
|
1481
|
+
<div class="loop__step reveal reveal-delay-1">
|
|
1482
|
+
<div class="loop__role loop__role--you">you</div>
|
|
1483
|
+
<div class="loop__icon-box">
|
|
1484
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
1485
|
+
<path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"/>
|
|
1486
|
+
<path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
|
|
1487
|
+
<line x1="12" y1="19" x2="12" y2="22"/>
|
|
1488
|
+
</svg>
|
|
1489
|
+
</div>
|
|
1490
|
+
<div class="loop__label">Record + Narrate</div>
|
|
1491
|
+
<div class="loop__desc">Start a session and describe what you see in real time.</div>
|
|
1492
|
+
</div>
|
|
1493
|
+
|
|
1494
|
+
<!-- Step 2 -->
|
|
1495
|
+
<div class="loop__step loop__step--auto reveal reveal-delay-2">
|
|
1496
|
+
<div class="loop__role loop__role--auto">markupR</div>
|
|
1497
|
+
<div class="loop__icon-box">
|
|
1498
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
1499
|
+
<circle cx="12" cy="12" r="3"/>
|
|
1500
|
+
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z"/>
|
|
1501
|
+
</svg>
|
|
1502
|
+
</div>
|
|
1503
|
+
<div class="loop__label">Mark + Assemble</div>
|
|
1504
|
+
<div class="loop__desc">Manual shots are confirmed instantly, then AI aligns transcript + frames after stop.</div>
|
|
1505
|
+
</div>
|
|
1506
|
+
|
|
1507
|
+
<!-- Step 3 -->
|
|
1508
|
+
<div class="loop__step reveal reveal-delay-3">
|
|
1509
|
+
<div class="loop__role loop__role--you">you</div>
|
|
1510
|
+
<div class="loop__icon-box">
|
|
1511
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
1512
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"/>
|
|
1513
|
+
<path d="M14 2v6h6"/>
|
|
1514
|
+
<line x1="9" y1="13" x2="15" y2="13"/>
|
|
1515
|
+
<line x1="9" y1="17" x2="13" y2="17"/>
|
|
1516
|
+
</svg>
|
|
1517
|
+
</div>
|
|
1518
|
+
<div class="loop__label">Share Report</div>
|
|
1519
|
+
<div class="loop__desc">Open the markdown report and paste it into your tools or AI agent.</div>
|
|
1520
|
+
</div>
|
|
1521
|
+
</div>
|
|
1522
|
+
|
|
1523
|
+
<!-- The actual user experience -->
|
|
1524
|
+
<div class="keystroke-flow reveal">
|
|
1525
|
+
<div class="keystroke-flow__step">
|
|
1526
|
+
<span class="keystroke-flow__keys">⌘⇧F</span>
|
|
1527
|
+
<span class="keystroke-flow__label">start</span>
|
|
1528
|
+
</div>
|
|
1529
|
+
<span class="keystroke-flow__arrow" aria-hidden="true">→</span>
|
|
1530
|
+
<div class="keystroke-flow__step">
|
|
1531
|
+
<span class="keystroke-flow__ellipsis" aria-hidden="true">...</span>
|
|
1532
|
+
<span class="keystroke-flow__label">talk</span>
|
|
1533
|
+
</div>
|
|
1534
|
+
<span class="keystroke-flow__arrow" aria-hidden="true">→</span>
|
|
1535
|
+
<div class="keystroke-flow__step">
|
|
1536
|
+
<span class="keystroke-flow__keys">⌘⇧F</span>
|
|
1537
|
+
<span class="keystroke-flow__label">stop</span>
|
|
1538
|
+
</div>
|
|
1539
|
+
<span class="keystroke-flow__arrow" aria-hidden="true">→</span>
|
|
1540
|
+
<div class="keystroke-flow__step">
|
|
1541
|
+
<span class="keystroke-flow__keys">⌘V</span>
|
|
1542
|
+
<span class="keystroke-flow__label">paste into your agent</span>
|
|
1543
|
+
</div>
|
|
1544
|
+
</div>
|
|
1545
|
+
</div>
|
|
1546
|
+
</section>
|
|
1547
|
+
|
|
1548
|
+
<hr class="divider" aria-hidden="true">
|
|
1549
|
+
|
|
1550
|
+
<!-- ==========================================
|
|
1551
|
+
WHY IT MATTERS
|
|
1552
|
+
========================================== -->
|
|
1553
|
+
<section aria-label="Why it matters">
|
|
1554
|
+
<div class="container--wide">
|
|
1555
|
+
<div class="section-header reveal">
|
|
1556
|
+
<p class="overline">Why it matters</p>
|
|
1557
|
+
<h2>Feedback without the friction.</h2>
|
|
1558
|
+
</div>
|
|
1559
|
+
|
|
1560
|
+
<div class="why__grid">
|
|
1561
|
+
<!-- Card 1 -->
|
|
1562
|
+
<div class="card why__card reveal reveal-delay-1">
|
|
1563
|
+
<h3>Stop retyping what you already see.</h3>
|
|
1564
|
+
<p>
|
|
1565
|
+
You found the bug. You can see it right there. Now you have to context-switch into writing mode, describe it in text, screenshot it, crop it, drag it into the right spot. markupR lets you just say it. The documentation happens behind you.
|
|
1566
|
+
</p>
|
|
1567
|
+
</div>
|
|
1568
|
+
|
|
1569
|
+
<!-- Card 2 -->
|
|
1570
|
+
<div class="card why__card reveal reveal-delay-2">
|
|
1571
|
+
<h3>You talk at 150 wpm. You type at 60.</h3>
|
|
1572
|
+
<p>
|
|
1573
|
+
A five-minute narration produces more structured output than twenty minutes of writing. And the result is better — markupR places screenshots at the exact moments you were describing something, not wherever you remembered to paste them.
|
|
1574
|
+
</p>
|
|
1575
|
+
</div>
|
|
1576
|
+
|
|
1577
|
+
<!-- Card 3 -->
|
|
1578
|
+
<div class="card why__card reveal reveal-delay-3">
|
|
1579
|
+
<h3>Choose local privacy or cloud convenience.</h3>
|
|
1580
|
+
<p>
|
|
1581
|
+
markupr supports both local Whisper transcription and OpenAI BYOK transcription. Stay fully local when privacy is critical, or use cloud transcription when you want fast setup and reliable results.
|
|
1582
|
+
</p>
|
|
1583
|
+
</div>
|
|
1584
|
+
</div>
|
|
1585
|
+
</div>
|
|
1586
|
+
</section>
|
|
1587
|
+
|
|
1588
|
+
<hr class="divider" aria-hidden="true">
|
|
1589
|
+
|
|
1590
|
+
<!-- ==========================================
|
|
1591
|
+
UNDER THE HOOD
|
|
1592
|
+
========================================== -->
|
|
1593
|
+
<section class="tech" aria-label="Technical details">
|
|
1594
|
+
<div class="container--wide">
|
|
1595
|
+
<div class="section-header reveal">
|
|
1596
|
+
<p class="overline">Under the hood</p>
|
|
1597
|
+
<h2>Built for developers who read source.</h2>
|
|
1598
|
+
</div>
|
|
1599
|
+
|
|
1600
|
+
<div class="tech__content">
|
|
1601
|
+
<!-- Bullets -->
|
|
1602
|
+
<ul class="tech__bullets reveal">
|
|
1603
|
+
<li>
|
|
1604
|
+
<strong>Dual transcription paths</strong>
|
|
1605
|
+
<span>Use local Whisper for on-device processing, or OpenAI BYOK for fast, reliable post-session transcription.</span>
|
|
1606
|
+
</li>
|
|
1607
|
+
<li>
|
|
1608
|
+
<strong>Intelligent frame extraction</strong>
|
|
1609
|
+
<span>Records your full screen, then uses transcript timestamps to pull the exact frames that match what you were describing.</span>
|
|
1610
|
+
</li>
|
|
1611
|
+
<li>
|
|
1612
|
+
<strong>macOS native</strong>
|
|
1613
|
+
<span>Lives in your menu bar. No dock icon. No browser tab. Launches at login if you want it to.</span>
|
|
1614
|
+
</li>
|
|
1615
|
+
<li>
|
|
1616
|
+
<strong>Structured Markdown output</strong>
|
|
1617
|
+
<span>Sections, headings, and images assembled into a document your tools already understand. Paste into GitHub, feed to Claude Code, drop into Slack.</span>
|
|
1618
|
+
</li>
|
|
1619
|
+
<li>
|
|
1620
|
+
<strong>Open source, MIT licensed</strong>
|
|
1621
|
+
<span>Read the code, fork it, break it, fix it. No telemetry, no tracking, no analytics.</span>
|
|
1622
|
+
</li>
|
|
1623
|
+
</ul>
|
|
1624
|
+
|
|
1625
|
+
<!-- Code Block -->
|
|
1626
|
+
<div class="code-block reveal reveal-delay-1">
|
|
1627
|
+
<div class="code-block__header">
|
|
1628
|
+
<span class="code-block__dot code-block__dot--red"></span>
|
|
1629
|
+
<span class="code-block__dot code-block__dot--yellow"></span>
|
|
1630
|
+
<span class="code-block__dot code-block__dot--green"></span>
|
|
1631
|
+
<span class="code-block__title">session-output.md</span>
|
|
1632
|
+
</div>
|
|
1633
|
+
<pre><code><span class="syn-kw">## Feedback Session</span> <span class="syn-cm">— Feb 5, 2026</span>
|
|
1634
|
+
|
|
1635
|
+
<span class="syn-kw">### Button sizing issue</span>
|
|
1636
|
+
The submit button is way too small on mobile.
|
|
1637
|
+
I'm trying to tap it and keep hitting the cancel
|
|
1638
|
+
link underneath. Needs more vertical padding,
|
|
1639
|
+
maybe 12px minimum tap target.
|
|
1640
|
+
<span class="syn-fn">![Screenshot at 0:34]</span><span class="syn-str">(screenshots/fb-001.png)</span>
|
|
1641
|
+
|
|
1642
|
+
<span class="syn-kw">### Loading state feels janky</span>
|
|
1643
|
+
After the spinner disappears, the content just
|
|
1644
|
+
pops in with no transition. There's a visible
|
|
1645
|
+
layout shift — the sidebar jumps left by about
|
|
1646
|
+
20 pixels.
|
|
1647
|
+
<span class="syn-fn">![Screenshot at 1:12]</span><span class="syn-str">(screenshots/fb-002.png)</span>
|
|
1648
|
+
|
|
1649
|
+
<span class="syn-kw">### Nav highlight is wrong</span>
|
|
1650
|
+
I'm on the Settings page but the Dashboard tab
|
|
1651
|
+
is still highlighted. Looks like the active state
|
|
1652
|
+
isn't updating on route change.
|
|
1653
|
+
<span class="syn-fn">![Screenshot at 1:45]</span><span class="syn-str">(screenshots/fb-003.png)</span></code></pre>
|
|
1654
|
+
</div>
|
|
1655
|
+
</div>
|
|
1656
|
+
</div>
|
|
1657
|
+
</section>
|
|
1658
|
+
|
|
1659
|
+
<hr class="divider" aria-hidden="true">
|
|
1660
|
+
|
|
1661
|
+
<!-- ==========================================
|
|
1662
|
+
PREMIUM TEASER
|
|
1663
|
+
========================================== -->
|
|
1664
|
+
<section aria-label="Premium features">
|
|
1665
|
+
<div class="container--wide">
|
|
1666
|
+
<div class="section-header reveal">
|
|
1667
|
+
<p class="overline">Launch Modes</p>
|
|
1668
|
+
<h2>Same markupr output. Two ways to run it.</h2>
|
|
1669
|
+
<p class="body-lg" style="margin-top: 16px;">
|
|
1670
|
+
markupr open source and markupr premium run the same core pipeline: record screen + narration, transcribe, extract the right frames, and generate agent-ready markdown. Premium is the touchless path with hosted keys preconfigured. BYOK stays fully supported.
|
|
1671
|
+
</p>
|
|
1672
|
+
</div>
|
|
1673
|
+
|
|
1674
|
+
<div class="premium__features">
|
|
1675
|
+
<div class="card premium__card reveal reveal-delay-1">
|
|
1676
|
+
<h3>Open source (BYOK)</h3>
|
|
1677
|
+
<p>Bring your own OpenAI + Anthropic keys. Full control, same report quality, fully transparent stack.</p>
|
|
1678
|
+
</div>
|
|
1679
|
+
<div class="card premium__card reveal reveal-delay-2">
|
|
1680
|
+
<h3>Premium (touchless)</h3>
|
|
1681
|
+
<p>Exactly the same workflow and output, but keys are hosted for you. No API setup screens, no key management.</p>
|
|
1682
|
+
</div>
|
|
1683
|
+
<div class="card premium__card reveal reveal-delay-3">
|
|
1684
|
+
<h3>Switch anytime</h3>
|
|
1685
|
+
<p>Start with BYOK tonight, move to premium when you want convenience. No workflow migration required.</p>
|
|
1686
|
+
</div>
|
|
1687
|
+
</div>
|
|
1688
|
+
|
|
1689
|
+
<div class="premium__cta reveal">
|
|
1690
|
+
<a class="btn btn--primary" href="https://github.com/eddiesanjuan/markupr" target="_blank" rel="noopener noreferrer">Use BYOK Open Source</a>
|
|
1691
|
+
<a class="btn btn--accent" href="mailto:premium@markupr.com?subject=markupr%20premium%20access">Get Premium Access</a>
|
|
1692
|
+
</div>
|
|
1693
|
+
<p class="caption premium__note reveal">Launch plan: both BYOK and premium are available on day one. Premium is convenience, not extra capability.</p>
|
|
1694
|
+
</div>
|
|
1695
|
+
</section>
|
|
1696
|
+
|
|
1697
|
+
<!-- ==========================================
|
|
1698
|
+
FOOTER
|
|
1699
|
+
========================================== -->
|
|
1700
|
+
<footer class="footer" aria-label="Footer">
|
|
1701
|
+
<div class="footer__divider"></div>
|
|
1702
|
+
|
|
1703
|
+
<nav class="footer__links" aria-label="Footer navigation">
|
|
1704
|
+
<a href="https://github.com/eddiesanjuan/markupr" class="footer__link" target="_blank" rel="noopener noreferrer">
|
|
1705
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/></svg>
|
|
1706
|
+
GitHub
|
|
1707
|
+
</a>
|
|
1708
|
+
<button type="button" class="footer__link footer__link--button" data-donate-open>
|
|
1709
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78L12 21.23l8.84-8.84a5.5 5.5 0 0 0 0-7.78Z"/></svg>
|
|
1710
|
+
Support markupr
|
|
1711
|
+
</button>
|
|
1712
|
+
</nav>
|
|
1713
|
+
|
|
1714
|
+
<p class="footer__license">MIT License. Free as in freedom, free as in beer.</p>
|
|
1715
|
+
<p class="footer__built">Built by <a href="https://github.com/eddiesanjuan">Eddie San Juan</a>.</p>
|
|
1716
|
+
<p class="footer__support">Want faster shipping? <a href="https://ko-fi.com/eddiesanjuan" target="_blank" rel="noopener noreferrer">Support markupr on Ko-fi</a>.</p>
|
|
1717
|
+
</footer>
|
|
1718
|
+
|
|
1719
|
+
<div class="donate-modal" id="donateModal" aria-hidden="true">
|
|
1720
|
+
<div class="donate-modal__panel" role="dialog" aria-modal="true" aria-labelledby="donateModalTitle">
|
|
1721
|
+
<div class="donate-modal__header">
|
|
1722
|
+
<h3 class="donate-modal__title" id="donateModalTitle">Support markupr</h3>
|
|
1723
|
+
<button type="button" class="donate-modal__close" aria-label="Close donation dialog" data-donate-close>×</button>
|
|
1724
|
+
</div>
|
|
1725
|
+
<p class="donate-modal__text">
|
|
1726
|
+
If markupr saves you time, you can drop a quick contribution here. Pick an amount and continue straight to Ko-fi checkout.
|
|
1727
|
+
</p>
|
|
1728
|
+
<div class="donate-amounts" role="radiogroup" aria-label="Donation amount">
|
|
1729
|
+
<button type="button" class="donate-amount" data-amount="5" aria-pressed="false">$5</button>
|
|
1730
|
+
<button type="button" class="donate-amount is-selected" data-amount="10" aria-pressed="true">$10</button>
|
|
1731
|
+
<button type="button" class="donate-amount" data-amount="25" aria-pressed="false">$25</button>
|
|
1732
|
+
</div>
|
|
1733
|
+
<p class="donate-modal__meta">
|
|
1734
|
+
You will complete payment securely on Ko-fi.
|
|
1735
|
+
</p>
|
|
1736
|
+
<div class="donate-modal__actions">
|
|
1737
|
+
<button type="button" class="btn btn--accent" id="donateContinue">Continue to Ko-fi</button>
|
|
1738
|
+
<button type="button" class="donate-modal__ghost" data-donate-close>Not now</button>
|
|
1739
|
+
</div>
|
|
1740
|
+
</div>
|
|
1741
|
+
</div>
|
|
1742
|
+
|
|
1743
|
+
<!-- ==========================================
|
|
1744
|
+
SCROLL REVEAL — Minimal JS
|
|
1745
|
+
========================================== -->
|
|
1746
|
+
<script>
|
|
1747
|
+
(function() {
|
|
1748
|
+
// Respect reduced motion preference
|
|
1749
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
|
1750
|
+
|
|
1751
|
+
var observer = new IntersectionObserver(function(entries) {
|
|
1752
|
+
entries.forEach(function(entry) {
|
|
1753
|
+
if (entry.isIntersecting) {
|
|
1754
|
+
entry.target.classList.add('visible');
|
|
1755
|
+
observer.unobserve(entry.target);
|
|
1756
|
+
}
|
|
1757
|
+
});
|
|
1758
|
+
}, { threshold: 0.15 });
|
|
1759
|
+
|
|
1760
|
+
document.querySelectorAll('.reveal').forEach(function(el) {
|
|
1761
|
+
observer.observe(el);
|
|
1762
|
+
});
|
|
1763
|
+
})();
|
|
1764
|
+
|
|
1765
|
+
(function() {
|
|
1766
|
+
var modal = document.getElementById('donateModal');
|
|
1767
|
+
var openButtons = document.querySelectorAll('[data-donate-open]');
|
|
1768
|
+
var continueButton = document.getElementById('donateContinue');
|
|
1769
|
+
var amountButtons = document.querySelectorAll('.donate-amount');
|
|
1770
|
+
var closeButtons = document.querySelectorAll('[data-donate-close]');
|
|
1771
|
+
var selectedAmount = '10';
|
|
1772
|
+
|
|
1773
|
+
if (!modal || !openButtons.length || !continueButton || !amountButtons.length) return;
|
|
1774
|
+
|
|
1775
|
+
function setAmount(amount) {
|
|
1776
|
+
selectedAmount = amount;
|
|
1777
|
+
amountButtons.forEach(function(button) {
|
|
1778
|
+
var isSelected = button.getAttribute('data-amount') === amount;
|
|
1779
|
+
button.classList.toggle('is-selected', isSelected);
|
|
1780
|
+
button.setAttribute('aria-pressed', isSelected ? 'true' : 'false');
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
function openModal() {
|
|
1785
|
+
modal.classList.add('is-open');
|
|
1786
|
+
modal.setAttribute('aria-hidden', 'false');
|
|
1787
|
+
document.body.classList.add('donate-modal-open');
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
function closeModal() {
|
|
1791
|
+
modal.classList.remove('is-open');
|
|
1792
|
+
modal.setAttribute('aria-hidden', 'true');
|
|
1793
|
+
document.body.classList.remove('donate-modal-open');
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
openButtons.forEach(function(button) {
|
|
1797
|
+
button.addEventListener('click', openModal);
|
|
1798
|
+
});
|
|
1799
|
+
closeButtons.forEach(function(button) {
|
|
1800
|
+
button.addEventListener('click', closeModal);
|
|
1801
|
+
});
|
|
1802
|
+
|
|
1803
|
+
modal.addEventListener('click', function(event) {
|
|
1804
|
+
if (event.target === modal) {
|
|
1805
|
+
closeModal();
|
|
1806
|
+
}
|
|
1807
|
+
});
|
|
1808
|
+
|
|
1809
|
+
document.addEventListener('keydown', function(event) {
|
|
1810
|
+
if (event.key === 'Escape' && modal.classList.contains('is-open')) {
|
|
1811
|
+
closeModal();
|
|
1812
|
+
}
|
|
1813
|
+
});
|
|
1814
|
+
|
|
1815
|
+
amountButtons.forEach(function(button) {
|
|
1816
|
+
button.addEventListener('click', function() {
|
|
1817
|
+
var amount = button.getAttribute('data-amount') || '10';
|
|
1818
|
+
setAmount(amount);
|
|
1819
|
+
});
|
|
1820
|
+
});
|
|
1821
|
+
|
|
1822
|
+
continueButton.addEventListener('click', function() {
|
|
1823
|
+
var donateUrl = new URL('https://ko-fi.com/eddiesanjuan');
|
|
1824
|
+
donateUrl.searchParams.set('amount', selectedAmount);
|
|
1825
|
+
donateUrl.searchParams.set('hidefeed', 'true');
|
|
1826
|
+
donateUrl.searchParams.set('utm_source', 'markupr_site');
|
|
1827
|
+
donateUrl.searchParams.set('utm_medium', 'donation_modal');
|
|
1828
|
+
window.open(donateUrl.toString(), '_blank', 'noopener,noreferrer');
|
|
1829
|
+
closeModal();
|
|
1830
|
+
});
|
|
1831
|
+
})();
|
|
1832
|
+
</script>
|
|
1833
|
+
|
|
1834
|
+
</body>
|
|
1835
|
+
</html>
|