Skip to content

Instantly share code, notes, and snippets.

@ttscoff
Last active November 19, 2024 15:20
Show Gist options
  • Save ttscoff/041eccfbdd70c72698ffb570586dbea5 to your computer and use it in GitHub Desktop.
Save ttscoff/041eccfbdd70c72698ffb570586dbea5 to your computer and use it in GitHub Desktop.
Custom CSS to give linkding a dark, card-based layout
/*
Card-based layout for Linkding
Large images, fully clickable
Entire card selectable in bulk edit mode
Tags moved to expandable sidebar
Author: Brett Terpstra (https://brettterpstra.com)
GitHub: @ttscoff <https://github.com/ttscoff>
License: MIT
*/
body {
--bg: 0, 18, 25;
--fbc-blue-60: rgb(var(--bg));
--fbc-blue-70: rgb(var(--bg));
background: rgb(var(--bg));
}
:root {
--background: 0, 18, 25;
--modal-container-bg-color: rgba(var(--background), 0.95);
--light-color: 255, 255, 255;
--dark-color: 0, 95, 115;
--error: 174, 32, 18;
--hover-color: 10, 147, 150;
--main-color: 148, 210, 189;
--tertiary: 233, 216, 166;
--tertiary-dark: 153, 136, 87;
--alternative-color-dark: var(--primary-text-color);
--alternative-color: var(--primary-text-color);
--bookmark-border-color: #333;
--bookmark-actions-color: rgb(var(--tertiary));
--bookmark-title-color: rgb(var(--light-color));
--bookmark-title-weight: 600;
--btn-primary-bg-color: rgb(var(--dark-color));
--btn-primary-hover-bg-color: rgb(var(--hover-color));
--btn-primary-text-color: rgb(var(--main-color));
--checkbox-bg-color: rgba(var(--dark-color), 0.75);
--control-icon-size: 25px;
--placeholder-color: linear-gradient(
0deg,
hsla(160, 41%, 70%, 1) 0%,
hsla(190, 100%, 23%, 1) 100%
);
--primary-color: rgb(var(--main-color));
--primary-text-color: rgb(var(--main-color));
--secondary-link-color: rgb(var(--tertiary-dark));
--success-color: var(--btn-primary-hover-bg-color);
--error-color: rgb(var(--error));
}
/* Logo */
header h1 {
transform: rotate(-5deg) translate(-7px, -13px);
}
header h1::after {
color: rgba(202, 103, 2, 1);
content: " redux";
left: 0;
opacity: 0.8;
position: absolute;
top: 1em;
}
/* Tag cloud */
.col-1 {
background: rgba(var(--bg), 0.95);
border-radius: 8px 0 0 8px;
border: solid 2px rgba(var(--hover-color), 0.85);
height: calc(100vh - 159px);
left: 100%;
opacity: 0.5;
overflow-y: auto;
padding: 30px;
position: fixed;
top: 149px;
transition: all 0.2s ease-in-out;
width: 60vw;
z-index: 20;
}
section.content-area.col-1 .content-area-header {
background: rgba(var(--bg), 0.95);
border-color: var(--btn-primary-hover-bg-color);
border-color: rgba(var(--hover-color), 0.85);
border-radius: 8px 8px 0 0;
border-style: solid;
border-width: 2px 2px 0 2px;
border-bottom: 0;
cursor: pointer;
display: block;
margin-bottom: 0;
padding: 0 20px;
position: fixed;
transform: rotate(-90deg) translate(-30px, -88px);
}
section.content-area.col-1 .content-area-header:first-of-type {
margin-top: -12px;
}
.col-1 .content-area-header h2 {
color: var(--btn-primary-hover-bg-color);
}
.col-1:hover,
.col-1:focus {
margin-left: -57vw;
opacity: 1;
transition: all 0.2s ease-in-out;
}
:is(.tag-cloud .unselected-tags) a {
border-radius: 15px;
border: solid 1px rgba(var(--dark-color), 0.3);
color: rgb(var(--dark-color));
display: inline-block;
font-weight: 500;
margin: 0 0 0.25em 0 !important;
padding: 0 6px;
}
.tag-cloud .highlight-char {
color: var(--btn-primary-hover-bg-color);
}
:is(.tag-cloud .unselected-tags) a:visited:hover,
:is(.tag-cloud .unselected-tags) a:visited:focus,
:is(.tag-cloud .unselected-tags) a:hover,
:is(.tag-cloud .unselected-tags) a:focus {
background: rgba(var(--main-color), 0.8);
box-shadow: 0 0 4px rgba(var(--main-color), 0.35);
text-decoration: none;
transform: scale(1.1);
transition: all 0.15s ease-in-out;
}
:is(.tag-cloud .unselected-tags) a {
transition: all 0.3s ease-in-out;
}
.tag-cloud a {
font-weight: 500;
}
/* Bookmark cards */
li[ld-bookmark-item] {
background-color: rgba(var(--dark-color), 0.09);
border-radius: 8px;
border: solid 1px var(--bookmark-border-color);
display: block;
gap: 0px 0px;
margin: 0 10px 10px 0;
min-width: 250px;
overflow: hidden;
padding: 210px 10px 10px 10px;
position: relative;
width: 100%;
}
@media screen and (min-width: 770px) {
li[ld-bookmark-item] {
width: 48%;
}
}
@media screen and (min-width: 900px) {
li[ld-bookmark-item] {
width: 32%;
}
}
@media screen and (min-width: 1300px) {
li[ld-bookmark-item] {
width: 24%;
}
}
/* make image clickable */
li[ld-bookmark-item] .title img + a::before {
content: "";
display: block;
height: 250px;
left: -10px;
position: absolute;
top: -250px;
width: 110%;
z-index: 8;
}
li[ld-bookmark-item] .preview-image {
height: 200px;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
li[ld-bookmark-item] .title img {
top: 10px;
transition: transform 0.2s ease-in-out;
}
li[ld-bookmark-item] .title:hover img {
transform: translateY(-50%) scale(1.3);
transition: transform 0.2s ease-in-out;
}
ul.bookmark-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
li[ld-bookmark-item] .title {
background: 0;
}
li[ld-bookmark-item] .content {
display: block;
height: 100%;
max-width: 100%;
padding-bottom: 70px;
position: relative;
width: 100%;
}
li[ld-bookmark-item] .title a {
width: 100%;
}
li[ld-bookmark-item] .url-display,
li[ld-bookmark-item] .url-path {
margin-bottom: 7.3em;
}
.grid {
display: block;
}
.container {
max-width: 100%;
}
/* Make entire card clickable in bulk edit mode */
[ld-bulk-edit] li[ld-bookmark-item] .form-checkbox.bulk-edit-checkbox {
cursor: pointer;
height: 600px;
left: -11px;
top: -212px;
transform: none;
width: 109%;
z-index: 10;
}
:is(li[ld-bookmark-item] .tags) a,
:is(li[ld-bookmark-item] .tags) a:visited:hover {
background: rgba(var(--main-color), 0.15);
border-radius: 15px;
color: rgba(var(--main-color), 1);
font-size: 90%;
padding: 3px 6px;
text-decoration: none;
}
a[data-turbo-frame="details-modal"] {
clear: left;
}
:is(li[ld-bookmark-item] .tags) a:visited:hover,
:is(li[ld-bookmark-item] .tags) a:hover {
background: rgb(var(--dark-color));
color: var(--btn-primary-text-color);
transition: all 0.1s linear;
}
li[ld-bookmark-item] .tags {
margin: 1em 0;
}
/* Preview image */
li[ld-bookmark-item] .preview-image {
border: 0;
border-radius: 0;
margin-top: 0;
background: var(--placeholder-color);
}
.placeholder:is(li[ld-bookmark-item] .preview-image) {
background: var(--placeholder-color);
}
.placeholder:is(li[ld-bookmark-item] .preview-image) .img {
mask: 0;
background-color: transparent;
}
/* Description */
li[ld-bookmark-item] .description {
color: #aaa;
margin: 1em 0;
}
li[ld-bookmark-item] .description.separate {
-webkit-mask-image: linear-gradient(180deg, #000 60%, transparent);
max-height: 4.3em;
position: absolute;
top: 3em;
background: rgba(var(--bg), 0.7);
padding: 5px;
transition: all 0.2s linear;
white-space: wrap;
}
li[ld-bookmark-item] .description.separate:hover {
-webkit-mask-image: linear-gradient(180deg, #000 60%, #000);
max-height: 15em;
transition: all 0.3s ease-in-out;
z-index: 11;
}
/* Actions */
li[ld-bookmark-item] .actions,
li[ld-bookmark-item] .extra-actions {
bottom: 0;
display: block;
left: 0;
position: absolute;
}
:is(li[ld-bookmark-item] .actions) a,
:is(li[ld-bookmark-item] .actions) button.btn-link {
padding: 0 4px;
}
li[ld-bookmark-item] .actions {
bottom: 0;
height: 70px;
margin-top: 10px;
padding-top: 10px;
position: absolute;
width: 100%;
}
:is(li[ld-bookmark-item] .actions) button.btn-link {
border: solid 1px rgba(var(--tertiary-dark), 0.5);
}
.extra-actions {
clear: both;
display: block;
padding-top: 5px;
width: 100%;
}
.actions span {
display: none;
}
.extra-actions .btn {
background: rgba(var(--hover-color), 0.5);
}
:is(li[ld-bookmark-item] .actions) a:first-of-type {
background: 0;
border: 0;
bottom: 0;
color: rgb(var(--dark-color));
margin: 0;
padding: 0 4px 0 0;
position: absolute;
right: 0;
width: auto;
z-index: 10;
}
:is(li[ld-bookmark-item] .actions) a {
background-color: rgb(var(--dark-color));
border-radius: 4px;
color: var(--btn-primary-text-color);
float: left;
margin: 0 4px 4px 0;
padding: 0 4px;
text-align: center;
width: 50px;
}
:is(li[ld-bookmark-item] .actions) a:hover {
background: var(--btn-primary-text-color);
color: rgb(var(--dark-color)) !important;
transition: all 0.1s linear;
}
:is(li[ld-bookmark-item] .actions) button.btn-link {
background: rgba(var(--error), 0.25);
border: solid 1px rgba(var(--error), 0.5);
color: var(--var-error-color);
opacity: 0.6;
}
:is(li[ld-bookmark-item] .actions) button.btn-link:hover {
opacity: 1;
transition: all 0.1s linear;
}
:is(li[ld-bookmark-item] .actions) a:first-of-type:hover {
background-color: transparent;
color: var(--btn-primary-text-color) !important;
transition: color 0.1s linear;
}
:is(li[ld-bookmark-item] .actions .extra-actions) button.btn-link {
background: 0;
border: 0;
color: var(--btn-primary-text-color);
opacity: 0.5;
padding: 0;
}
:is(li[ld-bookmark-item] .actions .extra-actions) button.btn-link:hover,
:is(li[ld-bookmark-item] .actions .extra-actions) button.btn-link:focus {
opacity: 1;
}
:is(li[ld-bookmark-item] .actions) a {
float: left;
}
.actions span.confirmation {
margin-right: 4px;
}
.actions span.confirmation {
display: block;
float: left;
}
.actions span.confirmation .btn {
margin: 0 4px;
margin: 0;
position: relative;
visibility: hidden;
width: 22px;
}
.actions span.confirmation .btn::before {
border-radius: 4px;
border: solid 1px;
color: rgb(148, 210, 189);
content: "\2713";
display: inline-block;
font-size: 150%;
font-weight: 600;
height: 20px;
left: 0;
padding: 0;
position: absolute;
top: 0;
visibility: visible;
width: 20px;
z-index: 1;
}
.actions span.confirmation .btn.mr-1::before {
color: rgb(255, 42, 21);
content: "\00D7";
font-size: 180%;
line-height: 0.65;
}
:is(li[ld-bookmark-item] .actions) button.btn-link {
float: left;
}
/* pagination */
.bookmark-pagination.sticky {
background: rgb(var(--bg));
}
.bookmark-pagination.sticky::before {
background: rgb(var(--bg));
}
@ttscoff
Copy link
Author

ttscoff commented Nov 17, 2024

CleanShot 2024-11-17 at 13 34 41@2x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment