Theming

The package's colours, fonts, radii and shadows are CSS custom properties named --nbp-*, declared on :root in styles/globals.css. Override any of them and the blog and admin panel follow — there is nothing to fork and no component to wrap.

Class names are prefixed nbp-, so nothing collides with Tailwind, your own styles, or another design system.

One exception, so it doesn't surprise you: styles/prose.css — the post body typography — hardcodes a handful of values rather than reading variables. Inline code, code block backgrounds, table stripes, highlight marks and the four callout colours are literals. Override them by class (.nbp-post-content code, .nbp-callout-info, and so on) rather than by variable.

Variables

Variable Default Used for
--nbp-primary #2563eb Links, buttons, active states
--nbp-primary-hover #1d4ed8 Primary hover
--nbp-primary-light #dbeafe Tag backgrounds, highlights
--nbp-text #1f2937 Body text
--nbp-text-muted #6b7280 Secondary text
--nbp-bg #ffffff Page background
--nbp-bg-secondary #f9fafb Cards, sidebar, hover rows
--nbp-card-bg #ffffff Card background
--nbp-border #e5e7eb Borders
--nbp-border-focus #2563eb Input focus border
--nbp-radius 0.5rem Border radius
--nbp-shadow 0 1px 3px … Default shadow
--nbp-shadow-sm 0 1px 2px … Small shadow
--nbp-shadow-lg 0 10px 15px … Large shadow
--nbp-shadow-xl 0 20px 25px … Extra large shadow
--nbp-font-heading "Inter", system-ui, -apple-system, sans-serif Headings
--nbp-font-body "Inter", system-ui, -apple-system, sans-serif Body
--nbp-font-code "JetBrains Mono", "Fira Code", "Cascadia Code", monospace Code
--nbp-success #10b981 Success states
--nbp-warning #f59e0b Warnings
--nbp-danger #ef4444 Errors, destructive actions
--nbp-info #3b82f6 Info callouts
--nbp-transition cubic-bezier(0.4, 0, 0.2, 1) Easing curve
--nbp-focus-ring 0 0 0 3px rgba(37, 99, 235, 0.1) Focus ring shadow

Overriding

Anywhere a :root rule reaches the page will do — your global stylesheet is the simplest:

/* app/globals.css */
:root {
  --nbp-primary: #0891b2;
  --nbp-primary-hover: #0e7490;
  --nbp-primary-light: #ccfbf1;
  --nbp-bg-secondary: #f0fdfa;
  --nbp-border-focus: #0891b2;
  --nbp-font-heading: var(--font-geist-sans), system-ui, sans-serif;
  --nbp-font-body: var(--font-geist-sans), system-ui, sans-serif;
}

To scope the overrides to the blog rather than the whole site, put them in the blog layout:

// app/blog/layout.tsx
import 'next-blogpanel/styles/blog.css';

export default function BlogLayout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <style dangerouslySetInnerHTML={{ __html: `
        :root {
          --nbp-primary: #0891b2;
          --nbp-primary-hover: #0e7490;
          --nbp-primary-light: #ccfbf1;
          --nbp-bg-secondary: #f0fdfa;
        }
      `}} />
      {children}
    </>
  );
}

Pointing --nbp-font-* at a next/font CSS variable, as above, is the tidiest way to inherit your site's typography.

You can also set theme.variables in next-blogpanel.config.ts. That map is merged over the defaults and is available to server code, but it does not emit a stylesheet — CSS remains the way to actually apply an override.

Colour presets

Red

--nbp-primary: #dc2626;
--nbp-primary-hover: #b91c1c;
--nbp-primary-light: #fee2e2;
--nbp-bg-secondary: #fef2f2;

Teal

--nbp-primary: #0891b2;
--nbp-primary-hover: #0e7490;
--nbp-primary-light: #ccfbf1;
--nbp-bg-secondary: #f0fdfa;

Purple

--nbp-primary: #7c3aed;
--nbp-primary-hover: #6d28d9;
--nbp-primary-light: #ede9fe;
--nbp-bg-secondary: #f5f3ff;

Green

--nbp-primary: #059669;
--nbp-primary-hover: #047857;
--nbp-primary-light: #d1fae5;
--nbp-bg-secondary: #ecfdf5;

Orange

--nbp-primary: #ea580c;
--nbp-primary-hover: #c2410c;
--nbp-primary-light: #ffedd5;
--nbp-bg-secondary: #fff7ed;

Dark mode

globals.css ships a prefers-color-scheme: dark block that reassigns six variables:

@media (prefers-color-scheme: dark) {
  :root {
    --nbp-text: #f3f4f6;
    --nbp-text-muted: #9ca3af;
    --nbp-bg: #111827;
    --nbp-bg-secondary: #1f2937;
    --nbp-card-bg: #1f2937;
    --nbp-border: #374151;
  }
}

The brand colours are deliberately left alone — your primary usually works in both modes, and when it doesn't you probably want a specific alternative rather than an automatic one.

Override the dark palette in the same media query. Make sure your rule comes after globals.css in the cascade, which it will if you import the package stylesheet before your own:

@media (prefers-color-scheme: dark) {
  :root {
    --nbp-bg: #0f172a;
    --nbp-bg-secondary: #1e293b;
    --nbp-text: #f1f5f9;
    --nbp-text-muted: #94a3b8;
    --nbp-border: #334155;
    --nbp-card-bg: #1e293b;
    --nbp-primary: #38bdf8;
  }
}

Dark mode follows the operating system. There is no class-based toggle in 1.0, so if your site has a manual switch, drive the same variables from whatever selector it sets:

:root[data-theme='dark'] {
  --nbp-bg: #0f172a;
  --nbp-text: #f1f5f9;
  /* … */
}