+
🔎
+
Preview OpenGraph metadata
+
+ Enter a URL above to see how it unfurls on social platforms.
+ Local dev servers like http://localhost:3000 work too.
+
+
+
+
+
+
diff --git a/.github/extensions/og-preview/ui/styles.css b/.github/extensions/og-preview/ui/styles.css
new file mode 100644
index 000000000..ef16039c1
--- /dev/null
+++ b/.github/extensions/og-preview/ui/styles.css
@@ -0,0 +1,517 @@
+:root {
+ --card-radius: 12px;
+ --gap: 16px;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html,
+body {
+ margin: 0;
+ height: 100%;
+}
+
+body {
+ background: var(--background-color-default, #ffffff);
+ color: var(--text-color-default, #1f2328);
+ font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
+ font-size: var(--text-body-medium, 14px);
+ line-height: var(--leading-body-medium, 20px);
+ display: flex;
+ flex-direction: column;
+}
+
+.muted {
+ color: var(--text-color-muted, #59636e);
+}
+
+code {
+ font-family: var(--font-mono, "SFMono-Regular", Consolas, "Liberation Mono", monospace);
+ font-size: var(--text-code-inline, 12px);
+ background: var(--background-color-muted, rgba(129, 139, 152, 0.12));
+ padding: 1px 5px;
+ border-radius: 5px;
+}
+
+/* ---------- Toolbar ---------- */
+.toolbar {
+ position: sticky;
+ top: 0;
+ z-index: 5;
+ padding: 12px 16px 0;
+ background: var(--background-color-default, #ffffff);
+ border-bottom: 1px solid var(--border-color-default, #d1d9e0);
+}
+
+.url-form {
+ display: flex;
+ gap: 8px;
+ align-items: center;
+}
+
+.url-input {
+ flex: 1;
+ min-width: 0;
+ padding: 8px 12px;
+ border-radius: 8px;
+ border: 1px solid var(--border-color-default, #d1d9e0);
+ background: var(--background-color-inset, #f6f8fa);
+ color: inherit;
+ font-size: 14px;
+ font-family: var(--font-mono, monospace);
+}
+
+.url-input:focus {
+ outline: 2px solid var(--color-focus-outline, #0969da);
+ outline-offset: -1px;
+ border-color: transparent;
+}
+
+.btn {
+ border: 1px solid var(--border-color-default, #d1d9e0);
+ background: var(--background-color-default, #ffffff);
+ color: inherit;
+ padding: 8px 14px;
+ border-radius: 8px;
+ font-size: 14px;
+ font-weight: var(--font-weight-semibold, 600);
+ cursor: pointer;
+ white-space: nowrap;
+}
+
+.btn:hover {
+ background: var(--background-color-muted, rgba(129, 139, 152, 0.12));
+}
+
+.btn.primary {
+ background: var(--true-color-blue, #0969da);
+ border-color: var(--true-color-blue, #0969da);
+ color: var(--color-white, #ffffff);
+}
+
+.btn.primary:hover {
+ filter: brightness(1.05);
+}
+
+.btn.icon {
+ padding: 8px 12px;
+ font-size: 16px;
+ line-height: 1;
+}
+
+.btn.small {
+ padding: 4px 10px;
+ font-size: 12px;
+}
+
+.tabs {
+ display: flex;
+ gap: 4px;
+ margin-top: 10px;
+}
+
+.tab {
+ border: none;
+ background: none;
+ color: var(--text-color-muted, #59636e);
+ padding: 8px 4px;
+ margin-right: 12px;
+ font-size: 14px;
+ font-weight: var(--font-weight-semibold, 600);
+ cursor: pointer;
+ border-bottom: 2px solid transparent;
+}
+
+.tab:hover {
+ color: var(--text-color-default, #1f2328);
+}
+
+.tab.active {
+ color: var(--text-color-default, #1f2328);
+ border-bottom-color: var(--true-color-orange, #fb8500);
+}
+
+/* ---------- Status ---------- */
+.status {
+ margin: 12px 16px 0;
+ padding: 10px 14px;
+ border-radius: 8px;
+ font-size: 13px;
+ border: 1px solid var(--border-color-default, #d1d9e0);
+}
+
+.status.loading {
+ background: var(--background-color-inset, #f6f8fa);
+}
+
+.status.error {
+ background: var(--true-color-red-muted, rgba(255, 129, 130, 0.15));
+ border-color: var(--true-color-red, #cf222e);
+ color: var(--true-color-red, #cf222e);
+}
+
+/* ---------- Panels ---------- */
+.content {
+ flex: 1;
+ overflow: auto;
+ padding: 16px;
+}
+
+.panel {
+ display: none;
+}
+
+.panel.active {
+ display: block;
+}
+
+.empty {
+ margin: auto;
+ text-align: center;
+ max-width: 420px;
+ padding: 48px 24px;
+}
+
+.empty-icon {
+ font-size: 40px;
+}
+
+.empty-title {
+ font-size: var(--text-title-medium, 18px);
+ font-weight: var(--font-weight-semibold, 600);
+ margin: 8px 0 4px;
+}
+
+.is-busy .empty {
+ display: none;
+}
+
+/* ---------- Previews grid ---------- */
+.previews-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
+ gap: 20px;
+ align-items: start;
+}
+
+.preview {
+ min-width: 0;
+}
+
+.preview-label {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 12px;
+ font-weight: var(--font-weight-semibold, 600);
+ text-transform: uppercase;
+ letter-spacing: 0.04em;
+ color: var(--text-color-muted, #59636e);
+ margin-bottom: 8px;
+}
+
+.preview-label .dot {
+ width: 9px;
+ height: 9px;
+ border-radius: 50%;
+}
+
+.card-img {
+ width: 100%;
+ display: block;
+ background: #e9edf1 url("data:image/svg+xml;utf8,