{"componentChunkName":"component---src-templates-post-jsx","path":"/blog/polypane-30-playgrounds-side-panel-extension-api-updated-video-recording-and-chromium-152/","result":{"data":{"mdx":{"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nconst _frontmatter = {\n  \"title\": \"Polypane 30: Playgrounds, Side Panel extension API, updated video recording and Chromium 152\",\n  \"cover\": \"/img/mail/icon.svg\",\n  \"date\": \"2026-08-19\",\n  \"type\": [\"announcement\"]\n};\nconst layoutProps = {\n  _frontmatter\n};\nconst MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  let {\n    components\n  } = _ref,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, `Polypane 30 introduces Playgrounds so you can open directories as real HTTPS URLs in seconds, adds support for the Side Panel extension API, brings major Network panel improvements, and includes a fully rewritten video recording implementation that's much faster and supports recording sound. It runs on Chromium 152.`), mdx(PolypaneIntro, {\n    mdxType: \"PolypaneIntro\"\n  }), mdx(\"h2\", {\n    \"id\": \"polypane-playgrounds\"\n  }, `Polypane Playgrounds`), mdx(\"p\", null, `Playgrounds lets you select any directory on your device and open it as a real URL over HTTPS. That gives you access to security-restricted APIs, cookies, and localStorage.`), mdx(\"p\", null, `That way you can test your work without all the fuss of setting up a local server, managing ports and dealing with self-signed certificates.`), mdx(\"p\", null, `You choose a folder and a localhost domain, and Polypane does all the work.`), mdx(\"p\", null, `Setting up a Playground is a matter of opening the Playgrounds Manager (through right-clicking the reload button, finding it in the Edit menu, or typing \"playground\" in our `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/docs/command-bar\"\n  }), `command bar`), `) and adding a playground:`), mdx(\"img\", {\n    src: playgroundsmanager,\n    alt: \"The playgrounds manager\",\n    className: \"imgshadow\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `But Playgrounds is much more than just a slightly-more-convenient http-server, and it comes with a bunch of developer goodness:`), mdx(\"h3\", {\n    \"id\": \"live-reloading\"\n  }, `Live reloading`), mdx(\"p\", null, `By default, Playground URLs hook into Polypane's `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/docs/live-auto-reloading/\"\n  }), `live reloading system`), `. Any change you make to a file in the playground will trigger an update in Polypane.`), mdx(\"p\", null, `Polypane re-injects CSS and images without a full reload, ignores system files, and reloads HTML when it changes. Just open your HTML file in any code editor and every save will be visible in Polypane.`), mdx(\"h3\", {\n    \"id\": \"spa-fallback\"\n  }, `SPA Fallback`), mdx(\"p\", null, `Are you trying out an SPA or using client-side routing? Playgrounds can be configured to always serve your index.html for unknown URLs.`), mdx(\"p\", null, `That way your SPA can use client-side routing like the history and navigation API without configuring any server!`), mdx(\"h3\", {\n    \"id\": \"directory-listings\"\n  }, `Directory listings`), mdx(\"p\", null, `Open any file directory (without an `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `index.html`), `) to show a listing of the files in that directory. Navigate into sub-directories and show or hide hidden files. The directory listing is fully styled and supports dark mode, so it works well in any pane. This works for Playgrounds and the file protocol.`), mdx(\"img\", {\n    src: directorylisting,\n    alt: \"The directory listing for a playground\",\n    className: \"imgshadow\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `If you don't want directory listings for a particular Playground, you can disable it in the playground settings.`), mdx(\"h3\", {\n    \"id\": \"portal-enabled\"\n  }, `Portal-enabled`), mdx(\"p\", null, `Lastly, Playgrounds work perfectly together with `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/docs/polypane-portal/\"\n  }), `Polypane Portal`), ` to make your playground available on other browsers and devices, and have them all synced together.`), mdx(\"p\", null, `So you can set a folder up as a Playground, open it in Polypane, and then share it with your team or clients. They can open the same Playground on their devices and see the same content, with synced scroll, hover and focus states.`), mdx(\"video\", {\n    src: playgroundportal,\n    alt: \"Polypane Portal in action\",\n    className: \"imgshadow\",\n    style: {\n      maxWidth: '100%'\n    },\n    controls: true\n  }), mdx(\"p\", null, `I don't think there's any faster way to go from an `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `index.html`), ` on your device to a fully synced, multi-device test environment that's available worldwide.`), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Credit where credit is due`), ` The only reason Playgrounds exists is because of the Firefox Devtools team creating `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://firefox-source-docs.mozilla.org/devtools-user/local_mode/index.html\"\n  }), `Local mode`), ` for Firefox 153. Go try it out! They came up with the concept, I just took it and gave it a Polypane spin.`)), mdx(\"h2\", {\n    \"id\": \"network-panel-improvements\"\n  }, `Network panel improvements`), mdx(\"p\", null, `Thanks to everyone who wrote in to share their experiences with the new Network panel. We fixed several bugs (thanks Matija!) and added a couple of new features to make it even better.`), mdx(\"h3\", {\n    \"id\": \"toggle-between-per-origin-and-all-requests\"\n  }, `Toggle between per origin and all requests`), mdx(\"p\", null, `The Network panel splits requests per origin, a design decision that helps you get a better overview of the requests made by a page and easily see how many external origins are involved in loading it.`), mdx(\"p\", null, `Having the full list of requests is still useful because it can tell you when those external requests are made during load, and what the full request tree looks like. So you can now toggle between the two views with a new button in the top right of the Network panel.`), mdx(\"img\", {\n    src: networkfilter,\n    className: \"imgshadow\",\n    alt: \"Network filter\"\n  }), mdx(\"h3\", {\n    \"id\": \"filter-requests\"\n  }, `Filter requests`), mdx(\"p\", null, `You can now filter requests by typing in the filter input. The filter checks against the URL and its headers. Filtering is case-insensitive by default, but also supports case-sensitive and regex filtering.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: networkfilter,\n    alt: \"Filtering requests in the network panel\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `Testing against headers lets you do things like find every request served by Cloudflare.`), mdx(\"h3\", {\n    \"id\": \"highlighting-initiators\"\n  }, `Highlighting initiators`), mdx(\"p\", null, `When you hover over an initiator, the panel now highlights the request that initiated it. This makes it much easier to see which request caused a specific request to be made, and lets you very quickly drill down your request tree.`), mdx(ThanksCallout, {\n    name: \"Matija\",\n    mdxType: \"ThanksCallout\"\n  }, \" for asking about this feature!\"), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: initiator,\n    alt: \"The initiator of a request is highlighted when hovering over it\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `The initiator in each request line has a tooltip that also shows which file or function initiated this request. Now you no longer have to find the request that initiated it in the list, as it's highlighted for you.`), mdx(\"h2\", {\n    \"id\": \"video-recording-improvements\"\n  }, `Video recording improvements`), mdx(\"p\", null, `The previous video recording implementation had a couple of things I wasn't happy with. Recording a video took a lot of memory (so you couldn't make long videos), processing the video after creation was slow and it didn't support sound.`), mdx(\"p\", null, `Polypane 30 has a fully rewritten video recording implementation that processes videos essentially instantly and because of that has a much lower memory footprint. Videos are created as `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `webm`), ` and include any sound that was playing in the pane.`), mdx(\"video\", {\n    src: video1,\n    muted: true,\n    controls: true,\n    preload: \"auto\",\n    loading: \"lazy\",\n    playsInline: true,\n    className: \"imgshadow\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `Everything else remains the same: you record a video, Polypane highlights clicks and you can trim and annotate the video with our built-in video editor (made with the amazing `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://pqina.nl/pintura?atp=lsxmJ1\"\n  }), `Pintura`), `).`), mdx(\"h2\", {\n    \"id\": \"extension-side-panel-api\"\n  }, `Extension side panel API`), mdx(\"p\", null, `Polypane's extension API support has been extended with the Side Panel API. Extensions like `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://chromewebstore.google.com/detail/look-up-wcag-scs-wcag-suc/koppadkncigccambhpcmgilnphmaahad\"\n  }), `Look up WCAG SCs`), ` by Ian Lloyd (or those AI sidebar tools) can now add a sidebar to Polypane.`), mdx(\"img\", {\n    src: sidepanel,\n    alt: \"Side panel API\",\n    style: {\n      \"margin\": \"2rem auto\",\n      \"maxWidth\": \"100%\",\n      \"display\": \"block\"\n    }\n  }), mdx(\"p\", null, `The sidebar lives in the Panel, and will automatically be added or removed depending on the extension state.`), mdx(\"h2\", {\n    \"id\": \"extension-tabcapture-apis\"\n  }, `Extension tabCapture APIs`), mdx(\"p\", null, `Extensions using the various tabCapture APIs to create screenshots or videos are now also fully supported.`), mdx(ThanksCallout, {\n    name: \"Kathryn\",\n    mdxType: \"ThanksCallout\"\n  }, \"for reporting the issue\"), mdx(\"h3\", {\n    \"id\": \"other-extension-improvements\"\n  }, `Other extension improvements`), mdx(\"p\", null, `As users report issues with specific extensions, I have been working to make sure Polypane supports those extensions better by fixing gaps in our APIs or adding support for more APIs.`), mdx(\"p\", null, `For this release, I made sure that the APIs used by the `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://keepassxc.org/\"\n  }), `KeePassXC`), ` extension work correctly in Polypane.`), mdx(ThanksCallout, {\n    name: \"Mateus\",\n    mdxType: \"ThanksCallout\"\n  }, \"for reporting the issue\"), mdx(\"p\", null, `Extensions using the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `browser`), ` namespace instead of `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `chrome`), ` now have better support, string replacement has broader support, and managing popups and extension permissions now cover more cases.`), mdx(\"p\", null, `Polypane now automatically opens `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `chrome-extension://`), ` links in full layout, so you can use the extension's UI as intended.`), mdx(\"h2\", {\n    \"id\": \"elements-panel-improvements\"\n  }, `Elements panel improvements`), mdx(\"p\", null, `The elements panel got a few upgrades in Polypane 30.`), mdx(\"h3\", {\n    \"id\": \"quirks-mode-badge\"\n  }, `Quirks mode badge`), mdx(\"p\", null, `When a page is running in quirks mode (when you don't have a doctype) the Elements panel now shows a warning badge where normally the doctype is.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: quirksmode,\n    alt: \"The quirks mode badge in the elements panel\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `Quirks mode has a lot of weird implications for how a page is rendered, but the absence of a doctype isn't the clearest indicator of that. The badge now makes it clear that the page is running in quirks mode.`), mdx(ThanksCallout, {\n    name: \"Roma\",\n    mdxType: \"ThanksCallout\"\n  }, \"for suggesting this\"), mdx(\"p\", null, mdx(\"em\", {\n    parentName: \"p\"\n  }, `This suggestion happened in a Mastodon conversation between Nicolas of the Firefox Devtools team, Roma and me, and it's also coming to Firefox: `, mdx(\"a\", _extends({\n    parentName: \"em\"\n  }, {\n    \"href\": \"https://bugzilla.mozilla.org/show_bug.cgi?id=2040627\"\n  }), ` Bug 2040627 `))), mdx(\"h3\", {\n    \"id\": \"support-for-commandforelement-in-the-dom-tree\"\n  }, `Support for `, mdx(\"code\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"className\": \"language-text\"\n  }), `commandForElement`), ` in the DOM tree`), mdx(\"p\", null, `The `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `command`), ` and `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `commandfor`), ` attributes of the invoker API make it easy to create custom interactions without needing JavaScript. But `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `commandfor`), ` needs to reference another element by ID, and adding IDs all over the place (that need to be unique) can be bothersome.`), mdx(\"p\", null, `The `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Web/API/HTMLButtonElement/commandForElement\"\n  }), mdx(\"code\", _extends({\n    parentName: \"a\"\n  }, {\n    \"className\": \"language-text\"\n  }), `commandForElement`), ` API`), ` lets you reference any element directly with JavaScript, so no ID is needed. That's really useful, but it creates a challenge for the DOM tree, because the value of `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `commandForElement`), ` isn't a string but a direct reference.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: commandforelement,\n    alt: \"The commandForElement badge in the elements panel\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `The Elements panel now supports this by showing the referenced element as a badge in the DOM tree that you can click to jump to the referenced element.`), mdx(ThanksCallout, {\n    name: \"Rik\",\n    mdxType: \"ThanksCallout\"\n  }, \"(of \", mdx(\"a\", {\n    href: \"/pintura?atp=lsxmJ1\"\n  }, \"Pintura\"), \" fame!) for reporting on this\"), mdx(\"h3\", {\n    \"id\": \"support-for-if-in-css-properties-with-proper-indentation\"\n  }, `Support for `, mdx(\"code\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"className\": \"language-text\"\n  }), `if()`), ` in CSS properties with proper indentation`), mdx(\"p\", null, `The new `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `if()`), ` CSS function broke our CSS parsing logic, causing the elements panel to look broken. We now support `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `if()`), ` in CSS properties and even preserve the indentation you're using in your CSS, so things stay readable in the way you prefer.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: ifsupport,\n    alt: \"A style using if() in the elements panel\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"h3\", {\n    \"id\": \"selectable-pseudos-in-the-dom-tree\"\n  }, `Selectable pseudos in the DOM tree`), mdx(\"p\", null, `Pseudo elements like `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `::before`), ` and `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `::after`), ` are not part of the DOM so in the Polypane elements panel, they were not individually selectable. Editing their styles happens through their parent element.`), mdx(\"p\", null, `People expect to be able to click on these pseudo elements though, so in Polypane 30 you can click them and it automatically opens the styles for that pseudo element in the Styles overview.`), mdx(\"h3\", {\n    \"id\": \"expanding-text-editor\"\n  }, `Expanding text editor`), mdx(\"p\", null, `The text and HTML editors in the navigator are one of our favorite features, because they make editing the text or HTML of an element really easy without any of the focus or modal requirements and, in the case of the text editor, live feedback.`), mdx(\"p\", null, `At our CSS Day booth, Bernd asked if we could make the text editor resizable so that it's easier to work with larger amounts of text, and we thought that was a great idea. The text editor now automatically scales to the content.`), mdx(ThanksCallout, {\n    name: \"Bernd\",\n    mdxType: \"ThanksCallout\"\n  }, \"for requesting this feature at CSS Day\"), mdx(\"h3\", {\n    \"id\": \"accessibility-property-tooltips\"\n  }, `Accessibility property tooltips`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: a11ytooltip,\n    alt: \"A tooltip showing for the 'controls' property explaining that it's a list of IDs controlled by this element\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `If you look at the accessibility overview and are unsure what a specific property means, you can hover over it to see a description of what it is and when it is relevant.`), mdx(\"h2\", {\n    \"id\": \"default-inspection-tools\"\n  }, `Default inspection tools`), mdx(\"p\", null, `The devtools icons, inspect buttons, shortcuts, and context menus now always open the same devtools: Polypane's Elements panel or Chromium DevTools. This lowers the mental load of remembering which devtools you opened last, and makes it easier to use devtools in Polypane.`), mdx(\"img\", {\n    src: pickdevtools,\n    className: \"imgshadow\",\n    alt: \"Pick default devtools\",\n    style: {\n      maxWidth: '300px'\n    }\n  }), mdx(\"p\", null, `Right-click the devtools button in the header to set a default devtools, and all devtools buttons and shortcuts will open that devtools.`), mdx(\"p\", null, `Both devtools are still available in the panel, so you can default to Polypane DevTools and open Chromium DevTools when you need, for example, React DevTools.`), mdx(\"p\", null, `To learn more about the differences between the Polypane and Chromium devtools, check out docs on `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/docs/developer-tools/\"\n  }), `Chromium `, `&`, ` Polypane devtools`)), mdx(\"h2\", {\n    \"id\": \"peek-improvements\"\n  }, `Peek improvements`), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/docs/polypane-peek/\"\n  }), `Polypane peek`), ` lets you hold `, mdx(ShortCutDisplay, {\n    altKey: true,\n    mdxType: \"ShortCutDisplay\"\n  }), ` to inspect elements. It's really, `, mdx(\"em\", {\n    parentName: \"p\"\n  }, `really`), ` nice.`), mdx(\"img\", {\n    src: \"/doc-img/elementspanel/inspect.png\",\n    className: \"imgshadow\",\n    alt: \"Inspect overlay and tooltip.\"\n  }), mdx(\"p\", null, `This release has a few changes to make it better:`), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Touch emulation is disabled when using peek so hovering works (Thanks Marc!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Scroll syncing is disabled when using Peek, so pages no longer jump when the tooltip causes a scroll event to be sent to the other panes`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Our color preview now supports the `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `color-mix()`), ` function to the previews display those correctly (Thanks Marc!). We'll be updating color support throughout the app in upcoming releases.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `If an element has specific aria attributes, Peek now shows those in the tooltip as well (Thanks Eric!)`)), mdx(\"h2\", {\n    \"id\": \"emulation-improvements\"\n  }, `Emulation improvements`), mdx(\"p\", null, `There are new emulation features in Polypane 30, and some existing ones have been improved.`), mdx(\"h3\", {\n    \"id\": \"text-scale-emulation\"\n  }, mdx(\"code\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"className\": \"language-text\"\n  }), `text-scale`), ` emulation`), mdx(\"p\", null, `Browsers, by default, ignore OS-level text scaling, as many sites are not built to handle a default font size other than `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `16px`), `.`), mdx(\"p\", null, `There is a new `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `text-scale`), ` meta tag that will let you tell the browser how to respond to the OS-level text scaling. It looks like this:`), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"html\"\n  }, mdx(\"pre\", _extends({\n    parentName: \"div\"\n  }, {\n    \"className\": \"language-html\"\n  }), mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-html\"\n  }), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token comment\"\n  }), `<!-- The default, old behavior -->`), `\n`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `<`), `meta`), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-name\"\n  }), `name`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-value\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation attr-equals\"\n  }), `=`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`), `text-scale`, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`)), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-name\"\n  }), `content`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-value\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation attr-equals\"\n  }), `=`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`), `legacy`, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`)), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `/>`)), `\n\n`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token comment\"\n  }), `<!-- Opting in to the new behavior -->`), `\n`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `<`), `meta`), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-name\"\n  }), `name`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-value\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation attr-equals\"\n  }), `=`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`), `text-scale`, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`)), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-name\"\n  }), `content`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-value\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation attr-equals\"\n  }), `=`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`), `scale`, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`)), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `/>`))))), mdx(\"p\", null, `By setting the text-scale meta tag to `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `scale`), `, you opt in to using the OS-level text scaling. So if a user has e.g. a 200% scale on their Android Phone, your site's default font size is now 32px instead of 16px. This is a great way to make your site more accessible to users that need larger text.`), mdx(\"p\", null, `In the emulations panel you can now easily test this by changing the OS text scale from the default of 100% to between 85 and 200%.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: textscale,\n    alt: \"The text-scale emulation in the emulations panel\",\n    style: {\n      maxWidth: '50%'\n    }\n  }), mdx(\"p\", null, `With text-scale set to legacy, this will have no effect, but with text-scale set to scale, you can see how your site responds to the OS-level text scaling.`), mdx(\"h3\", {\n    \"id\": \"svh-difference-overlay\"\n  }, mdx(\"code\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"className\": \"language-text\"\n  }), `svh`), ` difference overlay`), mdx(\"p\", null, `The `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `svh`), ` difference was always applied, but the visual overlay was off by default. This led to confusion for people who didn't realize their sites or themes used `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `svh`), `, and instead reported \"blank areas\".`), mdx(\"p\", null, `To prevent this confusion, Polypane 30 splits out the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `safe-area-insets`), ` and `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `svh`), ` overlay displays and turns the svh overlay on for all devices that support it.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: svhoverlays,\n    alt: \"The svh difference overlay\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `The overlay now has a new style to make it clear that the overlay is showing the difference between `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `svh`), ` and `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `vh`), `, and has an info icon to explain it.`), mdx(\"p\", null, `You can toggle the overlay through the media and emulations popup for a pane.`), mdx(\"h3\", {\n    \"id\": \"new-devices\"\n  }, `New devices`), mdx(\"p\", null, `The new iPhone 17e and Pixel 10 devices are now available in Polypane. Both are fully emulated, `, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `including safe-area-insets and `, mdx(\"code\", _extends({\n    parentName: \"strong\"\n  }, {\n    \"className\": \"language-text\"\n  }), `svh`), ` emulation`), `, only available in Polypane.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: new30devices,\n    alt: \"The new iPhone 17e and Pixel 10 devices\",\n    style: {\n      maxWidth: '80%'\n    }\n  }), mdx(\"h2\", {\n    \"id\": \"meta-panel-improvements\"\n  }, `Meta panel improvements`), mdx(\"p\", null, `With support for emulating the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `text-scale`), ` meta tag, we also added support for it in the Meta panel. The Meta panel now shows the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `text-scale`), ` meta tag and its value, and will show a warning if the value is invalid.`), mdx(\"p\", null, `We took this opportunity to refresh the layout of the meta panel. We removed the \"mobile friendly\" check (Thanks Robbert!) as it's no longer something used by Google, reordered and grouped the different lists of meta tags and added support for standard-site validation.`), mdx(\"h3\", {\n    \"id\": \"standard-site-validation\"\n  }, `Standard site validation`), mdx(\"p\", null, `Standard.site is a new standard for sharing publications on the at-proto protocol that's used by Bluesky. When you have it set up properly, your Bluesky sharing links will include the name and icon of your site and a button to visit it, in a color that matches your site.`), mdx(\"img\", {\n    src: standardsite,\n    className: \"imgshadow\",\n    alt: \"Standard.site validation panel.\"\n  }), mdx(\"p\", null, `Polypane fetches your Standard Site configurations for documents and publications, validates them against the standard.site lexicon, and shows you if there are any issues.`), mdx(\"p\", null, `The Bluesky preview then takes that data and makes it easy to see what your standard site configuration will look like when shared on Bluesky.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: standardsitepreview,\n    alt: \"The standard site preview in the meta panel\",\n    style: {\n      maxWidth: '80%'\n    }\n  }), mdx(\"p\", null, `It also supports Leaflet publications.`), mdx(\"h3\", {\n    \"id\": \"mastodon-domain-validation\"\n  }, `Mastodon domain validation`), mdx(\"p\", null, `Since our initial implementation of the Mastodon preview, the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `fediverse:creator`), ` requirements changed. You now also need a verified domain before the preview sghows your user byline.`), mdx(\"p\", null, `Polypane now checks if the domain is verified and shows a warning explaining how to get it verified when that's missing.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: mastodonpreview,\n    alt: \"The Mastodon preview in the meta panel\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(ThanksCallout, {\n    name: \"Manuel\",\n    mdxType: \"ThanksCallout\"\n  }, \"for pointing this out to me at CSS Day\"), mdx(\"h3\", {\n    \"id\": \"og-image-size-warnings\"\n  }, `OG image size warnings`), mdx(\"p\", null, `Different social media sites have different minimum and maximum dimensions and file sizes for OG images. Polypane now shows the dimensions and file size of the OG and Twitter images in the meta panel, and shows a warning if the image is larger or smaller than preferred, or when it's too small or too large to be displayed.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: largeogpreview,\n    alt: \"The OG image size warning in the meta panel\",\n    style: {\n      maxWidth: '80%'\n    }\n  }), mdx(ThanksCallout, {\n    name: \"Ky\",\n    mdxType: \"ThanksCallout\"\n  }, \"for finding this issue\"), mdx(\"h3\", {\n    \"id\": \"robotstxt-contents\"\n  }, `Robots.txt contents`), mdx(\"p\", null, `Along with a parsed robots.txt that shows you the rules along with validating the current page against them, the panel now also shows the full robots.txt content.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: robotsplaintext,\n    alt: \"The robots.txt contents in the meta panel\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `Now you can also see anything that's commented out and any other information that might be in the robots.txt file.`), mdx(\"h2\", {\n    \"id\": \"console-panel-improvements\"\n  }, `Console panel improvements`), mdx(\"p\", null, `The Console panel has received a few nice upgrades that make it much easier to use. As a result, evaluation is now faster too.`), mdx(\"h3\", {\n    \"id\": \"better-object-displays\"\n  }, `Better object displays`), mdx(\"p\", null, `We now support HTML references in arrays and object previews, so you can see the actual element in the preview, hoverable and clickable to open in the Elements panel.`), mdx(\"img\", {\n    src: arrayelems,\n    className: \"imgshadow\",\n    alt: \"HTML references in the console panel\",\n    style: {\n      maxWidth: '400px'\n    }\n  }), mdx(\"p\", null, `This makes it much easier to see what you're working with. Object nesting support has also been improved, so you can now expand and collapse more deeply nested objects in the console panel, as well as objects inside of arrays and the other way around.`), mdx(\"h3\", {\n    \"id\": \"same-world-evaluation\"\n  }, `Same-world evaluation`), mdx(\"p\", null, `Polypane's console commands used to be evaluated in an 'isolated world', which meant that you couldn't access global variables and functions defined by you in the page's main world.`), mdx(\"p\", null, `Console commands are now evaluated in the main world, so you can access your own variables and functions.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: sameworld,\n    alt: \"The console panel in Polypane\",\n    style: {\n      maxWidth: '400px'\n    }\n  }), mdx(\"p\", null, `This also means we keep assignments around, so if you specify a `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `const foo = \"bar\"`), ` in one command, you can reference it in the next command. This makes it much easier to work with the console panel.`), mdx(\"h2\", {\n    \"id\": \"accessibility-display-improvements\"\n  }, `Accessibility display improvements`), mdx(\"p\", null, `Did you know a button can have an invalid user entry? or that `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `hr`), ` can set values? That's (almost) never relevant, but it's an artifact of the accessibility model.`), mdx(\"p\", null, `We consulted a number of accessibility experts to go over some of the accessibility information we show to decide if and when we should show certain properties.`), mdx(\"p\", null, `We now hide values that are irrelevant for the element's role in both the Elements and Outline panels, so that the information that is there is more clearly actionable and relevant.`), mdx(ThanksCallout, {\n    name: \"Christian, Eric, Manuel, Sara, Jules and Ronny\",\n    mdxType: \"ThanksCallout\"\n  }), mdx(\"p\", null, mdx(\"em\", {\n    parentName: \"p\"\n  }, `I'm incredibly lucky to have such a group of caring, knowledgeable, and passionate accessibility experts to consult with. Thank you all for lending your expertise and time to make Polypane better.`)), mdx(\"h2\", {\n    \"id\": \"outline-panel-improvements\"\n  }, `Outline panel improvements`), mdx(\"p\", null, `The outline panel gathers the accessibility info more efficiently on load, making it slightly more responsive.`), mdx(\"h3\", {\n    \"id\": \"updated-focus-order-overlay\"\n  }, `Updated focus order overlay`), mdx(\"p\", null, `The focus order overlay and the way it calculates the tab order got some performance and correctness improvements.`), mdx(\"p\", null, `The result is a more complete and accurate focus order that is also much faster to update as your page changes and the focusable elements get reindexed (for example, when resizing the pane or scrolling).`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: focusorder,\n    alt: \"The focus order overlay in the outline panel\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `I have yet to find a tool that is as complete and accurate as Polypane's focus order overlay. For example, in the screenshot above you can see that it correctly matches the reading order, even though the DOM order is different.`), mdx(\"p\", null, `It means that you can trust the focus order overlay when auditing, rather than you having to tab through all the (sometimes hundreds of) focusable elements to see if the tab order makes sense. You can just look at the overlay and see if the tab order is correct.`), mdx(\"h4\", {\n    \"id\": \"small-bugfix\"\n  }, `Small bugfix`), mdx(\"p\", null, `Lastly, we also fixed a bug where the focus overlay would sometimes mark elements as going against the reading order when they were clearly not. This was caused by our reading order logic using the wrong set of focusable elements (including programatically focusable ones) when calculating the reading order. The focus order overlay now only uses keyboard focusable elements in its calculations.`), mdx(ThanksCallout, {\n    name: \"Eric\",\n    mdxType: \"ThanksCallout\"\n  }, \"for mentioning this bug\"), mdx(\"h2\", {\n    \"id\": \"panes\"\n  }, `Panes`), mdx(\"p\", null, `Our goal for this year is to sand away some of the edges in Polypane, the things that require Polypane-specific knowledge to understand.`), mdx(\"h3\", {\n    \"id\": \"updated-pane-header-design\"\n  }, `Updated pane header design`), mdx(\"p\", null, `We've updated the design of the pane header to make the icons more clearly distinguishable and to keep things more consistent as you interact with the pane.`), mdx(\"img\", {\n    src: paneheader,\n    alt: \"The updated pane header design\",\n    className: \"imgshadow\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `Icons not currently active appear dimmed, and we're distinguishing the devtools-opening icon from the others.`), mdx(\"p\", null, `When hovering a pane header, the sizes stay where they are and the scale settings and rotate button appear to the left of them, so things no longer move around.`), mdx(\"img\", {\n    src: paneheaderhovered,\n    alt: \"The pane header when hovered\",\n    className: \"imgshadow\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"h3\", {\n    \"id\": \"panes-now-zoom-to-fit-vertically\"\n  }, `Panes now zoom to fit vertically`), mdx(\"p\", null, `In previous versions in the horizontal and focus layouts, panes that were too tall to fit the window were clipped. This was a conscious design decision because it always kept scrolling locked in one dimension, but it was confusing when your pane wasn't the size you expected.`), mdx(\"video\", {\n    src: panescales,\n    controls: true,\n    style: {\n      \"margin\": \"2rem auto\",\n      \"maxWidth\": \"100%\",\n      \"display\": \"block\"\n    }\n  }), mdx(\"p\", null, `Starting in Polypane 30, all panes are automatically scaled down to fit the window vertically in the horizontal and focus layouts, just like they were already scaled down to fit horizontally in the vertical layout.`), mdx(\"p\", null, `Now you always see the pane at its intended dimensions.`), mdx(\"h3\", {\n    \"id\": \"manual-scaling-with-shortcutdisplay-cmdkey-\"\n  }, `Manual scaling with `, mdx(ShortCutDisplay, {\n    cmdKey: true,\n    mdxType: \"ShortCutDisplay\"\n  })), mdx(\"p\", null, `By holding `, mdx(ShortCutDisplay, {\n    cmdKey: true,\n    mdxType: \"ShortCutDisplay\"\n  }), ` while dragging a pane's resize handle, you scale the pane instead of resizing it. This keeps the internal dimensions the same but displays the pane at a different scale.`), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Did you know:`), ` holding `, mdx(ShortCutDisplay, {\n    shiftKey: true,\n    mdxType: \"ShortCutDisplay\"\n  }), ` while resizing a pane will keep the aspect ratio!`)), mdx(\"h2\", {\n    \"id\": \"project-improvements\"\n  }, `Project improvements`), mdx(\"p\", null, `Projects can now have a custom default tab, and adding bookmarks and environments to a project now automatically scrolls the newly added item into view.`), mdx(\"h3\", {\n    \"id\": \"project-specific-default-tabs\"\n  }, `Project specific default tabs`), mdx(\"p\", null, `The Default tab, or `, mdx(\"em\", {\n    parentName: \"p\"\n  }, `homepage`), `, can now be set up per project. Configure the current tab as you like (which layout, URL, set of panes, location of the panel etc), open the project settings and click \"Set current tab as new tab\" to set it as the default tab for that project.`), mdx(\"img\", {\n    className: \"imgshadow\",\n    src: defaultnewprojecttab,\n    alt: \"Setting the default tab for a project\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(ThanksCallout, {\n    name: \"Silas\",\n    mdxType: \"ThanksCallout\"\n  }, \"for requesting this\"), mdx(\"p\", null, `The project homepage is optional and will fall back to the globally set default new tab.`), mdx(\"h3\", {\n    \"id\": \"automatically-scroll-newly-added-bookmarks-and-environments-into-view\"\n  }, `Automatically scroll newly added bookmarks and environments into view`), mdx(\"p\", null, `When you add a new bookmark or environment to a project, the project editor now automatically scrolls the newly added item into view. This makes it much easier to see what you just added, especially when you have a long list of bookmarks or environments.`), mdx(ThanksCallout, {\n    name: \"Eric\",\n    mdxType: \"ThanksCallout\"\n  }, \"for requesting this\"), mdx(\"h2\", {\n    \"id\": \"syncing-improvements\"\n  }, `Syncing improvements`), mdx(\"p\", null, `Polypane's syncing engine is the most robust and complete one out there, syncing everything from scroll position to hover and focus states. But there's always room for improvement.`), mdx(\"p\", null, `In Polypane 30 we added syncing for text selection and reset buttons.`), mdx(\"h3\", {\n    \"id\": \"text-selection-syncing\"\n  }, `Text selection syncing`), mdx(\"p\", null, `Your text selection is now synced across panes and portal-connected browsers.`), mdx(\"video\", {\n    src: textselection,\n    controls: true,\n    style: {\n      \"margin\": \"2rem auto\",\n      \"maxWidth\": \"100%\",\n      \"display\": \"block\"\n    }\n  }), mdx(\"p\", null, `So if you select text, that text is now selected everywhere. Neat!`), mdx(\"h3\", {\n    \"id\": \"reset-button-syncing\"\n  }, `Reset button syncing`), mdx(\"p\", null, `We prevented button clicks from syncing if they were inside forms to prevent duplicate form submissions, but the way we set it up also prevented reset buttons from syncing. If you were working on a form and were counting on resetting the form in one go, that wouldn't work.`), mdx(\"p\", null, `You probably shouldn't be using reset buttons as they're not great for UX, but if you do, they now sync across panes and portal-connected browsers. The benefit is that your form state resets everywhere.`), mdx(\"h2\", {\n    \"id\": \"area-screenshot-improvements\"\n  }, `Area screenshot improvements`), mdx(\"p\", null, `Creating area screenshots is now much easier. Every measurement area you draw has its own camera icon that lets you capture that area.`), mdx(\"video\", {\n    src: areascreenshots,\n    controls: true,\n    style: {\n      \"margin\": \"2rem auto\",\n      \"maxWidth\": \"100%\",\n      \"display\": \"block\"\n    }\n  }), mdx(\"p\", null, `Previously you had to draw a measurement area and then go to the camera menu to screenshot it. Now you can just click the camera icon to take a screenshot of that area.`), mdx(\"h2\", {\n    \"id\": \"smaller-improvements\"\n  }, `Smaller improvements`), mdx(\"p\", null, `For the full list there's the changelog below, but we wanted to call out a few smaller improvements that we think are worth mentioning.`), mdx(\"h3\", {\n    \"id\": \"toggle-between-last-two-panel-positions\"\n  }, `Toggle between last two panel positions`), mdx(\"p\", null, `You can now toggle between the last two panel positions with a new shortcut `, mdx(ShortCutDisplay, {\n    cmdKey: true,\n    altKey: true,\n    letter: \"p\",\n    mdxType: \"ShortCutDisplay\"\n  }), `. For example, you can toggle between the right-aligned and bottom-aligned panel with a single shortcut, or detach and reattach the panel.`), mdx(ThanksCallout, {\n    name: \"Bas\",\n    mdxType: \"ThanksCallout\"\n  }, \"for requesting this\"), mdx(\"h3\", {\n    \"id\": \"address-bar-interactions\"\n  }, `Address bar interactions`), mdx(\"p\", null, `The address bar, I keep learning, is surprisingly complex. Its text selection logic now follows other browsers:`), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Click + drag selects text instead of focusing the entire content`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Click once selects the entire content`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Click again to place the cursor at the clicked position`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Double-click selects the word, and triple-click selects the entire content again`)), mdx(ThanksCallout, {\n    name: \"Rick\",\n    mdxType: \"ThanksCallout\"\n  }, \"for requesting this\"), mdx(\"p\", null, `We've also updated the logic on when to start showing suggestions to align with other browsers, only starting to show suggestions after the user has started typing.`), mdx(\"h3\", {\n    \"id\": \"automatic-layout-choice-for-json-files\"\n  }, `Automatic layout choice for JSON files`), mdx(\"p\", null, `When you drag a JSON file to the tab bar and open it in a new tab, Polypane now automatically opens it in the full layout instead of your default layout.`), mdx(\"h3\", {\n    \"id\": \"emoji-picker-update\"\n  }, `Emoji picker update`), mdx(\"p\", null, `The emoji picker we use in the screenshot editor and project selector now uses Emoji 17.0, so you can use the latest emojis in your screenshots and projects.`), mdx(\"h3\", {\n    \"id\": \"context-menu-features\"\n  }, `Context menu features`), mdx(\"p\", null, `The context menus now let you copy email addresses without the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `mailto:`), ` part, telephone numbers without the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `tel:`), ` part, and you can now copy or save a video frame from any video.`), mdx(\"h2\", {\n    \"id\": \"chromium-152\"\n  }, `Chromium 152`), mdx(\"p\", null, `Polypane 30 is built on Chromium 152. For all the experimental features enabled in this release, check out the `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/experimental-web-platform-features/\"\n  }), `experimental web platform features overview`), `.`), mdx(\"h2\", {\n    \"id\": \"get-polypane-30\"\n  }, `Get Polypane 30`), mdx(\"p\", null, `Polypane is available for Windows, Mac, and Linux in 64-bit and ARM versions. Polypane automatically updates, but you can also go to `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/download/\"\n  }), `the download page`), ` to download the latest version!`), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Don't have Polypane yet? There is a 14-day trial available. `, mdx(\"br\", null), ` `, mdx(\"a\", _extends({\n    parentName: \"strong\"\n  }, {\n    \"href\": \"https://dashboard.polypane.app/register\"\n  }), `Try it for free`), `.`), ` No credit card needed.`)), mdx(\"h2\", {\n    \"id\": \"polypane-30-changelog\"\n  }, `Polypane 30 Changelog`), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `New`)), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Polypane Playgrounds`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Video recording supports sound and improved performance`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Extensions: Side Panel extension support`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Network panel: filter requests`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Network panel: sort by all requests or per origin`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Emulation: `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `svh`), ` difference overlay is now on by default`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Emulation: `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `text-scale`), ` emulation support`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Emulation: Pixel and iPhone device previews`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Elements panel: Support `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `commandForElement`), ` display in DOM tree (Thanks Rik!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Projects can now have project-specific default tabs (Thanks Silas!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Syncing engine: Synced text selection`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Meta panel: Standard Site validation and previews`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Chromium 152`)), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Improvements`)), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Faster startup-time due to Electron improvements`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` A roughly 20% performance improvement due to Electron improvements`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Network panel: hover initiator to highlight the request that initiated it (Thanks Matija!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Head order overview now recognises viewport-fit as valid value`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Redesign layout and add `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `text-scale`)), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Show warnings for incorrectly sized OG images (Thanks Ky!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Improved fallback suggestions in OG tag lists`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Improve Google SERP preview`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Show plaintext robots.txt content (to help with comments)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Mastodon preview now checks for verified domain value (Thanks Manuel!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Update Mastodon preview colors`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Outline panel: Faster updating of focus overlay when scrolling and resizing`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Outline panel: Faster accessibility tree parsing`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: Show a warning badge for quirks mode (Thanks Roma!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: The text editor is now resizable (Thanks Bernd!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: Support `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `if()`), ` in CSS properties with proper indentation`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: consistent opening of Elements panel or chromium devtools under one shortcut/menu item`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: You can now click on pseudo elements in the DOM tree`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: Newly supported CSS Properties and values`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: Add support for focusgroup attribute autocomplete`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Console panel: Improved performance, better previews and evaluation in main world and portals`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Console panel: Element references like `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `$0`), ` now work across shadow boundaries`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Console panel: Assignments are now kept in scope`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Accessibility overviews now provide additional information for properties on hover`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Accessibility overviews now hide irrelevant properties depending on the element role (Thanks Christian, Eric, Manuel, Sara, Jules and Ronny!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Peek: Turn touch emulation off when inspecting with Peek (Thanks Marc!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Peek: Show values of aria-current, aria-pressed and aria-expanded if defined (Thanks Eric!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` New tab: now open with the last used layout`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Rendering: the 'in-polypane' class is now off by default`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Extensions: automatically open chrome-extension links in full layout`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Extensions: Support extension id substitute strings in CSS`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Extensions: Correctly support `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `browser`), ` namespace in extensions`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Extensions: support for tabCapture APIs (Thanks Kathryn!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Extensions: Support for KeePassXC extension (Thanks Mateus!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Extensions: Decrease logging in the terminal`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Panes: now zoom out to fit in horizontal and focus layouts instead of clipping (Thanks Brady!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Panes: Cmd/Ctrl + dragging now scales panes`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Panes: Shift + scale now follows the larger side when resizing`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Image overlay: renamed from reference image`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Debug overlays: Renamed from Debug tools`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Debug overlays: Improved performance for contrast checker, text spacing, z-index and disable `, `*`, ` debug tools`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Shortcuts: toggle Panel between last two positions (Thanks Bas!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Shortcuts: Esc no longer removed focus from pane (Thanks Eric!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` All file size notations across the app now use the same SI 1000-base units`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Context menus: Now detect email address and phone numbers for easy copying`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Context menus: Copy and save video frame options`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Panel: Automatically update tab widths for larger text sizes (Thanks Ashlee!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Syncing engine: Reset buttons are now synced across panes`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Project editor: Automatically scroll newly added bookmarks and environments into view (Thanks Eric!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Screenshots: Improve performance of full-page screenshots for very long pages (Thanks Brad!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Rulers: Measure areas now have a camera icon to create screenshots of the measured area`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Address bar: You can now click + drag to select text, instead of it focusing the entire content (Thanks Rick!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Emoji picker: Now supports Emoji 17.0`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Polypane Peek: disables scroll syncing on inspect`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Dragged-in JSON files automatically open in full layouts`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` JSON and XML viewers: improve dark mode styling`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Passkey support should now work with more authentication methods`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Updated list of Google Fonts`)), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Removed`)), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Removed`), ` Meta panel: The \"mobile friendly\" check is removed as it's no longer used by search engines (Thanks Robbert!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Removed`), ` A11y.css is now available as a snippet and no longer part of the Debug overlays`)), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Fixes`)), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Meta panel: Whatsapp card was missing title`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Meta panel: Opening a new tab no longer resets preview order`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Network panel: Sort origins by first connection time, rather than last activity (Thanks Matija!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Network panel: Web Vitals data was cleared when switching tabs (Thanks Matija!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Network panel: Prevent resetting of size bars`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Elements panel: Fix missing computed styles for some websites (Thanks Matija!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Elements panel: Properly expand attribute value fields for long values`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Elements panel: Show nested declarations in @scope rules (Thanks Rick!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Peek: the color preview for `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `color-mix()`), ` was broken (Thanks Marc!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Pane URL bar: prevent selecting a preset on enter and applying URL on blur`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Polypane Message Bus: Message bus is now available again`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Console panel: Prevent console from getting its element references from different tab`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Reference image: Properly support non-ascii characters (Thanks Sigmundur!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Panes: Fix sizer position for zoomed out panes`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Debug overlays: Disable Images now correctly restores when turned off`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Debug overlays: Right-click no longer re-applies debug overlays twice`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Address bar: Pressing enter on an empty address bar no longer submits`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Address bar: Make sure the address bar doesn't overlap warning icons (Thanks Vadim!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Outline panel: Focus overlay correctly ignores tabindex=-1 elements for comparisons`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Outline panel: styling issue fixes for warnings and indicators`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Screenshots: Fix issue where images weren't saved to disk directly`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Screenshots: Prevent visual glitch when taking a full height screenshot`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Screenshots: Prevent silent error when trying to save to a non-existent folder`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `svh`), ` and safe area insets now redraw faster during resize`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Google Fonts import didn't use variable fonts`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Extensions: Automatically support default permissions for all extensions`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Middle click ruler button on full layout now clears the rulers`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Portal only syncs events from the portalled tab`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Portal syncs non-tab originated navigation events again`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Focus overlay now only uses tabbable elements for tab order validation instead of all focusable elements (Thanks Eric!)`)));\n}\n;\nMDXContent.isMDXComponent = true;","timeToRead":19,"tableOfContents":{"items":[{"url":"#polypane-playgrounds","title":"Polypane Playgrounds","items":[{"url":"#live-reloading","title":"Live reloading"},{"url":"#spa-fallback","title":"SPA Fallback"},{"url":"#directory-listings","title":"Directory listings"},{"url":"#portal-enabled","title":"Portal-enabled"}]},{"url":"#network-panel-improvements","title":"Network panel improvements","items":[{"url":"#toggle-between-per-origin-and-all-requests","title":"Toggle between per origin and all requests"},{"url":"#filter-requests","title":"Filter requests"},{"url":"#highlighting-initiators","title":"Highlighting initiators"}]},{"url":"#video-recording-improvements","title":"Video recording improvements"},{"url":"#extension-side-panel-api","title":"Extension side panel API"},{"url":"#extension-tabcapture-apis","title":"Extension tabCapture APIs","items":[{"url":"#other-extension-improvements","title":"Other extension improvements"}]},{"url":"#elements-panel-improvements","title":"Elements panel improvements","items":[{"url":"#quirks-mode-badge","title":"Quirks mode badge"},{"url":"#support-for-commandforelement-in-the-dom-tree","title":"Support for commandForElement in the DOM tree"},{"url":"#support-for-if-in-css-properties-with-proper-indentation","title":"Support for if() in CSS properties with proper indentation"},{"url":"#selectable-pseudos-in-the-dom-tree","title":"Selectable pseudos in the DOM tree"},{"url":"#expanding-text-editor","title":"Expanding text editor"},{"url":"#accessibility-property-tooltips","title":"Accessibility property tooltips"}]},{"url":"#default-inspection-tools","title":"Default inspection tools"},{"url":"#peek-improvements","title":"Peek improvements"},{"url":"#emulation-improvements","title":"Emulation improvements","items":[{"url":"#text-scale-emulation","title":"text-scale emulation"},{"url":"#svh-difference-overlay","title":"svh difference overlay"},{"url":"#new-devices","title":"New devices"}]},{"url":"#meta-panel-improvements","title":"Meta panel improvements","items":[{"url":"#standard-site-validation","title":"Standard site validation"},{"url":"#mastodon-domain-validation","title":"Mastodon domain validation"},{"url":"#og-image-size-warnings","title":"OG image size warnings"},{"url":"#robotstxt-contents","title":"Robots.txt contents"}]},{"url":"#console-panel-improvements","title":"Console panel improvements","items":[{"url":"#better-object-displays","title":"Better object displays"},{"url":"#same-world-evaluation","title":"Same-world evaluation"}]},{"url":"#accessibility-display-improvements","title":"Accessibility display improvements"},{"url":"#outline-panel-improvements","title":"Outline panel improvements","items":[{"url":"#updated-focus-order-overlay","title":"Updated focus order overlay","items":[{"url":"#small-bugfix","title":"Small bugfix"}]}]},{"url":"#panes","title":"Panes","items":[{"url":"#updated-pane-header-design","title":"Updated pane header design"},{"url":"#panes-now-zoom-to-fit-vertically","title":"Panes now zoom to fit vertically"},{"url":"#manual-scaling-with-shortcutdisplay-cmdkey-","title":"Manual scaling with <ShortCutDisplay cmdKey />"}]},{"url":"#project-improvements","title":"Project improvements","items":[{"url":"#project-specific-default-tabs","title":"Project specific default tabs"},{"url":"#automatically-scroll-newly-added-bookmarks-and-environments-into-view","title":"Automatically scroll newly added bookmarks and environments into view"}]},{"url":"#syncing-improvements","title":"Syncing improvements","items":[{"url":"#text-selection-syncing","title":"Text selection syncing"},{"url":"#reset-button-syncing","title":"Reset button syncing"}]},{"url":"#area-screenshot-improvements","title":"Area screenshot improvements"},{"url":"#smaller-improvements","title":"Smaller improvements","items":[{"url":"#toggle-between-last-two-panel-positions","title":"Toggle between last two panel positions"},{"url":"#address-bar-interactions","title":"Address bar interactions"},{"url":"#automatic-layout-choice-for-json-files","title":"Automatic layout choice for JSON files"},{"url":"#emoji-picker-update","title":"Emoji picker update"},{"url":"#context-menu-features","title":"Context menu features"}]},{"url":"#chromium-152","title":"Chromium 152"},{"url":"#get-polypane-30","title":"Get Polypane 30"},{"url":"#polypane-30-changelog","title":"Polypane 30 Changelog"}]},"excerpt":"Polypane 30 introduces Playgrounds so you can open directories as real HTTPS URLs in seconds, adds support for the Side Panel extension API, brings major…","frontmatter":{"title":"Polypane 30: Playgrounds, Side Panel extension API, updated video recording and Chromium 152","cover":"/img/mail/icon.svg","date":"2026-08-19","updated":null},"fields":{"slug":"/blog/polypane-30-playgrounds-side-panel-extension-api-updated-video-recording-and-chromium-152/","date":"2026-08-18T22:00:00.000Z","ogFileName":"polypane-30-playgrounds-side-panel-extension-api-updated-video-recording-and-chromium-152"}}},"pageContext":{"slug":"/blog/polypane-30-playgrounds-side-panel-extension-api-updated-video-recording-and-chromium-152/"}},"staticQueryHashes":["4164364741","425175329"]}