We built the Renkara Media Group corporate website without React. Without Next.js. Without Gatsby, Astro, Hugo, or any other framework that would have been the obvious choice in 2026. The entire site is static HTML, a single CSS file with 40+ custom properties, and vanilla JavaScript. It loads in under 2 seconds on a 3G connection, supports full dark mode, and deploys from a 4-script build pipeline to S3 and CloudFront. This is how we built it and why.
The Architecture Decision
A corporate website is not an application. It does not manage state. It does not fetch data at runtime. It does not need hydration, server components, or a virtual DOM. It needs to load fast, look good, and get out of the way. We chose the simplest tool that could do the job: plain HTML files served from a CDN.
The entire design system lives in a single style.css file. Over 40 CSS custom properties define the color palette, typography scale, spacing rhythm, border radii, shadows, and animation timings. Dark mode is handled entirely through [data-theme="dark"] selectors that remap those properties. There is no JavaScript involved in theming beyond reading the user's preference from localStorage on page load and toggling the attribute on click.
The result is a site that scores 100 on Lighthouse performance audits, requires zero runtime dependencies, and can be understood by anyone who opens View Source. Every page is a self-contained document. There is no routing layer, no code splitting, no bundle analyzer. The mental model is the same one Tim Berners-Lee had in 1991: files on a server.
The Timeline
The timeline page is the most complex piece of the site. It traces Renkara's history from February 2008, when Apple announced the iPhone SDK and made the App Store possible, through April 2026 and the launch of AccelaStudy(R) AI. Over 60 milestones are laid out along a vertical spine, alternating left and right in a chronological flow that spans 18 years of company history.
Each entry is tagged with a category: Launch, IP, Milestone, Innovation, or Tool. The entries carry real specifics. There is the day Flashcard Champion hit #1 in the Education category on the App Store and set a single-day sales record of $2,420. There is the cease-and-desist letter from Patton Boggs LLP on behalf of Chuck Norris regarding the "Chuck Norris Facts" flashcard deck. There is Apple selecting iPhraseBook as the iPad App of the Week, with content licensed from HarperCollins. There is the partnership with Michael Rowley to bring his KanjiPictoGraphix illustrations into AccelaStudy Japanese, turning a static reference book into an interactive learning tool.
The timeline is generated from a single timeline.md Markdown file via a Node.js build script. Each milestone is a Markdown section with frontmatter-style metadata (date, category tag, optional image gallery). The build script parses the Markdown, generates the alternating left-right HTML layout, and injects the result into the timeline page template. This means adding a new milestone requires editing one Markdown file and running one command.
Scroll-Driven Animation
A thin vertical line runs down the center of the timeline. As the user scrolls, a fill animation tracks their progress. This is powered by an IntersectionObserver that watches each milestone entry as it enters the viewport, updating a CSS custom property that controls the fill height. The result is a smooth, performant animation that requires no scroll event listeners and no JavaScript animation frames.
Lightbox Galleries
Many timeline entries include photo galleries with original App Store screenshots from 2008 through 2013. These are lazy-loaded using the native loading="lazy" attribute and open in a custom lightbox with previous/next navigation. Over 360 photos are organized across the timeline. On desktop, entries sit side-by-side with the central spine. On mobile, they stack vertically with the spine collapsed to a left-edge indicator. The responsive breakpoint is handled entirely in CSS with no JavaScript media queries.
The Tools Section
Renkara operates 14 internal tools that support everything from defect tracking to accounting. The tools section of the site organizes them into four groups, each with its own card grid and detail pages. This section has more moving parts than any other area of the site.
Tool Groups
The tools are organized into four functional groups. Dev & Ops includes Docket for defect tracking and Vigil for service health monitoring. Marketing & Comms covers Beacon for AI-driven marketing, Herald for newsletter management, and Pulse for privacy-first web analytics. Finance holds Meridian for time tracking and invoicing, and Trellis for double-entry bookkeeping. Productivity rounds out the set with Cadence, Courier, Narrative, Slate, Packed, Dossier, and Fulcrum.
Each tool card on the main tools page shows the tool's icon, name, and a one-line description. Clicking through leads to a detail page with a full description, feature list, and a screenshot gallery.
Theme-Aware Screenshot Galleries
Every tool detail page includes a gallery of screenshots captured in both light and dark mode. The screenshots swap automatically when the user toggles the site theme. This is handled by a data-theme-img attribute on each image element, with data-light and data-dark attributes pointing to the respective PNG files. A small JavaScript observer watches the data-theme attribute on the document root and swaps the image src accordingly. The screenshots themselves were captured using Playwright against each tool's running frontend, populated with novel seed data generated specifically for the screenshots to avoid exposing real operational data.
Lucide Icon Generation
Each tool's icon is generated from the Lucide open-source SVG library using a single Node.js script. The script renders each tool's primary glyph (and optional accent glyph) onto a canvas at 8 different sizes: 1024px (square and rounded variants), 180px (Apple Touch), 112px (retina), 56px (thumbnail), 48px (navbar 2x), 32px (favicon), 24px (navbar), and 16px (favicon small). Each size is rendered in both light and dark theme variants. From a single configuration mapping 14 tools to their glyphs and accent colors, the script produces 224 icon variants. Every tool has its own accent color defined as a CSS custom property, ensuring visual distinction across the site.
The WebGL Hero
The hero section on the homepage uses Three.js to render a particle network visualization. 3,000 particles drift across the viewport with custom vertex and fragment shaders controlling their appearance. Connection lines draw between nearby particles, capped at 5,000 to prevent performance degradation on dense clusters.
The visualization responds to mouse movement, with particles gently repelling or attracting based on cursor proximity. It is fully theme-aware: in light mode, the palette uses navy, blue, and slate tones against a gradient background. In dark mode, deeper blues with cyan highlights take over. The palette swap happens instantly when the user toggles the theme.
Performance is a priority. The visualization checks prefers-reduced-motion and disables animation entirely for users who request it, showing a static particle arrangement instead. Three.js loads lazily from a CDN, so pages that do not use the hero (blog posts, tool pages, the timeline) never download the library. An IntersectionObserver pauses the render loop when the hero scrolls out of the viewport, dropping GPU usage to zero on pages where the user has scrolled past it.
The Design System
The visual language of renkara.com is defined entirely in CSS custom properties. The font stack pairs Plus Jakarta Sans for all body and heading text with Fira Code for inline code elements. No other fonts are loaded.
The color system is built on the Renkara brand palette: --renkara-navy (#1B2A4A) for primary text and headings, --renkara-blue (#2E6B9E) for interactive elements and accents, --renkara-slate (#5A6577) for secondary text, and --cloud-white (#F8FAFC) for backgrounds. Additional tokens cover borders, subtle backgrounds, muted text, and hover states. Each tool adds its own accent color variable (e.g., --docket-accent, --beacon-accent), allowing tool detail pages to carry their own visual identity while staying within the system.
Typography uses 8 levels, from 12px (--text-xs) through 48px (--text-4xl). Spacing follows a 4px base unit, with tokens from 4px (--space-xs) through 64px (--space-4xl). Border radii, box shadows, and transition timings all reference shared tokens. The discipline is strict: no ad-hoc hex values, no magic numbers, no one-off spacing.
Dark mode remaps every color token under [data-theme="dark"] selectors. Backgrounds invert from cloud-white to deep navy. Text inverts from navy to near-white. Borders, shadows, and subtle backgrounds all have dark counterparts. The toggle preserves the user's preference in localStorage and respects prefers-color-scheme on first visit. Because theming is pure CSS, there is no flash of wrong theme on page load. A tiny inline script in the <head> sets the attribute before the browser paints a single pixel.
The Build Pipeline
Four Node.js scripts transform source files into the deployed site. They run independently and compose into a single npm run build command.
build-timeline.js reads timeline.md, parses milestone entries with their metadata and image references, and generates the HTML for the timeline page. It handles the alternating left-right layout, tag styling, image gallery markup, and scroll-animation data attributes.
build.js is the main build script. It processes every HTML file through html-minifier-terser (collapsing whitespace, removing comments, minifying inline CSS and JS). CSS files pass through cssnano via PostCSS for full optimization. JavaScript files go through terser for compression and mangling. The output lands in a dist/ directory that mirrors the source structure.
optimize-images.js uses the sharp library to process every image on the site. PNGs are re-encoded with maximum compression. JPEGs are optimized and stripped of metadata. The script runs once after new images are added and does not run on every build, since the optimized images are committed to the repository.
generate-tool-icons.js reads a configuration object mapping each tool to its Lucide glyph, accent color, and optional secondary glyph. It renders every combination of tool, size, shape, and theme onto an HTML canvas, exports the result as a PNG, and writes it to the generated icons directory. One config object, 224 output files.
The deployment target is S3 with CloudFront in front. The dist/ directory syncs to the bucket, a CloudFront invalidation fires, and the new version is live within seconds. Staging and production are separate S3 buckets with separate CloudFront distributions, each deployed with a single npm script.
The best framework is the one you do not need. When the problem is "serve documents fast," HTML is the answer. It was the answer in 1993 and it is still the answer in 2026.
The total site weight is under 200KB for the initial page load, excluding images that load lazily. There are no node_modules in production. There is no hydration step. There is no client-side router. There is no build cache to invalidate. The site is a collection of files, and the server's only job is to hand them to you as fast as the network allows. Some things do not need to be reinvented.