← All UI styles

Book Transitional

Set like a page of a well-made book: one column, wide margins, nothing else.

BareeditorialReading and study toolsDocumentationEssays and notes

Construction · Bare

There is no surface at all — no fill, no line, no tint. Size, weight and distance are the only tools left.

Book Transitional — interface concept shot

Concept shot — generated from this style's terms, the way a designer would present it. The specimen below is the contract: rendered from the exact tokens on this page.

Every style renders this same screen, so the only thing changing between two of them is the style. The component above is the file below, running.

Prompt

Design this interface in the Book Transitional style. A transitional serif at reading size with wide margins and long line height. Chrome is removed almost entirely so the text block is the interface.

Build every surface the Bare way: There is no surface at all — no fill, no line, no tint. Size, weight and distance are the only tools left.

Use exactly these values: background #fcfbf9, surfaces #fcfbf9, text #221f1b, secondary text #635d54, accent #7a3b2e with #ffffff on it; corner radius 2/4/6px; no card borders, hairline separators only; no shadows of any kind; Baskerville for body at 16px, line height 1.7; 8px spacing grid, generous breathing room.

Never: sans-serif body text; cards and panels; tight leading; colored surfaces.

Dark mode uses background #111010, surfaces #161514, text #f0ece5, accent #d98c74 — the same style, not an inverted one.

The numbers in this prompt are printed from the tokens below, so it cannot drift from what the specimen renders.

What carries the look

  • transitional serif
  • wide margins
  • long line height
  • no chrome

What this style refuses

  • sans-serif body text
  • cards and panels
  • tight leading
  • colored surfaces

The refusals are the half that keeps generated interfaces from converging — a prompt that only says what to add gets the default look.

Tokens

Palette

RoleLightDark
Background#fcfbf9#111010
Surface#fcfbf9#161514
Border#e0dcd4#2c2926
Text#221f1b#f0ece5
Muted text#635d54#a29b91
Accent#7a3b2e#d98c74
On accent#ffffff#1c0d08

Shape and type

Radius2 / 4 / 6 px
Bordernone
Shadownone
DisplayBaskerville
BodyBaskerville
MonoCourier New
Type scale11 · 13 · 16 · 18 · 23 · 31 px
Weights400 / 600 / 600
Line height1.7
Tracking0em
Spacing8px grid · roomy
Surfaceflat
Accentunderline
Separatorhairline
Labelssentence case
Blurnone

Measured contrast — body 15.87:1 light, 16.13:1 dark; secondary text 6.3:1 and 6.91:1. Every pair clears WCAG AA in both themes, checked on each build.

Specimen · Specimen.tsx

import type { CSSProperties } from "react";

/**
 * Vibary · Book Transitional
 *
 * Set like a page of a well-made book: one column, wide margins, nothing else.
 *
 * One complete product screen, rendered from the token object below —
 * the same screen every other Vibary specimen renders, so the style
 * is the only variable. Self-contained: React only, no CSS file, no
 * assets, no chart library.
 *
 * `theme` defaults to following the system setting; pass "light" or
 * "dark" to pin one.
 */

export const TOKENS = {
  "material": "bare",
  "color": {
    "light": {
      "bg": "#fcfbf9",
      "surface": "#fcfbf9",
      "border": "#e0dcd4",
      "text": "#221f1b",
      "muted": "#635d54",
      "accent": "#7a3b2e",
      "accentText": "#ffffff"
    },
    "dark": {
      "bg": "#111010",
      "surface": "#161514",
      "border": "#2c2926",
      "text": "#f0ece5",
      "muted": "#a29b91",
      "accent": "#d98c74",
      "accentText": "#1c0d08"
    }
  },
  "radius": {
    "sm": 2,
    "md": 4,
    "lg": 6,
    "pill": 999
  },
  "border": {
    "width": 0,
    "style": "none"
  },
  "shadow": {
    "level": "none",
    "value": "none"
  },
  "type": {
    "family": {
      "display": "Baskerville, \"Libre Baskerville\", Georgia, serif",
      "body": "Baskerville, \"Libre Baskerville\", Georgia, serif",
      "mono": "\"Courier New\", Courier, \"Nimbus Mono PS\", monospace"
    },
    "scale": [
      11,
      13,
      16,
      18,
      23,
      31
    ],
    "weight": {
      "body": 400,
      "strong": 600,
      "display": 600
    },
    "lineHeight": 1.7,
    "tracking": 0
  },
  "space": {
    "unit": 8,
    "density": "roomy"
  },
  "effects": {
    "surface": "flat",
    "accentStyle": "underline",
    "separator": "hairline",
    "labelCase": "none",
    "blur": 0
  }
};

type Palette = typeof TOKENS.color.light;

export type BookTransitionalSpecimenProps = {
  theme?: "system" | "light" | "dark";
  /** Scopes the custom properties; only matters if you render two. */
  scope?: string;
};

function vars(palette: Palette): string {
  return [
    `--sp-bg: ${palette.bg}`,
    `--sp-surface: ${palette.surface}`,
    `--sp-border: ${palette.border}`,
    `--sp-text: ${palette.text}`,
    `--sp-muted: ${palette.muted}`,
    `--sp-accent: ${palette.accent}`,
    `--sp-accent-text: ${palette.accentText}`,
  ].join("; ");
}

/** Fixed content: identical in every specimen, on purpose. */
const NAV: readonly { label: string; path: string }[] = [
  { label: "Overview", path: "M3 9.5 9 4.5l6 5V15a1 1 0 0 1-1 1h-2.5v-4h-5v4H4a1 1 0 0 1-1-1z" },
  { label: "Orders", path: "M4 5h10l-1 9H5zM7 5V3.5h4V5" },
  { label: "Customers", path: "M9 9a2.6 2.6 0 1 0 0-5.2A2.6 2.6 0 0 0 9 9M3.6 15.4c0-2.4 2.4-3.8 5.4-3.8s5.4 1.4 5.4 3.8" },
  { label: "Reports", path: "M4.5 15V8M9 15V4.5M13.5 15v-4.5" },
  { label: "Settings", path: "M9 11.4A2.4 2.4 0 1 0 9 6.6a2.4 2.4 0 0 0 0 4.8M9 2.6v1.4M9 14v1.4M15.4 9H14M4 9H2.6M13.5 4.5l-1 1M5.5 12.5l-1 1M13.5 13.5l-1-1M5.5 5.5l-1-1" },
];

const STATS: readonly { label: string; value: string; delta: string; up: boolean }[] = [
  { label: "Revenue", value: "$48,290", delta: "+12.4%", up: true },
  { label: "Orders", value: "1,284", delta: "+3.1%", up: true },
  { label: "Refunds", value: "42", delta: "-1.8%", up: false },
];

const BARS: readonly { day: string; value: number }[] = [
  { day: "M", value: 0.42 },
  { day: "T", value: 0.61 },
  { day: "W", value: 0.38 },
  { day: "T", value: 0.74 },
  { day: "F", value: 0.93 },
  { day: "S", value: 0.55 },
  { day: "S", value: 0.29 },
];

const ROWS: readonly { name: string; meta: string; state: string; amount: string }[] = [
  { name: "Kyoto Print Co.", meta: "Invoice 2841", state: "Paid", amount: "420.00" },
  { name: "Aurora Supply", meta: "Invoice 2839", state: "Pending", amount: "186.50" },
  { name: "Northwind Studio", meta: "Invoice 2836", state: "Overdue", amount: "678.00" },
];

const SWITCHES: readonly { label: string; on: boolean }[] = [
  { label: "Auto-pay invoices", on: true },
  { label: "Email receipts", on: false },
];

/**
 * The material: how this style paints an element, as opposed to what
 * color it paints it. This is the part that makes Bare
 * a different design language rather than a different theme —
 * There is no surface at all — no fill, no line, no tint. Size, weight and distance are the only tools left.
 */
const MATERIAL = {
  "surface": {
    "background": "transparent",
    "boxShadow": "none",
    "border": "none"
  },
  "button": {
    "background": "transparent",
    "color": "var(--sp-accent)",
    "boxShadow": "none",
    "border": "none",
    "borderBottom": "2px solid var(--sp-accent)"
  },
  "switchOn": {
    "background": "var(--sp-accent)",
    "boxShadow": "none",
    "border": "none"
  },
  "switchOff": {
    "background": "color-mix(in srgb, var(--sp-text) 20%, transparent)",
    "boxShadow": "none",
    "border": "none"
  },
  "knob": {
    "background": "var(--sp-bg)",
    "boxShadow": "none"
  },
  "navActive": {
    "background": "transparent",
    "boxShadow": "none"
  },
  "bar": {
    "background": "var(--sp-accent)",
    "boxShadow": "none",
    "border": "none"
  }
};

const SURFACE_BORDER = "none";
const ROW_SEPARATOR = "1px solid var(--sp-border)";
const RING = 0.68;

export function BookTransitionalSpecimen({ theme = "system", scope = "sp-book-transitional" }: BookTransitionalSpecimenProps) {
  const css =
    theme === "light"
      ? `.${scope}{${vars(TOKENS.color.light)}}`
      : theme === "dark"
        ? `.${scope}{${vars(TOKENS.color.dark)}}`
        : `.${scope}{${vars(TOKENS.color.light)}}@media(prefers-color-scheme:dark){.${scope}{${vars(TOKENS.color.dark)}}}`;

  const label: CSSProperties = {
    font: `${TOKENS.type.weight.strong} ${TOKENS.type.scale[0]}px ${TOKENS.type.family.body}`,
    letterSpacing: `${TOKENS.type.tracking}em`,
    textTransform: "none",
    color: "var(--sp-muted)",
  };

  const meta: CSSProperties = {
    font: `${TOKENS.type.weight.body} ${TOKENS.type.scale[0]}px ${TOKENS.type.family.body}`,
    color: "var(--sp-muted)",
  };

  const card: CSSProperties = {
    ...MATERIAL.surface,
    borderRadius: TOKENS.radius.md,
    padding: 19,
  };

  const heading: CSSProperties = {
    font: `${TOKENS.type.weight.strong} ${TOKENS.type.scale[2]}px ${TOKENS.type.family.display}`,
    textTransform: "none",
    letterSpacing: "0",
  };

  const primary: CSSProperties = { ...MATERIAL.button, borderRadius: TOKENS.radius.sm };

  const pill = (active: boolean): CSSProperties => ({
    padding: "2px 8px",
    borderRadius: TOKENS.radius.pill,
    background: active
      ? "var(--sp-accent)"
      : "color-mix(in srgb, var(--sp-text) 10%, transparent)",
    color: active ? "var(--sp-accent-text)" : "var(--sp-muted)",
    font: `${TOKENS.type.weight.strong} ${TOKENS.type.scale[0]}px ${TOKENS.type.family.body}`,
    textTransform: "none",
    letterSpacing: "0",
  });

  return (
    <div
      className={scope}
      style={{
        width: 760,
        display: "flex",
        background: "var(--sp-bg)",
        color: "var(--sp-text)",
        font: `${TOKENS.type.weight.body} ${TOKENS.type.scale[1]}px/${TOKENS.type.lineHeight} ${TOKENS.type.family.body}`,
        letterSpacing: `${TOKENS.type.tracking}em`,
        overflow: "hidden",
        position: "relative",
      }}
    >
      <style>{css}</style>

      {/* Sidebar */}
      <div
        style={{
          width: 176,
          flex: "none",
          display: "flex",
          flexDirection: "column",
          gap: 4,
          padding: 24,
          borderRight: "1px solid var(--sp-border)",
          background: "color-mix(in srgb, var(--sp-surface) 70%, transparent)",
        }}
      >
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 18 }}>
          <span
            style={{
              width: 22,
              height: 22,
              borderRadius: TOKENS.radius.sm,
              background: "var(--sp-accent)",
              display: "grid",
              placeItems: "center",
              color: "var(--sp-accent-text)",
              font: `${TOKENS.type.weight.display} ${TOKENS.type.scale[0]}px ${TOKENS.type.family.display}`,
            }}
          >
            N
          </span>
          <span
            style={{
              font: `${TOKENS.type.weight.display} ${TOKENS.type.scale[2]}px ${TOKENS.type.family.display}`,
              textTransform: "none",
              letterSpacing: "0",
            }}
          >
            Northwind
          </span>
        </div>

        {NAV.map((item, index) => (
          <span
            key={item.label}
            style={{
              display: "flex",
              alignItems: "center",
              gap: 9,
              height: 40,
              padding: "0 9px",
              borderRadius: TOKENS.radius.sm,
              ...(index === 0 ? MATERIAL.navActive : null),
              color: index === 0 ? "var(--sp-accent)" : "var(--sp-muted)",
              font: `${index === 0 ? TOKENS.type.weight.strong : TOKENS.type.weight.body} ${TOKENS.type.scale[1]}px ${TOKENS.type.family.body}`,
              textTransform: "none",
              letterSpacing: "0",
            }}
          >
            <svg width="17" height="17" viewBox="0 0 18 18" fill="none" aria-hidden="true">
              <path
                d={item.path}
                stroke="currentColor"
                strokeWidth={index === 0 ? 1.7 : 1.3}
                strokeLinecap="round"
                strokeLinejoin="round"
              />
            </svg>
            {item.label}
          </span>
        ))}

        <span style={{ flex: 1 }} />

        <span
          style={{
            display: "flex",
            alignItems: "center",
            gap: 8,
            paddingTop: 18,
            borderTop: "1px solid var(--sp-border)",
          }}
        >
          <span
            style={{
              width: 26,
              height: 26,
              flex: "none",
              display: "grid",
              placeItems: "center",
              borderRadius: TOKENS.radius.pill,
              background: "color-mix(in srgb, var(--sp-text) 12%, transparent)",
              font: `${TOKENS.type.weight.strong} ${TOKENS.type.scale[0]}px ${TOKENS.type.family.body}`,
            }}
          >
            MK
          </span>
          <span style={{ minWidth: 0 }}>
            <span style={{ display: "block", font: `${TOKENS.type.weight.strong} ${TOKENS.type.scale[0]}px ${TOKENS.type.family.body}` }}>
              Mika Ito
            </span>
            <span style={{ ...meta, display: "block" }}>Finance</span>
          </span>
        </span>
      </div>

      {/* Main */}
      <div
        style={{
          flex: 1,
          minWidth: 0,
          display: "flex",
          flexDirection: "column",
          gap: 18,
          padding: 24,
        }}
      >
        {/* Header */}
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <span style={{ flex: 1, minWidth: 0 }}>
            <span style={{ ...label, display: "block" }}>March 2026</span>
            <span
              style={{
                display: "block",
                font: `${TOKENS.type.weight.display} ${TOKENS.type.scale[4]}px ${TOKENS.type.family.display}`,
                textTransform: "none",
                letterSpacing: `${TOKENS.type.tracking}em`,
              }}
            >
              Overview
            </span>
          </span>
          <span
            style={{
              display: "flex",
              alignItems: "center",
              gap: 7,
              padding: "7px 11px",
              background: "var(--sp-surface)",
              border: "1px solid var(--sp-border)",
              borderRadius: TOKENS.radius.sm,
              color: "var(--sp-muted)",
              font: `${TOKENS.type.weight.body} ${TOKENS.type.scale[0]}px ${TOKENS.type.family.body}`,
            }}
          >
            <svg width="13" height="13" viewBox="0 0 18 18" fill="none" aria-hidden="true">
              <circle cx="8" cy="8" r="5.4" stroke="currentColor" strokeWidth="1.5" />
              <path d="M12.4 12.4 16 16" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
            </svg>
            Search
          </span>
          <span
            style={{
              ...primary,
              padding: "8px 13px",
              font: `${TOKENS.type.weight.strong} ${TOKENS.type.scale[0]}px ${TOKENS.type.family.body}`,
              textTransform: "none",
              letterSpacing: "0",
            }}
          >
            New report
          </span>
        </div>

        {/* Stats */}
        <div style={{ display: "flex", gap: 18 }}>
          {STATS.map((stat) => (
            <div key={stat.label} style={{ ...card, flex: 1, minWidth: 0 }}>
              <span style={{ ...label, display: "block" }}>{stat.label}</span>
              <span
                style={{
                  display: "block",
                  marginTop: 3,
                  fontVariantNumeric: "tabular-nums",
                  font: `${TOKENS.type.weight.display} ${TOKENS.type.scale[4]}px ${TOKENS.type.family.display}`,
                }}
              >
                {stat.value}
              </span>
              <span style={{ display: "inline-flex", marginTop: 6, ...pill(stat.up) }}>
                {stat.delta}
              </span>
            </div>
          ))}
        </div>

        {/* Chart + ring */}
        <div style={{ display: "flex", gap: 18 }}>
          <div style={{ ...card, flex: 1.6, minWidth: 0 }}>
            <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between" }}>
              <span style={heading}>Revenue by day</span>
              <span style={meta}>7 days</span>
            </div>
            <div
              style={{
                display: "flex",
                alignItems: "flex-end",
                gap: 7,
                height: 104,
                marginTop: 10,
              }}
            >
              {BARS.map((bar, index) => (
                <span key={index} style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", gap: 5 }}>
                  <span
                    style={{
                      width: "100%",
                      height: bar.value * 86,
                      borderRadius: `${TOKENS.radius.sm}px ${TOKENS.radius.sm}px 0 0`,
                      ...(index === 4
                        ? MATERIAL.bar
                        : {
                            background: "color-mix(in srgb, var(--sp-accent) 32%, var(--sp-surface))",
                            border: SURFACE_BORDER,
                          }),
                    }}
                  />
                  <span style={meta}>{bar.day}</span>
                </span>
              ))}
            </div>
          </div>

          <div style={{ ...card, flex: 1, minWidth: 0, display: "flex", alignItems: "center", gap: 12 }}>
            <span
              style={{
                width: 74,
                height: 74,
                flex: "none",
                borderRadius: TOKENS.radius.pill,
                display: "grid",
                placeItems: "center",
                background: `conic-gradient(var(--sp-accent) 0turn ${RING}turn, color-mix(in srgb, var(--sp-text) 12%, transparent) ${RING}turn 1turn)`,
              }}
            >
              <span
                style={{
                  width: 52,
                  height: 52,
                  borderRadius: TOKENS.radius.pill,
                  background: "var(--sp-surface)",
                  display: "grid",
                  placeItems: "center",
                  fontVariantNumeric: "tabular-nums",
                  font: `${TOKENS.type.weight.strong} ${TOKENS.type.scale[2]}px ${TOKENS.type.family.mono}`,
                }}
              >
                68%
              </span>
            </span>
            <span style={{ minWidth: 0 }}>
              <span style={{ ...heading, display: "block" }}>Budget</span>
              <span style={{ ...meta, display: "block", marginTop: 4 }}>Spent $34,120</span>
              <span style={{ ...meta, display: "block" }}>Left $16,170</span>
            </span>
          </div>
        </div>

        {/* Table + controls */}
        <div style={{ display: "flex", gap: 18 }}>
          <div style={{ ...card, flex: 1.6, minWidth: 0, padding: 0, overflow: "hidden" }}>
            <div
              style={{
                display: "flex",
                alignItems: "center",
                justifyContent: "space-between",
                padding: `${19}px ${19}px 8px`,
              }}
            >
              <span style={heading}>Recent orders</span>
              <span style={{ color: "var(--sp-accent)", font: `${TOKENS.type.weight.strong} ${TOKENS.type.scale[0]}px ${TOKENS.type.family.body}` }}>
                View all
              </span>
            </div>
            {ROWS.map((row, index) => (
              <div
                key={row.name}
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 10,
                  height: 52,
                  padding: `0 ${19}px`,
                  borderTop: ROW_SEPARATOR,
                }}
              >
                <span
                  style={{
                    width: 24,
                    height: 24,
                    flex: "none",
                    display: "grid",
                    placeItems: "center",
                    borderRadius: TOKENS.radius.sm,
                    background: "color-mix(in srgb, var(--sp-text) 9%, transparent)",
                    font: `${TOKENS.type.weight.strong} ${TOKENS.type.scale[0]}px ${TOKENS.type.family.mono}`,
                  }}
                >
                  {row.name.slice(0, 1)}
                </span>
                <span style={{ flex: 1, minWidth: 0 }}>
                  <span style={{ display: "block", font: `${TOKENS.type.weight.strong} ${TOKENS.type.scale[1]}px ${TOKENS.type.family.body}` }}>
                    {row.name}
                  </span>
                  <span style={{ ...meta, display: "block" }}>{row.meta}</span>
                </span>
                <span style={pill(index === 0)}>{row.state}</span>
                <span
                  style={{
                    width: 66,
                    textAlign: "right",
                    fontVariantNumeric: "tabular-nums",
                    font: `${TOKENS.type.weight.strong} ${TOKENS.type.scale[1]}px ${TOKENS.type.family.mono}`,
                  }}
                >
                  {row.amount}
                </span>
              </div>
            ))}
          </div>

          <div style={{ ...card, flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: 10 }}>
            <span style={heading}>Preferences</span>
            {SWITCHES.map((item) => (
              <span key={item.label} style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <span style={{ flex: 1, minWidth: 0, font: `${TOKENS.type.weight.body} ${TOKENS.type.scale[0]}px ${TOKENS.type.family.body}` }}>
                  {item.label}
                </span>
                <span
                  style={{
                    width: 34,
                    height: 20,
                    flex: "none",
                    position: "relative",
                    borderRadius: TOKENS.radius.pill,
                    ...(item.on ? MATERIAL.switchOn : MATERIAL.switchOff),
                  }}
                >
                  <span
                    style={{
                      position: "absolute",
                      top: 3,
                      left: item.on ? 17 : 3,
                      width: 14,
                      height: 14,
                      borderRadius: TOKENS.radius.pill,
                      ...MATERIAL.knob,
                    }}
                  />
                </span>
              </span>
            ))}
            <span style={{ marginTop: 2 }}>
              <span style={{ display: "flex", justifyContent: "space-between" }}>
                <span style={meta}>Alert threshold</span>
                <span style={{ ...meta, fontVariantNumeric: "tabular-nums" }}>62%</span>
              </span>
              <span
                style={{
                  display: "block",
                  position: "relative",
                  height: 5,
                  marginTop: 7,
                  borderRadius: TOKENS.radius.pill,
                  background: "color-mix(in srgb, var(--sp-text) 14%, transparent)",
                }}
              >
                <span
                  style={{
                    position: "absolute",
                    inset: "0 38% 0 0",
                    borderRadius: TOKENS.radius.pill,
                    background: "var(--sp-accent)",
                  }}
                />
                <span
                  style={{
                    position: "absolute",
                    top: -5,
                    left: "62%",
                    width: 15,
                    height: 15,
                    marginLeft: -7,
                    borderRadius: TOKENS.radius.pill,
                    background: "var(--sp-surface)",
                    border: `2px solid var(--sp-accent)`,
                  }}
                />
              </span>
            </span>
          </div>
        </div>
      </div>
    </div>
  );
}

export default BookTransitionalSpecimen;

Nearby styles