website: bold keywords in every paragraph, saturated prism colors, font-weight 500 for code
- Add <strong> to every paragraph so each has at least one bold keyword - Increase light mode Prism saturation: brighter purple, amber, green, blue - Set font-weight 500 for code blocks and inline code - Add letter-spacing 0.02em to code blocks and inline code
This commit is contained in:
@@ -63,7 +63,7 @@ export default function LivelinePage() {
|
||||
<EditorialPage toc={tocItems} logo="playwriter">
|
||||
|
||||
<P>
|
||||
Playwriter lets you control your Chrome browser with the full
|
||||
Playwriter lets you <strong>control your Chrome browser</strong> with the full
|
||||
Playwright API. A Chrome extension, a local relay, and a CLI. No new
|
||||
browser windows, no Chrome flags, no context bloat.{" "}
|
||||
<A href="https://github.com/remorses/playwriter">Star on GitHub</A>.
|
||||
@@ -84,7 +84,7 @@ export default function LivelinePage() {
|
||||
Every browser automation MCP I tried either spawns a new Chrome
|
||||
instance or forces you into a limited set of predefined tools. Playwriter
|
||||
does neither. It connects to the browser you already have open,
|
||||
exposes the full Playwright API through a single{" "}
|
||||
exposes the <strong>full Playwright API</strong> through a single{" "}
|
||||
<Code>execute</Code> tool, and gets out of the way.
|
||||
One tool. Any Playwright code. No wrappers.
|
||||
</P>
|
||||
@@ -92,7 +92,7 @@ export default function LivelinePage() {
|
||||
<Section id="getting-started" title="Getting started">
|
||||
|
||||
<P>
|
||||
Three steps. Extension, icon click, then you're automating.
|
||||
<strong>Three steps.</strong> Extension, icon click, then you're automating.
|
||||
</P>
|
||||
|
||||
<OL>
|
||||
@@ -110,7 +110,7 @@ export default function LivelinePage() {
|
||||
`}</CodeBlock>
|
||||
|
||||
<P>
|
||||
The extension connects your browser to a local WebSocket relay on{" "}
|
||||
The extension connects your browser to a <strong>local WebSocket relay</strong> on{" "}
|
||||
<Code>localhost:19988</Code>. The CLI sends Playwright
|
||||
code through the relay. No remote servers, no accounts, nothing
|
||||
leaves your machine.
|
||||
@@ -135,8 +135,8 @@ export default function LivelinePage() {
|
||||
The extension uses <Code>chrome.debugger</Code> to
|
||||
attach to tabs where you clicked the icon. It opens a WebSocket
|
||||
connection to a local relay server. The CLI (or MCP, or your own
|
||||
Playwright script) connects to the same relay. CDP commands flow
|
||||
through; the extension forwards them to Chrome and sends responses
|
||||
Playwright script) connects to the same relay. <strong>CDP commands flow
|
||||
through</strong>; the extension forwards them to Chrome and sends responses
|
||||
back.
|
||||
</P>
|
||||
|
||||
@@ -158,9 +158,9 @@ export default function LivelinePage() {
|
||||
`}</CodeBlock>
|
||||
|
||||
<P>
|
||||
No Chrome restart required. No <Code>--remote-debugging-port</Code>{" "}
|
||||
<strong>No Chrome restart required.</strong> No <Code>--remote-debugging-port</Code>{" "}
|
||||
flags. The extension handles the CDP attachment transparently, and
|
||||
the relay multiplexes sessions so multiple agents or CLI instances
|
||||
the relay <strong>multiplexes sessions</strong> so multiple agents or CLI instances
|
||||
can work with the same browser simultaneously.
|
||||
</P>
|
||||
|
||||
@@ -187,9 +187,9 @@ export default function LivelinePage() {
|
||||
`}</CodeBlock>
|
||||
|
||||
<P>
|
||||
Each line ends with a locator you can pass directly to{" "}
|
||||
Each line ends with a <strong>locator</strong> you can pass directly to{" "}
|
||||
<Code>page.locator()</Code>. Subsequent calls return a
|
||||
diff, so you only see what changed. Use{" "}
|
||||
<strong> diff</strong>, so you only see what changed. Use{" "}
|
||||
<Code>search</Code> to filter large pages.
|
||||
</P>
|
||||
|
||||
@@ -202,8 +202,8 @@ export default function LivelinePage() {
|
||||
`}</CodeBlock>
|
||||
|
||||
<P>
|
||||
Snapshots are text. They cost a fraction of what screenshots cost in
|
||||
tokens. Use them as your primary debugging tool. Only reach for
|
||||
Snapshots are <strong>text</strong>. They cost a fraction of what screenshots cost in
|
||||
tokens. Use them as your <strong>primary debugging tool</strong>. Only reach for
|
||||
screenshots when spatial layout matters — grids, dashboards, maps.
|
||||
</P>
|
||||
|
||||
@@ -217,8 +217,8 @@ export default function LivelinePage() {
|
||||
|
||||
<P>
|
||||
For pages where spatial layout matters,{" "}
|
||||
<Code>screenshotWithAccessibilityLabels</Code> overlays
|
||||
Vimium-style labels on every interactive element. Take a screenshot,
|
||||
<Code>screenshotWithAccessibilityLabels</Code> overlays{" "}
|
||||
<strong>Vimium-style labels</strong> on every interactive element. Take a screenshot,
|
||||
read the labels, click by reference.
|
||||
</P>
|
||||
|
||||
@@ -230,7 +230,7 @@ export default function LivelinePage() {
|
||||
`}</CodeBlock>
|
||||
|
||||
<P>
|
||||
Labels are color-coded by element type: yellow for links, orange for
|
||||
Labels are <strong>color-coded by element type</strong>: yellow for links, orange for
|
||||
buttons, coral for inputs, pink for checkboxes, peach for sliders,
|
||||
salmon for menus, amber for tabs. The ref system is shared with{" "}
|
||||
<Code>snapshot()</Code>, so you can switch between text
|
||||
@@ -246,7 +246,7 @@ export default function LivelinePage() {
|
||||
<Section id="sessions" title="Sessions">
|
||||
|
||||
<P>
|
||||
Each session runs in an isolated sandbox with its own{" "}
|
||||
Each session runs in an <strong>isolated sandbox</strong> with its own{" "}
|
||||
<Code>state</Code> object. Variables, pages, listeners
|
||||
persist between calls within a session. Different sessions get
|
||||
different state. Browser tabs are shared.
|
||||
@@ -265,7 +265,7 @@ export default function LivelinePage() {
|
||||
`}</CodeBlock>
|
||||
|
||||
<P>
|
||||
Create your own page to avoid interference from other agents. Reuse
|
||||
Create your own page to <strong>avoid interference</strong> from other agents. Reuse
|
||||
an existing <Code>about:blank</Code> tab or create a
|
||||
fresh one, and store it in <Code>state</Code>.
|
||||
</P>
|
||||
@@ -282,7 +282,7 @@ export default function LivelinePage() {
|
||||
<Section id="debugger-and-editor" title="Debugger & editor">
|
||||
|
||||
<P>
|
||||
Full Chrome DevTools Protocol access. Set breakpoints, step through
|
||||
<strong>Full Chrome DevTools Protocol access.</strong> Set breakpoints, step through
|
||||
code, inspect variables at runtime. Live-edit page scripts and CSS
|
||||
without reloading.
|
||||
</P>
|
||||
@@ -299,7 +299,7 @@ export default function LivelinePage() {
|
||||
`}</CodeBlock>
|
||||
|
||||
<P>
|
||||
Edits are in-memory and persist until the page reloads. Useful for
|
||||
Edits are <strong>in-memory</strong> and persist until the page reloads. Useful for
|
||||
toggling debug flags, patching broken code, or testing quick fixes
|
||||
without touching source files. The editor also supports{" "}
|
||||
<Code>grep</Code> across all loaded scripts.
|
||||
@@ -314,7 +314,7 @@ export default function LivelinePage() {
|
||||
<Section id="network-interception" title="Network interception">
|
||||
|
||||
<P>
|
||||
Intercept requests and responses to reverse-engineer APIs, scrape
|
||||
<strong>Intercept requests and responses</strong> to reverse-engineer APIs, scrape
|
||||
data, or debug network issues. Store captured data in{" "}
|
||||
<Code>state</Code> and analyze across calls.
|
||||
</P>
|
||||
@@ -332,7 +332,7 @@ export default function LivelinePage() {
|
||||
`}</CodeBlock>
|
||||
|
||||
<P>
|
||||
This is faster than scrolling through DOM. Capture the real API
|
||||
This is <strong>faster than scrolling through DOM</strong>. Capture the real API
|
||||
calls, inspect their schemas, and replay them with different
|
||||
parameters. Works for pagination, authenticated endpoints, and
|
||||
anything behind JavaScript rendering.
|
||||
@@ -343,9 +343,9 @@ export default function LivelinePage() {
|
||||
<Section id="screen-recording" title="Screen recording">
|
||||
|
||||
<P>
|
||||
Record the active tab as video using{" "}
|
||||
<strong>Record the active tab as video</strong> using{" "}
|
||||
<Code>chrome.tabCapture</Code>. The recording runs in
|
||||
the extension context, so it survives page navigation. Video is saved
|
||||
the extension context, so it <strong>survives page navigation</strong>. Video is saved
|
||||
as MP4.
|
||||
</P>
|
||||
|
||||
@@ -363,7 +363,7 @@ export default function LivelinePage() {
|
||||
|
||||
<P>
|
||||
Unlike <Code>getDisplayMedia</Code>, this approach
|
||||
persists across navigations because the extension holds the{" "}
|
||||
<strong> persists across navigations</strong> because the extension holds the{" "}
|
||||
<Code>MediaRecorder</Code>, not the page. You can also
|
||||
check recording status with <Code>isRecording</Code> or
|
||||
cancel without saving with <Code>cancelRecording</Code>.
|
||||
@@ -424,11 +424,11 @@ export default function LivelinePage() {
|
||||
<Section id="remote-access" title="Remote access">
|
||||
|
||||
<P>
|
||||
Control Chrome on any machine from anywhere over the internet.
|
||||
Control Chrome on <strong>any machine from anywhere</strong> over the internet.
|
||||
The relay runs on the host alongside Chrome.
|
||||
A{" "}
|
||||
<A href="https://traforo.dev">traforo</A>{" "}
|
||||
tunnel exposes it through Cloudflare, giving you a secure public URL.
|
||||
tunnel exposes it through Cloudflare, giving you a <strong>secure public URL</strong>.
|
||||
No VPN, no firewall rules, no port forwarding.
|
||||
</P>
|
||||
|
||||
@@ -443,7 +443,7 @@ export default function LivelinePage() {
|
||||
`}</CodeBlock>
|
||||
|
||||
<P>
|
||||
Also works on a LAN without tunnels — just set{" "}
|
||||
Also works on a <strong>LAN without tunnels</strong> — just set{" "}
|
||||
<Code>PLAYWRITER_HOST=192.168.1.10</Code>. Works for MCP
|
||||
too — set <Code>PLAYWRITER_HOST</Code> and{" "}
|
||||
<Code>PLAYWRITER_TOKEN</Code> in your MCP client env config.
|
||||
@@ -456,7 +456,7 @@ export default function LivelinePage() {
|
||||
<Section id="security" title="Security">
|
||||
|
||||
<P>
|
||||
Playwriter is local by default. The relay runs on{" "}
|
||||
Playwriter is <strong>local by default</strong>. The relay runs on{" "}
|
||||
<Code>localhost:19988</Code> and only accepts connections
|
||||
from the extension. There's no remote server, no account, no
|
||||
telemetry.
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
/*
|
||||
* Prism.js light theme matching benji.org's GitHub-style syntax highlighting.
|
||||
* Prism.js light theme — more saturated, brighter variant of GitHub Light.
|
||||
*
|
||||
* Color palette extracted from the original:
|
||||
* - Keywords (import, function, return): #CF222E (red)
|
||||
* - Strings: #0A3069 (dark blue)
|
||||
* - Functions/components: #8250DF (purple)
|
||||
* - Parameters/properties: #953800 (orange-brown)
|
||||
* - HTML tags: #116329 (green)
|
||||
* - Attributes/numbers: #0550AE (blue)
|
||||
* - Punctuation/text: #1F2328 (near-black)
|
||||
* Color palette:
|
||||
* - Keywords (import, function, return): #d1242f (vivid red)
|
||||
* - Strings: #0550ae (rich blue)
|
||||
* - Functions/components: #7c3aed (vivid purple)
|
||||
* - Parameters/properties: #b45309 (warm amber)
|
||||
* - HTML tags: #16a34a (bright green)
|
||||
* - Attributes/numbers: #2563eb (bright blue)
|
||||
* - Punctuation/text: #1e293b (slate)
|
||||
*/
|
||||
|
||||
/* Base code style - override Prism defaults */
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: #1f2328;
|
||||
color: #1e293b;
|
||||
background: none;
|
||||
text-shadow: none;
|
||||
font-family: var(--ll-font-code, "SF Mono", "SFMono-Regular", "Consolas",
|
||||
"Liberation Mono", Menlo, Courier, monospace);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.02em;
|
||||
line-height: 18px;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
@@ -35,64 +37,64 @@ pre[class*="language-"] {
|
||||
.token.module,
|
||||
.token.imports,
|
||||
.token.control-flow {
|
||||
color: #cf222e;
|
||||
color: #d1242f;
|
||||
}
|
||||
|
||||
/* Strings and template literals */
|
||||
.token.string,
|
||||
.token.template-string,
|
||||
.token.attr-value {
|
||||
color: #0a3069;
|
||||
color: #0550ae;
|
||||
}
|
||||
|
||||
/* Function names */
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #8250df;
|
||||
color: #7c3aed;
|
||||
}
|
||||
|
||||
/* Object properties, parameters, variables in destructuring */
|
||||
.token.property,
|
||||
.token.parameter {
|
||||
color: #953800;
|
||||
color: #b45309;
|
||||
}
|
||||
|
||||
/* HTML/JSX tag names */
|
||||
.token.tag .token.tag {
|
||||
color: #116329;
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
/* Also color component names (PascalCase tags) in JSX */
|
||||
.token.tag .token.class-name {
|
||||
color: #116329;
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
/* Attributes in JSX/HTML */
|
||||
.token.tag .token.attr-name,
|
||||
.token.attr-name {
|
||||
color: #0550ae;
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
/* Numbers */
|
||||
.token.number {
|
||||
color: #0550ae;
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
/* Operators: =, ===, =>, +, - */
|
||||
.token.operator {
|
||||
color: #cf222e;
|
||||
color: #d1242f;
|
||||
}
|
||||
|
||||
/* Punctuation: brackets, parens, commas, semicolons */
|
||||
.token.punctuation {
|
||||
color: #1f2328;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
/* Booleans, null, undefined */
|
||||
.token.boolean,
|
||||
.token.constant,
|
||||
.token.builtin {
|
||||
color: #0550ae;
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
/* Comments */
|
||||
@@ -100,33 +102,33 @@ pre[class*="language-"] {
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: #6e7781;
|
||||
color: #6b7280;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* JSX specific: tag punctuation < > / */
|
||||
.token.tag .token.punctuation {
|
||||
color: #1f2328;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
/* Spread operator, rest */
|
||||
.token.spread {
|
||||
color: #cf222e;
|
||||
color: #d1242f;
|
||||
}
|
||||
|
||||
/* Plain text inside tags */
|
||||
.token.plain-text {
|
||||
color: #1f2328;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
/* Regex */
|
||||
.token.regex {
|
||||
color: #0a3069;
|
||||
color: #0550ae;
|
||||
}
|
||||
|
||||
/* Shell/bash specific */
|
||||
.language-bash .token.function {
|
||||
color: #0550ae;
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
/* No text shadow on any token */
|
||||
|
||||
@@ -244,9 +244,9 @@
|
||||
display: inline-block;
|
||||
font-family: var(--ll-font-code);
|
||||
font-size: 12.6px;
|
||||
font-weight: 460;
|
||||
font-weight: 500;
|
||||
line-height: 12.6px;
|
||||
letter-spacing: -0.09px;
|
||||
letter-spacing: 0.02em;
|
||||
padding: 1.6px 3.2px;
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user