Various AT Protocol integrations with obsidian
20
fork

Configure Feed

Select the types of activity you want to include in your feed.

add post embed processor

+992 -1
+9
bun.lock
··· 15 15 "@atcute/oauth-browser-client": "^3.0.0", 16 16 "@atcute/pckt": "^0.1.5", 17 17 "@atcute/standard-site": "^1.0.0", 18 + "bluesky-post-embed": "^1.0.6", 18 19 "obsidian": "latest", 19 20 "remark-parse": "^11.0.0", 20 21 "remark-stringify": "^11.0.0", ··· 38 39 "@atcute/atproto": ["@atcute/atproto@3.1.10", "", { "dependencies": { "@atcute/lexicons": "^1.2.6" } }, "sha512-+GKZpOc0PJcdWMQEkTfg/rSNDAAHxmAUGBl60g2az15etqJn5WaUPNGFE2sB7hKpwi5Ue2h/L0OacINcE/JDDQ=="], 39 40 40 41 "@atcute/bluesky": ["@atcute/bluesky@3.2.16", "", { "dependencies": { "@atcute/atproto": "^3.1.10", "@atcute/lexicons": "^1.2.7" } }, "sha512-phFAJNE+SCkIbCcgzjFxntS2KpGvzkLw0JA9qKIXlueF4wNreEt/D5HjnB5eRR9pV1/kcD94II9f7ZAwarf0lQ=="], 42 + 43 + "@atcute/bluesky-richtext-segmenter": ["@atcute/bluesky-richtext-segmenter@2.0.4", "", { "dependencies": { "@atcute/bluesky": "^3.2.5", "@atcute/lexicons": "^1.2.2" } }, "sha512-6m5QEAv4lU3qTy5MeJXJRRG33acipYJnMW1T7W/KrMyThGhQ7jSTTh8Z48quElgivgX7MDj6o/ow1oLUsjsCKw=="], 41 44 42 45 "@atcute/car": ["@atcute/car@5.1.0", "", { "dependencies": { "@atcute/cbor": "^2.3.0", "@atcute/cid": "^2.4.0", "@atcute/uint8array": "^1.0.6", "@atcute/varint": "^1.0.3" } }, "sha512-W9axHVrwIkZJaeN/VQ1LyyU3b95wHBjQnrREouxygvmvWd1lmjFvF8Si8b0AG0VkWJ6h7h6qhOeUATynBzBFIg=="], 43 46 ··· 276 279 "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], 277 280 278 281 "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], 282 + 283 + "bluesky-post-embed": ["bluesky-post-embed@1.0.6", "", { "dependencies": { "@atcute/bluesky": "^2.1.1", "@atcute/bluesky-richtext-segmenter": "^2.0.4", "@atcute/client": "^3.1.0" } }, "sha512-gJ+HKQbpDE+Mr7iv72NAF7WRNKu9CsWDwfbdgCtcZruN2HJfAeKHdCk5pflbz1fABwMMInjwN4909HCQjMCY2w=="], 279 284 280 285 "brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], 281 286 ··· 838 843 "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], 839 844 840 845 "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], 846 + 847 + "bluesky-post-embed/@atcute/bluesky": ["@atcute/bluesky@2.1.1", "", { "peerDependencies": { "@atcute/client": "^3.0.0" } }, "sha512-wEZfFW58J6yC1SqHcVJOn4qbHENTTzjeCEWthRT5HvKovADLqk54HSMSAuXDMBUbintSTBr0khQNZQ3ZdgzDdQ=="], 848 + 849 + "bluesky-post-embed/@atcute/client": ["@atcute/client@3.1.0", "", {}, "sha512-+rQPsHXSf0DUm8XoHoaH7Y2E8tIpbsW84djyPj7dqAyrFIjvGuJ1X1DvMufwbTIcmLerdy+dzl34iZcz/h3Vhg=="], 841 850 842 851 "eslint/@eslint/js": ["@eslint/js@9.39.2", "", {}, "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA=="], 843 852
+1
package.json
··· 35 35 "@atcute/oauth-browser-client": "^3.0.0", 36 36 "@atcute/pckt": "^0.1.5", 37 37 "@atcute/standard-site": "^1.0.0", 38 + "bluesky-post-embed": "^1.0.6", 38 39 "obsidian": "latest", 39 40 "remark-parse": "^11.0.0", 40 41 "remark-stringify": "^11.0.0",
+13 -1
src/lib.ts
··· 1 1 import { Record } from "@atcute/atproto/types/repo/listRecords"; 2 2 3 - export { getRecord, deleteRecord, putRecord} from "./lib/atproto"; 3 + export { getRecord, deleteRecord, putRecord } from "./lib/atproto"; 4 + 5 + export const BSKY_POST_RE = /https:\/\/bsky\.app\/profile\/([^/?#]+)\/post\/([A-Za-z0-9]+)/; 6 + 7 + export function bskyPostATUri(url: string): string | null { 8 + const match = url.match(BSKY_POST_RE); 9 + if (!match) return null; 10 + 11 + const [, handleOrDid, rkey] = match; 12 + if (!handleOrDid || !rkey) return null; 13 + 14 + return `at://${handleOrDid}/app.bsky.feed.post/${rkey}`; 15 + } 4 16 5 17 export { 6 18 getSembleCollections,
+5
src/main.ts
··· 6 6 import { ATClient } from "lib/client"; 7 7 import { Clipper } from "lib/clipper"; 8 8 import { registerIcons } from "./icons"; 9 + import { BlueskyPostProcessor } from "./postprocessor"; 9 10 10 11 export default class AtmospherePlugin extends Plugin { 11 12 settings: AtProtoSettings = DEFAULT_SETTINGS; ··· 15 16 async onload() { 16 17 registerIcons(); 17 18 await this.loadSettings(); 19 + 18 20 this.client = new ATClient(); 19 21 this.clipper = new Clipper(this); 20 22 ··· 33 35 new Notice('Authentication error. Please try again.'); 34 36 } 35 37 }); 38 + 39 + const bskyProcessor = new BlueskyPostProcessor(); 40 + this.registerMarkdownPostProcessor((el, ctx) => bskyProcessor.process(el, ctx)); 36 41 37 42 this.registerView(VIEW_TYPE_ATMOSPHERE_BOOKMARKS, (leaf) => { 38 43 return new BookmarksView(leaf, this);
+56
src/postprocessor.ts
··· 1 + import { Component, MarkdownPostProcessorContext, setIcon } from "obsidian"; 2 + import { BSKY_POST_RE, bskyPostATUri } from "lib"; 3 + 4 + 5 + export class BlueskyPostProcessor extends Component { 6 + 7 + async process(el: HTMLElement, _ctx: MarkdownPostProcessorContext) { 8 + 9 + if (!customElements.get("bluesky-post")) { 10 + import("bluesky-post-embed"); 11 + } 12 + 13 + const links = el.findAll("a").filter(link => { 14 + const href = link.getAttribute("href") ?? ""; 15 + return BSKY_POST_RE.test(href); 16 + }); 17 + 18 + if (links.length === 0) return; 19 + 20 + for (const link of links) { 21 + const atUri = bskyPostATUri(link.getAttribute("href") ?? ""); 22 + if (!atUri) continue; 23 + 24 + this.attachToggle(link, atUri); 25 + } 26 + } 27 + 28 + private attachToggle(link: HTMLElement, uri: string) { 29 + const embedId = `bsky-embed-${uri.replace(/[:\/]/g, "-")}`; 30 + 31 + const btn = document.createElement("button"); 32 + btn.setAttribute("aria-label", "Toggle post embed"); 33 + btn.addClass("bsky-embed-toggle"); 34 + setIcon(btn, "message-circle"); 35 + 36 + link.insertAdjacentElement("afterend", btn); 37 + 38 + btn.addEventListener("click", () => { 39 + const existing = document.getElementById(embedId); 40 + if (existing) { 41 + existing.remove(); 42 + setIcon(btn, "message-circle"); 43 + return; 44 + } 45 + 46 + const embedEl = document.createElement("bluesky-post") as HTMLElement; 47 + embedEl.id = embedId; 48 + embedEl.setAttribute("src", uri); 49 + embedEl.setAttribute("allow-unauthenticated", ""); 50 + embedEl.addClass("bsky-post-embed-wrapper"); 51 + 52 + btn.insertAdjacentElement("afterend", embedEl); 53 + setIcon(btn, "x"); 54 + }); 55 + } 56 + }
+908
styles.css
··· 1608 1608 margin: 0 auto; 1609 1609 } 1610 1610 } 1611 + 1612 + /* Bluesky post embed - toggle button */ 1613 + .bsky-embed-toggle { 1614 + display: inline-flex; 1615 + align-items: center; 1616 + justify-content: center; 1617 + width: 1.4em; 1618 + height: 1.4em; 1619 + margin-left: 0.25em; 1620 + padding: 0; 1621 + border: none; 1622 + background: transparent; 1623 + cursor: pointer; 1624 + opacity: 0.6; 1625 + color: var(--text-accent); 1626 + vertical-align: middle; 1627 + transition: opacity 0.15s ease; 1628 + } 1629 + 1630 + .bsky-embed-toggle:hover { 1631 + opacity: 1; 1632 + } 1633 + 1634 + /* bluesky-post-embed web component wrapper */ 1635 + bluesky-post { 1636 + display: block; 1637 + margin: 0.75em 0; 1638 + 1639 + /* Map Obsidian theme vars to bluesky-embed vars */ 1640 + --font-size: var(--font-text-size, 16px); 1641 + --font-family: var(--font-text); 1642 + --background-primary: var(--background-secondary); 1643 + --background-secondary: var(--background-modifier-hover); 1644 + --divider: var(--background-modifier-border); 1645 + --divider-hover: var(--background-modifier-border-hover); 1646 + --text-primary: var(--text-normal); 1647 + --text-secondary: var(--text-muted); 1648 + --text-link: var(--link-color); 1649 + } 1650 + 1651 + /* bluesky-embed library styles */ 1652 + 1653 + .bluesky-embed.s-3olstj { 1654 + position: relative; 1655 + box-sizing: border-box; 1656 + margin: 0 auto; 1657 + border: 1px solid var(--divider); 1658 + border-radius: 8px; 1659 + background: var(--background-primary); 1660 + min-width: 250px; 1661 + max-width: 550px; 1662 + overflow: hidden; 1663 + color: var(--text-primary); 1664 + font-weight: 400; 1665 + font-size: calc(var(--font-size) * 0.875); 1666 + line-height: calc(var(--font-size) * 1.25); 1667 + font-family: var(--font-family); 1668 + 1669 + :where(*), 1670 + :where(*::before), 1671 + :where(*::after) { 1672 + box-sizing: border-box; 1673 + margin: 0; 1674 + padding: 0; 1675 + } 1676 + :where(a) { 1677 + color: inherit; 1678 + text-decoration: none; 1679 + } 1680 + 1681 + :where(.icon) { 1682 + flex-shrink: 0; 1683 + width: 1em; 1684 + height: 1em; 1685 + } 1686 + } 1687 + 1688 + .gate.s-q6x07m { 1689 + display: flex; 1690 + align-items: center; 1691 + gap: 12px; 1692 + cursor: pointer; 1693 + border: 1px solid var(--divider); 1694 + border-radius: 6px; 1695 + padding: 0 12px; 1696 + height: 44px; 1697 + 1698 + .content-hider[open]:where(.s-q6x07m) & { 1699 + margin-bottom: 12px; 1700 + } 1701 + 1702 + &:hover { 1703 + border-color: var(--divider-hover); 1704 + } 1705 + } 1706 + 1707 + .icon.s-q6x07m { 1708 + width: 18px; 1709 + height: 18px; 1710 + color: var(--text-secondary); 1711 + } 1712 + .label.s-q6x07m { 1713 + flex-grow: 1; 1714 + overflow: hidden; 1715 + font-weight: 500; 1716 + user-select: none; 1717 + text-overflow: ellipsis; 1718 + } 1719 + 1720 + .action.s-q6x07m { 1721 + color: var(--text-link); 1722 + font-weight: 500; 1723 + font-size: calc(var(--font-size) * 0.8125); 1724 + line-height: calc(var(--font-size) * 1.25); 1725 + 1726 + &::before { 1727 + content: 'Show'; 1728 + } 1729 + .content-hider[open]:where(.s-q6x07m) &::before { 1730 + content: 'Hide'; 1731 + } 1732 + } 1733 + 1734 + .external-embed.s-rtbqd8 { 1735 + display: block; 1736 + border: 1px solid var(--divider); 1737 + border-radius: 6px; 1738 + overflow: hidden; 1739 + 1740 + &:hover { 1741 + border-color: var(--divider-hover); 1742 + } 1743 + } 1744 + 1745 + .thumbnail.s-rtbqd8 { 1746 + display: block; 1747 + border-bottom: 1px solid var(--divider); 1748 + background: #000000; 1749 + aspect-ratio: 1.91; 1750 + width: 100%; 1751 + 1752 + .external-embed:where(.s-rtbqd8):hover & { 1753 + border-color: var(--divider-hover); 1754 + } 1755 + } 1756 + 1757 + .meta.s-rtbqd8 { 1758 + padding: 12px; 1759 + } 1760 + 1761 + .title.s-rtbqd8 { 1762 + display: -webkit-box; 1763 + overflow: hidden; 1764 + font-weight: 700; 1765 + white-space: pre-wrap; 1766 + -webkit-box-orient: vertical; 1767 + -webkit-line-clamp: 2; 1768 + line-clamp: 2; 1769 + overflow-wrap: break-word; 1770 + 1771 + &:empty { 1772 + display: none; 1773 + } 1774 + } 1775 + .description.s-rtbqd8 { 1776 + display: -webkit-box; 1777 + overflow: hidden; 1778 + color: var(--text-secondary); 1779 + font-size: calc(var(--font-size) * 0.8125); 1780 + white-space: pre-wrap; 1781 + -webkit-box-orient: vertical; 1782 + -webkit-line-clamp: 2; 1783 + line-clamp: 2; 1784 + overflow-wrap: break-word; 1785 + 1786 + &:empty { 1787 + display: none; 1788 + } 1789 + } 1790 + 1791 + .domain.s-rtbqd8 { 1792 + display: flex; 1793 + align-items: center; 1794 + gap: 6px; 1795 + margin: 6px 0 0 0; 1796 + color: var(--text-secondary); 1797 + font-weight: 500; 1798 + font-size: calc(var(--font-size) * 0.75); 1799 + } 1800 + 1801 + .feed-embed.s-156tlwp { 1802 + display: flex; 1803 + flex-direction: column; 1804 + gap: 12px; 1805 + border: 1px solid var(--divider); 1806 + border-radius: 6px; 1807 + padding: 12px; 1808 + 1809 + &:hover { 1810 + border-color: var(--divider-hover); 1811 + } 1812 + } 1813 + 1814 + .main.s-156tlwp { 1815 + display: flex; 1816 + gap: 12px; 1817 + } 1818 + 1819 + .avatar-wrapper.s-156tlwp { 1820 + margin: 2px 0 0 0; 1821 + border-radius: 6px; 1822 + background: var(--background-secondary); 1823 + width: 36px; 1824 + height: 36px; 1825 + overflow: hidden; 1826 + } 1827 + .avatar.s-156tlwp { 1828 + width: 100%; 1829 + height: 100%; 1830 + object-fit: cover; 1831 + } 1832 + 1833 + .name.s-156tlwp { 1834 + font-weight: 700; 1835 + } 1836 + 1837 + .creator.s-156tlwp { 1838 + color: var(--text-secondary); 1839 + font-size: calc(var(--font-size) * 0.8125); 1840 + } 1841 + 1842 + .description.s-156tlwp { 1843 + display: -webkit-box; 1844 + overflow: hidden; 1845 + font-size: calc(var(--font-size) * 0.8125); 1846 + white-space: pre-wrap; 1847 + -webkit-box-orient: vertical; 1848 + -webkit-line-clamp: 2; 1849 + line-clamp: 2; 1850 + overflow-wrap: break-word; 1851 + 1852 + &:empty { 1853 + display: none; 1854 + } 1855 + } 1856 + 1857 + .is-aligned.s-t3k6fc { 1858 + align-self: baseline; 1859 + max-width: 100%; 1860 + } 1861 + 1862 + .grid.s-t3k6fc { 1863 + display: flex; 1864 + gap: 2px; 1865 + } 1866 + .col.s-t3k6fc { 1867 + display: flex; 1868 + flex: 1; 1869 + flex-direction: column; 1870 + gap: 2px; 1871 + } 1872 + 1873 + .square.s-t3k6fc { 1874 + aspect-ratio: 1; 1875 + } 1876 + .wide.s-t3k6fc { 1877 + aspect-ratio: 1.5; 1878 + } 1879 + 1880 + .item.s-t3k6fc { 1881 + position: relative; 1882 + flex-grow: 1; 1883 + flex-shrink: 0; 1884 + overflow: hidden; 1885 + } 1886 + 1887 + .is-bordered.s-t3k6fc { 1888 + .tl:where(.s-t3k6fc), 1889 + .tr:where(.s-t3k6fc), 1890 + .bl:where(.s-t3k6fc), 1891 + .br:where(.s-t3k6fc) { 1892 + border: 1px solid var(--divider); 1893 + } 1894 + 1895 + .tl:where(.s-t3k6fc) { 1896 + border-top-left-radius: 6px; 1897 + } 1898 + .tr:where(.s-t3k6fc) { 1899 + border-top-right-radius: 6px; 1900 + } 1901 + .bl:where(.s-t3k6fc) { 1902 + border-bottom-left-radius: 6px; 1903 + } 1904 + .br:where(.s-t3k6fc) { 1905 + border-bottom-right-radius: 6px; 1906 + } 1907 + } 1908 + 1909 + .single-item.s-t3k6fc { 1910 + position: relative; 1911 + aspect-ratio: 16 / 9; 1912 + overflow: hidden; 1913 + 1914 + .image:where(.s-t3k6fc) { 1915 + object-fit: contain; 1916 + } 1917 + } 1918 + .is-standalone.s-t3k6fc { 1919 + min-width: 64px; 1920 + max-width: 100%; 1921 + min-height: 64px; 1922 + max-height: 320px; 1923 + } 1924 + 1925 + .image.s-t3k6fc { 1926 + position: absolute; 1927 + inset: 0; 1928 + background: #000000; 1929 + width: 100%; 1930 + height: 100%; 1931 + object-fit: cover; 1932 + font-size: 0px; 1933 + } 1934 + .is-blurred.s-t3k6fc { 1935 + scale: 125%; 1936 + filter: blur(24px); 1937 + } 1938 + 1939 + .placeholder.s-t3k6fc { 1940 + width: 100vw; 1941 + height: 100vh; 1942 + } 1943 + 1944 + .list-embed.s-6uize5 { 1945 + display: flex; 1946 + flex-direction: column; 1947 + gap: 12px; 1948 + border: 1px solid var(--divider); 1949 + border-radius: 6px; 1950 + padding: 12px; 1951 + 1952 + &:hover { 1953 + border-color: var(--divider-hover); 1954 + } 1955 + } 1956 + 1957 + .main.s-6uize5 { 1958 + display: flex; 1959 + gap: 12px; 1960 + } 1961 + 1962 + .avatar-wrapper.s-6uize5 { 1963 + margin: 2px 0 0 0; 1964 + border-radius: 6px; 1965 + background: var(--background-secondary); 1966 + width: 36px; 1967 + height: 36px; 1968 + overflow: hidden; 1969 + } 1970 + .avatar.s-6uize5 { 1971 + width: 100%; 1972 + height: 100%; 1973 + object-fit: cover; 1974 + } 1975 + 1976 + .name.s-6uize5 { 1977 + font-weight: 700; 1978 + } 1979 + 1980 + .creator.s-6uize5 { 1981 + color: var(--text-secondary); 1982 + font-size: calc(var(--font-size) * 0.8125); 1983 + } 1984 + 1985 + .description.s-6uize5 { 1986 + display: -webkit-box; 1987 + overflow: hidden; 1988 + font-size: calc(var(--font-size) * 0.8125); 1989 + white-space: pre-wrap; 1990 + -webkit-box-orient: vertical; 1991 + -webkit-line-clamp: 2; 1992 + line-clamp: 2; 1993 + overflow-wrap: break-word; 1994 + 1995 + &:empty { 1996 + display: none; 1997 + } 1998 + } 1999 + 2000 + .video-embed.s-1azk58e { 2001 + display: block; 2002 + position: relative; 2003 + background: #000000; 2004 + aspect-ratio: 16 / 9; 2005 + overflow: hidden; 2006 + } 2007 + .is-bordered.s-1azk58e { 2008 + border: 1px solid var(--divider); 2009 + border-radius: 6px; 2010 + } 2011 + .is-standalone.s-1azk58e { 2012 + align-self: baseline; 2013 + aspect-ratio: auto; 2014 + max-width: 100%; 2015 + } 2016 + 2017 + .constrainer.s-1azk58e { 2018 + min-width: 64px; 2019 + max-width: 100%; 2020 + min-height: 64px; 2021 + max-height: 320px; 2022 + } 2023 + 2024 + .thumbnail.s-1azk58e { 2025 + width: 100%; 2026 + height: 100%; 2027 + object-fit: contain; 2028 + } 2029 + .is-blurred.s-1azk58e { 2030 + scale: 125%; 2031 + filter: blur(24px); 2032 + } 2033 + 2034 + .placeholder.s-1azk58e { 2035 + width: 100vw; 2036 + height: 100vh; 2037 + } 2038 + 2039 + .play.s-1azk58e { 2040 + display: grid; 2041 + position: absolute; 2042 + top: 50%; 2043 + left: 50%; 2044 + place-items: center; 2045 + translate: -50% -50%; 2046 + border-radius: 50%; 2047 + background: rgba(64, 64, 64, 0.6); 2048 + aspect-ratio: 1 / 1; 2049 + height: 40%; 2050 + max-height: 48px; 2051 + color: #ffffff; 2052 + font-size: 20px; 2053 + 2054 + .icon:where(.s-1azk58e) { 2055 + width: 40%; 2056 + height: 40%; 2057 + } 2058 + 2059 + .is-standalone:where(.s-1azk58e) &:hover { 2060 + background: rgba(64, 64, 64, 0.8); 2061 + } 2062 + } 2063 + 2064 + .quote-embed.s-za6fip { 2065 + display: block; 2066 + border: 1px solid var(--divider); 2067 + border-radius: 6px; 2068 + overflow: hidden; 2069 + 2070 + &:hover { 2071 + border-color: var(--divider-hover); 2072 + } 2073 + } 2074 + 2075 + .meta.s-za6fip { 2076 + display: flex; 2077 + padding: 12px 12px 0 12px; 2078 + color: var(--text-secondary); 2079 + 2080 + .avatar-wrapper:where(.s-za6fip) { 2081 + flex-shrink: 0; 2082 + margin: 0 8px 0 0; 2083 + border-radius: 9999px; 2084 + background: var(--background-secondary); 2085 + width: 20px; 2086 + height: 20px; 2087 + overflow: hidden; 2088 + } 2089 + .avatar:where(.s-za6fip) { 2090 + width: 100%; 2091 + height: 100%; 2092 + } 2093 + 2094 + .name-wrapper:where(.s-za6fip) { 2095 + display: flex; 2096 + gap: 4px; 2097 + max-width: 100%; 2098 + overflow: hidden; 2099 + text-overflow: ellipsis; 2100 + white-space: nowrap; 2101 + } 2102 + .display-name-wrapper:where(.s-za6fip) { 2103 + overflow: hidden; 2104 + text-overflow: ellipsis; 2105 + } 2106 + .display-name:where(.s-za6fip) { 2107 + color: var(--text-primary); 2108 + font-weight: 700; 2109 + } 2110 + .handle:where(.s-za6fip) { 2111 + display: block; 2112 + overflow: hidden; 2113 + text-overflow: ellipsis; 2114 + white-space: nowrap; 2115 + } 2116 + 2117 + .dot:where(.s-za6fip) { 2118 + flex-shrink: 0; 2119 + margin: 0 6px; 2120 + } 2121 + 2122 + .date:where(.s-za6fip) { 2123 + white-space: nowrap; 2124 + } 2125 + } 2126 + 2127 + .body.s-za6fip { 2128 + display: flex; 2129 + align-items: flex-start; 2130 + } 2131 + 2132 + .aside.s-za6fip { 2133 + flex-grow: 1; 2134 + flex-basis: 0; 2135 + margin: 8px 0 12px 12px; 2136 + max-width: 20%; 2137 + } 2138 + 2139 + .text.s-za6fip { 2140 + display: -webkit-box; 2141 + margin: 8px 12px 12px 12px; 2142 + overflow: hidden; 2143 + -webkit-box-orient: vertical; 2144 + -webkit-line-clamp: 6; 2145 + line-clamp: 6; 2146 + flex-grow: 4; 2147 + flex-basis: 0px; 2148 + min-width: 0px; 2149 + white-space: pre-wrap; 2150 + overflow-wrap: break-word; 2151 + } 2152 + 2153 + .divide.s-za6fip { 2154 + padding: 6px 0; 2155 + } 2156 + 2157 + .starterpack-embed.s-15v965v { 2158 + display: block; 2159 + border: 1px solid var(--divider); 2160 + border-radius: 6px; 2161 + overflow: hidden; 2162 + 2163 + &:hover { 2164 + border-color: var(--divider-hover); 2165 + } 2166 + } 2167 + 2168 + .banner.s-15v965v { 2169 + display: block; 2170 + aspect-ratio: 1.91; 2171 + width: 100%; 2172 + } 2173 + 2174 + .meta.s-15v965v { 2175 + display: flex; 2176 + flex-direction: column; 2177 + gap: 12px; 2178 + padding: 12px; 2179 + } 2180 + 2181 + .main.s-15v965v { 2182 + display: flex; 2183 + gap: 12px; 2184 + } 2185 + 2186 + .avatar.s-15v965v { 2187 + margin: 2px; 2188 + width: 36px; 2189 + height: 36px; 2190 + } 2191 + 2192 + .name.s-15v965v { 2193 + font-weight: 700; 2194 + } 2195 + 2196 + .creator.s-15v965v { 2197 + color: var(--text-secondary); 2198 + font-size: calc(var(--font-size) * 0.8125); 2199 + } 2200 + 2201 + .description.s-15v965v { 2202 + display: -webkit-box; 2203 + overflow: hidden; 2204 + font-size: calc(var(--font-size) * 0.8125); 2205 + white-space: pre-wrap; 2206 + -webkit-box-orient: vertical; 2207 + -webkit-line-clamp: 2; 2208 + line-clamp: 2; 2209 + overflow-wrap: break-word; 2210 + 2211 + &:empty { 2212 + display: none; 2213 + } 2214 + } 2215 + 2216 + .embeds.s-azdpbr { 2217 + display: flex; 2218 + flex-direction: column; 2219 + gap: 12px; 2220 + margin: 12px 0 0 0; 2221 + } 2222 + 2223 + .message.s-azdpbr { 2224 + border: 1px solid var(--divider); 2225 + border-radius: 6px; 2226 + padding: 12px; 2227 + color: var(--text-secondary); 2228 + } 2229 + 2230 + .rich-text.s-1lecfnd { 2231 + overflow: hidden; 2232 + white-space: pre-wrap; 2233 + overflow-wrap: break-word; 2234 + 2235 + &:empty { 2236 + display: none; 2237 + } 2238 + } 2239 + .is-large.s-1lecfnd { 2240 + font-size: calc(var(--font-size) * 1); 2241 + line-height: calc(var(--font-size) * 1.5); 2242 + } 2243 + 2244 + .link.s-1lecfnd, 2245 + .mention.s-1lecfnd, 2246 + .hashtag.s-1lecfnd { 2247 + color: var(--text-link); 2248 + 2249 + &:hover { 2250 + text-decoration: underline; 2251 + } 2252 + } 2253 + 2254 + .highlighted-post.s-hik11q { 2255 + padding: 16px; 2256 + } 2257 + 2258 + .meta.s-hik11q { 2259 + display: flex; 2260 + align-items: center; 2261 + gap: 12px; 2262 + margin: 0 0 12px 0; 2263 + color: var(--text-secondary); 2264 + } 2265 + 2266 + .avatar-wrapper.s-hik11q { 2267 + display: block; 2268 + flex-shrink: 0; 2269 + border-radius: 9999px; 2270 + background: var(--background-secondary); 2271 + width: 40px; 2272 + height: 40px; 2273 + overflow: hidden; 2274 + 2275 + &:hover { 2276 + filter: brightness(0.85); 2277 + } 2278 + } 2279 + 2280 + .avatar.s-hik11q { 2281 + width: 100%; 2282 + height: 100%; 2283 + object-fit: cover; 2284 + } 2285 + .is-blurred.s-hik11q { 2286 + scale: 125%; 2287 + filter: blur(4px); 2288 + } 2289 + 2290 + .name-wrapper.s-hik11q { 2291 + display: block; 2292 + flex-grow: 1; 2293 + max-width: 100%; 2294 + overflow: hidden; 2295 + color: inherit; 2296 + text-overflow: ellipsis; 2297 + white-space: nowrap; 2298 + } 2299 + .display-name-wrapper.s-hik11q { 2300 + overflow: hidden; 2301 + text-overflow: ellipsis; 2302 + 2303 + .name-wrapper:where(.s-hik11q):hover & { 2304 + text-decoration: underline; 2305 + } 2306 + } 2307 + .display-name.s-hik11q { 2308 + color: var(--text-primary); 2309 + font-weight: 700; 2310 + } 2311 + .handle.s-hik11q { 2312 + display: block; 2313 + overflow: hidden; 2314 + text-overflow: ellipsis; 2315 + white-space: nowrap; 2316 + } 2317 + 2318 + .logo.s-hik11q { 2319 + width: 32px; 2320 + height: 32px; 2321 + } 2322 + 2323 + .context.s-hik11q { 2324 + overflow: hidden; 2325 + color: var(--text-secondary); 2326 + font-size: calc(var(--font-size) * 0.8125); 2327 + text-overflow: ellipsis; 2328 + white-space: nowrap; 2329 + 2330 + a:where(.s-hik11q) { 2331 + color: inherit; 2332 + font-weight: 500; 2333 + 2334 + &:hover { 2335 + text-decoration: underline; 2336 + } 2337 + } 2338 + } 2339 + 2340 + .date.s-hik11q { 2341 + display: flex; 2342 + flex-wrap: wrap; 2343 + align-items: center; 2344 + gap: 8px; 2345 + margin: 12px 0 0; 2346 + border-bottom: 1px solid var(--divider); 2347 + padding: 0 0 12px 0; 2348 + color: var(--text-secondary); 2349 + } 2350 + 2351 + .stats.s-hik11q { 2352 + display: flex; 2353 + flex-wrap: wrap; 2354 + align-items: center; 2355 + gap: 8px 16px; 2356 + margin: 0 0 -16px 0; 2357 + padding: 12px 0; 2358 + color: var(--text-secondary); 2359 + 2360 + .gap:where(.s-hik11q) { 2361 + flex: 1 1 auto; 2362 + } 2363 + 2364 + .permalink:where(.s-hik11q) { 2365 + display: flex; 2366 + align-items: center; 2367 + gap: 4px; 2368 + color: var(--text-link); 2369 + font-weight: 700; 2370 + 2371 + &:hover { 2372 + text-decoration: underline; 2373 + } 2374 + } 2375 + } 2376 + .stat.s-hik11q { 2377 + display: flex; 2378 + align-items: center; 2379 + gap: 8px; 2380 + font-weight: 500; 2381 + } 2382 + 2383 + .post.s-12mzi62 { 2384 + display: flex; 2385 + position: relative; 2386 + gap: 12px; 2387 + padding: 12px 16px 0 16px; 2388 + } 2389 + 2390 + .logo.s-12mzi62 { 2391 + position: absolute; 2392 + top: 12px; 2393 + right: 12px; 2394 + width: 24px; 2395 + height: 24px; 2396 + } 2397 + 2398 + .aside.s-12mzi62 { 2399 + flex-shrink: 0; 2400 + } 2401 + 2402 + .avatar-wrapper.s-12mzi62 { 2403 + display: block; 2404 + border-radius: 9999px; 2405 + background: var(--background-secondary); 2406 + width: 40px; 2407 + height: 40px; 2408 + overflow: hidden; 2409 + 2410 + &:hover { 2411 + filter: brightness(0.85); 2412 + } 2413 + } 2414 + 2415 + .avatar.s-12mzi62 { 2416 + width: 100%; 2417 + height: 100%; 2418 + object-fit: cover; 2419 + } 2420 + .is-blurred.s-12mzi62 { 2421 + scale: 125%; 2422 + filter: blur(4px); 2423 + } 2424 + 2425 + .line.s-12mzi62 { 2426 + position: absolute; 2427 + top: 56px; 2428 + bottom: -12px; 2429 + left: 35px; 2430 + border-left: 2px solid var(--divider); 2431 + } 2432 + 2433 + .main.s-12mzi62 { 2434 + display: flex; 2435 + flex-grow: 1; 2436 + flex-direction: column; 2437 + min-width: 0px; 2438 + } 2439 + 2440 + .meta.s-12mzi62 { 2441 + display: flex; 2442 + align-items: center; 2443 + margin: 0 0 2px 0; 2444 + padding: 0 calc(24px + 8px) 0 0; 2445 + color: var(--text-secondary); 2446 + 2447 + .name-wrapper:where(.s-12mzi62) { 2448 + display: flex; 2449 + gap: 4px; 2450 + max-width: 100%; 2451 + overflow: hidden; 2452 + color: inherit; 2453 + text-decoration: none; 2454 + text-overflow: ellipsis; 2455 + white-space: nowrap; 2456 + } 2457 + 2458 + .display-name-wrapper:where(.s-12mzi62) { 2459 + overflow: hidden; 2460 + text-overflow: ellipsis; 2461 + 2462 + .name-wrapper:where(.s-12mzi62):hover & { 2463 + text-decoration: underline; 2464 + } 2465 + } 2466 + 2467 + .display-name:where(.s-12mzi62) { 2468 + color: var(--text-primary); 2469 + font-weight: 700; 2470 + } 2471 + 2472 + .handle:where(.s-12mzi62) { 2473 + display: block; 2474 + overflow: hidden; 2475 + text-overflow: ellipsis; 2476 + white-space: nowrap; 2477 + } 2478 + 2479 + .dot:where(.s-12mzi62) { 2480 + flex-shrink: 0; 2481 + margin: 0 6px; 2482 + } 2483 + 2484 + .date:where(.s-12mzi62) { 2485 + color: inherit; 2486 + text-decoration: none; 2487 + white-space: nowrap; 2488 + 2489 + &:hover { 2490 + text-decoration: underline; 2491 + } 2492 + } 2493 + } 2494 + 2495 + .context.s-12mzi62 { 2496 + overflow: hidden; 2497 + color: var(--text-secondary); 2498 + font-size: calc(var(--font-size) * 0.8125); 2499 + text-overflow: ellipsis; 2500 + white-space: nowrap; 2501 + 2502 + a:where(.s-12mzi62) { 2503 + color: inherit; 2504 + font-weight: 500; 2505 + 2506 + &:hover { 2507 + text-decoration: underline; 2508 + } 2509 + } 2510 + } 2511 + 2512 + .message.s-1q9cbx0 { 2513 + margin: 0 auto; 2514 + padding: 32px 16px; 2515 + max-width: 380px; 2516 + color: var(--text-secondary); 2517 + text-align: center; 2518 + }