major UI/UX overhaul, a few minor bug fixes

This commit is contained in:
2026-01-18 19:28:07 -05:00
parent 9dc7de9f4f
commit 8fdfc72b4f
8 changed files with 3073 additions and 487 deletions

View File

@@ -540,7 +540,7 @@ function buildTemplateBody(template, replacements) {
try { try {
return JSON.parse(filled); return JSON.parse(filled);
} catch { } catch {
throw new Error("Invalid request template JSON." + filled); throw new Error("Invalid request template JSON.");
} }
} }

View File

@@ -590,7 +590,6 @@ const observer = new MutationObserver(() => {
observer.observe(document.documentElement, { childList: true, subtree: true }); observer.observe(document.documentElement, { childList: true, subtree: true });
chrome.storage.onChanged.addListener(() => { chrome.storage.onChanged.addListener(() => {
if (suppressObserver) return;
scheduleToolbarRefresh(); scheduleToolbarRefresh();
}); });

View File

@@ -1,7 +1,7 @@
{ {
"manifest_version": 3, "manifest_version": 3,
"name": "SiteCompanion", "name": "SiteCompanion",
"version": "0.4.5", "version": "0.4.6",
"description": "AI companion for site-bound text extraction and tasks.", "description": "AI companion for site-bound text extraction and tasks.",
"permissions": ["storage", "activeTab"], "permissions": ["storage", "activeTab"],
"host_permissions": ["<all_urls>"], "host_permissions": ["<all_urls>"],

View File

@@ -287,14 +287,14 @@ button:active {
padding: 8px; padding: 8px;
background: var(--output-bg); background: var(--output-bg);
min-height: 210px; min-height: 210px;
max-height: 360px; max-height: 280px;
overflow: hidden; overflow: hidden;
} }
.output-body { .output-body {
margin: 0; margin: 0;
word-break: break-word; word-break: break-word;
max-height: 340px; max-height: 260px;
overflow-y: auto; overflow-y: auto;
font-size: 11px; font-size: 11px;
line-height: 1.45; line-height: 1.45;

View File

@@ -401,6 +401,75 @@ function sanitizeUrl(url) {
return ""; return "";
} }
function sanitizeEmail(email) {
const trimmed = email.trim();
if (/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i.test(trimmed)) {
return trimmed;
}
return "";
}
function linkifyPlainUrls(html) {
if (!html) return "";
const parts = html.split(/(<[^>]+>)/g);
let inAnchor = false;
const isOpenAnchor = (part) => /^<a\b/i.test(part);
const isCloseAnchor = (part) => /^<\/a\b/i.test(part);
const splitTrailing = (value) => {
let url = value;
let trailing = "";
while (/[).,!?:;\]]$/.test(url)) {
trailing = url.slice(-1) + trailing;
url = url.slice(0, -1);
}
return { url, trailing };
};
const linkifyText = (text) =>
text.replace(
/\bmailto:[^\s<>"']+|\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}\b|\bhttps?:\/\/[^\s<>"']+|\b(?:www\.)?[a-z0-9.-]+\.[a-z]{2,}(?:\/[^\s<>"']*)?/gi,
(match) => {
const { url, trailing } = splitTrailing(match);
if (!url) return match;
if (/^mailto:/i.test(url)) {
const email = sanitizeEmail(url.slice(7));
if (!email) return match;
const href = escapeAttribute(`mailto:${email}`);
return `<a href="${href}" target="_blank" rel="noreferrer">mailto:${email}</a>${trailing}`;
}
if (url.includes("@") && !/^https?:\/\//i.test(url)) {
const email = sanitizeEmail(url);
if (!email) return match;
const href = escapeAttribute(`mailto:${email}`);
return `<a href="${href}" target="_blank" rel="noreferrer">${email}</a>${trailing}`;
}
if (/^https?:\/\//i.test(url)) {
const safeUrl = sanitizeUrl(url);
if (!safeUrl) return match;
const href = escapeAttribute(safeUrl);
return `<a href="${href}" target="_blank" rel="noreferrer">${url}</a>${trailing}`;
}
const withScheme = `https://${url}`;
const safeUrl = sanitizeUrl(withScheme);
if (!safeUrl) return match;
const href = escapeAttribute(safeUrl);
return `<a href="${href}" target="_blank" rel="noreferrer">${url}</a>${trailing}`;
}
);
return parts
.map((part) => {
if (!part) return part;
if (part.startsWith("<")) {
if (isOpenAnchor(part)) inAnchor = true;
if (isCloseAnchor(part)) inAnchor = false;
return part;
}
if (inAnchor) return part;
return linkifyText(part);
})
.join("");
}
function applyInline(text) { function applyInline(text) {
if (!text) return ""; if (!text) return "";
const codeSpans = []; const codeSpans = [];
@@ -421,6 +490,7 @@ function applyInline(text) {
output = output.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>"); output = output.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
output = output.replace(/\*([^*]+)\*/g, "<em>$1</em>"); output = output.replace(/\*([^*]+)\*/g, "<em>$1</em>");
output = output.replace(/_([^_]+)_/g, "<em>$1</em>"); output = output.replace(/_([^_]+)_/g, "<em>$1</em>");
output = linkifyPlainUrls(output);
output = output.replace(/@@CODESPAN(\d+)@@/g, (_match, id) => { output = output.replace(/@@CODESPAN(\d+)@@/g, (_match, id) => {
const code = codeSpans[Number(id)] || ""; const code = codeSpans[Number(id)] || "";

View File

@@ -2,6 +2,7 @@
--ink: #221b15; --ink: #221b15;
--muted: #6b5f55; --muted: #6b5f55;
--accent: #b14d2b; --accent: #b14d2b;
--danger: #b42318;
--panel: #fffaf1; --panel: #fffaf1;
--border: #eadbc8; --border: #eadbc8;
--bg: #f5ead7; --bg: #f5ead7;
@@ -16,6 +17,7 @@
--ink: #abb2bf; --ink: #abb2bf;
--muted: #8b93a5; --muted: #8b93a5;
--accent: #61afef; --accent: #61afef;
--danger: #ff6b6b;
--panel: #2f343f; --panel: #2f343f;
--border: #3e4451; --border: #3e4451;
--bg: linear-gradient(160deg, #2a2f3a, #1f232b); --bg: linear-gradient(160deg, #2a2f3a, #1f232b);
@@ -79,6 +81,16 @@ body {
color: var(--ink); color: var(--ink);
} }
.toc a.toc-active {
color: var(--accent);
font-weight: 600;
}
.toc a.toc-active::before {
content: "•";
margin-right: 6px;
}
.toc-links { .toc-links {
display: block; display: block;
overflow-y: auto; overflow-y: auto;
@@ -222,18 +234,32 @@ body.is-resizing {
cursor: pointer; cursor: pointer;
padding: 12px 16px; padding: 12px 16px;
margin: 0; margin: 0;
display: list-item; display: flex;
list-style: revert; align-items: center;
list-style-position: inside; gap: 8px;
list-style: none;
line-height: 1.2;
} }
.panel-summary::marker { .panel-summary::marker {
color: var(--muted); content: "";
} }
.panel-summary h2, .panel-summary h2,
.panel-summary h3 { .panel-summary h3 {
display: inline; display: inline;
margin-left: 0;
}
.panel-summary::before {
content: "▶";
font-size: 12px;
color: var(--muted);
line-height: 1;
}
details[open] > .panel-summary::before {
content: "▼";
} }
.panel-summary .row-title { .panel-summary .row-title {
@@ -243,6 +269,33 @@ body.is-resizing {
flex-wrap: wrap; flex-wrap: wrap;
} }
.panel-summary-row {
display: inline-flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding-left: 8px;
min-height: 32px;
width: 100%;
line-height: normal;
vertical-align: middle;
}
.panel-summary-left {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
flex: 1;
}
.panel-summary-right {
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.sub-panel .panel-summary { .sub-panel .panel-summary {
padding: 10px 12px; padding: 10px 12px;
} }
@@ -280,6 +333,11 @@ body.is-resizing {
margin-bottom: 0; margin-bottom: 0;
} }
.workspace-card .sub-panel,
.site-card .sub-panel {
margin-bottom: 8px;
}
.row { .row {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -382,6 +440,11 @@ button:active {
transform: translateY(1px); transform: translateY(1px);
} }
.enabled-toggle {
padding: 6px 10px;
font-size: 12px;
}
.accent { .accent {
background: var(--accent); background: var(--accent);
color: #fff9f3; color: #fff9f3;
@@ -398,6 +461,11 @@ button:active {
color: var(--accent); color: var(--accent);
} }
.status.is-dirty {
color: var(--danger);
font-weight: 600;
}
.tasks { .tasks {
display: grid; display: grid;
gap: 12px; gap: 12px;
@@ -411,12 +479,17 @@ button:active {
.workspace-card, .workspace-card,
.site-card { .site-card {
padding: 12px; padding: 0;
display: grid; display: grid;
gap: 12px; gap: 0;
overflow: visible; overflow: visible;
} }
.workspace-card:not([open]) > .panel-summary,
.site-card:not([open]) > .panel-summary {
border-bottom: none;
}
.workspace-header, .workspace-header,
.site-header { .site-header {
align-items: flex-end; align-items: flex-end;
@@ -428,12 +501,27 @@ button:active {
} }
.task-card { .task-card {
padding: 12px; margin-bottom: 0;
border-radius: 12px; padding: 0;
border: 1px solid var(--border); }
background: var(--card-bg);
.task-fields {
display: grid; display: grid;
gap: 8px; grid-template-columns: repeat(3, minmax(0, 1fr));
grid-template-rows: auto auto;
column-gap: 10px;
row-gap: 6px;
align-items: center;
}
.task-field-label {
margin: 0;
font-size: 11px;
letter-spacing: 0.6px;
}
.task-field-input {
width: 100%;
} }
.shortcuts { .shortcuts {
@@ -442,12 +530,27 @@ button:active {
} }
.shortcut-card { .shortcut-card {
padding: 12px; margin-bottom: 0;
border-radius: 12px; padding: 0;
border: 1px solid var(--border); }
background: var(--card-bg);
.shortcut-fields {
display: grid; display: grid;
gap: 8px; grid-template-columns: repeat(4, minmax(0, 1fr));
grid-template-rows: auto auto;
column-gap: 10px;
row-gap: 6px;
align-items: center;
}
.shortcut-field-label {
margin: 0;
font-size: 11px;
letter-spacing: 0.6px;
}
.shortcut-field-input {
width: 100%;
} }
.scope-group { .scope-group {
@@ -461,6 +564,38 @@ button:active {
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.8px; letter-spacing: 0.8px;
color: var(--muted); color: var(--muted);
display: flex;
align-items: center;
gap: 8px;
}
.scope-meta-link {
border: none;
padding: 0;
background: transparent;
font: inherit;
text-transform: none;
cursor: pointer;
}
.panel-meta-link {
border: none;
padding: 0;
background: transparent;
font: inherit;
text-transform: none;
cursor: pointer;
margin-left: 8px;
}
.panel-meta-link:focus-visible {
outline: 1px solid var(--accent);
outline-offset: 2px;
}
.scope-meta-link:focus-visible {
outline: 1px solid var(--accent);
outline-offset: 2px;
} }
.inherited-list { .inherited-list {
@@ -524,6 +659,11 @@ button:active {
min-width: 160px; min-width: 160px;
} }
.dup-select option.dup-option-cancel {
color: #c0392b;
font-weight: 600;
}
.sites-list { .sites-list {
display: grid; display: grid;
gap: 6px; gap: 6px;
@@ -545,12 +685,8 @@ button:active {
} }
.api-key-card { .api-key-card {
padding: 12px; margin-bottom: 0;
border-radius: 12px; padding: 0;
border: 1px solid var(--border);
background: var(--card-bg);
display: grid;
gap: 8px;
} }
.api-key-actions { .api-key-actions {
@@ -569,13 +705,13 @@ button:active {
color: #fff6f2; color: #fff6f2;
} }
.workspace-header .delete, .workspace-card .panel-summary-right .delete,
.site-header .delete { .site-card .panel-summary-right .delete {
background: #c0392b; background: #c0392b;
border-color: #c0392b; border-color: #c0392b;
color: #fff6f2; color: #fff6f2;
padding: 10px 12px; padding: 8px 12px;
font-size: 13px; font-size: inherit;
} }
.api-configs { .api-configs {
@@ -584,14 +720,58 @@ button:active {
} }
.api-config-card { .api-config-card {
padding: 12px; margin-bottom: 0;
border-radius: 12px; padding: 0;
border: 1px solid var(--border); }
background: var(--card-bg);
.card-summary .card-title {
font-size: 13px;
font-weight: 600;
text-transform: none;
letter-spacing: 0;
}
.card-body {
display: grid; display: grid;
gap: 8px; gap: 8px;
} }
.inline-fields {
display: grid;
gap: 10px;
}
.inline-fields.two {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.inline-fields.three {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.inline-fields .field {
margin-bottom: 0;
}
.api-config-primary {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.api-config-card.is-advanced .api-config-primary {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.api-config-card.is-advanced .api-config-model-field {
display: none;
}
.field-label-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.api-config-card.is-advanced .basic-only { .api-config-card.is-advanced .basic-only {
display: none; display: none;
} }
@@ -620,12 +800,8 @@ button:active {
} }
.env-config-card { .env-config-card {
padding: 12px; margin-bottom: 0;
border-radius: 12px; padding: 0;
border: 1px solid var(--border);
background: var(--card-bg);
display: grid;
gap: 8px;
} }
.env-config-actions { .env-config-actions {
@@ -640,12 +816,8 @@ button:active {
} }
.profile-card { .profile-card {
padding: 12px; margin-bottom: 0;
border-radius: 12px; padding: 0;
border: 1px solid var(--border);
background: var(--card-bg);
display: grid;
gap: 8px;
} }
.profile-actions { .profile-actions {

View File

@@ -25,12 +25,42 @@
<summary><a href="#global-config-panel">Global Configuration</a></summary> <summary><a href="#global-config-panel">Global Configuration</a></summary>
<ul class="toc-sub"> <ul class="toc-sub">
<li><a href="#appearance-panel">Appearance</a></li> <li><a href="#appearance-panel">Appearance</a></li>
<li><a href="#api-keys-panel">API Keys</a></li> <li>
<li><a href="#api-panel">API</a></li> <details class="toc-group toc-global-section" data-state-key="toc:global:api-keys">
<li><a href="#environment-panel">Environments</a></li> <summary><a href="#api-keys-panel">API Keys</a></summary>
<li><a href="#profiles-panel">Profiles</a></li> <ul class="toc-sub toc-cards" id="toc-global-api-keys-list"></ul>
<li><a href="#tasks-panel">Tasks</a></li> </details>
<li><a href="#shortcuts-panel">Toolbar Shortcuts</a></li> </li>
<li>
<details class="toc-group toc-global-section" data-state-key="toc:global:api-configs">
<summary><a href="#api-panel">API</a></summary>
<ul class="toc-sub toc-cards" id="toc-global-api-configs-list"></ul>
</details>
</li>
<li>
<details class="toc-group toc-global-section" data-state-key="toc:global:envs">
<summary><a href="#environment-panel">Environments</a></summary>
<ul class="toc-sub toc-cards" id="toc-global-envs-list"></ul>
</details>
</li>
<li>
<details class="toc-group toc-global-section" data-state-key="toc:global:profiles">
<summary><a href="#profiles-panel">Profiles</a></summary>
<ul class="toc-sub toc-cards" id="toc-global-profiles-list"></ul>
</details>
</li>
<li>
<details class="toc-group toc-global-section" data-state-key="toc:global:tasks">
<summary><a href="#tasks-panel">Tasks</a></summary>
<ul class="toc-sub toc-cards" id="toc-global-tasks-list"></ul>
</details>
</li>
<li>
<details class="toc-group toc-global-section" data-state-key="toc:global:shortcuts">
<summary><a href="#shortcuts-panel">Toolbar Shortcuts</a></summary>
<ul class="toc-sub toc-cards" id="toc-global-shortcuts-list"></ul>
</details>
</li>
<li><a href="#global-sites-panel">Sites</a></li> <li><a href="#global-sites-panel">Sites</a></li>
</ul> </ul>
</details> </details>
@@ -54,15 +84,26 @@
<main class="settings-main"> <main class="settings-main">
<details class="panel" id="global-config-panel" open> <details class="panel" id="global-config-panel" open>
<summary class="panel-summary"> <summary class="panel-summary">
<div class="panel-summary-row">
<div class="panel-summary-left">
<h2>Global Configuration</h2> <h2>Global Configuration</h2>
</div>
<div class="panel-summary-right"></div>
</div>
</summary> </summary>
<div class="panel-body"> <div class="panel-body">
<!-- Appearance --> <!-- Appearance -->
<details class="panel sub-panel" id="appearance-panel"> <details class="panel sub-panel" id="appearance-panel">
<summary class="panel-summary"> <summary class="panel-summary">
<div class="panel-summary-row">
<div class="panel-summary-left">
<h2>Appearance</h2> <h2>Appearance</h2>
</div>
<div class="panel-summary-right"></div>
</div>
</summary> </summary>
<div class="panel-body"> <div class="panel-body">
<div class="inline-fields two appearance-fields">
<div class="field"> <div class="field">
<label for="themeSelect">Theme</label> <label for="themeSelect">Theme</label>
<select id="themeSelect"> <select id="themeSelect">
@@ -81,6 +122,8 @@
<option value="bottom-center">Bottom Center</option> <option value="bottom-center">Bottom Center</option>
</select> </select>
</div> </div>
</div>
<div class="inline-fields two appearance-toggles">
<div class="field"> <div class="field">
<label class="toggle-label"> <label class="toggle-label">
<input id="toolbarAutoHide" type="checkbox" /> <input id="toolbarAutoHide" type="checkbox" />
@@ -94,18 +137,22 @@
</label> </label>
</div> </div>
</div> </div>
</div>
</details> </details>
<!-- API Keys --> <!-- API Keys -->
<details class="panel sub-panel" id="api-keys-panel"> <details class="panel sub-panel" id="api-keys-panel">
<summary class="panel-summary"> <summary class="panel-summary">
<div class="panel-summary-row">
<div class="panel-summary-left">
<h2>API KEYS</h2> <h2>API KEYS</h2>
</div>
<div class="panel-summary-right">
<button id="addApiKeyBtn" class="accent" type="button">Add</button>
</div>
</div>
</summary> </summary>
<div class="panel-body"> <div class="panel-body">
<div class="row">
<div></div>
<button id="addApiKeyBtn" class="ghost" type="button">Add Key</button>
</div>
<div id="apiKeys" class="api-keys"></div> <div id="apiKeys" class="api-keys"></div>
</div> </div>
</details> </details>
@@ -113,15 +160,16 @@
<!-- API --> <!-- API -->
<details class="panel sub-panel" id="api-panel"> <details class="panel sub-panel" id="api-panel">
<summary class="panel-summary"> <summary class="panel-summary">
<div class="panel-summary-row">
<div class="panel-summary-left">
<h2>API</h2> <h2>API</h2>
</div>
<div class="panel-summary-right">
<button id="addApiConfigBtn" class="accent" type="button">Add</button>
</div>
</div>
</summary> </summary>
<div class="panel-body"> <div class="panel-body">
<div class="row">
<div></div>
<div class="row-actions">
<button id="addApiConfigBtn" class="ghost" type="button">Add Config</button>
</div>
</div>
<div id="apiConfigs" class="api-configs"></div> <div id="apiConfigs" class="api-configs"></div>
</div> </div>
</details> </details>
@@ -129,16 +177,19 @@
<!-- Envs --> <!-- Envs -->
<details class="panel sub-panel" id="environment-panel"> <details class="panel sub-panel" id="environment-panel">
<summary class="panel-summary"> <summary class="panel-summary">
<div class="panel-summary-row">
<div class="panel-summary-left">
<div class="row-title"> <div class="row-title">
<h2>ENVIRONMENTS</h2> <h2>ENVIRONMENTS</h2>
<span class="hint hint-accent">Baseline environments</span> <span class="hint hint-accent">Baseline environments</span>
</div> </div>
</div>
<div class="panel-summary-right">
<button id="addEnvConfigBtn" class="accent" type="button">Add</button>
</div>
</div>
</summary> </summary>
<div class="panel-body"> <div class="panel-body">
<div class="row">
<div></div>
<button id="addEnvConfigBtn" class="ghost" type="button">Add Env</button>
</div>
<div id="envConfigs" class="env-configs"></div> <div id="envConfigs" class="env-configs"></div>
</div> </div>
</details> </details>
@@ -146,16 +197,19 @@
<!-- Profiles --> <!-- Profiles -->
<details class="panel sub-panel" id="profiles-panel"> <details class="panel sub-panel" id="profiles-panel">
<summary class="panel-summary"> <summary class="panel-summary">
<div class="panel-summary-row">
<div class="panel-summary-left">
<div class="row-title"> <div class="row-title">
<h2>PROFILES</h2> <h2>PROFILES</h2>
<span class="hint hint-accent">Baseline user contexts</span> <span class="hint hint-accent">Baseline user contexts</span>
</div> </div>
</div>
<div class="panel-summary-right">
<button id="addProfileBtn" class="accent" type="button">Add</button>
</div>
</div>
</summary> </summary>
<div class="panel-body"> <div class="panel-body">
<div class="row">
<div></div>
<button id="addProfileBtn" class="ghost" type="button">Add Profile</button>
</div>
<div id="profiles" class="profiles"></div> <div id="profiles" class="profiles"></div>
</div> </div>
</details> </details>
@@ -163,16 +217,19 @@
<!-- Tasks --> <!-- Tasks -->
<details class="panel sub-panel" id="tasks-panel"> <details class="panel sub-panel" id="tasks-panel">
<summary class="panel-summary"> <summary class="panel-summary">
<div class="panel-summary-row">
<div class="panel-summary-left">
<div class="row-title"> <div class="row-title">
<h2>TASKS</h2> <h2>TASKS</h2>
<span class="hint hint-accent">Baseline execution units</span> <span class="hint hint-accent">Baseline execution units</span>
</div> </div>
</div>
<div class="panel-summary-right">
<button id="addTaskBtn" class="accent" type="button">Add</button>
</div>
</div>
</summary> </summary>
<div class="panel-body"> <div class="panel-body">
<div class="row">
<div></div>
<button id="addTaskBtn" class="ghost" type="button">Add Task</button>
</div>
<div id="tasks" class="tasks"></div> <div id="tasks" class="tasks"></div>
</div> </div>
</details> </details>
@@ -180,16 +237,19 @@
<!-- Toolbar Shortcuts --> <!-- Toolbar Shortcuts -->
<details class="panel sub-panel" id="shortcuts-panel"> <details class="panel sub-panel" id="shortcuts-panel">
<summary class="panel-summary"> <summary class="panel-summary">
<div class="panel-summary-row">
<div class="panel-summary-left">
<div class="row-title"> <div class="row-title">
<h2>TOOLBAR SHORTCUTS</h2> <h2>TOOLBAR SHORTCUTS</h2>
<span class="hint hint-accent">One-click toolbar runs</span> <span class="hint hint-accent">One-click toolbar runs</span>
</div> </div>
</div>
<div class="panel-summary-right">
<button id="addShortcutBtn" class="accent" type="button">Add</button>
</div>
</div>
</summary> </summary>
<div class="panel-body"> <div class="panel-body">
<div class="row">
<div></div>
<button id="addShortcutBtn" class="ghost" type="button">Add Shortcut</button>
</div>
<div id="shortcuts" class="shortcuts"></div> <div id="shortcuts" class="shortcuts"></div>
</div> </div>
</details> </details>
@@ -197,10 +257,15 @@
<!-- Sites --> <!-- Sites -->
<details class="panel sub-panel" id="global-sites-panel"> <details class="panel sub-panel" id="global-sites-panel">
<summary class="panel-summary"> <summary class="panel-summary">
<div class="panel-summary-row">
<div class="panel-summary-left">
<div class="row-title"> <div class="row-title">
<h2>SITES</h2> <h2>SITES</h2>
<span class="hint hint-accent">Inherit directly from global</span> <span class="hint hint-accent">Inherit directly from global</span>
</div> </div>
</div>
<div class="panel-summary-right"></div>
</div>
</summary> </summary>
<div class="panel-body"> <div class="panel-body">
<div id="globalSites" class="sites-list"></div> <div id="globalSites" class="sites-list"></div>
@@ -211,32 +276,38 @@
<details class="panel" id="workspaces-panel"> <details class="panel" id="workspaces-panel">
<summary class="panel-summary"> <summary class="panel-summary">
<div class="panel-summary-row">
<div class="panel-summary-left">
<div class="row-title"> <div class="row-title">
<h2>Workspaces</h2> <h2>Workspaces</h2>
<span class="hint hint-accent">Namespace for sites and resources</span> <span class="hint hint-accent">Namespace for sites and resources</span>
</div> </div>
</div>
<div class="panel-summary-right">
<button id="addWorkspaceBtn" class="accent" type="button">Add</button>
</div>
</div>
</summary> </summary>
<div class="panel-body"> <div class="panel-body">
<div class="row">
<div></div>
<button id="addWorkspaceBtn" class="ghost" type="button">Add Workspace</button>
</div>
<div id="workspaces" class="workspaces"></div> <div id="workspaces" class="workspaces"></div>
</div> </div>
</details> </details>
<details class="panel" id="sites-panel"> <details class="panel" id="sites-panel">
<summary class="panel-summary"> <summary class="panel-summary">
<div class="panel-summary-row">
<div class="panel-summary-left">
<div class="row-title"> <div class="row-title">
<h2>Sites</h2> <h2>Sites</h2>
<span class="hint hint-accent">Configure known sites</span> <span class="hint hint-accent">Configure known sites</span>
</div> </div>
</div>
<div class="panel-summary-right">
<button id="addSiteBtn" class="accent" type="button">Add</button>
</div>
</div>
</summary> </summary>
<div class="panel-body"> <div class="panel-body">
<div class="row">
<div></div>
<button id="addSiteBtn" class="ghost" type="button">Add Site</button>
</div>
<div id="sites" class="sites"></div> <div id="sites" class="sites"></div>
</div> </div>
</details> </details>

File diff suppressed because it is too large Load Diff