@use 'mixins' as *; // ---------- Editor ---------- .editor-page { padding-block: 36px 90px; max-width: 1080px; } .editor-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; margin-bottom: 24px; h1 { margin: 0; font-size: 1.5rem; letter-spacing: -0.025em; font-weight: 800; } } .editor-head-actions { display: flex; gap: 10px; align-items: center; } .field { margin-bottom: 18px; label { display: block; font-size: 0.8rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; color: var(--muted); margin-bottom: 7px; } .hint { text-transform: none; font-weight: 500; letter-spacing: 0; color: var(--faint); } input[type='text'], select { width: 100%; padding: 12px 14px; border-radius: 11px; border: 1px solid var(--border); background: var(--bg-elev); transition: border-color 0.15s, box-shadow 0.2s; } // `input:focus` (not just the styled types) so every field input — // the sign-in popup's password among them — gets the same ring input:focus, select:focus { outline: none; border-color: var(--accent); box-shadow: var(--ring); } input.title-input { font-size: 1.25rem; font-weight: 720; letter-spacing: -0.02em; padding: 14px 16px; } select { cursor: pointer; } } .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; @media (max-width: 640px) { grid-template-columns: 1fr; } } .slug-preview { font-size: 0.8rem; color: var(--faint); margin-top: 6px; code { color: var(--accent); } } // editor body .editor-body { // One height for the writing field and the preview side by side: each holds // its text in a box of this height and scrolls it inside, so a long article // never makes the editor taller than the field the writer is looking at. --editor-pane-h: 480px; border: 1px solid var(--border); border-radius: 15px; background: var(--bg-elev); overflow: hidden; box-shadow: var(--shadow-sm); } .editor-toolbar { display: flex; align-items: center; gap: 4px; padding: 9px 11px; border-bottom: 1px solid var(--border); background: var(--surface); } .mode-btn { padding: 7px 14px; border-radius: 8px; font-size: 0.85rem; font-weight: 620; color: var(--muted); transition: background-color 0.15s, color 0.15s; &:hover { color: var(--text); } &.active { background: var(--surface-2); color: var(--text); box-shadow: inset 0 0 0 1px var(--border); } } .toolbar-actions { margin-left: auto; display: flex; align-items: center; gap: 4px; } .toolbar-icon-btn { display: inline-flex; align-items: center; justify-content: center; padding: 7px 9px; flex: 0 0 auto; } .editor-grid { display: grid; grid-template-columns: 1fr 1fr; height: var(--editor-pane-h); &.mode-write { grid-template-columns: 1fr; .preview-pane { display: none; } } &.mode-preview { grid-template-columns: 1fr; .write-pane { display: none; } } } textarea.md-input { display: block; width: 100%; height: 100%; padding: 22px; border: 0; background: transparent; resize: none; font-size: 0.9rem; line-height: 1.75; tab-size: 2; &:focus { outline: none; } &::placeholder { color: var(--faint); } } .preview-pane { border-left: 1px solid var(--border); padding: 22px 26px; min-width: 0; overflow-y: auto; // and reaching the end of a long preview doesn't start scrolling the page overscroll-behavior: contain; overflow-wrap: break-word; } .preview-label { @include eyebrow; margin-bottom: 14px; } @media (max-width: 900px) { .editor-grid { grid-template-columns: 1fr; height: auto; } // stacked, the two panes keep the height the split gives them — each still // scrolls its own text rather than stretching the editor .write-pane, .preview-pane { height: var(--editor-pane-h); } .preview-pane { border-left: 0 !important; border-top: 1px solid var(--border); } } // editor writing-cheatsheet popup — same shape as the settings modal, // but above the fullscreen editor (z-index 1000) .cheatsheet-overlay { @include overlay(1100, clamp(40px, 10vh, 110px)); } .cheatsheet-modal { @include sheet(680px, min(620px, calc(100vh - 90px))); } .cheatsheet-head { @include sheet-head; } .cheatsheet-title { @include sheet-title; } .cheatsheet-body { @include sheet-body(20px); display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 24px 28px; align-items: start; } .cheatsheet-group-title { @include eyebrow(0.74rem, 750, 0.08em, var(--accent)); margin: 0 0 10px; } .cheat-row { display: flex; align-items: baseline; gap: 10px; font-size: 0.84rem; color: var(--muted); & + & { margin-top: 7px; } code { flex: 0 0 auto; padding: 2px 7px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface-2); color: var(--text); font-size: 0.78rem; } .katex { font-size: 1em; } } @include popup-anim('cheatsheet-popup', '.cheatsheet-modal', 0.18s, transform 0.18s ease, 10px); // discard-changes popup — small sibling of the settings modal, raised above // the fullscreen editor (z-index 1000) .confirm-overlay { @include overlay(1150, clamp(56px, 18vh, 200px)); } .confirm-modal { width: min(430px, 100%); border: 1px solid var(--border); border-radius: 16px; background: var(--bg-elev); box-shadow: var(--shadow-lg); padding: 22px; } .confirm-title { margin: 0; font-size: 1.02rem; font-weight: 700; } .confirm-message { margin: 8px 0 0; font-size: 0.88rem; line-height: 1.55; color: var(--muted); } .confirm-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 22px; } @include popup-anim('confirm-popup', '.confirm-modal', 0.18s, transform 0.18s ease, 10px); // sent-request popup — the discard popup's shape in a success temper: it // confirms a proposal filed with the admins, and closing it ends the edit .sent-check { display: grid; place-items: center; width: 46px; height: 46px; margin-bottom: 14px; border-radius: 50%; background: color-mix(in srgb, var(--success) 14%, transparent); color: var(--success); font-size: 1.3rem; font-weight: 800; } // fullscreen editor .editor-body.is-fullscreen { position: fixed; inset: 0; z-index: 1000; border-radius: 0; border-left: 0; border-right: 0; display: flex; flex-direction: column; .editor-toolbar { flex: 0 0 auto; } .editor-grid { flex: 1; height: auto; min-height: 0; } // the screen decides how tall a pane is here, not --editor-pane-h .write-pane, .preview-pane { height: auto; min-height: 0; overflow-y: auto; } textarea.md-input { height: 100%; min-height: 0; resize: none; } } // below 900px the split stacks vertically — give each pane half the screen @media (max-width: 900px) { .editor-body.is-fullscreen .editor-grid:not(.mode-write):not(.mode-preview) { grid-template-rows: 1fr 1fr; } } .form-error { color: var(--danger); font-size: 0.88rem; margin: 12px 2px 0; }