Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ plannotator/
│ │ ├── ide.ts # VS Code diff integration (openEditorDiff)
│ │ ├── editor-annotations.ts # VS Code editor annotation endpoints
│ │ └── project.ts # Project name detection for tags
│ ├── ui/ # Shared React components
│ ├── ui/ # Shared React components + theme
│ │ ├── theme.css # Single source of truth for color tokens + Tailwind bridge
│ │ ├── components/ # Viewer, Toolbar, Settings, etc.
│ │ │ ├── plan-diff/ # PlanDiffBadge, PlanDiffViewer, clean/raw diff views
│ │ │ └── sidebar/ # SidebarContainer, SidebarTabs, VersionBrowser
Expand Down
16 changes: 10 additions & 6 deletions apps/marketing/src/layouts/Base.astro
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,19 @@ import '../styles/global.css';
<body class="min-h-screen antialiased">
<slot />
<script is:inline>
// Read theme cookie and set class before paint to prevent FOUC
// Read theme cookies and set classes before paint to prevent FOUC
(function() {
var match = document.cookie.match(/(?:^|; )plannotator-theme=([^;]*)/);
var theme = match ? decodeURIComponent(match[1]) : 'dark';
var root = document.documentElement;
root.classList.remove('light');
if (theme === 'light') {
// Color theme (palette) — marketing uses whatever the user set in the app
var colorMatch = document.cookie.match(/(?:^|; )plannotator-color-theme=([^;]*)/);
var colorTheme = colorMatch ? decodeURIComponent(colorMatch[1]) : 'plannotator';
root.classList.add('theme-' + colorTheme);
// Mode (dark/light/system)
var modeMatch = document.cookie.match(/(?:^|; )plannotator-theme=([^;]*)/);
var mode = modeMatch ? decodeURIComponent(modeMatch[1]) : 'dark';
if (mode === 'light') {
root.classList.add('light');
} else if (theme === 'system') {
} else if (mode === 'system') {
if (window.matchMedia('(prefers-color-scheme: light)').matches) {
root.classList.add('light');
}
Expand Down
146 changes: 1 addition & 145 deletions apps/marketing/src/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,151 +6,7 @@
@source "../layouts/**/*.astro";
@source "../pages/**/*.astro";

:root {
--background: oklch(0.15 0.02 260);
--foreground: oklch(0.90 0.01 260);
--card: oklch(0.22 0.02 260);
--card-foreground: oklch(0.90 0.01 260);
--popover: oklch(0.28 0.025 260);
--popover-foreground: oklch(0.90 0.01 260);
--primary: oklch(0.75 0.18 280);
--primary-foreground: oklch(0.15 0.02 260);
--secondary: oklch(0.65 0.15 180);
--secondary-foreground: oklch(0.15 0.02 260);
--muted: oklch(0.26 0.02 260);
--muted-foreground: oklch(0.72 0.02 260);
--accent: oklch(0.70 0.20 60);
--accent-foreground: oklch(0.15 0.02 260);
--destructive: oklch(0.65 0.20 25);
--destructive-foreground: oklch(0.98 0 0);
--border: oklch(0.35 0.02 260);
--input: oklch(0.26 0.02 260);
--ring: oklch(0.75 0.18 280);
--success: oklch(0.72 0.17 150);
--success-foreground: oklch(0.15 0.02 260);
--warning: oklch(0.75 0.15 85);
--warning-foreground: oklch(0.20 0.02 260);

--font-sans: 'Inter', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
--radius: 0.75rem;
}

.light {
--background: oklch(0.97 0.005 260);
--foreground: oklch(0.18 0.02 260);
--card: oklch(1 0 0);
--card-foreground: oklch(0.18 0.02 260);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.18 0.02 260);
--primary: oklch(0.50 0.25 280);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.50 0.18 180);
--secondary-foreground: oklch(1 0 0);
--muted: oklch(0.92 0.01 260);
--muted-foreground: oklch(0.40 0.02 260);
--accent: oklch(0.60 0.22 50);
--accent-foreground: oklch(0.18 0.02 260);
--destructive: oklch(0.50 0.25 25);
--destructive-foreground: oklch(1 0 0);
--border: oklch(0.88 0.01 260);
--input: oklch(0.92 0.01 260);
--ring: oklch(0.50 0.25 280);
--success: oklch(0.45 0.20 150);
--success-foreground: oklch(1 0 0);
--warning: oklch(0.55 0.18 85);
--warning-foreground: oklch(0.18 0.02 260);
}

@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--font-sans: var(--font-sans);
--font-mono: var(--font-mono);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
}

* {
border-color: var(--border);
}

body {
font-family: var(--font-sans);
background: var(--background);
color: var(--foreground);
font-feature-settings: "ss01", "ss02", "cv01";
}

/* Subtle grid background */
.bg-grid {
background-image:
linear-gradient(to right, oklch(0.32 0.02 260 / 0.5) 1px, transparent 1px),
linear-gradient(to bottom, oklch(0.32 0.02 260 / 0.5) 1px, transparent 1px);
background-size: 24px 24px;
}

.light .bg-grid {
background-image:
linear-gradient(to right, oklch(0.90 0.01 260 / 0.6) 1px, transparent 1px),
linear-gradient(to bottom, oklch(0.90 0.01 260 / 0.6) 1px, transparent 1px);
}

/* Glow effects */
.glow-primary {
box-shadow: 0 0 20px oklch(0.75 0.18 280 / 0.15), 0 0 40px oklch(0.75 0.18 280 / 0.05);
}

.glow-sm {
box-shadow: 0 0 10px oklch(0.75 0.18 280 / 0.1);
}

/* Custom scrollbar */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--muted-foreground); }

/* Selection */
::selection {
background: oklch(0.75 0.18 280 / 0.3);
}

/* Smooth transitions */
* {
transition-property: color, background-color, border-color, box-shadow, opacity, transform;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}

/* Focus states */
:focus-visible {
outline: 2px solid var(--ring);
outline-offset: 2px;
}
@import "../../../../packages/ui/theme.css";

/* Shiki dual theme — dark by default, light when .light class */
.astro-code {
Expand Down
7 changes: 5 additions & 2 deletions packages/editor/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useEffect, useMemo, useRef } from 'react';
import { parseMarkdownToBlocks, exportAnnotations, exportLinkedDocAnnotations, exportEditorAnnotations, extractFrontmatter, Frontmatter } from '@plannotator/ui/utils/parser';
import { parseMarkdownToBlocks, exportAnnotations, exportLinkedDocAnnotations, exportEditorAnnotations, extractFrontmatter, wrapFeedbackForAgent, Frontmatter } from '@plannotator/ui/utils/parser';
import { Viewer, ViewerHandle } from '@plannotator/ui/components/Viewer';
import { AnnotationPanel } from '@plannotator/ui/components/AnnotationPanel';
import { ExportModal } from '@plannotator/ui/components/ExportModal';
Expand Down Expand Up @@ -1041,7 +1041,7 @@ const App: React.FC = () => {
className="w-full text-left px-3 py-1.5 text-xs hover:bg-muted transition-colors flex items-center gap-2"
>
<svg className="w-3.5 h-3.5 text-muted-foreground" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m4-4l-4 4m0 0l-4-4m4 4V4" />
<path strokeLinecap="round" strokeLinejoin="round" d="M15 3h4a2 2 0 012 2v14a2 2 0 01-2 2h-4M10 17l5-5-5-5M15 12H3" />
</svg>
Import Review
</button>
Expand Down Expand Up @@ -1229,6 +1229,9 @@ const App: React.FC = () => {
editorAnnotations={editorAnnotations}
onDeleteEditorAnnotation={deleteEditorAnnotation}
onClose={() => setIsPanelOpen(false)}
onQuickCopy={async () => {
await navigator.clipboard.writeText(wrapFeedbackForAgent(annotationsOutput));
}}
/>
</div>

Expand Down
Loading
Loading