> ## Documentation Index
> Fetch the complete documentation index at: https://openai-hd4n6.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Compare Models

export const ModelCard = ({img, href, title, description}) => {
  return <a href={href} target="_blank" rel="noopener noreferrer" className="group">
      <div className="flex flex-col gap-4 rounded-xl ">
        <div className="w-full h-40 overflow-hidden rounded-xl">
          <img src={img} className="w-full h-full object-cover" alt={title} />
        </div>
        <div className="flex flex-col gap-3">
          <h2 className="text-xl font-medium text-gray-900 dark:text-gray-200 group-hover:text-[#10a37f] dark:group-hover:text-[#10a37f] transition-colors">
            {title}
          </h2>
          <p className="text-gray-600 dark:text-gray-400 text-md">
            {description}
          </p>
        </div>
      </div>
    </a>;
};

export const ModelSpecs = ({modelName}) => {
  const modelData = {
    'o4-mini': {
      reasoning: 4,
      speed: 3,
      intelligence: 4,
      input: {
        text: true,
        image: true,
        audio: false
      },
      output: {
        text: true,
        image: false,
        audio: false
      },
      reasoningTokens: true,
      pricing: {
        input: '$1.10',
        cachedInput: '$0.28',
        output: '$4.40'
      },
      context: {
        window: '200,000',
        maxOutputTokens: '100,000'
      },
      knowledgeCutoff: 'May 31, 2024'
    },
    'o3': {
      reasoning: 5,
      speed: 1,
      intelligence: 5,
      input: {
        text: true,
        image: true,
        audio: false
      },
      output: {
        text: true,
        image: false,
        audio: false
      },
      reasoningTokens: true,
      pricing: {
        input: '$2.00',
        cachedInput: '$0.50',
        output: '$8.00'
      },
      context: {
        window: '200,000',
        maxOutputTokens: '100,000'
      },
      knowledgeCutoff: 'May 31, 2024'
    },
    'GPT-4.1': {
      reasoning: 4,
      speed: 3,
      intelligence: 4,
      input: {
        text: true,
        image: true,
        audio: false
      },
      output: {
        text: true,
        image: false,
        audio: false
      },
      reasoningTokens: false,
      pricing: {
        input: '$2.00',
        cachedInput: '$0.50',
        output: '$8.00'
      },
      context: {
        window: '1,047,576',
        maxOutputTokens: '32,768'
      },
      knowledgeCutoff: 'May 31, 2024'
    }
  };
  const data = modelData[modelName];
  if (!data) return null;
  const renderRatingDots = (rating, maxRating = 5) => {
    return <div className="flex gap-1">
        {[...Array(maxRating)].map((_, i) => <div key={i} className={`w-2 h-2 rounded-full ${i < rating ? 'bg-primary dark:bg-white' : 'bg-gray-400 dark:bg-gray-600'}`} />)}
      </div>;
  };
  const renderSpeedIcons = speed => {
    return <div className="flex gap-1">
        {[...Array(3)].map((_, i) => <svg key={i} className={`w-4 h-4 ${i < speed ? 'text-primary dark:text-white' : 'text-gray-400 dark:text-gray-600'}`} width="1em" height="1em" viewBox="0 0 25 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
            <path d="M13.0431 2.16652C14.2385 0.779832 16.4914 1.92781 16.0721 3.70998L15.0626 8.00002H20.1177C21.829 8.00002 22.7499 10.0097 21.6325 11.3059L12.557 21.8335C11.3615 23.2202 9.10867 22.0722 9.528 20.2901L10.5374 16H5.48239C3.77101 16 2.85015 13.9903 3.96757 12.6941L13.0431 2.16652Z" fill="currentColor" />
          </svg>)}
      </div>;
  };
  const renderIntelligenceIcons = intelligence => {
    return <div className="flex gap-1">
        {[...Array(4)].map((_, i) => <svg key={i} className={`w-4 h-4 ${i < intelligence ? 'text-primary dark:text-white' : 'text-gray-400 dark:text-gray-600'}`} width="1em" height="1em" viewBox="0 0 25 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
            <path d="M15.9692 16.9915C16.4483 16.9915 16.9257 16.8817 17.3266 16.6192C19.5768 15.1458 20.8496 13.1405 20.8496 10.25C20.8496 5.69365 17.156 2 12.5996 2C8.04326 2 4.34961 5.69365 4.34961 10.25C4.34961 13.1405 5.65945 15.1458 7.90964 16.6192C8.31051 16.8817 8.78789 16.9915 9.26705 16.9915H15.9692Z" fill="currentColor" />
            <path d="M8.22852 18.918C8.22852 18.7109 8.37305 18.5908 8.60337 18.5908H16.6111C16.8246 18.5908 16.9706 18.7231 16.9706 18.9718C16.9706 21.2421 15.1268 22.9585 12.8565 22.9585H12.3427C10.0724 22.9585 8.22852 21.1883 8.22852 18.918Z" fill="currentColor" />
          </svg>)}
      </div>;
  };
  const renderInputOutputIcons = capabilities => {
    const textIcon = <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 24 24">
        <path fillRule="evenodd" d="M8 9a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v1a1 1 0 1 1-2 0h-1v4a1 1 0 1 1 0 2h-2a1 1 0 1 1 0-2v-4h-1a1 1 0 1 1-2 0V9Z" clipRule="evenodd" />
        <path fillRule="evenodd" d="M10.357 3h3.286c1.084 0 1.958 0 2.666.058.729.06 1.369.185 1.961.487a5 5 0 0 1 2.185 2.185c.302.592.428 1.233.487 1.961C21 8.4 21 9.273 21 10.357v3.286c0 1.084 0 1.958-.058 2.666-.06.729-.185 1.369-.487 1.961a5 5 0 0 1-2.185 2.185c-.592.302-1.232.428-1.961.487C15.6 21 14.727 21 13.643 21h-3.286c-1.084 0-1.958 0-2.666-.058-.728-.06-1.369-.185-1.96-.487a5 5 0 0 1-2.186-2.185c-.302-.592-.428-1.232-.487-1.961C3 15.6 3 14.727 3 13.643v-3.286c0-1.084 0-1.958.058-2.666.06-.728.185-1.369.487-1.96A5 5 0 0 1 5.73 3.544c.592-.302 1.233-.428 1.961-.487C8.4 3 9.273 3 10.357 3ZM7.854 5.051c-.605.05-.953.142-1.216.276a3 3 0 0 0-1.311 1.311c-.134.263-.226.611-.276 1.216C5.001 8.471 5 9.264 5 10.4v3.2c0 1.137 0 1.929.051 2.546.05.605.142.953.276 1.216a3 3 0 0 0 1.311 1.311c.263.134.611.226 1.216.276.617.05 1.41.051 2.546.051h3.2c1.137 0 1.929 0 2.546-.051.605-.05.953-.142 1.216-.276a3 3 0 0 0 1.311-1.311c.134-.263.226-.611.276-1.216.05-.617.051-1.41.051-2.546v-3.2c0-1.137 0-1.929-.051-2.546-.05-.605-.142-.953-.276-1.216a3 3 0 0 0-1.311-1.311c-.263-.134-.611-.226-1.216-.276C15.529 5.001 14.736 5 13.6 5h-3.2c-1.137 0-1.929 0-2.546.051Z" clipRule="evenodd" />
      </svg>;
    const imageIcon = <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 24 24">
        <path d="M8.759 3h6.482c.805 0 1.47 0 2.01.044.563.046 1.08.145 1.565.392a4 4 0 0 1 1.748 1.748c.247.485.346 1.002.392 1.564C21 7.29 21 7.954 21 8.758v6.483c0 .805 0 1.47-.044 2.01-.046.563-.145 1.08-.392 1.565a4 4 0 0 1-1.748 1.748c-.485.247-1.002.346-1.564.392-.541.044-1.206.044-2.01.044H8.758c-.805 0-1.47 0-2.01-.044-.563-.046-1.08-.145-1.565-.392a4 4 0 0 1-1.748-1.748c-.247-.485-.346-1.002-.392-1.564C3 16.71 3 16.046 3 15.242V8.758c0-.805 0-1.47.044-2.01.046-.563.145-1.08.392-1.565a4 4 0 0 1 1.748-1.748c.485-.247 1.002-.346 1.564-.392C7.29 3 7.954 3 8.758 3ZM6.91 5.038c-.438.035-.663.1-.819.18a2 2 0 0 0-.874.874c-.08.156-.145.38-.18.819C5.001 8.471 5 9.264 5 10.4v4.786l.879-.879a3 3 0 0 1 4.242 0l6.286 6.286c.261-.005.484-.014.682-.03.438-.036.663-.101.819-.181a2 2 0 0 0 .874-.874c.08-.156.145-.38.18-.819.037-.45.038-1.032.038-1.889V8.8c0-.857 0-1.439-.038-1.889-.035-.438-.1-.663-.18-.819a2 2 0 0 0-.874-.874c-.156-.08-.38-.145-.819-.18C16.639 5 16.057 5 15.2 5H8.8c-.857 0-1.439 0-1.889.038ZM13.586 19l-4.879-4.879a1 1 0 0 0-1.414 0l-2.286 2.286c.005.261.014.484.03.682.036.438.101.663.181.819a2 2 0 0 0 .874.874c.156.08.38.145.819.18C7.361 19 7.943 19 8.8 19h4.786ZM14.5 8.5a1 1 0 1 0 0 2 1 1 0 0 0 0-2Zm-3 1a3 3 0 1 1 6 0 3 3 0 0 1-6 0Z" />
      </svg>;
    const audioDisabledIcon = <svg width="1em" height="1em" xmlns="http://www.w3.org/2000/svg">
        <defs>
          <mask id="maskSubtract" x="0" y="0" width="1em" height="1em">
            <rect width="1em" height="1em" fill="white" />
            <path fillRule="evenodd" clipRule="evenodd" d="M1.58594 4.06069L4.06081 1.58582L22.475 20L20.0002 22.4749L1.58594 4.06069Z" fill="black" />
          </mask>
        </defs>
        <g mask="url(#maskSubtract)">
          <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 24 24">
            <path fillRule="evenodd" d="M10.357 3h3.286c1.084 0 1.958 0 2.666.058.729.06 1.369.185 1.961.487a5 5 0 0 1 2.185 2.185c.302.592.428 1.233.487 1.961C21 8.4 21 9.273 21 10.357v3.286c0 1.084 0 1.958-.058 2.666-.06.729-.185 1.369-.487 1.961a5 5 0 0 1-2.185 2.185c-.592.302-1.232.428-1.961.487C15.6 21 14.727 21 13.643 21h-3.286c-1.084 0-1.958 0-2.666-.058-.728-.06-1.369-.185-1.96-.487a5 5 0 0 1-2.186-2.185c-.302-.592-.428-1.232-.487-1.961C3 15.6 3 14.727 3 13.643v-3.286c0-1.084 0-1.958.058-2.666.06-.728.185-1.369.487-1.96A5 5 0 0 1 5.73 3.544c.592-.302 1.233-.428 1.961-.487C8.4 3 9.273 3 10.357 3ZM7.854 5.051c-.605.05-.953.142-1.216.276a3 3 0 0 0-1.311 1.311c-.134.263-.226.611-.276 1.216C5.001 8.471 5 9.264 5 10.4v3.2c0 1.137 0 1.929.051 2.546.05.605.142.953.276 1.216a3 3 0 0 0 1.311 1.311c.263.134.611.226 1.216.276.617.05 1.41.051 2.546.051h3.2c1.137 0 1.929 0 2.546-.051.605-.05.953-.142 1.216-.276a3 3 0 0 0 1.311-1.311c.134-.263.226-.611.276-1.216.05-.617.051-1.41.051-2.546v-3.2c0-1.137 0-1.929-.051-2.546-.05-.605-.142-.953-.276-1.216a3 3 0 0 0-1.311-1.311c-.263-.134-.611-.226-1.216-.276C15.529 5.001 14.736 5 13.6 5h-3.2c-1.137 0-1.929 0-2.546.051Z" clipRule="evenodd" />
            <path fillRule="evenodd" d="M12 7.5a1 1 0 0 1 1 1v7a1 1 0 1 1-2 0v-7a1 1 0 0 1 1-1Zm4 2a1 1 0 0 1 1 1v3a1 1 0 1 1-2 0v-3a1 1 0 0 1 1-1Zm-8 0a1 1 0 0 1 1 1v3a1 1 0 1 1-2 0v-3a1 1 0 0 1 1-1Z" clipRule="evenodd" />
          </svg>
        </g>
        <svg width="1em" height="1em" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
          <path d="M18.1162 19.8839L18.4697 20.2375L18.8233 19.8839L19.8839 18.8233L20.2375 18.4697L19.8839 18.1162L2.88394 1.11617L2.53039 0.76262L2.17683 1.11617L1.11617 2.17683L0.76262 2.53039L1.11617 2.88394L18.1162 19.8839Z" fill="currentColor" stroke="var(--bg-color)" />
        </svg>
      </svg>;
    return <div className="flex gap-1">
        <span className={capabilities.text ? 'text-primary dark:text-white' : 'text-gray-400 dark:text-gray-600'}>{textIcon}</span>
        <span className={capabilities.image ? 'text-primary dark:text-white' : 'text-gray-400 dark:text-gray-600'}>{imageIcon}</span>
        <span className={capabilities.audio ? 'text-primary dark:text-white' : 'text-gray-400 dark:text-gray-600'}>{audioDisabledIcon}</span>
      </div>;
  };
  const renderReasoningTokens = hasReasoningTokens => {
    const checkIcon = <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 24 24">
        <path fillRule="evenodd" d="M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12Zm14.076-4.068a1 1 0 0 1 .242 1.393l-4.75 6.75a1 1 0 0 1-1.558.098l-2.5-2.75a1 1 0 0 1 1.48-1.346l1.66 1.827 4.032-5.73a1 1 0 0 1 1.394-.242Z" clipRule="evenodd" />
      </svg>;
    const xIcon = <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 24 24">
        <path d="M10.207 8.793a1 1 0 0 0-1.414 1.414L10.586 12l-1.793 1.793a1 1 0 1 0 1.414 1.414L12 13.414l1.793 1.793a1 1 0 0 0 1.414-1.414L13.414 12l1.793-1.793a1 1 0 0 0-1.414-1.414L12 10.586l-1.793-1.793Z" />
        <path fillRule="evenodd" d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Z" clipRule="evenodd" />
      </svg>;
    return <span className={hasReasoningTokens ? 'text-green-400' : 'text-red-400'}>
        {hasReasoningTokens ? checkIcon : xIcon}
      </span>;
  };
  return <div className="text-gray-900 dark:text-white mt-6 w-full">
      <div className="border-b border-gray-700" />
      <div className="space-y-0 mb-8">
        <div className="flex justify-between items-center py-4 border-b border-gray-700">
          <span className="text-gray-600 dark:text-gray-300 text-sm">Reasoning</span>
          {renderIntelligenceIcons(data.reasoning)}
        </div>
        
        <div className="flex justify-between items-center py-4 border-b border-gray-700">
          <span className="text-gray-600 dark:text-gray-300 text-sm">Speed</span>
          {renderSpeedIcons(data.speed)}
        </div>
        
        <div className="flex justify-between items-center py-4 border-b border-gray-700">
          <span className="text-gray-600 dark:text-gray-300 text-sm">Intelligence</span>
          {renderRatingDots(data.intelligence)}
        </div>
        
        <div className="flex justify-between items-center py-4 border-b border-gray-700">
          <span className="text-gray-600 dark:text-gray-300 text-sm">Input</span>
          {renderInputOutputIcons(data.input)}
        </div>
        
        <div className="flex justify-between items-center py-4 border-b border-gray-700">
          <span className="text-gray-600 dark:text-gray-300 text-sm">Output</span>
          {renderInputOutputIcons(data.output)}
        </div>
        
        <div className="flex justify-between items-center py-4 border-b border-gray-700">
          <span className="text-gray-600 dark:text-gray-300 text-sm">Reasoning tokens</span>
          {renderReasoningTokens(data.reasoningTokens)}
        </div>
      </div>

      
      <div className="pt-8 mb-8">
        <div className="flex justify-between items-center mb-4">
          <span className="text-gray-500 dark:text-gray-400 text-xs font-semibold uppercase">PRICING</span>
          <span className="text-gray-500 dark:text-gray-400 text-xs">PER 1M TOKENS</span>
        </div>
        
        <div className="space-y-0">
          <div className="flex justify-between py-4 border-b border-gray-700">
            <span className="text-gray-600 dark:text-gray-300 text-sm">Input</span>
            <span className="text-gray-900 dark:text-white font-mono">{data.pricing.input}</span>
          </div>
          
          <div className="flex justify-between py-4 border-b border-gray-700">
            <span className="text-gray-600 dark:text-gray-300 text-sm">Cached Input</span>
            <span className="text-gray-900 dark:text-white font-mono">{data.pricing.cachedInput}</span>
          </div>
          
          <div className="flex justify-between py-4 border-b border-gray-700">
            <span className="text-gray-600 dark:text-gray-300 text-sm">Output</span>
            <span className="text-gray-900 dark:text-white font-mono">{data.pricing.output}</span>
          </div>
        </div>
      </div>

     
      <div className="pt-8">
        <div className="text-gray-500 dark:text-gray-400 text-xs font-semibold uppercase mb-4">CONTEXT</div>
        
        <div className="space-y-0">
          <div className="flex justify-between py-4 border-b border-gray-700">
            <span className="text-gray-600 dark:text-gray-300 text-sm">Window</span>
            <span className="text-gray-900 dark:text-white">{data.context.window}</span>
          </div>
          
          <div className="flex justify-between py-4 border-b border-gray-700">
            <span className="text-gray-600 dark:text-gray-300 text-sm">Max Output Tokens</span>
            <span className="text-gray-900 dark:text-white ">{data.context.maxOutputTokens}</span>
          </div>
          
          <div className="flex justify-between py-4 border-b border-gray-700">
            <span className="text-gray-600 dark:text-gray-300 text-sm">Knowledge Cutoff</span>
            <span className="text-gray-900 dark:text-white ">{data.knowledgeCutoff}</span>
          </div>
        </div>
      </div>
    </div>;
};

export const ModelSelector = ({label = "Select Model", options = [], selected, setSelected, searchable = true, placeholder = "Search models..."}) => {
  const [dropdownOpen, setDropdownOpen] = useState(false);
  const [searchTerm, setSearchTerm] = useState('');
  const filteredOptions = searchable ? options.filter(option => option.toLowerCase().includes(searchTerm.toLowerCase())) : options;
  const handleOptionClick = option => {
    setSelected(option);
    setDropdownOpen(false);
    setSearchTerm('');
  };
  return <div className="relative inline-block w-full max-w-md">
      {dropdownOpen && <div className="fixed inset-0 z-10" onClick={() => {
    setDropdownOpen(false);
    setSearchTerm('');
  }} />}
      
      <button className="w-full px-4 py-3 bg-primary-light dark:bg-[#202123] dark:text-white text-gray-900 rounded-lg border border-gray-600 hover:border-gray-500 flex items-center justify-between transition-colors" onClick={() => setDropdownOpen(!dropdownOpen)}>
        <span className="text-left text-sm">
          {selected || label}
        </span>
        <svg className={`w-3 h-3 transition-transform duration-200 ${dropdownOpen ? 'rotate-180' : ''}`} fill="currentColor" viewBox="0 0 24 24">
          <path d="M7 10l5 5 5-5z" />
        </svg>
      </button>

      {dropdownOpen && <div className="absolute z-20 w-full mt-2 bg-primary-light dark:bg-[#202123] text-gray-900 dark:text-white border border-gray-600 rounded-lg shadow-xl max-h-80 overflow-hidden">
         
          {searchable && <div className="p-3 border-b border-gray-600">
              <div className="relative">
                <svg className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-900 dark:text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <circle cx="11" cy="11" r="8" />
                  <path d="M21 21l-4.35-4.35" />
                </svg>
                <input type="text" placeholder={placeholder} value={searchTerm} onChange={e => setSearchTerm(e.target.value)} className="w-full pl-10 pr-4 py-2 bg-primary-light dark:bg-[#202123] text-gray-900 dark:text-white rounded-lg border-2 border-[#10a37f] focus:border-green-00 focus:outline-none placeholder-gray-900 dark:placeholder-gray-400 text-sm" autoFocus />
              </div>
            </div>}

          <div className="max-h-60 overflow-y-auto">
            {filteredOptions.length > 0 ? filteredOptions.map((option, index) => <button key={index} onClick={() => handleOptionClick(option)} className={`w-full px-4 py-2.5 text-left hover:bg-primary-light dark:hover:bg-[#202123] transition-colors flex items-center justify-between text-sm ${selected === option ? 'bg-primary-light dark:bg-[#202123] text-gray-900 dark:text-white' : 'text-gray-900 dark:text-white'}`}>
                  <span>{option}</span>
                  {selected === option && <svg className="w-4 h-4 text-[#10a37f]" fill="currentColor" viewBox="0 0 20 20">
                      <path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
                    </svg>}
                </button>) : <div className="px-4 py-8 text-center text-gray-400">
                <div className="text-sm">No models found</div>
                <div className="text-xs mt-1">Try adjusting your search</div>
              </div>}
          </div>
        </div>}
    </div>;
};

export const LearnTitle = ({children}) => {
  return <div className="text-gray-900 dark:text-gray-200 text-4xl font-bold tracking-tight">
      {children}
    </div>;
};

export const availableModels = ['o4-mini', 'o3', 'GPT-4.1'];

export const CompareModelsLayout = () => {
  const [selectedModel1, setSelectedModel1] = useState('GPT-4.1');
  const [selectedModel2, setSelectedModel2] = useState('o4-mini');
  const [selectedModel3, setSelectedModel3] = useState('o3');
  const getModelDetails = model => {
    switch (model) {
      case 'o4-mini':
        return {
          title: 'o4-mini',
          description: 'Faster, more affordable reasoning model',
          img: 'https://mintlify-assets.b-cdn.net/o4-mini.svg'
        };
      case 'o3':
        return {
          title: 'o3',
          description: 'Our most powerful reasoning model',
          img: 'https://mintlify-assets.b-cdn.net/o3-image.svg'
        };
      case 'GPT-4.1':
        return {
          title: 'GPT-4.1',
          description: 'Flagship GPT model for complex tasks',
          img: 'https://mintlify-assets.b-cdn.net/gpt-4.1.svg'
        };
      default:
        return null;
    }
  };
  const renderColumn = (defaultModel, selectedModel, setSelectedModel) => {
    const modelDetail = getModelDetails(selectedModel);
    return <div className="flex flex-col gap-6 w-full max-w-xl mx-auto">
        <ModelSelector label="Choose Model" options={availableModels} selected={selectedModel} setSelected={setSelectedModel} placeholder="Search models..." />
      
        <div className="h-full">
          <ModelCard title={modelDetail.title} description={modelDetail.description} href="#" img={modelDetail.img} />
        </div>
      
        <div className="flex gap-4">
          <a href="#" className="button-link px-6 py-2 rounded-full border border-gray-600 dark:border-gray-500 text-gray-900 dark:text-white hover:bg-gray-300 dark:hover:bg-gray-700/50">
            Learn more
          </a>
          <a href="#" className="button-link px-6 py-2 rounded-full bg-[#202123] dark:bg-gray-100 text-white dark:text-gray-900 hover:bg-gray-700 dark:hover:bg-gray-300">
            Playground
          </a>
        </div>
      
        <ModelSpecs modelName={selectedModel} />
      </div>;
  };
  return <div className="grid grid-cols-1 lg:grid-cols-3 gap-8 max-w-7xl mx-auto">
      {renderColumn('o4-mini', selectedModel2, setSelectedModel2)}
      {renderColumn('o3', selectedModel3, setSelectedModel3)}
      {renderColumn('GPT-4.1', selectedModel1, setSelectedModel1)}
    </div>;
};

<div className="frame-context">
  <h1 className="text-3xl text-gray-900 dark:text-gray-200 font-bold">Compare Models</h1>

  <p className="text-[#3D4045] dark:text-gray-300 font-medium text-[1.05rem] mb-1 mt-1 pb-8">
    Explore all available models and compare their capabilities.
  </p>

  <CompareModelsLayout />
</div>
