{
  "schemaVersion": "1.0",
  "id": "custard-schoolbook",
  "version": "1.1.0",
  "name": "Custard Schoolbook",
  "tier": "free",
  "summary": "Retro-modern learning UI: ochre actions on cream paper, heavy Epilogue headlines and hard-offset shadows on a modern 4px grid.",
  "tags": {
    "industries": [
      "education",
      "e-learning",
      "publishing"
    ],
    "moods": [
      "retro",
      "friendly",
      "bold",
      "warm"
    ],
    "density": "comfortable",
    "contrast": "standard"
  },
  "rationale": {
    "overview": "Custard Schoolbook is for learning products that borrow from 70s textbooks, 80s software manuals and risograph print. The retro cues are limited to three things: the ochre and cream palette, Epilogue 700-800 headlines, and zero-blur offset shadows. Spacing, contrast and control sizes follow current accessibility practice. Text pairs meet at least 4.5:1 in both modes, and controls are 44px tall, so lessons stay readable over long sessions.",
    "color": "Ochre (OKLCH hue about 70) is the only action color. It is used for primary, ring, links and progress. In light mode primary is brand.600 #96600a with white text (about 5.3:1). Against the cream background it measures about 4.9:1. The neutral ramp is tinted toward the same hue: steps 400-700 were nudged from olive toward brown so mid-greys don't go muddy. Ink is neutral.950 #1b1812, a brown-black rather than grey. Destructive is crimson (danger.600 #b92646, about 6.1:1 with white), roughly 60° of hue away from ochre, so an error never reads as a darker primary. Warning stays lemon yellow (warning.200 fill with warning.900 text) so it is not confused with the brand. Success is a warm textbook green (success.700 with white, about 7:1). In dark mode, background is neutral.950 and card/popover are neutral.900, one step lifted. Primary moves to brand.400 #e8a52d with brand.950 text (about 8:1), giving a CRT-amber glow without neon saturation.",
    "typography": "Display and heading sizes follow a 1.4 ratio: 20 → 28 → 40 → 56px. Tracking tightens as size grows: heading-md -0.01em, heading-lg -0.015em, display-md -0.025em, display-lg -0.03em. Epilogue uses only weights 700 and 800. Karla (400/500/700) sets all body text, forms and buttons. Body sizes step 14 → 16 → 18px with line heights of 1.5-1.6 for long reading. IBM Plex Mono 400/500 (typography.code, 14/1.55) is reserved for code, keyboard shortcuts, quiz answer keys and data labels.",
    "layout": "Comfortable density on a 4px base grid (space.1 = 4px). Reading columns max out at about 68ch (about 680px at body-md), and page containers at 1160px. Buttons and inputs are 44px tall. Card padding is space.6 (24px). Page sections are separated by space.12 to space.16 (48-64px).",
    "elevation": "Depth uses hard-offset, zero-blur shadows: sm 2px, md 4px, lg 8px, all in brand.950 at 85% opacity, paired with a 2px border. Cards and raised buttons use shadow.sm. Popovers and dialogs use shadow.lg. In dark mode the shadow nearly disappears against neutral.950, so the 2px border carries the edge. No blurred shadows anywhere.",
    "shapes": "Controls use radius.md (6px) and cards use radius.lg (10px), for a printed-label feel. radius.full is limited to badges and progress tracks. Cards, inputs and buttons use a 2px border: border (neutral.300 light / neutral.700 dark) on cards, input (neutral.400 / neutral.600) on fields."
  },
  "primitives": {
    "color": {
      "brand": {
        "50": "#fff8ea",
        "100": "#ffedc9",
        "200": "#fedb97",
        "300": "#f6c25f",
        "400": "#e8a52d",
        "500": "#c08113",
        "600": "#96600a",
        "700": "#764a08",
        "800": "#5a3707",
        "900": "#3f2605",
        "950": "#271602"
      },
      "neutral": {
        "50": "#fbf6ec",
        "100": "#f3ecde",
        "200": "#e5dbca",
        "300": "#cec2ad",
        "400": "#ad9f8a",
        "500": "#8c7f69",
        "600": "#71654f",
        "700": "#5a503e",
        "800": "#433c2e",
        "900": "#2e291f",
        "950": "#1b1812"
      },
      "success": {
        "50": "#f0fae8",
        "100": "#dcf3cd",
        "200": "#bae3a4",
        "300": "#93ce78",
        "400": "#6cb451",
        "500": "#4c9a37",
        "600": "#387e27",
        "700": "#2a6520",
        "800": "#1e4c17",
        "900": "#143610",
        "950": "#0a1f08"
      },
      "warning": {
        "50": "#fffbe0",
        "100": "#fff4b0",
        "200": "#f8e46e",
        "300": "#e7ce3a",
        "400": "#cfb31a",
        "500": "#ad9306",
        "600": "#8b7500",
        "700": "#6c5a00",
        "800": "#514300",
        "900": "#392e00",
        "950": "#231b00"
      },
      "danger": {
        "50": "#fff4f5",
        "100": "#ffe2e6",
        "200": "#ffc4cd",
        "300": "#fb97a8",
        "400": "#ef677f",
        "500": "#d93d5d",
        "600": "#b92646",
        "700": "#961a38",
        "800": "#73122b",
        "900": "#520a1d",
        "950": "#340210"
      }
    },
    "font": {
      "display": {
        "family": "Epilogue",
        "fallback": "system-ui, sans-serif",
        "source": "google",
        "weights": [
          700,
          800
        ]
      },
      "sans": {
        "family": "Karla",
        "fallback": "system-ui, sans-serif",
        "source": "google",
        "weights": [
          400,
          500,
          700
        ]
      },
      "mono": {
        "family": "IBM Plex Mono",
        "fallback": "ui-monospace, monospace",
        "source": "google",
        "weights": [
          400,
          500
        ]
      }
    },
    "radius": {
      "none": 0,
      "sm": 2,
      "md": 6,
      "lg": 10,
      "xl": 16,
      "full": 9999
    },
    "space": {
      "0": 0,
      "1": 4,
      "2": 8,
      "3": 12,
      "4": 16,
      "5": 20,
      "6": 24,
      "8": 32,
      "10": 40,
      "12": 48,
      "16": 64,
      "20": 80,
      "24": 96,
      "0.5": 2,
      "1.5": 6
    },
    "shadow": {
      "sm": "2px 2px 0 rgba(39, 22, 2, 0.85)",
      "md": "4px 4px 0 rgba(39, 22, 2, 0.85)",
      "lg": "8px 8px 0 rgba(39, 22, 2, 0.85)"
    }
  },
  "typography": {
    "display-lg": {
      "font": "display",
      "size": 56,
      "lineHeight": 1.05,
      "weight": 800,
      "letterSpacing": -0.03
    },
    "display-md": {
      "font": "display",
      "size": 40,
      "lineHeight": 1.1,
      "weight": 800,
      "letterSpacing": -0.025
    },
    "heading-lg": {
      "font": "display",
      "size": 28,
      "lineHeight": 1.2,
      "weight": 700,
      "letterSpacing": -0.015
    },
    "heading-md": {
      "font": "display",
      "size": 20,
      "lineHeight": 1.3,
      "weight": 700,
      "letterSpacing": -0.01
    },
    "heading-sm": {
      "font": "sans",
      "size": 16,
      "lineHeight": 1.4,
      "weight": 700,
      "letterSpacing": 0
    },
    "body-lg": {
      "font": "sans",
      "size": 18,
      "lineHeight": 1.6,
      "weight": 400,
      "letterSpacing": 0
    },
    "body-md": {
      "font": "sans",
      "size": 16,
      "lineHeight": 1.6,
      "weight": 400,
      "letterSpacing": 0
    },
    "body-sm": {
      "font": "sans",
      "size": 14,
      "lineHeight": 1.5,
      "weight": 400,
      "letterSpacing": 0
    },
    "label": {
      "font": "sans",
      "size": 14,
      "lineHeight": 1.25,
      "weight": 700,
      "letterSpacing": 0.01
    },
    "caption": {
      "font": "sans",
      "size": 12,
      "lineHeight": 1.4,
      "weight": 500,
      "letterSpacing": 0.02
    },
    "code": {
      "font": "mono",
      "size": 14,
      "lineHeight": 1.55,
      "weight": 400,
      "letterSpacing": 0
    }
  },
  "semantic": {
    "light": {
      "background": "{color.neutral.50}",
      "foreground": "{color.neutral.950}",
      "card": "#fffdf8",
      "card-foreground": "{color.neutral.950}",
      "popover": "#fffdf8",
      "popover-foreground": "{color.neutral.950}",
      "primary": "{color.brand.600}",
      "primary-foreground": "#ffffff",
      "secondary": "{color.neutral.100}",
      "secondary-foreground": "{color.neutral.900}",
      "muted": "{color.neutral.100}",
      "muted-foreground": "{color.neutral.700}",
      "accent": "{color.brand.100}",
      "accent-foreground": "{color.brand.900}",
      "destructive": "{color.danger.600}",
      "destructive-foreground": "#ffffff",
      "success": "{color.success.700}",
      "success-foreground": "#ffffff",
      "warning": "{color.warning.200}",
      "warning-foreground": "{color.warning.900}",
      "border": "{color.neutral.300}",
      "input": "{color.neutral.400}",
      "ring": "{color.brand.600}"
    },
    "dark": {
      "background": "{color.neutral.950}",
      "foreground": "{color.neutral.50}",
      "card": "{color.neutral.900}",
      "card-foreground": "{color.neutral.50}",
      "popover": "{color.neutral.900}",
      "popover-foreground": "{color.neutral.50}",
      "primary": "{color.brand.400}",
      "primary-foreground": "{color.brand.950}",
      "secondary": "{color.neutral.800}",
      "secondary-foreground": "{color.neutral.100}",
      "muted": "{color.neutral.800}",
      "muted-foreground": "{color.neutral.300}",
      "accent": "{color.brand.900}",
      "accent-foreground": "{color.brand.100}",
      "destructive": "{color.danger.400}",
      "destructive-foreground": "{color.danger.950}",
      "success": "{color.success.400}",
      "success-foreground": "{color.success.950}",
      "warning": "{color.warning.400}",
      "warning-foreground": "{color.warning.950}",
      "border": "{color.neutral.700}",
      "input": "{color.neutral.600}",
      "ring": "{color.brand.400}"
    }
  },
  "components": {
    "button": {
      "height": 44,
      "paddingX": "{space.5}",
      "radius": "{radius.md}",
      "typography": "{typography.label}",
      "fontWeight": 700,
      "shadow": "{shadow.sm}",
      "borderWidth": 2
    },
    "input": {
      "height": 44,
      "paddingX": "{space.3}",
      "radius": "{radius.md}",
      "typography": "{typography.body-md}",
      "borderWidth": 2
    },
    "card": {
      "padding": "{space.6}",
      "radius": "{radius.lg}",
      "shadow": "{shadow.sm}",
      "borderWidth": 2
    },
    "badge": {
      "height": 24,
      "paddingX": "{space.2}",
      "radius": "{radius.full}",
      "typography": "{typography.caption}"
    }
  },
  "guidance": {
    "do": [
      "Use primary (brand.600 in light, brand.400 in dark) for one main action per view, such as 'Start lesson'. Use secondary or ghost buttons for every other action in that view.",
      "Set display-lg (56px, -0.03em), display-md (40px, -0.025em) and heading-lg (28px, -0.015em) in Epilogue 800/800/700. Keep the token letterSpacing values; don't loosen them.",
      "Give cards and raised buttons a 2px border plus shadow.sm. Use shadow.lg only for dialogs and popovers.",
      "In dark mode, let the 2px border (neutral.700) define card and dialog edges, since the brand.950 shadow barely shows on neutral.950.",
      "Set lesson copy in body-md (Karla 16px / 1.6) or body-lg (18px / 1.6). Cap reading columns at 68ch.",
      "Show focus on buttons and inputs as a 2px ring in the ring token with a 2px offset. It measures at least 3:1 against background in both modes.",
      "Use typography.code (IBM Plex Mono 14px) only for code samples, keyboard shortcuts and quiz answer keys.",
      "Pair every success, warning and destructive state with an icon or text label so meaning never depends on color alone."
    ],
    "dont": [
      "Don't add blur to shadows. Every shadow token is a zero-blur offset (2/4/8px).",
      "Don't use brand ochre for errors. Use destructive (danger.600 light / danger.400 dark), and keep warning on the warning scale (warning.200 fill with warning.900 text in light).",
      "Don't set Epilogue below 20px (heading-md) or under weight 700. Use Karla heading-sm or label for anything smaller.",
      "Don't use brand.500 or lighter for text or icons on background or card in light mode. Brand.500 is about 2.9:1 and brand.400 about 2:1 on neutral.50.",
      "Don't use #000000, #ffffff or cool grey for page backgrounds. Stay on the neutral ramp; light card and popover may use #fffdf8.",
      "Don't place more than one primary-filled button in the same card, dialog footer or toolbar.",
      "Don't round buttons or inputs beyond radius.md (6px) or cards beyond radius.lg (10px). Reserve radius.full for badges and progress tracks."
    ]
  }
}
