Files
fizzy/app/assets/stylesheets/card-columns.css
T
2025-09-12 16:08:24 -05:00

446 lines
11 KiB
CSS

@layer components {
/* Columns
/* ------------------------------------------------------------------------ */
/* Card contents are resized via container queries. We're using #main here as
the primary container so all cards have the same container reference */
#main:has(.card-columns) {
--cards-gap: min(1.5cqi, 1.5rem);
--gradient-border: linear-gradient(to right,var(--color-canvas), var(--color-ink) 3%, var(--color-ink) 97%, var(--color-canvas));
--reserved-bubble-space: 0;
--bubble-gap: 0.5rem;
--bubble-size: 3.5rem;
container-type: inline-size;
max-inline-size: var(--main-width);
@media (max-width: 639px) {
--bubble-gap: -0.5rem;
--bubble-size: 3rem;
}
}
.card-columns {
margin: auto;
max-inline-size: 100%;
padding-inline: var(--reserved-bubble-space);
position: relative;
transition: 300ms ease-in-out;
&:has(.cards) {
min-block-size: 20lh;
}
&:before {
background: var(--gradient-border);
block-size: 1px;
content: "";
inset: 0 -0.6em 100% -0.6em;
opacity: 0.15;
position: absolute;
z-index: 1;
}
@media (min-width: 640px) {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}
/* Cards
/* ------------------------------------------------------------------------ */
.cards {
align-items: stretch;
display: flex;
flex-direction: column;
gap: var(--cards-gap);
justify-content: start;
padding: 0 var(--cards-gap) var(--cards-gap);
position: relative;
/* Make sure filter dialogs don't end up behind sticky headers */
&:has([open]) {
z-index: 3;
}
@media (max-width: 639px) {
padding-block-end: calc(var(--cards-gap) * 2);
padding-inline-start: var(--cards-gap);
}
.card {
--block-space: 1em;
--block-space-half: 0.5em;
--text-xx-large: 1.6em;
--text-x-small: 1em;
/* Set lower limit for font size */
font-size: clamp(0.6rem, 0.85cqi, 100px);
}
.card__title {
line-height: 1.2;
pointer-events: none;
}
.card__link {
z-index: 1;
}
.card__hide-on-index {
display: none;
}
.card:has(.card__background img:not([src=""])) {
.card__content,
.card__meta,
.workflow-stage:not(.workflow-stage--current) {
opacity: 0;
transition: opacity 0.2s ease-in-out;
@media (any-hover: hover) {
.card:hover & {
opacity: 1;
}
}
}
}
@media (any-hover: hover) {
.card:has(.card__background img:not([src=""])):hover .card__background img:not([src=""]) {
filter: blur(3px) brightness(1.2);
opacity: 0.2;
}
}
.card__steps {
display: flex;
}
}
.cards--related:not(:hover):not(.drag-and-drop__hover-container) {
.card {
box-shadow: 0 0 1px var(--color-ink-medium);
opacity: 0.9;
transition: box-shadow 450ms ease-in-out, opacity 150ms ease-in-out;
@media (prefers-color-scheme: dark) {
opacity: 0.8;
transition: opacity 150ms ease-in-out;
}
}
}
/* Column elements
/* ------------------------------------------------------------------------ */
.cards__heading {
display: flex;
font-size: var(--text-medium);
inset-block-start: 0;
justify-content: center;
margin-block-start: 1px;
margin-inline: -8px; /* enough to cover card shadows, but avoid overlapping bubbles */
padding-block: var(--cards-gap) 0;
position: sticky;
z-index: 3;
/* Cover bubbles and cards on small viewports */
@media (max-width: 639px) {
&:not(.cards--closed &) {
margin-inline: calc(-1 * var(--cards-gap) - var(--reserved-bubble-space) - var(--main-padding));
}
}
&, .cards__filter {
font-weight: bold;
text-transform: uppercase;
}
.cards__filter {
--filter-block-padding: 0.5rem;
background-color: var(--color-canvas);
border-radius: 99rem;
inline-size: auto;
margin-block: calc(-1 * var(--filter-block-padding));
padding-block: var(--filter-block-padding);
}
dialog {
font-weight: normal;
text-transform: none;
}
}
/* Considering
/* ------------------------------------------------------------------------ */
.cards--considering {
background-color: var(--color-canvas);
background-image: linear-gradient(90deg,
transparent 0%,
color-mix(in srgb, var(--color-considering) 25%, transparent) 33%,
color-mix(in srgb, var(--color-considering) 25%, transparent) 66%,
transparent 100%);
padding-block-start: 2em;
@supports(mask: radial-gradient(black)) {
&:before {
background: linear-gradient(90deg,
color-mix(in oklch, var(--color-considering) 0%, transparent) 0%,
color-mix(in oklch, var(--color-considering) 20%, transparent) 25%,
color-mix(in oklch, var(--color-considering) 20%, transparent) 50%,
color-mix(in oklch, var(--color-considering) 0%, transparent) 100%);
content: "";
inset: 0;
mask: radial-gradient(6px at 50% calc(100% + 3px), transparent calc(99% - 2px), black calc(101% - 2px) 99%, transparent 101%) calc(50% - 8px) calc(50% - 3px + .5px)/16px 6px,
radial-gradient(6px at 50% -3px, transparent calc(99% - 2px), black calc(101% - 2px) 99%, transparent 101%) 50% calc(50% + 3px)/16px 6px;
position: absolute;
z-index: 0;
}
}
@media (min-width: 640px) {
padding-inline: var(--cards-gap);
}
.cards__decoration {
--size: 4.25em;
background-color: var(--color-canvas);
background-image: radial-gradient(ellipse at bottom,
color-mix(in srgb, var(--color-considering) 30%, transparent) 0%,
transparent 70%);
block-size: var(--size);
inline-size: 100%;
inset: calc(var(--size) * -1) 0 auto 0;
position: absolute;
z-index: -1;
@supports(mask: radial-gradient(black)) {
&:before {
background: radial-gradient(ellipse at bottom,
color-mix(in srgb, var(--color-considering) 30%, transparent) 0%,
transparent 70%);
content: "";
inset: 0;
mask: radial-gradient(6px at 50% calc(100% + 3px), transparent calc(99% - 2px), black calc(101% - 2px) 99%, transparent 101%) calc(50% - 8px) calc(50% - 3px + .5px)/16px 6px,
radial-gradient(6px at 50% -3px, transparent calc(99% - 2px), black calc(101% - 2px) 99%, transparent 101%) 50% calc(50% + 3px)/16px 6px;
position: absolute;
z-index: 0;
}
}
&.cards__decoration--end {
inset: auto 0 calc(var(--size) * -1);
rotate: 180deg;
}
}
.card {
--avatar-size: 2.75em;
--text-small: 1.1em;
background-color: var(--color-canvas);
line-height: 1.2;
@media (min-width: 640px) {
--text-xx-large: 1.6em;
}
&:nth-child(1n) { rotate: -1deg; }
&:nth-child(1) { rotate: 0deg; }
&:nth-child(2n) { rotate: 1deg; }
&:nth-child(3n) { rotate: -0.5deg; }
&:nth-child(4n) { rotate: 0.5deg; }
}
.card--new {
--border-color: var(--color-selected-dark);
--border-size: 1px;
--card-padding-block: var(--block-space);
border: 1px solid var(--color-selected-dark);
text-align: center;
.btn {
&.btn--link {
font-size: 1.2em;
margin-block-start: 0.1em;
}
&:not(.btn--link) {
border: 0;
color: var(--color-link);
}
}
footer {
font-size: var(--text-x-small);
margin-block-end: calc(var(--block-space-half) * -1);
}
.overflow-count {
font-size: 1.2em;
font-weight: 500;
padding: 0.5em 0.3em;
}
}
.card__body {
padding-block-start: 0;
padding-inline: 0;
}
.card__collection {
background-color: transparent;
color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink));
}
.card__collection-name {
border-inline-start: 1px solid color-mix(in srgb, var(--color-ink) 33%, var(--color-canvas));
color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink));
}
.card--drafted {
--card-color: var(--color-ink-medium) !important;
border-color: var(--card-color) !important;
border-style: dashed !important;
box-shadow: none !important;
}
.card__header {
color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink));
margin-inline: calc(-0.5 * var(--card-padding-inline)) calc(-0.25 * var(--card-padding-inline));
}
.card__people-label {
display: none;
}
.card__title {
min-block-size: 0;
}
.card__tags {
font-size: var(--text-small);
}
}
/* On Deck
/* ------------------------------------------------------------------------ */
.cards--on-deck {
@media (min-width: 640px) {
padding-inline: var(--cards-gap);
}
}
/* Doing
/* ------------------------------------------------------------------------ */
.cards--doing {
@media (min-width: 640px) {
padding-inline: var(--cards-gap);
}
@media (max-width: 639px) {
&::before {
background: var(--gradient-border);
block-size: 1px;
content: "";
inset: 0 0 auto;
opacity: 0.15;
position: absolute;
}
}
}
/* Closed
/* ------------------------------------------------------------------------ */
.cards--closed {
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
inline-size: 100%;
margin: 0 auto;
position: relative;
&:before {
background: var(--gradient-border);
block-size: 1px;
content: "";
inset: 0 -0.6em 100% -0.6em;
opacity: 0.15;
position: absolute;
}
@media (max-width: 639px) {
flex-direction: column;
padding-inline: var(--reserved-bubble-space);
}
.cards__heading {
min-inline-size: 100%;
@media (max-width: 639px) {
margin-inline-end: calc(-1 * var(--cards-gap));
}
}
.card {
@media (min-width: 640px) {
inline-size: calc((100% - var(--cards-gap)) / 2);
}
@media (min-width: 960px) {
inline-size: calc((100% - var(--cards-gap) * 2) / 3);
}
&:nth-of-type(7) {
margin-block-start: var(--cards-gap);
}
&:nth-of-type(n+7) {
background-color: var(--color-canvas);
border: none;
border-block-end: 1px solid var(--color-ink-lighter);
box-shadow: none;
inline-size: 100%;
margin-inline: auto;
max-inline-size: 110ch;
padding: 0 0 var(--cards-gap);
.card__meta,
.card__closed-by-line,
.card__closed-date {
display: none;
}
.card__body {
padding-block-end: 0;
}
.card__closed {
border-width: 0.5ch;
font-size: 0.75em;
inset: auto 0 var(--cards-gap) auto;
rotate: 0deg;
}
.card__header {
margin: 0;
}
.card__title {
min-block-size: 0;
}
}
}
}
}