Compare commits

...

2 Commits

Author SHA1 Message Date
e3e96e95fe Added configuration
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-08-23 06:55:26 +01:00
4c13478b6e Include libraries directly
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-08-23 05:28:02 +01:00
7 changed files with 300 additions and 105 deletions

138
src/BindIt.js Normal file
View File

@@ -0,0 +1,138 @@
function bindIt(obj, base = '', withFuncs = {}, onUpdate = ()=>{}) {
let arrayHandler = {
apply: function (fn, arr, argumentsList) {
obj[prop]._push(argumentsList);
triggerUpdate(bindKey, obj[prop]);
}
};
for (let key in obj) {
// Make sure all child objects are proxied too
if (obj.hasOwnProperty(key) && Object.prototype.toString.call(obj[key]) === '[object Object]') {
obj[key] = bindIt(obj[key], `${base ? base + '.' : ''}${key}`, withFuncs, onUpdate);
}
// ...as well as arrays
if (obj.hasOwnProperty(key) && Object.prototype.toString.call(obj[key]) === '[object Array]') {
obj[key] = new Proxy(obj[key], arrayHander);
}
}
function wrapArray(obj, prop, bindKey) {
if (Object.prototype.toString.call(obj[prop]) === '[object Array]') {
obj[prop]._push = obj[prop].push;
obj[prop].push = new Proxy(obj[prop].push, arrayHandler);
}
}
function triggerUpdate(bindKey, value) {
let elements = document.querySelectorAll(`[bind-it-to='${bindKey}']`);
requestAnimationFrame(() => {
for (let element of elements) {
let bindType = element.getAttribute('bind-it-with') || 'innerText';
switch (bindType) {
case 'innerText':
element.innerText = value;
break;
case 'innerHTML':
element.innerHTML = value;
break;
case 'value':
element.value = value;
break;
case 'checked':
element.checked = value;
break;
case 'visible':
if (value == false || value == "") {
element.style.display = 'none';
} else {
element.style.display = '';
}
break;
default:
if (typeof withFuncs[bindType] === 'function') {
withFuncs[bindType].apply(element, [value]);
} else if (typeof window[bindType] === 'function') {
window[bindType].apply(element, [value]);
}
break;
}
}
if (onUpdate !== undefined) {
requestAnimationFrame(() => {
onUpdate();
});
}
});
}
let handler = {
get: function (obj, key) {
if (typeof key === 'string') {
// Ensure safe deep get/set (no need to set up the structute)
if (obj[key] === undefined) obj[key] = bindIt({}, `${base ? base + '.' : ''}${key}`, withFuncs, onUpdate);
return obj[key];
}
},
set: function (obj, prop, value) {
const bindKey = `${base ? base + '.' : ''}${prop}`;
// Set the new value
obj[prop] = value;
// Handle arrays
wrapArray(obj, prop, bindKey);
// Handle bindings
triggerUpdate(bindKey, obj[prop]);
return obj;
}
};
let proxied = new Proxy(obj, handler);
// Handle two-way and initial bind
if (base === '') {
let elements = document.querySelectorAll(`[bind-it-to]`);
for (let element of elements) {
let key = element.getAttribute('bind-it-to');
let keyParts = key.split('.');
let wantedValue = obj;
while (keyParts.length) {
wantedValue = wantedValue[keyParts.splice(0, 1)];
}
triggerUpdate(key, wantedValue);
}
let twoWayElements = document.querySelectorAll(`[bind-it-two-way]`);
const setObjPath = (t, path, value) => {
if (typeof t != "object") throw Error("non-object")
if (path == "") throw Error("empty path")
const pos = path.indexOf(".")
return pos == -1
? (t[path] = value, value)
: setObjPath(t[path.slice(0, pos)], path.slice(pos + 1), value)
}
for (let element of twoWayElements) {
element.addEventListener('change', function () {
let prop = this.getAttribute('bind-it-to');
let bindType = this.getAttribute('bind-it-with') || 'value';
switch (bindType) {
case 'innerText':
setObjPath(proxied, prop, this.innerText);
break;
case 'innerHTML':
setObjPath(proxied, prop, this.innerHTML);
break;
case 'checked':
setObjPath(proxied, prop, this.checked);
break;
default:
setObjPath(proxied, prop, this.value);
break;
}
});
}
}
return proxied;
}

2
src/dom-to-image.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -16,12 +16,11 @@
<meta property="og:image" content="https://opengraph.cluster.fun/opengraph/?siteTitle=&title=Bsky%20Screenshot&tags=bluesky%2Cimage%2Cscreenshot&image=https%3A%2F%2Fbsky-screenshot.cluster.fun%2Ficon.png&bluesky=&fediverse=&github=&website=bsky-screenshot.cluster.fun&bgColor=%2370c9d0&fgColor=%230b1415"> <meta property="og:image" content="https://opengraph.cluster.fun/opengraph/?siteTitle=&title=Bsky%20Screenshot&tags=bluesky%2Cimage%2Cscreenshot&image=https%3A%2F%2Fbsky-screenshot.cluster.fun%2Ficon.png&bluesky=&fediverse=&github=&website=bsky-screenshot.cluster.fun&bgColor=%2370c9d0&fgColor=%230b1415">
<meta name="twitter:image" content="https://opengraph.cluster.fun/opengraph/?siteTitle=&title=Bsky%20Screenshot&tags=bluesky%2Cimage%2Cscreenshot&image=https%3A%2F%2Fbsky-screenshot.cluster.fun%2Ficon.png&bluesky=&fediverse=&github=&website=bsky-screenshot.cluster.fun&bgColor=%2370c9d0&fgColor=%230b1415"> <meta name="twitter:image" content="https://opengraph.cluster.fun/opengraph/?siteTitle=&title=Bsky%20Screenshot&tags=bluesky%2Cimage%2Cscreenshot&image=https%3A%2F%2Fbsky-screenshot.cluster.fun%2Ficon.png&bluesky=&fediverse=&github=&website=bsky-screenshot.cluster.fun&bgColor=%2370c9d0&fgColor=%230b1415">
<script tpye="application/javascript" src="https://cdn.githubraw.com/AverageMarcus/BindIt.js/refs/heads/master/BindIt.js"></script> <script tpye="application/javascript" src="BindIt.js"></script>
<script tpye="application/javascript" src="https://cdn.githubraw.com/tsayen/dom-to-image/refs/heads/master/dist/dom-to-image.min.js"></script> <script tpye="application/javascript" src="dom-to-image.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic"> <link rel="stylesheet" href="normalize.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.css"> <link rel="stylesheet" href="milligram.min.css">
<link rel="stylesheet" href="https://githubraw.com/AverageMarcus/milligram/master/dist/milligram.min.css">
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
</head> </head>
<body> <body>
@@ -39,33 +38,34 @@
<div class="column"> <div class="column">
<div class="form"> <div class="form">
<input type="text" id="post-url" bind-it-to="bskyPost.url" bind-it-with="value" /> <input type="text" id="post-url" bind-it-to="bskyPost.url" bind-it-with="value" />
<button id="submit">Fetch</button>
</div> </div>
<!-- Config is still WiP --> <details class="config">
<!--
<details>
<summary>Advanced Config</summary> <summary>Advanced Config</summary>
<div> <div>
<label>CORS Proxy: <input type="text" bind-it-to="config.corsProxy" bind-it-with="value" bind-it-two-way /></label> <label><span>CORS Proxy:</span><input type="text" bind-it-to="config.corsProxy" bind-it-with="value" bind-it-two-way /></label>
<label>Width: <input type="number" bind-it-to="config.width" bind-it-with="value" bind-it-two-way /></label> <label><span>Width:</span><input type="number" bind-it-to="config.width" bind-it-with="value" bind-it-two-way /></label>
<label>Window Decoration: <input type="checkbox" bind-it-to="config.windowDecoration" bind-it-with="checked" bind-it-two-way /></label> <label><span>Title:</span><input type="text" bind-it-to="config.windowTitle" bind-it-with="value" bind-it-two-way /></label>
<label><span>Window Decoration:</span><input type="checkbox" bind-it-to="config.windowDecoration" bind-it-with="checked" bind-it-two-way /></label>
<label><span>Show Border:</span><input type="checkbox" bind-it-to="config.showBorder" bind-it-with="checked" bind-it-two-way /></label>
<label><span>Interactions:</span><input type="checkbox" bind-it-to="config.showInteractions" bind-it-with="checked" bind-it-two-way /></label>
<label><span>Post Date:</span><input type="checkbox" bind-it-to="config.showDate" bind-it-with="checked" bind-it-two-way /></label>
</div> </div>
</details> </details>
-->
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="column post-wrapper"> <div class="column post-wrapper">
<div id="post" bind-it-to="config.width" bind-it-with="setWidth"> <div id="post" class="border" bind-it-to="config.showBorder" bind-it-with="showBorder">
<div class="post border" bind-it-to="config.width" bind-it-with="setWidth"> <div class="post" bind-it-to="config.width" bind-it-with="setWidth">
<div class="windowDecoration" bind-it-to="config.windowDecoration" bind-it-with="shouldShow"> <div class="windowDecoration" bind-it-to="config.windowDecoration" bind-it-with="visible">
<div class="buttons"> <div class="buttons">
<div class="roundButton" style="background-color: #ff544d; border-color: #dd3a33"></div> <div class="roundButton" style="background-color: #ff544d; border-color: #dd3a33"></div>
<div class="roundButton" style="background-color: #feb429; border-color: #da9211"></div> <div class="roundButton" style="background-color: #feb429; border-color: #da9211"></div>
<div class="roundButton" style="background-color: #d9d8d7; border-color: #b7b5b5"></div> <div class="roundButton" style="background-color: #d9d8d7; border-color: #b7b5b5"></div>
</div> </div>
<div class="title" bind-it-to="bskyPost.handle"></div> <div class="title"></div>
<div class="spacer"></div> <div class="spacer"></div>
</div> </div>
<div class="header"> <div class="header">
@@ -78,21 +78,21 @@
<div class="body" bind-it-to="bskyPost.text" bind-it-with="asHTML"></div> <div class="body" bind-it-to="bskyPost.text" bind-it-with="asHTML"></div>
<div class="embeds"> <div class="embeds">
<div class="images" bind-it-to="bskyPost.images.exists" bind-it-with="shouldShow"> <div class="images" bind-it-to="bskyPost.images.exists" bind-it-with="visible">
<div bind-it-to="bskyPost.images.image1" bind-it-with="shouldShow"> <div bind-it-to="bskyPost.images.image1" bind-it-with="visible">
<img bind-it-to="bskyPost.images.image1" bind-it-with="imageSrc" /> <img bind-it-to="bskyPost.images.image1" bind-it-with="imageSrc" />
</div> </div>
<div bind-it-to="bskyPost.images.image2" bind-it-with="shouldShow"> <div bind-it-to="bskyPost.images.image2" bind-it-with="visible">
<img bind-it-to="bskyPost.images.image2" bind-it-with="imageSrc" /> <img bind-it-to="bskyPost.images.image2" bind-it-with="imageSrc" />
</div> </div>
<div bind-it-to="bskyPost.images.image3" bind-it-with="shouldShow"> <div bind-it-to="bskyPost.images.image3" bind-it-with="visible">
<img bind-it-to="bskyPost.images.image3" bind-it-with="imageSrc" /> <img bind-it-to="bskyPost.images.image3" bind-it-with="imageSrc" />
</div> </div>
<div bind-it-to="bskyPost.images.image4" bind-it-with="shouldShow"> <div bind-it-to="bskyPost.images.image4" bind-it-with="visible">
<img bind-it-to="bskyPost.images.image4" bind-it-with="imageSrc" /> <img bind-it-to="bskyPost.images.image4" bind-it-with="imageSrc" />
</div> </div>
</div> </div>
<div class="externalLink" bind-it-to="bskyPost.externalLink.exists" bind-it-with="shouldShow"> <div class="externalLink" bind-it-to="bskyPost.externalLink.exists" bind-it-with="visible">
<img id="externalLinkImage" bind-it-to="bskyPost.externalLink.image" bind-it-with="imageSrc" /> <img id="externalLinkImage" bind-it-to="bskyPost.externalLink.image" bind-it-with="imageSrc" />
<div class="linkMeta"> <div class="linkMeta">
<div class="linkTitle" bind-it-to="bskyPost.externalLink.title"></div> <div class="linkTitle" bind-it-to="bskyPost.externalLink.title"></div>
@@ -106,7 +106,7 @@
</div> </div>
<div class="footer"> <div class="footer">
<div class="interactions" bind-it-to="config.interactions" bind-it-with="shouldShow"> <div class="interactions" bind-it-to="config.showInteractions" bind-it-with="visible">
<span class="replies"> <span class="replies">
<svg fill="none" width="18" viewBox="0 0 24 24" height="18" style="color: rgb(111, 134, 159); pointer-events: none;"><path fill="hsl(211, 20%, 53%)" fill-rule="evenodd" clip-rule="evenodd" d="M2.002 6a3 3 0 0 1 3-3h14a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H12.28l-4.762 2.858A1 1 0 0 1 6.002 21v-2h-1a3 3 0 0 1-3-3V6Zm3-1a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v1.234l3.486-2.092a1 1 0 0 1 .514-.142h7a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-14Z"></path></svg> <svg fill="none" width="18" viewBox="0 0 24 24" height="18" style="color: rgb(111, 134, 159); pointer-events: none;"><path fill="hsl(211, 20%, 53%)" fill-rule="evenodd" clip-rule="evenodd" d="M2.002 6a3 3 0 0 1 3-3h14a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H12.28l-4.762 2.858A1 1 0 0 1 6.002 21v-2h-1a3 3 0 0 1-3-3V6Zm3-1a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v1.234l3.486-2.092a1 1 0 0 1 .514-.142h7a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-14Z"></path></svg>
<span bind-it-to="bskyPost.replies"></span> replies <span bind-it-to="bskyPost.replies"></span> replies
@@ -120,7 +120,9 @@
<span bind-it-to="bskyPost.likes"></span> likes <span bind-it-to="bskyPost.likes"></span> likes
</span> </span>
</div> </div>
<div class="createdAt" bind-it-to="bskyPost.createdAt"></div> <div bind-it-to="config.showDate" bind-it-with="visible">
<div class="createdAt" bind-it-to="bskyPost.createdAt"></div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -128,7 +130,6 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="column"> <div class="column">
<img src="" id="result-image" /> <img src="" id="result-image" />
@@ -140,17 +141,14 @@
<button id="download">Download Image</button> <button id="download">Download Image</button>
</div> </div>
</div> </div>
<div class="container">
<div class="row">
<div class="column column-60 column-offset-20" style="text-align: center;">
Source code available on <a href="https://github.com/AverageMarcus/bsky-screenshot" target="_blank" rel="noopener noreferrer">GitHub</a>, <a href="https://gitlab.com/AverageMarcus/bsky-screenshot" target="_blank" rel="noopener noreferrer">GitLab</a>, <a href="https://bitbucket.org/AverageMarcus/bsky-screenshot/" target="_blank" rel="noopener noreferrer">Bitbucket</a> & <a href="https://git.cluster.fun/AverageMarcus/bsky-screenshot" target="_blank" rel="noopener noreferrer">my own Gitea server</a>.
</div>
</div>
</div>
</div> </div>
<div class="container"> <div class="container">
<div class="row">
<div class="column column-60 column-offset-20" style="text-align: center;">
Source code available on <a href="https://github.com/AverageMarcus/bsky-screenshot" target="_blank" rel="noopener noreferrer">GitHub</a>, <a href="https://gitlab.com/AverageMarcus/bsky-screenshot" target="_blank" rel="noopener noreferrer">GitLab</a>, <a href="https://bitbucket.org/AverageMarcus/bsky-screenshot/" target="_blank" rel="noopener noreferrer">Bitbucket</a> & <a href="https://git.cluster.fun/AverageMarcus/bsky-screenshot" target="_blank" rel="noopener noreferrer">my own Gitea server</a>.
</div>
</div>
<div class="row"> <div class="row">
<div class="column column-60 column-offset-20"> <div class="column column-60 column-offset-20">
<footer> <footer>

3
src/milligram.min.css vendored Normal file

File diff suppressed because one or more lines are too long

2
src/normalize.min.css vendored Normal file
View File

@@ -0,0 +1,2 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}
/*# sourceMappingURL=normalize.min.css.map */

View File

@@ -1,76 +1,100 @@
function imageSrc(value) {
if (value) {
this.setAttribute('src', value);
} else {
this.setAttribute('src', "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==");
}
}
function asHTML(value) {
this.innerHTML = value;
}
function shouldShow(value) {
if (value == false || value == "") {
this.style.display = 'none';
} else {
this.style.display = '';
}
}
function setWidth(value) {
this.style.width = `${value}px`;
}
var updateImageTimeout;
function updateImage() {
if (updateImageTimeout) {
window.cancelAnimationFrame(updateImageTimeout);
}
updateImageTimeout = window.requestAnimationFrame(function() {
domtoimage.toPng(document.getElementById('post'), { cacheBust: false })
.then(function (dataUrl) {
document.getElementById('result-image').src = dataUrl;
});
});
}
[...document.querySelectorAll('#post img'), ...document.querySelectorAll('#input-form input')].forEach(el => el.addEventListener('load', updateImage));
(() => { (() => {
let {bskyPost, config} = bindIt({ let {bskyPost, config} = bindIt(
config: { {
corsProxy: `https://corsproxy.io/?url=`, config: {
width: 600, corsProxy: `https://corsproxy.io/?url=`,
windowDecoration: true, width: 600,
showInteractions: true windowTitle: "$handle", // $handle, $displayName, $url
}, windowDecoration: true,
bskyPost: { showInteractions: true,
url: 'https://bsky.app/profile/averagemarcus.bsky.social/post/3lwyxxwjnxc2k', showDate: true,
handle: '', showBorder: true
displayName: '',
avatar: '',
text: '',
createdAt: '',
likes: 0,
reposts: 0,
replies: 0,
externalLink: {
exists: false,
title: "",
description: "",
image: "",
domain: ""
}, },
images: { bskyPost: {
exists: false, url: 'https://bsky.app/profile/averagemarcus.bsky.social/post/3lwyxxwjnxc2k',
image1: "", handle: '',
image2: "", displayName: '',
image3: "", avatar: '',
image4: "", text: '',
createdAt: '',
likes: 0,
reposts: 0,
replies: 0,
externalLink: {
exists: false,
title: "",
description: "",
image: "",
domain: ""
},
images: {
exists: false,
image1: "",
image2: "",
image3: "",
image4: "",
}
} }
},
"",
{
imageSrc: function(value) {
if (value) {
this.setAttribute('src', value);
} else {
this.setAttribute('src', "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==");
}
},
asHTML: function(value) {
this.innerHTML = value;
},
setWidth: function(value) {
this.style.width = `${value}px`;
},
showBorder: function(value) {
if (value) {
this.style.borderStyle = "double";
} else {
this.style.borderStyle = "none";
}
}
},
updateImage
);
var updateImageTimeout;
function updateImage() {
if (updateImageTimeout) {
window.cancelAnimationFrame(updateImageTimeout);
} }
}); setWindowTitle();
updateImageTimeout = window.requestAnimationFrame(function() {
domtoimage.toPng(document.getElementById('post'), { cacheBust: false })
.then(function (dataUrl) {
document.getElementById('result-image').src = dataUrl;
});
});
}
[...document.querySelectorAll('#post img')].forEach(el => el.addEventListener('load', updateImage));
[...document.querySelectorAll('#input-form input')].forEach(el => el.addEventListener('change', updateImage));
function setWindowTitle() {
switch (config.windowTitle) {
case "$handle":
document.querySelector('.windowDecoration .title').innerText = bskyPost.handle;
break;
case "$displayName":
document.querySelector('.windowDecoration .title').innerText = bskyPost.displayName;
break;
case "$url":
document.querySelector('.windowDecoration .title').innerText = bskyPost.url.replaceAll("https://", "");
break;
default:
document.querySelector('.windowDecoration .title').innerText = config.windowTitle;
break;
}
}
function isValidHttpUrl(string) { function isValidHttpUrl(string) {
let url; let url;
@@ -176,9 +200,13 @@ function updateImage() {
updateImage(); updateImage();
} }
document.getElementById('submit').addEventListener('click', loadPost);
document.getElementById('post-url').addEventListener('change', loadPost); document.getElementById('post-url').addEventListener('change', loadPost);
document.getElementById('post-url').addEventListener('keyup', loadPost); document.getElementById('post-url').addEventListener('keyup', loadPost);
document.getElementById('post-url').addEventListener('paste', (ev) =>{
let data = ev.clipboardData.getData("text/plain");
document.getElementById('post-url').value = data;
loadPost();
});
window.requestAnimationFrame(loadPost); window.requestAnimationFrame(loadPost);
document.getElementById('download').addEventListener('click', function() { document.getElementById('download').addEventListener('click', function() {
@@ -187,4 +215,8 @@ function updateImage() {
link.href = document.getElementById('result-image').src; link.href = document.getElementById('result-image').src;
link.click(); link.click();
}); });
window.debugBskyPost = function() {
console.log(bskyPost, config);
}
})(); })();

View File

@@ -11,6 +11,27 @@ body {
margin: 2px; margin: 2px;
} }
.config > div {
display: flex;
flex-wrap: wrap;
gap: 0 24px;
justify-content: space-evenly;
align-items: flex-start;
flex-direction: row;
text-align: center;
}
.config > div label input {
margin: 0;
display: block;
}
.config > div label input[type=checkbox] {
margin: 15px auto;
scale: 2;
}
.config > div label:nth-of-type(1) {
flex-basis: 100%;
}
.post-wrapper { .post-wrapper {
overflow: hidden; overflow: hidden;
position: relative; position: relative;
@@ -20,7 +41,6 @@ body {
position: absolute; position: absolute;
left: -9999; left: -9999;
top: -9999; top: -9999;
width: 600px;
margin-left: -10px; margin-left: -10px;
} }