Last active
November 19, 2024 15:20
-
-
Save ttscoff/041eccfbdd70c72698ffb570586dbea5 to your computer and use it in GitHub Desktop.
Custom CSS to give linkding a dark, card-based layout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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)); | |
} |
Author
ttscoff
commented
Nov 17, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment