@metricinsights/pp-dev 1.5.0-beta.1 → 1.5.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +4 -1
  2. package/dist/README.md +4 -1
  3. package/dist/cjs/cli.js +1 -1
  4. package/dist/cjs/{index-FgUi7Fqw.js → index-CNJgcIGX.js} +2 -2
  5. package/dist/cjs/{index-FgUi7Fqw.js.map → index-CNJgcIGX.js.map} +1 -1
  6. package/dist/cjs/index.js +1 -1
  7. package/dist/cjs/{migrate-pmX6NEmP.js → migrate-DkUysGJq.js} +2 -2
  8. package/dist/cjs/{migrate-pmX6NEmP.js.map → migrate-DkUysGJq.js.map} +1 -1
  9. package/dist/cjs/package.json +1 -1
  10. package/dist/cjs/plugin-BZ6G8J6V.js +2 -0
  11. package/dist/cjs/plugin-BZ6G8J6V.js.map +1 -0
  12. package/dist/cjs/plugin.js +1 -1
  13. package/dist/cjs/{version-plugin-0EjcUgtP.js → version-plugin-433yyuTq.js} +2 -2
  14. package/dist/cjs/{version-plugin-0EjcUgtP.js.map → version-plugin-433yyuTq.js.map} +1 -1
  15. package/dist/client/client.css +1 -1
  16. package/dist/client/client.css.map +1 -1
  17. package/dist/client/client.js +89 -8
  18. package/dist/client/client.js.map +1 -1
  19. package/dist/esm/cli.js +1 -1
  20. package/dist/esm/{index-BA9vecJD.js → index-BeF76QPw.js} +2 -2
  21. package/dist/esm/{index-BA9vecJD.js.map → index-BeF76QPw.js.map} +1 -1
  22. package/dist/esm/index.js +1 -1
  23. package/dist/esm/{migrate-Dsd7Aqx-.js → migrate-CCFtF5bt.js} +2 -2
  24. package/dist/esm/{migrate-Dsd7Aqx-.js.map → migrate-CCFtF5bt.js.map} +1 -1
  25. package/dist/esm/package.json +1 -1
  26. package/dist/esm/plugin-l4fgvJz0.js +2 -0
  27. package/dist/esm/plugin-l4fgvJz0.js.map +1 -0
  28. package/dist/esm/plugin.js +1 -1
  29. package/dist/esm/{version-plugin-pYbaqnAH.js → version-plugin-Bqy1V1SQ.js} +2 -2
  30. package/dist/esm/{version-plugin-pYbaqnAH.js.map → version-plugin-Bqy1V1SQ.js.map} +1 -1
  31. package/docs/features.md +5 -4
  32. package/package.json +1 -1
  33. package/dist/cjs/plugin-yWlSj5sK.js +0 -2
  34. package/dist/cjs/plugin-yWlSj5sK.js.map +0 -1
  35. package/dist/esm/plugin-CFtRWPwU.js +0 -2
  36. package/dist/esm/plugin-CFtRWPwU.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["client.scss"],"names":[],"mappings":"AA+FA,uBAtBI,sXA2BF,qDA3BE,sXA+BF,2CACE,eACA,SACA,WACA,YACA,6BACA,YACA,gDACA,uCACA,kBACA,aACA,sBACA,qBACA,QACA,aACA,gDACA,gBACA,eACA,uDACA,wBACA,UACA,sBACA,6DAEA,oDACE,wCACA,UAGF,mDACE,wCACA,UAGF,iDACE,aACA,uBACA,8BACA,QACA,UACA,aACA,WACA,sBACA,gBACA,cAEA,sDACE,aACA,mBACA,uBACA,WACA,YACA,cACA,sCAGF,sDACE,OACA,cACA,eACA,gBACA,iBACA,gBACA,sBAGF,uDACE,eACA,eACA,gBACA,aACA,mBACA,uBACA,UACA,SACA,gBACA,aACA,yBACA,kBACA,0BACA,cAEA,6DACE,oCAGF,qEACE,kDACA,mBAGF,2DACE,8BAKN,mDACE,iBACA,UACA,wBACA,gBACA,sBACA,YACA,+BACA,wBACA,eACA,gBACA,iBACA,gBACA,sBACA,qBAGF,oDACE,6DACA,mDAGF,mDACE,4DACA,kDAGF,iDACE,0DACA,gDAGF,oDACE,6DACA,mDAIF,iDACE,WACA,UACA,iBACA,uDAEA,mHAEE,yCAKN,yGAEE,eACA,QACA,eACA,aACA,mBACA,uBACA,iCACA,0BACA,kCAGF,6CACE,8BACA,kBACA,iCACA,gDACA,8CACA,gBAEA,mDACE,kBACA,eACA,gBACA,wCACA,oCACA,iCAGF,qDACE,aACA,qBACA,oCACA,eACA,gBAGF,qDACE,aACA,sBACA,QACA,oBAGF,iDACE,WACA,iBACA,kBACA,+BACA,eACA,gBACA,eACA,wBAEA,yDACE,oCACA,+BACA,4BAGF,0DACE,qCACA,kDAGF,uDACE,WAKN,uEAEE,eACA,eACA,mBACA,kBACA,OAxUY,KAyUZ,kBACA,YACA,QACA,gDACA,oCACA,sBACA,aACA,mBACA,gDACA,iBACA,0BACA,kCAMA,2EACE,oCACA,+BACA,eACA,gBACA,iBACA,iBACA,qBACA,uBACA,uBACA,sBACA,SACA,UACA,SACA,UACA,eACA,gBACA,mCACA,kCAGF,yFACE,aACA,mBACA,QAGF,yFACE,aACA,mBACA,kBACA,cAEA,yIACE,WACA,kBACA,QACA,QACA,2BACA,YACA,UACA,oCAEA,mMACE,sCAGF,+CAdF,yIAeI,sCAEA,qMACE,qCAKN,iHACE,eAGF,+GACE,gBAIJ,mFACE,aACA,mBACA,QACA,eACA,gBACA,iBAGF,qFACE,yCACA,gBAGF,qFACE,gBAGF,mFACE,uCACA,qBACA,0BACA,aACA,mBACA,QAEA,+FACE,uCACA,0BAQJ,yFACE,kDAGF,yFACE,kDAGF,mFACE,+CAGF,yFACE,kDAGF,uFACE,iDAGF,2EACE,uCACA,qBACA,sBACA,iBAEA,uFACE,qBAGF,gLAEE,UAIJ,qFACE,YACA,YACA,gBACA,eACA,aAGF,oLA/CE,gBAoDF,iGACE,aACA,mBACA,uBACA,cACA,WACA,YACA,YACA,kBACA,kBACA,yCACA,YACA,WACE,2CAGF,yGACE,oBACA,kBAGF,6GACE,UACA,oCAIJ,mGACE,aACA,mBACA,uBACA,WACA,YACA,YACA,kBACA,eACA,yCACA,wBAEA,2GACE,WACA,YACA,UACA,8BAGF,+GACE,uCACA,oCAEA,uHACE,wBAKN,2FACE,kBACA,gBACA,aACA,aACA,sBACA,SACA,gDACA,oCACA,kBACA,wCACA,eACA,eACA,mBACA,gBAEA,qJACE,eACA,gBACA,yCACA,yBACA,oBAGF,iJACE,aACA,mBACA,8BACA,SAGF,uJACE,gBACA,4BACA,WACA,YACA,8CACA,eACA,cAGF,+IACE,aACA,sCACA,QAGF,6IACE,WACA,YACA,oCACA,kBACA,eACA,kBACA,yBACA,iCAEA,2JACE,WACA,kBACA,WACA,WACA,kBACA,oDACA,qCAGF,+KACE,QACA,SAGF,iLACE,QACA,UAGF,qLACE,WACA,SAGF,uLACE,WACA,UAGF,yJACE,8CAGF,2JACE,8CAEA,yKACE,kDAKN,6IACE,aACA,QAGF,2IACE,gBACA,oCACA,kBACA,eACA,yBACA,eACA,iBACA,yCACA,WACE,+DAIF,uJACE,8CACA,uCAGF,yJACE,8CACA,kDACA,qCAGF,uKACE,mDACA,mBAIJ,2JACE,WACA,iBACA,mCACA,kBACA,eACA,gBACA,sCACA,qCAEA,uKACE,qCAIJ,qJACE,aACA,sBACA,QACA,iBACA,wCAGF,iJACE,aACA,sBACA,QAGF,yIACE,WACA,iBACA,kBACA,eACA,gBACA,kBACA,uCACA,mCACA,mCACA,WACE,gDAGF,qJACE,oCACA,+BAGF,qKACE,mDACA,mBAIJ,mJACE,eACA,iBACA,yCAEA,6JACE,sBACA,eAIJ,qJACE,sBACA,eACA,uCACA,eAEA,iKACE,0BAMN,6FACE,aACA,mBACA,uBACA,WACA,YACA,YACA,kBACA,eACA,yCACA,wBAEA,qGACE,WACA,YACA,cAGF,yGACE,uCACA,oCAKJ,mKACE,WACA,yBAEA,+KACE,yBAIJ,iIACE,YACA,6BACA,sBAEA,iLACE,eACA,iBACA,oCAEA,2LACE,cACA,eACA,yCAIJ,mLACE,aACA,sBACA,QACA,iBACA,gBAGF,iLACE,aACA,mBACA,QACA,gBACA,kBACA,oCAEA,uMACE,0BACA,sCAIJ,yLACE,gBACA,yBACA,WACA,YACA,SACA,cACA,8CACA,eAEA,2MACE,mBAIJ,iLACE,aACA,sBACA,YACA,OAGF,mLACE,eACA,gBACA,oCACA,gBACA,uBAGF,mLACE,eACA,iBACA,yCACA,gBACA,uBAGF,6MACE,sCAGF,uLACE,cACA,gBACA,oCACA,kBACA,yBACA,eACA,eACA,iBACA,uCAEA,mMACE,8CAGF,uMACE,8CACA,kDACA,qCAIJ,uLACE,cACA,WACA,YACA,UACA,YACA,kBACA,yBACA,eACA,eACA,iBACA,yCAEA,mMACE,sCACA,qCAIJ,qLACE,WACA,sBACA,gBACA,oCACA,kBACA,yBACA,eACA,oCAEA,iMACE,aACA,8CAIJ,sXAEE,eACA,iBACA,sCAGF,iMACE,yCAGF,mJACE,wBAIJ,2FACE,sBACA,aACA,mBACA,uBACA,WACA,YACA,YACA,eACA,kBACA,qCAEA,uGACE,oCACA,yCAGF,uGACE,WACA,YACA,oCACA,UACA,8BAIJ,qFACE,eAGE,+IACE,0CASJ,mHACE,MACA,OACA,wBACA,4CACA,2CAEA,iKACE,qBACA,OA6BA,iKACE,SAEA,6KACE,yBAIJ,iIACE,yCAEA,2LACE,uBAIJ,uOACE,wCACA,WACE,mFAGF,qPACE,WACA,kBACA,SACA,YACA,WACA,UAlER,qHACE,MACA,QACA,wBACA,6CACA,2CAEA,mKACE,qBACA,QAIA,mIACE,wCAEA,6LACE,yBAIJ,yOACE,uCACA,WACE,mFAIF,uPACE,WACA,kBACA,SACA,YACA,UACA,UAlCR,yHACE,SACA,OACA,wBACA,6CACA,wCAEA,uKACE,wBACA,OA6BA,uKACE,SAEA,mLACE,yBAIJ,uIACE,yCAEA,iMACE,uBAIJ,6OACE,wCACA,WACE,oFAGF,2PACE,WACA,kBACA,SACA,YACA,WACA,UAlER,2HACE,SACA,QACA,wBACA,8CACA,wCAEA,yKACE,wBACA,QAIA,yIACE,wCAEA,mMACE,yBAIJ,+OACE,uCACA,WACE,oFAIF,6PACE,WACA,kBACA,SACA,YACA,UACA,UAuCV,qHACE,eAGF,+FACE,gBACA,iBACA,gBAEA,mJACE,gBAIJ,+GACE,aAGF,iGACE,aACA,mBACA,uBACA,WACA,YACA,YACA,+BACA,kBACA,eACA,uCACA,wBACA,kBACA,gBAEA,iHACE,WACA,kBACA,MACA,OACA,WACA,YACA,8BACA,UACA,4BACA,kBAGF,yGACE,WACA,YACA,kBACA,UACA,8BAGF,2IACE,uCACA,oCAEA,mJACE,mCACA,8BAKF,qJACE,mCAIJ,mHACE,WACA,mBACA,oBACA,yCAIA,yHACE,sCAKN,iFACE,oBACA,cACA,UACA,YACA,oCAEA,2IACE,sCAGF,+CAXF,iFAYI,sCAEA,6IACE,qCAKN,kBACE,KACE,uBAEF,GACE,0BAIJ,2FACE,iBAGF,6FACE,kBAGF,iGACE,+BACA,eACA,gBACA,sBACA,iBACA,oCAEA,yIACE,kDAIJ,oBACE,GACE,uBAEF,KACE,0BAIJ,sBACE,GACE,0BAEF,IACE,2BAEF,KACE,2BAOJ,iIAloCA,yXAOF,+KACE,sCACA,kCAEA,2LACE,sCACA,kCAIJ,2LACE,uCAunCA,+CA94BF,uEA3PE,yXAOF,qHACE,sCACA,kCAEA,iIACE,sCACA,kCAIJ,iIACE,wCA6nCF,uCACE,gKAIE","file":"client.css","sourcesContent":["@use 'sass:map';\n\n$pp-dev-height: 32px;\n$pp-dev-peek: 4px;\n\n// Corner map: v/h — anchored edges; sx — horizontal slide direction for minimize/auto-hide\n// (1 → slides right, -1 → slides left); radius/shadow face the viewport center;\n// edge — hairline border on the exposed horizontal edge.\n$pp-dev-corners: (\n 'top-left': (\n v: top,\n h: left,\n sx: -1,\n radius: 0 0 4px 0,\n shadow: 2px 2px 8px 0 rgba(34, 34, 34, 0.08),\n edge: border-bottom,\n ),\n 'top-right': (\n v: top,\n h: right,\n sx: 1,\n radius: 0 0 0 4px,\n shadow: -2px 2px 8px 0 rgba(34, 34, 34, 0.08),\n edge: border-bottom,\n ),\n 'bottom-left': (\n v: bottom,\n h: left,\n sx: -1,\n radius: 0 4px 0 0,\n shadow: 2px -2px 8px 0 rgba(34, 34, 34, 0.08),\n edge: border-top,\n ),\n 'bottom-right': (\n v: bottom,\n h: right,\n sx: 1,\n radius: 4px 0 0 0,\n shadow: -2px -2px 8px 0 rgba(34, 34, 34, 0.08),\n edge: border-top,\n ),\n);\n\n// Light/dark color maps, shared by the default (light) rules, the prefers-color-scheme:dark\n// media query (Auto), and the explicit data-pp-dev-theme override (Dark/Light picked in the\n// panel's settings popover — see src/client/theme.ts). One place to edit either palette.\n$pp-dev-light-colors: (\n primary: #075b7e,\n secondary: rgba(34, 34, 34, 0.64),\n success: #077e45,\n info: #17a2b8,\n warning: #ffb000,\n danger: #ac2b2b,\n light: #f8f9fa,\n dark: #343a40,\n 'white': #ffffff,\n 'black': #000000,\n);\n$pp-dev-dark-colors: (\n primary: #2a8db5,\n secondary: rgba(220, 220, 220, 0.64),\n success: #0fad5e,\n info: #2dccff,\n warning: #ffb302,\n danger: #e05252,\n light: #343a40,\n dark: #f8f9fa,\n 'white': #000000,\n 'black': #ffffff,\n);\n\n@mixin pp-dev-theme-colors($colors) {\n @each $name, $value in $colors {\n --pp-dev-info-color-#{$name}: #{$value};\n }\n}\n\n// rgba() literals don't follow the --pp-dev-info-color-primary reassignment above,\n// so the button fill/border are re-tinted here to match the dark-mode primary.\n@mixin pp-dev-dark-tints {\n .pp-dev-info__vars-btn {\n background-color: rgba(42, 141, 181, 0.14);\n border-color: rgba(42, 141, 181, 0.45);\n\n &:hover {\n background-color: rgba(42, 141, 181, 0.24);\n border-color: rgba(42, 141, 181, 0.65);\n }\n }\n\n .pp-dev-info__settings-group {\n border-top-color: rgba(255, 255, 255, 0.15);\n }\n}\n\n.pp-dev-info-namespace {\n // Define theme colors — light by default; overridden for Auto (media query, below) or an\n // explicit Dark/Light pick (html[data-pp-dev-theme], below — always wins on specificity).\n @include pp-dev-theme-colors($pp-dev-light-colors);\n\n html[data-pp-dev-theme='light'] & {\n @include pp-dev-theme-colors($pp-dev-light-colors);\n }\n\n .pp-dev-info__popup {\n position: fixed;\n top: 10px;\n right: 10px;\n width: 280px;\n max-width: calc(100vw - 20px);\n height: auto;\n background-color: var(--pp-dev-info-color-white);\n box-shadow: 0 2px 4px rgba(34, 34, 34, 0.2);\n border-radius: 2px;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 4px;\n padding: 12px;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n z-index: 100001;\n border-left: 2px solid var(--pp-dev-info-color-primary);\n transform: translateX(0);\n opacity: 1;\n box-sizing: border-box;\n --pp-dev-info-popup-accent: var(--pp-dev-info-color-primary);\n\n &.entering {\n transform: translateX(calc(100% + 10px));\n opacity: 0;\n }\n\n &.exiting {\n transform: translateX(calc(100% + 10px));\n opacity: 0;\n }\n\n &-title {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 8px;\n padding: 0;\n min-height: 0;\n width: 100%;\n box-sizing: border-box;\n border-bottom: 0;\n color: #040404;\n\n &-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n color: var(--pp-dev-info-popup-accent);\n }\n\n &-text {\n flex: 1;\n color: #040404;\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n text-align: left;\n word-break: break-word;\n }\n\n &-close {\n cursor: pointer;\n min-width: 24px;\n min-height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: 0;\n background: none;\n font: inherit;\n color: rgba(34, 34, 34, 0.64);\n border-radius: 2px;\n transition: color 0.2s ease;\n flex-shrink: 0;\n\n &:hover {\n color: var(--pp-dev-info-color-dark);\n }\n\n &:focus-visible {\n outline: 2px solid var(--pp-dev-info-popup-accent);\n outline-offset: 1px;\n }\n\n svg {\n transition: transform 0.2s ease;\n }\n }\n }\n\n &-content {\n margin-left: 24px;\n padding: 0;\n width: calc(100% - 24px);\n overflow-y: auto;\n box-sizing: border-box;\n flex-grow: 0;\n background-color: transparent;\n color: rgba(34, 34, 34, 0.8);\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n text-align: left;\n word-break: break-word;\n white-space: pre-line;\n }\n\n &--success {\n --pp-dev-info-popup-accent: var(--pp-dev-info-color-success);\n border-left-color: var(--pp-dev-info-color-success);\n }\n\n &--danger {\n --pp-dev-info-popup-accent: var(--pp-dev-info-color-danger);\n border-left-color: var(--pp-dev-info-color-danger);\n }\n\n &--info {\n --pp-dev-info-popup-accent: var(--pp-dev-info-color-info);\n border-left-color: var(--pp-dev-info-color-info);\n }\n\n &--warning {\n --pp-dev-info-popup-accent: var(--pp-dev-info-color-warning);\n border-left-color: var(--pp-dev-info-color-warning);\n }\n\n // Popups anchored to the left screen edge (panel in a left corner)\n &--left {\n right: auto;\n left: 10px;\n border-left: none;\n border-right: 2px solid var(--pp-dev-info-popup-accent);\n\n &.entering,\n &.exiting {\n transform: translateX(calc(-100% - 10px));\n }\n }\n }\n\n &.pp-dev-info__confirm-overlay,\n .pp-dev-info__confirm-overlay {\n position: fixed;\n inset: 0;\n z-index: 100003;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: rgba(0, 0, 0, 0.35);\n backdrop-filter: blur(2px);\n -webkit-backdrop-filter: blur(2px);\n }\n\n .pp-dev-info__confirm {\n width: min(408px, calc(100vw - 32px));\n border-radius: 3px;\n border: 1px solid rgba(0, 0, 0, 0.15);\n background-color: var(--pp-dev-info-color-white);\n box-shadow: 0px 8px 32px 0px rgba(34, 34, 34, 0.4);\n overflow: hidden;\n\n &-title {\n padding: 14px 16px;\n font-size: 15px;\n font-weight: 600;\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n color: var(--pp-dev-info-color-dark);\n background-color: rgba(0, 0, 0, 0.03);\n }\n\n &-content {\n padding: 16px;\n white-space: pre-wrap;\n color: var(--pp-dev-info-color-dark);\n font-size: 13px;\n line-height: 1.5;\n }\n\n &-actions {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 0 16px 16px;\n }\n\n &-btn {\n width: 100%;\n padding: 8px 12px;\n border-radius: 6px;\n border: 1px solid transparent;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n\n &--cancel {\n color: var(--pp-dev-info-color-dark);\n background-color: transparent;\n border-color: rgba(0, 0, 0, 0.2);\n }\n\n &--confirm {\n color: var(--pp-dev-info-color-white);\n background-color: var(--pp-dev-info-color-primary);\n }\n\n &:hover {\n opacity: 0.9;\n }\n }\n }\n\n &.pp-dev-info,\n .pp-dev-info {\n position: fixed;\n z-index: 100000;\n white-space: nowrap;\n width: fit-content;\n height: $pp-dev-height;\n text-align: center;\n padding: 2px;\n gap: 8px;\n background-color: var(--pp-dev-info-color-white);\n color: var(--pp-dev-info-color-dark);\n box-sizing: border-box;\n display: flex;\n align-items: center;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: visible;\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n\n // Setup default values for styles that can be overlapped by other page styles\n // (e.g. color, font-family, font-size etc.)\n // This is needed to make sure that the extension styles are not overlapped by the page styles\n // and the extension is still usable\n * {\n color: var(--pp-dev-info-color-dark);\n font-family: 'Inter', sans-serif;\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n letter-spacing: 0;\n text-decoration: none;\n text-transform: inherit;\n vertical-align: inherit;\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0;\n outline: 0;\n background: 0 0;\n list-style: none;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n\n &__content {\n display: flex;\n align-items: center;\n gap: 0px;\n }\n\n &__section {\n display: flex;\n align-items: center;\n position: relative;\n padding: 0 8px;\n\n &:not(:last-child)::after {\n content: '';\n position: absolute;\n right: 0;\n top: 50%;\n transform: translateY(-50%);\n height: 16px;\n width: 1px;\n background-color: rgba(34, 34, 34, 0.24);\n\n html[data-pp-dev-theme='dark'] & {\n background-color: rgba(255, 255, 255, 0.2);\n }\n\n @media screen and (prefers-color-scheme: dark) {\n background-color: rgba(255, 255, 255, 0.2);\n\n html[data-pp-dev-theme='light'] & {\n background-color: rgba(34, 34, 34, 0.24);\n }\n }\n }\n\n &:first-child {\n padding-left: 0;\n }\n\n &:last-child {\n padding-right: 0;\n }\n }\n\n &__item {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n }\n\n &__label {\n color: var(--pp-dev-info-color-secondary);\n font-weight: 400;\n }\n\n &__value {\n font-weight: 600;\n }\n\n &__link {\n color: var(--pp-dev-info-color-primary);\n text-decoration: none;\n transition: color 0.2s ease;\n display: flex;\n align-items: center;\n gap: 8px;\n\n &:hover {\n color: var(--pp-dev-info-color-primary);\n text-decoration: underline;\n }\n }\n\n @mixin bold {\n font-weight: 700;\n }\n\n .primary {\n color: var(--pp-dev-info-color-primary) !important;\n }\n\n .success {\n color: var(--pp-dev-info-color-success) !important;\n }\n\n .info {\n color: var(--pp-dev-info-color-info) !important;\n }\n\n .warning {\n color: var(--pp-dev-info-color-warning) !important;\n }\n\n .danger {\n color: var(--pp-dev-info-color-danger) !important;\n }\n\n a {\n color: var(--pp-dev-info-color-primary);\n text-decoration: none;\n vertical-align: middle;\n line-height: 18px;\n\n &:hover {\n text-decoration: none;\n }\n\n &:active,\n &:hover {\n outline: 0;\n }\n }\n\n button {\n padding: 1px;\n border: none;\n background: none;\n cursor: pointer;\n outline: none;\n }\n\n .bold,\n .status-text {\n @include bold;\n }\n\n &__drag-handle {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 14px;\n height: 28px;\n cursor: grab;\n touch-action: none;\n border-radius: 3px;\n color: var(--pp-dev-info-color-secondary);\n opacity: 0.55;\n transition:\n opacity 0.2s ease,\n background-color 0.2s ease;\n\n svg {\n pointer-events: none;\n fill: currentColor;\n }\n\n &:hover {\n opacity: 1;\n background-color: rgba(7, 91, 126, 0.06);\n }\n }\n\n &__settings-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n border-radius: 3px;\n cursor: pointer;\n color: var(--pp-dev-info-color-secondary);\n transition: all 0.2s ease;\n\n svg {\n width: 16px;\n height: 16px;\n fill: none;\n transition: transform 0.3s ease;\n }\n\n &:hover {\n color: var(--pp-dev-info-color-primary);\n background-color: rgba(7, 91, 126, 0.06);\n\n svg {\n transform: rotate(45deg);\n }\n }\n }\n\n &__settings {\n position: absolute;\n min-width: 216px;\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n background-color: var(--pp-dev-info-color-white);\n border: 1px solid rgba(34, 34, 34, 0.15);\n border-radius: 3px;\n box-shadow: 0 4px 16px rgba(34, 34, 34, 0.2);\n z-index: 100002;\n cursor: default;\n white-space: normal;\n text-align: left;\n\n .pp-dev-info__settings-title {\n font-size: 10px;\n font-weight: 600;\n color: var(--pp-dev-info-color-secondary);\n text-transform: uppercase;\n letter-spacing: 0.4px;\n }\n\n .pp-dev-info__settings-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n }\n\n .pp-dev-info__settings-toggle {\n appearance: auto;\n -webkit-appearance: checkbox;\n width: 14px;\n height: 14px;\n accent-color: var(--pp-dev-info-color-primary);\n cursor: pointer;\n flex-shrink: 0;\n }\n\n .pp-dev-info__corner-grid {\n display: grid;\n grid-template-columns: repeat(2, 30px);\n gap: 4px;\n }\n\n .pp-dev-info__corner-btn {\n width: 30px;\n height: 22px;\n border: 1px solid rgba(34, 34, 34, 0.25);\n border-radius: 3px;\n cursor: pointer;\n position: relative;\n background: transparent;\n transition: border-color 0.2s ease;\n\n &::after {\n content: '';\n position: absolute;\n width: 10px;\n height: 6px;\n border-radius: 1px;\n background-color: var(--pp-dev-info-color-secondary);\n transition: background-color 0.2s ease;\n }\n\n &--top-left::after {\n top: 2px;\n left: 2px;\n }\n\n &--top-right::after {\n top: 2px;\n right: 2px;\n }\n\n &--bottom-left::after {\n bottom: 2px;\n left: 2px;\n }\n\n &--bottom-right::after {\n bottom: 2px;\n right: 2px;\n }\n\n &:hover {\n border-color: var(--pp-dev-info-color-primary);\n }\n\n &.active {\n border-color: var(--pp-dev-info-color-primary);\n\n &::after {\n background-color: var(--pp-dev-info-color-primary);\n }\n }\n }\n\n .pp-dev-info__theme-grid {\n display: flex;\n gap: 4px;\n }\n\n .pp-dev-info__theme-btn {\n padding: 3px 8px;\n border: 1px solid rgba(34, 34, 34, 0.25);\n border-radius: 3px;\n cursor: pointer;\n background: transparent;\n font-size: 11px;\n line-height: 16px;\n color: var(--pp-dev-info-color-secondary);\n transition:\n border-color 0.2s ease,\n color 0.2s ease,\n background-color 0.2s ease;\n\n &:hover {\n border-color: var(--pp-dev-info-color-primary);\n color: var(--pp-dev-info-color-primary);\n }\n\n &.active {\n border-color: var(--pp-dev-info-color-primary);\n background-color: var(--pp-dev-info-color-primary);\n color: var(--pp-dev-info-color-white);\n }\n\n &:focus-visible {\n outline: 2px solid var(--pp-dev-info-color-primary);\n outline-offset: 1px;\n }\n }\n\n .pp-dev-info__settings-hide-btn {\n width: 100%;\n padding: 6px 10px;\n border: 1px solid rgba(34, 34, 34, 0.2);\n border-radius: 4px;\n cursor: pointer;\n font-weight: 600;\n color: var(--pp-dev-info-color-danger);\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: rgba(172, 43, 43, 0.06);\n }\n }\n\n .pp-dev-info__settings-group {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding-top: 10px;\n border-top: 1px solid rgba(34, 34, 34, 0.12);\n }\n\n .pp-dev-info__vars-buttons {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .pp-dev-info__vars-btn {\n width: 100%;\n padding: 6px 10px;\n border-radius: 4px;\n cursor: pointer;\n font-weight: 600;\n text-align: center;\n color: var(--pp-dev-info-color-primary);\n background-color: rgba(7, 91, 126, 0.1);\n border: 1px solid rgba(7, 91, 126, 0.4);\n transition:\n background-color 0.2s ease,\n border-color 0.2s ease;\n\n &:hover {\n background-color: rgba(7, 91, 126, 0.18);\n border-color: rgba(7, 91, 126, 0.6);\n }\n\n &:focus-visible {\n outline: 2px solid var(--pp-dev-info-color-primary);\n outline-offset: 1px;\n }\n }\n\n .pp-dev-info__settings-hint {\n font-size: 10px;\n line-height: 14px;\n color: var(--pp-dev-info-color-secondary);\n\n code {\n font-family: monospace;\n font-size: 10px;\n }\n }\n\n .pp-dev-info__settings-reset {\n align-self: flex-start;\n font-size: 11px;\n color: var(--pp-dev-info-color-primary);\n cursor: pointer;\n\n &:hover {\n text-decoration: underline;\n }\n }\n }\n\n // ── Users (PP-4597) ──────────────────────────────────────────────────────\n &__users-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n border-radius: 3px;\n cursor: pointer;\n color: var(--pp-dev-info-color-secondary);\n transition: all 0.2s ease;\n\n svg {\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n }\n\n &:hover {\n color: var(--pp-dev-info-color-primary);\n background-color: rgba(7, 91, 126, 0.06);\n }\n }\n\n // A saved user's tab: the button stands out, so the tab is never taken for your own.\n &.pp-dev-info--user-tab .pp-dev-info__users-btn {\n color: #ffffff;\n background-color: #7a3fb8;\n\n &:hover {\n background-color: #8d52cc;\n }\n }\n\n &__users.pp-dev-info__settings {\n width: 320px;\n max-width: calc(100vw - 16px);\n box-sizing: border-box;\n\n .pp-dev-info__users-tab {\n font-size: 12px;\n line-height: 16px;\n color: var(--pp-dev-info-color-dark);\n\n span {\n display: block;\n font-size: 10px;\n color: var(--pp-dev-info-color-secondary);\n }\n }\n\n .pp-dev-info__users-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n max-height: 240px;\n overflow-y: auto;\n }\n\n .pp-dev-info__users-row {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 6px;\n border-radius: 3px;\n border-left: 2px solid transparent;\n\n &.is-current {\n border-left-color: #7a3fb8;\n background-color: rgba(122, 63, 184, 0.08);\n }\n }\n\n .pp-dev-info__users-default {\n appearance: auto;\n -webkit-appearance: radio;\n width: 13px;\n height: 13px;\n margin: 0;\n flex-shrink: 0;\n accent-color: var(--pp-dev-info-color-primary);\n cursor: pointer;\n\n &:disabled {\n cursor: not-allowed;\n }\n }\n\n .pp-dev-info__users-who {\n display: flex;\n flex-direction: column;\n min-width: 0;\n flex: 1;\n }\n\n .pp-dev-info__users-name {\n font-size: 12px;\n font-weight: 600;\n color: var(--pp-dev-info-color-dark);\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .pp-dev-info__users-meta {\n font-size: 10px;\n line-height: 13px;\n color: var(--pp-dev-info-color-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .needs-login .pp-dev-info__users-meta {\n color: var(--pp-dev-info-color-danger);\n }\n\n .pp-dev-info__users-action {\n flex-shrink: 0;\n padding: 2px 7px;\n border: 1px solid rgba(34, 34, 34, 0.25);\n border-radius: 3px;\n background: transparent;\n cursor: pointer;\n font-size: 11px;\n line-height: 16px;\n color: var(--pp-dev-info-color-primary);\n\n &:hover {\n border-color: var(--pp-dev-info-color-primary);\n }\n\n &--accent {\n border-color: var(--pp-dev-info-color-primary);\n background-color: var(--pp-dev-info-color-primary);\n color: var(--pp-dev-info-color-white);\n }\n }\n\n .pp-dev-info__users-remove {\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n padding: 0;\n border: none;\n border-radius: 3px;\n background: transparent;\n cursor: pointer;\n font-size: 15px;\n line-height: 20px;\n color: var(--pp-dev-info-color-secondary);\n\n &:hover {\n color: var(--pp-dev-info-color-danger);\n background-color: rgba(172, 43, 43, 0.08);\n }\n }\n\n .pp-dev-info__users-input {\n width: 100%;\n box-sizing: border-box;\n padding: 5px 8px;\n border: 1px solid rgba(34, 34, 34, 0.25);\n border-radius: 3px;\n background: transparent;\n font-size: 12px;\n color: var(--pp-dev-info-color-dark);\n\n &:focus {\n outline: none;\n border-color: var(--pp-dev-info-color-primary);\n }\n }\n\n .pp-dev-info__users-error,\n .pp-dev-info__users-unavailable {\n font-size: 11px;\n line-height: 15px;\n color: var(--pp-dev-info-color-danger);\n }\n\n .pp-dev-info__users-unavailable {\n color: var(--pp-dev-info-color-secondary);\n }\n\n [hidden] {\n display: none !important;\n }\n }\n\n &__wrap-btn {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n cursor: pointer;\n border-radius: 3px;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: rgba(7, 91, 126, 0.06);\n animation: arrowHover 0.8s linear infinite;\n }\n\n &-arrow {\n width: 16px;\n height: 16px;\n color: var(--pp-dev-info-color-dark);\n fill: none;\n transition: transform 0.2s ease;\n }\n }\n\n &.closed {\n z-index: 100002;\n\n & .pp-dev-info__wrap-btn {\n &:hover {\n animation: arrowHover 1.2s linear infinite;\n }\n }\n }\n\n // Corner variants: placement, center-facing radius/shadow, direction-aware\n // minimize (.closed) and auto-hide slides. The corner class is always rendered\n // on the panel root (server default: bottom-right).\n @each $name, $c in $pp-dev-corners {\n &.pp-dev-info--#{$name} {\n #{map.get($c, v)}: 0;\n #{map.get($c, h)}: 0;\n border-radius: map.get($c, radius);\n box-shadow: map.get($c, shadow);\n #{map.get($c, edge)}: 1px solid rgba(34, 34, 34, 0.08);\n\n .pp-dev-info__settings {\n #{map.get($c, v)}: calc(100% + 8px);\n #{map.get($c, h)}: 0;\n }\n\n @if map.get($c, sx) == 1 {\n &.closed {\n transform: translateX(calc(100% - $pp-dev-height));\n\n .pp-dev-info__wrap-btn-arrow {\n transform: rotate(180deg);\n }\n }\n\n &.pp-dev-info--auto-hide:not(.is-peeking):not(.is-dragging) {\n transform: translateX(calc(100% - $pp-dev-peek));\n box-shadow:\n map.get($c, shadow),\n inset $pp-dev-peek 0 0 0 var(--pp-dev-info-color-primary);\n\n // Extended invisible hover zone on the inner side of the 4px strip\n &::after {\n content: '';\n position: absolute;\n top: -6px;\n bottom: -6px;\n left: -8px;\n width: 8px;\n }\n }\n } @else {\n .pp-dev-info__wrap-btn {\n order: 99;\n\n &-arrow {\n transform: rotate(180deg);\n }\n }\n\n &.closed {\n transform: translateX(calc(-100% + $pp-dev-height));\n\n .pp-dev-info__wrap-btn-arrow {\n transform: rotate(0deg);\n }\n }\n\n &.pp-dev-info--auto-hide:not(.is-peeking):not(.is-dragging) {\n transform: translateX(calc(-100% + $pp-dev-peek));\n box-shadow:\n map.get($c, shadow),\n inset (-$pp-dev-peek) 0 0 0 var(--pp-dev-info-color-primary);\n\n &::after {\n content: '';\n position: absolute;\n top: -6px;\n bottom: -6px;\n right: -8px;\n width: 8px;\n }\n }\n }\n }\n }\n\n &.pp-dev-info--auto-hide {\n z-index: 100002;\n }\n\n &.is-dragging {\n transition: none;\n user-select: none;\n cursor: grabbing;\n\n .pp-dev-info__drag-handle {\n cursor: grabbing;\n }\n }\n\n &.pp-dev-info--hidden {\n display: none;\n }\n\n .sync-button {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n background-color: transparent;\n border-radius: 3px;\n cursor: pointer;\n color: var(--pp-dev-info-color-primary);\n transition: all 0.2s ease;\n position: relative;\n overflow: hidden;\n\n &::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: currentColor;\n opacity: 0;\n transition: opacity 0.2s ease;\n border-radius: 3px;\n }\n\n svg {\n width: 16px;\n height: 16px;\n position: relative;\n z-index: 1;\n transition: transform 0.3s ease;\n }\n\n &:hover:not(.disabled) {\n color: var(--pp-dev-info-color-primary);\n background-color: rgba(7, 91, 126, 0.06);\n\n svg {\n transform: scale(1.1) rotate(45deg);\n transition: transform 0.2s ease;\n }\n }\n\n &:active:not(.disabled) {\n svg {\n transform: scale(0.9) rotate(45deg);\n }\n }\n\n &.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n color: var(--pp-dev-info-color-secondary);\n }\n\n &.syncing {\n svg {\n animation: rotate 1.5s linear infinite;\n }\n }\n }\n\n &__sep {\n display: inline-flex;\n flex-shrink: 0;\n width: 1px;\n height: 16px;\n background-color: rgba(34, 34, 34, 0.24);\n\n html[data-pp-dev-theme='dark'] & {\n background-color: rgba(255, 255, 255, 0.2);\n }\n\n @media screen and (prefers-color-scheme: dark) {\n background-color: rgba(255, 255, 255, 0.2);\n\n html[data-pp-dev-theme='light'] & {\n background-color: rgba(34, 34, 34, 0.24);\n }\n }\n }\n\n @keyframes rotate {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n\n .margin-5 {\n margin-right: 5px;\n }\n\n .margin-10 {\n margin-right: 10px;\n }\n\n .custom-font {\n font-family: 'Inter', sans-serif;\n font-size: 13px;\n font-weight: 400;\n vertical-align: middle;\n line-height: 18px;\n color: var(--pp-dev-info-color-dark);\n\n &:not(.not-colored) a {\n color: var(--pp-dev-info-color-primary) !important;\n }\n }\n\n @keyframes rotation {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }\n\n @keyframes arrowHover {\n 0% {\n transform: translateX(2px);\n }\n 50% {\n transform: translateX(-2px);\n }\n 100% {\n transform: translateX(2px);\n }\n }\n\n // Explicit Dark pick (html[data-pp-dev-theme='dark'], set via the settings popover's Theme\n // row — see src/client/theme.ts) — always wins over both the light default above and the\n // Auto media query below, on selector specificity alone.\n html[data-pp-dev-theme='dark'] & {\n @include pp-dev-theme-colors($pp-dev-dark-colors);\n @include pp-dev-dark-tints;\n }\n\n // Auto (OS/browser preference) — same values, only takes effect when no explicit\n // html[data-pp-dev-theme] override is set (those always outrank a plain :root/& selector).\n @media screen and (prefers-color-scheme: dark) {\n @include pp-dev-theme-colors($pp-dev-dark-colors);\n @include pp-dev-dark-tints;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n &.pp-dev-info,\n .pp-dev-info,\n .pp-dev-info__popup,\n .pp-dev-info__settings {\n transition: none;\n }\n }\n}\n"]}
1
+ {"version":3,"sourceRoot":"","sources":["client.scss"],"names":[],"mappings":"AAqGA,uBAtBI,wcA2BF,qDA3BE,wcA+BF,2CACE,eACA,SACA,WACA,YACA,6BACA,YACA,gDACA,uCACA,kBACA,aACA,sBACA,qBACA,QACA,aACA,gDACA,gBACA,eACA,uDACA,wBACA,UACA,sBACA,6DAEA,oDACE,wCACA,UAGF,mDACE,wCACA,UAGF,iDACE,aACA,uBACA,8BACA,QACA,UACA,aACA,WACA,sBACA,gBACA,cAEA,sDACE,aACA,mBACA,uBACA,WACA,YACA,cACA,sCAGF,sDACE,OACA,cACA,eACA,gBACA,iBACA,gBACA,sBAGF,uDACE,eACA,eACA,gBACA,aACA,mBACA,uBACA,UACA,SACA,gBACA,aACA,yBACA,kBACA,0BACA,cAEA,6DACE,oCAGF,qEACE,kDACA,mBAGF,2DACE,8BAKN,mDACE,iBACA,UACA,wBACA,gBACA,sBACA,YACA,+BACA,wBACA,eACA,gBACA,iBACA,gBACA,sBACA,qBAGF,oDACE,6DACA,mDAGF,mDACE,4DACA,kDAGF,iDACE,0DACA,gDAGF,oDACE,6DACA,mDAIF,iDACE,WACA,UACA,iBACA,uDAEA,mHAEE,yCAKN,yGAEE,eACA,QACA,eACA,aACA,mBACA,uBACA,iCACA,0BACA,kCAGF,6CACE,8BACA,kBACA,iCACA,gDACA,8CACA,gBAEA,mDACE,kBACA,eACA,gBACA,wCACA,oCACA,iCAGF,qDACE,aACA,qBACA,oCACA,eACA,gBAGF,qDACE,aACA,sBACA,QACA,oBAGF,iDACE,WACA,iBACA,kBACA,+BACA,eACA,gBACA,eACA,wBAEA,yDACE,oCACA,+BACA,4BAGF,0DACE,qCACA,kDAGF,uDACE,WAKN,uEAEE,eACA,eACA,mBACA,kBACA,OA9UY,KA+UZ,kBACA,YACA,QACA,gDACA,oCACA,sBACA,aACA,mBACA,gDACA,iBACA,0BACA,kCAMA,2EACE,oCACA,+BACA,eACA,gBACA,iBACA,iBACA,qBACA,uBACA,uBACA,sBACA,SACA,UACA,SACA,UACA,eACA,gBACA,mCACA,kCAGF,yFACE,aACA,mBACA,QAGF,yFACE,aACA,mBACA,kBACA,cAEA,yIACE,WACA,kBACA,QACA,QACA,2BACA,YACA,UACA,oCAEA,mMACE,sCAGF,+CAdF,yIAeI,sCAEA,qMACE,qCAKN,iHACE,eAGF,+GACE,gBAIJ,mFACE,aACA,mBACA,QACA,eACA,gBACA,iBAGF,qFACE,yCACA,gBAGF,qFACE,gBAGF,mFACE,uCACA,qBACA,0BACA,aACA,mBACA,QAEA,+FACE,uCACA,0BAQJ,yFACE,kDAGF,yFACE,kDAGF,mFACE,+CAGF,yFACE,kDAGF,uFACE,iDAGF,2EACE,uCACA,qBACA,sBACA,iBAEA,uFACE,qBAGF,gLAEE,UAIJ,qFACE,YACA,YACA,gBACA,eACA,aAGF,oLA/CE,gBAoDF,iGACE,aACA,mBACA,uBACA,cACA,WACA,YACA,YACA,kBACA,kBACA,yCACA,YACA,WACE,2CAGF,yGACE,oBACA,kBAGF,6GACE,UACA,oCAIJ,mGACE,aACA,mBACA,uBACA,WACA,YACA,YACA,kBACA,eACA,yCACA,wBAEA,2GACE,WACA,YACA,UACA,8BAGF,+GACE,uCACA,oCAEA,uHACE,wBAKN,2FACE,kBACA,gBACA,aACA,aACA,sBACA,SACA,gDACA,oCACA,kBACA,wCACA,eACA,eACA,mBACA,gBAEA,qJACE,eACA,gBACA,yCACA,yBACA,oBAGF,iJACE,aACA,mBACA,8BACA,SAGF,uJACE,gBACA,4BACA,WACA,YACA,8CACA,eACA,cAGF,+IACE,aACA,sCACA,QAGF,6IACE,WACA,YACA,+CACA,kBACA,eACA,kBACA,yBACA,iCAEA,2JACE,WACA,kBACA,WACA,WACA,kBACA,oDACA,qCAGF,+KACE,QACA,SAGF,iLACE,QACA,UAGF,qLACE,WACA,SAGF,uLACE,WACA,UAGF,yJACE,8CAGF,2JACE,8CAEA,yKACE,kDAKN,6IACE,aACA,QAGF,2IACE,gBACA,+CACA,kBACA,eACA,yBACA,eACA,iBACA,yCACA,WACE,+DAIF,uJACE,8CACA,uCAGF,yJACE,8CACA,kDACA,qCAGF,uKACE,mDACA,mBAIJ,2JACE,WACA,iBACA,mCACA,kBACA,eACA,gBACA,sCACA,qCAEA,uKACE,qCAIJ,qJACE,aACA,sBACA,QACA,iBACA,wCAGF,iJACE,aACA,sBACA,QAGF,yIACE,WACA,iBACA,kBACA,eACA,gBACA,kBACA,uCACA,mCACA,mCACA,WACE,gDAGF,qJACE,oCACA,+BAGF,qKACE,mDACA,mBAIJ,mJACE,eACA,iBACA,yCAEA,6JACE,sBACA,eAIJ,qJACE,sBACA,eACA,uCACA,eAEA,iKACE,0BAMN,6FACE,aACA,mBACA,uBACA,WACA,YACA,YACA,kBACA,eACA,yCACA,wBAEA,qGACE,WACA,YACA,cAGF,yGACE,uCACA,oCAKJ,mKACE,WACA,yBAEA,+KACE,yBAIJ,iIACE,YACA,6BACA,sBAEA,iLACE,eACA,iBACA,oCAIF,6LACE,mBACA,iBACA,cACA,qBACA,yBACA,yCAGF,qLACE,gBACA,cACA,8BACA,kBACA,cACA,gBACA,iBACA,mBACA,mCAGF,mLACE,aACA,sBACA,QACA,iBACA,gBAGF,iLACE,aACA,mBACA,QACA,gBACA,kBACA,oCAEA,uMACE,0BACA,sCAIJ,yLACE,gBACA,yBACA,WACA,YACA,SACA,cACA,8CACA,eAEA,2MACE,mBAIJ,iLACE,aACA,sBACA,YACA,OAGF,mLACE,eACA,gBACA,oCACA,gBACA,uBAGF,mLACE,eACA,iBACA,yCACA,gBACA,uBAGF,6MACE,sCAGF,uLACE,cACA,gBACA,+CACA,kBACA,yBACA,eACA,eACA,iBACA,uCAEA,mMACE,8CAGF,uMACE,8CACA,kDACA,qCAKJ,mLACE,sBACA,oBACA,QACA,SAGF,mMACE,aACA,yBACA,QAGF,uLACE,cACA,WACA,YACA,UACA,YACA,kBACA,yBACA,eACA,eACA,iBACA,yCAEA,mMACE,sCACA,qCAIJ,qLACE,WACA,sBACA,gBACA,+CACA,kBACA,yBACA,eACA,oCAEA,iMACE,aACA,8CAIJ,sXAEE,eACA,iBACA,sCAGF,iMACE,yCAGF,mJACE,wBAIJ,2FACE,sBACA,aACA,mBACA,uBACA,WACA,YACA,YACA,eACA,kBACA,qCAEA,uGACE,oCACA,yCAGF,uGACE,WACA,YACA,oCACA,UACA,8BAIJ,qFACE,eAGE,+IACE,0CASJ,mHACE,MACA,OACA,wBACA,4CACA,2CAEA,iKACE,qBACA,OA6BA,iKACE,SAEA,6KACE,yBAIJ,iIACE,yCAEA,2LACE,uBAIJ,uOACE,wCACA,WACE,mFAGF,qPACE,WACA,kBACA,SACA,YACA,WACA,UAlER,qHACE,MACA,QACA,wBACA,6CACA,2CAEA,mKACE,qBACA,QAIA,mIACE,wCAEA,6LACE,yBAIJ,yOACE,uCACA,WACE,mFAIF,uPACE,WACA,kBACA,SACA,YACA,UACA,UAlCR,yHACE,SACA,OACA,wBACA,6CACA,wCAEA,uKACE,wBACA,OA6BA,uKACE,SAEA,mLACE,yBAIJ,uIACE,yCAEA,iMACE,uBAIJ,6OACE,wCACA,WACE,oFAGF,2PACE,WACA,kBACA,SACA,YACA,WACA,UAlER,2HACE,SACA,QACA,wBACA,8CACA,wCAEA,yKACE,wBACA,QAIA,yIACE,wCAEA,mMACE,yBAIJ,+OACE,uCACA,WACE,oFAIF,6PACE,WACA,kBACA,SACA,YACA,UACA,UAuCV,qHACE,eAGF,+FACE,gBACA,iBACA,gBAEA,mJACE,gBAIJ,+GACE,aAGF,iGACE,aACA,mBACA,uBACA,WACA,YACA,YACA,+BACA,kBACA,eACA,uCACA,wBACA,kBACA,gBAEA,iHACE,WACA,kBACA,MACA,OACA,WACA,YACA,8BACA,UACA,4BACA,kBAGF,yGACE,WACA,YACA,kBACA,UACA,8BAGF,2IACE,uCACA,oCAEA,mJACE,mCACA,8BAKF,qJACE,mCAIJ,mHACE,WACA,mBACA,oBACA,yCAIA,yHACE,sCAKN,iFACE,oBACA,cACA,UACA,YACA,oCAEA,2IACE,sCAGF,+CAXF,iFAYI,sCAEA,6IACE,qCAKN,kBACE,KACE,uBAEF,GACE,0BAIJ,2FACE,iBAGF,6FACE,kBAGF,iGACE,+BACA,eACA,gBACA,sBACA,iBACA,oCAEA,yIACE,kDAIJ,oBACE,GACE,uBAEF,KACE,0BAIJ,sBACE,GACE,0BAEF,IACE,2BAEF,KACE,2BAOJ,iIAhqCA,6cAOF,+KACE,sCACA,kCAEA,2LACE,sCACA,kCAIJ,2LACE,uCAqpCA,+CA56BF,uEA3PE,6cAOF,qHACE,sCACA,kCAEA,iIACE,sCACA,kCAIJ,iIACE,wCA2pCF,uCACE,gKAIE","file":"client.css","sourcesContent":["@use 'sass:map';\n\n$pp-dev-height: 32px;\n$pp-dev-peek: 4px;\n\n// Corner map: v/h — anchored edges; sx — horizontal slide direction for minimize/auto-hide\n// (1 → slides right, -1 → slides left); radius/shadow face the viewport center;\n// edge — hairline border on the exposed horizontal edge.\n$pp-dev-corners: (\n 'top-left': (\n v: top,\n h: left,\n sx: -1,\n radius: 0 0 4px 0,\n shadow: 2px 2px 8px 0 rgba(34, 34, 34, 0.08),\n edge: border-bottom,\n ),\n 'top-right': (\n v: top,\n h: right,\n sx: 1,\n radius: 0 0 0 4px,\n shadow: -2px 2px 8px 0 rgba(34, 34, 34, 0.08),\n edge: border-bottom,\n ),\n 'bottom-left': (\n v: bottom,\n h: left,\n sx: -1,\n radius: 0 4px 0 0,\n shadow: 2px -2px 8px 0 rgba(34, 34, 34, 0.08),\n edge: border-top,\n ),\n 'bottom-right': (\n v: bottom,\n h: right,\n sx: 1,\n radius: 4px 0 0 0,\n shadow: -2px -2px 8px 0 rgba(34, 34, 34, 0.08),\n edge: border-top,\n ),\n);\n\n// Light/dark color maps, shared by the default (light) rules, the prefers-color-scheme:dark\n// media query (Auto), and the explicit data-pp-dev-theme override (Dark/Light picked in the\n// panel's settings popover — see src/client/theme.ts). One place to edit either palette.\n$pp-dev-light-colors: (\n primary: #075b7e,\n secondary: rgba(34, 34, 34, 0.64),\n success: #077e45,\n info: #17a2b8,\n warning: #ffb000,\n danger: #ac2b2b,\n light: #f8f9fa,\n dark: #343a40,\n 'white': #ffffff,\n 'black': #000000,\n // Outline of inputs and outlined buttons.\n line: rgba(34, 34, 34, 0.25),\n // The \"this tab\" badge in the Users popover.\n tab: #7a3fb8,\n);\n$pp-dev-dark-colors: (\n primary: #2a8db5,\n secondary: rgba(220, 220, 220, 0.64),\n success: #0fad5e,\n info: #2dccff,\n warning: #ffb302,\n danger: #e05252,\n light: #343a40,\n dark: #f8f9fa,\n 'white': #000000,\n 'black': #ffffff,\n line: rgba(220, 220, 220, 0.3),\n tab: #b48ae6,\n);\n\n@mixin pp-dev-theme-colors($colors) {\n @each $name, $value in $colors {\n --pp-dev-info-color-#{$name}: #{$value};\n }\n}\n\n// rgba() literals don't follow the --pp-dev-info-color-primary reassignment above,\n// so the button fill/border are re-tinted here to match the dark-mode primary.\n@mixin pp-dev-dark-tints {\n .pp-dev-info__vars-btn {\n background-color: rgba(42, 141, 181, 0.14);\n border-color: rgba(42, 141, 181, 0.45);\n\n &:hover {\n background-color: rgba(42, 141, 181, 0.24);\n border-color: rgba(42, 141, 181, 0.65);\n }\n }\n\n .pp-dev-info__settings-group {\n border-top-color: rgba(255, 255, 255, 0.15);\n }\n}\n\n.pp-dev-info-namespace {\n // Define theme colors — light by default; overridden for Auto (media query, below) or an\n // explicit Dark/Light pick (html[data-pp-dev-theme], below — always wins on specificity).\n @include pp-dev-theme-colors($pp-dev-light-colors);\n\n html[data-pp-dev-theme='light'] & {\n @include pp-dev-theme-colors($pp-dev-light-colors);\n }\n\n .pp-dev-info__popup {\n position: fixed;\n top: 10px;\n right: 10px;\n width: 280px;\n max-width: calc(100vw - 20px);\n height: auto;\n background-color: var(--pp-dev-info-color-white);\n box-shadow: 0 2px 4px rgba(34, 34, 34, 0.2);\n border-radius: 2px;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 4px;\n padding: 12px;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n z-index: 100001;\n border-left: 2px solid var(--pp-dev-info-color-primary);\n transform: translateX(0);\n opacity: 1;\n box-sizing: border-box;\n --pp-dev-info-popup-accent: var(--pp-dev-info-color-primary);\n\n &.entering {\n transform: translateX(calc(100% + 10px));\n opacity: 0;\n }\n\n &.exiting {\n transform: translateX(calc(100% + 10px));\n opacity: 0;\n }\n\n &-title {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 8px;\n padding: 0;\n min-height: 0;\n width: 100%;\n box-sizing: border-box;\n border-bottom: 0;\n color: #040404;\n\n &-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n color: var(--pp-dev-info-popup-accent);\n }\n\n &-text {\n flex: 1;\n color: #040404;\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n text-align: left;\n word-break: break-word;\n }\n\n &-close {\n cursor: pointer;\n min-width: 24px;\n min-height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: 0;\n background: none;\n font: inherit;\n color: rgba(34, 34, 34, 0.64);\n border-radius: 2px;\n transition: color 0.2s ease;\n flex-shrink: 0;\n\n &:hover {\n color: var(--pp-dev-info-color-dark);\n }\n\n &:focus-visible {\n outline: 2px solid var(--pp-dev-info-popup-accent);\n outline-offset: 1px;\n }\n\n svg {\n transition: transform 0.2s ease;\n }\n }\n }\n\n &-content {\n margin-left: 24px;\n padding: 0;\n width: calc(100% - 24px);\n overflow-y: auto;\n box-sizing: border-box;\n flex-grow: 0;\n background-color: transparent;\n color: rgba(34, 34, 34, 0.8);\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n text-align: left;\n word-break: break-word;\n white-space: pre-line;\n }\n\n &--success {\n --pp-dev-info-popup-accent: var(--pp-dev-info-color-success);\n border-left-color: var(--pp-dev-info-color-success);\n }\n\n &--danger {\n --pp-dev-info-popup-accent: var(--pp-dev-info-color-danger);\n border-left-color: var(--pp-dev-info-color-danger);\n }\n\n &--info {\n --pp-dev-info-popup-accent: var(--pp-dev-info-color-info);\n border-left-color: var(--pp-dev-info-color-info);\n }\n\n &--warning {\n --pp-dev-info-popup-accent: var(--pp-dev-info-color-warning);\n border-left-color: var(--pp-dev-info-color-warning);\n }\n\n // Popups anchored to the left screen edge (panel in a left corner)\n &--left {\n right: auto;\n left: 10px;\n border-left: none;\n border-right: 2px solid var(--pp-dev-info-popup-accent);\n\n &.entering,\n &.exiting {\n transform: translateX(calc(-100% - 10px));\n }\n }\n }\n\n &.pp-dev-info__confirm-overlay,\n .pp-dev-info__confirm-overlay {\n position: fixed;\n inset: 0;\n z-index: 100003;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: rgba(0, 0, 0, 0.35);\n backdrop-filter: blur(2px);\n -webkit-backdrop-filter: blur(2px);\n }\n\n .pp-dev-info__confirm {\n width: min(408px, calc(100vw - 32px));\n border-radius: 3px;\n border: 1px solid rgba(0, 0, 0, 0.15);\n background-color: var(--pp-dev-info-color-white);\n box-shadow: 0px 8px 32px 0px rgba(34, 34, 34, 0.4);\n overflow: hidden;\n\n &-title {\n padding: 14px 16px;\n font-size: 15px;\n font-weight: 600;\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n color: var(--pp-dev-info-color-dark);\n background-color: rgba(0, 0, 0, 0.03);\n }\n\n &-content {\n padding: 16px;\n white-space: pre-wrap;\n color: var(--pp-dev-info-color-dark);\n font-size: 13px;\n line-height: 1.5;\n }\n\n &-actions {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 0 16px 16px;\n }\n\n &-btn {\n width: 100%;\n padding: 8px 12px;\n border-radius: 6px;\n border: 1px solid transparent;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n\n &--cancel {\n color: var(--pp-dev-info-color-dark);\n background-color: transparent;\n border-color: rgba(0, 0, 0, 0.2);\n }\n\n &--confirm {\n color: var(--pp-dev-info-color-white);\n background-color: var(--pp-dev-info-color-primary);\n }\n\n &:hover {\n opacity: 0.9;\n }\n }\n }\n\n &.pp-dev-info,\n .pp-dev-info {\n position: fixed;\n z-index: 100000;\n white-space: nowrap;\n width: fit-content;\n height: $pp-dev-height;\n text-align: center;\n padding: 2px;\n gap: 8px;\n background-color: var(--pp-dev-info-color-white);\n color: var(--pp-dev-info-color-dark);\n box-sizing: border-box;\n display: flex;\n align-items: center;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: visible;\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n\n // Setup default values for styles that can be overlapped by other page styles\n // (e.g. color, font-family, font-size etc.)\n // This is needed to make sure that the extension styles are not overlapped by the page styles\n // and the extension is still usable\n * {\n color: var(--pp-dev-info-color-dark);\n font-family: 'Inter', sans-serif;\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n letter-spacing: 0;\n text-decoration: none;\n text-transform: inherit;\n vertical-align: inherit;\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0;\n outline: 0;\n background: 0 0;\n list-style: none;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n\n &__content {\n display: flex;\n align-items: center;\n gap: 0px;\n }\n\n &__section {\n display: flex;\n align-items: center;\n position: relative;\n padding: 0 8px;\n\n &:not(:last-child)::after {\n content: '';\n position: absolute;\n right: 0;\n top: 50%;\n transform: translateY(-50%);\n height: 16px;\n width: 1px;\n background-color: rgba(34, 34, 34, 0.24);\n\n html[data-pp-dev-theme='dark'] & {\n background-color: rgba(255, 255, 255, 0.2);\n }\n\n @media screen and (prefers-color-scheme: dark) {\n background-color: rgba(255, 255, 255, 0.2);\n\n html[data-pp-dev-theme='light'] & {\n background-color: rgba(34, 34, 34, 0.24);\n }\n }\n }\n\n &:first-child {\n padding-left: 0;\n }\n\n &:last-child {\n padding-right: 0;\n }\n }\n\n &__item {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n }\n\n &__label {\n color: var(--pp-dev-info-color-secondary);\n font-weight: 400;\n }\n\n &__value {\n font-weight: 600;\n }\n\n &__link {\n color: var(--pp-dev-info-color-primary);\n text-decoration: none;\n transition: color 0.2s ease;\n display: flex;\n align-items: center;\n gap: 8px;\n\n &:hover {\n color: var(--pp-dev-info-color-primary);\n text-decoration: underline;\n }\n }\n\n @mixin bold {\n font-weight: 700;\n }\n\n .primary {\n color: var(--pp-dev-info-color-primary) !important;\n }\n\n .success {\n color: var(--pp-dev-info-color-success) !important;\n }\n\n .info {\n color: var(--pp-dev-info-color-info) !important;\n }\n\n .warning {\n color: var(--pp-dev-info-color-warning) !important;\n }\n\n .danger {\n color: var(--pp-dev-info-color-danger) !important;\n }\n\n a {\n color: var(--pp-dev-info-color-primary);\n text-decoration: none;\n vertical-align: middle;\n line-height: 18px;\n\n &:hover {\n text-decoration: none;\n }\n\n &:active,\n &:hover {\n outline: 0;\n }\n }\n\n button {\n padding: 1px;\n border: none;\n background: none;\n cursor: pointer;\n outline: none;\n }\n\n .bold,\n .status-text {\n @include bold;\n }\n\n &__drag-handle {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 14px;\n height: 28px;\n cursor: grab;\n touch-action: none;\n border-radius: 3px;\n color: var(--pp-dev-info-color-secondary);\n opacity: 0.55;\n transition:\n opacity 0.2s ease,\n background-color 0.2s ease;\n\n svg {\n pointer-events: none;\n fill: currentColor;\n }\n\n &:hover {\n opacity: 1;\n background-color: rgba(7, 91, 126, 0.06);\n }\n }\n\n &__settings-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n border-radius: 3px;\n cursor: pointer;\n color: var(--pp-dev-info-color-secondary);\n transition: all 0.2s ease;\n\n svg {\n width: 16px;\n height: 16px;\n fill: none;\n transition: transform 0.3s ease;\n }\n\n &:hover {\n color: var(--pp-dev-info-color-primary);\n background-color: rgba(7, 91, 126, 0.06);\n\n svg {\n transform: rotate(45deg);\n }\n }\n }\n\n &__settings {\n position: absolute;\n min-width: 216px;\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n background-color: var(--pp-dev-info-color-white);\n border: 1px solid rgba(34, 34, 34, 0.15);\n border-radius: 3px;\n box-shadow: 0 4px 16px rgba(34, 34, 34, 0.2);\n z-index: 100002;\n cursor: default;\n white-space: normal;\n text-align: left;\n\n .pp-dev-info__settings-title {\n font-size: 10px;\n font-weight: 600;\n color: var(--pp-dev-info-color-secondary);\n text-transform: uppercase;\n letter-spacing: 0.4px;\n }\n\n .pp-dev-info__settings-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n }\n\n .pp-dev-info__settings-toggle {\n appearance: auto;\n -webkit-appearance: checkbox;\n width: 14px;\n height: 14px;\n accent-color: var(--pp-dev-info-color-primary);\n cursor: pointer;\n flex-shrink: 0;\n }\n\n .pp-dev-info__corner-grid {\n display: grid;\n grid-template-columns: repeat(2, 30px);\n gap: 4px;\n }\n\n .pp-dev-info__corner-btn {\n width: 30px;\n height: 22px;\n border: 1px solid var(--pp-dev-info-color-line);\n border-radius: 3px;\n cursor: pointer;\n position: relative;\n background: transparent;\n transition: border-color 0.2s ease;\n\n &::after {\n content: '';\n position: absolute;\n width: 10px;\n height: 6px;\n border-radius: 1px;\n background-color: var(--pp-dev-info-color-secondary);\n transition: background-color 0.2s ease;\n }\n\n &--top-left::after {\n top: 2px;\n left: 2px;\n }\n\n &--top-right::after {\n top: 2px;\n right: 2px;\n }\n\n &--bottom-left::after {\n bottom: 2px;\n left: 2px;\n }\n\n &--bottom-right::after {\n bottom: 2px;\n right: 2px;\n }\n\n &:hover {\n border-color: var(--pp-dev-info-color-primary);\n }\n\n &.active {\n border-color: var(--pp-dev-info-color-primary);\n\n &::after {\n background-color: var(--pp-dev-info-color-primary);\n }\n }\n }\n\n .pp-dev-info__theme-grid {\n display: flex;\n gap: 4px;\n }\n\n .pp-dev-info__theme-btn {\n padding: 3px 8px;\n border: 1px solid var(--pp-dev-info-color-line);\n border-radius: 3px;\n cursor: pointer;\n background: transparent;\n font-size: 11px;\n line-height: 16px;\n color: var(--pp-dev-info-color-secondary);\n transition:\n border-color 0.2s ease,\n color 0.2s ease,\n background-color 0.2s ease;\n\n &:hover {\n border-color: var(--pp-dev-info-color-primary);\n color: var(--pp-dev-info-color-primary);\n }\n\n &.active {\n border-color: var(--pp-dev-info-color-primary);\n background-color: var(--pp-dev-info-color-primary);\n color: var(--pp-dev-info-color-white);\n }\n\n &:focus-visible {\n outline: 2px solid var(--pp-dev-info-color-primary);\n outline-offset: 1px;\n }\n }\n\n .pp-dev-info__settings-hide-btn {\n width: 100%;\n padding: 6px 10px;\n border: 1px solid rgba(34, 34, 34, 0.2);\n border-radius: 4px;\n cursor: pointer;\n font-weight: 600;\n color: var(--pp-dev-info-color-danger);\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: rgba(172, 43, 43, 0.06);\n }\n }\n\n .pp-dev-info__settings-group {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding-top: 10px;\n border-top: 1px solid rgba(34, 34, 34, 0.12);\n }\n\n .pp-dev-info__vars-buttons {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .pp-dev-info__vars-btn {\n width: 100%;\n padding: 6px 10px;\n border-radius: 4px;\n cursor: pointer;\n font-weight: 600;\n text-align: center;\n color: var(--pp-dev-info-color-primary);\n background-color: rgba(7, 91, 126, 0.1);\n border: 1px solid rgba(7, 91, 126, 0.4);\n transition:\n background-color 0.2s ease,\n border-color 0.2s ease;\n\n &:hover {\n background-color: rgba(7, 91, 126, 0.18);\n border-color: rgba(7, 91, 126, 0.6);\n }\n\n &:focus-visible {\n outline: 2px solid var(--pp-dev-info-color-primary);\n outline-offset: 1px;\n }\n }\n\n .pp-dev-info__settings-hint {\n font-size: 10px;\n line-height: 14px;\n color: var(--pp-dev-info-color-secondary);\n\n code {\n font-family: monospace;\n font-size: 10px;\n }\n }\n\n .pp-dev-info__settings-reset {\n align-self: flex-start;\n font-size: 11px;\n color: var(--pp-dev-info-color-primary);\n cursor: pointer;\n\n &:hover {\n text-decoration: underline;\n }\n }\n }\n\n // ── Users (PP-4597) ──────────────────────────────────────────────────────\n &__users-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n border-radius: 3px;\n cursor: pointer;\n color: var(--pp-dev-info-color-secondary);\n transition: all 0.2s ease;\n\n svg {\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n }\n\n &:hover {\n color: var(--pp-dev-info-color-primary);\n background-color: rgba(7, 91, 126, 0.06);\n }\n }\n\n // A saved user's tab: the button stands out, so the tab is never taken for your own.\n &.pp-dev-info--user-tab .pp-dev-info__users-btn {\n color: #ffffff;\n background-color: #7a3fb8;\n\n &:hover {\n background-color: #8d52cc;\n }\n }\n\n &__users.pp-dev-info__settings {\n width: 320px;\n max-width: calc(100vw - 16px);\n box-sizing: border-box;\n\n .pp-dev-info__users-tab {\n font-size: 12px;\n line-height: 16px;\n color: var(--pp-dev-info-color-dark);\n }\n\n // Over the radios: they pick who localhost works as, not this tab.\n .pp-dev-info__users-list-head {\n margin-bottom: -4px;\n padding-left: 4px;\n font-size: 9px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--pp-dev-info-color-secondary);\n }\n\n .pp-dev-info__users-badge {\n margin-left: 6px;\n padding: 0 5px;\n border: 1px solid currentColor;\n border-radius: 3px;\n font-size: 9px;\n font-weight: 400;\n line-height: 13px;\n vertical-align: 1px;\n color: var(--pp-dev-info-color-tab);\n }\n\n .pp-dev-info__users-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n max-height: 240px;\n overflow-y: auto;\n }\n\n .pp-dev-info__users-row {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 6px;\n border-radius: 3px;\n border-left: 2px solid transparent;\n\n &.is-current {\n border-left-color: #7a3fb8;\n background-color: rgba(122, 63, 184, 0.08);\n }\n }\n\n .pp-dev-info__users-default {\n appearance: auto;\n -webkit-appearance: radio;\n width: 13px;\n height: 13px;\n margin: 0;\n flex-shrink: 0;\n accent-color: var(--pp-dev-info-color-primary);\n cursor: pointer;\n\n &:disabled {\n cursor: not-allowed;\n }\n }\n\n .pp-dev-info__users-who {\n display: flex;\n flex-direction: column;\n min-width: 0;\n flex: 1;\n }\n\n .pp-dev-info__users-name {\n font-size: 12px;\n font-weight: 600;\n color: var(--pp-dev-info-color-dark);\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .pp-dev-info__users-meta {\n font-size: 10px;\n line-height: 13px;\n color: var(--pp-dev-info-color-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .needs-login .pp-dev-info__users-meta {\n color: var(--pp-dev-info-color-danger);\n }\n\n .pp-dev-info__users-action {\n flex-shrink: 0;\n padding: 2px 7px;\n border: 1px solid var(--pp-dev-info-color-line);\n border-radius: 3px;\n background: transparent;\n cursor: pointer;\n font-size: 11px;\n line-height: 16px;\n color: var(--pp-dev-info-color-primary);\n\n &:hover {\n border-color: var(--pp-dev-info-color-primary);\n }\n\n &--accent {\n border-color: var(--pp-dev-info-color-primary);\n background-color: var(--pp-dev-info-color-primary);\n color: var(--pp-dev-info-color-white);\n }\n }\n\n // A token user's row while it is being edited: name, new token, Save and Cancel.\n .pp-dev-info__users-edit {\n flex-direction: column;\n align-items: stretch;\n gap: 6px;\n margin: 0;\n }\n\n .pp-dev-info__users-edit-actions {\n display: flex;\n justify-content: flex-end;\n gap: 6px;\n }\n\n .pp-dev-info__users-remove {\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n padding: 0;\n border: none;\n border-radius: 3px;\n background: transparent;\n cursor: pointer;\n font-size: 15px;\n line-height: 20px;\n color: var(--pp-dev-info-color-secondary);\n\n &:hover {\n color: var(--pp-dev-info-color-danger);\n background-color: rgba(172, 43, 43, 0.08);\n }\n }\n\n .pp-dev-info__users-input {\n width: 100%;\n box-sizing: border-box;\n padding: 5px 8px;\n border: 1px solid var(--pp-dev-info-color-line);\n border-radius: 3px;\n background: transparent;\n font-size: 12px;\n color: var(--pp-dev-info-color-dark);\n\n &:focus {\n outline: none;\n border-color: var(--pp-dev-info-color-primary);\n }\n }\n\n .pp-dev-info__users-error,\n .pp-dev-info__users-unavailable {\n font-size: 11px;\n line-height: 15px;\n color: var(--pp-dev-info-color-danger);\n }\n\n .pp-dev-info__users-unavailable {\n color: var(--pp-dev-info-color-secondary);\n }\n\n [hidden] {\n display: none !important;\n }\n }\n\n &__wrap-btn {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n cursor: pointer;\n border-radius: 3px;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: rgba(7, 91, 126, 0.06);\n animation: arrowHover 0.8s linear infinite;\n }\n\n &-arrow {\n width: 16px;\n height: 16px;\n color: var(--pp-dev-info-color-dark);\n fill: none;\n transition: transform 0.2s ease;\n }\n }\n\n &.closed {\n z-index: 100002;\n\n & .pp-dev-info__wrap-btn {\n &:hover {\n animation: arrowHover 1.2s linear infinite;\n }\n }\n }\n\n // Corner variants: placement, center-facing radius/shadow, direction-aware\n // minimize (.closed) and auto-hide slides. The corner class is always rendered\n // on the panel root (server default: bottom-right).\n @each $name, $c in $pp-dev-corners {\n &.pp-dev-info--#{$name} {\n #{map.get($c, v)}: 0;\n #{map.get($c, h)}: 0;\n border-radius: map.get($c, radius);\n box-shadow: map.get($c, shadow);\n #{map.get($c, edge)}: 1px solid rgba(34, 34, 34, 0.08);\n\n .pp-dev-info__settings {\n #{map.get($c, v)}: calc(100% + 8px);\n #{map.get($c, h)}: 0;\n }\n\n @if map.get($c, sx) == 1 {\n &.closed {\n transform: translateX(calc(100% - $pp-dev-height));\n\n .pp-dev-info__wrap-btn-arrow {\n transform: rotate(180deg);\n }\n }\n\n &.pp-dev-info--auto-hide:not(.is-peeking):not(.is-dragging) {\n transform: translateX(calc(100% - $pp-dev-peek));\n box-shadow:\n map.get($c, shadow),\n inset $pp-dev-peek 0 0 0 var(--pp-dev-info-color-primary);\n\n // Extended invisible hover zone on the inner side of the 4px strip\n &::after {\n content: '';\n position: absolute;\n top: -6px;\n bottom: -6px;\n left: -8px;\n width: 8px;\n }\n }\n } @else {\n .pp-dev-info__wrap-btn {\n order: 99;\n\n &-arrow {\n transform: rotate(180deg);\n }\n }\n\n &.closed {\n transform: translateX(calc(-100% + $pp-dev-height));\n\n .pp-dev-info__wrap-btn-arrow {\n transform: rotate(0deg);\n }\n }\n\n &.pp-dev-info--auto-hide:not(.is-peeking):not(.is-dragging) {\n transform: translateX(calc(-100% + $pp-dev-peek));\n box-shadow:\n map.get($c, shadow),\n inset (-$pp-dev-peek) 0 0 0 var(--pp-dev-info-color-primary);\n\n &::after {\n content: '';\n position: absolute;\n top: -6px;\n bottom: -6px;\n right: -8px;\n width: 8px;\n }\n }\n }\n }\n }\n\n &.pp-dev-info--auto-hide {\n z-index: 100002;\n }\n\n &.is-dragging {\n transition: none;\n user-select: none;\n cursor: grabbing;\n\n .pp-dev-info__drag-handle {\n cursor: grabbing;\n }\n }\n\n &.pp-dev-info--hidden {\n display: none;\n }\n\n .sync-button {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n background-color: transparent;\n border-radius: 3px;\n cursor: pointer;\n color: var(--pp-dev-info-color-primary);\n transition: all 0.2s ease;\n position: relative;\n overflow: hidden;\n\n &::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: currentColor;\n opacity: 0;\n transition: opacity 0.2s ease;\n border-radius: 3px;\n }\n\n svg {\n width: 16px;\n height: 16px;\n position: relative;\n z-index: 1;\n transition: transform 0.3s ease;\n }\n\n &:hover:not(.disabled) {\n color: var(--pp-dev-info-color-primary);\n background-color: rgba(7, 91, 126, 0.06);\n\n svg {\n transform: scale(1.1) rotate(45deg);\n transition: transform 0.2s ease;\n }\n }\n\n &:active:not(.disabled) {\n svg {\n transform: scale(0.9) rotate(45deg);\n }\n }\n\n &.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n color: var(--pp-dev-info-color-secondary);\n }\n\n &.syncing {\n svg {\n animation: rotate 1.5s linear infinite;\n }\n }\n }\n\n &__sep {\n display: inline-flex;\n flex-shrink: 0;\n width: 1px;\n height: 16px;\n background-color: rgba(34, 34, 34, 0.24);\n\n html[data-pp-dev-theme='dark'] & {\n background-color: rgba(255, 255, 255, 0.2);\n }\n\n @media screen and (prefers-color-scheme: dark) {\n background-color: rgba(255, 255, 255, 0.2);\n\n html[data-pp-dev-theme='light'] & {\n background-color: rgba(34, 34, 34, 0.24);\n }\n }\n }\n\n @keyframes rotate {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n\n .margin-5 {\n margin-right: 5px;\n }\n\n .margin-10 {\n margin-right: 10px;\n }\n\n .custom-font {\n font-family: 'Inter', sans-serif;\n font-size: 13px;\n font-weight: 400;\n vertical-align: middle;\n line-height: 18px;\n color: var(--pp-dev-info-color-dark);\n\n &:not(.not-colored) a {\n color: var(--pp-dev-info-color-primary) !important;\n }\n }\n\n @keyframes rotation {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }\n\n @keyframes arrowHover {\n 0% {\n transform: translateX(2px);\n }\n 50% {\n transform: translateX(-2px);\n }\n 100% {\n transform: translateX(2px);\n }\n }\n\n // Explicit Dark pick (html[data-pp-dev-theme='dark'], set via the settings popover's Theme\n // row — see src/client/theme.ts) — always wins over both the light default above and the\n // Auto media query below, on selector specificity alone.\n html[data-pp-dev-theme='dark'] & {\n @include pp-dev-theme-colors($pp-dev-dark-colors);\n @include pp-dev-dark-tints;\n }\n\n // Auto (OS/browser preference) — same values, only takes effect when no explicit\n // html[data-pp-dev-theme] override is set (those always outrank a plain :root/& selector).\n @media screen and (prefers-color-scheme: dark) {\n @include pp-dev-theme-colors($pp-dev-dark-colors);\n @include pp-dev-dark-tints;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n &.pp-dev-info,\n .pp-dev-info,\n .pp-dev-info__popup,\n .pp-dev-info__settings {\n transition: none;\n }\n }\n}\n"]}
@@ -652,6 +652,8 @@ function initPanelSettings($panel, controller, hooks) {
652
652
  const USERS_API = '/@api/users';
653
653
  const REFRESH_INTERVAL = 3000;
654
654
  const USER_HOST_REGEXP = /^([a-z](?:[a-z0-9-]*[a-z0-9])?)\.localhost$/;
655
+ /** Marks the user this tab works as, apart from the radio, which picks localhost's user. */
656
+ const THIS_TAB_BADGE = '<span class="pp-dev-info__users-badge">this tab</span>';
655
657
  const STATE_LABELS = {
656
658
  pending: 'not logged in yet',
657
659
  active: 'logged in',
@@ -714,6 +716,8 @@ function initUsersPanel($panel, hooks) {
714
716
  let data = null;
715
717
  // What the list shows now, so a refresh with the same data leaves it (and the focus) alone.
716
718
  let renderedData = '';
719
+ // The token user being edited, whose row shows the edit form instead.
720
+ let editing = null;
717
721
  const onDocClick = (ev) => {
718
722
  const target = ev.target;
719
723
  if ($popover && !$popover.contains(target) && !$btn.contains(target)) {
@@ -729,6 +733,7 @@ function initUsersPanel($panel, hooks) {
729
733
  if (!$popover) {
730
734
  return;
731
735
  }
736
+ editing = null;
732
737
  window.clearInterval(refreshTimer);
733
738
  $popover.remove();
734
739
  $popover = null;
@@ -762,11 +767,25 @@ function initUsersPanel($panel, hooks) {
762
767
  return null;
763
768
  }
764
769
  };
770
+ /**
771
+ * Who this tab works as: on a user's host that user, on localhost the default user, and on an IP
772
+ * address or a custom domain you (`undefined`). Before the users are loaded, a user's host only.
773
+ */
774
+ const getCurrentUser = () => tabUser ?? (window.location.hostname === 'localhost' ? data?.defaultUser : null) ?? undefined;
765
775
  const renderList = () => {
766
776
  const $list = $popover?.querySelector('.pp-dev-info__users-list');
767
777
  if (!$popover || !$list || !data) {
768
778
  return;
769
779
  }
780
+ // The user being edited is gone (removed, logged out): nothing to edit any more.
781
+ if (editing && !data.users.some((user) => user.name === editing && user.kind === 'token')) {
782
+ editing = null;
783
+ }
784
+ else if (editing && $list.querySelector('.pp-dev-info__users-edit')?.dataset.user === editing) {
785
+ // A refresh must not wipe what is being typed into the edit form. (Edit on another user
786
+ // redraws it for that one.)
787
+ return;
788
+ }
770
789
  const snapshot = JSON.stringify(data);
771
790
  if (snapshot === renderedData) {
772
791
  return;
@@ -777,9 +796,7 @@ function initUsersPanel($panel, hooks) {
777
796
  ? document.activeElement.dataset.focusKey
778
797
  : undefined;
779
798
  const defaultUser = data.defaultUser;
780
- // The main host (localhost) works as the default user, a user's host as that user, and an IP
781
- // address or a custom domain as you.
782
- const currentUser = tabUser ?? (window.location.hostname === 'localhost' ? defaultUser : null) ?? undefined;
799
+ const currentUser = getCurrentUser();
783
800
  const $tab = $popover.querySelector('.pp-dev-info__users-tab strong');
784
801
  if ($tab) {
785
802
  $tab.textContent = currentUser ?? 'you';
@@ -789,7 +806,7 @@ function initUsersPanel($panel, hooks) {
789
806
  <input type="radio" name="pp-dev-default-user" class="pp-dev-info__users-default" value="" data-focus-key=":default"
790
807
  title="Make the main host (localhost) work as you" ${defaultUser ? '' : 'checked'} />
791
808
  <div class="pp-dev-info__users-who">
792
- <span class="pp-dev-info__users-name">You</span>
809
+ <span class="pp-dev-info__users-name">You${currentUser ? '' : THIS_TAB_BADGE}</span>
793
810
  <span class="pp-dev-info__users-meta">original user · the dev panel always works as you</span>
794
811
  </div>
795
812
  ${
@@ -804,6 +821,19 @@ function initUsersPanel($panel, hooks) {
804
821
  const needsLogin = user.kind === 'session' && user.state !== 'active';
805
822
  const needsAttention = needsLogin || user.state === 'expired';
806
823
  const name = escapeHtml(user.name);
824
+ if (user.kind === 'token' && user.name === editing) {
825
+ return `<form class="pp-dev-info__users-row pp-dev-info__users-edit" data-user="${name}">
826
+ <input class="pp-dev-info__users-input pp-dev-info__users-edit-name" value="${name}" maxlength="32"
827
+ autocomplete="off" spellcheck="false" aria-label="Name" data-focus-key="${name}:edit-name"
828
+ title="Lowercase latin letters, digits and -, starting with a letter. The user opens on <name>.localhost." />
829
+ <input class="pp-dev-info__users-input pp-dev-info__users-edit-token" type="password" autocomplete="off"
830
+ placeholder="New API token (empty keeps the current one)" aria-label="New API token" data-focus-key="${name}:edit-token" />
831
+ <div class="pp-dev-info__users-edit-actions">
832
+ <button type="submit" class="pp-dev-info__users-action pp-dev-info__users-action--accent" data-focus-key="${name}:save">Save</button>
833
+ <button type="button" class="pp-dev-info__users-action" data-cancel-edit data-focus-key="${name}:cancel">Cancel</button>
834
+ </div>
835
+ </form>`;
836
+ }
807
837
  let defaultTitle = `Make the main host (localhost) work as ${name}`;
808
838
  if (!canBeDefault) {
809
839
  defaultTitle =
@@ -814,12 +844,15 @@ function initUsersPanel($panel, hooks) {
814
844
  title="${defaultTitle}"
815
845
  ${user.name === defaultUser ? 'checked' : ''} ${canBeDefault ? '' : 'disabled'} />
816
846
  <div class="pp-dev-info__users-who">
817
- <span class="pp-dev-info__users-name">${name}</span>
847
+ <span class="pp-dev-info__users-name">${name}${user.name === currentUser ? THIS_TAB_BADGE : ''}</span>
818
848
  <span class="pp-dev-info__users-meta">${escapeHtml(describeUser(user))}</span>
819
849
  </div>
820
850
  ${needsLogin && user.loginUrl
821
851
  ? `<button type="button" class="pp-dev-info__users-action pp-dev-info__users-action--accent" data-open="${escapeHtml(user.loginUrl)}" data-raw="true" data-focus-key="${name}:login">Log in</button>`
822
852
  : ''}
853
+ ${user.kind === 'token'
854
+ ? `<button type="button" class="pp-dev-info__users-action" data-edit="${name}" data-focus-key="${name}:edit" title="Rename ${name} or replace its API token">Edit</button>`
855
+ : ''}
823
856
  <button type="button" class="pp-dev-info__users-action" data-open="${escapeHtml(user.origin)}" data-focus-key="${name}:open" title="Open this page as ${name}">Open</button>
824
857
  <button type="button" class="pp-dev-info__users-remove" data-remove="${name}" data-focus-key="${name}:remove" title="Remove ${name}" aria-label="Remove ${name}">×</button>
825
858
  </div>`;
@@ -838,6 +871,46 @@ function initUsersPanel($panel, hooks) {
838
871
  window.open($open.dataset.raw ? target : samePageOn(target), '_blank');
839
872
  });
840
873
  });
874
+ const startEditing = (name) => {
875
+ editing = name;
876
+ renderedData = '';
877
+ renderList();
878
+ $list.querySelector('.pp-dev-info__users-edit-name')?.focus();
879
+ };
880
+ $list.querySelectorAll('[data-edit]').forEach(($edit) => {
881
+ $edit.addEventListener('click', (ev) => {
882
+ ev.preventDefault();
883
+ startEditing($edit.dataset.edit);
884
+ });
885
+ });
886
+ $list.querySelector('[data-cancel-edit]')?.addEventListener('click', (ev) => {
887
+ ev.preventDefault();
888
+ setError('');
889
+ startEditing(null);
890
+ });
891
+ $list.querySelector('.pp-dev-info__users-edit')?.addEventListener('submit', async (ev) => {
892
+ ev.preventDefault();
893
+ const name = editing;
894
+ const $form = ev.currentTarget;
895
+ const newName = $form.querySelector('.pp-dev-info__users-edit-name').value.trim();
896
+ const token = $form.querySelector('.pp-dev-info__users-edit-token').value.trim();
897
+ const response = await request('PATCH', `${USERS_API}/${encodeURIComponent(name)}`, {
898
+ name: newName,
899
+ ...(token ? { token } : {}),
900
+ });
901
+ if (!response) {
902
+ return;
903
+ }
904
+ const { user } = (await response.json());
905
+ // This tab's own user got a new host: go on there (the old one would only send it on).
906
+ if (tabUser === name && user.name !== name) {
907
+ window.location.href = samePageOn(user.origin);
908
+ return;
909
+ }
910
+ editing = null;
911
+ renderedData = '';
912
+ await refresh();
913
+ });
841
914
  $list.querySelectorAll('[data-remove]').forEach(($remove) => {
842
915
  $remove.addEventListener('click', async (ev) => {
843
916
  ev.preventDefault();
@@ -946,10 +1019,13 @@ function initUsersPanel($panel, hooks) {
946
1019
  $popover.innerHTML = `
947
1020
  <div class="pp-dev-info__settings-title">Users</div>
948
1021
  <div class="pp-dev-info__users-tab">
949
- This tab works as <strong>${escapeHtml(tabUser ?? 'you')}</strong>.
950
- <span>localhost works as the checked user; each user's own host as that user.</span>
1022
+ This tab works as <strong>${escapeHtml(getCurrentUser() ?? 'you')}</strong>.
1023
+ </div>
1024
+ <div class="pp-dev-info__users-list-head" aria-hidden="true">localhost</div>
1025
+ <div class="pp-dev-info__users-list" role="radiogroup" aria-label="Who localhost works as">
1026
+ <span class="pp-dev-info__users-meta">Loading users…</span>
951
1027
  </div>
952
- <div class="pp-dev-info__users-list" role="radiogroup" aria-label="Default user"></div>
1028
+ <div class="pp-dev-info__settings-hint">The radio picks who localhost works as; each user's own host always works as that user.</div>
953
1029
  <div class="pp-dev-info__users-unavailable" hidden></div>
954
1030
  <form class="pp-dev-info__settings-group pp-dev-info__users-add" hidden>
955
1031
  <span class="pp-dev-info__settings-label">Add user</span>
@@ -983,10 +1059,15 @@ function initUsersPanel($panel, hooks) {
983
1059
  document.addEventListener('click', onDocClick, true);
984
1060
  document.addEventListener('keydown', onKeyDown, true);
985
1061
  hooks?.onOpenChange?.(true);
1062
+ // Shown right away from what was loaded with the panel, then brought up to date.
1063
+ renderList();
1064
+ renderAvailability();
986
1065
  refresh();
987
1066
  // Picks up logins and expired sessions while the popover is open.
988
1067
  refreshTimer = window.setInterval(refresh, REFRESH_INTERVAL);
989
1068
  };
1069
+ // Loaded with the panel, so the popover opens with its list.
1070
+ refresh();
990
1071
  $btn.addEventListener('click', (ev) => {
991
1072
  ev.preventDefault();
992
1073
  if ($popover) {