main.css 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920
  1. @font-face {
  2. font-family: 'JetBrains Mono';
  3. font-style: normal;
  4. font-weight: 400;
  5. font-display: swap;
  6. src: url('fonts/JetBrainsMono-Regular.woff2') format('woff2');
  7. }
  8. :root {
  9. font-size: 10px;
  10. --scheme: ;
  11. --bgh: 240;
  12. --bgs: 8%;
  13. --bgl: 9%;
  14. --bghs: var(--bgh), var(--bgs);
  15. --cm: 1;
  16. --tsm: 1;
  17. --widget-gap: 25px;
  18. --widget-content-vertical-padding: 15px;
  19. --widget-content-horizontal-padding: 17px;
  20. --widget-content-padding: var(--widget-content-vertical-padding) var(--widget-content-horizontal-padding);
  21. --content-bounds-padding: 15px;
  22. --border-radius: 5px;
  23. --mobile-navigation-height: 50px;
  24. --color-primary: hsl(43, 50%, 70%);
  25. --color-positive: var(--color-primary);
  26. --color-negative: hsl(0, 70%, 70%);
  27. --color-background: hsl(var(--bghs), var(--bgl));
  28. --color-widget-background-hsl-values: var(--bghs), calc(var(--bgl) + 1%);
  29. --color-widget-background: hsl(var(--color-widget-background-hsl-values));
  30. --color-separator: hsl(var(--bghs), calc(var(--scheme) ((var(--scheme) var(--bgl)) + 4% * var(--cm))));
  31. --color-widget-content-border: hsl(var(--bghs), calc(var(--scheme) (var(--scheme) var(--bgl) + 4%)));
  32. --color-widget-background-highlight: hsl(var(--bghs), calc(var(--scheme) (var(--scheme) var(--bgl) + 4%)));
  33. --color-popover-background: hsl(var(--bgh), calc(var(--bgs) + 3%), calc(var(--bgl) + 3%));
  34. --color-popover-border: hsl(var(--bghs), calc(var(--scheme) (var(--scheme) var(--bgl) + 12%)));
  35. --color-progress-border: hsl(var(--bghs), calc(var(--scheme) ((var(--scheme) var(--bgl)) + 10% * var(--cm))));
  36. --color-progress-value: hsl(var(--bgh), calc(var(--bgs) * var(--tsm)), calc(var(--scheme) ((var(--scheme) var(--bgl)) + 27% * var(--cm))));
  37. --color-graph-gridlines: hsl(var(--bghs), calc(var(--scheme) ((var(--scheme) var(--bgl)) + 6% * var(--cm))));
  38. --ths: var(--bgh), calc(var(--bgs) * var(--tsm));
  39. --color-text-base: hsl(var(--ths), calc(var(--scheme) var(--cm) * 58%));
  40. --color-text-base-muted: hsl(var(--ths), calc(var(--scheme) var(--cm) * 52%));
  41. --color-text-highlight: hsl(var(--ths), calc(var(--scheme) var(--cm) * 85%));
  42. --color-text-subdue: hsl(var(--ths), calc(var(--scheme) var(--cm) * 35%));
  43. --font-size-h1: 1.7rem;
  44. --font-size-h2: 1.6rem;
  45. --font-size-h3: 1.5rem;
  46. --font-size-h4: 1.4rem;
  47. --font-size-base: 1.3rem;
  48. --font-size-h5: 1.2rem;
  49. --font-size-h6: 1.1rem;
  50. }
  51. .light-scheme {
  52. --scheme: 100% -;
  53. }
  54. .page {
  55. height: 100%;
  56. padding-block: var(--widget-gap);
  57. }
  58. .page-content, .page.content-ready .page-loading-container {
  59. display: none;
  60. }
  61. .page.content-ready > .page-content {
  62. display: block;
  63. }
  64. .page-column-small .size-title-dynamic {
  65. font-size: var(--font-size-h4);
  66. }
  67. .page-column-full .size-title-dynamic {
  68. font-size: var(--font-size-h3);
  69. }
  70. .color-primary-if-not-visited:not(:visited) {
  71. color: var(--color-primary);
  72. }
  73. .text-truncate,
  74. .single-line-titles .title
  75. {
  76. overflow: hidden;
  77. text-overflow: ellipsis;
  78. white-space: nowrap;
  79. }
  80. .single-line-titles .title {
  81. display: block;
  82. }
  83. .text-truncate-2-lines, .text-truncate-3-lines {
  84. overflow: hidden;
  85. text-overflow: ellipsis;
  86. display: -webkit-box;
  87. -webkit-box-orient: vertical;
  88. }
  89. .text-truncate-3-lines { line-clamp: 3; -webkit-line-clamp: 3; }
  90. .text-truncate-2-lines { line-clamp: 2; -webkit-line-clamp: 2; }
  91. .visited-indicator:not(.text-truncate)::after,
  92. .visited-indicator.text-truncate::before,
  93. .bookmarks-link:not(.bookmarks-link-no-arrow)::after {
  94. content: '↗';
  95. margin-left: 0.5em;
  96. display: inline-block;
  97. position: relative;
  98. top: 0.15em;
  99. color: var(--color-text-base);
  100. }
  101. .visited-indicator.text-truncate {
  102. direction: rtl;
  103. text-align: left;
  104. }
  105. .visited-indicator:not(:visited)::before, .visited-indicator:not(:visited)::after {
  106. color: var(--color-primary);
  107. }
  108. .page-columns-transitioned .list-with-transition > * { animation: collapsibleItemReveal .25s backwards; }
  109. .list-with-transition > *:nth-child(2) { animation-delay: 30ms; }
  110. .list-with-transition > *:nth-child(3) { animation-delay: 60ms; }
  111. .list-with-transition > *:nth-child(4) { animation-delay: 90ms; }
  112. .list-with-transition > *:nth-child(5) { animation-delay: 120ms; }
  113. .list-with-transition > *:nth-child(6) { animation-delay: 150ms; }
  114. .list-with-transition > *:nth-child(7) { animation-delay: 180ms; }
  115. .list-with-transition > *:nth-child(8) { animation-delay: 210ms; }
  116. .list > *:not(:first-child) {
  117. margin-top: calc(var(--list-half-gap) * 2);
  118. }
  119. .list.list-with-separator > *:not(:first-child) {
  120. margin-top: var(--list-half-gap);
  121. border-top: 1px solid var(--color-separator);
  122. padding-top: var(--list-half-gap);
  123. }
  124. .collapsible-container:not(.container-expanded) > .collapsible-item {
  125. display: none;
  126. }
  127. .collapsible-item {
  128. animation: collapsibleItemReveal .25s backwards;
  129. }
  130. @keyframes collapsibleItemReveal {
  131. from {
  132. opacity: 0;
  133. transform: translateY(10px);
  134. }
  135. }
  136. .expand-toggle-button {
  137. font: inherit;
  138. border: 0;
  139. cursor: pointer;
  140. display: block;
  141. width: 100%;
  142. text-align: left;
  143. color: var(--color-text-base);
  144. text-transform: uppercase;
  145. font-size: var(--font-size-h4);
  146. padding: var(--widget-content-vertical-padding) 0;
  147. background: var(--color-widget-background);
  148. }
  149. .expand-toggle-button.container-expanded {
  150. position: sticky;
  151. /* -1px to hide 1px gap on chrome */
  152. bottom: -1px;
  153. }
  154. .expand-toggle-button-icon {
  155. display: inline-block;
  156. margin-left: 1rem;
  157. position: relative;
  158. top: -.2rem;
  159. }
  160. .expand-toggle-button-icon::before {
  161. content: '';
  162. font-size: 0.8rem;
  163. transform: rotate(90deg);
  164. line-height: 1;
  165. display: inline-block;
  166. transition: transform 0.3s;
  167. }
  168. .expand-toggle-button.container-expanded .expand-toggle-button-icon::before {
  169. transform: rotate(-90deg);
  170. }
  171. .widget-group-header {
  172. overflow-x: auto;
  173. scrollbar-width: thin;
  174. }
  175. .widget-group-title {
  176. background: none;
  177. font: inherit;
  178. border: none;
  179. text-transform: uppercase;
  180. border-bottom: 1px dotted transparent;
  181. cursor: pointer;
  182. flex-shrink: 0;
  183. transition: color .3s, border-color .3s;
  184. color: var(--color-text-subdue);
  185. line-height: calc(1.6em - 1px);
  186. }
  187. .widget-group-title:hover:not(.widget-group-title-current) {
  188. color: var(--color-text-base);
  189. }
  190. .widget-group-title-current {
  191. border-bottom-color: var(--color-text-base-muted);
  192. color: var(--color-text-base);
  193. }
  194. .widget-group-content {
  195. animation: widgetGroupContentEntrance .3s cubic-bezier(0.25, 1, 0.5, 1) backwards;
  196. }
  197. .widget-group-content[data-direction="right"] {
  198. --direction: 5px;
  199. }
  200. .widget-group-content[data-direction="left"] {
  201. --direction: -5px;
  202. }
  203. @keyframes widgetGroupContentEntrance {
  204. from {
  205. opacity: 0;
  206. transform: translateX(var(--direction));
  207. }
  208. }
  209. .widget-group-content:not(.widget-group-content-current) {
  210. display: none;
  211. }
  212. .widget-content:has(.expand-toggle-button:last-child) {
  213. padding-bottom: 0;
  214. }
  215. .cards-grid.collapsible-container + .expand-toggle-button {
  216. text-align: center;
  217. margin-top: 0.5rem;
  218. background-color: var(--color-background);
  219. }
  220. .attachments {
  221. display: flex;
  222. flex-wrap: wrap;
  223. gap: 0.5rem;
  224. }
  225. .attachments > * {
  226. border-radius: var(--border-radius);
  227. padding: 0.1rem 0.5rem;
  228. font-size: var(--font-size-h6);
  229. background-color: var(--color-separator);
  230. }
  231. pre {
  232. font: inherit;
  233. }
  234. ::selection {
  235. background-color: hsl(var(--bghs), calc(var(--scheme) (var(--scheme) var(--bgl) + 20%)));
  236. color: var(--color-text-highlight);
  237. }
  238. ::-webkit-scrollbar-thumb {
  239. background: var(--color-text-subdue);
  240. border-radius: var(--border-radius);
  241. }
  242. ::-webkit-scrollbar {
  243. background: var(--color-background);
  244. height: 5px;
  245. width: 10px;
  246. }
  247. *, *::before, *::after {
  248. box-sizing: border-box;
  249. }
  250. * {
  251. padding: 0;
  252. margin: 0;
  253. }
  254. hr {
  255. border: 0;
  256. height: 1px;
  257. background-color: var(--color-separator);
  258. }
  259. img, svg {
  260. display: block;
  261. max-width: 100%;
  262. }
  263. img[loading=lazy].loaded:not(.finished-transition) {
  264. transition: opacity .4s;
  265. }
  266. img[loading=lazy].cached:not(.finished-transition) {
  267. transition: none;
  268. }
  269. img[loading=lazy]:not(.loaded, .cached) {
  270. opacity: 0;
  271. }
  272. html {
  273. scrollbar-color: var(--color-text-subdue) transparent;
  274. scroll-behavior: smooth;
  275. }
  276. html, body, .body-content {
  277. height: 100%;
  278. }
  279. a {
  280. text-decoration: none;
  281. color: inherit;
  282. overflow-wrap: break-word;
  283. }
  284. ul {
  285. list-style: none;
  286. }
  287. body {
  288. font-size: 1.3rem;
  289. font-family: 'JetBrains Mono', monospace;
  290. font-variant-ligatures: none;
  291. line-height: 1.6;
  292. color: var(--color-text-base);
  293. background-color: var(--color-background);
  294. overflow-y: scroll;
  295. }
  296. .page-column-small {
  297. width: 300px;
  298. flex-shrink: 0;
  299. }
  300. .page-column-full {
  301. width: 100%;
  302. min-width: 0;
  303. }
  304. .page-columns {
  305. display: flex;
  306. gap: var(--widget-gap);
  307. animation: pageColumnsEntrance .3s cubic-bezier(0.25, 1, 0.5, 1) backwards;
  308. }
  309. @keyframes pageColumnsEntrance {
  310. from {
  311. opacity: 0;
  312. transform: translateY(10px);
  313. }
  314. }
  315. .page-loading-container {
  316. height: 100%;
  317. display: flex;
  318. align-items: center;
  319. justify-content: center;
  320. animation: loadingContainerEntrance 200ms backwards;
  321. animation-delay: 150ms;
  322. font-size: 2rem;
  323. }
  324. .page-loading-container > .loading-icon {
  325. translate: 0 -250%;
  326. }
  327. @keyframes loadingContainerEntrance {
  328. from {
  329. opacity: 0;
  330. }
  331. }
  332. .loading-icon {
  333. min-width: 1.5em;
  334. width: 1.5em;
  335. height: 1.5em;
  336. border: 0.25em solid hsl(var(--bghs), calc(var(--scheme) ((var(--scheme) var(--bgl)) + 12%)));
  337. border-top-color: hsl(var(--bghs), calc(var(--scheme) ((var(--scheme) var(--bgl)) + 40%)));
  338. border-radius: 50%;
  339. animation: loadingIconSpin 800ms infinite linear;
  340. }
  341. @keyframes loadingIconSpin {
  342. to {
  343. transform: rotate(360deg);
  344. }
  345. }
  346. .notice-icon {
  347. width: 0.7rem;
  348. height: 0.7rem;
  349. border-radius: 50%;
  350. }
  351. .notice-icon-major {
  352. background: var(--color-negative);
  353. }
  354. .notice-icon-minor {
  355. border: 1px solid var(--color-negative);
  356. }
  357. kbd {
  358. font: inherit;
  359. padding: 0.1rem 0.8rem;
  360. border-radius: var(--border-radius);
  361. border: 2px solid var(--color-widget-background-highlight);
  362. box-shadow: 0 2px 0 var(--color-widget-background-highlight);
  363. user-select: none;
  364. transition: transform .1s, box-shadow .1s;
  365. font-size: var(--font-size-h5);
  366. cursor: pointer;
  367. }
  368. kbd:active {
  369. transform: translateY(2px);
  370. box-shadow: 0 0 0 0 var(--color-widget-background-highlight);
  371. }
  372. .masonry {
  373. display: flex;
  374. gap: var(--widget-gap);
  375. }
  376. .masonry-column {
  377. flex: 1;
  378. display: flex;
  379. flex-direction: column;
  380. }
  381. .popover-container, [data-popover-html] {
  382. display: none;
  383. }
  384. .popover-container {
  385. --triangle-size: 10px;
  386. --triangle-offset: 50%;
  387. --triangle-margin: calc(var(--triangle-size) + 3px);
  388. --entrance-y-offset: 8px;
  389. --entrance-direction: calc(var(--entrance-y-offset) * -1);
  390. z-index: 20;
  391. position: absolute;
  392. padding-top: var(--triangle-margin);
  393. padding-inline: var(--content-bounds-padding);
  394. }
  395. .popover-container.position-above {
  396. --entrance-direction: var(--entrance-y-offset);
  397. padding-top: 0;
  398. padding-bottom: var(--triangle-margin);
  399. }
  400. .popover-frame {
  401. --shadow-properties: 0 15px 20px -10px;
  402. --shadow-color: hsla(var(--bghs), calc(var(--bgl) * 0.2), 0.5);
  403. position: relative;
  404. padding: 10px;
  405. background: var(--color-popover-background);
  406. border: 1px solid var(--color-popover-border);
  407. border-radius: 5px;
  408. animation: popoverFrameEntrance 0.3s backwards cubic-bezier(0.16, 1, 0.3, 1);
  409. box-shadow: var(--shadow-properties) var(--shadow-color);
  410. }
  411. .popover-frame::before {
  412. content: '';
  413. position: absolute;
  414. width: var(--triangle-size);
  415. height: var(--triangle-size);
  416. transform: rotate(45deg);
  417. background-color: var(--color-popover-background);
  418. border-top-left-radius: 2px;
  419. border-left: 1px solid var(--color-popover-border);
  420. border-top: 1px solid var(--color-popover-border);
  421. left: calc(var(--triangle-offset) - (var(--triangle-size) / 2));
  422. top: calc(var(--triangle-size) / 2 * -1 - 1px);
  423. }
  424. .popover-container.position-above .popover-frame::before {
  425. transform: rotate(-135deg);
  426. top: auto;
  427. bottom: calc(var(--triangle-size) / 2 * -1 - 1px);
  428. }
  429. .popover-container.position-above .popover-frame {
  430. --shadow-properties: 0 10px 20px -10px;
  431. }
  432. @keyframes popoverFrameEntrance {
  433. from {
  434. opacity: 0;
  435. transform: translateY(var(--entrance-direction));
  436. }
  437. }
  438. .summary {
  439. width: 100%;
  440. cursor: pointer;
  441. word-spacing: -0.18em;
  442. user-select: none;
  443. list-style: none;
  444. position: relative;
  445. display: flex;
  446. z-index: 1;
  447. }
  448. .details[open] .summary {
  449. margin-bottom: .8rem;
  450. }
  451. .summary::before {
  452. content: "";
  453. position: absolute;
  454. inset: -.3rem -.8rem;
  455. border-radius: var(--border-radius);
  456. background-color: var(--color-widget-background-highlight);
  457. opacity: 0;
  458. transition: opacity 0.2s;
  459. z-index: -1;
  460. }
  461. .details[open] .summary::before, .summary:hover::before {
  462. opacity: 1;
  463. }
  464. .details:not([open]) .list-with-transition {
  465. display: none;
  466. }
  467. .summary::after {
  468. content: "◀";
  469. font-size: 1.2em;
  470. position: absolute;
  471. top: 0;
  472. bottom: 0;
  473. line-height: 1.3em;
  474. right: 0;
  475. transition: rotate .5s cubic-bezier(0.22, 1, 0.36, 1);
  476. }
  477. details[open] .summary::after {
  478. rotate: -90deg;
  479. }
  480. .content-bounds {
  481. max-width: 1600px;
  482. width: 100%;
  483. margin-inline: auto;
  484. padding: 0 var(--content-bounds-padding);
  485. }
  486. .page-width-wide .content-bounds {
  487. max-width: 1920px;
  488. }
  489. .page-width-slim .content-bounds {
  490. max-width: 1100px;
  491. }
  492. .page-center-vertically .page {
  493. display: flex;
  494. justify-content: center;
  495. flex-direction: column;
  496. }
  497. /* TODO: refactor, otherwise I hope I never have to change dynamic columns again */
  498. .dynamic-columns {
  499. --list-half-gap: 0.5rem;
  500. gap: var(--widget-content-vertical-padding) var(--widget-content-horizontal-padding);
  501. display: grid;
  502. grid-template-columns: repeat(var(--columns-per-row), 1fr);
  503. }
  504. .dynamic-columns > * {
  505. padding-left: var(--widget-content-horizontal-padding);
  506. border-left: 1px solid var(--color-separator);
  507. min-width: 0;
  508. }
  509. .dynamic-columns > *:first-child {
  510. padding-top: 0;
  511. border-top: none;
  512. border-left: none;
  513. }
  514. .dynamic-columns:has(> :nth-child(1)) { --columns-per-row: 1; }
  515. .dynamic-columns:has(> :nth-child(2)) { --columns-per-row: 2; }
  516. .dynamic-columns:has(> :nth-child(3)) { --columns-per-row: 3; }
  517. .dynamic-columns:has(> :nth-child(4)) { --columns-per-row: 4; }
  518. .dynamic-columns:has(> :nth-child(5)) { --columns-per-row: 5; }
  519. @container widget (max-width: 599px) {
  520. .dynamic-columns { gap: 0; }
  521. .dynamic-columns:has(> :nth-child(1)) { --columns-per-row: 1; }
  522. .dynamic-columns > * {
  523. border-left: none;
  524. padding-left: 0;
  525. }
  526. .dynamic-columns > *:not(:first-child) {
  527. margin-top: calc(var(--list-half-gap) * 2);
  528. }
  529. .dynamic-columns.list-with-separator > *:not(:first-child) {
  530. margin-top: var(--list-half-gap);
  531. border-top: 1px solid var(--color-separator);
  532. padding-top: var(--list-half-gap);
  533. }
  534. }
  535. @container widget (min-width: 600px) and (max-width: 849px) {
  536. .dynamic-columns:has(> :nth-child(2)) { --columns-per-row: 2; }
  537. .dynamic-columns > :nth-child(2n-1) {
  538. border-left: none;
  539. padding-left: 0;
  540. }
  541. }
  542. @container widget (min-width: 850px) and (max-width: 1249px) {
  543. .dynamic-columns:has(> :nth-child(3)) { --columns-per-row: 3; }
  544. .dynamic-columns > :nth-child(3n+1) {
  545. border-left: none;
  546. padding-left: 0;
  547. }
  548. }
  549. @container widget (min-width: 1250px) and (max-width: 1499px) {
  550. .dynamic-columns:has(> :nth-child(4)) { --columns-per-row: 4; }
  551. .dynamic-columns > :nth-child(4n+1) {
  552. border-left: none;
  553. padding-left: 0;
  554. }
  555. }
  556. @container widget (min-width: 1500px) {
  557. .dynamic-columns:has(> :nth-child(5)) { --columns-per-row: 5; }
  558. .dynamic-columns > :nth-child(5n+1) {
  559. border-left: none;
  560. padding-left: 0;
  561. }
  562. }
  563. .cards-vertical {
  564. flex-direction: column;
  565. }
  566. .cards-horizontal {
  567. --cards-per-row: 6.5;
  568. }
  569. .cards-horizontal, .cards-vertical {
  570. --cards-gap: calc(var(--widget-content-vertical-padding) * 0.7);
  571. display: flex;
  572. gap: var(--cards-gap);
  573. }
  574. .card {
  575. display: flex;
  576. flex-direction: column;
  577. }
  578. .cards-horizontal .card {
  579. flex-shrink: 0;
  580. width: calc(100% / var(--cards-per-row) - var(--cards-gap) * (var(--cards-per-row) - 1) / var(--cards-per-row));
  581. }
  582. .cards-grid .card {
  583. min-width: 0;
  584. }
  585. .cards-horizontal {
  586. overflow-x: auto;
  587. scrollbar-width: thin;
  588. padding-bottom: 1rem;
  589. }
  590. .cards-grid {
  591. --cards-per-row: 6;
  592. display: grid;
  593. grid-template-columns: repeat(var(--cards-per-row), 1fr);
  594. gap: calc(var(--widget-content-vertical-padding) * 0.7);
  595. }
  596. @container widget (max-width: 1300px) { .cards-horizontal { --cards-per-row: 5.5; } }
  597. @container widget (max-width: 1100px) { .cards-horizontal { --cards-per-row: 4.5; } }
  598. @container widget (max-width: 850px) { .cards-horizontal { --cards-per-row: 3.5; } }
  599. @container widget (max-width: 750px) { .cards-horizontal { --cards-per-row: 3.5; } }
  600. @container widget (max-width: 650px) { .cards-horizontal { --cards-per-row: 2.5; } }
  601. @container widget (max-width: 450px) { .cards-horizontal { --cards-per-row: 2.3; } }
  602. @container widget (max-width: 1300px) { .cards-grid { --cards-per-row: 5; } }
  603. @container widget (max-width: 1100px) { .cards-grid { --cards-per-row: 4; } }
  604. @container widget (max-width: 850px) { .cards-grid { --cards-per-row: 3; } }
  605. @container widget (max-width: 750px) { .cards-grid { --cards-per-row: 3; } }
  606. @container widget (max-width: 650px) { .cards-grid { --cards-per-row: 2; } }
  607. .widget-small-content-bounds {
  608. max-width: 350px;
  609. margin: 0 auto;
  610. }
  611. .widget-error-header {
  612. display: flex;
  613. align-items: center;
  614. justify-content: space-between;
  615. position: relative;
  616. margin-bottom: 1.8rem;
  617. z-index: 1;
  618. }
  619. .widget-error-header::before {
  620. content: '';
  621. position: absolute;
  622. inset: calc(0rem - (var(--widget-content-vertical-padding) / 2)) calc(0rem - (var(--widget-content-horizontal-padding) / 2));
  623. background: var(--color-negative);
  624. opacity: 0.05;
  625. border-radius: var(--border-radius);
  626. z-index: -1;
  627. }
  628. .widget-error-icon {
  629. width: 2.4rem;
  630. height: 2.4rem;
  631. flex-shrink: 0;
  632. stroke: var(--color-negative);
  633. opacity: 0.6;
  634. }
  635. .widget-content {
  636. container-type: inline-size;
  637. container-name: widget;
  638. }
  639. .widget-content:not(.widget-content-frameless) {
  640. padding: var(--widget-content-padding);
  641. }
  642. .widget-content:not(.widget-content-frameless), .widget-content-frame {
  643. background: var(--color-widget-background);
  644. border-radius: var(--border-radius);
  645. border: 1px solid var(--color-widget-content-border);
  646. box-shadow: 0px 3px 0px 0px hsl(var(--bghs), calc(var(--scheme) (var(--scheme) var(--bgl)) - 0.5%));
  647. }
  648. .padding-widget {
  649. padding: var(--widget-content-padding);
  650. }
  651. .margin-bottom-widget {
  652. margin-bottom: var(--widget-content-vertical-padding);
  653. }
  654. .padding-block-widget {
  655. padding-block: var(--widget-content-vertical-padding);
  656. }
  657. .padding-inline-widget {
  658. padding-inline: var(--widget-content-horizontal-padding);
  659. }
  660. .widget-header {
  661. padding: 0 calc(var(--widget-content-horizontal-padding) + 1px);
  662. font-size: var(--font-size-h4);
  663. margin-bottom: 0.9rem;
  664. display: flex;
  665. align-items: center;
  666. gap: 1rem;
  667. }
  668. .widget + .widget {
  669. margin-top: var(--widget-gap);
  670. }
  671. .list-horizontal-text {
  672. display: flex;
  673. list-style: none;
  674. flex-wrap: wrap;
  675. align-items: center;
  676. }
  677. .list-horizontal-text > *:not(:last-child)::after {
  678. content: '•';
  679. color: var(--color-text-subdue);
  680. margin: 0 0.5rem;
  681. position: relative;
  682. top: 0.1rem;
  683. }
  684. .header-container {
  685. margin-top: calc(var(--widget-gap) / 2);
  686. --header-height: 45px;
  687. --header-items-gap: 2.5rem;
  688. }
  689. .header {
  690. display: flex;
  691. height: var(--header-height);
  692. gap: var(--header-items-gap);
  693. }
  694. .logo {
  695. height: 100%;
  696. line-height: var(--header-height);
  697. font-size: 2rem;
  698. color: var(--color-text-highlight);
  699. border-right: 1px solid var(--color-widget-content-border);
  700. padding-right: var(--widget-content-horizontal-padding);
  701. }
  702. .logo:has(img) {
  703. display: flex;
  704. align-items: center;
  705. }
  706. .logo img {
  707. max-height: 2.7rem;
  708. }
  709. .nav {
  710. height: 100%;
  711. gap: var(--header-items-gap);
  712. }
  713. .nav .nav-item {
  714. line-height: var(--header-height);
  715. }
  716. .footer {
  717. padding-bottom: calc(var(--widget-gap) * 1.5);
  718. padding-top: calc(var(--widget-gap) / 2);
  719. animation: loadingContainerEntrance 200ms backwards;
  720. animation-delay: 150ms;
  721. }
  722. .mobile-navigation, .mobile-reachability-header {
  723. display: none;
  724. }
  725. .nav-item {
  726. display: block;
  727. height: 100%;
  728. border-bottom: 2px solid transparent;
  729. transition: color .3s, border-color .3s;
  730. font-size: var(--font-size-h3);
  731. flex-shrink: 0;
  732. }
  733. .nav-item:not(.nav-item-current):hover {
  734. border-bottom-color: var(--color-text-subdue);
  735. color: var(--color-text-highlight);
  736. }
  737. .nav-item.nav-item-current {
  738. border-bottom-color: var(--color-primary);
  739. color: var(--color-text-highlight);
  740. }
  741. .release-source-icon {
  742. width: 16px;
  743. height: 16px;
  744. flex-shrink: 0;
  745. opacity: 0.4;
  746. }
  747. .market-chart {
  748. margin-left: auto;
  749. width: 6.5rem;
  750. flex-shrink: 0;
  751. }
  752. .market-chart svg {
  753. width: 100%;
  754. }
  755. .market-values {
  756. min-width: 8rem;
  757. }
  758. .carousel-container {
  759. position: relative;
  760. }
  761. .carousel-container::before, .carousel-container::after {
  762. content: '';
  763. position: absolute;
  764. width: 2rem;
  765. top: 0;
  766. bottom: 1rem;
  767. z-index: 10;
  768. opacity: 0;
  769. pointer-events: none;
  770. transition-duration: 0.2s;
  771. }
  772. .carousel-container::before {
  773. left: 0;
  774. background: linear-gradient(to right, var(--color-background), transparent);
  775. }
  776. .carousel-container::after {
  777. right: 0;
  778. background: linear-gradient(to left, var(--color-background), transparent);
  779. }
  780. .carousel-container.show-left-cutoff::before, .carousel-container.show-right-cutoff::after {
  781. opacity: 1;
  782. }
  783. .video-thumbnail {
  784. width: 100%;
  785. aspect-ratio: 16 / 8.9;
  786. object-fit: cover;
  787. border-radius: var(--border-radius) var(--border-radius) 0 0;
  788. }
  789. .search-icon {
  790. width: 2.3rem;
  791. }
  792. .search-icon-container {
  793. position: relative;
  794. flex-shrink: 0;
  795. }
  796. /* gives a wider hit area for the 3 people that will notice the animation : ) */
  797. .search-icon-container::before {
  798. content: '';
  799. position: absolute;
  800. inset: -1rem;
  801. }
  802. .search-icon-container:hover > .search-icon {
  803. animation: searchIconHover 2.9s forwards;
  804. }
  805. @keyframes searchIconHover {
  806. 0%, 39% { translate: 0 0; }
  807. 20% { scale: 1.3; }
  808. 40% { scale: 1; }
  809. 50% { translate: -30% 30%; }
  810. 70% { translate: 30% -30%; }
  811. 90% { translate: -30% -30%; }
  812. 100% { translate: 0 0; }
  813. }
  814. .search {
  815. transition: border-color .2s;
  816. position: relative;
  817. }
  818. .search:hover {
  819. border-color: var(--color-text-subdue);
  820. }
  821. .search:focus-within {
  822. border-color: var(--color-primary);
  823. }
  824. .search-input {
  825. border: 0;
  826. background: none;
  827. width: 100%;
  828. height: 6rem;
  829. font: inherit;
  830. outline: none;
  831. color: var(--color-text-highlight);
  832. }
  833. .search-input::placeholder {
  834. color: var(--color-text-base-muted);
  835. opacity: 1;
  836. }
  837. .search-bangs { display: none; }
  838. .search-bang {
  839. border-radius: calc(var(--border-radius) * 2);
  840. background: var(--color-widget-background-highlight);
  841. padding: 0.3rem 1rem;
  842. flex-shrink: 0;
  843. font-size: var(--font-size-h5);
  844. animation: searchBangsEntrance .3s cubic-bezier(0.25, 1, 0.5, 1) backwards;
  845. }
  846. @keyframes searchBangsEntrance {
  847. 0% {
  848. opacity: 0;
  849. transform: translateX(-10px);
  850. }
  851. }
  852. .search-bang:empty {
  853. display: none;
  854. }
  855. .forum-post-list-item {
  856. display: flex;
  857. gap: 1.2rem;
  858. }
  859. .forum-post-list-thumbnail {
  860. flex-shrink: 0;
  861. width: 6rem;
  862. height: 4.1rem;
  863. border-radius: var(--border-radius);
  864. object-fit: cover;
  865. border: 1px solid var(--color-separator);
  866. margin-top: 0.1rem;
  867. }
  868. .forum-post-tags-container {
  869. transform: translateY(-0.15rem);
  870. }
  871. .bookmarks-group {
  872. --bookmarks-group-color: var(--color-primary);
  873. }
  874. .bookmarks-group-title {
  875. color: var(--bookmarks-group-color);
  876. }
  877. .bookmarks-group .bookmarks-link::after {
  878. color: var(--bookmarks-group-color);
  879. }
  880. .bookmarks-icon-container {
  881. margin-block: 0.1rem;
  882. background-color: var(--color-widget-background-highlight);
  883. border-radius: var(--border-radius);
  884. padding: 0.5rem;
  885. opacity: 0.7;
  886. flex-shrink: 0;
  887. }
  888. .bookmarks-icon {
  889. width: 20px;
  890. height: 20px;
  891. opacity: 0.8;
  892. }
  893. :root:not(.light-scheme) .flat-icon {
  894. filter: invert(1);
  895. }
  896. .calendar-day {
  897. width: calc(100% / 7);
  898. text-align: center;
  899. display: flex;
  900. flex-direction: column;
  901. align-items: center;
  902. padding: 0.6rem 0;
  903. }
  904. .calendar-day-today {
  905. border-radius: var(--border-radius);
  906. background-color: hsl(
  907. var(--bghs),
  908. calc(var(--scheme) (var(--scheme) (var(--bgl)) + 6%))
  909. );
  910. color: var(--color-text-highlight);
  911. }
  912. .calendar-isevent {
  913. color: var(--color-primary);
  914. cursor: pointer;
  915. }
  916. .tooltip {
  917. position: relative;
  918. display: inline-block;
  919. width: 0;
  920. height: 0;
  921. }
  922. .tooltiptext {
  923. transition: 0.5s;
  924. }
  925. /* Tooltip text */
  926. .tooltip .tooltiptext {
  927. visibility: hidden;
  928. width: 150px;
  929. background-color: hsl(
  930. var(--bghs),
  931. calc(var(--scheme) (var(--scheme) (var(--bgl)) + 6%))
  932. );
  933. color: var(--color-text-highlight);
  934. text-align: center;
  935. padding: 5px 0;
  936. border-radius: 6px;
  937. opacity: 0;
  938. position: absolute;
  939. z-index: 1;
  940. bottom: 100%;
  941. left: 50%;
  942. margin-bottom: 5px;
  943. margin-left: -75px;
  944. }
  945. .calendar-day:hover .tooltiptext {
  946. visibility: visible;
  947. opacity: 0.8;
  948. }
  949. .dns-stats-totals {
  950. transition: opacity .3s;
  951. transition-delay: 50ms;
  952. }
  953. .dns-stats:has(.dns-stats-graph .popover-active) .dns-stats-totals {
  954. opacity: 0.1;
  955. transition-delay: 0s;
  956. }
  957. .dns-stats-graph {
  958. --graph-height: 70px;
  959. height: var(--graph-height);
  960. position: relative;
  961. margin-bottom: 2.5rem;
  962. }
  963. .dns-stats-graph-gridlines-container {
  964. position: absolute;
  965. inset: 0;
  966. }
  967. .dns-stats-graph-gridlines {
  968. height: 100%;
  969. width: 100%;
  970. }
  971. .dns-stats-graph-columns {
  972. display: flex;
  973. height: 100%;
  974. }
  975. .dns-stats-graph-column {
  976. display: flex;
  977. justify-content: flex-end;
  978. align-items: center;
  979. flex-direction: column;
  980. width: calc(100% / 8);
  981. position: relative;
  982. }
  983. .dns-stats-graph-column::before {
  984. content: '';
  985. position: absolute;
  986. inset: 1px 0;
  987. opacity: 0;
  988. background: var(--color-text-base);
  989. transition: opacity .2s;
  990. }
  991. .dns-stats-graph-column:hover::before {
  992. opacity: 0.05;
  993. }
  994. .dns-stats-graph-bar {
  995. width: 14px;
  996. height: calc((var(--bar-height) / 100) * var(--graph-height));
  997. border: 1px solid var(--color-progress-border);
  998. border-radius: var(--border-radius) var(--border-radius) 0 0;
  999. display: flex;
  1000. background: var(--color-widget-background);
  1001. padding: 2px 2px 0 2px;
  1002. flex-direction: column;
  1003. gap: 2px;
  1004. transition: border-color .2s;
  1005. min-height: 10px;
  1006. }
  1007. .dns-stats-graph-column.popover-active .dns-stats-graph-bar {
  1008. border-color: var(--color-text-subdue);
  1009. border-bottom-color: var(--color-progress-border);
  1010. }
  1011. .dns-stats-graph-bar > * {
  1012. border-radius: 2px;
  1013. background: var(--color-progress-value);
  1014. min-height: 1px;
  1015. }
  1016. .dns-stats-graph-bar > .queries {
  1017. flex-grow: 1;
  1018. }
  1019. .dns-stats-graph-bar > *:last-child {
  1020. border-bottom-right-radius: 0;
  1021. border-bottom-left-radius: 0;
  1022. }
  1023. .dns-stats-graph-bar > .blocked {
  1024. background-color: var(--color-negative);
  1025. }
  1026. .dns-stats-graph-column:nth-child(even) .dns-stats-graph-time {
  1027. opacity: 1;
  1028. transform: translateY(0);
  1029. }
  1030. .dns-stats-graph-time, .dns-stats-graph-columns:hover .dns-stats-graph-time {
  1031. position: absolute;
  1032. font-size: var(--font-size-h6);
  1033. inset-inline: 0;
  1034. text-align: center;
  1035. height: 2.5rem;
  1036. line-height: 2.5rem;
  1037. top: 100%;
  1038. user-select: none;
  1039. opacity: 0;
  1040. transform: translateY(-0.5rem);
  1041. transition: opacity .2s, transform .2s;
  1042. }
  1043. .dns-stats-graph-column:hover .dns-stats-graph-time {
  1044. opacity: 1;
  1045. transform: translateY(0);
  1046. }
  1047. .dns-stats-graph-columns:hover .dns-stats-graph-column:not(:hover) .dns-stats-graph-time {
  1048. opacity: 0;
  1049. }
  1050. .weather-column {
  1051. position: relative;
  1052. display: flex;
  1053. align-items: center;
  1054. justify-content: end;
  1055. flex-direction: column;
  1056. width: calc(100% / 12);
  1057. padding-top: 3px;
  1058. }
  1059. .weather-column-value, .weather-columns:hover .weather-column-value {
  1060. font-size: 13px;
  1061. color: var(--color-text-highlight);
  1062. letter-spacing: -0.1rem;
  1063. margin-right: 0.1rem;
  1064. position: relative;
  1065. margin-bottom: 0.3rem;
  1066. opacity: 0;
  1067. transform: translateY(0.5rem);
  1068. transition: opacity .2s, transform .2s;
  1069. user-select: none;
  1070. }
  1071. .weather-column-current .weather-column-value, .weather-column:hover .weather-column-value {
  1072. opacity: 1;
  1073. transform: translateY(0);
  1074. }
  1075. .weather-column-value::after {
  1076. position: absolute;
  1077. content: '°';
  1078. left: 100%;
  1079. color: var(--color-text-subdue);
  1080. }
  1081. .weather-column-value.weather-column-value-negative::before {
  1082. position: absolute;
  1083. content: '-';
  1084. right: 100%;
  1085. }
  1086. .weather-bar, .weather-columns:hover .weather-bar {
  1087. height: calc(20px + var(--weather-bar-height) * 40px);
  1088. width: 6px;
  1089. background-color: hsl(var(--ths), calc(var(--scheme) ((var(--scheme) var(--bgl)) + 18%)));
  1090. border: 1px solid hsl(var(--ths), calc(var(--scheme) ((var(--scheme) var(--bgl)) + 24%)));
  1091. border-bottom: 0;
  1092. border-radius: 6px 6px 0 0;
  1093. mask-image: linear-gradient(0deg, transparent 0, #000 10px);
  1094. -webkit-mask-image: linear-gradient(0deg, transparent 0, #000 10px);
  1095. transition: background-color .2s, border-color .2s, width .2s;
  1096. }
  1097. .weather-column-current .weather-bar, .weather-column:hover .weather-bar {
  1098. width: 10px;
  1099. background-color: hsl(var(--ths), calc(var(--scheme) ((var(--scheme) var(--bgl)) + 40%)));
  1100. border: 1px solid hsl(var(--ths), calc(var(--scheme) ((var(--scheme) var(--bgl)) + 50%)));
  1101. }
  1102. .weather-column-rain {
  1103. position: absolute;
  1104. inset: 0;
  1105. bottom: 20%;
  1106. overflow: hidden;
  1107. mask-image: linear-gradient(0deg, transparent 40%, #000);
  1108. -webkit-mask-image: linear-gradient(0deg, transparent 40%, #000);
  1109. }
  1110. .weather-column-rain::before {
  1111. content: '';
  1112. position: absolute;
  1113. /* TODO: figure out a way to make it look continuous between columns, right now
  1114. depending on the width of the page the rain inside two columns next to each other
  1115. can overlap and look bad */
  1116. background: radial-gradient(circle at 4px 4px, hsl(200, 90%, 70%, 0.4) 1px, transparent 0);
  1117. background-size: 8px 8px;
  1118. transform: rotate(45deg) translate(-50%, 25%);
  1119. height: 130%;
  1120. aspect-ratio: 1;
  1121. left: 55%;
  1122. }
  1123. .weather-column:nth-child(3) .weather-column-time,
  1124. .weather-column:nth-child(7) .weather-column-time,
  1125. .weather-column:nth-child(11) .weather-column-time {
  1126. opacity: 1;
  1127. transform: translateY(0);
  1128. }
  1129. .weather-column-time, .weather-columns:hover .weather-column-time {
  1130. margin-top: 0.3rem;
  1131. font-size: var(--font-size-h6);
  1132. opacity: 0;
  1133. transform: translateY(-0.5rem);
  1134. transition: opacity .2s, transform .2s;
  1135. user-select: none;
  1136. }
  1137. .weather-column:hover .weather-column-time {
  1138. opacity: 1;
  1139. transform: translateY(0);
  1140. }
  1141. .weather-column-daylight {
  1142. position: absolute;
  1143. inset: 0;
  1144. background: linear-gradient(0deg, transparent 30px, hsl(50, 50%, 30%, 0.2));
  1145. }
  1146. .weather-column-daylight-sunrise {
  1147. border-radius: 20px 0 0 0;
  1148. }
  1149. .weather-column-daylight-sunset {
  1150. border-radius: 0 20px 0 0;
  1151. }
  1152. .location-icon {
  1153. width: 0.8em;
  1154. height: 0.8em;
  1155. border-radius: 0 50% 50% 50%;
  1156. background-color: currentColor;
  1157. transform: rotate(225deg) translate(.1em, .1em);
  1158. position: relative;
  1159. flex-shrink: 0;
  1160. }
  1161. .location-icon::after {
  1162. content: '';
  1163. position: absolute;
  1164. z-index: 2;
  1165. width: .4em;
  1166. height: .4em;
  1167. border-radius: 50%;
  1168. background-color: var(--color-widget-background);
  1169. top: 50%;
  1170. left: 50%;
  1171. transform: translate(-50%, -50%);
  1172. }
  1173. .clock-time {
  1174. min-width: 8ch;
  1175. }
  1176. .clock-time span {
  1177. color: var(--color-text-highlight);
  1178. }
  1179. .monitor-site-icon {
  1180. display: block;
  1181. opacity: 0.8;
  1182. filter: grayscale(0.4);
  1183. object-fit: contain;
  1184. aspect-ratio: 1 / 1;
  1185. width: 3.2rem;
  1186. position: relative;
  1187. top: -0.1rem;
  1188. transition: filter 0.3s, opacity 0.3s;
  1189. }
  1190. .monitor-site-icon.flat-icon {
  1191. opacity: 0.7;
  1192. }
  1193. .monitor-site:hover .monitor-site-icon {
  1194. opacity: 1;
  1195. }
  1196. .monitor-site:hover .monitor-site-icon:not(.flat-icon) {
  1197. filter: grayscale(0);
  1198. }
  1199. .monitor-site-status-icon {
  1200. flex-shrink: 0;
  1201. margin-left: auto;
  1202. width: 2rem;
  1203. height: 2rem;
  1204. }
  1205. .monitor-site-status-icon-compact {
  1206. width: 1.8rem;
  1207. height: 1.8rem;
  1208. flex-shrink: 0;
  1209. }
  1210. .docker-container-icon {
  1211. display: block;
  1212. filter: grayscale(0.4);
  1213. object-fit: contain;
  1214. aspect-ratio: 1 / 1;
  1215. width: 2.7rem;
  1216. opacity: 0.8;
  1217. transition: filter 0.3s, opacity 0.3s;
  1218. }
  1219. .docker-container-icon.flat-icon {
  1220. opacity: 0.7;
  1221. }
  1222. .docker-container:hover .docker-container-icon {
  1223. opacity: 1;
  1224. }
  1225. .docker-container:hover .docker-container-icon:not(.flat-icon) {
  1226. filter: grayscale(0);
  1227. }
  1228. .docker-container-status-icon {
  1229. width: 2rem;
  1230. height: 2rem;
  1231. }
  1232. .thumbnail {
  1233. filter: grayscale(0.2) contrast(0.9);
  1234. opacity: 0.8;
  1235. transition: filter 0.2s, opacity .2s;
  1236. }
  1237. .thumbnail-container {
  1238. flex-shrink: 0;
  1239. border: 1px solid var(--color-separator);
  1240. border-radius: var(--border-radius);
  1241. }
  1242. .thumbnail-container > * {
  1243. border-radius: var(--border-radius);
  1244. object-fit: cover;
  1245. }
  1246. .thumbnail-parent:hover .thumbnail {
  1247. opacity: 1;
  1248. filter: none;
  1249. }
  1250. .rss-card-image {
  1251. height: var(--rss-thumbnail-height, 10rem);
  1252. object-fit: cover;
  1253. border-radius: var(--border-radius) var(--border-radius) 0 0;
  1254. }
  1255. .rss-card-2 {
  1256. position: relative;
  1257. height: var(--rss-card-height, 27rem);
  1258. overflow: hidden;
  1259. }
  1260. .rss-card-2::before {
  1261. content: '';
  1262. position: absolute;
  1263. inset: 0;
  1264. pointer-events: none;
  1265. background-image: linear-gradient(
  1266. 0deg,
  1267. var(--color-widget-background),
  1268. hsla(var(--color-widget-background-hsl-values), 0.8) 6rem, transparent 14rem
  1269. );
  1270. z-index: 2;
  1271. }
  1272. .rss-card-2-image {
  1273. position: absolute;
  1274. width: 100%;
  1275. height: 100%;
  1276. object-fit: cover;
  1277. /* +1px is required to fix some weird graphical bug where the image overflows on the bottom in firefox */
  1278. border-radius: calc(var(--border-radius) + 1px);
  1279. opacity: 0.9;
  1280. z-index: 1;
  1281. }
  1282. .rss-card-2-content {
  1283. position: absolute;
  1284. inset-inline: 0;
  1285. bottom: var(--widget-content-vertical-padding);
  1286. z-index: 3;
  1287. }
  1288. .rss-detailed-description {
  1289. max-width: 55rem;
  1290. color: var(--color-text-base-muted);
  1291. }
  1292. .rss-detailed-thumbnail {
  1293. margin-top: 0.3rem;
  1294. }
  1295. .rss-detailed-thumbnail > * {
  1296. aspect-ratio: 3 / 2;
  1297. height: 8.7rem;
  1298. }
  1299. .twitch-category-thumbnail {
  1300. width: 5rem;
  1301. aspect-ratio: 3 / 4;
  1302. border-radius: var(--border-radius);
  1303. }
  1304. .twitch-channel-avatar {
  1305. aspect-ratio: 1;
  1306. border-radius: 50%;
  1307. }
  1308. .twitch-channel-avatar-container {
  1309. width: 4.4rem;
  1310. height: 4.4rem;
  1311. border: 2px solid var(--color-text-subdue);
  1312. padding: 2px;
  1313. border-radius: 50%;
  1314. position: relative;
  1315. flex-shrink: 0;
  1316. }
  1317. .twitch-channel-live .twitch-channel-avatar-container {
  1318. border: 2px solid var(--color-positive);
  1319. margin-bottom: 1rem;
  1320. }
  1321. .twitch-channel-live .twitch-channel-avatar-container::after {
  1322. content: 'LIVE';
  1323. position: absolute;
  1324. background: var(--color-positive);
  1325. color: var(--color-widget-background);
  1326. font-size: var(--font-size-h6);
  1327. left: 50%;
  1328. bottom: -35%;
  1329. border-radius: var(--border-radius);
  1330. padding-inline: 0.3rem;
  1331. transform: translate(-50%);
  1332. border: 2px solid var(--color-widget-background);
  1333. }
  1334. .twitch-stream-preview {
  1335. max-width: 100%;
  1336. width: 400px;
  1337. aspect-ratio: 16 / 9;
  1338. border-radius: var(--border-radius);
  1339. object-fit: cover;
  1340. }
  1341. .reddit-card-thumbnail {
  1342. width: 100%;
  1343. height: 100%;
  1344. object-fit: cover;
  1345. object-position: 0% 20%;
  1346. opacity: 0.15;
  1347. filter: blur(1px);
  1348. }
  1349. .reddit-card-thumbnail-container {
  1350. position: absolute;
  1351. inset: 0;
  1352. overflow: hidden;
  1353. border-radius: var(--border-radius);
  1354. }
  1355. .reddit-card-thumbnail-container::after {
  1356. content: '';
  1357. position: absolute;
  1358. inset: 0;
  1359. background: linear-gradient(0deg, var(--color-widget-background) 10%, transparent);
  1360. }
  1361. @media (max-width: 1190px) {
  1362. .header-container {
  1363. display: none;
  1364. }
  1365. .page-column-small .size-title-dynamic {
  1366. font-size: var(--font-size-h3);
  1367. }
  1368. .page-column-small {
  1369. width: 100%;
  1370. flex-shrink: 1;
  1371. }
  1372. .page-column {
  1373. display: none;
  1374. animation: columnEntrance .0s cubic-bezier(0.25, 1, 0.5, 1) backwards;
  1375. }
  1376. .page-columns-transitioned .page-column {
  1377. animation-duration: .3s;
  1378. }
  1379. @keyframes columnEntrance {
  1380. from {
  1381. opacity: 0;
  1382. transform: scaleX(0.95);
  1383. }
  1384. }
  1385. .mobile-navigation-offset {
  1386. height: var(--mobile-navigation-height);
  1387. flex-shrink: 0;
  1388. }
  1389. .mobile-navigation {
  1390. display: block;
  1391. position: fixed;
  1392. bottom: 0;
  1393. transform: translateY(calc(100% - var(--mobile-navigation-height)));
  1394. left: var(--content-bounds-padding);
  1395. right: var(--content-bounds-padding);
  1396. z-index: 10;
  1397. background-color: var(--color-widget-background);
  1398. border: 1px solid var(--color-widget-content-border);
  1399. border-bottom: 0;
  1400. border-radius: var(--border-radius) var(--border-radius) 0 0;
  1401. transition: transform .3s;
  1402. }
  1403. .mobile-navigation:has(.mobile-navigation-page-links-input:checked) .hamburger-icon {
  1404. --spacing: 7px;
  1405. color: var(--color-primary);
  1406. height: 2px;
  1407. }
  1408. .mobile-navigation:has(.mobile-navigation-page-links-input:checked) {
  1409. transform: translateY(0);
  1410. }
  1411. .mobile-navigation-page-links {
  1412. border-top: 1px solid var(--color-widget-content-border);
  1413. padding: 15px var(--content-bounds-padding);
  1414. display: flex;
  1415. align-items: center;
  1416. overflow-x: auto;
  1417. scrollbar-width: thin;
  1418. gap: 2.5rem;
  1419. }
  1420. .mobile-navigation-icons {
  1421. display: flex;
  1422. justify-content: space-around;
  1423. align-items: center;
  1424. }
  1425. body:has(.mobile-navigation-input[value="0"]:checked) .page-columns > :nth-child(1),
  1426. body:has(.mobile-navigation-input[value="1"]:checked) .page-columns > :nth-child(2),
  1427. body:has(.mobile-navigation-input[value="2"]:checked) .page-columns > :nth-child(3) {
  1428. display: block;
  1429. }
  1430. .mobile-navigation-label {
  1431. display: flex;
  1432. flex: 1;
  1433. max-width: 50px;
  1434. height: var(--mobile-navigation-height);
  1435. justify-content: center;
  1436. align-items: center;
  1437. cursor: pointer;
  1438. font-size: 15px;
  1439. line-height: var(--mobile-navigation-height);
  1440. }
  1441. .mobile-navigation-pill {
  1442. display: block;
  1443. background: var(--color-text-base);
  1444. height: 10px;
  1445. width: 10px;
  1446. border-radius: 10px;
  1447. transition: width .3s, background-color .3s;
  1448. }
  1449. .mobile-navigation-label:hover > .mobile-navigation-pill {
  1450. background-color: var(--color-text-highlight);
  1451. }
  1452. .mobile-navigation-label:hover {
  1453. color: var(--color-text-highlight);
  1454. }
  1455. .mobile-navigation-input:checked + .mobile-navigation-pill {
  1456. background: var(--color-primary);
  1457. width: 30px;
  1458. }
  1459. .mobile-navigation-input, .mobile-navigation-page-links-input {
  1460. display: none;
  1461. }
  1462. .hamburger-icon {
  1463. --spacing: 4px;
  1464. width: 1em;
  1465. height: 1px;
  1466. background-color: currentColor;
  1467. transition: color .3s, box-shadow .3s;
  1468. box-shadow: 0 calc(var(--spacing) * -1) 0 0 currentColor, 0 var(--spacing) 0 0 currentColor;
  1469. }
  1470. .expand-toggle-button.container-expanded {
  1471. bottom: var(--mobile-navigation-height);
  1472. }
  1473. .cards-grid + .expand-toggle-button.container-expanded {
  1474. /* hides content that peeks through the rounded borders of the mobile navigation */
  1475. box-shadow: 0 var(--border-radius) 0 0 var(--color-background);
  1476. }
  1477. .weather-column-rain::before {
  1478. background-size: 7px 7px;
  1479. }
  1480. .ios .search-input {
  1481. /* so that iOS Safari does not zoom the page when the input is focused */
  1482. font-size: 16px;
  1483. }
  1484. }
  1485. @media (max-width: 1190px) and (display-mode: standalone) {
  1486. :root {
  1487. --safe-area-inset-bottom: env(safe-area-inset-bottom, 0);
  1488. }
  1489. .ios .body-content {
  1490. height: 100dvh;
  1491. }
  1492. .expand-toggle-button.container-expanded {
  1493. bottom: calc(var(--mobile-navigation-height) + var(--safe-area-inset-bottom));
  1494. }
  1495. .mobile-navigation {
  1496. transform: translateY(calc(100% - var(--mobile-navigation-height) - var(--safe-area-inset-bottom)));
  1497. padding-bottom: var(--safe-area-inset-bottom);
  1498. }
  1499. .mobile-navigation-icons {
  1500. padding-bottom: var(--safe-area-inset-bottom);
  1501. transition: padding-bottom .3s;
  1502. }
  1503. .mobile-navigation-offset {
  1504. height: calc(var(--mobile-navigation-height) + var(--safe-area-inset-bottom));
  1505. }
  1506. .mobile-navigation-icons:has(.mobile-navigation-page-links-input:checked) {
  1507. padding-bottom: 0;
  1508. }
  1509. }
  1510. @media (display-mode: standalone) {
  1511. body {
  1512. padding-top: env(safe-area-inset-top, 0);
  1513. }
  1514. }
  1515. @media (max-width: 550px) {
  1516. :root {
  1517. font-size: 9px;
  1518. --widget-gap: 15px;
  1519. --widget-content-vertical-padding: 10px;
  1520. --widget-content-horizontal-padding: 10px;
  1521. --content-bounds-padding: 10px;
  1522. }
  1523. .dynamic-columns:has(> :nth-child(1)) { --columns-per-row: 1; }
  1524. .row-reverse-on-mobile {
  1525. flex-direction: row-reverse;
  1526. }
  1527. .hide-on-mobile, .thumbnail-container:has(> .hide-on-mobile) {
  1528. display: none
  1529. }
  1530. .mobile-reachability-header {
  1531. display: block;
  1532. font-size: 3rem;
  1533. padding: 10vh 1rem;
  1534. text-align: center;
  1535. color: var(--color-text-highlight);
  1536. animation: pageColumnsEntrance .3s cubic-bezier(0.25, 1, 0.5, 1) backwards;
  1537. }
  1538. .rss-detailed-thumbnail > * {
  1539. height: 6rem;
  1540. }
  1541. .rss-detailed-description {
  1542. line-clamp: 3;
  1543. -webkit-line-clamp: 3;
  1544. }
  1545. }
  1546. .size-h1 { font-size: var(--font-size-h1); }
  1547. .size-h2 { font-size: var(--font-size-h2); }
  1548. .size-h3 { font-size: var(--font-size-h3); }
  1549. .size-h4 { font-size: var(--font-size-h4); }
  1550. .size-base { font-size: var(--font-size-base); }
  1551. .size-h5 { font-size: var(--font-size-h5); }
  1552. .size-h6 { font-size: var(--font-size-h6); }
  1553. .color-highlight { color: var(--color-text-highlight); }
  1554. .color-base { color: var(--color-text-base); }
  1555. .color-subdue { color: var(--color-text-subdue); }
  1556. .color-negative { color: var(--color-negative); }
  1557. .color-positive { color: var(--color-positive); }
  1558. .color-primary { color: var(--color-primary); }
  1559. .cursor-help { cursor: help; }
  1560. .break-all { word-break: break-all; }
  1561. .text-left { text-align: left; }
  1562. .text-right { text-align: right; }
  1563. .text-center { text-align: center; }
  1564. .text-elevate { margin-top: -0.2em; }
  1565. .text-compact { word-spacing: -0.18em; }
  1566. .rtl { direction: rtl; }
  1567. .shrink { flex-shrink: 1; }
  1568. .shrink-0 { flex-shrink: 0; }
  1569. .min-width-0 { min-width: 0; }
  1570. .max-width-100 { max-width: 100%; }
  1571. .block { display: block; }
  1572. .inline-block { display: inline-block; }
  1573. .overflow-hidden { overflow: hidden; }
  1574. .relative { position: relative; }
  1575. .flex { display: flex; }
  1576. .flex-wrap { flex-wrap: wrap; }
  1577. .flex-nowrap { flex-wrap: nowrap; }
  1578. .justify-between { justify-content: space-between; }
  1579. .justify-stretch { justify-content: stretch; }
  1580. .justify-evenly { justify-content: space-evenly; }
  1581. .justify-center { justify-content: center; }
  1582. .justify-end { justify-content: end; }
  1583. .uppercase { text-transform: uppercase; }
  1584. .grow { flex-grow: 1; }
  1585. .flex-column { flex-direction: column; }
  1586. .items-center { align-items: center; }
  1587. .items-start { align-items: start; }
  1588. .gap-5 { gap: 0.5rem; }
  1589. .gap-7 { gap: 0.7rem; }
  1590. .gap-10 { gap: 1rem; }
  1591. .gap-12 { gap: 1.2rem; }
  1592. .gap-15 { gap: 1.5rem; }
  1593. .gap-20 { gap: 2rem; }
  1594. .gap-25 { gap: 2.5rem; }
  1595. .gap-35 { gap: 3.5rem; }
  1596. .gap-45 { gap: 4.5rem; }
  1597. .gap-55 { gap: 5.5rem; }
  1598. .margin-left-auto { margin-left: auto; }
  1599. .margin-top-3 { margin-top: 0.3rem; }
  1600. .margin-top-5 { margin-top: 0.5rem; }
  1601. .margin-top-7 { margin-top: 0.7rem; }
  1602. .margin-top-10 { margin-top: 1rem; }
  1603. .margin-top-15 { margin-top: 1.5rem; }
  1604. .margin-top-20 { margin-top: 2rem; }
  1605. .margin-top-25 { margin-top: 2.5rem; }
  1606. .margin-top-35 { margin-top: 3.5rem; }
  1607. .margin-top-40 { margin-top: 4rem; }
  1608. .margin-top-auto { margin-top: auto; }
  1609. .margin-block-3 { margin-block: 0.3rem; }
  1610. .margin-block-5 { margin-block: 0.5rem; }
  1611. .margin-block-7 { margin-block: 0.7rem; }
  1612. .margin-block-8 { margin-block: 0.8rem; }
  1613. .margin-block-10 { margin-block: 1rem; }
  1614. .margin-block-15 { margin-block: 1.5rem; }
  1615. .margin-bottom-3 { margin-bottom: 0.3rem; }
  1616. .margin-bottom-5 { margin-bottom: 0.5rem; }
  1617. .margin-bottom-7 { margin-bottom: 0.7rem; }
  1618. .margin-bottom-10 { margin-bottom: 1rem; }
  1619. .margin-bottom-15 { margin-bottom: 1.5rem; }
  1620. .margin-bottom-auto { margin-bottom: auto; }
  1621. .padding-block-5 { padding-block: 0.5rem; }
  1622. .scale-half { transform: scale(0.5); }
  1623. .list { --list-half-gap: 0rem; }
  1624. .list-gap-2 { --list-half-gap: 0.1rem; }
  1625. .list-gap-4 { --list-half-gap: 0.2rem; }
  1626. .list-gap-8 { --list-half-gap: 0.4rem; }
  1627. .list-gap-10 { --list-half-gap: 0.5rem; }
  1628. .list-gap-14 { --list-half-gap: 0.7rem; }
  1629. .list-gap-20 { --list-half-gap: 1rem; }
  1630. .list-gap-24 { --list-half-gap: 1.2rem; }
  1631. .list-gap-34 { --list-half-gap: 1.7rem; }