diff --git a/app/assets/stylesheets/attachments.css b/app/assets/stylesheets/attachments.css new file mode 100644 index 000000000..85dc7652d --- /dev/null +++ b/app/assets/stylesheets/attachments.css @@ -0,0 +1,207 @@ +@layer components { + .attachment { + block-size: auto; + display: block; + inline-size: fit-content; + position: relative; + max-inline-size: 100%; + + progress { + inline-size: 100%; + margin: auto; + } + } + + .attachment__caption { + color: color-mix(in oklch, var(--color-ink) 66%, transparent); + font-size: var(--text-small); + + textarea { + --input-border-radius: 0.3em; + --input-border-size: 0; + --input-padding: 0; + + background-color: var(--input-background, transparent); + border: none; + color: inherit; + inline-size: 100%; + max-inline-size: 100%; + resize: none; + text-align: center; + + &:focus { + --focus-ring-size: 0; + } + + @supports (field-sizing: content) { + field-sizing: content; + inline-size: auto; + min-inline-size: 20ch; + } + } + } + + .attachment__icon { + aspect-ratio: 4/5; + background-color: color-mix(var(--attachment-icon-color), transparent 90%); + block-size: 2.5lh; + border: 2px solid var(--attachment-icon-color); + border-block-start-width: 1ch; + border-radius: 0.5ch; + box-sizing: border-box; + color: var(--attachment-icon-color); + display: grid; + font-size: var(--text-small); + font-weight: bold; + inline-size: auto; + padding-inline: 0.5ch; + place-content: center; + text-transform: uppercase; + white-space: nowrap; + } + + .attachment--preview { + margin-inline: auto; + text-align: center; + + img, video { + block-size: auto; + display: block; + margin-inline: auto; + max-inline-size: 100%; + user-select: none; + } + + > a { + display: block; + } + + .attachment__caption { + column-gap: 0.5ch; + display: flex; + flex-wrap: wrap; + justify-content: center; + margin-block-start: 0.5ch; + } + } + + .attachment--file { + --attachment-icon-color: var(--color-ink-medium); + + align-items: center; + display: flex; + flex-wrap: wrap; + gap: 1ch; + inline-size: 100%; + margin-inline: 0; + + .attachment__caption { + display: grid; + flex: 1; + text-align: start; + } + + .attachment__name { + color: var(--color-ink); + font-weight: bold; + } + + /* Video attachments don't have an identifiable class, but we need to + * make sure the caption is always below the video */ + &:has(video) { + .attachment__caption { + flex: none; + inline-size: 100%; + } + } + } + + .attachment--psd, + .attachment--key, + .attachment--sketch, + .attachment--ai, + .attachment--eps, + .attachment--indd, + .attachment--svg, + .attachment--ppt, + .attachment--pptx { + --attachment-icon-color: oklch(var(--lch-red-medium)); + } + + .attachment--css, + .attachment--crash, + .attachment--php, + .attachment--json, + .attachment--htm, + .attachment--html, + .attachment--rb, + .attachment--erb, + .attachment--ts, + .attachment--js { + --attachment-icon-color: oklch(var(--lch-purple-medium)); + } + + .attachment--txt, + .attachment--pages, + .attachment--rtf, + .attachment--md, + .attachment--doc, + .attachment--docx { + --attachment-icon-color: oklch(var(--lch-blue-medium)); + } + + .attachment--csv &, + .attachment--numbers &, + .attachment--xls &, + .attachment--xlsx & { + --attachment-icon-color: oklch(var(--lch-green-medium)); + } + + .attachment__link { + color: var(--color-link); + text-decoration: underline; + } + + /* Custom attachments such as mentions, etc. */ + action-text-attachment[content-type^='application/vnd.actiontext'] { + --attachment-bg-color: transparent; + --attachment-image-size: 1em; + --attachment-text-color: currentColor; + + align-items: center; + background: var(--attachment-bg-color); + border-radius: 99rem; + box-shadow: + -0.25ch 0 0 var(--attachment-bg-color), + 0.5ch 0 0 var(--attachment-bg-color); + color: var(--attachment-text-color); + display: inline-flex; + gap: 0.25ch; + margin: 0; + padding: 0; + position: relative; + vertical-align: bottom; + white-space: normal; + + lexxy-editor & { + cursor: pointer; + } + + img { + block-size: var(--attachment-image-size); + border-radius: 50%; + inline-size: var(--attachment-image-size); + } + + &.node--selected { + --attachment-bg-color: oklch(var(--lch-blue-dark)); + --attachment-text-color: var(--color-ink-inverted); + } + } + + action-text-attachment[content-type^='application/vnd.actiontext.mention'] { + img { + object-fit: cover; + } + } +} diff --git a/app/assets/stylesheets/lexxy.css b/app/assets/stylesheets/lexxy.css index 316d9e4c0..7eb0377ef 100644 --- a/app/assets/stylesheets/lexxy.css +++ b/app/assets/stylesheets/lexxy.css @@ -3,11 +3,13 @@ @import url("lexxy-editor.css") layer(base); @layer components { + /* Editor + /* ------------------------------------------------------------------------ */ + lexxy-editor { --lexxy-border-color: oklch(var(--lch-ink-darkest) / 20%); --lexxy-editor-padding: 0; --lexxy-toolbar-button-size: 2rem; - --lexxy-toolbar-gap: 0; background-color: transparent; border: none; @@ -21,9 +23,35 @@ .lexxy-editor__toolbar-button { background: transparent; + &[aria-pressed="true"] { + background-color: oklch(var(--lch-blue-medium) / 20%); + } + @media(any-hover: hover) { - &:hover { - background-color: color-mix(in srgb, transparent, var(--color-ink) 10%); + &:hover:not([aria-pressed="true"]) { + background-color: oklch(var(--lch-ink-dark) / 20%); + } + } + } + + lexxy-link-dropdown { + --lexxy-toolbar-spacing: 1.5ch; + + max-inline-size: 20rem; + + form { + flex-direction: column; + } + + .lexxy-editor__toolbar-button { + border-radius: 99rem; + + &[type="submit"] { + background-color: var(--color-link); + } + + &[type="button"] { + border: 1px solid var(--color-ink-light); } } } @@ -31,4 +59,51 @@ .lexxy-editor__content { margin-block-start: 0.5lh; } + + .lexxy-code-language-picker { + border-radius: 99rem; + } + + [data-lexical-cursor] { + animation: blink 1s step-end infinite; + block-size: 1lh; + border-inline-start: 1px solid currentColor; + line-height: inherit; + margin-block: 1em; + } + + /* Content + /* ------------------------------------------------------------------------ */ + + .lexxy-content { + --lexxy-content-margin: 0.5lh; + + color: currentColor; + + h1, h2, h3, h4, h5, h6 { + font-weight: 800; + letter-spacing: -0.02ch; + line-height: 1.1; + overflow-wrap: break-word; + text-wrap: balance; + } + + p { + margin: 0; + } + + blockquote { + border-inline-start: 0.25em solid var(--color-ink-lighter); + padding-block: 0; + } + + code { + background: var(--color-canvas); + border: 1px solid var(--color-ink-lighter); + } + + hr { + border-block-end-width: 2px; + } + } } diff --git a/app/assets/stylesheets/rich-text-content.css b/app/assets/stylesheets/rich-text-content.css deleted file mode 100644 index 5111423f9..000000000 --- a/app/assets/stylesheets/rich-text-content.css +++ /dev/null @@ -1,471 +0,0 @@ -@layer components { - :where(.rich-text-content) { - --block-margin: 0.5lh; - - h1, h2, h3, h4, h5, h6 { - display: block; - font-weight: 800; - letter-spacing: -0.02ch; - line-height: 1.1; - margin-block: 0 var(--block-margin); - overflow-wrap: break-word; - text-wrap: balance; - } - - h1 { font-size: 2em; } - h2 { font-size: 1.5em; } - h3 { font-size: 1.17em; } - h4 { font-size: 1em; } - h5 { font-size: 0.83em; } - h6 { font-size: 0.67em; } - - p, ul, ol, dl, blockquote, figure, .attachment { - margin-block: 0 var(--block-margin); - - &:not(lexxy-editor &) { - overflow-wrap: break-word; - text-wrap: pretty; - } - } - - p:has(+ p) { - margin: 0; - } - - ol, ul { - padding-inline-start: 3ch; - } - - ol { - list-style: decimal; - } - - ul { - list-style: disc; - } - - li:has(li) { - list-style: none; - - ol, ul { - margin: 0; - padding-inline-start: 2ch; - } - } - - b, strong, .lexxy-content__bold { - font-weight: 700; - } - - i, em, .lexxy-content__italic { - font-style: italic; - } - - s, .lexxy-content__strikethrough { - text-decoration: line-through; - } - - mark, .lexxy-content__highlight { - background-color: transparent; - color: inherit; - } - - p, blockquote { - letter-spacing: -0.005ch; - } - - /* Avoid extra space due to empty paragraphs */ - p:empty { - display: none; - } - - blockquote { - border-inline-start: 0.25em solid var(--color-ink-lighter); - font-style: italic; - margin: var(--block-margin) 0; - padding-inline-start: 2ch; - } - - img, video, embed, object { - inline-size: auto; - margin-inline: auto; - max-block-size: 32rem; - object-fit: contain; - } - - /* Links should hug media contained within */ - a:has(img), - a:has(video) { - inline-size: fit-content; - margin-inline: auto; - } - - hr { - color: currentColor; - block-size: 0; - border: none; - border-block-end: 2px solid currentColor; - inline-size: 20%; - margin: calc(var(--block-margin) * 2) 0; - } - - .horizontal-divider { - margin: var(--block-margin) 0; - padding-block: var(--block-margin); - } - - /* Code */ - code, pre { - background-color: var(--color-canvas); - border: 1px solid var(--color-ink-lighter); - border-radius: 0.3em; - color: var(--color-ink); - font-family: var(--font-mono); - font-size: 0.85em; - font-weight: 500; - margin-block: var(--block-margin); - padding: 0.1em 0.3em; - - &:is(pre), - &[data-language] { - border-radius: 0.5em; - display: block; - overflow-x: auto; - padding: 0.5lh 2ch; - tab-size: 2; - text-wrap: nowrap; - white-space: pre; - word-break: break-word; - - /* Keywords and attributes */ - .code-token__attr, - .token.atrule, - .token.attr, - .token.keyword { - color: var(--color-code-token__att); - } - - /* Constants, booleans, numbers, properties, tags */ - .code-token__property, - .token.boolean, - .token.constant, - .token.deleted, - .token.number, - .token.property, - .token.symbol, - .token.tag { - color: var(--color-code-token__property); - } - - /* Strings, selectors, and built-in constructs */ - .code-token__selector, - .token.builtin, - .token.char, - .token.inserted, - .token.selector, - .token.string { - color: var(--color-code-token__selector); - } - - /* Comments and meta information */ - .code-token__comment, - .token.cdata, - .token.comment, - .token.doctype, - .token.prolog { - color: var(--color-code-token__comment); - font-style: italic; - } - - /* Operators and symbolic entities */ - .code-token__operator, - .token.entity, - .token.operator, - .token.url { - color: var(--color-code-token__operator); - } - - /* Functions and class names */ - .code-token__function, - .token.class, - .token.class-name, - .token.function { - color: var(--color-code-token__function); - } - - /* Variables, regex, namespaces, important */ - .code-token__variable, - .token.important, - .token.namespace, - .token.regex, - .token.variable { - color: var(--color-code-token__variable); - } - - /* Punctuation */ - .code-token__punctuation, - .token.punctuation { - color: var(--color-code-token__punctuation); - } - } - } - - /* Tables */ - .lexxy-content__table-wrapper { - margin: 0; - margin-block: 1ch; - overflow-x: auto; - } - - table { - border-collapse: collapse; - border-spacing: 0; - inline-size: calc(100% - 0.5ch); - margin: 0.25ch; - - th, - td { - background-color: var(--color-canvas); - border: 1px solid var(--color-ink-light); - font-size: var(--text-small); - min-width: 5ch; - max-width: 50ch; - padding: 0.75ch; - text-align: start; - word-break: normal; - - *:last-child { - margin-block-end: 0; - } - - &.lexxy-content__table-cell--header { - background-color: var(--color-ink-lightest); - font-weight: bold; - } - - *:is(code, pre) { - hyphens: auto; - text-wrap: wrap; - white-space: pre-wrap; - } - } - } - } - - /* Attachments - /* ------------------------------------------------------------------------ */ - - .attachment { - block-size: auto; - display: block; - inline-size: fit-content; - position: relative; - max-inline-size: 100%; - - progress { - inline-size: 100%; - margin: auto; - } - } - - .attachment__caption { - color: color-mix(in oklch, var(--color-ink) 66%, transparent); - font-size: var(--text-small); - - textarea { - --input-border-radius: 0.3em; - --input-border-size: 0; - --input-padding: 0; - - background-color: var(--input-background, transparent); - border: none; - color: inherit; - inline-size: 100%; - max-inline-size: 100%; - resize: none; - text-align: center; - - &:focus { - --focus-ring-size: 0; - } - - @supports (field-sizing: content) { - field-sizing: content; - inline-size: auto; - min-inline-size: 20ch; - } - } - } - - .attachment__icon { - aspect-ratio: 4/5; - background-color: color-mix(var(--attachment-icon-color), transparent 90%); - block-size: 2.5lh; - border: 2px solid var(--attachment-icon-color); - border-block-start-width: 1ch; - border-radius: 0.5ch; - box-sizing: border-box; - color: var(--attachment-icon-color); - display: grid; - font-size: var(--text-small); - font-weight: bold; - inline-size: auto; - padding-inline: 0.5ch; - place-content: center; - text-transform: uppercase; - white-space: nowrap; - } - - .attachment--preview { - margin-inline: auto; - text-align: center; - - img, video { - block-size: auto; - display: block; - margin-inline: auto; - max-inline-size: 100%; - user-select: none; - } - - > a { - display: block; - } - - .attachment__caption { - column-gap: 0.5ch; - display: flex; - flex-wrap: wrap; - justify-content: center; - margin-block-start: 0.5ch; - } - } - - .attachment--file { - --attachment-icon-color: var(--color-ink-medium); - - align-items: center; - display: flex; - flex-wrap: wrap; - gap: 1ch; - inline-size: 100%; - margin-inline: 0; - - .attachment__caption { - display: grid; - flex: 1; - text-align: start; - } - - .attachment__name { - color: var(--color-ink); - font-weight: bold; - } - - /* Video attachments don't have an identifiable class, but we need to - * make sure the caption is always below the video */ - &:has(video) { - .attachment__caption { - flex: none; - inline-size: 100%; - } - } - } - - .attachment--psd, - .attachment--key, - .attachment--sketch, - .attachment--ai, - .attachment--eps, - .attachment--indd, - .attachment--svg, - .attachment--ppt, - .attachment--pptx { - --attachment-icon-color: oklch(var(--lch-red-medium)); - } - - .attachment--css, - .attachment--crash, - .attachment--php, - .attachment--json, - .attachment--htm, - .attachment--html, - .attachment--rb, - .attachment--erb, - .attachment--ts, - .attachment--js { - --attachment-icon-color: oklch(var(--lch-purple-medium)); - } - - .attachment--txt, - .attachment--pages, - .attachment--rtf, - .attachment--md, - .attachment--doc, - .attachment--docx { - --attachment-icon-color: oklch(var(--lch-blue-medium)); - } - - .attachment--csv &, - .attachment--numbers &, - .attachment--xls &, - .attachment--xlsx & { - --attachment-icon-color: oklch(var(--lch-green-medium)); - } - - .attachment__link { - color: var(--color-link); - text-decoration: underline; - } - - /* Custom attachments such as mentions, etc. */ - action-text-attachment[content-type^='application/vnd.actiontext'] { - --attachment-bg-color: transparent; - --attachment-image-size: 1em; - --attachment-text-color: currentColor; - - align-items: center; - background: var(--attachment-bg-color); - border-radius: 99rem; - box-shadow: - -0.25ch 0 0 var(--attachment-bg-color), - 0.5ch 0 0 var(--attachment-bg-color); - color: var(--attachment-text-color); - display: inline-flex; - gap: 0.25ch; - margin: 0; - padding: 0; - position: relative; - vertical-align: bottom; - white-space: normal; - - lexxy-editor & { - cursor: pointer; - } - - img { - block-size: var(--attachment-image-size); - border-radius: 50%; - inline-size: var(--attachment-image-size); - } - - &.node--selected { - --attachment-bg-color: oklch(var(--lch-blue-dark)); - --attachment-text-color: var(--color-ink-inverted); - } - } - - action-text-attachment[content-type^='application/vnd.actiontext.mention'] { - img { - object-fit: cover; - } - } - - [data-lexical-cursor] { - animation: blink 1s step-end infinite; - block-size: 1lh; - border-inline-start: 1px solid currentColor; - line-height: inherit; - margin-block: 1em; - } -} diff --git a/app/views/boards/edit/_publication.html.erb b/app/views/boards/edit/_publication.html.erb index c0f60cd77..b37f0c1ac 100644 --- a/app/views/boards/edit/_publication.html.erb +++ b/app/views/boards/edit/_publication.html.erb @@ -30,7 +30,7 @@ Add an optional description to the public page
<%= tag.span card.title, class: "card__title-link" %>
-