Skip to content

Commit 10f025c

Browse files
committed
🎨 Dark-first docs theme, permission auto-prompting, and codesign improvements
- Docs site defaults to dark theme matching landing page brand - Green accent color, themed code blocks, tables, and blockquotes - App prompts for accessibility/screen recording on first launch - Prefer Developer ID over Apple Development for stable TCC grants - Touch bundle after build so Finder shows correct modified date
1 parent e9c36f6 commit 10f025c

8 files changed

Lines changed: 70 additions & 33 deletions

File tree

-16 Bytes
Binary file not shown.

‎app/Sources/HotkeyManager.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Carbon
22
import AppKit
3+
import Foundation
34

45
/// Global callback registry keyed by hotkey ID
56
private var hotkeyCallbacks: [UInt32: () -> Void] = [:]

‎app/Sources/PermissionChecker.swift‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ final class PermissionChecker: ObservableObject {
1313

1414
var allGranted: Bool { accessibility && screenRecording }
1515

16-
/// Check current permission state without prompting.
16+
/// Check current permission state, prompting on first launch if not granted.
1717
func check() {
1818
let diag = DiagnosticLog.shared
1919

2020
let ax = AXIsProcessTrusted()
2121
let sr = CGPreflightScreenCaptureAccess()
2222

23-
// First check: log detailed identity info to help debug TCC issues
23+
// First check: log identity info and prompt if needed
2424
if !hasLoggedInitial {
2525
hasLoggedInitial = true
2626
let bundleId = Bundle.main.bundleIdentifier ?? "<no bundle id>"
@@ -30,6 +30,16 @@ final class PermissionChecker: ObservableObject {
3030
diag.info("PermissionChecker: exec=\(execPath)")
3131
diag.info("AXIsProcessTrusted() → \(ax)")
3232
diag.info("CGPreflightScreenCaptureAccess() → \(sr)")
33+
34+
// Prompt for missing permissions on first check
35+
if !ax {
36+
requestAccessibility()
37+
return
38+
}
39+
if !sr {
40+
requestScreenRecording()
41+
return
42+
}
3343
}
3444

3545
// Log on state changes

‎bin/lattices-app.js‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ function buildFromSource() {
7878
try {
7979
// Prefer a real signing identity for stable TCC grants; fall back to ad-hoc with fixed identifier
8080
const identities = execSync("security find-identity -v -p codesigning", { stdio: "pipe" }).toString();
81-
const devId = identities.match(/"(Apple Development:[^"]+)"/)?.[1]
82-
|| identities.match(/"(Developer ID Application:[^"]+)"/)?.[1];
81+
const devId = identities.match(/"(Developer ID Application:[^"]+)"/)?.[1]
82+
|| identities.match(/"(Apple Development:[^"]+)"/)?.[1];
8383
const signArg = devId ? `'${devId}'` : "-";
8484
execSync(
8585
`codesign --force --sign ${signArg} --identifier com.arach.lattices '${bundlePath}'`,
@@ -89,6 +89,8 @@ function buildFromSource() {
8989
// Non-fatal — app still works, just permissions won't persist across rebuilds
9090
console.log("Warning: code signing failed — permissions may not persist across rebuilds.");
9191
}
92+
// Update bundle timestamp so Finder shows the correct modified date
93+
try { execSync(`touch '${bundlePath}'`, { stdio: "pipe" }); } catch {}
9294
console.log("Build complete.");
9395
return true;
9496
}

‎docs-site/src/layouts/BaseLayout.astro‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const { title = 'Docs' } = Astro.props
1919
try {
2020
var saved = localStorage.getItem('theme')
2121
} catch (e) {}
22-
var theme = saved || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
22+
var theme = saved || (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark')
2323
document.documentElement.setAttribute('data-theme', theme)
2424
})()
2525
</script>
@@ -82,7 +82,7 @@ const { title = 'Docs' } = Astro.props
8282
try {
8383
var themeToggle = document.querySelector('[data-theme-toggle]')
8484
themeToggle && themeToggle.addEventListener('click', function () {
85-
var current = document.documentElement.getAttribute('data-theme') || 'light'
85+
var current = document.documentElement.getAttribute('data-theme') || 'dark'
8686
var next = current === 'dark' ? 'light' : 'dark'
8787
document.documentElement.setAttribute('data-theme', next)
8888
try { localStorage.setItem('theme', next) } catch (e) {}
@@ -161,7 +161,7 @@ const { title = 'Docs' } = Astro.props
161161
block.dataset.copyReady = 'true'
162162
var button = document.createElement('button')
163163
button.textContent = 'Copy'
164-
button.className = 'absolute right-3 top-3 rounded bg-black/60 px-2 py-1 text-xs text-white transition hover:bg-black/80'
164+
button.className = 'absolute right-3 top-3 rounded bg-white/10 px-2 py-1 text-xs text-[var(--color-text-muted)] transition hover:bg-white/15 hover:text-[var(--color-text)]'
165165
button.addEventListener('click', function () {
166166
var code = block.querySelector('code')
167167
if (!code) return

‎docs-site/src/styles/base.css‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
}
55

66
html {
7-
color-scheme: light;
7+
color-scheme: dark;
88
font-family: "Space Grotesk", "Inter", "SF Pro Text", system-ui, -apple-system, sans-serif;
99
background: var(--color-bg);
1010
color: var(--color-text);
11+
-webkit-font-smoothing: antialiased;
12+
-moz-osx-font-smoothing: grayscale;
1113
}
1214

1315
body {
@@ -18,8 +20,8 @@
1820
position: relative;
1921
}
2022

21-
[data-theme='dark'] {
22-
color-scheme: dark;
23+
[data-theme='light'] {
24+
color-scheme: light;
2325
}
2426

2527
h1,

‎docs-site/src/styles/markdown.css‎

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,16 @@
7171
}
7272

7373
.doc-content pre {
74-
background: #1e1e1e;
75-
border: 1px solid rgba(255, 255, 255, 0.1);
74+
background: var(--color-surface);
75+
border: 1px solid var(--color-border-lit);
7676
border-radius: var(--radius-md);
7777
padding: 1rem 1.25rem;
7878
overflow-x: auto;
7979
}
8080

8181
.doc-content code {
82-
background: rgba(255, 255, 255, 0.08);
83-
border: 1px solid rgba(255, 255, 255, 0.12);
82+
background: var(--color-surface);
83+
border: 1px solid var(--color-border-lit);
8484
border-radius: 4px;
8585
padding: 0.15rem 0.4rem;
8686
font-size: 12px;
@@ -114,7 +114,26 @@
114114
text-align: left;
115115
}
116116

117+
.doc-content th {
118+
background: var(--color-surface);
119+
font-weight: 600;
120+
font-size: 13px;
121+
}
122+
117123
.doc-content tr:last-child td {
118124
border-bottom: none;
119125
}
126+
127+
.doc-content blockquote {
128+
margin: 0 0 1.25rem;
129+
padding: 0.75rem 1rem;
130+
border-left: 3px solid var(--color-accent);
131+
background: var(--color-surface);
132+
border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
133+
color: var(--color-text-muted);
134+
}
135+
136+
.doc-content blockquote p:last-child {
137+
margin-bottom: 0;
138+
}
120139
}
Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
11
@layer base {
22
:root {
3-
--color-bg: #f7f3ec;
4-
--color-surface: #ffffff;
5-
--color-surface-muted: #f3efe7;
6-
--color-border: rgba(16, 21, 24, 0.1);
7-
--color-text: #101518;
8-
--color-text-muted: #5c676c;
9-
--color-accent: #f07c4f;
10-
--color-accent-strong: #e86f42;
3+
/* Dark-first — matches landing page and native app brand */
4+
--color-bg: #111113;
5+
--color-surface: #1c1c1e;
6+
--color-surface-muted: #161618;
7+
--color-border: rgba(255, 255, 255, 0.06);
8+
--color-border-lit: rgba(255, 255, 255, 0.10);
9+
--color-text: rgba(255, 255, 255, 0.92);
10+
--color-text-muted: rgba(255, 255, 255, 0.50);
11+
--color-accent: #33c773;
12+
--color-accent-strong: #3dd882;
1113
--radius-sm: 6px;
1214
--radius-md: 10px;
1315
--radius-lg: 14px;
1416
--sidebar-width: 260px;
1517
--toc-width: 220px;
1618
--content-max: 760px;
17-
--shadow-soft: 0 12px 30px rgba(16, 21, 24, 0.08);
19+
--shadow-soft: 0 12px 30px rgba(0, 0, 0, 0.35);
1820
}
1921

20-
[data-theme='dark'] {
21-
--color-bg: #0a0c0e;
22-
--color-surface: #101418;
23-
--color-surface-muted: #121820;
24-
--color-border: rgba(255, 255, 255, 0.08);
25-
--color-text: #e5e7eb;
26-
--color-text-muted: #9ca3af;
27-
--color-accent: #f07c4f;
28-
--color-accent-strong: #f07c4f;
29-
--shadow-soft: 0 12px 30px rgba(0, 0, 0, 0.35);
22+
[data-theme='light'] {
23+
--color-bg: #fafaf9;
24+
--color-surface: #ffffff;
25+
--color-surface-muted: #f3f3f1;
26+
--color-border: rgba(16, 21, 24, 0.10);
27+
--color-border-lit: rgba(16, 21, 24, 0.15);
28+
--color-text: #101518;
29+
--color-text-muted: #5c676c;
30+
--color-accent: #1a9d52;
31+
--color-accent-strong: #158a47;
32+
--shadow-soft: 0 12px 30px rgba(16, 21, 24, 0.08);
3033
}
3134
}

0 commit comments

Comments
 (0)