2026-08-31 04:46:00
I've followed and engaged in politics for about 8 years now, on and off. A lot of what we see on the news feels way too big to make any difference, and often it feels like no matter what effort goes in, we're just kind of crossing our fingers & hoping the right powerful people win - sometimes they do, and sometimes the bad ones win.
We clearly failed to stop Trump from being elected, and we've failed to stop ICE from terrorizing brown (and sometimes white) people. Trans people are losing rights in a lot of states (though, they've been protected in others).
So much of it feels hopeless, feels like there's nothing we can actually do to make a difference.
But data centers have been a galvanizing issue for people nationwide. I've seen countless videos online of people speaking at city council meetings, of local legislative victories. I've also seen politicians from both major parties change their stance on AI Data Centers.
Pritzker (D), Governor of Illinois, was a champion of Data Centers at first because jobs jobs jobs. Abbot (R), Governor of Texas, was also a champion of Data Centers, and helped move many projects forward in Texas. Both have changed their stances amid massive pushback. I've seen a slew of reports about cities in my state passing data center moratoriums, too.
This is not an issue where we're getting 100% success. There have been and will continue to be bad outcomes. But we are seeing a lot of successes across the entire country. We're seeing bipartisan support for the cause against data centers.
My community is facing pro-data-center advocacy right now, but we also have an organized group resisting. They're organizing protests, they're going to county board and city council meetings, they're spreading information on Facebook. They're doing the work, and they're staying consistent.
I'm not officially a member of either of the two organizations, but I've been showing up to meetings, speaking, and I've been taking photos to provide for the anti-data-center propaganda efforts. I don't know if we'll win. The tables do seem to be stacked against us. But we're trying, and we've seen so many other communities succeed on this issue.
I have hope. And you should too. And you should be involved if you're able. You don't need to be an expert, an academic, or a professional speaker, or anything like that. You are a member of your community, you are member in a Democracy. It is your right and your duty to participate in the process.
Email your city counselor, or speak at a public meeting just stating your opposition to data centers, or hold a sign at a protest, or donate some money to your local organizations.
2026-08-31 01:32:22
For the updated code, see code for bearblog book theme. Just replace your old CSS & Javascript with what's on that post now.
bugfix1 added display:block to list elements because ... well it sort of fixed a problem where lists (like your 'all blog posts' page) caused the side-scrolling to just not work right. But it didn't completely fix it. It was a hacky solution. And after implementing bugfix2, bugfix1 was no longer needed.
So. Bugfix2.
First, I was incorrectly calculating the number of pages. TLDR, the calculated page-width and the measured page-width just don't seem to align perfectly. After the fix, they're still not perfectly aligned, but my updated calculation seems to work. The improper calculations were causing the right-scroll to stop before reaching the last page (bc my calculation determined there were fewer pages than actually existed)
Second, when scrolling long lists, some pages were being skipped. I was using a scroll-snap feature of CSS before, which allowed fixed-scrolling-widths when you used the scroll bar at the bottom of the book. I was targeting paragraph elements within posts as targets to snap to, which are direct children of <main> (which contains your full post). WELL. With list elements, the parent is <ul> and then each list item is <li>. I think the scroll snapping was breaking things because it was snapping to paragraph elements, and skipping pages of <li> elements. Targeting <li> would require main > ul > li so .... idk ... Rather than troubleshooting the scroll snapping to make it work for everything, I just removed the scroll snapping. It wasn't that important of a feature. I don't intend to re-implement the scroll-snap behavior.
2026-08-30 01:02:00
I previously posted My book theme and discovered that on some pages, the side-scrolling was not working correctly.
This fix is (hopefully) temporary, as it eliminates list-styling features. But it seems to work, and was the quickest thing I could come up with. Follow my #bearblog posts for any additional updates.
NOTICE: This bugfix helped, but did not fully fix the problem. I have more troubleshooting to do.
TLDR, add this to your theme:
li {
display: block;
}
2026-08-29 04:48:00
I've made this theme for bearblog where your posts look like they're pages in a book!!! (on mobile, it's an old parchment, not a book)
There are still sure to be some rough edges. I haven't added any custom styling for things like lists or images. Code blocks are still ugly (but they at least kinda work). It would be awesome to add a page-turning animation, but I doubt I will.
I would like to put the toast button and the taglist somewhere static, rather than on the last page of the "book". But I haven't decided on this yet.
I might change the toast button into a book.
Here is a longer post that does a great job of showing off this theme.
For future reference, here is an image of the theme.
Here's what the mobile layout looks like, which uses an old scroll instead of a book.
Here's the code for this theme. It requires javscript to make the book-scrolling work, so I believe you can only use it on paid bearblogs.
For updates to this theme (if I publish any), check my Bearblog page or subscribe to my bearblog posts with a feed reader
Bugfix 1: See bugfix for page weirdness Bugfix 2: I believe I've completely fixed the two bugs I had. See bugfix2 for book theme
2026-08-29 04:33:00
(includes bugfix 2 (bugfix1 removed because it was a quick hack and not a real fix))
:root {
--book_width: clamp(100px, 134.38vh , min(100vw, 1000px));
--max_book_height: min( 100vh, calc( var(--book_width) / 1.3438));
--book_height: clamp(100px, 100vh, var(--max_book_height));
--header_height: 200px;
--left-arrow-space: calc( var(--book_width) * 0.035) ;
--right-arrow-space: calc( var(--book_width) * 0.045) ;
--right-pad: calc(var(--left-arrow-space) + 3.5vh);
--left-pad: calc(var(--left-arrow-space) + 2.5vh);
/** distance from the edge of the page? */
--arrow-margin: calc((100vw - var(--book_width))/2);
--arrow-margin: 0px;
--arrow_font_size: var(--right-arrow-space);
--color_cream: rgba(240, 224, 200, 1);
--color_brown: rgba(54,30,23, 1);
/*
--url_scroll_bg: url("/scroll.jpeg");
--url_background_leather: url('/background-leather.jpeg');
--url_header_bg: url('/shelf.jpeg');
--url_book: url("/book1.jpeg");
*/
--url_header_bg: url('https://bear-images.sfo2.cdn.digitaloceanspaces.com/reedybear/shelf.webp');
--url_scroll_bg: url('https://bear-images.sfo2.cdn.digitaloceanspaces.com/reedybear/scroll.webp');
--url_book: url('https://bear-images.sfo2.cdn.digitaloceanspaces.com/reedybear/book1.webp');
--url_background_leather: url('https://bear-images.sfo2.cdn.digitaloceanspaces.com/reedybear/background-leather.webp');
}
* {
box-sizing: border-box;
}
html {
background: var(--url_background_leather);
background-repeat: repeat;
}
body {
overflow-x: hidden;
margin:0;
margin-left: auto;
margin-right: auto;
height: 100vh;
height: calc(100vh + var(--header_height));
width: var(--book_width);
background: var(--url_background_leather);
background-repeat: repeat;
position:relative;
}
footer {
top:0;
right:0;
position: absolute;
height:var(--header_height);
display:flex;
flex-direction: column;
justify-content:space-between;
text-align: right;
font-size: 0.8em;
}
footer > span#footer-directive > p {
display:flex;
flex-direction: column;
color: var(--color_cream);
justify-content:end;
background: rgba(54,30,23, 0.5);
border-radius: 4px;
box-shadow: 0px 0px 3px 3px var(--color_brown);
}
footer > span#footer-directive > p > a {
color:var(--color_cream);
text-decoration: none;
}
footer > span#footer-directive > p > a:hover {
text-decoration: underline;
}
footer > span {
color: var(--color_cream);
}
footer > span > a {
color: var(--color_cream);
}
footer > span > a:hover {
text-decoration: none;
}
header {
background: var(--url_header_bg);
background-size:cover;
height: var(--header_height);
width: var(--book_width);
color: white;
padding: 16px;
box-shadow: 0px -8px 5px 10px var(--color_brown)
}
header a {
color:white;
}
header > a {
display: inline-block;
padding: 4px 12px;
border-radius: 27% 12px;
border: 1px solid rgba(171,155,130,1);
text-decoration:none;
background:var(--color_brown);
color: var(--color_cream);
}
header > a:hover {
border-color: var(--color_brown);
background-color: var(--color_cream);
color: var(--color_brown);
}
header > a > h1 {
margin-top: 8px;
margin-bottom: 12px;
}
header > nav > p {
display: inline-block;
padding: 0px 8px 0px 8px;
text-decoration:none;
background: rgba(54,30,23, 0.9);
border: 1px solid rgba(171,155,130,0.9);
border-radius: 12px 15%;
}
header > nav > p > a {
display: inline-block;
text-decoration:none;
padding: 6px 6px;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
margin-left: 8px;
color: var(--color_cream);
}
header > nav > p > a:hover {
border-color: var(--color_cream);
background-color: var(--color_cream);
color:var(--color_brown);
}
main {
color: var(--color_brown);
box-sizing: border-box;
columns: 2;
background: var(--url_book);
background-size: contain;
overflow-x: scroll;
background-repeat: no-repeat;
grid-gap: var(--right-pad);
/** Caused some pages to get skipped when using BookScroller.scroll() function */
--scroll-snap-type: x mandatory;
width: var(--book_width);
height: var(--book_height);
padding-right: var(--right-pad);
padding-left: var(--left-pad);
padding-top: 5.5vh;
padding-bottom: 2.5vh;
box-shadow: 0px -4px 10px 10px var(--color_brown)
}
/*main > ul {*/
/*margin: 0;*/
/*}*/
main a {
color: var(--color_brown);
}
main .highlight:has(> pre) {
max-height: calc(var(--book_height) - 9.5vh);
overflow-y: scroll;
overflow-x: scroll;
}
main > p {
scroll-snap-align: start;
scroll-margin-left: 55px;
scroll-margin-left: calc( var(--book_width) * .0610 );
/* width: 378px vs book_width of 805 */
/* need ration so that I can set the scroll-margin-left so that scroll snap positions are correct */
}
.leftarrow, .rightarrow {
position: absolute;
top:0;
margin-top: var(--header_height);
color: var(--color_cream);
height: var(--book_height);
line-height: var(--book_height);
cursor: pointer;
text-align: center;
font-size: var(--arrow_font_size);
user-select: none;
background: none;
border: none;
}
.leftarrow:hover, .rightarrow:hover {
background: rgba(54, 30, 23, 0.3);
}
.rightarrow {
right: 0;
margin-right: var(--arrow-margin);
width: var(--right-arrow-space);
}
.leftarrow {
left: 0;
margin-left: var(--arrow-margin);
width: var(--left-arrow-space);
}
.pagesleft {
position: absolute;
top:0;
margin-top: var(--header_height);
padding-top: 2vh;
margin-left: calc(var(--left-pad) + 1.5vh);
color: white;
text-align: center;
vertical-align:top;
color: var(--color_brown);
font-weight: bolder;
}
.pagesright {
position: absolute;
top:0;
right:0;
margin-top: var(--header_height);
padding-top: 2vh;
margin-right: calc(var(--arrow-margin) + var(--right-pad) + 3.5vh);
color: white;
text-align: center;
vertical-align:top;
color: var(--color_brown);
font-weight: bolder;
}
img {
/*
max-width: calc((var(--book_width) / 2) - 5vh);
*/
}
@media (max-width: 600px) {
:root {
--header_height: 250px;
}
body {
height: unset;
overflow-x: visible;
}
main {
overflow-x: visible;
columns: 1;
height: unset;
background-repeat: repeat;
background: var(--url_scroll_bg);
}
.leftarrow, .rightarrow, .pagesright, .pagesleft {
display:none;
}
}
(includes bugfix2 (bugfix1 was a CSS-only change)) Goes in Dashboard -> Settings -> Header and footer directives -> Head directive
<!-- MY BOOK THEME -->
<script>
const BookScroller = {
min_width: 600,
/* tracking the right-hand page number because it works with the maths */
current_page: 2,
book_el: null,
rightarrow: null,
leftarrow: null,
pagesright: null,
pagesleft: null,
timeout: null,
};
BookScroller.get_num_pages =
function(){
const book_el = BookScroller.book_el;
if (book_el.scrollLeftMax == 0){
return 2;
}
const left_pad = book_el.offsetWidth * 0.035 + window.innerHeight * 0.025;
const page_width = (book_el.offsetWidth - left_pad) / 2;
const page_count = Math.round(book_el.scrollWidth / page_width);
//const zbook_el = BookScroller.book_el;
//console.log(" ------ get_num_pages ------");
//console.log("scrollWidth: "+zbook_el.scrollWidth);
//console.log("offsetWidth: "+zbook_el.offsetWidth);
//console.log("pageWidth: "+page_width);
//console.log("numpages: "+page_count);
//console.log("Scrollpos:"+zbook_el.scrollLeft);
return page_count;
};
BookScroller.setup_dynamic_stuff =
function(){
const page_count = BookScroller.get_num_pages();
if (page_count <= 2){
BookScroller.rightarrow.style.display = "none";
}
for (const n of document.querySelectorAll('p.book_page_extender')){
n.parentNode.removeChild(n);
}
// ENSURE EVEN NUMBER OF PAGES
const max_loops = 25;
let num_loops = 0;
while ((BookScroller.get_num_pages() % 2) != 0){
const p = document.createElement('p');
p.classList.add('book_page_extender');
p.innerHTML = ' ';
book_el.appendChild(p);
// SANITY CHECK just to prevent infinte loops in case of bug
if (num_loops++ >= max_loops)break;
}
const max_scroll_loops = 50;
let scroll_loop_count = 0;
while (BookScroller.current_page >2){
BookScroller.scroll(-1);
// Sanity check to prevent infinite loop in case of bug
if (scroll_loop_count++ > max_scroll_loops)break;
}
};
BookScroller.init
= function(){
BookScroller.book_el = book_el = document.querySelector('body > main');
BookScroller.rightarrow = rightarrow = document.createElement('button');
rightarrow.classList.add("rightarrow");
rightarrow.setAttribute("tabindex", 1);
rightarrow.innerHTML = ">";
rightarrow.innerHTML = "➤"; // I couldn't find the left-hand equivalent
rightarrow.innerHTML = "⮞";
document.querySelector('body').appendChild(rightarrow);
BookScroller.leftarrow = leftarrow = document.createElement('button');
leftarrow.classList.add("leftarrow");
leftarrow.setAttribute("tabindex", 2);
leftarrow.style.display = "none";
leftarrow.innerHTML = "<";
leftarrow.innerHTML = "⮜";
document.querySelector('body').appendChild(leftarrow);
BookScroller.pagesleft = pagesleft = document.createElement('div');
pagesleft.classList.add('pagesleft');
pagesleft.innerText = "1";
document.querySelector('body').appendChild(pagesleft);
BookScroller.pagesright = pagesright = document.createElement('div');
pagesright.classList.add('pagesright');
pagesright.innerText = "2";
document.querySelector('body').appendChild(pagesright);
rightarrow.addEventListener('click',
BookScroller.scroll.bind(this,1)
);
leftarrow.addEventListener('click',
BookScroller.scroll.bind(this,-1)
);
book_el.addEventListener("wheel",
function (e) {
if (window.innerWidth <= 600){
return;
}
if (e.target.tagName == 'pre'
&& e.target.parentNode.classList.contains('highlight')
|| e.target.closest("div.highlight > pre") != null){
return;
}
if (e.deltaY > 0){
BookScroller.scroll(1);
} else {
BookScroller.scroll(-1);
}
e.preventDefault();
e.stopPropagation();
}
);
window.addEventListener("keydown",
function (e) {
if (window.innerWidth <= 600){
return;
}
if (e.key == 'ArrowRight'){
BookScroller.scroll(1);
e.preventDefault();
e.stopPropagation();
} else if (e.key == 'ArrowLeft') {
BookScroller.scroll(-1);
e.preventDefault();
e.stopPropagation();
}
}
);
BookScroller.setup_dynamic_stuff();
}
document.addEventListener('DOMContentLoaded',
function(){
BookScroller.init();
}
);
window.addEventListener('resize',
function(){
clearTimeout(BookScroller.timeout);
setTimeout(BookScroller.setup_dynamic_stuff, 250);
}
);
BookScroller.scroll =
/** direction is 1 or -1 for right or left */
function(direction){
//console.log(BookScroller);
//console.log(BookScroller.get_num_pages());
if (window.innerWidth <= BookScroller.min_width){
// we're showing mobile view, no book view
return;
}
if (direction > 0 && BookScroller.current_page >= BookScroller.get_num_pages()){
// trying to scroll right, but there are no pages to scroll to
return;
}
if (direction < 0 && BookScroller.current_page <= 2){
// trying to scroll left, but we're at the first two pages already
return;
}
BookScroller.current_page += (direction * 2);
const book_el = BookScroller.book_el;
// scroll distance is the book width - left pad - right pad + grid gap
// grid gap & right pad are the same
// these formulas are defined in the CSS
let left_pad = book_el.offsetWidth * 0.035 + .025*window.innerHeight;
let scroll_distance = book_el.offsetWidth - left_pad;
scroll_pos = scroll_distance * ((BookScroller.current_page/2)-1);
//book_el.scrollIntoView();
book_el.scroll(scroll_pos, 0);
//console.log("CurrentPage: "+BookScroller.current_page);
if (BookScroller.current_page >= BookScroller.get_num_pages()){
//console.log("hide right arrow!");
BookScroller.rightarrow.style.display = "none";
} else {
BookScroller.rightarrow.style.display = "block";
}
if (BookScroller.current_page <= 2){
BookScroller.leftarrow.style.display = "none";
} else {
BookScroller.leftarrow.style.display = "block";
}
pagesleft.innerText = BookScroller.current_page - 1;
pagesright.innerText = BookScroller.current_page;
//console.log(BookScroller);
//console.log(BookScroller.get_num_pages());
};
</script>