NobGit
public anord read

Ledger

Why work hard when you can work easier?

Languages

Repository composition by tracked source files.

TypeScript
TypeScript 86% CSS 10% SQL 3% Shell 1% HTML 0%
Create file Wiki Documentation
Clone
https://nobgit.com/orgs/anord/ledger.git
ssh://[email protected]:2222/orgs/anord/ledger.git

Commit

Continues UI Fixes

7b9fd81
Alex Nord <[email protected]> 3 months ago
apps/api/src/http/routes/settings.ts      |   3 -
 apps/api/src/http/routes/setup.ts         |   1 -
 apps/api/src/services/settings.ts         |   9 +-
 apps/api/src/services/setup.ts            |   5 +-
 apps/web/src/AppShell.tsx                 |  34 ++-----
 apps/web/src/components/AdminConsole.tsx  |  11 +-
 apps/web/src/components/DashboardView.tsx |  11 +-
 apps/web/src/docs-theme.css               | 163 +++++++++++++++++-------------
 packages/shared/src/contracts.ts          |   1 -
 9 files changed, 114 insertions(+), 124 deletions(-)

Diff

diff --git a/apps/api/src/http/routes/settings.ts b/apps/api/src/http/routes/settings.ts
index 9437748..d00f30f 100644
--- a/apps/api/src/http/routes/settings.ts
+++ b/apps/api/src/http/routes/settings.ts
@@ -8,7 +8,6 @@ const brandingSchema = z.object({
   siteName: z.string().min(2),
   logoUrl: z.string().url().nullable(),
   brandColor: z.string().regex(/^#[0-9a-fA-F]{6}$/),
-  footerText: z.string().max(200).nullable(),
   publicKnowledgeBaseEnabled: z.boolean()
 });
 
@@ -21,7 +20,6 @@ settingsRouter.get("/public", async (_req, res) => {
       siteName: branding.site_name,
       logoUrl: branding.logo_url,
       brandColor: branding.brand_color,
-      footerText: branding.footer_text,
       publicKnowledgeBaseEnabled: branding.public_knowledge_base_enabled
     }
   });
@@ -38,4 +36,3 @@ settingsRouter.put("/branding", requireAdmin, async (req, res) => {
   await logAudit(req.user!.id, "settings.branding.update", "branding_settings", updated.id);
   return res.json(updated);
 });
-
diff --git a/apps/api/src/http/routes/setup.ts b/apps/api/src/http/routes/setup.ts
index bbac773..21aca46 100644
--- a/apps/api/src/http/routes/setup.ts
+++ b/apps/api/src/http/routes/setup.ts
@@ -6,7 +6,6 @@ import { initializeLedger, getSetupStatus } from "../../services/setup.js";
 const setupSchema = z.object({
   siteName: z.string().min(2),
   brandColor: z.string().regex(/^#[0-9a-fA-F]{6}$/),
-  footerText: z.string().max(200).nullable(),
   publicKnowledgeBaseEnabled: z.boolean(),
   ownerEmail: z.string().email(),
   ownerDisplayName: z.string().min(2),
diff --git a/apps/api/src/services/settings.ts b/apps/api/src/services/settings.ts
index 20a8a5b..9cd25fa 100644
--- a/apps/api/src/services/settings.ts
+++ b/apps/api/src/services/settings.ts
@@ -1,6 +1,8 @@
 import { env } from "../config/env.js";
 import { pool } from "../db/pool.js";
 
+const FIXED_FOOTER = "Powered by Ledger made by ANord.cc";
+
 export async function getBrandingSettings() {
   const result = await pool.query(`SELECT * FROM branding_settings ORDER BY created_at ASC LIMIT 1`);
   return (
@@ -9,7 +11,7 @@ export async function getBrandingSettings() {
       site_name: "Ledger",
       logo_url: null,
       brand_color: "#245cff",
-      footer_text: "Built for fast, trusted answers.",
+      footer_text: FIXED_FOOTER,
       public_knowledge_base_enabled: true
     }
   );
@@ -19,7 +21,6 @@ export async function upsertBrandingSettings(input: {
   siteName: string;
   logoUrl: string | null;
   brandColor: string;
-  footerText: string | null;
   publicKnowledgeBaseEnabled: boolean;
 }) {
   const existing = await getBrandingSettings();
@@ -37,7 +38,7 @@ export async function upsertBrandingSettings(input: {
         input.siteName,
         input.logoUrl,
         input.brandColor,
-        input.footerText,
+        FIXED_FOOTER,
         input.publicKnowledgeBaseEnabled
       ]
     );
@@ -54,7 +55,7 @@ export async function upsertBrandingSettings(input: {
       input.siteName,
       input.logoUrl,
       input.brandColor,
-      input.footerText,
+      FIXED_FOOTER,
       input.publicKnowledgeBaseEnabled
     ]
   );
diff --git a/apps/api/src/services/setup.ts b/apps/api/src/services/setup.ts
index 70c9604..39bbacd 100644
--- a/apps/api/src/services/setup.ts
+++ b/apps/api/src/services/setup.ts
@@ -2,10 +2,11 @@ import { hashPassword, createSessionToken, getUserForSession } from "./auth.js";
 import { logAudit } from "./audit.js";
 import { pool } from "../db/pool.js";
 
+const FIXED_FOOTER = "Powered by Ledger made by ANord.cc";
+
 interface SetupInput {
   siteName: string;
   brandColor: string;
-  footerText: string | null;
   publicKnowledgeBaseEnabled: boolean;
   ownerEmail: string;
   ownerDisplayName: string;
@@ -51,7 +52,7 @@ export async function initializeLedger(input: SetupInput) {
         WHERE id = (SELECT id FROM branding_settings ORDER BY created_at ASC LIMIT 1)
         RETURNING id
       `,
-      [input.siteName, input.brandColor, input.footerText, input.publicKnowledgeBaseEnabled]
+      [input.siteName, input.brandColor, FIXED_FOOTER, input.publicKnowledgeBaseEnabled]
     );
 
     await pool.query(
diff --git a/apps/web/src/AppShell.tsx b/apps/web/src/AppShell.tsx
index b3da8d1..49a8e9f 100644
--- a/apps/web/src/AppShell.tsx
+++ b/apps/web/src/AppShell.tsx
@@ -31,11 +31,12 @@ type BrandingResponse = {
     siteName: string;
     logoUrl?: string | null;
     brandColor: string;
-    footerText: string | null;
     publicKnowledgeBaseEnabled: boolean;
   };
 };
 
+const LEDGER_FOOTER = "Powered by Ledger made by ANord.cc";
+
 type SetupStatus = {
   isInitialized: boolean;
   branding: {
@@ -315,7 +316,7 @@ function DocsShell({
         </header>
 
         <main className="app-content">{children}</main>
-        <footer className="app-footer">{branding?.footerText ?? "Built for fast, trusted answers."}</footer>
+        <footer className="app-footer">{LEDGER_FOOTER}</footer>
       </div>
     </div>
   );
@@ -796,7 +797,6 @@ function SetupPage({
   const [form, setForm] = useState({
     siteName: initialBranding?.site_name ?? "Ledger",
     brandColor: initialBranding?.brand_color ?? "#245cff",
-    footerText: "Built for fast, trusted answers.",
     publicKnowledgeBaseEnabled: true,
     ownerEmail: "",
     ownerDisplayName: "",
@@ -807,16 +807,12 @@ function SetupPage({
   async function submit(event: React.FormEvent) {
     event.preventDefault();
     try {
-      const response = await api.post<{ user: SessionUser }>("/api/setup/initialize", {
-        ...form,
-        footerText: form.footerText || null
-      });
+      const response = await api.post<{ user: SessionUser }>("/api/setup/initialize", form);
 
       onInitialized(response.user, {
         siteName: form.siteName,
         logoUrl: null,
         brandColor: form.brandColor,
-        footerText: form.footerText || null,
         publicKnowledgeBaseEnabled: form.publicKnowledgeBaseEnabled
       });
 
@@ -867,14 +863,6 @@ function SetupPage({
           </label>
         </div>
 
-        <label className="field">
-          Footer text
-          <input
-            value={form.footerText}
-            onChange={(event) => setForm((current) => ({ ...current, footerText: event.target.value }))}
-          />
-        </label>
-
         <label className="checkbox-row checkbox-card">
           <input
             type="checkbox"
@@ -947,7 +935,6 @@ function Dashboard({ user, spaces }: { user: SessionUser; spaces: Space[] }) {
     siteName: "Ledger",
     logoUrl: "",
     brandColor: "#245cff",
-    footerText: "",
     publicKnowledgeBaseEnabled: true
   });
   const [settingsStatus, setSettingsStatus] = useState<string | null>(null);
@@ -971,7 +958,6 @@ function Dashboard({ user, spaces }: { user: SessionUser; spaces: Space[] }) {
             siteName: branding.site_name,
             logoUrl: branding.logo_url ?? "",
             brandColor: branding.brand_color,
-            footerText: branding.footer_text ?? "",
             publicKnowledgeBaseEnabled: branding.public_knowledge_base_enabled
           });
         });
@@ -984,7 +970,6 @@ function Dashboard({ user, spaces }: { user: SessionUser; spaces: Space[] }) {
         siteName: brandingForm.siteName,
         logoUrl: brandingForm.logoUrl || null,
         brandColor: brandingForm.brandColor,
-        footerText: brandingForm.footerText || null,
         publicKnowledgeBaseEnabled: brandingForm.publicKnowledgeBaseEnabled
       });
       setSettingsStatus("Brand settings saved.");
@@ -1044,13 +1029,10 @@ function Dashboard({ user, spaces }: { user: SessionUser; spaces: Space[] }) {
                 />
               </label>
             </div>
-            <label className="field">
-              Footer text
-              <input
-                value={brandingForm.footerText}
-                onChange={(event) => setBrandingForm((current) => ({ ...current, footerText: event.target.value }))}
-              />
-            </label>
+            <div className="list-item">
+              <strong>Footer</strong>
+              <span>Powered by Ledger made by ANord.cc</span>
+            </div>
             <label className="checkbox-row checkbox-card">
               <input
                 type="checkbox"
diff --git a/apps/web/src/components/AdminConsole.tsx b/apps/web/src/components/AdminConsole.tsx
index 24918da..abd545c 100644
--- a/apps/web/src/components/AdminConsole.tsx
+++ b/apps/web/src/components/AdminConsole.tsx
@@ -59,7 +59,6 @@ export function AdminConsole({ user, spaces }: { user: SessionUser; spaces: Spac
     siteName: "Ledger",
     logoUrl: "",
     brandColor: "#245cff",
-    footerText: "",
     publicKnowledgeBaseEnabled: true
   });
   const [users, setUsers] = useState<AdminUser[]>([]);
@@ -122,7 +121,6 @@ export function AdminConsole({ user, spaces }: { user: SessionUser; spaces: Spac
         siteName: settingsResponse.branding.site_name,
         logoUrl: settingsResponse.branding.logo_url ?? "",
         brandColor: settingsResponse.branding.brand_color,
-        footerText: settingsResponse.branding.footer_text ?? "",
         publicKnowledgeBaseEnabled: settingsResponse.branding.public_knowledge_base_enabled
       });
       setIntegrations(integrationsResponse.integrations);
@@ -188,7 +186,6 @@ export function AdminConsole({ user, spaces }: { user: SessionUser; spaces: Spac
         siteName: brandingForm.siteName,
         logoUrl: brandingForm.logoUrl || null,
         brandColor: brandingForm.brandColor,
-        footerText: brandingForm.footerText || null,
         publicKnowledgeBaseEnabled: brandingForm.publicKnowledgeBaseEnabled
       });
       setStatus("General settings saved.");
@@ -356,10 +353,10 @@ export function AdminConsole({ user, spaces }: { user: SessionUser; spaces: Spac
                   <input value={brandingForm.logoUrl} onChange={(event) => setBrandingForm((current) => ({ ...current, logoUrl: event.target.value }))} />
                 </label>
               </div>
-              <label className="field">
-                Footer text
-                <input value={brandingForm.footerText} onChange={(event) => setBrandingForm((current) => ({ ...current, footerText: event.target.value }))} />
-              </label>
+              <div className="list-item">
+                <strong>Footer</strong>
+                <span>Powered by Ledger made by ANord.cc</span>
+              </div>
               <label className="checkbox-row checkbox-card">
                 <input type="checkbox" checked={brandingForm.publicKnowledgeBaseEnabled} onChange={(event) => setBrandingForm((current) => ({ ...current, publicKnowledgeBaseEnabled: event.target.checked }))} />
                 <span>Public knowledge base enabled</span>
diff --git a/apps/web/src/components/DashboardView.tsx b/apps/web/src/components/DashboardView.tsx
index 7243869..fa470d9 100644
--- a/apps/web/src/components/DashboardView.tsx
+++ b/apps/web/src/components/DashboardView.tsx
@@ -41,7 +41,6 @@ export function DashboardView({ user, spaces }: { user: SessionUser; spaces: Spa
     siteName: "Ledger",
     logoUrl: "",
     brandColor: "#245cff",
-    footerText: "",
     publicKnowledgeBaseEnabled: true
   });
   const [status, setStatus] = useState<string | null>(null);
@@ -95,7 +94,6 @@ export function DashboardView({ user, spaces }: { user: SessionUser; spaces: Spa
       siteName: settingsResponse.branding.site_name,
       logoUrl: settingsResponse.branding.logo_url ?? "",
       brandColor: settingsResponse.branding.brand_color,
-      footerText: settingsResponse.branding.footer_text ?? "",
       publicKnowledgeBaseEnabled: settingsResponse.branding.public_knowledge_base_enabled
     });
   }
@@ -109,7 +107,6 @@ export function DashboardView({ user, spaces }: { user: SessionUser; spaces: Spa
       siteName: brandingForm.siteName,
       logoUrl: brandingForm.logoUrl || null,
       brandColor: brandingForm.brandColor,
-      footerText: brandingForm.footerText || null,
       publicKnowledgeBaseEnabled: brandingForm.publicKnowledgeBaseEnabled
     });
     setStatus("Workspace settings saved.");
@@ -362,10 +359,10 @@ export function DashboardView({ user, spaces }: { user: SessionUser; spaces: Spa
                   <input value={brandingForm.logoUrl} onChange={(event) => setBrandingForm((current) => ({ ...current, logoUrl: event.target.value }))} />
                 </label>
               </div>
-              <label className="field">
-                Footer text
-                <input value={brandingForm.footerText} onChange={(event) => setBrandingForm((current) => ({ ...current, footerText: event.target.value }))} />
-              </label>
+              <div className="list-item">
+                <strong>Footer</strong>
+                <span>Powered by Ledger made by ANord.cc</span>
+              </div>
               <label className="checkbox-row checkbox-card">
                 <input type="checkbox" checked={brandingForm.publicKnowledgeBaseEnabled} onChange={(event) => setBrandingForm((current) => ({ ...current, publicKnowledgeBaseEnabled: event.target.checked }))} />
                 <span>Public knowledge base enabled</span>
diff --git a/apps/web/src/docs-theme.css b/apps/web/src/docs-theme.css
index bee25c0..26c6180 100644
--- a/apps/web/src/docs-theme.css
+++ b/apps/web/src/docs-theme.css
@@ -1,25 +1,25 @@
 :root {
-  --bg: #111318;
-  --bg-elevated: #15181f;
-  --bg-sidebar: #0d1015;
-  --bg-panel: #15181f;
-  --bg-soft: #0f1319;
-  --bg-soft-2: #171c24;
-  --text: #edf1f7;
+  --bg: #0f1115;
+  --bg-elevated: #12151b;
+  --bg-sidebar: #0a0c10;
+  --bg-panel: #12151b;
+  --bg-soft: #10141a;
+  --bg-soft-2: #171b22;
+  --text: #eef2f7;
   --text-muted: #9aa4b2;
-  --text-soft: #6f7b8d;
-  --line: #252c37;
-  --line-strong: #343d4b;
-  --brand: #f59e0b;
-  --brand-soft: rgba(245, 158, 11, 0.12);
+  --text-soft: #697586;
+  --line: #1b2028;
+  --line-strong: #2a313d;
+  --brand: #f2a43a;
+  --brand-soft: rgba(242, 164, 58, 0.12);
   --shadow: none;
-  --radius-lg: 4px;
-  --radius-md: 4px;
-  --radius-sm: 3px;
-  --sidebar-width: 260px;
+  --radius-lg: 2px;
+  --radius-md: 2px;
+  --radius-sm: 2px;
+  --sidebar-width: 272px;
   color: var(--text);
   background: var(--bg);
-  font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
+  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
 }
 
 * {
@@ -76,7 +76,7 @@ select:focus,
 textarea:focus,
 button:focus,
 a:focus {
-  outline: 2px solid rgba(45, 106, 79, 0.22);
+  outline: 2px solid rgba(242, 164, 58, 0.22);
   outline-offset: 2px;
 }
 
@@ -93,9 +93,9 @@ a:focus {
 
 .eyebrow {
   margin: 0 0 0.55rem;
-  font-size: 0.72rem;
+  font-size: 0.7rem;
   font-weight: 700;
-  letter-spacing: 0.14em;
+  letter-spacing: 0.12em;
   text-transform: uppercase;
   color: var(--text-soft);
 }
@@ -124,7 +124,7 @@ a:focus {
 
 .button-secondary {
   border: 1px solid var(--line);
-  background: var(--bg-soft);
+  background: transparent;
 }
 
 button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-link):not(.collection-card):not(.search-launcher) {
@@ -151,7 +151,7 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
   position: sticky;
   top: 0;
   height: 100vh;
-  padding: 0.9rem 0.75rem 1rem;
+  padding: 0.75rem 0.65rem 1rem;
   background: var(--bg-sidebar);
   border-right: 1px solid var(--line);
   overflow-y: auto;
@@ -183,7 +183,8 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 
 .sidebar__workspace {
   margin: 0;
-  font-size: 1.25rem;
+  font-size: 0.95rem;
+  font-weight: 600;
 }
 
 .sidebar-nav,
@@ -200,7 +201,7 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 }
 
 .sidebar-nav {
-  margin: 1rem 0 1.25rem;
+  margin: 0.8rem 0 1.25rem;
 }
 
 .sidebar-nav__item,
@@ -209,15 +210,16 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
   display: flex;
   align-items: center;
   gap: 0.7rem;
-  padding: 0.55rem 0.65rem;
+  padding: 0.5rem 0.6rem;
   border-radius: var(--radius-sm);
   color: var(--text-muted);
+  font-size: 0.92rem;
 }
 
 .sidebar-nav__item.is-current,
 .sidebar-doc.is-current,
 .collection-link.is-current {
-  background: var(--bg-soft-2);
+  background: #171b22;
   color: var(--text);
 }
 
@@ -238,9 +240,8 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 }
 
 .collection-group {
-  border: 1px solid var(--line);
-  border-radius: var(--radius-md);
   background: transparent;
+  border: 0;
 }
 
 .collection-group__header,
@@ -257,8 +258,9 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .collection-group__header {
   width: 100%;
   justify-content: space-between;
-  padding: 0.8rem 0.9rem;
+  padding: 0.55rem 0.6rem;
   background: transparent;
+  border-top: 1px solid var(--line);
 }
 
 .collection-group__title {
@@ -272,7 +274,7 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 }
 
 .collection-group__body {
-  padding: 0 0.55rem 0.65rem;
+  padding: 0.1rem 0 0.45rem;
 }
 
 .tree-item {
@@ -286,15 +288,15 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
   align-items: center;
   justify-content: space-between;
   gap: 0.7rem;
-  padding: 0.38rem 0.55rem;
-  border-radius: 10px;
+  padding: 0.34rem 0.55rem;
+  border-radius: var(--radius-sm);
   color: var(--text-muted);
 }
 
 .tree-item.is-active .tree-link {
-  background: #fff;
+  background: #171b22;
   color: var(--text);
-  box-shadow: inset 0 0 0 1px rgba(202, 215, 203, 0.8);
+  box-shadow: inset 2px 0 0 0 var(--brand);
 }
 
 .tree-link__title {
@@ -324,8 +326,8 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
   align-items: center;
   gap: 0.35rem;
   border-radius: var(--radius-sm);
-  padding: 0.22rem 0.42rem;
-  font-size: 0.78rem;
+  padding: 0.18rem 0.38rem;
+  font-size: 0.72rem;
   font-weight: 600;
 }
 
@@ -349,12 +351,12 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .app-header,
 .app-content,
 .app-footer {
-  width: min(1240px, calc(100% - 2.5rem));
+  width: min(1220px, calc(100% - 2rem));
   margin: 0 auto;
 }
 
 .app-header {
-  padding: 0.8rem 0;
+  padding: 0.72rem 0;
   border-bottom: 1px solid var(--line);
 }
 
@@ -367,6 +369,7 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .brand small {
   display: block;
   color: var(--text-muted);
+  font-size: 0.74rem;
 }
 
 .brand-mark {
@@ -376,12 +379,12 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 }
 
 .search-launcher {
-  min-width: min(560px, 100%);
+  min-width: min(520px, 100%);
   justify-content: space-between;
-  padding: 0.7rem 0.85rem;
+  padding: 0.62rem 0.78rem;
   border-radius: var(--radius-sm);
   border: 1px solid var(--line);
-  background: var(--bg-soft);
+  background: #0f1318;
   color: var(--text-muted);
 }
 
@@ -394,12 +397,15 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 }
 
 .app-content {
-  padding: 1.5rem 0 2.5rem;
+  padding: 1.1rem 0 2.2rem;
 }
 
 .app-footer {
-  padding: 1rem 0 2rem;
-  color: var(--text-muted);
+  padding: 0.95rem 0 1.4rem;
+  color: var(--text-soft);
+  font-size: 0.8rem;
+  border-top: 1px solid var(--line);
+  letter-spacing: 0.02em;
 }
 
 .overview-layout,
@@ -417,7 +423,7 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .setup-form {
   border: 1px solid var(--line);
   border-radius: var(--radius-lg);
-  background: var(--bg-panel);
+  background: transparent;
 }
 
 .overview-hero,
@@ -426,7 +432,7 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .panel,
 .auth-form,
 .setup-form {
-  padding: 1.1rem 1.2rem;
+  padding: 1.05rem 1.1rem;
 }
 
 .overview-hero {
@@ -434,6 +440,7 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
   grid-template-columns: 1.2fr 0.9fr;
   gap: 1rem;
   align-items: end;
+  background: var(--bg-elevated);
 }
 
 .overview-hero h1,
@@ -441,8 +448,8 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .auth-panel h1,
 .manage-hero h1 {
   margin: 0;
-  font-size: clamp(2rem, 2.6vw, 3.2rem);
-  line-height: 1.05;
+  font-size: clamp(1.85rem, 2.4vw, 3rem);
+  line-height: 1.08;
   letter-spacing: -0.03em;
 }
 
@@ -465,9 +472,9 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .article-list__item {
   width: 100%;
   justify-content: space-between;
-  padding: 0.85rem 0.95rem;
+  padding: 0.8rem 0.9rem;
   border-radius: var(--radius-md);
-  background: transparent;
+  background: #11151b;
   border: 1px solid var(--line);
   color: inherit;
 }
@@ -503,8 +510,8 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 
 .document-layout {
   display: grid;
-  grid-template-columns: minmax(0, 1fr) 260px;
-  gap: 1.2rem;
+  grid-template-columns: minmax(0, 1fr) 240px;
+  gap: 2rem;
   align-items: start;
 }
 
@@ -521,9 +528,9 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 }
 
 .breadcrumbs {
-  margin-bottom: 1rem;
+  margin-bottom: 0.85rem;
   color: var(--text-soft);
-  font-size: 0.92rem;
+  font-size: 0.86rem;
 }
 
 .doc-meta,
@@ -546,11 +553,13 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
   position: sticky;
   top: 1rem;
   display: grid;
-  gap: 1rem;
+  gap: 0.75rem;
 }
 
 .rail-card {
-  padding: 1rem;
+  padding: 0.9rem 0 0.9rem 1rem;
+  border: 0;
+  border-left: 1px solid var(--line);
 }
 
 .toc-rail a {
@@ -570,18 +579,19 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 }
 
 .markdown-prose {
-  max-width: 76ch;
-  font-family: ui-serif, Georgia, "Times New Roman", serif;
-  font-size: 1rem;
-  line-height: 1.8;
+  max-width: 74ch;
+  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
+  font-size: 1.02rem;
+  line-height: 1.75;
+  color: #d7dde7;
 }
 
 .markdown-prose :is(h1, h2, h3, h4) {
-  margin-top: 2.4rem;
-  margin-bottom: 1rem;
+  margin-top: 2.1rem;
+  margin-bottom: 0.8rem;
   line-height: 1.18;
   letter-spacing: -0.02em;
-  font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
+  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
 }
 
 .markdown-prose p,
@@ -629,8 +639,9 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
   padding: 1rem;
   border-radius: var(--radius-md);
   overflow: auto;
-  background: #18201a;
-  color: #e9f1ea;
+  background: #10141a;
+  color: #dfe7f2;
+  border: 1px solid var(--line);
 }
 
 .markdown-prose code {
@@ -664,7 +675,7 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .auth-layout,
 .setup-screen {
   min-height: 100vh;
-  width: min(1200px, calc(100% - 2rem));
+  width: min(1180px, calc(100% - 2rem));
   margin: 0 auto;
   display: grid;
   grid-template-columns: 1fr 1fr;
@@ -730,7 +741,7 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .sidebar-overlay {
   position: fixed;
   inset: 0;
-  background: rgba(20, 29, 21, 0.35);
+  background: rgba(6, 8, 12, 0.55);
   opacity: 0;
   pointer-events: none;
   transition: opacity 160ms ease;
@@ -803,10 +814,12 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .search-result {
   padding: 0.85rem;
   border-radius: var(--radius-md);
+  border: 1px solid transparent;
 }
 
 .search-result:hover {
   background: var(--bg-soft);
+  border-color: var(--line);
 }
 
 .search-result__icon {
@@ -937,7 +950,8 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
   justify-content: space-between;
   align-items: flex-start;
   gap: 1rem;
-  padding: 0.4rem 0 0.8rem;
+  padding: 0.35rem 0 0.5rem;
+  border-bottom: 1px solid var(--line);
 }
 
 .page-header__actions {
@@ -957,6 +971,7 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
   top: 1rem;
   align-self: start;
   background: var(--bg-sidebar);
+  padding: 0.9rem 0.75rem;
 }
 
 .admin-backlink {
@@ -975,15 +990,17 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .admin-nav__item {
   display: flex;
   align-items: center;
-  min-height: 2.8rem;
-  padding: 0.65rem 0.8rem;
+  min-height: 2.45rem;
+  padding: 0.48rem 0.65rem;
   border-radius: var(--radius-sm);
   color: var(--text-soft);
+  font-size: 0.92rem;
 }
 
 .admin-nav__item.is-current {
-  background: var(--bg-soft-2);
+  background: #171b22;
   color: var(--text);
+  box-shadow: inset 2px 0 0 0 var(--brand);
 }
 
 .admin-content,
@@ -1000,10 +1017,10 @@ button:not(.button-ghost):not(.button-secondary):not(.tree-toggle):not(.space-li
 .list-item {
   display: grid;
   gap: 0.25rem;
-  padding: 0.95rem 1rem;
+  padding: 0.8rem 0.9rem;
   border: 1px solid var(--line);
   border-radius: var(--radius-md);
-  background: transparent;
+  background: #11151b;
 }
 
 .integration-card--selectable {
diff --git a/packages/shared/src/contracts.ts b/packages/shared/src/contracts.ts
index f39b253..f47c04e 100644
--- a/packages/shared/src/contracts.ts
+++ b/packages/shared/src/contracts.ts
@@ -69,7 +69,6 @@ export interface BrandingSettings {
   siteName: string;
   logoUrl: string | null;
   brandColor: string;
-  footerText: string | null;
   publicKnowledgeBaseEnabled: boolean;
 }