> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ibbe.services/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude Skill

> Apply the ibbe brand design language (tactile, brutalist-editorial, spring-loaded) to any UI, web page, component, or layout made for ibbe or "the ibbe journal". Trigger this whenever a user asks to design, build, mock up, or code a page, card, sidebar, navbar, form, dashboard, or any visual surface "for ibbe", "in the ibbe style", or describes thick borders, hard offset shadows, cream/bone/charcoal palettes, or the Inter + JetBrains Mono pairing. Covers color tokens, type scale, spacing, shadows, the 12-column editorial grid, card/sidebar/omnibox component specs, motion physics, and three complete starter page templates.

<Info>
  You can download the raw markdown file here: [Download SKILL.md](https://apac-southern-primary-static-delivery-zone-mn.ssl.media.assets.ibbe.cloud/design/SKILL%20\(2\).md)
</Info>

# ibbe design system

ibbe builds interfaces that feel like physical objects on a desk: thick charcoal borders, hard offset shadows, a spring-loaded snap when you touch anything. Every surface should read as deliberate and tactile rather than soft or corporate. Color stays restrained (cream and bone cover most of the canvas) so the personality lives in shape and motion rather than decoration. When a choice feels generic or safe, push toward the version with more weight, more contrast, or more attitude.

## Contents

1. Token cheat sheet
2. Color
3. Typography
4. Spacing
5. Borders, radius, shadow (the physics)
6. CSS variables and Tailwind config
7. Components: cards, sticker, sidebar, omnibox
8. Layout patterns: the editorial grid, the dossier layout
9. Starter templates: home page, article page, omnibox demo

## 1. Token cheat sheet

Use these everywhere. Treat them as fixed; resist adding new hex values for "visual interest".

**Color**

| token    | hex       | role                                  |
| -------- | --------- | ------------------------------------- |
| cream    | `#F7F2E9` | page background, dominant neutral     |
| bone     | `#FFF9F0` | card surfaces, sidebars, app shells   |
| charcoal | `#1D1D1F` | text, borders, dark fills             |
| gray     | `#8E8E93` | secondary text, meta, disabled        |
| line     | `#E8E2D8` | hairline dividers, thin borders       |
| blue     | `#2962FF` | primary CTA, links, tech/info accents |
| green    | `#28C76F` | success, online, positive             |
| red      | `#FF453A` | danger, delete, alerts                |
| yellow   | `#FFD60A` | ops/visual category accent, stickers  |

Cream and bone together should cover roughly 80% of any screen.

**Type:** Inter (400 to 800) for voice, JetBrains Mono for data (timestamps, IDs, nav labels, buttons, code).

**Spacing:** 8px base unit; common stops are 4, 8, 12, 16, 24, 32px.

**Shape:** structural borders 3px solid charcoal; inner borders/active states 2px solid charcoal; dividers 1px solid `line`. Outer containers (cards) round to 16px, inner elements (buttons, inputs) round to 12px, tags/pills snap sharp to 4px.

**Motion:** every hover and click moves the element on `cubic-bezier(0.25, 0.8, 0.25, 1)` while the shadow grows or shrinks, simulating an object lifting off or pressing into the page.

## 2. Color

### Foundations

| token    | hex       | rgb           | usage                                               |
| -------- | --------- | ------------- | --------------------------------------------------- |
| cream    | `#F7F2E9` | 247, 242, 233 | page background, dominant neutral, canvas           |
| bone     | `#FFF9F0` | 255, 249, 240 | card surfaces, sidebars, app shells                 |
| charcoal | `#1D1D1F` | 29, 29, 31    | text, borders, dark fills, ink                      |
| gray     | `#8E8E93` | 142, 142, 147 | secondary text, disabled states, placeholders, meta |
| line     | `#E8E2D8` | 232, 226, 216 | hairline dividers, thin borders, stone              |

### Semantic accents

| token  | hex       | rgb          | usage                                                       |
| ------ | --------- | ------------ | ----------------------------------------------------------- |
| blue   | `#2962FF` | 41, 98, 255  | primary CTA, links, tech/info category                      |
| green  | `#28C76F` | 40, 199, 111 | success, online status, positive action, updates category   |
| red    | `#FF453A` | 255, 69, 58  | danger, end call, delete, alert/culture category            |
| yellow | `#FFD60A` | 255, 214, 10 | ops/visuals category, sticker backgrounds, highlight blocks |

### Rules

Cream and bone act as neutral partners and should fill roughly 80% of any interface; layer them intentionally rather than randomly (cream for outer canvas, bone for the surfaces sitting on top of it). Charcoal on bone is the default text pairing and clears WCAG AA at every size used in this system. Color carries meaning: green always reads as "go", red always reads as "stop", blue always reads as "primary action or tech", yellow always reads as "ops or visual category". Gradients, soft pastel blues, or extra hexes added for visual interest sit outside the palette; resist them and push personality into shape and motion instead.

## 3. Typography

**Font pairing:** Inter for voice (headlines, body, UI labels), JetBrains Mono for data (timestamps, IDs, navigation labels, buttons, code). System fallback for Inter: `-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif`.

### General UI scale

Use this scale for app-like surfaces: dashboards, settings, forms, sidebars, modals.

| level   | size | weight | line-height | usage                        |
| ------- | ---- | ------ | ----------- | ---------------------------- |
| h1      | 32px | 800    | 1.1         | page titles, major headings  |
| h2      | 28px | 700    | 1.2         | section titles               |
| h3      | 24px | 700    | 1.3         | card titles, subsections     |
| h4      | 20px | 700    | 1.3         | minor headings               |
| body    | 16px | 400    | 1.5         | main text, paragraphs        |
| sm-text | 15px | 400    | 1.5         | secondary text, descriptions |
| label   | 13px | 600    | 1.4         | form labels, badges, hints   |
| xs-text | 11px | 600    | 1.4         | timestamps, metadata         |

### Editorial scale

Use this scale for content/reading surfaces: the Journal home feed, article pages, hero blocks.

| role       | family         | weight | size (desktop) | letter-spacing | usage                        |
| ---------- | -------------- | ------ | -------------- | -------------- | ---------------------------- |
| Display XL | Inter          | 800    | 56px           | -2.0px         | hero headlines               |
| Display L  | Inter          | 800    | 32px           | -1.0px         | section headers              |
| Heading M  | Inter          | 700    | 24px           | -0.5px         | card titles                  |
| Body Copy  | Inter          | 400    | 16px           | 0px            | article excerpts, paragraphs |
| Mono Bold  | JetBrains Mono | 700    | 12px           | 0px            | navigation, buttons          |
| Mono Meta  | JetBrains Mono | 500    | 11px           | 0.5px          | dates, authors, IDs          |

### Rules

Headers carry weight 700 or above to signal hierarchy at a glance; body copy stays at weight 400 for readability. Line-height runs generous for reading text (1.5 or higher) and tight for headings (around 1.1). UI labels (buttons, nav items, tags) typically render in lowercase rather than title case or caps; headings are the exception and can run in their natural case. Large headings tighten with negative letter-spacing per the tables above. Body text holds a 15px floor across the whole system. Inter ships without italic weights, so italics stay absent entirely. ALL CAPS stays reserved for JetBrains Mono / technical contexts (timestamps, IDs, nav chips) rather than headline text. Mixing in a third typeface, anywhere, sits outside the system: Inter and JetBrains Mono are the complete set.

## 4. Spacing

8px base unit. Every margin, padding, and gap in the system resolves to one of these stops.

| token        | value | usage                                              |
| ------------ | ----- | -------------------------------------------------- |
| `--space-1`  | 1px   | hairlines, borders                                 |
| `--space-2`  | 2px   | micro spacing                                      |
| `--space-4`  | 4px   | icon padding, tight spacing                        |
| `--space-6`  | 6px   | input padding                                      |
| `--space-8`  | 8px   | small gaps, button padding                         |
| `--space-12` | 12px  | medium gaps                                        |
| `--space-16` | 16px  | standard padding                                   |
| `--space-20` | 20px  | large sections                                     |
| `--space-24` | 24px  | section separation, card padding, card-to-card gap |
| `--space-32` | 32px  | major breaks, card padding on dense layouts        |

Card interiors typically use 24px to 48px of padding so type has room to breathe; the gap between cards in a grid is usually 24px or 32px.

## 5. Borders, radius, shadow (the physics)

### Borders

| name             | value               | usage                                      |
| ---------------- | ------------------- | ------------------------------------------ |
| structural       | `3px solid #1D1D1F` | cards, sidebar, top bar, outer containers  |
| internal divider | `1px solid #E8E2D8` | between list items, meta sections, footers |
| active           | `2px solid #1D1D1F` | focused inputs, active nav links           |

### Radius

| scope                            | value                                                               |
| -------------------------------- | ------------------------------------------------------------------- |
| outer containers (cards)         | 16px                                                                |
| inner elements (buttons, inputs) | 12px                                                                |
| tags / pills                     | 4px (sharp, deliberately the odd one out next to the rounded cards) |

### Shadow and the tactile hover

Shadows sit hard and offset, never soft or blurred, and they shrink or grow to suggest the object lifting toward the cursor or pressing down on click.

```css theme={null}
--ease-snap: cubic-bezier(0.25, 0.8, 0.25, 1);
--duration-fast: 200ms;
--duration-medium: 400ms;

/* Rest */
transform: translate(0, 0);
box-shadow: 6px 6px 0px var(--charcoal);

/* Hover: lifts up and away from the page */
transform: translate(-2px, -2px);
box-shadow: 8px 8px 0px var(--charcoal);

/* Active / click: presses down into the page */
transform: translate(2px, 2px);
box-shadow: 2px 2px 0px var(--charcoal);
```

Apply the snap curve to every layout transition, hover state, and movement; a linear or ease-in-out transition reads as generic and breaks the tactile feel. A clickable element that only swaps color on hover is missing the system's core interaction; it should also move.

### Entrance choreography

Content enters staggered rather than all at once, especially in a grid:

```css theme={null}
@keyframes enter-up {
  0% { opacity: 0; transform: translateY(20px); }
  100% { opacity: 1; transform: translateY(0); }
}
/* apply animation-delay: calc(var(--index) * 100ms) to grid items */
```

## 6. CSS variables and Tailwind config

```css theme={null}
:root {
  --cream: #F7F2E9;
  --bone: #FFF9F0;
  --charcoal: #1D1D1F;
  --gray: #8E8E93;
  --line: #E8E2D8;
  --blue: #2962FF;
  --green: #28C76F;
  --red: #FF453A;
  --yellow: #FFD60A;
  --border-thick: 3px;
  --border-thin: 1px;
  --radius-outer: 16px;
  --radius-inner: 12px;
  --radius-tag: 4px;
  --shadow: 6px 6px 0px var(--charcoal);
  --shadow-hover: 8px 8px 0px var(--charcoal);
  --shadow-active: 2px 2px 0px var(--charcoal);
  --ease-snap: cubic-bezier(0.25, 0.8, 0.25, 1);
}
```

```js theme={null}
theme: {
  extend: {
    colors: {
      cream: '#F7F2E9',
      bone: '#FFF9F0',
      charcoal: '#1D1D1F',
      gray: '#8E8E93',
      line: '#E8E2D8',
      brandBlue: '#2962FF',
      brandGreen: '#28C76F',
      brandRed: '#FF453A',
      brandYellow: '#FFD60A',
    },
    fontFamily: {
      sans: ['Inter', 'sans-serif'],
      mono: ['JetBrains Mono', 'monospace'],
    },
    boxShadow: {
      tactile: '6px 6px 0px #1D1D1F',
      'tactile-hover': '8px 8px 0px #1D1D1F',
      'tactile-active': '2px 2px 0px #1D1D1F',
    },
    borderWidth: { '3': '3px' },
    transitionTimingFunction: { snap: 'cubic-bezier(0.25, 0.8, 0.25, 1)' },
  },
}
```

## 7. Components

### The Journal Card family

Every card shares the same base, then a variant decides its grid span and internal layout.

```css theme={null}
.card {
  background: var(--cream);
  border: 3px solid var(--charcoal);
  border-radius: 16px;
  box-shadow: 6px 6px 0px var(--charcoal);
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
  transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);
  cursor: pointer;
}
.card:hover {
  transform: translate(-2px, -2px);
  box-shadow: 8px 8px 0px var(--charcoal);
  z-index: 5;
}
.card-body { padding: 24px; display: flex; flex-direction: column; height: 100%; }
.card-meta {
  font-family: 'JetBrains Mono';
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--charcoal); }
.dot.blue { background: var(--blue); }
.dot.red { background: var(--red); }
.dot.green { background: var(--green); }
.dot.yellow { background: var(--yellow); }
.card-headline { font-size: 24px; font-weight: 800; line-height: 1.1; letter-spacing: -0.5px; margin: 0 0 12px; }
.card-text { font-size: 15px; line-height: 1.5; color: #444; margin-bottom: 20px; }
.card-footer {
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-family: 'JetBrains Mono';
  font-size: 11px;
  color: var(--gray);
  display: flex;
  justify-content: space-between;
}
```

Anatomy, regardless of variant: a colored status dot plus uppercase mono category label up top, an extra-bold tight-line-height headline, a 15px gray-toned excerpt, and a footer separated by a hairline that carries a doc ID, read time, byline, or call-to-action arrow.

**Variants and grid spans** (assumes a 12-column grid; see section 8)

| variant       | span           | notes                                                                                                                                                                           |
| ------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| hero-card     | 8 cols, 2 rows | charcoal background, bone text; splits into a text half and a `hero-visual` half (a solid-color block, often `--blue`, holding a large icon or graphic); headline jumps to 48px |
| list-card     | 4 cols, 2 rows | bone background; holds a stack of `.list-item` rows (title + mono meta date), each separated by a 1px line divider, with a "view archive" link pinned to the bottom             |
| standard-card | 4 cols         | the default card; can host a `.sticker` in the top-right corner for emphasis                                                                                                    |
| wide-card     | 6 cols         | lays its body out horizontally (`flex-direction: row`) so text sits beside a secondary block, e.g. a download chip                                                              |
| visual-card   | 4 cols         | solid `--yellow` background, centered content, used for film/photo/illustration-led entries rather than text excerpts                                                           |

### The Sticker

A small rotated tag that reads as a physical label slapped on top of a card, used to flag something as essential, new, or featured.

```css theme={null}
.sticker {
  position: absolute;
  top: 12px;
  right: 12px;
  background: var(--red);
  color: white;
  padding: 4px 10px;
  font-family: 'JetBrains Mono';
  font-size: 10px;
  font-weight: 700;
  transform: rotate(15deg);
  border: 2px solid var(--charcoal);
  box-shadow: 2px 2px 0px rgba(0,0,0,0.2);
  z-index: 10;
}
```

Keep the rotation between 10 and 15 degrees; anything flatter loses the "physically stuck on" feeling.

### The Sticky Sidebar

Acts as the table of contents or admin control panel for a page. Stays pinned while the canvas beside it scrolls.

```css theme={null}
.sidebar {
  background: var(--cream);
  border-right: 3px solid var(--charcoal);
  padding: 32px 24px;
  position: sticky;
  top: 60px;
  height: calc(100vh - 60px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.menu-link {
  display: flex;
  justify-content: space-between;
  padding: 10px 12px;
  margin-bottom: 4px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 600;
  border: 1px solid transparent;
  transition: all 0.1s;
}
.menu-link:hover { background: var(--bone); border-color: var(--charcoal); transform: translateX(4px); }
.menu-link.active { background: var(--charcoal); color: var(--bone); box-shadow: 3px 3px 0px rgba(0,0,0,0.2); }
```

The active state inverts to a charcoal fill with bone text, paired with a small offset shadow, rather than a simple underline or color swap. Group links under uppercase mono section headers (e.g. "THE FOUNDATION", "THE ECOSYSTEM") with a count badge at the end of each row.

### The Omnibox (URL-bar style nav)

A search/nav field styled like a browser address bar: pill-shaped and centered at rest, expanding into a left-aligned input with a suggestions dropdown on focus.

```css theme={null}
.omnibox-input {
  width: 100%;
  background: rgba(255,255,255,0.1);
  border: 2px solid transparent;
  border-radius: 50px;
  padding: 10px 20px;
  color: var(--bone);
  text-align: center;
  transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);
  outline: none;
}
.omnibox-input:focus {
  background: var(--bone);
  color: var(--charcoal);
  border-color: var(--blue);
  text-align: left;
  box-shadow: 0px 10px 30px rgba(0,0,0,0.3);
  border-radius: 12px 12px 0 0;
}
.omnibox-suggestions {
  position: absolute;
  top: 100%; left: 0; right: 0;
  background: var(--bone);
  border: 2px solid var(--blue);
  border-top: none;
  border-radius: 0 0 12px 12px;
  display: none;
}
.omnibox-input:focus + .omnibox-suggestions { display: block; }
```

Behavior: centered pill text at rest reads as a calm "url", and focus snaps it open into an active search field with a dropdown of path suggestions. The full markup, plus the focus/blur JS that drives the placeholder swap, sits in the omnibox demo template in section 9.

## 8. Layout patterns

### The editorial grid ("the desk")

Listing and home pages use a 12-column asymmetric grid rather than a uniform card grid; the asymmetry (one big hero, a tall list beside it, then a mix of standard/wide/visual cards) is what makes the page feel like a curated desk rather than a generic feed.

```css theme={null}
.layout-wrapper {
  display: grid;
  grid-template-columns: 260px 1fr; /* sidebar | canvas */
  min-height: 100vh;
}
.canvas {
  padding: 48px;
  background: var(--bone);
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-auto-rows: minmax(100px, auto);
  gap: 24px;
}
```

Span guide:

* Hero content: 8 columns, 2 rows.
* Lists / tall sidebars-within-the-grid: 4 columns, 2 rows.
* Standard cards: 4 columns.
* Wide cards: 6 columns.
* Visual/featured cards: 4 or 6 columns.

Order matters as much as span: open with the hero plus its companion list card, then alternate standard, wide, and visual cards so no two same-width cards sit back to back for more than a pair.

Responsive: around 1200px the hero collapses to the full 12 columns and drops its side visual; list and standard cards step down to 6-column halves. Below about 900px, the sidebar drops out of the flow entirely and the canvas switches from a grid to a single flex column, with cards stacking full-width.

### The dossier layout (article / detail pages)

Three columns at full width: a sticky left rail for the title and meta, a centered reading column, and a right rail of "marginalia" notes.

```css theme={null}
.dossier-grid {
  display: grid;
  grid-template-columns: 350px 1fr 280px; /* title/nav | content | marginalia */
  max-width: 1920px;
  margin: 0 auto;
}
.col-left { position: sticky; top: 53px; height: calc(100vh - 53px); border-right: 3px solid var(--charcoal); }
.col-center { padding: 80px 60px; border-right: 1px solid var(--line); }
.article-body { max-width: 680px; margin: 0 auto; font-size: 18px; line-height: 1.6; }
.col-right { display: flex; flex-direction: column; gap: 32px; padding: 40px 24px; }
```

**Left rail:** a back link, the category chip, a large (48px, tight line-height) title, a short deck line, an author/date/ID meta block, and a reading-progress bar pinned toward the bottom of the rail.

**Center column:** the article body itself, capped at 680px for line length. The first paragraph gets a drop-cap treatment that matches the tactile system rather than a plain serif drop-cap:

```css theme={null}
.article-body > p:first-of-type::first-letter {
  float: left;
  font-weight: 800;
  font-size: 80px;
  line-height: 0.8;
  margin-right: 16px;
  border: 3px solid var(--charcoal);
  padding: 8px 12px;
  background: var(--yellow);
  box-shadow: 4px 4px 0px var(--charcoal);
  transform: rotate(-2deg);
}
```

H2s inside the body get a soft translucent highlight bar behind the text via a `::after` pseudo-element rather than a simple underline, and list items swap their bullet for a bold arrow (`â†’`) in `--blue`.

**Right rail (marginalia):** a mix of definition boxes (term plus short description, framed by two horizontal rules), small rotated "note cards" (sticky-note styling: cream background, 2px border, hard offset shadow, a slight rotation, a colored uppercase label like "TECHNICAL NOTE"), and an occasional yellow "key takeaway" card pulling out a pull-quote-style line from the piece.

Responsive: around 1300px the grid drops to two columns (`350px 1fr`) and the marginalia rail steps out of the flow; below 900px it collapses to a single column, with the left rail becoming a normal (non-sticky) block above the article body.

## 9. Starter templates

Three complete, copy-pasteable pages. Start from these rather than building a layout from scratch when the task is a full page; pull single components out of them when the task is smaller.

### Home / listing page

```html theme={null}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ibbe journal / chaos documented</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root {
  --cream: #F7F2E9;
  --bone: #FFF9F0;
  --charcoal: #1D1D1F;
  --gray: #8E8E93;
  --blue: #2962FF;
  --green: #28C76F;
  --red: #FF453A;
  --yellow: #FFD60A;
  --border-thick: 3px;
  --border-thin: 1px;
  --radius: 12px;
  --shadow: 6px 6px 0px var(--charcoal);
  --shadow-hover: 2px 2px 0px var(--charcoal);
}
* { box-sizing: border-box; }
body { margin: 0; padding: 0; background-color: var(--cream); font-family: 'Inter', sans-serif; color: var(--charcoal); overflow-x: hidden; }
a { text-decoration: none; color: inherit; }
.url-bar { background: var(--charcoal); color: var(--bone); padding: 14px 24px; font-family: 'JetBrains Mono', monospace; font-size: 12px; display: flex; align-items: center; justify-content: space-between; border-bottom: var(--border-thick) solid var(--charcoal); position: sticky; top: 0; z-index: 999; }
.url-input { background: rgba(255,255,255,0.15); padding: 8px 16px; border-radius: 50px; width: 400px; max-width: 100%; text-align: center; display: flex; align-items: center; justify-content: center; gap: 8px; margin: 0 auto; }
.traffic-lights { display: flex; gap: 8px; }
.light { width: 10px; height: 10px; border-radius: 50%; }
.layout-wrapper { display: grid; grid-template-columns: 260px 1fr; min-height: 100vh; max-width: 1920px; margin: 0 auto; }
.sidebar { background: var(--cream); border-right: var(--border-thick) solid var(--charcoal); padding: 32px 24px; position: sticky; top: 60px; height: calc(100vh - 60px); overflow-y: auto; display: flex; flex-direction: column; }
.brand { font-size: 32px; font-weight: 800; letter-spacing: -1px; margin-bottom: 40px; padding-bottom: 20px; border-bottom: 2px solid #E8E2D8; }
.menu-section { margin-bottom: 32px; }
.menu-header { font-family: 'JetBrains Mono', monospace; font-size: 10px; text-transform: uppercase; color: var(--gray); margin-bottom: 12px; letter-spacing: 1px; font-weight: 700; }
.menu-link { display: flex; justify-content: space-between; padding: 10px 12px; margin-bottom: 4px; border-radius: 6px; font-size: 14px; font-weight: 600; transition: all 0.1s; border: 1px solid transparent; }
.menu-link:hover { background: var(--bone); border-color: var(--charcoal); transform: translateX(4px); }
.menu-link.active { background: var(--charcoal); color: var(--bone); box-shadow: 3px 3px 0px rgba(0,0,0,0.2); }
.count { font-family: 'JetBrains Mono'; font-size: 11px; opacity: 0.6; }
.canvas { padding: 48px; background: var(--bone); display: grid; grid-template-columns: repeat(12, 1fr); grid-auto-rows: minmax(100px, auto); gap: 24px; }
.card { background: var(--cream); border: var(--border-thick) solid var(--charcoal); border-radius: var(--radius); box-shadow: var(--shadow); display: flex; flex-direction: column; position: relative; overflow: hidden; transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1); cursor: pointer; }
.card:hover { transform: translate(-2px, -2px); box-shadow: 8px 8px 0px var(--charcoal); z-index: 5; }
.card-body { padding: 24px; display: flex; flex-direction: column; height: 100%; }
.card-meta { font-family: 'JetBrains Mono'; font-size: 11px; font-weight: 700; color: var(--charcoal); text-transform: uppercase; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
.dot { width: 8px; height: 8px; background: var(--charcoal); border-radius: 50%; }
.dot.blue { background: var(--blue); }
.dot.red { background: var(--red); }
.dot.green { background: var(--green); }
.dot.yellow { background: var(--yellow); }
.card-headline { font-size: 24px; font-weight: 800; line-height: 1.1; margin: 0 0 12px 0; letter-spacing: -0.5px; }
.card-text { font-size: 15px; line-height: 1.5; color: #444; margin-bottom: 20px; }
.card-footer { margin-top: auto; padding-top: 16px; border-top: 1px solid #E8E2D8; font-family: 'JetBrains Mono'; font-size: 11px; color: var(--gray); display: flex; justify-content: space-between; }
.hero-card { grid-column: span 8; grid-row: span 2; background: var(--charcoal); color: var(--bone); display: grid; grid-template-columns: 1fr 1fr; }
.hero-card .card-body { color: var(--bone); justify-content: center; padding: 48px; }
.hero-card .card-headline { font-size: 48px; margin-bottom: 24px; }
.hero-card .card-text { color: #ccc; font-size: 18px; max-width: 90%; }
.hero-card .card-meta { color: var(--green); }
.hero-visual { background: var(--blue); border-left: var(--border-thick) solid var(--bone); display: flex; align-items: center; justify-content: center; font-size: 120px; }
.list-card { grid-column: span 4; grid-row: span 2; background: var(--bone); }
.list-item { padding: 16px 0; border-bottom: 1px solid #E8E2D8; }
.list-item:last-child { border-bottom: none; }
.list-title { font-weight: 700; font-size: 15px; margin-bottom: 4px; display: block; }
.list-date { font-family: 'JetBrains Mono'; font-size: 10px; color: var(--gray); }
.standard-card { grid-column: span 4; }
.wide-card { grid-column: span 6; }
.visual-card { grid-column: span 4; background: var(--yellow); color: var(--charcoal); display: flex; align-items: center; justify-content: center; text-align: center; padding: 32px; }
.visual-card h3 { font-size: 32px; font-weight: 800; }
.sticker { position: absolute; top: 12px; right: 12px; background: var(--red); color: white; padding: 4px 10px; font-family: 'JetBrains Mono'; font-size: 10px; font-weight: 700; transform: rotate(15deg); border: 2px solid var(--charcoal); box-shadow: 2px 2px 0px rgba(0,0,0,0.2); }
@media (max-width: 1200px) { .hero-card { grid-column: span 12; grid-template-columns: 1fr; } .hero-visual { display: none; } .list-card { grid-column: span 6; } .standard-card { grid-column: span 6; } }
@media (max-width: 900px) { .layout-wrapper { grid-template-columns: 1fr; } .sidebar { display: none; } .canvas { padding: 24px; display: flex; flex-direction: column; gap: 24px; } }
</style>
</head>
<body>
<nav class="url-bar">
  <div class="traffic-lights">
    <div class="light" style="background:#FF5F56"></div>
    <div class="light" style="background:#FFBD2E"></div>
    <div class="light" style="background:#27C93F"></div>
  </div>
  <div class="url-input"><span>ðŸ”’</span><span>journal.ibbe.in</span></div>
  <div style="font-family: 'JetBrains Mono'; font-weight: 700;">LOGIN_DISABLED</div>
</nav>
<div class="layout-wrapper">
  <aside class="sidebar">
    <div class="brand">ibbe.</div>
    <div class="menu-section">
      <div class="menu-header">The Foundation</div>
      <a href="#" class="menu-link active"><span>Core Philosophy</span><span class="count">03</span></a>
      <a href="#" class="menu-link"><span>Education &amp; Learning</span><span class="count">12</span></a>
      <a href="#" class="menu-link"><span>Leadership</span><span class="count">08</span></a>
    </div>
    <div class="menu-section">
      <div class="menu-header">The Ecosystem</div>
      <a href="#" class="menu-link"><span>Community &amp; Culture</span><span class="count">24</span></a>
      <a href="#" class="menu-link"><span>Startups</span><span class="count">05</span></a>
      <a href="#" class="menu-link"><span>Universe Updates</span><span class="count">99</span></a>
    </div>
    <div class="menu-section">
      <div class="menu-header">Deep Dives</div>
      <a href="#" class="menu-link"><span>Research</span><span class="count">14</span></a>
      <a href="#" class="menu-link"><span>Events</span><span class="count">02</span></a>
    </div>
    <div style="margin-top: auto; font-size: 11px; color: var(--gray); line-height: 1.5;">System: Normal<br>Uptime: 99.9%<br>Coffee: 0%</div>
  </aside>
  <main class="canvas">
    <article class="card hero-card">
      <div class="card-body">
        <div class="card-meta"><span class="dot green"></span> TECHNOLOGY &amp; SYSTEMS</div>
        <h1 class="card-headline">The Walled Garden Has a Hole In It.</h1>
        <p class="card-text">Google just taught Android to speak "AirDrop." Apple didn't open the door; Google picked the lock. A breakdown of AWDL, Rust, and the end of the Green Bubble era.</p>
        <div class="card-footer" style="border-color: rgba(255,255,255,0.2); color: #888;"><span>READ TIME: 4 MIN</span><span>BY CTO OFFICE</span></div>
      </div>
      <div class="hero-visual"><svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"></path></svg></div>
    </article>
    <div class="card list-card">
      <div class="card-body">
        <div class="card-headline" style="font-size: 20px; margin-bottom: 24px;">Quick Dispatches</div>
        <div class="list-item"><span class="list-title">Server migration complete (mostly)</span><span class="list-date">UNIVERSE UPDATES â€¢ 2H AGO</span></div>
        <div class="list-item"><span class="list-title">Why we stopped using "Please" in UI copy</span><span class="list-date">CORE PHILOSOPHY â€¢ YESTERDAY</span></div>
        <div class="list-item"><span class="list-title">Recap: The Jaipur Education Summit</span><span class="list-date">EVENTS â€¢ 2 DAYS AGO</span></div>
        <div class="list-item"><span class="list-title">New compliance vault protocols live</span><span class="list-date">OPERATIONS â€¢ 3 DAYS AGO</span></div>
        <div style="margin-top: auto; text-align: center; padding-top: 12px;"><a href="#" style="font-size: 12px; font-weight: 700; text-decoration: underline;">VIEW ARCHIVE -&gt;</a></div>
      </div>
    </div>
    <article class="card standard-card">
      <div class="sticker">ESSENTIAL</div>
      <div class="card-body">
        <div class="card-meta"><span class="dot yellow"></span> OPERATIONS</div>
        <h3 class="card-headline">The Art of the Checklist</h3>
        <p class="card-text">System design isn't sexy, until it saves the project. Notes from the Compliance Vault.</p>
        <div class="card-footer"><span>DOC ID: #8492</span><span>â†’</span></div>
      </div>
    </article>
    <article class="card standard-card">
      <div class="card-body">
        <div class="card-meta"><span class="dot red"></span> CORE PHILOSOPHY</div>
        <h3 class="card-headline">We Don't Do "Nice."</h3>
        <p class="card-text">Politeness is often a disguise for lack of clarity. Thick borders are a form of respect.</p>
        <div class="card-footer"><span>READ REFLECTION</span><span>â†’</span></div>
      </div>
    </article>
    <article class="card visual-card">
      <div>
        <div class="card-meta" style="justify-content: center; margin-bottom: 8px;">HANDS THAT BUILT HOME</div>
        <h3 style="line-height: 1;">THE<br>WEAVER'S<br>TALE</h3>
        <div style="margin-top: 16px; font-size: 12px; font-weight: 700; border: 2px solid var(--charcoal); padding: 8px 16px; display: inline-block; border-radius: 50px; background: var(--cream);">WATCH FILM</div>
      </div>
    </article>
    <article class="card wide-card">
      <div class="card-body" style="flex-direction: row; align-items: center; gap: 32px;">
        <div style="flex: 1;">
          <div class="card-meta"><span class="dot blue"></span> RESEARCH &amp; ANALYSIS</div>
          <h3 class="card-headline">The Future of Pedagogy: Skill-Based Models</h3>
          <p class="card-text">An internal whitepaper contrasting 19th-century rote memorization with 21st-century convergence models.</p>
        </div>
        <div style="background: var(--charcoal); color: var(--bone); padding: 20px; border-radius: 8px; font-family: 'JetBrains Mono'; font-size: 12px; text-align: center;">DOWNLOAD<br>PDF<br>(4.2 MB)</div>
      </div>
    </article>
    <article class="card standard-card">
      <div class="card-body">
        <div class="card-meta"><span class="dot green"></span> FROM THE FIELD</div>
        <h3 class="card-headline">"I walked 10km for a PDF."</h3>
        <p class="card-text">Real experiences from rural partners. This is why we optimize for low bandwidth.</p>
        <div class="card-footer"><span>READ STORY</span><span>â†’</span></div>
      </div>
    </article>
  </main>
</div>
</body>
</html>
```

### Article / dossier page

```html theme={null}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>the walled garden / ibbe journal</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root { --cream: #F7F2E9; --bone: #FFF9F0; --charcoal: #1D1D1F; --gray: #8E8E93; --blue: #2962FF; --green: #28C76F; --red: #FF453A; --yellow: #FFD60A; --border-thick: 3px; --border-thin: 1px; --radius: 12px; --shadow: 6px 6px 0px var(--charcoal); }
* { box-sizing: border-box; }
body { margin: 0; padding: 0; background-color: var(--cream); font-family: 'Inter', sans-serif; color: var(--charcoal); overflow-x: hidden; }
a { text-decoration: none; color: inherit; }
.url-bar { background: var(--charcoal); color: var(--bone); padding: 14px 24px; font-family: 'JetBrains Mono', monospace; font-size: 12px; display: flex; align-items: center; justify-content: space-between; border-bottom: var(--border-thick) solid var(--charcoal); position: sticky; top: 0; z-index: 999; }
.url-input { background: rgba(255,255,255,0.15); padding: 6px 16px; border-radius: 50px; width: 300px; text-align: center; }
.dossier-grid { display: grid; grid-template-columns: 350px 1fr 280px; max-width: 1920px; margin: 0 auto; min-height: 100vh; }
.col-left { background: var(--cream); border-right: var(--border-thick) solid var(--charcoal); padding: 40px 32px; position: sticky; top: 53px; height: calc(100vh - 53px); display: flex; flex-direction: column; justify-content: space-between; }
.back-link { font-family: 'JetBrains Mono'; font-weight: 700; font-size: 12px; display: inline-flex; align-items: center; gap: 8px; margin-bottom: 40px; text-transform: uppercase; letter-spacing: 0.5px; }
.back-link:hover { color: var(--blue); }
.article-meta-hero { margin-bottom: auto; }
.hero-category { display: inline-block; font-family: 'JetBrains Mono'; font-size: 11px; background: var(--charcoal); color: var(--bone); padding: 6px 10px; border-radius: 4px; margin-bottom: 24px; }
h1 { font-size: 48px; font-weight: 800; line-height: 0.95; letter-spacing: -2px; margin: 0 0 24px 0; }
.author-block { border-top: 1px solid #E8E2D8; padding-top: 24px; margin-top: 24px; font-family: 'JetBrains Mono'; font-size: 12px; }
.progress-container { margin-top: 40px; }
.progress-label { font-size: 10px; font-weight: 700; margin-bottom: 8px; text-transform: uppercase; color: var(--gray); }
.progress-track { width: 100%; height: 4px; background: #E8E2D8; border-radius: 2px; position: relative; }
.progress-fill { width: 35%; height: 100%; background: var(--blue); border-radius: 2px; }
.col-center { background: var(--bone); padding: 80px 60px; border-right: 1px solid #E8E2D8; }
.article-body { max-width: 680px; margin: 0 auto; font-size: 18px; line-height: 1.6; color: var(--charcoal); }
p { margin-bottom: 24px; }
.article-body > p:first-of-type::first-letter { float: left; font-family: 'Inter'; font-weight: 800; font-size: 80px; line-height: 0.8; margin-right: 16px; margin-top: 8px; color: var(--charcoal); border: 3px solid var(--charcoal); padding: 8px 12px; background: var(--yellow); box-shadow: 4px 4px 0px var(--charcoal); transform: rotate(-2deg); }
h2 { font-size: 28px; font-weight: 800; margin-top: 56px; margin-bottom: 20px; letter-spacing: -1px; position: relative; display: inline-block; }
h2::after { content: ''; position: absolute; bottom: 2px; left: -4px; right: -4px; height: 8px; background: rgba(41, 98, 255, 0.15); z-index: -1; }
ul { padding-left: 0; list-style: none; }
li { position: relative; padding-left: 24px; margin-bottom: 16px; }
li::before { content: 'â†’'; position: absolute; left: 0; font-weight: 800; color: var(--blue); }
.col-right { background: var(--bone); padding: 40px 24px; display: flex; flex-direction: column; gap: 32px; }
.note-card { background: var(--cream); border: 2px solid var(--charcoal); border-radius: 8px; padding: 16px; font-size: 13px; line-height: 1.5; box-shadow: 3px 3px 0px var(--charcoal); position: sticky; top: 80px; }
.note-label { font-family: 'JetBrains Mono'; font-size: 10px; font-weight: 700; text-transform: uppercase; color: var(--red); margin-bottom: 8px; display: flex; justify-content: space-between; }
.definition-box { border-top: 2px solid var(--charcoal); border-bottom: 2px solid var(--charcoal); padding: 16px 0; }
.def-term { font-weight: 800; display: block; margin-bottom: 4px; }
.def-desc { font-size: 13px; color: #555; }
@media (max-width: 1300px) { .dossier-grid { grid-template-columns: 280px 1fr; } .col-right { display: none; } }
@media (max-width: 900px) { .dossier-grid { grid-template-columns: 1fr; } .col-left { position: relative; height: auto; border-right: none; border-bottom: var(--border-thick) solid var(--charcoal); padding-bottom: 32px; } .col-center { padding: 40px 24px; } h1 { font-size: 36px; } .article-body > p:first-of-type::first-letter { font-size: 56px; } }
</style>
</head>
<body>
<nav class="url-bar">
  <div style="display:flex; gap:6px;">
    <div style="width:10px; height:10px; border-radius:50%; background:#FF5F56;"></div>
    <div style="width:10px; height:10px; border-radius:50%; background:#FFBD2E;"></div>
    <div style="width:10px; height:10px; border-radius:50%; background:#27C93F;"></div>
  </div>
  <div class="url-input">journal.ibbe.in/post/042</div>
  <div style="font-family:'JetBrains Mono'; font-weight:700;">READ_ONLY</div>
</nav>
<div class="dossier-grid">
  <aside class="col-left">
    <div>
      <a href="#" class="back-link">â† Back to Desk</a>
      <div class="article-meta-hero">
        <span class="hero-category">TECHNOLOGY &amp; SYSTEMS</span>
        <h1>The Walled Garden Has a Hole In It.</h1>
        <div style="font-size: 18px; line-height: 1.4; color: #555; margin-top: 16px;">Google didn't break the door down. They just learned how to pick the lock.</div>
      </div>
      <div class="author-block">
        <div><strong>AUTHOR:</strong> CTO Office</div>
        <div style="margin-top:4px;"><strong>DATE:</strong> 22 Nov 2025</div>
        <div style="margin-top:4px;"><strong>ID:</strong> #TK-421</div>
      </div>
    </div>
    <div class="progress-container">
      <div class="progress-label">Reading Progress</div>
      <div class="progress-track"><div class="progress-fill"></div></div>
    </div>
  </aside>
  <main class="col-center">
    <article class="article-body">
      <p>For over a decade, the "green bubble vs blue bubble" divide defined mobile loyalty. To get seamless file sharing, you bought an iPhone. But with Google's recent announcement that <strong>Quick Share</strong> now beams files directly to <strong>AirDrop</strong>, that era has ended.</p>
      <p>Users ask: Why did Apple let this happen? Is this a security risk? Why fail to block it? The answer lies in a complex mix of "linguistic" engineering, legal checkmates, and modern tech security reality.</p>
      <h2>1. The "Break-In" as Translation</h2>
      <p>It feels like Google "picked the lock" to your house. In reality, Google learned to speak your language. The secret language is a proprietary protocol called <strong>AWDL</strong> (Apple Wireless Direct Link). It mixes Bluetooth (for "hello, I'm here") and Wi-Fi (for "here is the file").</p>
      <p>Google avoided hacking servers or stealing source code. Instead, engineers reverse-engineered the protocol. Imagine two people speaking a secret code; listen long enough, and you figure out the grammar. Google taught Android phones to "speak Apple."</p>
      <h2>2. Security: Myth vs Reality</h2>
      <p>You worry: <em>If Google gets in, who else follows?</em> But the architecture remains surprisingly robust.</p>
      <ul>
        <li><strong>No Server Vulnerability:</strong> This works as a peer-to-peer (P2P) connection. Files go directly from device to device.</li>
        <li><strong>Built with Rust:</strong> Google built this integration using Rust, a modern programming language designed to remain "memory safe".</li>
        <li><strong>Battle-Tested:</strong> Before release, Google hired NetSPI to penetration-test the feature.</li>
      </ul>
      <h2>3. The Verdict</h2>
      <p>We often think of devices as fortresses, but the future of tech looks like a public square. Google avoided breaking the wall; Google turned the wall into a door. For now, thanks to the law and legacy code complexities, Apple must leave the door open.</p>
    </article>
  </main>
  <aside class="col-right">
    <div class="definition-box">
      <span class="def-term">AWDL</span>
      <span class="def-desc">Apple Wireless Direct Link. A low-latency peer-to-peer connection protocol used for AirDrop and AirPlay.</span>
    </div>
    <div class="note-card" style="transform: rotate(1deg);">
      <div class="note-label"><span>Technical Note</span><span>!</span></div>
      <div><strong>Why Rust?</strong><br>Rust prevents "buffer overflows," which are the #1 cause of security exploits in C++ based systems.</div>
    </div>
    <div class="note-card" style="background: var(--yellow); transform: rotate(-2deg); margin-top: 40px;">
      <div class="note-label" style="color: var(--charcoal);">KEY TAKEAWAY</div>
      <div style="font-weight: 800; font-size: 16px;">"Google taught Android phones to speak Apple."</div>
    </div>
  </aside>
</div>
</body>
</html>
```

### Omnibox navbar demo

```html theme={null}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ibbe journal / omnibox demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root { --cream: #F7F2E9; --bone: #FFF9F0; --charcoal: #1D1D1F; --blue: #2962FF; --gray: #8E8E93; --border-thick: 3px; --shadow: 6px 6px 0px var(--charcoal); }
body { margin: 0; font-family: 'Inter', sans-serif; background: var(--cream); }
.nav-wrapper { background: var(--charcoal); padding: 14px 24px; border-bottom: var(--border-thick) solid var(--charcoal); position: sticky; top: 0; z-index: 1000; display: flex; justify-content: center; }
.omnibox-container { position: relative; width: 480px; max-width: 100%; font-family: 'JetBrains Mono', monospace; }
.omnibox-input { width: 100%; background: rgba(255, 255, 255, 0.1); border: 2px solid transparent; border-radius: 50px; padding: 10px 20px; color: var(--bone); font-family: inherit; font-size: 13px; text-align: center; transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1); outline: none; cursor: text; }
.omnibox-input:focus { background: var(--bone); color: var(--charcoal); border-color: var(--blue); text-align: left; box-shadow: 0px 10px 30px rgba(0,0,0,0.3); border-radius: 12px 12px 0 0; }
.omnibox-suggestions { position: absolute; top: 100%; left: 0; right: 0; background: var(--bone); border: 2px solid var(--blue); border-top: none; border-radius: 0 0 12px 12px; overflow: hidden; display: none; box-shadow: 0px 10px 30px rgba(0,0,0,0.3); }
.omnibox-input:focus + .omnibox-suggestions { display: block; }
.suggestion-item { padding: 12px 16px; display: flex; align-items: center; gap: 12px; cursor: pointer; border-bottom: 1px solid #E8E2D8; transition: background 0.1s; }
.suggestion-item:last-child { border-bottom: none; }
.suggestion-item:hover { background: #E8E2D8; }
.s-icon { font-size: 14px; opacity: 0.5; }
.s-path { font-weight: 700; color: var(--charcoal); font-size: 13px; }
.s-desc { font-size: 11px; color: var(--gray); margin-left: auto; }
.highlight { color: var(--blue); }
.traffic-lights { position: absolute; left: 24px; top: 50%; transform: translateY(-50%); display: flex; gap: 6px; }
.light { width: 10px; height: 10px; border-radius: 50%; }
</style>
</head>
<body>
<nav class="nav-wrapper">
  <div class="traffic-lights">
    <div class="light" style="background:#FF5F56"></div>
    <div class="light" style="background:#FFBD2E"></div>
    <div class="light" style="background:#27C93F"></div>
  </div>
  <div class="omnibox-container">
    <input type="text" class="omnibox-input" value="journal.ibbe.in" id="urlBar" autocomplete="off">
    <div class="omnibox-suggestions">
      <div class="suggestion-item" onclick="navigate('/tech')"><span class="s-icon">ðŸ“‚</span><span class="s-path">journal.ibbe.in/<span class="highlight">tech</span></span><span class="s-desc">Technology &amp; Systems</span></div>
      <div class="suggestion-item" onclick="navigate('/philosophy')"><span class="s-icon">âš–ï¸</span><span class="s-path">journal.ibbe.in/<span class="highlight">philosophy</span></span><span class="s-desc">Core Values</span></div>
      <div class="suggestion-item" onclick="navigate('/latest')"><span class="s-icon">ðŸ”¥</span><span class="s-path">journal.ibbe.in/<span class="highlight">latest</span></span><span class="s-desc">New Arrivals</span></div>
      <div class="suggestion-item" onclick="navigate('/search')"><span class="s-icon">ðŸ”</span><span class="s-path">journal.ibbe.in/<span class="highlight">search?q=</span></span><span class="s-desc">Type to search...</span></div>
    </div>
  </div>
</nav>
<div style="padding: 100px; text-align: center; font-family: 'Inter'; color: var(--charcoal);">
  <h1>Click the URL bar above.</h1>
  <p>It mimics a browser address bar interaction.</p>
</div>
<script>
const input = document.getElementById('urlBar');
const originalValue = "journal.ibbe.in";
input.addEventListener('focus', () => {
  if (input.value === originalValue) {
    input.value = "journal.ibbe.in/";
    setTimeout(() => { input.selectionStart = input.selectionEnd = input.value.length; }, 0);
  }
});
input.addEventListener('blur', () => {
  setTimeout(() => {
    if (input.value === "journal.ibbe.in/" || input.value === "") {
      input.value = originalValue;
      input.style.textAlign = "center";
    }
  }, 200);
});
function navigate(path) {
  input.value = "journal.ibbe.in" + path;
  alert(`Navigating to: ${path}`);
}
input.addEventListener('input', (e) => { input.style.textAlign = "left"; });
</script>
</body>
</html>
```
