cab6992555
* main: (32 commits) Fix VCR fixtures Format Touch user on modification to invalidate cache Fix add card not working in the cards screen Submit and refresh results as you type terms Fix: When expanding filters, submitting filters should keep the filters expanded Invalidate cache when filter changes Switch to gpt-5-chat Reorded method and remove unnecessary param Add migration to convert accesses Handle filter toggles with JS Prevent glitch where you see the filter bar expanded when you clear it Remove unused templates Fix: all collections link not working after moving to turbo frame Restore cache I deleted by mistake Speed up filter expansion with turbo stream Fix: filtering collections not working after moving menu to turbo frame Respect params when loading the menu or they won't be reflected! Add HTTP cache for the menu Load main menu lazily with a turbo frame ...
483 lines
11 KiB
CSS
483 lines
11 KiB
CSS
@layer components {
|
|
/* Base
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
.card {
|
|
--avatar-size: 2.75em;
|
|
--card-bg-color: color-mix(in srgb, var(--card-color) 4%, var(--color-canvas));
|
|
--card-padding-inline: var(--inline-space-double);
|
|
--card-padding-block: var(--block-space);
|
|
--border-color: transparent;
|
|
--border-radius: 0.2em;
|
|
--border-size: 0;
|
|
|
|
aspect-ratio: var(--card-aspect-ratio, auto);
|
|
background-color: var(--card-bg-color);
|
|
border-radius: var(--border-radius);
|
|
box-shadow: var(--shadow);
|
|
color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink));
|
|
display: flex;
|
|
flex-direction: column;
|
|
inline-size: 100%;
|
|
padding: var(--card-padding-block) var(--card-padding-inline);
|
|
position: relative;
|
|
text-align: start;
|
|
z-index: 1;
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
box-shadow: 0 0 0 1px var(--color-ink-lighter);
|
|
}
|
|
|
|
.popup {
|
|
inline-size: 260px;
|
|
}
|
|
}
|
|
|
|
/* Header
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
.card__header {
|
|
align-items: center;
|
|
border-radius: var(--border-radius) 0 0 0;
|
|
display: flex;
|
|
flex-wrap: nowrap;
|
|
gap: var(--inline-space);
|
|
margin-block-start: calc(-1 * var(--card-padding-block));
|
|
margin-inline: calc(-1 * var(--card-padding-inline)) calc(-0.5 * var(--card-padding-inline));
|
|
max-inline-size: unset;
|
|
min-inline-size: 0;
|
|
|
|
.workflow-stage {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.card__id {
|
|
flex-shrink: 0;
|
|
margin-inline-start: calc(var(--inline-space) * -1);
|
|
|
|
.card-perma &:before {
|
|
content: "No.";
|
|
opacity: 0.5;
|
|
}
|
|
}
|
|
|
|
.card__collection {
|
|
background-color: var(--card-color);
|
|
border-radius: var(--border-radius) 0 var(--border-radius) 0;
|
|
color: var(--color-ink-inverted);
|
|
display: inline-flex;
|
|
font-weight: 800;
|
|
max-inline-size: 100%;
|
|
min-inline-size: 0;
|
|
padding: var(--block-space-half) var(--inline-space) var(--block-space-half) var(--card-padding-inline);
|
|
|
|
&:has(.collection-picker__button) {
|
|
cursor: pointer;
|
|
transition: background-color 100ms ease-out;
|
|
|
|
@media (any-hover: hover) {
|
|
&:hover {
|
|
background-color: color-mix(in srgb, var(--card-color) 90%, var(--color-ink));
|
|
}
|
|
}
|
|
|
|
&:has(.btn:focus-visible) {
|
|
outline: var(--focus-ring-size) solid var(--focus-ring-color);
|
|
outline-offset: var(--focus-ring-offset);
|
|
}
|
|
}
|
|
}
|
|
|
|
.card__collection-name {
|
|
border-inline-start: 1px solid color-mix(in srgb, var(--color-ink-inverted) 33%, var(--card-color));
|
|
color: currentcolor;
|
|
display: flex;
|
|
margin-inline-start: var(--inline-space-half);
|
|
max-inline-size: 100%;
|
|
min-inline-size: 0;
|
|
padding-inline-start: calc(var(--inline-space) * 0.75);
|
|
text-transform: uppercase;
|
|
|
|
.cards--considering & {
|
|
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__tag {
|
|
color: var(--card-color);
|
|
font-weight: 700;
|
|
}
|
|
|
|
.card__tags {
|
|
align-items: center;
|
|
color: var(--card-color);
|
|
display: flex;
|
|
min-inline-size: 0;
|
|
}
|
|
|
|
/* Body
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
.card__body {
|
|
display: flex;
|
|
flex-grow: 1;
|
|
gap: 1ch;
|
|
inline-size: 100%;
|
|
padding-block: calc(var(--card-padding-block) / 2);
|
|
|
|
@media (min-width: 640px) {
|
|
gap: var(--card-padding-inline);
|
|
}
|
|
}
|
|
|
|
.card__content {
|
|
contain: inline-size;
|
|
flex: 2 1 auto;
|
|
max-inline-size: 100%;
|
|
}
|
|
|
|
.card__title {
|
|
--input-border-radius: 0;
|
|
--input-color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink));
|
|
--lines: 3;
|
|
|
|
color: inherit;
|
|
font-size: var(--text-xx-large);
|
|
font-weight: 900;
|
|
line-height: 1.3;
|
|
text-wrap: balance;
|
|
|
|
@supports not (field-sizing: content) {
|
|
&:has(textarea) {
|
|
text-wrap: unset; /* Safari is annoying if you have text-wrap: balance in textareas */
|
|
}
|
|
}
|
|
|
|
.card-field__title {
|
|
&:is(textarea)::placeholder {
|
|
color: inherit;
|
|
opacity: 0.66;
|
|
}
|
|
}
|
|
|
|
.card__title-link {
|
|
color: inherit;
|
|
}
|
|
}
|
|
|
|
.card__description {
|
|
/* Hide the empty element that Lexical saves when nothing is added to the description <p><br /></p> */
|
|
action-text-content p:only-child:has(br:only-child) {
|
|
display: none;
|
|
}
|
|
|
|
& ~ .btn {
|
|
--btn-background: var(--card-color);
|
|
--btn-color: var(--color-ink-inverted);
|
|
}
|
|
}
|
|
|
|
.card-field__description {
|
|
lexxy-toolbar {
|
|
border-block-start: 1px solid var(--color-ink-light);
|
|
margin-block-start: var(--block-margin) !important;
|
|
}
|
|
}
|
|
|
|
.card__stages {
|
|
display: flex;
|
|
flex: 0 1 auto;
|
|
flex-direction: column;
|
|
justify-self: end;
|
|
max-inline-size: 20ch;
|
|
padding-block: var(--block-space-half);
|
|
}
|
|
|
|
/* Meta
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
.card__meta {
|
|
--meta-border: 1px solid color-mix(in srgb, var(--card-color) 50%, transparent);
|
|
--meta-spacer-block: 0.5ch;
|
|
--meta-spacer-inline: 0.75ch;
|
|
|
|
align-items: center;
|
|
display: grid;
|
|
font-size: var(--text-x-small);
|
|
font-weight: 500;
|
|
grid-template-areas:
|
|
"avatars-author text-added text-updated avatars-assignees"
|
|
"avatars-author text-author text-assignees avatars-assignees";
|
|
grid-template-columns: auto auto 1fr auto;
|
|
inline-size: fit-content;
|
|
text-transform: uppercase;
|
|
|
|
strong,
|
|
.local-time-value {
|
|
font-weight: 900;
|
|
}
|
|
}
|
|
|
|
/* Assign grid areas */
|
|
.card__meta-avatars--author { grid-area: avatars-author; }
|
|
.card__meta-avatars--assignees { grid-area: avatars-assignees; }
|
|
.card__meta-text--added { grid-area: text-added; }
|
|
.card__meta-text--author { grid-area: text-author; }
|
|
.card__meta-text--updated { grid-area: text-updated; }
|
|
.card__meta-text--assignees { grid-area: text-assignees; }
|
|
|
|
.card__meta-avatars {
|
|
align-self: center;
|
|
}
|
|
|
|
.card__meta-avatars--author {
|
|
margin-inline-end: var(--meta-spacer-inline);
|
|
}
|
|
|
|
.card__meta-avatars--assignees {
|
|
display: flex;
|
|
margin-inline-start: var(--meta-spacer-inline);
|
|
|
|
.avatar {
|
|
margin-inline-end: calc(-1 * var(--meta-spacer-inline));
|
|
}
|
|
}
|
|
|
|
.card__meta-text {
|
|
line-height: 1;
|
|
white-space: nowrap;
|
|
|
|
.icon {
|
|
--icon-size: 0.9em;
|
|
|
|
margin-inline-end: 0.5ch;
|
|
vertical-align: top;
|
|
}
|
|
}
|
|
|
|
/* Top */
|
|
.card__meta-text:nth-of-type(odd) {
|
|
border-block-end: var(--meta-border);
|
|
padding-block-end: var(--meta-spacer-block);
|
|
}
|
|
|
|
/* Bottom */
|
|
.card__meta-text:nth-of-type(even) {
|
|
padding-block-start: var(--meta-spacer-block);
|
|
}
|
|
|
|
/* Left */
|
|
.card__meta-text:nth-of-type(-n+2) {
|
|
border-inline-end: var(--meta-border);
|
|
padding-inline-end: var(--meta-spacer-inline);
|
|
}
|
|
|
|
/* Right */
|
|
.card__meta-text:nth-of-type(n+3) {
|
|
padding-inline-start: var(--meta-spacer-inline);
|
|
}
|
|
|
|
@media (max-width: 639px) {
|
|
.card__meta {
|
|
inline-size: 100%;
|
|
}
|
|
|
|
.card__meta-avatars--author,
|
|
.card__meta-avatars--assignees .avatar {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
/* Closed stamp
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
.card__closed {
|
|
--stamp-color: oklch(var(--lch-green-medium) / 0.65);
|
|
|
|
align-items: center;
|
|
background-color: color-mix(in srgb, var(--card-bg-color) 90%, transparent);
|
|
border-radius: 0.2em;
|
|
border: 0.5ch solid var(--stamp-color);
|
|
color: var(--color-ink-dark);
|
|
display: flex;
|
|
flex-direction: column;
|
|
font-weight: bold;
|
|
inset: auto 1ch 1ch auto;
|
|
justify-content: center;
|
|
max-inline-size: 25ch;
|
|
min-inline-size: 16ch;
|
|
padding: 1ch;
|
|
position: absolute;
|
|
rotate: 5deg;
|
|
transform-origin: top right;
|
|
}
|
|
|
|
.card:has(.card__closed),
|
|
.card-perma:has(.card__closed) {
|
|
--card-color: var(--color-card-complete) !important;
|
|
}
|
|
|
|
.card__closed-title {
|
|
color: var(--stamp-color);
|
|
font-size: 1.3em;
|
|
font-weight: 900;
|
|
line-height: 1.2;
|
|
position: relative;
|
|
text-align: center;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.card__closed-date {
|
|
font-family: var(--font-mono);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.card__closed-by {
|
|
border-block-end: 1px dashed currentcolor;
|
|
}
|
|
|
|
/* Misc bits
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
.card__background {
|
|
inset: 0;
|
|
position: absolute;
|
|
z-index: -1;
|
|
|
|
img {
|
|
block-size: 100%;
|
|
border-radius: var(--border-radius);
|
|
inline-size: 100%;
|
|
object-fit: cover;
|
|
object-position: center;
|
|
opacity: 1;
|
|
transition: filter 0.2s ease-in-out, opacity 0.2s ease-in-out;
|
|
}
|
|
}
|
|
|
|
.card__link {
|
|
content: "";
|
|
inset: 0;
|
|
position: absolute;
|
|
z-index: -1;
|
|
}
|
|
|
|
.card:nth-child(2n+1) .bubble { --bubble-rotate: -90deg; }
|
|
.card:nth-child(3n+1) .bubble { --bubble-rotate: 45deg; }
|
|
|
|
/* Variants
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
.card--notification {
|
|
--card-color: var(--color-card-default);
|
|
--card-padding-inline: 1ch;
|
|
--card-padding-block: 1ch;
|
|
|
|
background-color: var(--color-canvas);
|
|
|
|
&.card--closed {
|
|
--card-color: var(--color-card-complete) !important;
|
|
}
|
|
|
|
.card__body {
|
|
padding-block-end: 0;
|
|
}
|
|
|
|
.card__collection {
|
|
font-size: var(--text-xx-small);
|
|
padding-block: 0.5ch;
|
|
padding-inline-start: var(--inline-space-double);
|
|
}
|
|
|
|
.card__header {
|
|
margin-block-start: calc(-1.1 * var(--card-padding-block));
|
|
margin-inline: calc(-1 * var(--card-padding-inline));
|
|
max-inline-size: unset;
|
|
}
|
|
|
|
.card__timestamp {
|
|
opacity: 0.66;
|
|
}
|
|
|
|
.card__notification-body {
|
|
font-size: var(--text-x-small);
|
|
}
|
|
|
|
.card__notification-meta {
|
|
font-size: var(--text-xx-small);
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.card__notification-mentioner {
|
|
background-color: var(--color-highlight);
|
|
border-radius: 0.7em 0.2em 0.7em 0.2em;
|
|
color: inherit;
|
|
display: inline-flex;
|
|
padding: 0.1em 0.3em;
|
|
}
|
|
|
|
.card__title {
|
|
font-size: var(--text-small);
|
|
font-weight: bold;
|
|
min-block-size: 0;
|
|
}
|
|
}
|
|
|
|
.card__notification-unread-indicator {
|
|
--btn-background: var(--color-canvas);
|
|
--btn-border-color: var(--color-canvas);
|
|
--btn-icon-size: 0.75em;
|
|
--btn-padding: 0;
|
|
--btn-size: 1.25em;
|
|
|
|
position: relative;
|
|
z-index: 1;
|
|
|
|
&:before,
|
|
.icon {
|
|
transition: opacity 150ms ease;
|
|
}
|
|
|
|
/* The red dot */
|
|
&:before {
|
|
aspect-ratio: 1;
|
|
background-color: var(--color-marker);
|
|
border-radius: 50%;
|
|
content: "";
|
|
inline-size: 50%;
|
|
inset: 50% auto auto 50%;
|
|
position: absolute;
|
|
translate: -50% -50%;
|
|
}
|
|
|
|
/* The X */
|
|
.icon {
|
|
opacity: 0;
|
|
}
|
|
|
|
@media (hover: hover) {
|
|
.card:hover & {
|
|
--btn-background: transparent;
|
|
|
|
&:before { opacity: 0; }
|
|
.icon { opacity: 1; }
|
|
}
|
|
}
|
|
}
|
|
|
|
.card__collection-public-description {
|
|
max-inline-size: 66ch;
|
|
|
|
p:first-child {
|
|
margin-block-start: 0;
|
|
}
|
|
|
|
p:last-child {
|
|
margin-block-end: 0;
|
|
}
|
|
}
|
|
}
|