{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "iphone-17-pro-max",
  "title": "iPhone 17 Pro Max",
  "description": "Front-facing iPhone 17 Pro Max device frame with silver titanium rail, black rounded bezel, Dynamic Island, and iOS status bar - empty screen by default; optional children slot.",
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/new-york/blocks/iphone-17-pro-max/page.tsx",
      "content": "import Iphone17ProMax from \"./components/iphone-17-pro-max\"\n\nexport default function Page() {\n  return (\n    <div className=\"px-4 py-4 md:px-6 md:py-6\">\n      <Iphone17ProMax />\n    </div>\n  )\n}\n",
      "type": "registry:page",
      "target": "app/iphone-17-pro-max/page.tsx"
    },
    {
      "path": "registry/new-york/blocks/iphone-17-pro-max/components/iphone-17-pro-max.tsx",
      "content": "import { cn } from \"@/lib/utils\"\n\nimport IphoneDynamicIsland from \"./iphone-dynamic-island\"\nimport IphoneScreen, { type IphoneScreenProps } from \"./iphone-screen\"\nimport IphoneStatusBar, {\n  type IphoneStatusBarProps,\n} from \"./iphone-status-bar\"\n\nimport \"../styles/iphone-17-pro-max.css\"\n\ntype Iphone17ProMaxProps = {\n  className?: string\n  statusBar?: Omit<IphoneStatusBarProps, \"className\">\n} & Omit<IphoneScreenProps, \"className\">\n\nexport default function Iphone17ProMax({\n  className,\n  minHeight,\n  aspectRatio = \"1320 / 2740\",\n  statusBar,\n  children,\n}: Iphone17ProMaxProps) {\n  return (\n    <div\n      className={cn(\n        \"ip17-root relative mx-auto w-full max-w-[18rem] min-w-0 drop-shadow-(--ip17-shell-shadow)\",\n        className\n      )}\n      role=\"img\"\n      aria-label=\"iPhone 17 Pro Max device frame mockup\"\n    >\n      {/* Left side buttons: Action + Volume Up/Down */}\n      <span\n        className=\"ip17-button absolute top-[14%] -left-0.5 z-0 h-7 w-0.75 rounded-l-sm\"\n        aria-hidden\n      />\n      <span\n        className=\"ip17-button absolute top-[22%] -left-0.5 z-0 h-11 w-0.75 rounded-l-sm\"\n        aria-hidden\n      />\n      <span\n        className=\"ip17-button absolute top-[32%] -left-0.5 z-0 h-11 w-0.75 rounded-l-sm\"\n        aria-hidden\n      />\n\n      {/* Right side button: Power */}\n      <span\n        className=\"ip17-button absolute top-[26%] -right-0.5 z-0 h-16 w-0.75 rounded-r-sm\"\n        aria-hidden\n      />\n\n      {/*\n        Media fills the shell first; silver rail + black lip are overlays on top.\n        That way corners cannot show a light gap between content and frame.\n      */}\n      <div className=\"ip17-shell relative z-1 overflow-hidden rounded-[3rem]\">\n        <IphoneScreen minHeight={minHeight} aspectRatio={aspectRatio}>\n          {children}\n        </IphoneScreen>\n        <div className=\"ip17-rail-overlay\" aria-hidden />\n        <div className=\"ip17-bezel-overlay\" aria-hidden />\n        <IphoneDynamicIsland />\n        <IphoneStatusBar {...statusBar} />\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "app/iphone-17-pro-max/components/iphone-17-pro-max.tsx"
    },
    {
      "path": "registry/new-york/blocks/iphone-17-pro-max/components/iphone-screen.tsx",
      "content": "import type { CSSProperties, ReactNode } from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport type IphoneScreenProps = {\n  className?: string\n  minHeight?: string | number\n  aspectRatio?: string\n  children?: ReactNode\n}\n\nexport default function IphoneScreen({\n  className,\n  minHeight = \"26rem\",\n  aspectRatio = \"1320 / 2740\",\n  children,\n}: IphoneScreenProps) {\n  const style = {\n    ...(aspectRatio ? { aspectRatio } : {}),\n    minHeight: typeof minHeight === \"number\" ? `${minHeight}px` : minHeight,\n  } satisfies CSSProperties\n\n  return (\n    <div\n      className={cn(\n        \"ip17-screen relative z-1 box-border w-full overflow-hidden rounded-[3rem]\",\n        children ? \"bg-black\" : \"bg-(--ip17-screen)\",\n        className\n      )}\n      style={style}\n    >\n      {children ? (\n        <div className=\"ip17-screen-slot absolute inset-0 overflow-hidden rounded-[inherit]\">\n          {children}\n        </div>\n      ) : null}\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "app/iphone-17-pro-max/components/iphone-screen.tsx"
    },
    {
      "path": "registry/new-york/blocks/iphone-17-pro-max/components/iphone-status-bar.tsx",
      "content": "import { cn } from \"@/lib/utils\"\n\n/** iOS battery fill states: yellow Low Power Mode, red low, green charging. */\nexport type IphoneBatteryState = \"normal\" | \"low-power\" | \"low\" | \"charging\"\n\nexport type IphoneStatusBarProps = {\n  className?: string\n  time?: string\n  signalBars?: 1 | 2 | 3 | 4\n  batteryLevel?: number\n  batteryState?: IphoneBatteryState\n  tint?: \"dark\" | \"light\"\n}\n\n/** Every glyph renders at this exact height so the row reads as one size. */\nconst GLYPH_HEIGHT = 12\n\n/** `normal` inherits the row tint; the rest use scoped iOS system colors. */\nconst BATTERY_FILL: Record<IphoneBatteryState, string> = {\n  normal: \"currentColor\",\n  \"low-power\": \"var(--ip17-battery-low-power)\",\n  low: \"var(--ip17-battery-low)\",\n  charging: \"var(--ip17-battery-charging)\",\n}\n\nfunction SignalBarsIcon({ bars }: { bars: 1 | 2 | 3 | 4 }) {\n  const barHeights = [5, 7.25, 9.5, 12] as const\n\n  return (\n    <svg\n      viewBox=\"0 0 16.5 12\"\n      width=\"16.5\"\n      height={GLYPH_HEIGHT}\n      fill=\"currentColor\"\n      aria-hidden\n    >\n      {barHeights.map((height, index) => (\n        <rect\n          key={height}\n          x={index * 4.5}\n          y={12 - height}\n          width=\"3\"\n          height={height}\n          rx=\"1\"\n          opacity={index < bars ? 1 : 0.3}\n        />\n      ))}\n    </svg>\n  )\n}\n\nfunction WifiIcon() {\n  return (\n    <svg\n      viewBox=\"0 0 16 12\"\n      width=\"16\"\n      height={GLYPH_HEIGHT}\n      fill=\"none\"\n      aria-hidden\n    >\n      <path\n        d=\"M0.8 4.9a9.6 9.6 0 0 1 14.4 0\"\n        stroke=\"currentColor\"\n        strokeWidth=\"1.7\"\n        strokeLinecap=\"round\"\n      />\n      <path\n        d=\"M4.5 8.4a5 5 0 0 1 7 0\"\n        stroke=\"currentColor\"\n        strokeWidth=\"1.7\"\n        strokeLinecap=\"round\"\n      />\n      <circle cx=\"8\" cy=\"10.6\" r=\"1.4\" fill=\"currentColor\" />\n    </svg>\n  )\n}\n\nfunction BatteryIcon({\n  level,\n  state,\n}: {\n  level: number\n  state: IphoneBatteryState\n}) {\n  const clamped = Math.min(100, Math.max(0, level))\n  const fillWidth = (clamped / 100) * 18\n\n  return (\n    <svg\n      viewBox=\"0 0 25 12\"\n      width=\"25\"\n      height={GLYPH_HEIGHT}\n      fill=\"none\"\n      aria-hidden\n    >\n      <rect\n        x=\"0.5\"\n        y=\"0.5\"\n        width=\"21\"\n        height=\"11\"\n        rx=\"3.2\"\n        stroke=\"currentColor\"\n        strokeOpacity=\"0.4\"\n      />\n      <path\n        d=\"M22.8 4.2a1.8 1.8 0 0 1 0 3.6Z\"\n        fill=\"currentColor\"\n        fillOpacity=\"0.4\"\n      />\n      <rect\n        x=\"2\"\n        y=\"2\"\n        width={fillWidth}\n        height=\"8\"\n        rx=\"2\"\n        fill={BATTERY_FILL[state]}\n      />\n      {state === \"charging\" ? (\n        <path\n          d=\"M11.9 2.4 8.2 7.1h2.2l-.9 2.9 3.7-4.9h-2.3z\"\n          fill=\"var(--ip17-bezel)\"\n          fillOpacity=\"0.85\"\n        />\n      ) : null}\n    </svg>\n  )\n}\n\nexport default function IphoneStatusBar({\n  className,\n  time = \"08:00\",\n  signalBars = 4,\n  batteryLevel = 100,\n  batteryState = \"normal\",\n  tint = \"dark\",\n}: IphoneStatusBarProps) {\n  return (\n    <div\n      className={cn(\n        \"pointer-events-none absolute inset-x-0 top-3.5 z-6 flex h-7 items-center justify-between px-5\",\n        tint === \"dark\" ? \"text-black\" : \"text-white\",\n        className\n      )}\n      aria-hidden\n    >\n      <span className=\"text-[0.8125rem] leading-none font-semibold tracking-tight\">\n        {time}\n      </span>\n      <div className=\"flex items-center gap-1.5\">\n        <SignalBarsIcon bars={signalBars} />\n        <WifiIcon />\n        <BatteryIcon level={batteryLevel} state={batteryState} />\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "app/iphone-17-pro-max/components/iphone-status-bar.tsx"
    },
    {
      "path": "registry/new-york/blocks/iphone-17-pro-max/components/iphone-dynamic-island.tsx",
      "content": "import { cn } from \"@/lib/utils\"\n\ntype IphoneDynamicIslandProps = {\n  className?: string\n}\n\nexport default function IphoneDynamicIsland({\n  className,\n}: IphoneDynamicIslandProps) {\n  return (\n    <div\n      className={cn(\n        \"pointer-events-none absolute top-7 left-[51%] z-6 flex h-5 w-[27%] max-w-24 min-w-19 -translate-x-1/2 -translate-y-1/2 items-center justify-end rounded-full bg-(--ip17-island) pr-1.5\",\n        className\n      )}\n      aria-hidden\n    >\n      <span className=\"ip17-camera relative block size-2 shrink-0 rounded-full\" />\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "app/iphone-17-pro-max/components/iphone-dynamic-island.tsx"
    },
    {
      "path": "registry/new-york/blocks/iphone-17-pro-max/styles/iphone-17-pro-max.css",
      "content": "/* iphone-17-pro-max — silver titanium tokens, rail/button gradients, camera pseudo-elements */\n\n.ip17-root {\n  --ip17-silver-light: #cfcfd3;\n  --ip17-silver-mid: #b4b4b9;\n  --ip17-silver-dark: #96969c;\n  --ip17-silver-deep: #7a7a80;\n  --ip17-bezel: #060608;\n  --ip17-screen: #f5f5f7;\n  --ip17-island: #0a0a0c;\n  --ip17-frame-highlight: rgb(255 255 255 / 0.45);\n  --ip17-frame-shadow: rgb(0 0 0 / 0.28);\n  --ip17-shell-shadow: 0 24px 48px -16px rgb(0 0 0 / 0.28);\n  --ip17-shell-ring: rgb(0 0 0 / 0.14);\n  --ip17-button: #b0b0b5;\n  --ip17-button-edge: #909096;\n  --ip17-rail-width: 3px;\n  --ip17-bezel-width: 3.5px;\n  --ip17-battery-low-power: #ffd60a;\n  --ip17-battery-low: #ff453a;\n  --ip17-battery-charging: #34c759;\n}\n\n.dark .ip17-root {\n  --ip17-shell-shadow: 0 28px 56px -16px rgb(0 0 0 / 0.55);\n  --ip17-shell-ring: rgb(255 255 255 / 0.1);\n}\n\n.ip17-shell {\n  box-shadow: 0 0 0 1px var(--ip17-shell-ring);\n}\n\n/*\n  Silver titanium ring drawn as an overlay (masked gradient border).\n  Center stays transparent so media underneath shows through.\n*/\n.ip17-rail-overlay {\n  position: absolute;\n  inset: 0;\n  z-index: 5;\n  border-radius: inherit;\n  pointer-events: none;\n  padding: var(--ip17-rail-width);\n  background: linear-gradient(\n    180deg,\n    var(--ip17-silver-light) 0%,\n    var(--ip17-silver-mid) 55%,\n    var(--ip17-silver-dark) 100%\n  );\n  box-shadow:\n    inset 0 1px 0 var(--ip17-frame-highlight),\n    inset 0 -1px 0 var(--ip17-frame-shadow);\n  -webkit-mask:\n    linear-gradient(#fff 0 0) content-box,\n    linear-gradient(#fff 0 0);\n  -webkit-mask-composite: xor;\n  mask:\n    linear-gradient(#fff 0 0) content-box,\n    linear-gradient(#fff 0 0);\n  mask-composite: exclude;\n}\n\n/* Black display lip on top of media — separates content from the silver ring. */\n.ip17-bezel-overlay {\n  position: absolute;\n  inset: var(--ip17-rail-width);\n  z-index: 5;\n  border-radius: calc(3rem - var(--ip17-rail-width));\n  pointer-events: none;\n  box-shadow: inset 0 0 0 var(--ip17-bezel-width) var(--ip17-bezel);\n}\n\n.ip17-button {\n  background: linear-gradient(\n    180deg,\n    var(--ip17-silver-light) 0%,\n    var(--ip17-button) 45%,\n    var(--ip17-button-edge) 100%\n  );\n  box-shadow:\n    inset 0 1px 0 rgb(255 255 255 / 0.45),\n    inset 0 -1px 0 rgb(0 0 0 / 0.2),\n    0 0 0 0.5px rgb(0 0 0 / 0.12);\n}\n\n.ip17-camera {\n  background: radial-gradient(\n    circle at 38% 32%,\n    #2e2e38 0%,\n    #17171e 42%,\n    #0a0a0e 78%,\n    #050507 100%\n  );\n  box-shadow:\n    0 0 0 1px rgb(0 0 0 / 0.7),\n    inset 0 1px 1.5px rgb(0 0 0 / 0.6),\n    inset 0 -0.5px 0 rgb(255 255 255 / 0.05);\n}\n\n.ip17-camera::before {\n  content: \"\";\n  position: absolute;\n  inset: 22%;\n  border-radius: 50%;\n  background: radial-gradient(circle at 40% 35%, #181820 0%, #08080c 100%);\n  box-shadow: inset 0 0 1px rgb(0 0 0 / 0.8);\n}\n\n.ip17-camera::after {\n  content: \"\";\n  position: absolute;\n  top: 22%;\n  left: 30%;\n  width: 28%;\n  height: 28%;\n  border-radius: 50%;\n  background: radial-gradient(\n    circle at 50% 50%,\n    rgb(255 255 255 / 0.35) 0%,\n    rgb(255 255 255 / 0.08) 55%,\n    transparent 100%\n  );\n}\n\n.ip17-screen-slot > * {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  /* Overscale so object-cover media fully covers the curved clip, including AA fringe. */\n  transform: scale(1.08);\n  transform-origin: center;\n}\n",
      "type": "registry:file",
      "target": "app/iphone-17-pro-max/styles/iphone-17-pro-max.css"
    }
  ],
  "type": "registry:block"
}