/**
 * IDE preview of the Cursor models report.
 * Source of truth: /media/scade/Projects/cursormodels/data/current.json
 * This file cannot run on a website — use web/ for breyd.com.
 * October 2026 snapshot; monthly permalinks live on breyd.com.
 */
import {
  BarChart,
  Callout,
  Card,
  CardBody,
  CardHeader,
  Divider,
  Grid,
  H1,
  H2,
  H3,
  Link,
  Pill,
  Row,
  Select,
  Stack,
  Stat,
  Table,
  Text,
  useCanvasState,
  useMemo,
} from "cursor/canvas";

type Vendor = "Grok" | "Anthropic" | "OpenAI";
type TaskId = "trading" | "software" | "writing";
type Intensity = "light" | "standard" | "heavy";

type CatalogRow = {
  name: string;
  vendor: Vendor;
  pool: "Cursor Models" | "Other Models";
  input: number;
  output: number;
  cacheRead: number;
  cacheWrite: number | null;
  ctxDefault: string;
  ctxMax: string;
  visible: boolean;
  notes: string;
};

type CompareModel = {
  id: string;
  short: string;
  name: string;
  vendor: Vendor;
  input: number;
  output: number;
  cacheRead: number;
  pool: "cursor" | "other";
  ctxK: number;
  ctxMaxK: number;
  cursorbench: number | null;
  cursorbenchUsd: number | null;
  swePro: number | null;
  eqElo: number | null;
  gdpval: number | null;
  financeNote: string;
};

const CATALOG: CatalogRow[] = [
  {
    name: "Grok 4.7",
    vendor: "Grok",
    pool: "Cursor Models",
    input: 2,
    output: 6,
    cacheRead: 0.5,
    cacheWrite: null,
    ctxDefault: "256k",
    ctxMax: "500k",
    visible: true,
    notes: "Joint Cursor + SpaceXAI. Default 256k; long context >256k bills 2× up to 500k. Effort: low / medium / high / xhigh. Default high.",
  },
  {
    name: "Grok 4.7 Fast",
    vendor: "Grok",
    pool: "Cursor Models",
    input: 4,
    output: 12,
    cacheRead: 1,
    cacheWrite: null,
    ctxDefault: "256k",
    ctxMax: "500k",
    visible: true,
    notes: "Default speed on Pro and higher. 2× standard Grok 4.7. Fast long context (>256k) bills at 3× the standard rates, up to 500k.",
  },
  {
    name: "Grok 4.6",
    vendor: "Grok",
    pool: "Cursor Models",
    input: 2,
    output: 6,
    cacheRead: 0.5,
    cacheWrite: null,
    ctxDefault: "256k",
    ctxMax: "256k",
    visible: true,
    notes: "Joint Cursor + SpaceXAI. Effort: low / medium / high / xhigh. Default high.",
  },
  {
    name: "Grok 4.6 Fast",
    vendor: "Grok",
    pool: "Cursor Models",
    input: 4,
    output: 12,
    cacheRead: 1,
    cacheWrite: null,
    ctxDefault: "256k",
    ctxMax: "256k",
    visible: true,
    notes: "Fast speed for Grok 4.6. 2× standard Grok 4.6 rates. Grok 4.7 Fast is the current Pro default Grok.",
  },
  {
    name: "Grok 4.5",
    vendor: "Grok",
    pool: "Cursor Models",
    input: 2,
    output: 6,
    cacheRead: 0.5,
    cacheWrite: null,
    ctxDefault: "256k",
    ctxMax: "256k",
    visible: true,
    notes: "Previous Cursor Grok. Fast variant is $4 / $18.",
  },
  {
    name: "Grok 4.5 Fast",
    vendor: "Grok",
    pool: "Cursor Models",
    input: 4,
    output: 18,
    cacheRead: 1,
    cacheWrite: null,
    ctxDefault: "256k",
    ctxMax: "256k",
    visible: true,
    notes: "Fast speed tier. Output is 3× standard Grok 4.5, not 2×.",
  },
  {
    name: "Claude Fable 5.1",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 10,
    output: 50,
    cacheRead: 0.25,
    cacheWrite: 12.5,
    ctxDefault: "300k",
    ctxMax: "1M",
    visible: true,
    notes: "Needs data-retention opt-in. Cache reads $0.25/M. Guardrail trips route to Opus. About 2.5× Opus 5.5 on input and output.",
  },
  {
    name: "Claude Fable 5",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 10,
    output: 50,
    cacheRead: 1,
    cacheWrite: 12.5,
    ctxDefault: "300k",
    ctxMax: "1M",
    visible: false,
    notes: "Same list price as 5.1; cache reads 4× more expensive than 5.1.",
  },
  {
    name: "Claude Opus 5.5",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 4,
    output: 20,
    cacheRead: 0.2,
    cacheWrite: 5,
    ctxDefault: "300k",
    ctxMax: "1M",
    visible: true,
    notes: "Replaces Opus 5 as the visible Opus. 20% cheaper ($4 / $20). Cache reads $0.20/M. ZDR compatible. Fast is $8 / $40. No 1M surcharge.",
  },
  {
    name: "Claude Sonnet 5.5",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 2,
    output: 10,
    cacheRead: 0.2,
    cacheWrite: 2.5,
    ctxDefault: "200k",
    ctxMax: "1M",
    visible: true,
    notes: "Replaces Sonnet 5 as the visible Sonnet. Same $2 / $10. No 1M surcharge. US-only endpoints +10%.",
  },
  {
    name: "Claude Opus 5",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 5,
    output: 25,
    cacheRead: 0.5,
    cacheWrite: 6.25,
    ctxDefault: "300k",
    ctxMax: "1M",
    visible: false,
    notes: "Previous Opus. Hidden by default. $5 / $25. Fast mode is $10 / $50. No 1M surcharge.",
  },
  {
    name: "Claude Sonnet 5",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 2,
    output: 10,
    cacheRead: 0.2,
    cacheWrite: 2.5,
    ctxDefault: "200k",
    ctxMax: "1M",
    visible: false,
    notes: "Previous Sonnet. Hidden by default. Same $2 / $10 as Sonnet 5.5. Newer tokenizer can count more tokens for the same text.",
  },
  {
    name: "Claude 4.5 Haiku",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 1,
    output: 5,
    cacheRead: 0.1,
    cacheWrite: 1.25,
    ctxDefault: "200k",
    ctxMax: "200k",
    visible: false,
    notes: "Fastest Claude. Hidden by default. 200k context only.",
  },
  {
    name: "Claude Opus 4.8",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 5,
    output: 25,
    cacheRead: 0.5,
    cacheWrite: 6.25,
    ctxDefault: "300k",
    ctxMax: "1M",
    visible: false,
    notes: "Previous Opus. Same list price as Opus 5.",
  },
  {
    name: "Claude 4.7 Opus",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 5,
    output: 25,
    cacheRead: 0.5,
    cacheWrite: 6.25,
    ctxDefault: "300k",
    ctxMax: "1M",
    visible: false,
    notes: "Hidden. Fast preview of 4.7 is $30 / $150.",
  },
  {
    name: "Claude 4.6 Opus",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 5,
    output: 25,
    cacheRead: 0.5,
    cacheWrite: 6.25,
    ctxDefault: "200k",
    ctxMax: "1M",
    visible: false,
    notes: "Hidden. Same Opus-class list price.",
  },
  {
    name: "Claude 4.6 Sonnet",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 3,
    output: 15,
    cacheRead: 0.3,
    cacheWrite: 3.75,
    ctxDefault: "200k",
    ctxMax: "1M",
    visible: false,
    notes: "Hidden. Older Sonnet price is $3 / $15, above Sonnet 5.",
  },
  {
    name: "Claude 4.5 Opus",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 5,
    output: 25,
    cacheRead: 0.5,
    cacheWrite: 6.25,
    ctxDefault: "200k",
    ctxMax: "200k",
    visible: false,
    notes: "Hidden. 200k cap.",
  },
  {
    name: "Claude 4.5 Sonnet",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 3,
    output: 15,
    cacheRead: 0.3,
    cacheWrite: 3.75,
    ctxDefault: "200k",
    ctxMax: "1M",
    visible: false,
    notes: "Hidden. Extended context to 1M at the same rates.",
  },
  {
    name: "Claude 4 Sonnet",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 3,
    output: 15,
    cacheRead: 0.3,
    cacheWrite: 3.75,
    ctxDefault: "200k",
    ctxMax: "200k",
    visible: false,
    notes: "Hidden. 1M sibling doubles price above 200k input.",
  },
  {
    name: "Claude 4 Sonnet 1M",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 6,
    output: 22.5,
    cacheRead: 0.6,
    cacheWrite: 7.5,
    ctxDefault: "1M",
    ctxMax: "1M",
    visible: false,
    notes: "Hidden. 2× when input exceeds 200k. Easy to overspend.",
  },
  {
    name: "Claude Opus 4.7 Fast",
    vendor: "Anthropic",
    pool: "Other Models",
    input: 30,
    output: 150,
    cacheRead: 3,
    cacheWrite: 37.5,
    ctxDefault: "200k",
    ctxMax: "1M",
    visible: false,
    notes: "Limited research preview. Most expensive Claude in the picker.",
  },
  {
    name: "GPT-5.6 Sol",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 4,
    output: 20,
    cacheRead: 0.4,
    cacheWrite: 5,
    ctxDefault: "272k",
    ctxMax: "1M",
    visible: true,
    notes: "Promo price through 21 Nov 2026. Long context >272k: 2× input, 1.5× output.",
  },
  {
    name: "GPT-5.6 Terra",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 2,
    output: 12,
    cacheRead: 0.2,
    cacheWrite: 2.5,
    ctxDefault: "272k",
    ctxMax: "1M",
    visible: true,
    notes: "Mid GPT-5.6. Same 1M long-context multipliers as Sol.",
  },
  {
    name: "GPT-5.6 Luna",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 0.2,
    output: 1.2,
    cacheRead: 0.02,
    cacheWrite: 0.25,
    ctxDefault: "272k",
    ctxMax: "1M",
    visible: true,
    notes: "Cheapest GPT-5.6. Fast is 2×. Long context >272k: 2× input, 1.5× output.",
  },
  {
    name: "GPT-5.5",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 5,
    output: 30,
    cacheRead: 0.5,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "1M",
    visible: false,
    notes: "Hidden. More token-efficient than GPT-5.4. Long context 2× input.",
  },
  {
    name: "GPT-5.4",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 2.5,
    output: 15,
    cacheRead: 0.25,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "1M",
    visible: false,
    notes: "Hidden. Fast is ~15% faster at 2× price. Long context 2× input.",
  },
  {
    name: "GPT-5.4 Mini",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 0.75,
    output: 4.5,
    cacheRead: 0.075,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. 90% cache discount.",
  },
  {
    name: "GPT-5.4 Nano",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 0.2,
    output: 1.25,
    cacheRead: 0.02,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. Cost-optimised GPT-5.4.",
  },
  {
    name: "GPT-5.3 Codex",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 1.75,
    output: 14,
    cacheRead: 0.175,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. Coding-tuned GPT-5.3.",
  },
  {
    name: "GPT-5.2",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 1.75,
    output: 14,
    cacheRead: 0.175,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. Codex sibling at the same rates.",
  },
  {
    name: "GPT-5.2 Codex",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 1.75,
    output: 14,
    cacheRead: 0.175,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. Agentic coding variant of GPT-5.2.",
  },
  {
    name: "GPT-5.1 Codex",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 1.25,
    output: 10,
    cacheRead: 0.125,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. Mini sibling is $0.25 / $2 with 4× rate limits.",
  },
  {
    name: "GPT-5.1 Codex Max",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 1.25,
    output: 10,
    cacheRead: 0.125,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. Same token price as GPT-5.1 Codex.",
  },
  {
    name: "GPT-5.1 Codex Mini",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 0.25,
    output: 2,
    cacheRead: 0.025,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. 4× rate limits vs GPT-5.1 Codex.",
  },
  {
    name: "GPT-5",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 1.25,
    output: 10,
    cacheRead: 0.125,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. Fast is 2×. Mini is $0.25 / $2. Codex sibling same price.",
  },
  {
    name: "GPT-5 Fast",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 2.5,
    output: 20,
    cacheRead: 0.25,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. 2× GPT-5.",
  },
  {
    name: "GPT-5 Mini",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 0.25,
    output: 2,
    cacheRead: 0.025,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. Small GPT-5.",
  },
  {
    name: "GPT-5-Codex",
    vendor: "OpenAI",
    pool: "Other Models",
    input: 1.25,
    output: 10,
    cacheRead: 0.125,
    cacheWrite: null,
    ctxDefault: "272k",
    ctxMax: "272k",
    visible: false,
    notes: "Hidden. Original GPT-5 coding variant.",
  },
];

const COMPARE: CompareModel[] = [
  {
    id: "grok47",
    short: "Grok 4.7",
    name: "Grok 4.7",
    vendor: "Grok",
    input: 2,
    output: 6,
    cacheRead: 0.5,
    pool: "cursor",
    ctxK: 256,
    ctxMaxK: 500,
    cursorbench: 46.3,
    cursorbenchUsd: 6.01,
    swePro: null,
    eqElo: 2007,
    gdpval: null,
    financeNote: "No public FrontierFinance score. Stronger than Grok 4.6 on CursorBench Extra High (46.3% vs 41.4%). SWE-bench Pro still lists Grok 4.5, not 4.7.",
  },
  {
    id: "grok47fast",
    short: "Grok Fast",
    name: "Grok 4.7 Fast",
    vendor: "Grok",
    input: 4,
    output: 12,
    cacheRead: 1,
    pool: "cursor",
    ctxK: 256,
    ctxMaxK: 500,
    cursorbench: 46.3,
    cursorbenchUsd: 6.01,
    swePro: null,
    eqElo: 2007,
    gdpval: null,
    financeNote: "Same model, 2× token price. CursorBench cost already reflects measured tokens at Extra High.",
  },
  {
    id: "fable51",
    short: "Fable 5.1",
    name: "Claude Fable 5.1",
    vendor: "Anthropic",
    input: 10,
    output: 50,
    cacheRead: 0.25,
    pool: "other",
    ctxK: 300,
    ctxMaxK: 1000,
    cursorbench: 51.8,
    cursorbenchUsd: 17.28,
    swePro: 81.2,
    eqElo: 2162,
    gdpval: 1853,
    financeNote: "FrontierFinance 55.9% (vs Fable 5 at 49.2%). Jane Street: SOTA trading intuition. Needs data-retention opt-in.",
  },
  {
    id: "opus55",
    short: "Opus 5.5",
    name: "Claude Opus 5.5",
    vendor: "Anthropic",
    input: 4,
    output: 20,
    cacheRead: 0.2,
    pool: "other",
    ctxK: 300,
    ctxMaxK: 1000,
    cursorbench: 57.8,
    cursorbenchUsd: 13.43,
    swePro: 89.9,
    eqElo: 2050,
    gdpval: null,
    financeNote: "No FrontierFinance number published. ZDR compatible. CursorBench Max leads this snapshot. High effort is 56.0% at $3.97.",
  },
  {
    id: "sonnet55",
    short: "Sonnet 5.5",
    name: "Claude Sonnet 5.5",
    vendor: "Anthropic",
    input: 2,
    output: 10,
    cacheRead: 0.2,
    pool: "other",
    ctxK: 200,
    ctxMaxK: 1000,
    cursorbench: 55.5,
    cursorbenchUsd: 9.67,
    swePro: 81.3,
    eqElo: null,
    gdpval: null,
    financeNote: "Same list price as Sonnet 5. CursorBench Max is 55.5% at $9.67; High is 47.8% at $1.67. No published writing Elo on the Atlas snapshot used here.",
  },
  {
    id: "haiku45",
    short: "Haiku 4.5",
    name: "Claude 4.5 Haiku",
    vendor: "Anthropic",
    input: 1,
    output: 5,
    cacheRead: 0.1,
    pool: "other",
    ctxK: 200,
    ctxMaxK: 200,
    cursorbench: null,
    cursorbenchUsd: null,
    swePro: null,
    eqElo: null,
    gdpval: null,
    financeNote: "Fast skim / extract. Not a research model.",
  },
  {
    id: "sol",
    short: "Sol",
    name: "GPT-5.6 Sol",
    vendor: "OpenAI",
    input: 4,
    output: 20,
    cacheRead: 0.4,
    pool: "other",
    ctxK: 272,
    ctxMaxK: 1000,
    cursorbench: 41.7,
    cursorbenchUsd: 8.23,
    swePro: 64.6,
    eqElo: 1972,
    gdpval: 1711,
    financeNote: "No FrontierFinance number. Strong long-running agents; concise output. Promo $4 / $20 through 21 Nov 2026.",
  },
  {
    id: "terra",
    short: "Terra",
    name: "GPT-5.6 Terra",
    vendor: "OpenAI",
    input: 2,
    output: 12,
    cacheRead: 0.2,
    pool: "other",
    ctxK: 272,
    ctxMaxK: 1000,
    cursorbench: 41.3,
    cursorbenchUsd: 5.14,
    swePro: 63.4,
    eqElo: 1855,
    gdpval: null,
    financeNote: "Near-Sol coding at about half Sol’s list price. Behind Grok 4.7 Extra High on CursorBench (41.3% vs 46.3%).",
  },
  {
    id: "luna",
    short: "Luna",
    name: "GPT-5.6 Luna",
    vendor: "OpenAI",
    input: 0.2,
    output: 1.2,
    cacheRead: 0.02,
    pool: "other",
    ctxK: 272,
    ctxMaxK: 1000,
    cursorbench: 35.9,
    cursorbenchUsd: 1.03,
    swePro: 62.7,
    eqElo: 1829,
    gdpval: null,
    financeNote: "Cheap first pass. Weak on the hardest CursorBench tasks at low effort.",
  },
];

type Scenario = {
  label: string;
  blurb: string;
  input: number;
  output: number;
  cache: number;
};

const SCENARIOS: Record<TaskId, Record<Intensity, Scenario>> = {
  trading: {
    light: {
      label: "Quick ticker briefing",
      blurb:
        "One ticker, recent headlines, and a 1-page view. About 12k input tokens and 2.5k output. No long thinking.",
      input: 12000,
      output: 2500,
      cache: 0,
    },
    standard: {
      label: "Earnings + filing memo",
      blurb:
        "Selected 10-K excerpts, last earnings notes, and a long/short memo with risks. 45k input and 14k output, including about 8k thinking tokens billed as output.",
      input: 45000,
      output: 14000,
      cache: 0,
    },
    heavy: {
      label: "Deep diligence pack",
      blurb:
        "A large filing pack, transcript notes, and a full memo. 180k input and 32k output including thinking. Still under the 200k long-context surcharge for Grok and under 272k for GPT-5.6.",
      input: 180000,
      output: 32000,
      cache: 0,
    },
  },
  software: {
    light: {
      label: "Small one-file bugfix",
      blurb:
        "Read a file, patch it, run tests. 8k fresh input, 4k cached reread, 2.5k output.",
      input: 8000,
      output: 2500,
      cache: 4000,
    },
    standard: {
      label: "Feature with tests",
      blurb:
        "Multi-file agent loop: 30k fresh input, 50k cache reads, 20k output (code + reasoning). Typical Cursor feature, not a CursorBench hard task.",
      input: 30000,
      output: 20000,
      cache: 50000,
    },
    heavy: {
      label: "Hard CursorBench-style task",
      blurb:
        "Ambiguous multi-file work. Dollar figures below use Cursor’s published CursorBench 4.0 cost-per-task where the model was measured. Formula estimate is shown only if Cursor did not publish a cost.",
      input: 80000,
      output: 35000,
      cache: 40000,
    },
  },
  writing: {
    light: {
      label: "Blog post (~800 words)",
      blurb: "Short brief in, ~800 words out. About 600 input and 1,200 output tokens.",
      input: 600,
      output: 1200,
      cache: 0,
    },
    standard: {
      label: "Short story (~3,000 words)",
      blurb:
        "A 3,000-word story from a one-page brief. About 800 input and 4,000 output tokens.",
      input: 800,
      output: 4000,
      cache: 0,
    },
    heavy: {
      label: "Chapter + two revisions",
      blurb:
        "Draft a chapter, then two edit passes. 4.5k fresh input, 25k cache reads of prior draft, 24k output across three turns.",
      input: 4500,
      output: 24000,
      cache: 25000,
    },
  },
};

const TASKS: { id: TaskId; label: string }[] = [
  { id: "trading", label: "Stock & trading" },
  { id: "software", label: "Software development" },
  { id: "writing", label: "Creative writing" },
];

const INTENSITIES: { id: Intensity; label: string }[] = [
  { id: "light", label: "Light" },
  { id: "standard", label: "Standard" },
  { id: "heavy", label: "Heavy" },
];

function usd(n: number): string {
  if (!Number.isFinite(n)) return "—";
  if (n === 0) return "$0.00";
  if (n < 0.01) return `$${n.toFixed(4)}`;
  if (n < 1) return `$${n.toFixed(3)}`;
  return `$${n.toFixed(2)}`;
}

function tokenCost(
  model: CompareModel,
  scenario: Scenario,
  teamsRate: boolean,
  publishedHeavySoftware: boolean,
): number {
  if (publishedHeavySoftware && model.cursorbenchUsd != null) {
    const extra =
      teamsRate && model.pool === "other"
        ? ((scenario.input + scenario.output + scenario.cache) / 1_000_000) * 0.25
        : 0;
    return model.cursorbenchUsd + extra;
  }
  const base =
    (scenario.input / 1_000_000) * model.input +
    (scenario.output / 1_000_000) * model.output +
    (scenario.cache / 1_000_000) * model.cacheRead;
  const extra =
    teamsRate && model.pool === "other"
      ? ((scenario.input + scenario.output + scenario.cache) / 1_000_000) * 0.25
      : 0;
  return base + extra;
}

function vendorLabel(v: Vendor): string {
  if (v === "Grok") return "Cursor / SpaceXAI";
  return v;
}

type SeatPlan = {
  id: string;
  name: string;
  usdPerSeatMonth: number | null;
  priceLabel: string;
  billedHow: string;
  cursorModels: string;
  otherModels: string;
};

const TEAM_SIZES = [1, 5, 10, 25, 50] as const;

const SEAT_PLANS: SeatPlan[] = [
  {
    id: "hobby",
    name: "Hobby",
    usdPerSeatMonth: 0,
    priceLabel: "Free",
    billedHow: "Per account",
    cursorModels: "Limited (unpublished $)",
    otherModels: "Limited (unpublished $)",
  },
  {
    id: "start",
    name: "Start (India)",
    usdPerSeatMonth: null,
    priceLabel: "₹649/mo, tax inclusive",
    billedHow: "Per account",
    cursorModels:
      "Included (unpublished $). Grok 4.7 / 4.6 / 4.5 and Composer non-fast; Grok medium effort only.",
    otherModels: "Not included",
  },
  {
    id: "pro",
    name: "Pro",
    usdPerSeatMonth: 20,
    priceLabel: "$20/mo",
    billedHow: "Per account",
    cursorModels: "Included (unpublished $). Grok Fast is the Pro default (2×); Grok 4.7 Fast is the current default Grok.",
    otherModels: "Included (unpublished $)",
  },
  {
    id: "proPlus",
    name: "Pro Plus",
    usdPerSeatMonth: 60,
    priceLabel: "$60/mo",
    billedHow: "Per account",
    cursorModels: "Included (unpublished $)",
    otherModels: "Included (unpublished $)",
  },
  {
    id: "ultra",
    name: "Ultra",
    usdPerSeatMonth: 200,
    priceLabel: "$200/mo",
    billedHow: "Per account",
    cursorModels: "Included (unpublished $)",
    otherModels: "Included (unpublished $)",
  },
  {
    id: "teamsStandard",
    name: "Teams Standard",
    usdPerSeatMonth: 40,
    priceLabel: "$40/user/mo",
    billedHow: "Per active paid seat",
    cursorModels: "Per-seat allowance (unpublished $)",
    otherModels: "Per-seat allowance (unpublished $) plus $0.25/M Cursor Token Rate",
  },
  {
    id: "teamsPremium",
    name: "Teams Premium",
    usdPerSeatMonth: 120,
    priceLabel: "$120/user/mo",
    billedHow: "Per active paid seat",
    cursorModels: "5× Standard (unpublished $)",
    otherModels: "5× Standard (unpublished $) plus $0.25/M Cursor Token Rate",
  },
  {
    id: "unpaidAdmin",
    name: "Unpaid Admin",
    usdPerSeatMonth: 0,
    priceLabel: "$0/user/mo",
    billedHow: "Admin without Cursor access",
    cursorModels: "No Cursor access",
    otherModels: "No Cursor access",
  },
  {
    id: "enterprise",
    name: "Enterprise",
    usdPerSeatMonth: null,
    priceLabel: "Custom",
    billedHow: "Invoice / PO; pooled usage",
    cursorModels: "Pooled (unpublished $)",
    otherModels: "Pooled (unpublished $) plus $0.25/M Cursor Token Rate",
  },
];

function tasksPerSeat(seatUsd: number, taskUsd: number): string {
  if (!Number.isFinite(seatUsd) || !Number.isFinite(taskUsd) || taskUsd <= 0) {
    return "—";
  }
  const n = seatUsd / taskUsd;
  if (n >= 100) return String(Math.round(n));
  if (n >= 10) return n.toFixed(0);
  return n.toFixed(1);
}

export default function CursorModelsOct2026() {
  const [task, setTask] = useCanvasState<TaskId>("task", "software");
  const [intensity, setIntensity] = useCanvasState<Intensity>(
    "intensity",
    "standard",
  );
  const [teams, setTeams] = useCanvasState<string>("teams", "individual");
  const [speed, setSpeed] = useCanvasState<string>("speed", "standard");
  const [seatSize, setSeatSize] = useCanvasState<number>("seatSize", 10);

  const teamsRate = teams === "teams";
  const scenario = SCENARIOS[task][intensity];
  const publishedHeavySoftware = task === "software" && intensity === "heavy";

  const models = useMemo(() => {
    return COMPARE.filter((m) =>
      speed === "fast" ? m.id !== "grok47" : m.id !== "grok47fast",
    );
  }, [speed]);

  const costs = useMemo(() => {
    return models.map((m) => ({
      model: m,
      usd: tokenCost(m, scenario, teamsRate, publishedHeavySoftware),
    }));
  }, [models, scenario, teamsRate, publishedHeavySoftware]);

  const cheapest = costs.reduce((a, b) => (a.usd <= b.usd ? a : b));
  const dearest = costs.reduce((a, b) => (a.usd >= b.usd ? a : b));

  const pick = useMemo(() => {
    if (task === "software") {
      return {
        peak: {
          title: "Peak measured quality",
          model: "Claude Opus 5.5 (Max)",
          why: "Leads CursorBench 4.0 at 57.8% ($13.43/task) and SWE-bench Pro at 89.9%. Ahead of Fable 5.1 Max (51.8% at $17.28) and cheaper. Sonnet 5.5 Max is 55.5% at $9.67 if you want the next step down.",
        },
        value: {
          title: "Best measured quality per dollar",
          model: "Claude Opus 5.5 High, or Claude Sonnet 5.5 Extra High",
          why: "Opus 5.5 High is 56.0% for $3.97. Sonnet 5.5 Extra High is 53.1% for $3.88. Sonnet 5.5 High is 47.8% for $1.67 — still above Grok 4.7 Extra High (46.3% at $6.01) for a fraction of the bill. Grok 4.7 Extra High remains the Cursor Models pool pick.",
        },
        budget: {
          title: "Budget / high volume",
          model: "Claude Sonnet 5.5 Medium, GPT-5.6 Luna, or Grok 4.7 Medium",
          why: "Sonnet 5.5 Medium is 39.2% for $0.70. Luna Max is $1.03 at 35.9%. Grok 4.7 Medium is $3.49 at 41.6% and draws from the Cursor Models pool. Fine for routine edits. Weak on ambiguous, long-horizon work at low effort.",
        },
      };
    }
    if (task === "trading") {
      return {
        peak: {
          title: "Peak research quality",
          model: "Claude Fable 5.1",
          why: "Only model in this set with a published FrontierFinance score (55.9%). Jane Street called out trading intuition. Still not investment advice. Needs data-retention opt-in.",
        },
        value: {
          title: "Serious analysis without Fable pricing",
          model: "Claude Opus 5.5, or GPT-5.6 Sol / Terra",
          why: "Opus 5.5 is $4 / $20 — 20% cheaper than Opus 5 — and ZDR compatible. No new GDPval-AA number for 5.5 in this snapshot. Sol is the same $4 / $20 promo through 21 Nov 2026 and persistent on long tool loops.",
        },
        budget: {
          title: "Screening and summaries",
          model: "Grok 4.7, Claude Sonnet 5.5, or GPT-5.6 Luna",
          why: "A standard memo is about $0.17 on Grok 4.7 standard, $0.23 on Sonnet 5.5, $0.03 on Luna. Use these to triage; promote interesting names to Opus 5.5 or Fable. Live prices need web search — none of these models see the tape by themselves.",
        },
      };
    }
    return {
      peak: {
        title: "Peak published prose",
        model: "Claude Fable 5.1",
        why: "Leads the 7 Oct 2026 Benchmark Atlas Creative Writing v3 Elo snapshot among Cursor-listed models (2,162). GPT-6 Astra is 2,173 but is not in Cursor. Hidden Opus 5 is 2,133; visible Opus 5.5 is 2,050. Literary quality and agent coding quality are not the same skill.",
      },
      value: {
        title: "Strong writing at mid price",
        model: "Claude Opus 5.5, or Grok 4.7",
        why: "Opus 5.5 is 2,050 Elo at $4 / $20. Grok 4.7 is 2,007 in the Cursor Models pool. GPT-5.6 Sol is 1,972 at the same $4 / $20 promo. Sonnet 5.5 has no Elo on this Atlas snapshot.",
      },
      budget: {
        title: "Drafts and volume",
        model: "GPT-5.6 Luna or Grok 4.7",
        why: "A 3,000-word story is about half a cent on Luna and about 3 cents on Grok 4.7 standard. Luna Elo is 1,829; Grok 4.7 is 2,007. Cheap drafts, then a polish pass on Fable or Opus 5.5 if the piece matters.",
      },
    };
  }, [task]);

  const costCategories = costs.map((c) => c.model.short);
  const costSeries = costs.map((c) => Number(c.usd.toFixed(4)));

  const benchModels = COMPARE.filter(
    (m) => m.cursorbench != null && m.id !== "grok47fast",
  );
  const eloModels = COMPARE.filter((m) => m.eqElo != null && m.id !== "grok47fast");

  const monthFormula = useMemo(() => {
    const coding = SCENARIOS.software.standard;
    const memo = SCENARIOS.trading.standard;
    const story = SCENARIOS.writing.standard;
    return models.map((m) => {
      const code = tokenCost(m, coding, teamsRate, false) * 20;
      const trade = tokenCost(m, memo, teamsRate, false) * 8;
      const write = tokenCost(m, story, teamsRate, false) * 4;
      return { short: m.short, total: code + trade + write, code, trade, write };
    });
  }, [models, teamsRate]);

  const monthHard = useMemo(() => {
    return models
      .filter((m) => m.cursorbenchUsd != null)
      .map((m) => ({
        short: m.short,
        total: (m.cursorbenchUsd ?? 0) * 20,
      }));
  }, [models]);

  const grokNote =
    speed === "fast"
      ? "Grok 4.7 Fast is the default speed on Pro and higher ($4 / $12). Charts use that rate."
      : "Charts use Grok 4.7 standard speed ($2 / $6). On Pro, Fast is the default — switch speed above if that is how you actually run.";

  const chartSeatPlans = SEAT_PLANS.filter(
    (p) =>
      p.usdPerSeatMonth != null && p.id !== "hobby" && p.id !== "unpaidAdmin",
  );
  const usdSeatPlans = SEAT_PLANS.filter(
    (p) => p.usdPerSeatMonth != null && p.id !== "unpaidAdmin",
  );
  const vsSeatModels = COMPARE.filter((m) =>
    ["grok47", "grok47fast", "opus55", "luna", "fable51"].includes(m.id),
  );
  const vsHardModels = vsSeatModels.filter(
    (m) => m.cursorbenchUsd != null && m.id !== "grok47fast",
  );
  const standardSoftware = SCENARIOS.software.standard;

  return (
    <Stack gap={28}>
      <Stack gap={8}>
        <H1>Cursor models: Grok, Anthropic, OpenAI</H1>
        <Text tone="secondary">
          Snapshot for 7 October 2026. Prices, seats, and context windows are
          Cursor’s published list rates. Quality numbers are public benches, not
          my opinion. “Best” here means best fit for a stated goal — peak score,
          score per dollar, or lowest bill — not a single winner.
        </Text>
        <Text size="small" tone="tertiary">
          Sources:{" "}
          <Link href="https://cursor.com/docs/models-and-pricing">
            Cursor Models & Pricing
          </Link>
          {" · "}
          <Link href="https://cursor.com/pricing">Cursor pricing</Link>
          {" · "}
          <Link href="https://cursor.com/docs/account/teams/pricing">
            Team pricing
          </Link>
          {" · "}
          <Link href="https://cursor.com/docs">Cursor model table</Link>
          {" · "}
          <Link href="https://cursor.com/cursorbench">CursorBench 4.0</Link>
          {" · "}
          <Link href="https://platform.claude.com/docs/en/models/overview">
            Anthropic models
          </Link>
          {" · "}
          <Link href="https://www.anthropic.com/claude-fable-and-mythos-5-1">
            Fable 5.1
          </Link>
          {" · "}
          <Link href="https://docs.x.ai/developers/pricing">xAI pricing</Link>
          {" · "}
          <Link href="https://developers.openai.com/api/docs/models">
            OpenAI models
          </Link>
          {" · "}
          EQ-Bench Creative Writing v3 Elo via Benchmark Atlas (7 Oct 2026)
        </Text>
      </Stack>

      <Callout tone="warning" title="What this is not">
        These models are not licensed investment advisers. CursorBench and
        SWE-bench measure coding agents, not stock picking. Creative-writing Elo
        is a judged-prose contest, not a sales metric. Token math below is a
        bill estimate from published rates; your actual Cursor usage includes
        system prompt, tool traces, retries, and (on Teams/Enterprise) a $0.25/M
        Cursor Token Rate on third-party models.
      </Callout>

      <Grid columns={4} gap={16}>
        <Stat value="39" label="Grok + Claude + GPT rows in Cursor" />
        <Stat value="$0.20 / $1.20" label="Cheapest GPT-5.6 (Luna)" />
        <Stat value="$30 / $150" label="Dearest Claude (Opus 4.7 Fast)" />
        <Stat value="1M" label="Max context on current flagships" />
      </Grid>

      <H2>How Cursor charges you</H2>
      <Text>
        Two monthly pools. Grok 4.7, Grok 4.6, Grok 4.5, and Composer 2.5 draw from{" "}
        <Text as="span" weight="semibold">
          Cursor Models
        </Text>{" "}
        (more included usage). Claude and GPT draw from{" "}
        <Text as="span" weight="semibold">
          Other Models
        </Text>{" "}
        at the API list price. Pro is $20/mo, Pro Plus $60, Ultra $200. Teams
        Standard is $40/user, Premium $120. Start (India, ₹649 tax inclusive)
        includes only the Cursor Models pool. Fast speed on Grok 4.7 is the Pro
        default and doubles the token rate. Dollar size of either pool is
        unpublished on the live docs.
      </Text>
      <Grid columns={3} gap={16}>
        <Card>
          <CardHeader>Cursor Models pool</CardHeader>
          <CardBody>
            <Text>
              Grok 4.7, Grok 4.6, Grok 4.5, Composer 2.5. Exempt from the Teams Cursor
              Token Rate. Best place to spend included usage. Pool $ unpublished.
            </Text>
          </CardBody>
        </Card>
        <Card>
          <CardHeader>Other Models pool</CardHeader>
          <CardBody>
            <Text>
              Every Claude and GPT row. Burns included third-party credit at
              that model’s API price. Live docs say “Included” on Pro and up,
              not a dollar figure. Hidden rows still bill if you turn them on.
            </Text>
          </CardBody>
        </Card>
        <Card>
          <CardHeader>Seat vs tokens</CardHeader>
          <CardBody>
            <Text>
              The licence is a monthly floor. Token estimates below are extra
              once included usage is exhausted (on-demand, billed in arrears).
              Teams add $0.25/M on Claude and GPT.
            </Text>
          </CardBody>
        </Card>
      </Grid>

      <H2>Cost per developer licence</H2>
      <Text>
        Monthly Cursor licence floor for representative team sizes. Seat fee is
        not token spend: included pool dollars are unpublished on the live docs,
        so the tables show sourced $/seat (or say unpublished) and then how that
        floor sits next to per-task token estimates.
      </Text>
      <Text size="small" tone="tertiary">
        Sources retrieved 14 Sep 2026:{" "}
        <Link href="https://cursor.com/pricing">cursor.com/pricing</Link>
        {" · "}
        <Link href="https://cursor.com/docs/models-and-pricing">
          Models & Pricing
        </Link>
        {" · "}
        <Link href="https://cursor.com/docs/account/teams/pricing">
          Team pricing
        </Link>
        . Individual plans are N separate accounts. Teams bills per active paid
        seat. Prices exclude tax except Start.
      </Text>
      <Row gap={8} wrap>
        {TEAM_SIZES.map((size) => (
          <span key={size}>
            <Pill active={seatSize === size} onClick={() => setSeatSize(size)}>
              {size === 1 ? "1 developer" : `${size} developers`}
            </Pill>
          </span>
        ))}
      </Row>
      <Grid columns={4} gap={16}>
        <Stat
          value={`$${(20 * seatSize).toLocaleString("en-US")}`}
          label={`${seatSize} × Pro ($20)`}
        />
        <Stat
          value={`$${(40 * seatSize).toLocaleString("en-US")}`}
          label={`${seatSize} × Teams Standard ($40)`}
        />
        <Stat
          value={`$${(120 * seatSize).toLocaleString("en-US")}`}
          label={`${seatSize} × Teams Premium ($120)`}
        />
        <Stat
          value={`$${(200 * seatSize).toLocaleString("en-US")}`}
          label={`${seatSize} × Ultra ($200)`}
        />
      </Grid>
      <Stack gap={8}>
        <H3>Monthly USD for this headcount</H3>
        <BarChart
          categories={chartSeatPlans.map((p) => p.name.replace(" (India)", ""))}
          series={[
            {
              name: `Monthly USD for ${seatSize} developer licence(s)`,
              data: chartSeatPlans.map((p) => (p.usdPerSeatMonth ?? 0) * seatSize),
            },
          ]}
          horizontal
          height={240}
          valuePrefix="$"
          showValues
        />
        <Text size="small" tone="tertiary">
          USD per month at published list rates. Axis: plan (categories), monthly
          cost in USD. Enterprise and Start omitted (custom / INR). Hobby and
          unpaid admin omitted from the chart ($0).
        </Text>
      </Stack>
      <Grid columns={3} gap={16}>
        <Card>
          <CardHeader trailing={<Pill size="sm" active>Peak</Pill>}>
            Ultra ($200/mo) or Teams Premium ($120/user)
          </CardHeader>
          <CardBody>
            <Stack gap={8}>
              <Text weight="semibold">Peak included usage</Text>
              <Text>
                Cursor recommends Ultra for agent power users (often $200+/mo
                total usage). Premium is 5× a Standard Teams seat at 3× the $40
                list price. Enterprise list $ is unpublished.
              </Text>
            </Stack>
          </CardBody>
        </Card>
        <Card>
          <CardHeader trailing={<Pill size="sm" active>Value</Pill>}>
            Pro Plus ($60) or Teams Standard ($40/user)
          </CardHeader>
          <CardBody>
            <Stack gap={8}>
              <Text weight="semibold">Daily agents without Ultra</Text>
              <Text>
                Cursor says daily Agent users typically $60–$100/mo total usage
                and recommends Pro+ for that. Teams Standard is the published org
                floor; it adds SSO, shared billing, and $0.25/M on Claude and
                GPT. Five Pro accounts are $100 vs $200 for five Standard seats —
                the extra is the team product, not cheaper tokens.
              </Text>
            </Stack>
          </CardBody>
        </Card>
        <Card>
          <CardHeader trailing={<Pill size="sm">Budget</Pill>}>
            Pro ($20) or Start (₹649, India, Cursor Models only)
          </CardHeader>
          <CardBody>
            <Stack gap={8}>
              <Text weight="semibold">Lowest published paid seat</Text>
              <Text>
                Hobby is free with limited usage (unpublished $). Start cannot
                use the Other Models pool, Fast, or Grok effort above medium.
                Spend a Pro seat on Grok in the Cursor Models pool; Fable at
                $17.28 per hard CursorBench task will blow past any unpublished
                Other Models credit in one or two jobs.
              </Text>
            </Stack>
          </CardBody>
        </Card>
      </Grid>
      <H3>Published plans</H3>
      <Table
        headers={[
          "Plan",
          "List price",
          "Billed",
          "Cursor Models pool",
          "Other Models pool",
        ]}
        rows={SEAT_PLANS.map((p) => [
          p.name,
          p.priceLabel,
          p.billedHow,
          p.cursorModels,
          p.otherModels,
        ])}
        striped
        stickyHeader
      />
      <H3>Licence floor for 1 / 5 / 10 / 25 / 50 developers</H3>
      <Table
        headers={["Developers", ...usdSeatPlans.map((p) => p.name)]}
        columnAlign={["right" as const, ...usdSeatPlans.map(() => "right" as const)]}
        rows={TEAM_SIZES.map((size) => [
          String(size),
          ...usdSeatPlans.map((p) =>
            p.usdPerSeatMonth === 0
              ? "$0"
              : `$${((p.usdPerSeatMonth ?? 0) * size).toLocaleString("en-US")}`,
          ),
        ])}
        striped
        stickyHeader
      />
      <H3>How that floor sits next to per-task token estimates</H3>
      <Text tone="secondary">
        If the monthly licence were spent at list rates — not remaining credit,
        not an invoice. Included pool $ is unpublished. Standard features use
        the software “feature with tests” mix. Hard tasks use published
        CursorBench 4.0 $/task. Teams Token Rate is not applied here.
      </Text>
      <Table
        headers={[
          `Plan / ${seatSize} seats`,
          "$ / mo",
          ...vsSeatModels.map((m) => `${m.short} std`),
          ...vsHardModels.map((m) => `${m.short} hard`),
        ]}
        columnAlign={[
          "left" as const,
          "right" as const,
          ...vsSeatModels.map(() => "right" as const),
          ...vsHardModels.map(() => "right" as const),
        ]}
        rows={chartSeatPlans.map((p) => {
          const seat = (p.usdPerSeatMonth ?? 0) * seatSize;
          return [
            p.name,
            `$${seat.toLocaleString("en-US")}`,
            ...vsSeatModels.map((m) =>
              tasksPerSeat(seat, tokenCost(m, standardSoftware, false, false)),
            ),
            ...vsHardModels.map((m) =>
              tasksPerSeat(seat, m.cursorbenchUsd ?? 0),
            ),
          ];
        })}
        striped
        stickyHeader
      />
      <Callout tone="neutral" title="Unpublished on live Cursor pages (14 Sep 2026)">
        Dollar size of the Cursor Models pool; dollar size of included Other
        Models usage on Pro / Pro Plus / Ultra (live table says “Included”);
        Teams Standard allowance in dollars; Enterprise list price; volume
        discounts; yearly per-seat $ (yearly billing exists); USD equivalent of
        Start ₹649; Hobby included usage in dollars. Cursor bills Teams per
        active paid seat. Usage does not transfer between teammates. On-demand
        after included pools is billed in arrears.
      </Callout>

      <H2>Pick a task, then a bill</H2>
      <Text>
        Choose a job and a size. The chart is the estimated USD for that one
        job at published Cursor rates. Heavy software uses Cursor’s own
        CursorBench 4.0 cost-per-task where they published one.
      </Text>
      <Row gap={8} wrap>
        {TASKS.map((t) => (
          <span key={t.id}>
            <Pill active={task === t.id} onClick={() => setTask(t.id)}>
              {t.label}
            </Pill>
          </span>
        ))}
      </Row>
      <Row gap={8} wrap>
        {INTENSITIES.map((i) => (
          <span key={i.id}>
            <Pill
              active={intensity === i.id}
              onClick={() => setIntensity(i.id)}
            >
              {i.label}
            </Pill>
          </span>
        ))}
      </Row>
      <Row gap={16} wrap align="center">
        <Text size="small" tone="secondary">
          Grok speed
        </Text>
        <Select
          value={speed}
          onChange={setSpeed}
          options={[
            { value: "standard", label: "Grok 4.7 standard ($2 / $6)" },
            { value: "fast", label: "Grok 4.7 Fast ($4 / $12, Pro default)" },
          ]}
        />
        <Text size="small" tone="secondary">
          Plan surcharge
        </Text>
        <Select
          value={teams}
          onChange={setTeams}
          options={[
            { value: "individual", label: "Individual (no extra token rate)" },
            { value: "teams", label: "Teams/Enterprise (+$0.25/M on Claude & GPT)" },
          ]}
        />
      </Row>
      <Text weight="semibold">{scenario.label}</Text>
      <Text tone="secondary">{scenario.blurb}</Text>
      <Text size="small" tone="tertiary">
        {grokNote} Token mix: {scenario.input.toLocaleString()} input ·{" "}
        {scenario.output.toLocaleString()} output · {scenario.cache.toLocaleString()}{" "}
        cache-read.
        {publishedHeavySoftware
          ? " Heavy software bills use published CursorBench 4.0 $/task."
          : ""}
      </Text>

      <Grid columns={3} gap={16}>
        <Stat value={usd(cheapest.usd)} label={`Cheapest: ${cheapest.model.short}`} tone="success" />
        <Stat value={usd(dearest.usd)} label={`Most expensive: ${dearest.model.short}`} tone="warning" />
        <Stat
          value={
            cheapest.usd > 0 ? `${(dearest.usd / cheapest.usd).toFixed(0)}×` : "—"
          }
          label="Spread, dearest vs cheapest"
        />
      </Grid>

      <Stack gap={8}>
        <H3>Estimated USD for this one task</H3>
        <BarChart
          categories={costCategories}
          series={[{ name: "Estimated cost (USD)", data: costSeries }]}
          horizontal
          height={280}
          valuePrefix="$"
          showValues
        />
        <Text size="small" tone="tertiary">
          Source: Cursor list prices applied to the token mix above
          {publishedHeavySoftware
            ? "; heavy software uses CursorBench 4.0 published $/task (10 Sep 2026)"
            : ""}
          . Not a quote from your invoice.
        </Text>
      </Stack>

      <Grid columns={3} gap={16}>
        <Card>
          <CardHeader trailing={<Pill size="sm" active>Peak</Pill>}>
            {pick.peak.model}
          </CardHeader>
          <CardBody>
            <Stack gap={8}>
              <Text weight="semibold">{pick.peak.title}</Text>
              <Text>{pick.peak.why}</Text>
            </Stack>
          </CardBody>
        </Card>
        <Card>
          <CardHeader trailing={<Pill size="sm" active>Value</Pill>}>
            {pick.value.model}
          </CardHeader>
          <CardBody>
            <Stack gap={8}>
              <Text weight="semibold">{pick.value.title}</Text>
              <Text>{pick.value.why}</Text>
            </Stack>
          </CardBody>
        </Card>
        <Card>
          <CardHeader trailing={<Pill size="sm">Budget</Pill>}>
            {pick.budget.model}
          </CardHeader>
          <CardBody>
            <Stack gap={8}>
              <Text weight="semibold">{pick.budget.title}</Text>
              <Text>{pick.budget.why}</Text>
            </Stack>
          </CardBody>
        </Card>
      </Grid>

      <Table
        headers={[
          "Model",
          "Vendor",
          "Est. $",
          "Input / 1M",
          "Output / 1M",
          "Context",
          "Fit for this task",
        ]}
        columnAlign={["left", "left", "right", "right", "right", "left", "left"]}
        striped
        rows={costs.map((c) => {
          const m = c.model;
          let fit = m.financeNote;
          if (task === "software") {
            fit =
              m.cursorbench != null
                ? `CursorBench 4.0 ${m.cursorbench}%${m.swePro != null ? ` · SWE-Pro ${m.swePro}%` : ""}`
                : "Not on CursorBench 4.0. Use for cheap extract / drafts.";
          } else if (task === "writing") {
            fit =
              m.eqElo != null
                ? `EQ-Bench CW v3 Elo ${m.eqElo.toLocaleString()}`
                : "No published writing Elo.";
          }
          return [
            m.name,
            vendorLabel(m.vendor),
            usd(c.usd),
            `$${m.input}`,
            `$${m.output}`,
            `${m.ctxK}k` + (m.ctxMaxK > m.ctxK ? ` / ${m.ctxMaxK / 1000}M` : ""),
            fit,
          ];
        })}
      />

      <Divider />

      <H2>Software: measured quality vs measured bill</H2>
      <Text>
        CursorBench 4.0 (updated 10 September 2026) grades ambiguous, multi-file
        work from real Cursor sessions. Scores are low because the suite got
        harder (edit, refactor, investigation, intent, job management, design
        adherence). A 10-point gap is meaningful; 0.3 points is noise.
      </Text>
      <Grid columns={2} gap={16}>
        <Stack gap={8}>
          <H3>CursorBench 4.0 score (%)</H3>
          <BarChart
            categories={benchModels.map((m) => m.short)}
            series={[
              {
                name: "CursorBench 4.0 score",
                data: benchModels.map((m) => m.cursorbench ?? 0),
              },
            ]}
            horizontal
            height={260}
            valueSuffix="%"
            showValues
            yMax={60}
          />
          <Text size="small" tone="tertiary">
            Source: cursor.com/cursorbench · CursorBench 4.0 · 10 Sep 2026.
            Effort = Max or Extra High as published for that row.
          </Text>
        </Stack>
        <Stack gap={8}>
          <H3>USD per CursorBench 4.0 task</H3>
          <BarChart
            categories={benchModels.map((m) => m.short)}
            series={[
              {
                name: "Published $ / task",
                data: benchModels.map((m) => m.cursorbenchUsd ?? 0),
              },
            ]}
            horizontal
            height={260}
            valuePrefix="$"
            showValues
          />
          <Text size="small" tone="tertiary">
            Source: same CursorBench 4.0 table. Cost applies each model’s
            published input / cache / output rates to tokens actually used.
          </Text>
        </Stack>
      </Grid>

      <H3>SWE-bench Pro (public coding, not Cursor-specific)</H3>
      <BarChart
        categories={["Opus 5.5", "Sonnet 5.5", "Fable 5.1", "Opus 5", "Grok 4.5", "Sol", "Terra"]}
        series={[
          {
            name: "SWE-bench Pro (%)",
            data: [89.9, 81.3, 81.2, 79.2, 64.7, 64.6, 63.4],
          },
        ]}
        height={220}
        valueSuffix="%"
        showValues
        yMax={100}
      />
      <Text size="small" tone="tertiary">
        Source: SWE-bench Pro leaderboard via benchlm.ai, last updated 6 Oct
        2026, retrieved 7 Oct 2026. Grok 4.7 is not listed; Grok 4.5 is shown.
        Claude still leads this harness by a wide margin.
      </Text>

      <H2>Creative writing: judged prose, not agent score</H2>
      <Text>
        EQ-Bench Creative Writing v3 ranks short-form stories by pairwise Elo.
        Claude Fable 5.1 leads this Atlas snapshot among Cursor-listed models.
        Opus 5.5 and Grok 4.7 follow. Treat Elo as a writing taste test, not a
        Cursor coding rank.
      </Text>
      <BarChart
        categories={eloModels.map((m) => m.short)}
        series={[
          {
            name: "EQ-Bench Creative Writing v3 Elo",
            data: eloModels.map((m) => m.eqElo ?? 0),
          },
        ]}
        height={240}
        showValues
        beginAtZero={false}
        yMin={1500}
      />
      <Text size="small" tone="tertiary">
        Source: Creative Writing v3 Elo, Benchmark Atlas snapshot retrieved
        7 Oct 2026. Rank order differs from the mid-2026 snapshot used in
        September. GPT-6 Astra 2,173 is not in Cursor. Grok 4.7 is listed at
        2,007; Grok 4.6 is unlisted.
      </Text>

      <H2>Stock and trading: what we can actually measure</H2>
      <Grid columns={2} gap={16}>
        <Stack gap={8}>
          <H3>Published finance / knowledge scores</H3>
          <BarChart
            categories={["Fable 5.1", "Fable 5", "Opus 5", "Sol"]}
            series={[
              {
                name: "GDPval-AA v2 (higher better)",
                data: [1853, 1723, 1824, 1711],
              },
            ]}
            height={220}
            showValues
            beginAtZero={false}
            yMin={1650}
          />
          <Text size="small" tone="tertiary">
            Source: Anthropic Fable 5.1 announcement, Sep 2026. GDPval-AA v2 is
            knowledge work, not a trading PnL. No new row for Opus 5.5 or
            Sonnet 5.5. FrontierFinance (Fable 5.1 55.9% vs Fable 5 49.2%) was
            quoted there; Sol, Opus 5.5, and Grok were not scored on that same
            table.
          </Text>
        </Stack>
        <Stack gap={8}>
          <H3>What the numbers do not say</H3>
          <Text>
            Jane Street’s head of quant research said Fable 5.1 is state of the
            art on their trading-intuition tests. That is a customer quote, not
            a public leaderboard. No model here sees live bids, fills, or your
            broker. For trading work in Cursor, the practical split is: Luna /
            Haiku / Grok to ingest and outline; Opus or Fable to argue the
            thesis against the filing; you to take the risk.
          </Text>
          <Text>
            Grok’s xAI API can bill extra for web search and X search ($5 per
            1k calls). Cursor agent tools are billed at the model token rates
            above; do not assume xAI tool fees on top unless you are on the xAI
            API directly.
          </Text>
        </Stack>
      </Grid>

      <Divider />

      <H2>Price and context at a glance</H2>
      <Grid columns={2} gap={16}>
        <Stack gap={8}>
          <H3>List price per 1M tokens (USD)</H3>
          <BarChart
            categories={["Grok 4.7", "Fable 5.1", "Opus 5.5", "Sonnet 5.5", "Sol", "Terra", "Luna"]}
            series={[
              { name: "Input $ / 1M", data: [2, 10, 4, 2, 4, 2, 0.2] },
              { name: "Output $ / 1M", data: [6, 50, 20, 10, 20, 12, 1.2] },
            ]}
            height={260}
            valuePrefix="$"
          />
          <Text size="small" tone="tertiary">
            Source: cursor.com/docs/models-and-pricing, 7 Oct 2026. Sol
            promotional pricing through 21 Nov 2026. Grok Fast not shown (2×).
          </Text>
        </Stack>
        <Stack gap={8}>
          <H3>Context window in Cursor (thousand tokens)</H3>
          <BarChart
            categories={["Grok 4.7", "Fable 5.1", "Opus 5.5", "Sonnet 5.5", "Sol", "Terra", "Luna"]}
            series={[
              { name: "Default context (k)", data: [256, 300, 300, 200, 272, 272, 272] },
              { name: "Max context (k)", data: [500, 1000, 1000, 1000, 1000, 1000, 1000] },
            ]}
            height={260}
            valueSuffix="k"
          />
          <Text size="small" tone="tertiary">
            Source: Cursor docs model table. Grok 4.7 default 256k, max 500k
            (long context 2× above 256k; Fast long context 3× standard). GPT-5.6
            max 1M with a price bump after 272k.
          </Text>
        </Stack>
      </Grid>

      <H2>A mixed month in dollars</H2>
      <Text>
        Two pictures. The first is 20 standard features + 8 research memos + 4
        short stories using the token mixes above (formula). The second is 20
        hard CursorBench 4.0 tasks only — closer to a power-user coding month,
        and in line with Cursor’s own “$60–$100 typical daily agent, $200+
        power user” guidance when you live on Fable or Opus.
      </Text>
      <Grid columns={2} gap={16}>
        <Stack gap={8}>
          <H3>20 features + 8 memos + 4 stories (USD)</H3>
          <BarChart
            categories={monthFormula.map((m) => m.short)}
            series={[{ name: "Mixed month (USD)", data: monthFormula.map((m) => Number(m.total.toFixed(2))) }]}
            horizontal
            height={280}
            valuePrefix="$"
            showValues
          />
          <Text size="small" tone="tertiary">
            Formula from the Standard mixes in this report. Cache reads included
            on the coding slice. Excludes retries and Fast multipliers except
            Grok speed selected above.
          </Text>
        </Stack>
        <Stack gap={8}>
          <H3>20 CursorBench 4.0-hard tasks (USD)</H3>
          <BarChart
            categories={monthHard.map((m) => m.short)}
            series={[{ name: "20 hard tasks (USD)", data: monthHard.map((m) => Number(m.total.toFixed(2))) }]}
            horizontal
            height={280}
            valuePrefix="$"
            showValues
          />
          <Text size="small" tone="tertiary">
            20 × published CursorBench 4.0 $/task. Haiku omitted (not measured).
            This is the honest “I live in Agent all day on hard work” bill.
          </Text>
        </Stack>
      </Grid>

      <Callout tone="info" title="How to read the two months">
        If most of your Cursor use is “change this function and add a test,”
        the mixed-month chart is closer to reality and Grok / Sonnet 5.5 Medium /
        Luna stay cheap. If you run long agents on messy repos, the CursorBench
        month is the one that hits Pro Plus / Ultra. Opus 5.5 Max at 20 hard
        tasks is about $269; Fable 5.1 Max is about $346; Grok 4.7 Extra High is
        about $120.
      </Callout>

      <H2>Full catalog in Cursor today</H2>
      <Text>
        Every Grok, Anthropic, and OpenAI row on Cursor’s public model table as
        of this snapshot. “Shown” means not marked hidden-by-default in the
        docs. Hidden models still work if you enable them; they still bill.
        Composer 2.5 is a Cursor model, not Grok/Claude/GPT, so it is omitted
        here (CursorBench 4.0: 27.7% at $0.68/task — cheapest coding floor).
      </Text>
      <Text size="small" tone="tertiary">
        OpenAI’s API now lists GPT-6 Astra ($10 / $50, 1.05M context). It is
        not on Cursor’s model table in this snapshot. Do not assume it is
        selectable in the Cursor picker.
      </Text>

      {(["Grok", "Anthropic", "OpenAI"] as Vendor[]).map((vendor) => {
        const rows = CATALOG.filter((r) => r.vendor === vendor);
        return (
          <div key={vendor}>
            <Card collapsible defaultOpen={vendor === "Grok"}>
              <CardHeader trailing={<Pill size="sm">{rows.length} models</Pill>}>
                {vendor === "Grok" ? "Grok (Cursor / SpaceXAI)" : vendor}
              </CardHeader>
              <CardBody>
                <Table
                  headers={[
                    "Model",
                    "Pool",
                    "In",
                    "Out",
                    "Cache read",
                    "Default ctx",
                    "Max ctx",
                    "Shown",
                    "Notes",
                  ]}
                  columnAlign={[
                    "left",
                    "left",
                    "right",
                    "right",
                    "right",
                    "right",
                    "right",
                    "left",
                    "left",
                  ]}
                  striped
                  stickyHeader
                  rows={rows.map((r) => [
                    r.name,
                    r.pool,
                    `$${r.input}`,
                    `$${r.output}`,
                    `$${r.cacheRead}`,
                    r.ctxDefault,
                    r.ctxMax,
                    r.visible ? "Yes" : "Hidden",
                    r.notes,
                  ])}
                />
              </CardBody>
            </Card>
          </div>
        );
      })}

      <H2>Practical defaults (no single winner)</H2>
      <Table
        headers={["If you care most about…", "Use this first", "Spend up to this", "Skip this"]}
        rows={[
          [
            "Hardest coding in Cursor",
            "Grok 4.7 Extra High (pool + $6.01/task)",
            "Opus 5.5 Max or Sonnet 5.5 Max",
            "Fable 5.1 Max unless you already opted in ($17.28 for 51.8%)",
          ],
          [
            "Licence floor for a team",
            "Teams Standard ($40/user) if you need org features",
            "Pro Plus ($60) per person if you only need daily agent usage",
            "Assuming Enterprise has a public list price (it does not)",
          ],
          [
            "Daily software, included usage",
            "Grok 4.7 (Cursor Models pool)",
            "Sonnet 5.5 High ($1.67, 47.8%), then Opus 5.5 High",
            "Opus 4.7 Fast ($30 / $150)",
          ],
          [
            "Trading research quality",
            "Fable 5.1 for the names that matter",
            "Opus 5.5 if you cannot opt in to Fable data retention",
            "Using Luna as your only analyst",
          ],
          [
            "Literary / voice-heavy writing",
            "Claude Fable 5.1 on this Atlas snapshot",
            "Opus 5.5 or Grok 4.7 for a cheaper strong pass",
            "Treating GPT-6 Astra as selectable in Cursor",
          ],
          [
            "Lowest bill, good enough",
            "GPT-5.6 Luna or Sonnet 5.5 Medium",
            "Haiku 4.5 or Grok 4.7 medium",
            "Fable on every autocomplete-sized ask",
          ],
        ]}
      />

      <Callout tone="neutral" title="Bias check">
        I am Cursor Grok 4.6. CursorBench 4.0 now has Claude Opus 5.5 ahead of
        Fable 5.1 on hard agent work. The 7 Oct 2026 Atlas writing snapshot has
        Fable 5.1 ahead of Opus 5.5 on prose. Grok 4.7’s edge in this report is
        the Cursor Models pool plus Extra High CursorBench at $6.01. That is in
        the published table, not a self-score.
      </Callout>
    </Stack>
  );
}
