Robert Birming

Bearry Christmas theme for Bear

Bearry Christmas theme

Here in Sweden, we celebrate Christmas tomorrow. I’ve been busy preparing for that. Not with cooking or buying gifts, but by creating a Christmas theme for anyone who wants to spice up their blog for a day or two.

It includes falling snow, a sparkling title, glowing links, a present upvote button, and a bunch of other small festive touches.

Last Christmas, I gave you my data
The very next day, ads came to stay
This year, no cookies, no fear
It’s a joy to share, I’m using Bear

/*
 * Bearry Christmas — a seasonal Bear theme
 * Version 1.2.0 | 2026-02-12
 * Robert Birming | robertbirming.com
 */

/* =========================
   Palette
   ========================= */

:root {
  color-scheme: light dark;

  /* Light */
  --bg-light:   #fef9f3;
  --txt-light:  #1f3d2f;
  --link-light: #c7352f;

  /* Dark */
  --bg-dark:   #1a0f0f;
  --txt-dark:  #fff5e6;
  --link-dark: #4db854;
}

/* =========================
   Base tokens
   ========================= */

:root {
  --width: 720px;
  --font-main: Verdana, sans-serif;
  --font-secondary: Verdana, sans-serif;
  --font-scale: 1em;

  --background-color: var(--bg-light);
  --heading-color: var(--txt-light);
  --text-color: color-mix(in srgb, var(--txt-light) 86%, var(--bg-light));
  --link-color: var(--link-light);
  --visited-color: color-mix(in srgb, var(--link-light) 62%, #8b6fcb);

  --code-background-color: color-mix(in srgb, var(--bg-light) 86%, var(--txt-light));
  --code-color: var(--heading-color);
  --blockquote-color: var(--heading-color);

  --link: var(--link-color);
  --border: color-mix(in srgb, var(--text-color) 18%, var(--background-color));
  --surface: color-mix(in srgb, var(--background-color) 94%, var(--text-color));
  --space: 1rem;

  --glow-soft: color-mix(in srgb, var(--link) 26%, transparent);
  --glow-strong: color-mix(in srgb, var(--link) 46%, transparent);
}

@media (prefers-color-scheme: dark) {
  :root {
    --background-color: var(--bg-dark);
    --heading-color: var(--txt-dark);
    --text-color: color-mix(in srgb, var(--txt-dark) 88%, var(--bg-dark));
    --link-color: var(--link-dark);
    --visited-color: color-mix(in srgb, var(--link-dark) 60%, #8b6fcb);

    --code-background-color: color-mix(in srgb, var(--bg-dark) 84%, #000);
    --code-color: var(--heading-color);
    --blockquote-color: color-mix(in srgb, var(--heading-color) 88%, var(--bg-dark));

    --border: color-mix(in srgb, var(--text-color) 22%, var(--background-color));
    --surface: color-mix(in srgb, var(--background-color) 88%, #fff);

    --glow-soft: color-mix(in srgb, var(--link) 20%, transparent);
    --glow-strong: color-mix(in srgb, var(--link) 36%, transparent);
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--font-secondary);
  font-size: var(--font-scale);
  margin: auto;
  padding: 20px;
  max-width: var(--width);
  text-align: left;
  background-color: var(--background-color);
  word-wrap: break-word;
  overflow-wrap: break-word;
  line-height: 1.5;
  color: var(--text-color);
}

main { line-height: 1.6; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-main);
  color: var(--heading-color);
}

a {
  color: var(--link-color);
  cursor: pointer;
  text-decoration: none;
}

nav a { margin-right: 8px; }

strong, b { color: var(--heading-color); }

button { margin: 0; cursor: pointer; }

time {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-style: normal;
  font-size: 15px;
}

table { width: 100%; }

hr { border: 0; border-top: 1px dashed; }

img { max-width: 100%; }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  padding: 2px;
  background-color: var(--code-background-color);
  color: var(--code-color);
  border-radius: 3px;
}

blockquote {
  border-left: 1px solid #999;
  color: var(--blockquote-color);
  padding-left: 20px;
  font-style: italic;
}

footer {
  padding: 25px 0;
  text-align: center;
}

.title:hover { text-decoration: none; }
.title h1 { font-size: 1.5em; }

.inline { width: auto !important; }

.highlight, .code {
  padding: 1px 15px;
  background-color: var(--code-background-color);
  color: var(--code-color);
  border-radius: 3px;
  margin-block-start: 1em;
  margin-block-end: 1em;
  overflow-x: auto;
}

/* blog post list */
ul.blog-posts { list-style-type: none; padding: unset; }
ul.blog-posts li { display: flex; }
ul.blog-posts li span { flex: 0 0 130px; }
ul.blog-posts li a:visited { color: var(--visited-color); }

p { margin-block: 1.2em; }

h1, h2, h3, h4, h5, h6 {
  margin-block: 1.6rem 0.5rem;
  line-height: 1.3;
}

hr, img, blockquote { margin-block: 1.6em; }

img { display: block; height: auto; }

header { margin-block: 1rem 1.8rem; }
header a.title { display: inline-block; }
header .title h1 { margin-block: 0; }

header .title h1,
.post main > h1 { margin-block-end: 0.25rem; }

header nav p { margin-block-start: 0.35rem; }
.post main > h1 + p { margin-block-start: 0; }

footer p { margin-block: 0.7em; }
time { opacity: 0.8; }

/* Optional: neat prev/next if you use the plugin */
.post-nav { display: none; margin-block-end: 2.2rem; }
body.post .post-nav { display: block; }
body.post .post-nav p {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: 1.2rem;
  flex-wrap: wrap;
  text-align: center;
}
.post-nav a.previous-post::before { content: "« "; }
.post-nav a.next-post::after { content: " »"; }


/* =========================
   Christmas vibes
   ========================= */

body {
  background:
    radial-gradient(900px 520px at 12% -10%, color-mix(in srgb, var(--link) 9%, transparent), transparent 70%),
    radial-gradient(720px 420px at 92% 10%, color-mix(in srgb, var(--link) 6%, transparent), transparent 65%),
    var(--background-color);
}

/* Glow links */
a {
  transition: text-shadow 0.25s ease, transform 0.15s ease, color 0.15s ease;
  will-change: text-shadow, transform;
}

a:hover,
a:focus-visible {
  text-decoration: underline;
  text-shadow:
    0 0 6px var(--glow-strong),
    0 0 16px var(--glow-soft);
  transform: translateY(-1px);
}

header a.title:hover,
header a.title:focus-visible,
.title a:hover,
.title a:focus-visible {
  text-shadow: none;
  transform: none;
}

/* Tree title marker */
:where(header a.title h1, .title h1)::after {
  content: "🎄";
  margin-left: 0.25em;
  white-space: nowrap;
  color: #f2c94c;
  text-shadow:
    0 0 4px rgba(242, 201, 76, 0.45),
    0 0 10px rgba(242, 201, 76, 0.25);
  display: inline-block;
}

@media (prefers-reduced-motion: no-preference) {
  :where(header a.title h1, .title h1)::after {
    animation: bearry-twinkle 3.8s ease-in-out infinite;
  }
}

@keyframes bearry-twinkle {
  0%, 100% { opacity: 0.95; transform: translateY(0) scale(1); }
  45% { opacity: 0.6; transform: translateY(-1px) scale(0.98); }
  55% { opacity: 1; transform: translateY(0) scale(1.04); }
}

/* Twinkly headings, lightly */
@media (prefers-reduced-motion: no-preference) {
  :is(h1, h2, h3, h4) {
    animation: bearry-heading-twinkle 9s infinite steps(90, end);
  }
}
@keyframes bearry-heading-twinkle {
  0%, 100% { opacity: 1; }
  9% { opacity: 0.78; }
  11% { opacity: 1; }
  58% { opacity: 0.9; }
  59% { opacity: 1; }
}

/* Small seasonal markers (subtle) */
h2::before { content: "🍪 "; }
h3::before { content: "🔔 "; }
h4::before { content: "🕯️ "; }

/* Candy-cane divider */
hr {
  border: 0;
  height: 14px;
  background:
    linear-gradient(to right, transparent, var(--border), transparent) center/100% 1px no-repeat,
    repeating-linear-gradient(
      90deg,
      color-mix(in srgb, var(--link) 72%, transparent) 0 10px,
      transparent 10px 20px
    ) center/240px 6px no-repeat;
  opacity: 0.9;
}

/* Cozy blockquotes */
blockquote {
  border-left: 2px solid color-mix(in srgb, var(--link) 35%, var(--border));
  padding: 18px 20px;
  background:
    radial-gradient(560px 240px at 12% 0%, color-mix(in srgb, var(--link) 10%, transparent), transparent 65%),
    var(--surface);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--border) 70%, transparent),
    inset 0 0 14px color-mix(in srgb, var(--link) 10%, transparent);
}

/* Upvote button: Present */
#upvote-form > small {
  display: block;
  margin-top: 1.8rem;
  font-size: 1em;
}

#upvote-form .upvote-button {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  font: inherit;
  color: var(--text-color);
  opacity: 0.9;
}

#upvote-form .upvote-button svg {
  display: none;
}

#upvote-form .upvote-button::before {
  content: "🎁";
  font-size: 1.8rem;
  line-height: 1;
  transition: transform 0.15s ease, opacity 0.15s ease, filter 0.15s ease;
}

#upvote-form .upvote-count {
  font-size: 0.82em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--text-color);
  opacity: 0.8;
}

@media (hover: hover) {
  #upvote-form .upvote-button:not([disabled]):hover::before {
    transform: scale(1.08);
    filter: drop-shadow(0 0 10px color-mix(in srgb, var(--link-color) 18%, transparent));
  }

  #upvote-form .upvote-button:not([disabled]):hover .upvote-count {
    opacity: 0.9;
  }
}

#upvote-form .upvote-button.upvoted,
#upvote-form .upvote-button[disabled] {
  opacity: 0.65;
  cursor: default;
}

#upvote-form .upvote-button.upvoted::before,
#upvote-form .upvote-button[disabled]::before {
  content: "🎉";
}

#upvote-form .upvote-button.upvoted .upvote-count,
#upvote-form .upvote-button[disabled] .upvote-count {
  opacity: 0.85;
}

/* Be kind */
:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--link) 55%, transparent);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

Happy blogging, and Merry Christmas! 🎅