{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "hardware",
  "title": "Hardware95 foundation",
  "description": "The base of every Hardware95 part: shared material, legend, accent, bevel and shadow tokens, a matte plastic Faceplate in putty, cream or khaki, printed Legend text and a glass pilot Lamp.",
  "files": [
    {
      "path": "components/hardware/hardware.css",
      "content": ":where([data-hw]):not(:where([data-hw] [data-hw])) {\n  --hw-body: #d8d0bd;\n  --hw-body-hi: #efe9dc;\n  --hw-body-lo: #b3a993;\n  --hw-seam: #9d937d;\n  --hw-recess: #1f1e1c;\n  --hw-recess-hi: #3b3936;\n  --hw-legend: #2b2722;\n  --hw-red: #c4472f;\n  --hw-red-lit: #ff7452;\n  --hw-amber: #d39a33;\n  --hw-amber-lit: #ffc865;\n  --hw-green: #5fae72;\n  --hw-green-lit: #a6f5b4;\n  --hw-slate: #5d6977;\n  --hw-shadow-tint: 46 36 24;\n  --hw-font: \"DIN Condensed\", \"DIN Alternate\", \"Roboto Condensed\", \"Arial Narrow\", \"Helvetica Neue\", Helvetica, sans-serif;\n  --hw-grain: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' seed='4'/%3E%3CfeColorMatrix values='0 0 0 0 0.42 0 0 0 0 0.37 0 0 0 0 0.3 0 0 0 0.22 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E\");\n  --hw-bevel-raised: inset 1.5px 1.5px 0 var(--hw-body-hi), inset -1.5px -1.5px 0 var(--hw-body-lo), inset 0 0 0 1px rgb(var(--hw-shadow-tint) / 0.12);\n  --hw-bevel-recess: inset 2px 2px 5px rgb(0 0 0 / 0.55), inset -1px -1px 0 rgb(255 255 255 / 0.07);\n  --hw-shadow-ambient: 0 1px 1px rgb(var(--hw-shadow-tint) / 0.18), 0 8px 16px -6px rgb(var(--hw-shadow-tint) / 0.3), 0 22px 40px -16px rgb(var(--hw-shadow-tint) / 0.35);\n  --hw-shadow-part: 1px 2px 2px rgb(var(--hw-shadow-tint) / 0.45), 3px 7px 10px -3px rgb(var(--hw-shadow-tint) / 0.35);\n  font-family: var(--hw-font);\n  color: var(--hw-legend);\n  -webkit-user-select: none;\n  user-select: none;\n}\n\n[data-hw] [data-part=\"legend\"] {\n  font-family: var(--hw-font);\n  font-size: 11px;\n  font-weight: 700;\n  font-stretch: condensed;\n  letter-spacing: 0.08em;\n  line-height: 1;\n  text-transform: uppercase;\n  color: var(--hw-legend);\n  white-space: nowrap;\n  opacity: 0.92;\n}\n\n[data-hw] [data-part=\"legend\"][data-size=\"sm\"] {\n  font-size: 9px;\n}\n\n[data-hw] [data-part=\"legend\"][data-size=\"lg\"] {\n  font-size: 18px;\n  letter-spacing: 0.04em;\n}\n\n[data-part=\"faceplate\"] {\n  position: relative;\n  isolation: isolate;\n  padding: 30px 34px;\n  border-radius: 16px;\n  background: var(--hw-grain), linear-gradient(160deg, var(--hw-body-hi) -30%, var(--hw-body) 35%, var(--hw-body) 70%, var(--hw-body-lo) 140%);\n  background-blend-mode: multiply, normal;\n  box-shadow: var(--hw-bevel-raised), var(--hw-shadow-ambient);\n}\n\n[data-part=\"faceplate\"]::before {\n  content: \"\";\n  position: absolute;\n  inset: 7px;\n  z-index: -1;\n  border-radius: 11px;\n  pointer-events: none;\n  box-shadow:\n    inset 1px 1px 0 rgb(var(--hw-shadow-tint) / 0.32),\n    1px 1px 0 var(--hw-body-hi);\n}\n\n[data-part=\"faceplate\"][data-finish=\"cream\"] {\n  --hw-body: #e9e2d0;\n  --hw-body-hi: #f9f5eb;\n  --hw-body-lo: #c6bca6;\n  --hw-seam: #b0a68f;\n}\n\n[data-part=\"faceplate\"][data-finish=\"khaki\"] {\n  --hw-body: #c8c09e;\n  --hw-body-hi: #e1dbbe;\n  --hw-body-lo: #a29a76;\n  --hw-seam: #8f876a;\n}\n\n[data-part=\"screw\"] {\n  position: absolute;\n  width: 10px;\n  height: 10px;\n  border-radius: 50%;\n  background: radial-gradient(circle at 38% 34%, #8a857c, #5d5952 60%, #45423d);\n  box-shadow:\n    inset 0 0 0 1px rgb(0 0 0 / 0.25),\n    1px 1px 0 var(--hw-body-hi),\n    -0.5px -0.5px 0 rgb(var(--hw-shadow-tint) / 0.35);\n}\n\n[data-part=\"screw\"]::before {\n  content: \"\";\n  position: absolute;\n  inset: 4px 1.5px;\n  border-radius: 1px;\n  background: #2b2925;\n  box-shadow: 0 0.5px 0 rgb(255 255 255 / 0.18);\n  transform: rotate(var(--hw-screw-turn));\n}\n\n[data-part=\"screw\"][data-corner=\"top-left\"] {\n  top: 13px;\n  left: 13px;\n  --hw-screw-turn: 17deg;\n}\n\n[data-part=\"screw\"][data-corner=\"top-right\"] {\n  top: 13px;\n  right: 13px;\n  --hw-screw-turn: -32deg;\n}\n\n[data-part=\"screw\"][data-corner=\"bottom-left\"] {\n  bottom: 13px;\n  left: 13px;\n  --hw-screw-turn: 61deg;\n}\n\n[data-part=\"screw\"][data-corner=\"bottom-right\"] {\n  bottom: 13px;\n  right: 13px;\n  --hw-screw-turn: 4deg;\n}\n\n[data-part=\"lamp\"] {\n  --hw-lamp: var(--hw-red);\n  --hw-lamp-lit: var(--hw-red-lit);\n  display: inline-flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 8px;\n  vertical-align: middle;\n}\n\n[data-part=\"lamp\"][data-tone=\"amber\"] {\n  --hw-lamp: var(--hw-amber);\n  --hw-lamp-lit: var(--hw-amber-lit);\n}\n\n[data-part=\"lamp\"][data-tone=\"green\"] {\n  --hw-lamp: var(--hw-green);\n  --hw-lamp-lit: var(--hw-green-lit);\n}\n\n[data-part=\"lamp-bezel\"] {\n  position: relative;\n  display: grid;\n  place-items: center;\n  width: 26px;\n  height: 26px;\n  border-radius: 50%;\n  background:\n    repeating-conic-gradient(rgb(255 255 255 / 0.05) 0deg 6deg, rgb(0 0 0 / 0.12) 6deg 12deg),\n    radial-gradient(circle at 36% 30%, var(--hw-recess-hi), var(--hw-recess) 70%);\n  box-shadow: inset 1px 1px 0 rgb(255 255 255 / 0.12), inset -1px -1px 1px rgb(0 0 0 / 0.5), var(--hw-shadow-part);\n}\n\n[data-part=\"lamp-lens\"] {\n  position: relative;\n  width: 16px;\n  height: 16px;\n  border-radius: 50%;\n  background:\n    radial-gradient(ellipse 45% 30% at 38% 26%, rgb(255 255 255 / 0.32), rgb(255 255 255 / 0) 100%),\n    radial-gradient(circle at 50% 58%, color-mix(in oklab, var(--hw-lamp) 55%, #2a1d14), color-mix(in oklab, var(--hw-lamp) 25%, #120c08) 85%);\n  box-shadow: inset 0 1px 3px rgb(0 0 0 / 0.6), 0 0 0 1px rgb(0 0 0 / 0.55);\n  transition: background 50ms linear, box-shadow 50ms linear;\n}\n\n[data-part=\"lamp\"][data-on] [data-part=\"lamp-lens\"] {\n  background:\n    radial-gradient(ellipse 45% 30% at 38% 26%, rgb(255 255 255 / 0.5), rgb(255 255 255 / 0) 100%),\n    radial-gradient(circle at 50% 55%, color-mix(in oklab, var(--hw-lamp-lit) 55%, #fff4dc) 0 20%, var(--hw-lamp-lit) 52%, var(--hw-lamp) 100%);\n  box-shadow:\n    inset 0 -1px 2px rgb(0 0 0 / 0.25),\n    0 0 0 1px rgb(0 0 0 / 0.45),\n    0 0 4px 1px color-mix(in oklab, var(--hw-lamp-lit) 55%, transparent);\n}\n\n[data-part=\"lamp\"][data-on] [data-part=\"lamp-bezel\"] {\n  box-shadow:\n    inset 1px 1px 0 rgb(255 255 255 / 0.12),\n    inset -1px -1px 1px rgb(0 0 0 / 0.5),\n    var(--hw-shadow-part),\n    0 0 14px 4px color-mix(in oklab, var(--hw-lamp-lit) 32%, transparent),\n    0 0 34px 12px color-mix(in oklab, var(--hw-lamp-lit) 14%, transparent);\n}\n\n@media (prefers-reduced-motion: reduce) {\n  [data-part=\"lamp-lens\"] {\n    transition: none;\n  }\n}\n",
      "type": "registry:component",
      "target": "@components/hardware/hardware.css"
    },
    {
      "path": "components/hardware/faceplate.tsx",
      "content": "import \"./hardware.css\"\n\nimport * as React from \"react\"\n\ntype FaceplateFinish = \"putty\" | \"cream\" | \"khaki\"\n\ntype LegendSize = \"sm\" | \"md\" | \"lg\"\n\nconst SCREW_CORNERS = [\"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\"] as const\n\ntype FaceplateProps = React.ComponentProps<\"div\"> & {\n  finish?: FaceplateFinish\n  screws?: boolean\n}\n\nfunction Faceplate({ finish = \"putty\", screws = true, children, ...props }: FaceplateProps) {\n  return (\n    <div data-hw=\"\" data-part=\"faceplate\" data-finish={finish} {...props}>\n      {screws && SCREW_CORNERS.map((corner) => <span key={corner} aria-hidden data-part=\"screw\" data-corner={corner} />)}\n      {children}\n    </div>\n  )\n}\n\ntype LegendProps = React.ComponentProps<\"span\"> & {\n  size?: LegendSize\n}\n\nfunction Legend({ size = \"md\", ...props }: LegendProps) {\n  return <span data-part=\"legend\" data-size={size} {...props} />\n}\n\nexport { Faceplate, type FaceplateFinish, Legend, type LegendSize }\n",
      "type": "registry:component",
      "target": "@components/hardware/faceplate.tsx"
    },
    {
      "path": "components/hardware/lamp.tsx",
      "content": "import \"./hardware.css\"\n\nimport * as React from \"react\"\n\ntype LampTone = \"red\" | \"amber\" | \"green\"\n\ntype LampProps = Omit<React.ComponentProps<\"span\">, \"children\"> & {\n  on?: boolean\n  tone?: LampTone\n  label?: string\n}\n\nfunction Lamp({ on = false, tone = \"red\", label, ...props }: LampProps) {\n  const state = on ? \"on\" : \"off\"\n  return (\n    <span data-hw=\"\" data-part=\"lamp\" data-tone={tone} data-on={on ? \"\" : undefined} role=\"img\" aria-label={label ? `${label} ${state}` : state} {...props}>\n      <span aria-hidden data-part=\"lamp-bezel\">\n        <span data-part=\"lamp-lens\" />\n      </span>\n      {label && (\n        <span aria-hidden data-part=\"legend\" data-size=\"sm\">\n          {label}\n        </span>\n      )}\n    </span>\n  )\n}\n\nexport { Lamp, type LampTone }\n",
      "type": "registry:component",
      "target": "@components/hardware/lamp.tsx"
    }
  ],
  "docs": "Hardware95 parts style themselves under [data-hw] and never touch your shadcn theme, so they drop into any app. Faceplate takes finish=\"putty\" | \"cream\" | \"khaki\" and draws corner screws unless screws={false}. Legend prints condensed caps onto the panel in size sm, md or lg. Lamp takes on and tone=\"red\" | \"amber\" | \"green\". Every color and depth recipe is a --hw-* custom property, so override one on any ancestor to restyle every part inside it.",
  "categories": [
    "hardware"
  ],
  "type": "registry:ui"
}