{
  "version": "1.0.0",
  "selectors": {
    "$comment": "Higgsfield.ai DOM selectors served at https://higgsfield-automation.pages.dev/selectors.json. Edit hosting/selectors.json then `npm run cf:deploy` — the content script picks up changes on the next SW eviction-restart or within ~1 hour via the refreshRemoteConfig alarm. Mirror non-trivial changes into docs/higgsfield-recon/selectors.json so the in-repo capture stays current.",
    "capturedAt": "2026-05-01",
    "loggedIn": true,
    "domains": {
      "primary": "higgsfield.ai",
      "createImageUrl": "https://higgsfield.ai/ai/image",
      "createVideoUrl": "https://higgsfield.ai/ai/video",
      "assetsAllUrl": "https://higgsfield.ai/asset/all"
    },
    "promptTextbox": {
      "selector": "div[role='textbox'][contenteditable]",
      "scopedToVideo": "form.generate-form div[role='textbox']",
      "scopedToImage": "div.reference-prompt div[role='textbox'], form.image-form div[role='textbox']",
      "insertionStrategy": "contenteditable: focus + execCommand('selectAll') + dispatchEvent(new InputEvent('beforeinput', {inputType:'insertText', data:<text>}))"
    },
    "video": {
      "formAnchor": "form.generate-form",
      "tabs": {
        "createVideoTab": "TEXT_MATCH:Create Video",
        "editVideoTab": "TEXT_MATCH:Edit Video",
        "motionControlTab": "TEXT_MATCH:Motion Control"
      },
      "uploadMediaZone": "form.generate-form div.cursor-pointer.min-h-\\[120px\\]",
      "fileInput": "form.generate-form input[type='file'][multiple]",
      "fileInputCaptureNote": "lazy-mounted on uploadMediaZone click; to bypass OS picker, monkey-patch HTMLInputElement.prototype.click for type=file inputs to no-op while triggering",
      "modelButton": "form.generate-form button[aria-label='Model']",
      "modelDialog": {
        "container": "div[role='dialog']",
        "modelOption": "TEXT_MATCH within div[role='dialog'] button",
        "dismissButton": "div[role='dialog'] button[aria-label='Dismiss']"
      },
      "durationButton": "form.generate-form button[aria-label='Duration']",
      "ratioButton": "form.generate-form button[aria-label='Ratio']",
      "resolutionButton": "form.generate-form button[aria-label='Resolution']",
      "elementsButton": "TEXT_MATCH:Elements within form.generate-form button",
      "audioToggle": "form.generate-form input[name='enhancePrompt']",
      "submitButton": "form.generate-form button[type='submit']",
      "historyTab": "TEXT_MATCH:History role=tab",
      "outputTiles": {
        "rootSelector": "figure[data-asset-id]",
        "byId": "figure[data-asset-id='<UUID>']",
        "videoChild": "figure[data-asset-id] video[src]",
        "imgChild": "figure[data-asset-id] img[data-asset-preview]",
        "videoFullResUrlPattern": "https://d8j0ntlcm91z4.cloudfront.net/<userHash>/hf_<YYYYMMDD>_<HHMMSS>_<UUID>.mp4",
        "imageThumbUrlPattern": "https://higgsfield.ai/cdn-cgi/image/.../cdn.higgsfield.ai/<userHash>/hf_<...>_<UUID>_thumbnail.webp",
        "extractDownloadUrl": "video tiles: tile.querySelector('video').src; image tiles: derive full-res by stripping cdn-cgi/image transform prefix from img.src"
      }
    },
    "image": {
      "formAnchor": "form.image-form",
      "promptContainer": "div.reference-prompt",
      "modelByUrlQuery": "navigate /ai/image?model=<slug>; observed slug: nano-banana-pro",
      "navigationStrategy": "history.replaceState + dispatchEvent(new PopStateEvent('popstate'))",
      "ratioPillRegex": "form.image-form button text matches /^\\d+:\\d+$/",
      "variantCounter": {
        "valueSelector": "form.image-form span text matches /^\\d+/\\d+$/",
        "strategy": "locate value span; previousElementSibling = decrement, nextElementSibling = increment"
      },
      "drawButton": "TEXT_MATCH:Draw within form.image-form button",
      "addReferenceButton": "form.image-form button:first-of-type",
      "submitButton": "form.image-form button[type='submit']"
    },
    "elementsBrowser": {
      "container": "[role='dialog'].fixed.z-100.w-\\[560px\\]",
      "tabs": [
        "TEXT_MATCH:Uploads",
        "TEXT_MATCH:Image Generations",
        "TEXT_MATCH:Video Generations",
        "TEXT_MATCH:Elements",
        "TEXT_MATCH:Liked"
      ],
      "dismissStrategy": "Escape key dispatch",
      "assetCells": "[role='dialog'] figure[data-asset-id], [role='dialog'] [data-cell-id]"
    },
    "shared": {
      "fileInput": "input[type='file']",
      "optionDropdownItems": "[role='option'], [role='menuitem'], [role='radio'], button"
    },
    "downloadFlow": {
      "$comment": "No discrete download-button + quality-picker UI on tiles. Read tile src URL directly and use chrome.downloads.download.",
      "strategy": "direct-fetch from tile src URL; no quality picker",
      "videoSrcSelector": "figure[data-asset-id] video[src]",
      "imageThumbSelector": "figure[data-asset-id] img[data-asset-preview]"
    }
  }
}
