Shane Theme — Feature Reference
Version 2.2.0 · Theme and plugin system powering the reading, writing, and design of shane.blog
Architecture
This project is split into two components:
| Component | Owns |
|---|---|
| Shane theme | Presentation — CSS, display filters, reading UX, editor UI |
| Shane Site plugin | Data & behavior — shortcodes, taxonomies, reactions, Open Graph meta |
The plugin must be active for shortcodes ([shane_read_time], [shane_views], etc.) and data features to work. Separating them ensures post content and accumulated data (view counts, reactions, series assignments) survive a theme change.
Reading Experience
Reading Progress Bar
A 3px terracotta bar fixed to the top of the viewport on single post pages. Fills left to right as the reader scrolls. Accounts for the WordPress admin bar height.
Sticky Scroll-Aware Header
After scrolling past the post title, a compact sticky bar slides in from the top containing the truncated post title and a mini progress bar. Hides on scroll-down, reappears on scroll-up. Dismissed automatically when scrolling back to the top.
Reading Time Remaining
The “X min read” display in the post header updates dynamically as the reader scrolls. Switches to “~X min left” once reading has started, and “Almost done” when within the last 10%.
Last Updated Badge
Shortcode [shane_updated] outputs a small “Updated Month D, YYYY” badge below the post meta when the post has been meaningfully updated (modified date is >24 h after publish and the post is older than 7 days). Provided by the shane-site plugin.
Estimated Read Time
Shortcode [shane_read_time] outputs a formatted string like “4 min read” based on word count at 200 wpm. Used in the single post header. Provided by the shane-site plugin.
Auto Table of Contents
On single posts with 2 or more headings (h2/h3), a “In this post” navigation block is automatically injected before the first heading. Active section highlights in terracotta as the reader scrolls (IntersectionObserver-based scroll-spy).
Anchor Links on Headings
Every H2 and H3 inside post content gets a # anchor link that appears on hover. Clicking copies the direct URL to that section to the clipboard and shows a brief ✓ confirmation. Falls back to hash navigation if the Clipboard API is unavailable. Invisible at rest, terracotta on interaction.
Filename Labels on Code Blocks
A small label appears in the top-left of every code block. Two modes:
– Language label — auto-detected from the Prism language class (e.g. language-php → “PHP”). Shows on all highlighted blocks with no author effort.
– Custom filename — write // filename: functions.php (or # filename: ci.yml) as the very first line of your code block. The script strips it from the visible code and shows it as the label instead.
Reading Time on Feed Cards
The home feed meta row shows estimated reading time alongside the date and category — e.g. “Apr 28 · AI · 4 min read”. Uses the same [shane_read_time] shortcode as the single post header.
Tag / Category Archive Count
Tag and category archive pages show a post count line below the title — e.g. “14 posts tagged AI“. Rendered via the [shane_archive_meta] shortcode, which reads the queried term’s count directly from WordPress.
Keyboard Shortcuts Overlay
Press ? from anywhere on the site to open a panel listing all keyboard shortcuts. Press ? or Esc to close. Does not trigger when focus is inside an input. Lists: ⌘K (command palette), R (reading mode), ? (this overlay), Esc (close).
Copy Code Button
A “Copy” button appears in the top-right corner of every <pre> block on hover. Shows “Copied!” feedback for 2 seconds. Falls back to execCommand on HTTP (local dev).
Syntax Highlighting
Prism.js with a custom editorial palette. Supported languages: JavaScript, TypeScript, PHP, Python, Bash, JSON, YAML, SQL, CSS, HTML/Markup. Full dark mode support. Light mode uses a GitHub-inspired high-contrast palette.
Image Lightbox
Click any image in post content (that isn’t already a link) to open it full-screen on a dark overlay. Dismiss with Esc, clicking the overlay, or the ✕ button. Zoom cursor on hover signals the interaction.
Focus / Reading Mode
A small icon button fixed to the bottom-left of the screen hides all site chrome — header, footer, progress bar, ToC, share bar, related posts — leaving only the post content. Toggle with the button or press R. State persists for the browser session.
Back to Top
A terracotta circle button fixed to the bottom-right. Fades in after scrolling 35% of the page. Smooth scrolls to the top on click.
Post Series Navigation
Assign posts to a series via the post_series custom taxonomy. When a post belongs to a series with two or more entries, a series navigation block is automatically prepended to the content listing all posts in order with the current one highlighted in terracotta. Provided by the shane-site plugin.
Navigation & Discovery
Command Palette
Press ⌘K (or Ctrl+K) from anywhere on the site to open a search modal. Searches post titles and excerpts via the WordPress REST API with 280ms debounce. Keyboard navigation: ↑ ↓ to navigate, Enter to open, Esc to close.
Related Posts
Three posts from the same category appear at the bottom of every single post in a responsive 3-column grid. Degrades gracefully to 1 column on mobile.
Writing Tools
Footnotes
Inline shortcode [fn]...[/fn]. Renders a superscript number in the post body linked to a numbered list at the bottom of the post. The ↑ link returns the reader to the inline reference. Footnotes appear before the Related Posts section. Provided by the shane-site plugin.
Usage:
This is a claim.[fn]Source: example.com[/fn]
About Page
About Page Hero
The About page (/about/) uses a dedicated template (page-about.html) with a large display-font “Shane.” heading. The trailing period is colored in the terracotta accent via title-periods.js.
Blog Stats Row
Shortcode [shane_stats] renders a three-column stats row showing posts published, years writing, and total minutes of reading. Results are cached in a transient for 12 hours. Provided by the shane-site plugin.
Now Section + Interest Tags
A “Now” block pattern (shane/about-now) is available in the editor pattern inserter. Contains a structured “Now” section (Building / Learning / Reading / Location) and a row of hoverable interest tag pills. Edit directly in the About page editor.
Featured Image Controls
Blog Listing Toggle
A “Show on blog listing” toggle in the post editor sidebar (under “Cover Photo”) controls whether the featured image appears on the blog index. Off by default — opt-in per post.
Single Post Toggle
A “Show on single post” toggle (same panel) controls whether the featured image appears above the title on the single post page. On by default — opt-out per post.
Featured Image Fade
All featured images rendered via the shane-featured-image-fade class get a bottom-fade mask (mask-image), making them blend into the page background. Applied by default on single post pages.
Image “Fade Bottom” Block Style
Any individual image block can have the “Fade Bottom” style applied via the editor sidebar → Block → Styles. Applies the same bottom-fade mask without requiring a featured image.
Dark Mode
Dark/Light Toggle
A sun/moon icon button in the header toggles between light and dark mode. Preference is saved in localStorage and restored on every visit.
Default to Light
New visitors always start in light mode regardless of OS preference. On their first visit, a one-time hint (“Currently using light mode”) appears in Dancing Script for 5 seconds to the right of the toggle, then fades out over 2.5 seconds.
Warm Dark Palette
Dark mode uses a warm editorial palette: #18130E background, #D4612E terracotta accent, #FAF8F5 primary text. Designed to avoid harsh blue-tinted darks.
SEO & Sharing
Social Share Bar
Appears immediately after post content with three actions: Copy Link, Share on X, LinkedIn. Copy Link uses the Clipboard API with an execCommand fallback for HTTP. No external tracking scripts.
Highlight to Share
Select any text within a post and a tooltip appears above the selection with a “Share on X” link. The selected quote is wrapped in curly quotes and prepended to the post URL in the Twitter intent. Quotes longer than 260 characters are truncated.
Post View Counter
Increments on each non-admin, non-preview page load. Stored in post meta (shane_view_count). Displayed in the single post meta line via the [shane_views] shortcode. Does not count views while logged in. Provided by the shane-site plugin.
Open Graph Meta
og:title, og:description, og:image, og:url, og:site_name auto-generated from post title, excerpt (or trimmed content), and featured image. Skipped automatically if Yoast SEO or Rank Math is active. Provided by the shane-site plugin.
Twitter / X Card
twitter:card, twitter:title, twitter:description, twitter:image auto-generated alongside Open Graph tags. Uses summary_large_image format. Provided by the shane-site plugin.
Design
Accent-Colored Title Periods
Trailing periods in post and page titles are automatically wrapped in a <span class="shane-title-period"> and colored in the terracotta accent color via title-periods.js. Applies to post titles, entry titles, h1.wp-block-heading (used on Series, Deep Dives, and similar custom page templates), and .shane-about-name (About page hero).
Period Color Variants
Add shane-period-blue as an additional CSS class on any title block to render the trailing period in powder blue (#A8C8E8) instead of the default terracotta. Useful for differentiating page types or sections.
Compy Note
Add shane-compy-note as an additional CSS class on any paragraph block to render it as a small terminal-style footnote: JetBrains Mono, muted secondary color, with a terracotta > prefix via ::before. Designed for subtle easter eggs or asides.
Orange Dot in Site Title
The header site title renders as shane•blog with a terracotta bullet between the two words. Color swaps in dark mode.
Header Drop Shadow
The header uses a subtle box-shadow instead of a border for visual separation. Clean without drawing the eye.
Footer Tint
The footer uses a slightly tinted background to separate from the main content area without a hard line.
Typography
- Display: Playfair Display (serif) — headings and hero
- Body: IBM Plex Serif — paragraphs and long-form content
- UI: Inter — navigation, meta, captions, labels
- Script: Dancing Script — decorative accents
- Code: Fira Code / Fira Mono — code blocks and inline code
Drop Cap
On single post pages, the first letter of the first paragraph is set in Playfair Display at 4.2rem, floated left, in terracotta. Scales to 3rem on mobile. Full dark mode support.
Post-Type Indicators
A small uppercase label appears above the post title on the home feed for short and long posts. Posts under 250 words show “Quick take” in muted gray. Posts over 700 words show “Deep dive” in terracotta. Mid-length posts show no label — the indicator only appears when it means something. Applied via a post_class PHP filter on word count.
Mobile Typography
Tighter typographic hierarchy on screens ≤ 600px: hero scales from clamp(52px–84px) down to clamp(38px–56px), post titles drop to 1.35rem, body text steps from 18px to 16px inside single posts. Heading sizes inside posts tighten proportionally.
Editor Enhancements
Cover Photo Panel
A custom “Cover Photo” settings panel in the Gutenberg post sidebar contains both featured image toggles. Only visible on posts.
Templates
| Template | Description |
|---|---|
index.html |
Blog listing with featured images |
index-cards.html |
Card-style blog listing |
single.html |
Single post with featured image above title |
page.html |
Default page |
page-about.html |
About page with typed hero, stats row, Now pattern |
page-online.html |
Links page (Shane’s “Online” page) |
archive.html |
Category/tag archive |
search.html |
Search results |
404.html |
Not found |
page-now.html |
/now page — what I’m building, learning, reading |
archive-lab_entry.html |
/lab archive — build log, reverse-chronological |
single-lab_entry.html |
Single lab entry |
page-deep-dives.html |
/deep-dives/ — long-form post grid (> 700 words) |
page-series.html |
/series/ — Volume Cards index of all post series |
page-archive.html |
/archive/ — 3-section layout: full-width search, Latest Posts (5), Full Archive year accordion |
page-terminal.html |
/terminal — fake interactive shell, no header/footer, back button |
page-toomanysecrets.html |
/toomanysecrets — Adventure (Atari 2600) easter egg room, no header/footer |
AI & Automation
AI Post Summary
A one-line AI-generated summary displayed in the post header beneath the title. Generated via the Claude API (Haiku model) at publish time and stored in shane_ai_summary post meta. Renders as a terracotta-tinted callout with a “Quick take” label. An admin meta box in the post sidebar allows regeneration without republishing. Provided by the shane-site plugin.
Pages
Deep Dives (/deep-dives/)
A curated page listing every post over 700 words as a two-column card grid (single column on mobile). Each card shows the featured image, a “Deep Dive” badge, title, date/category/read time, excerpt, and a “Read →” link. Powered by the [shane_deep_dives] shortcode in the shane-site plugin. Provided by the shane-site plugin.
Series (/series/)
An index of all post series using the Volume Cards layout. Each card shows a Roman numeral badge (I, II, III…), series title, post count, an ongoing/complete status pill, every post in the series as a numbered clickable row with date, and a “Start from the beginning” link to the first post. Status defaults to “Ongoing”; set term meta series_status = complete to mark a series done. Powered by the [shane_series_list] shortcode. Provided by the shane-site plugin.
/now Page
A dedicated /now page documenting what Shane is currently building, learning, and reading. Uses a page-now.html FSE template with a title, [shane_now_meta] shortcode showing last-updated date, and standard post content. Content is edited directly in the WordPress block editor.
Build Log (/lab)
A running changelog of shipped agents, automations, apps, and experiments. Powered by the lab_entry custom post type with archive at /lab/. Ordered reverse-chronologically. Each entry: date, title, excerpt, optional full content. Separate from the main blog — shows process and velocity. Provided by the shane-site plugin.