Files
memos-chrome-extension/src/settings.css
Paul Spenke 84b3dd69f1 Fix security bugs and migrate image uploads to /api/v1/attachments
* Replace /api/v1/resources with /api/v1/attachments for image uploads
* Upload attachments as JSON with base64-encoded content field
* After memo creation, link each attachment via PATCH /api/v1/attachments/{id}
* Rewrite markdown image URLs to use /file/attachments/{id} pattern
* Fix XSS: sanitize marked.parse output with a DOM-based allowlist sanitizer
* Fix SSRF: validate img.src scheme (http/https only) before fetching
* Fix stack overflow: use chunked base64 encoding for large images
* Update CLAUDE.md to document new attachment flow
2026-03-18 17:55:04 +01:00

170 lines
3.3 KiB
CSS

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=IBM+Plex+Sans:wght@400;500;600&display=swap');
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #f9fafb;
--surface: #ffffff;
--border: #f3f4f6;
--accent: #10b981;
--accent-dim: #10b98130;
--text: #111827;
--text-dim: #4b5563;
--success: #10b981;
--error: #ef4444;
--radius: 8px;
--font: 'IBM Plex Sans', sans-serif;
--mono: 'IBM Plex Mono', monospace;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #0f0f11;
--surface: #1a1a1f;
--border: #2a2a35;
--text: #e8e8f0;
--text-dim: #888899;
--success: #4ade80;
--error: #f87171;
}
}
body {
font-family: var(--font);
background: var(--bg);
color: var(--text);
min-height: 100vh;
font-size: 14px;
line-height: 1.6;
}
.page { max-width: 560px; margin: 0 auto; padding: 32px 24px; }
header {
margin-bottom: 32px;
}
.logo {
display: flex;
align-items: center;
gap: 10px;
font-size: 16px;
font-weight: 600;
color: var(--text);
}
.logo svg { width: 22px; height: 22px; stroke: var(--accent); }
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 12px;
padding: 24px;
margin-bottom: 20px;
}
.card h2 {
font-size: 13px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: .08em;
color: var(--text-dim);
margin-bottom: 20px;
}
label {
display: flex;
flex-direction: column;
gap: 6px;
margin-bottom: 16px;
}
label > span {
font-size: 13px;
font-weight: 500;
color: var(--text);
}
input[type="url"],
input[type="password"],
input[type="text"],
select {
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-family: var(--mono);
font-size: 13px;
padding: 9px 12px;
outline: none;
transition: border-color .15s;
width: 100%;
}
input:focus, select:focus {
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-dim);
}
select option { background: var(--surface); }
small {
font-size: 11px;
color: var(--text-dim);
font-family: var(--font);
}
.checkbox-label {
flex-direction: row;
align-items: center;
gap: 10px;
cursor: pointer;
}
.checkbox-label input[type="checkbox"] {
width: 16px;
height: 16px;
accent-color: var(--accent);
cursor: pointer;
}
.checkbox-label span { font-size: 13px; font-weight: 400; }
.actions {
display: flex;
gap: 10px;
margin-top: 20px;
}
button {
font-family: var(--font);
font-size: 13px;
font-weight: 500;
padding: 9px 18px;
border-radius: var(--radius);
border: none;
cursor: pointer;
transition: all .15s;
}
button:not(.secondary) {
background: var(--accent);
color: #fff;
}
button:not(.secondary):hover { filter: brightness(1.15); }
button.secondary {
background: transparent;
border: 1px solid var(--border);
color: var(--text-dim);
}
button.secondary:hover { border-color: var(--accent); color: var(--accent); }
.status {
margin-top: 12px;
padding: 9px 12px;
border-radius: var(--radius);
font-size: 12px;
font-family: var(--mono);
}
.status.hidden { display: none; }
.status.ok { background: #4ade8015; border: 1px solid #4ade8040; color: var(--success); }
.status.err { background: #f8717115; border: 1px solid #f8717140; color: var(--error); }