Robert Birming

ValenTheme

ValenTheme

ValenTheme is a lovely Bear theme made for Valentine’s Day.

A sweet seasonal change if you feel like dressing up your blog for the occasion, though nothing is stopping you from using it all year round, of course.

How to use

Copy the styles below and paste them into your Bear theme settings, and you’re ready to go.

For a trail of little hearts following the cursor, also add the script at the bottom of this page to your footer.1

Styles

/*
 * ValenTheme – a Valentine-inspired theme
 * Version 1.2.0 | 2026-02-14
 * Robert Birming | robertbirming.com
 */

:root {
  --width: 45rem;
  --outer-margin: 2.5rem;
  --outer-margin-mobile: 1.125rem;
  --card-padding: 2.5rem;
  --card-padding-mobile: 1.375rem;
  --frame-border: 0.4375rem;
  --frame-border-mobile: 0.375rem;
  --radius-lg: 0.875rem;
  --radius-md: 0.625rem;
  --radius-sm: 0.375rem;
  --font-main: ui-rounded, "Arial Rounded MT Bold", "Trebuchet MS", system-ui, sans-serif;
  --font-secondary: system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
  --font-scale: 1em;
  --background-color: #FADCD9;
  --heading-color: #56021F;
  --text-color: #45010e;
  --link-color: #B82132;
  --visited-color: #872341;
  --code-background-color: #FFE2E2;
  --code-color: #56021F;
  --blockquote-color: #222;
  --gradient: linear-gradient(#B82132, #872341);
  --heart-blush: rgba(184, 33, 50, 0.08);
  --header-gap: 2.125rem;
  --header-pad-bottom: 1.375rem;
  --nav-mt: 0.75rem;
  --nav-mb: 2.5rem;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  background:
    radial-gradient(circle closest-side at 60% 43%, #b03 26%, rgba(187, 0, 51, 0) 27%),
    radial-gradient(circle closest-side at 40% 43%, #b03 26%, rgba(187, 0, 51, 0) 27%),
    radial-gradient(circle closest-side at 42% 22%, #d35 43%, rgba(221, 51, 85, 0) 45%),
    radial-gradient(circle closest-side at 58% 22%, #d35 43%, rgba(221, 51, 85, 0) 45%),
    radial-gradient(circle closest-side at 50% 35%, #d35 32%, rgba(221, 51, 85, 0) 27%),
    radial-gradient(circle closest-side at 60% 43%, #b03 26%, rgba(187, 0, 51, 0) 27%) 3.125rem 3.125rem,
    radial-gradient(circle closest-side at 40% 43%, #b03 26%, rgba(187, 0, 51, 0) 27%) 3.125rem 3.125rem,
    radial-gradient(circle closest-side at 40% 22%, #d35 40%, rgba(221, 51, 85, 0) 45%) 3.25rem 3.125rem,
    radial-gradient(circle closest-side at 60% 22%, #d35 40%, rgba(221, 51, 85, 0) 45%) 3rem 3.125rem,
    radial-gradient(circle closest-side at 50% 35%, #d35 30%, rgba(221, 51, 85, 0) 37%) 3.125rem 3.125rem;
  background-color: #b03;
  background-size: 6.25rem 6.25rem;
}

body {
  max-width: var(--width);
  margin: var(--outer-margin) auto;
  padding: var(--card-padding);
  font-family: var(--font-secondary);
  font-size: var(--font-scale);
  line-height: 1.5;
  text-align: left;
  background-color: var(--background-color);
  color: var(--text-color);
  word-wrap: break-word;
  overflow-wrap: break-word;
  border: var(--frame-border) solid color-mix(in srgb, var(--link-color) 85%, var(--background-color));
  border-radius: var(--radius-lg);
  box-shadow:
    0 1.125rem 2.5rem rgba(0, 0, 0, 0.18),
    0 0.125rem 0 rgba(255, 255, 255, 0.35) inset;
}

@media (max-width: 51.25rem) {
  body {
    margin: var(--outer-margin-mobile) auto;
    padding: var(--card-padding-mobile);
    border-width: var(--frame-border-mobile);
  }
}

::selection {
  background: var(--link-color);
  color: var(--background-color);
}

main {
  line-height: 1.6;
}

p {
  margin-block: 1.2em;
}

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

img {
  display: block;
  height: auto;
  max-width: 100%;
}

.inline {
  width: auto !important;
}

table {
  width: 100%;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: var(--font-main);
  color: var(--heading-color);
  margin-block: 1.6rem 0.5rem;
  line-height: 1.3;
}

h1 {
  font-size: 2.4em;
}

h2 {
  font-size: 1.9em;
}

h3 {
  font-size: 1.5em;
}

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

a {
  color: var(--link-color);
  cursor: pointer;
  text-decoration: none;
  background: linear-gradient(var(--link-color), var(--link-color)) no-repeat 0 100% / 0% 0.125rem;
  transition: background-size 180ms ease, color 140ms ease, box-shadow 140ms ease;
}

a:hover {
  background-size: 100% 0.125rem;
  color: var(--heading-color);
}

a:focus-visible,
button:focus-visible {
  outline: none;
  box-shadow: 0 0 0 0.1875rem color-mix(in srgb, var(--link-color) 35%, transparent);
  border-radius: var(--radius-sm);
}

button {
  margin: 0;
  cursor: pointer;
}

hr {
  border: 0;
  height: 1px;
  background-image: linear-gradient(to right, transparent, var(--link-color), transparent);
  margin: 2.5rem 0;
  overflow: visible;
  text-align: center;
}

hr::after {
  content: "♥" / "";
  display: inline-block;
  position: relative;
  top: -0.875rem;
  padding: 0 0.625rem;
  background: var(--background-color);
  color: var(--link-color);
  font-size: 1.2em;
}

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  background-color: var(--code-background-color);
  color: var(--code-color);
  border: 1px solid color-mix(in srgb, var(--link-color) 18%, transparent);
  border-radius: var(--radius-sm);
  padding: 0.12em 0.35em;
}

.highlight,
.code {
  padding: 0.0625rem 0.9375rem;
  background-color: var(--code-background-color);
  color: var(--code-color);
  border: 1px solid color-mix(in srgb, var(--link-color) 22%, transparent);
  border-radius: var(--radius-md);
  margin-block-start: 1em;
  margin-block-end: 1em;
  overflow-x: auto;
}

blockquote {
  position: relative;
  margin-block: 1.6em;
  padding: 1.1rem 1.25rem;
  border: 1px solid color-mix(in srgb, var(--link-color) 24%, var(--background-color));
  border-radius: var(--radius-md);
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--code-background-color) 65%, transparent),
    color-mix(in srgb, var(--background-color) 82%, transparent)
  );
  color: var(--text-color);
  font-style: italic;
  line-height: 1.65;
  box-shadow:
    0 0.125rem 0 rgba(255, 255, 255, 0.35) inset,
    0 0.25rem 0.6rem rgba(0, 0, 0, 0.05);
}

blockquote::after {
  content: "♥" / "";
  position: absolute;
  bottom: -0.6rem;
  right: 1.1rem;
  background: var(--background-color);
  padding: 0 0.45rem;
  color: var(--link-color);
  font-size: 1rem;
  opacity: 0.7;
  line-height: 1;
  pointer-events: none;
}

blockquote p {
  margin-block: 0.8em;
}

blockquote p:first-child {
  margin-block-start: 0;
}

blockquote p:last-child {
  margin-block-end: 0;
}

header {
  margin-bottom: var(--header-gap);
  padding-bottom: var(--header-pad-bottom);
  border-bottom: none;
  position: relative;
  text-align: center;
  margin-block: 1rem 1.8rem;
}

header a.title {
  display: inline-block;
  background-image: none;
}

header a.title:hover {
  background-image: none;
}

header .title h1 {
  margin-block: 0;
  font-size: 2em;
}

header::after {
  content: "";
  display: block;
  height: 0.1875rem;
  margin-top: var(--header-pad-bottom);
  background: linear-gradient(90deg, transparent, var(--link-color), transparent);
  border-radius: 0.125rem;
}

nav {
  margin-top: var(--nav-mt);
  margin-bottom: var(--nav-mb);
  font-size: 0.9rem;
}

nav,
nav > * {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.375rem 0.5rem;
}

nav p {
  margin-block-start: 0.35rem;
}

nav a {
  display: inline-block;
  margin: 0;
  padding: 0.375rem 0.75rem;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--link-color) 30%, transparent);
  background: color-mix(in srgb, var(--heart-blush) 60%, transparent);
  color: var(--heading-color);
  font-weight: 600;
  background-image: none;
  text-decoration: none;
  transition:
    transform 120ms ease,
    background-color 120ms ease,
    box-shadow 120ms ease,
    border-color 120ms ease;
}

nav a:hover {
  background: var(--heart-blush);
  border-color: var(--link-color);
  transform: translateY(-1px);
  box-shadow: 0 0.375rem 0.875rem rgba(0, 0, 0, 0.12);
  color: var(--heading-color);
  background-image: none;
  text-decoration: none;
}

nav a:active {
  transform: translateY(0);
  box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.10);
}

.title:hover {
  text-decoration: none;
}

@keyframes valen-shimmer {
  0% {
    background-position: -200% center;
  }

  100% {
    background-position: 200% center;
  }
}

.title h1::after {
  content: "*:・゚♥" / "";
  display: inline-block;
  margin-left: 0.3em;
  background: linear-gradient(135deg, #c0737a, #e8a0a8, #b05060, #e8a0a8, #c0737a);
  background-size: 200% auto;
  color: transparent;
  -webkit-background-clip: text;
  background-clip: text;
  transform: translateY(-1px);
  transition: transform 180ms ease, filter 180ms ease;
  filter: saturate(1.05);
}

.title:hover h1::after {
  transform: translateY(-2px) scale(1.03);
  filter: saturate(1.25) brightness(1.05);
  animation: valen-shimmer 2.8s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .title:hover h1::after {
    animation: none;
  }
}

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

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

.post main time,
.post main > time {
  display: inline-block;
  margin-block: 0 1rem;
  opacity: 0.8;
  font-style: normal;
}

footer {
  padding: 1.5625rem 0 !important;
  text-align: center;
  position: relative;
  margin-top: var(--header-gap);
}

footer::before {
  content: "";
  display: block;
  height: 0.1875rem;
  margin-bottom: 1.25rem;
  background: linear-gradient(90deg, transparent, var(--link-color), transparent);
  border-radius: 0.125rem;
}

footer p {
  margin-block: 0.7em;
}

ul.blog-posts {
  list-style: none;
  padding: 0;
  margin-block: 1.6rem 0;
}

ul.blog-posts li {
  display: grid;
  grid-template-columns: max-content 1fr;
  align-items: center;
  column-gap: 1.2rem;
  row-gap: 0.25rem;
  padding-block: 0.45rem;
  border-bottom: 1px solid color-mix(in srgb, var(--text-color) 12%, var(--background-color));
}

ul.blog-posts li:last-child {
  border-bottom: 0;
}

ul.blog-posts li span {
  margin: 0;
  padding: 0;
  color: var(--visited-color);
  font-size: 0.85em;
  opacity: 0.75;
  font-style: normal;
  line-height: 1.2;
  white-space: nowrap;
}

ul.blog-posts li span :is(i, em) {
  font-style: normal;
}

ul.blog-posts li time {
  font-style: normal;
}

ul.blog-posts li a {
  display: inline-block;
  font-weight: 600;
  background-image: none;
  min-width: 0;
}

ul.blog-posts li a:hover {
  background-image: none;
}

@media (max-width: 38rem) {
  ul.blog-posts li {
    grid-template-columns: 1fr;
    align-items: start;
    row-gap: 0.35rem;
    padding-block: 0.6rem;
  }

  ul.blog-posts li span {
    white-space: normal;
    opacity: 0.7;
  }

  ul.blog-posts li a {
    justify-self: start;
  }
}

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

#upvote-form .upvote-button {
  display: inline-flex !important;
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  align-items: center !important;
  justify-content: center !important;
  width: fit-content;
  max-width: 100%;
  white-space: nowrap;
  gap: 0.4em !important;
  margin: 0;
  padding: 0.375rem 0.75rem;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--link-color) 30%, transparent);
  background: color-mix(in srgb, var(--heart-blush) 60%, transparent);
  color: var(--heading-color);
  font-weight: 600;
  font-family: var(--font-secondary);
  font-size: 0.95em;
  line-height: 1.2;
  cursor: pointer;
  opacity: 1;
  background-image: none;
  text-decoration: none;
  transition:
    transform 120ms ease,
    background-color 120ms ease,
    box-shadow 120ms ease,
    border-color 120ms ease,
    color 120ms ease;
}

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

#upvote-form .upvote-count {
  display: none !important;
}

#upvote-form .upvote-button::before {
  content: "♡";
  display: inline-block;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 1.15em;
  line-height: 1;
  color: var(--heading-color);
  transform: translateY(0.02em);
}

#upvote-form .upvote-button::after {
  content: "Love it?";
  display: inline-block;
  white-space: nowrap;
}

@media (hover: hover) {
  #upvote-form .upvote-button:not([disabled]):not(.upvoted):hover {
    background: var(--heart-blush);
    border-color: var(--link-color);
    transform: translateY(-1px);
    box-shadow: 0 0.375rem 0.875rem rgba(0, 0, 0, 0.12);
    color: var(--heading-color);
  }
}

#upvote-form .upvote-button:not([disabled]):not(.upvoted):active {
  transform: translateY(0);
  box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.10);
}

#upvote-form .upvote-button:focus-visible {
  outline: none;
  box-shadow: 0 0 0 0.1875rem color-mix(in srgb, var(--link-color) 35%, transparent);
}

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

#upvote-form .upvote-button.upvoted::before,
#upvote-form .upvote-button[disabled]::before {
  content: "♥";
  color: var(--heading-color);
}

#upvote-form .upvote-button.upvoted::after,
#upvote-form .upvote-button[disabled]::after {
  content: "Love you!";
  color: var(--heading-color);
}

#guestbooks___guestbook-form-container form {
  display: flex;
  flex-direction: column;
  gap: 0.8em;
  margin-block: 1.6em;
}

#guestbooks___guestbook-form-container :is(input, textarea, button) {
  font: inherit;
  letter-spacing: inherit;
  appearance: none;
}

#guestbooks___guestbook-form-container :is(input[type="text"], input[type="email"], input[type="url"], textarea) {
  width: 100%;
  padding: 0.7rem 0.9rem;
  color: var(--text-color);
  background: color-mix(in srgb, var(--background-color) 86%, #fff);
  border: 1px solid color-mix(in srgb, var(--link-color) 26%, var(--background-color));
  border-radius: 10px;
  outline: none;
  box-shadow: 0 0.125rem 0 rgba(255, 255, 255, 0.35) inset;
}

#guestbooks___guestbook-form-container textarea {
  min-height: 7.5em;
  resize: vertical;
}

#guestbooks___guestbook-form-container :is(input, textarea):focus {
  border-color: color-mix(in srgb, var(--link-color) 50%, var(--background-color));
  box-shadow:
    0 0 0 3px color-mix(in srgb, var(--link-color) 16%, transparent),
    0 0.125rem 0 rgba(255, 255, 255, 0.35) inset;
}

#guestbooks___guestbook-form-container :is(button, input[type="submit"]) {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.55rem 0.9rem;
  color: var(--heading-color);
  background: color-mix(in srgb, var(--heart-blush) 60%, transparent);
  border: 1px solid color-mix(in srgb, var(--link-color) 30%, transparent);
  border-radius: 999px;
  font-weight: 600;
  cursor: pointer;
  transition:
    transform 120ms ease,
    background-color 120ms ease,
    box-shadow 120ms ease,
    border-color 120ms ease,
    color 120ms ease;
}

#guestbooks___guestbook-form-container :is(button, input[type="submit"])::before {
  content: "♡";
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1;
  transform: translateY(0.02em);
}

@media (hover: hover) {
  #guestbooks___guestbook-form-container :is(button, input[type="submit"]):hover {
    background: var(--heart-blush);
    border-color: var(--link-color);
    transform: translateY(-1px);
    box-shadow: 0 0.375rem 0.875rem rgba(0, 0, 0, 0.12);
  }
}

#guestbooks___guestbook-form-container :is(button, input[type="submit"]):active {
  transform: translateY(0);
  box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.10);
}

#guestbooks___guestbook-form-container :is(button, input[type="submit"]):focus-visible {
  outline: none;
  box-shadow: 0 0 0 0.1875rem color-mix(in srgb, var(--link-color) 35%, transparent);
}

#guestbooks___guestbook-messages-header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45em;
  margin-block: 2.2rem 1rem;
  text-align: center;
}

#guestbooks___guestbook-messages-header::before {
  content: "♥" / "";
  color: var(--link-color);
  translate: 0 1px;
}

#guestbooks___guestbook-messages-container > div {
  margin-block: 1.2em;
  padding: 1em 1.1em;
  font-size: 0.95em;
  border: 1px solid color-mix(in srgb, var(--link-color) 18%, var(--background-color));
  border-radius: 12px;
  background: color-mix(in srgb, var(--heart-blush) 75%, transparent);
  box-shadow: 0 0.125rem 0 rgba(255, 255, 255, 0.35) inset;
}

#guestbooks___guestbook-messages-container :is(blockquote, p) {
  margin: 0.35em 0 0;
  padding: 0;
  border: 0;
  background: none;
  font-style: normal;
}

#guestbooks___guestbook-messages-container time {
  font-size: 0.85em;
  opacity: 0.8;
  white-space: nowrap;
}

#guestbooks___guestbook-messages-container .guestbook-message-reply {
  position: relative;
  margin-block: 0.9rem 0.2rem;
  margin-inline-start: 1.25rem;
  padding: 0.9em 1.05em;
  background: color-mix(in srgb, var(--text-color) 3%, var(--background-color));
  border: 1px solid color-mix(in srgb, var(--link-color) 16%, var(--background-color));
  border-radius: 10px;
}

#guestbooks___guestbook-messages-container .guestbook-message-reply::before {
  content: "";
  position: absolute;
  top: -0.95rem;
  left: -0.85rem;
  width: 0.7rem;
  height: 1.55rem;
  border-left: 2px solid color-mix(in srgb, var(--link-color) 18%, var(--background-color));
  border-bottom: 2px solid color-mix(in srgb, var(--link-color) 18%, var(--background-color));
  border-bottom-left-radius: 8px;
  opacity: 0.6;
}

.cursor-heart {
  position: fixed;
  pointer-events: none;
  transform: translate(-50%, -50%);
  opacity: 0.9;
  color: #e2556b;
  user-select: none;
  z-index: 9999;
  will-change: transform, opacity;
  animation: heart-fade 0.9s ease-out forwards;
}

@keyframes heart-fade {
  0% {
    opacity: 0.9;
    transform: translate(-50%, -50%) scale(1);
  }

  100% {
    opacity: 0;
    transform: translate(-50%, -120%) scale(0.55);
  }
}

Heart trail (optional)

<script>
/* Heart trail | robertbirming.com */
(function () {
  if (matchMedia("(prefers-reduced-motion: reduce)").matches) return;

  const hearts = ["❤", "♡"];
  const maxHearts = 30;
  let lastSpawn = 0;

  document.addEventListener("mousemove", function (e) {
    const now = Date.now();
    if (now - lastSpawn < 35) return;
    lastSpawn = now;

    const heart = document.createElement("span");
    heart.textContent = hearts[Math.floor(Math.random() * hearts.length)];
    heart.className = "cursor-heart";
    heart.style.fontSize = heart.textContent === "❤" ? "15px" : "13px";
    heart.style.left = e.clientX + "px";
    heart.style.top = e.clientY + "px";
    document.body.appendChild(heart);

    const all = document.querySelectorAll(".cursor-heart");
    if (all.length > maxHearts) all[0].remove();

    setTimeout(() => heart.remove(), 900);
  });
})();
</script>

Lovely blogging! ❤️

Want more? Check out the full Bear Blog library.

  1. Requires JavaScript, available on Bear Blog's premium plan.↩