diff --git a/apps/app/app/assets/css/legal-document.css b/apps/app/app/assets/css/legal-document.css new file mode 100644 index 0000000..896a4d8 --- /dev/null +++ b/apps/app/app/assets/css/legal-document.css @@ -0,0 +1,165 @@ +/* The only prose in the app; the tag set is fixed by shared/utils/legal-markdown.ts. + The class is doubled on purpose: UEditor styles its content with utilities of the same specificity, and the document has to look the same in the editor as on the page. */ +.legal-document.legal-document { + font-size: 0.9375rem; + line-height: 1.7; +} + +.legal-document.legal-document > *:first-child { + margin-top: 0; +} + +.legal-document.legal-document h1 { + font-size: 1.75rem; + font-weight: 600; + letter-spacing: -0.015em; + color: var(--ui-text-highlighted); + margin-bottom: 1.5rem; + padding-bottom: 1rem; + border-bottom: 1px solid var(--ui-border); +} + +.legal-document.legal-document h2 { + font-size: 1.1875rem; + font-weight: 600; + letter-spacing: -0.01em; + color: var(--ui-text-highlighted); + margin-top: 2.5rem; + margin-bottom: 0.75rem; +} + +.legal-document.legal-document h3, +.legal-document.legal-document h4, +.legal-document.legal-document h5, +.legal-document.legal-document h6 { + font-size: 1rem; + font-weight: 600; + color: var(--ui-text-highlighted); + margin-top: 1.75rem; + margin-bottom: 0.5rem; +} + +.legal-document.legal-document p { + margin-top: 0; + margin-bottom: 1rem; +} + +.legal-document.legal-document strong { + font-weight: 600; + color: var(--ui-text-highlighted); +} + +.legal-document.legal-document a { + color: var(--ui-primary); + text-decoration: underline; + text-underline-offset: 3px; + text-decoration-thickness: 1px; +} + +.legal-document.legal-document a:hover { + text-decoration-thickness: 2px; +} + +.legal-document.legal-document ul, +.legal-document.legal-document ol { + margin-top: 0; + margin-bottom: 1rem; + padding-left: 1.5rem; +} + +.legal-document.legal-document ul { + list-style: disc; +} + +.legal-document.legal-document ol { + list-style: decimal; +} + +.legal-document.legal-document li { + margin-top: 0; + margin-bottom: 0.375rem; +} + +.legal-document.legal-document li::marker { + color: var(--ui-text-dimmed); +} + +.legal-document.legal-document blockquote { + border-left: 2px solid var(--ui-border-accented); + padding-left: 1rem; + margin: 1.25rem 0; + color: var(--ui-text-muted); +} + +/* Tiptap wraps cell and list-item content in a paragraph where the published page has bare text; without this the block margins land inside every cell. */ +.legal-document.legal-document :is(th, td, li) > p { + margin: 0; + line-height: inherit; +} + +/* Retention and cookie tables are the reason these documents need tables at all, and they scroll rather than squeezing their columns on a phone. The frame lives on the wrapper because that is the box that scrolls; Tiptap draws one around every table and LegalTable.vue matches it on the published page. */ +.legal-document.legal-document .tableWrapper { + margin-top: 0; + margin-bottom: 1.25rem; + overflow-x: auto; + border: 1px solid var(--ui-border); + border-radius: calc(var(--ui-radius) * 2); +} + +/* Separate borders rather than collapsed ones: collapsed borders leak past the wrapper's rounded corners, so the cells draw the grid instead. */ +.legal-document.legal-document table { + width: 100%; + font-size: 0.875rem; + border-collapse: separate; + border-spacing: 0; +} + +.legal-document.legal-document th, +.legal-document.legal-document td { + padding: 0.5rem 0.75rem; + text-align: left; + vertical-align: top; + border-right: 1px solid var(--ui-border); + border-bottom: 1px solid var(--ui-border); +} + +.legal-document.legal-document tr > *:last-child { + border-right: 0; +} + +.legal-document.legal-document tr:last-child > * { + border-bottom: 0; +} + +.legal-document.legal-document th { + background-color: var(--ui-bg-elevated); + font-weight: 600; + color: var(--ui-text-highlighted); +} + +.legal-document.legal-document code { + font-family: var(--font-mono, ui-monospace, monospace); + font-size: 0.875em; + background-color: var(--ui-bg-elevated); + border-radius: var(--ui-radius); + padding: 0.125rem 0.25rem; +} + +.legal-document.legal-document pre { + margin-top: 0; + background-color: var(--ui-bg-elevated); + border-radius: var(--ui-radius); + padding: 1rem; + overflow-x: auto; + margin-bottom: 1.25rem; +} + +.legal-document.legal-document pre code { + background-color: transparent; + padding: 0; +} + +.legal-document.legal-document hr { + border-top: 1px solid var(--ui-border); + margin: 2rem 0; +} diff --git a/apps/app/app/components/LegalDocument.vue b/apps/app/app/components/LegalDocument.vue index 2f1fa30..f78739b 100644 --- a/apps/app/app/components/LegalDocument.vue +++ b/apps/app/app/components/LegalDocument.vue @@ -1,155 +1,16 @@ - - diff --git a/apps/app/app/components/LegalEditor.client.vue b/apps/app/app/components/LegalEditor.client.vue new file mode 100644 index 0000000..f8dbec7 --- /dev/null +++ b/apps/app/app/components/LegalEditor.client.vue @@ -0,0 +1,126 @@ + + + diff --git a/apps/app/app/components/LegalTable.vue b/apps/app/app/components/LegalTable.vue new file mode 100644 index 0000000..b59508f --- /dev/null +++ b/apps/app/app/components/LegalTable.vue @@ -0,0 +1,11 @@ + + + diff --git a/apps/app/app/pages/admin/legal.vue b/apps/app/app/pages/admin/legal.vue index c135235..a42394d 100644 --- a/apps/app/app/pages/admin/legal.vue +++ b/apps/app/app/pages/admin/legal.vue @@ -1,6 +1,5 @@