Make note cards equal squares and open the editor as a centered modal.

Unify desktop and mobile create/edit into one modal dialog with a consistent grid layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-05 19:59:47 +03:30
co-authored by Cursor
parent f43aa125ea
commit 495b529aaa
+274 -319
View File
@@ -51,7 +51,6 @@ const blobCache = ref<Record<string, string>>({});
const audioDurations = ref<Record<string, string>>({}); const audioDurations = ref<Record<string, string>>({});
const editorOpen = ref(false); const editorOpen = ref(false);
const mobileEditor = ref(false);
const moreSheetOpen = ref(false); const moreSheetOpen = ref(false);
const showChecklistEditor = ref(false); const showChecklistEditor = ref(false);
const editingId = ref<string | null>(null); const editingId = ref<string | null>(null);
@@ -397,7 +396,6 @@ function openEditor(mode: OpenMode = 'default', note?: NoteDto) {
} }
} }
mobileEditor.value = isMobile.value;
editorOpen.value = true; editorOpen.value = true;
moreSheetOpen.value = false; moreSheetOpen.value = false;
@@ -411,7 +409,6 @@ function openEditor(mode: OpenMode = 'default', note?: NoteDto) {
function closeEditor() { function closeEditor() {
editorOpen.value = false; editorOpen.value = false;
mobileEditor.value = false;
moreSheetOpen.value = false; moreSheetOpen.value = false;
resetDraft(); resetDraft();
} }
@@ -836,7 +833,7 @@ onBeforeUnmount(() => {
<button <button
type="button" type="button"
class="note-card add-card desktop-only" class="note-card add-card"
@click="openEditor()" @click="openEditor()"
> >
<UiIcon name="plus" :size="22" /> <UiIcon name="plus" :size="22" />
@@ -880,12 +877,9 @@ onBeforeUnmount(() => {
@change="onFilesSelected($event, 'audio')" @change="onFilesSelected($event, 'audio')"
/> />
<!-- Desktop slide-over (RTL: start = left) --> <!-- Unified create/edit modal -->
<Teleport to="body"> <Teleport to="body">
<div <div v-if="editorOpen" class="panel-root">
v-if="editorOpen && !mobileEditor"
class="panel-root desktop-panel"
>
<div class="panel-backdrop" @click="closeEditor" /> <div class="panel-backdrop" @click="closeEditor" />
<aside <aside
class="editor-panel" class="editor-panel"
@@ -896,9 +890,19 @@ onBeforeUnmount(() => {
> >
<header class="panel-head"> <header class="panel-head">
<h2>{{ editorTitle }}</h2> <h2>{{ editorTitle }}</h2>
<button type="button" class="icon-btn" @click="closeEditor"> <div class="panel-head-actions">
<UiIcon name="x" :size="20" /> <button
</button> type="button"
class="btn-save mobile-only-flex"
:disabled="saving"
@click="saveNote"
>
{{ saving ? '…' : 'ذخیره' }}
</button>
<button type="button" class="icon-btn" @click="closeEditor">
<UiIcon name="x" :size="20" />
</button>
</div>
</header> </header>
<div class="panel-scroll"> <div class="panel-scroll">
@@ -923,21 +927,14 @@ onBeforeUnmount(() => {
:key="sw.value" :key="sw.value"
type="button" type="button"
class="swatch" class="swatch"
:class="[ :class="[`tone-${sw.value}`, { selected: draftColor === sw.value }]"
`tone-${sw.value}`,
{ selected: draftColor === sw.value },
]"
:style="{ backgroundColor: NOTE_COLOR_HEX[sw.value] }" :style="{ backgroundColor: NOTE_COLOR_HEX[sw.value] }"
:title="sw.label" :title="sw.label"
:aria-label="sw.label" :aria-label="sw.label"
:aria-selected="draftColor === sw.value" :aria-selected="draftColor === sw.value"
@click="draftColor = sw.value" @click="draftColor = sw.value"
> >
<UiIcon <UiIcon v-if="draftColor === sw.value" name="check-plain" :size="14" />
v-if="draftColor === sw.value"
name="check-plain"
:size="14"
/>
</button> </button>
</div> </div>
<button <button
@@ -951,7 +948,7 @@ onBeforeUnmount(() => {
</button> </button>
</div> </div>
<div class="media-row"> <div class="media-row desktop-only-flex">
<button type="button" class="media-btn" @click="imageInput?.click()"> <button type="button" class="media-btn" @click="imageInput?.click()">
<UiIcon name="layers" :size="18" /> تصویر <UiIcon name="layers" :size="18" /> تصویر
</button> </button>
@@ -1018,66 +1015,67 @@ onBeforeUnmount(() => {
</div> </div>
</div> </div>
<label class="field"> <div class="desktop-fields">
<span>نوع یادداشت</span>
<select v-model="draftType">
<option
v-for="opt in noteTypeOptions"
:key="opt.value"
:value="opt.value"
>
{{ opt.label }}
</option>
</select>
</label>
<div class="field-row">
<label class="field"> <label class="field">
<span>مرتبط با — مشتری</span> <span>نوع یادداشت</span>
<select v-model="draftPersonId"> <select v-model="draftType">
<option value="">—</option> <option
<option v-for="p in people" :key="p.id" :value="p.id"> v-for="opt in noteTypeOptions"
{{ p.fullName }} :key="opt.value"
:value="opt.value"
>
{{ opt.label }}
</option> </option>
</select> </select>
</label> </label>
<div class="field-row">
<label class="field">
<span>مرتبط با — مشتری</span>
<select v-model="draftPersonId">
<option value="">—</option>
<option v-for="p in people" :key="p.id" :value="p.id">
{{ p.fullName }}
</option>
</select>
</label>
<label class="field">
<span>معامله</span>
<select v-model="draftDealId">
<option value="">—</option>
<option v-for="d in deals" :key="d.id" :value="d.id">
{{ d.title }}
</option>
</select>
</label>
</div>
<label class="field"> <label class="field">
<span>معامله</span> <span>یادآوری</span>
<select v-model="draftDealId"> <JalaliDateInput v-model="draftReminder" mode="datetime" icon="bell" />
<option value="">—</option> </label>
<option v-for="d in deals" :key="d.id" :value="d.id"> <label class="field">
{{ d.title }} <span>برچسب‌ها</span>
</option> <input v-model="draftTags" type="text" placeholder="مثلاً قیمت جلسه" />
</select> </label>
<label class="field">
<span>موقعیت</span>
<input v-model="draftLocation" type="text" placeholder="اختیاری" />
</label>
<label class="ai-toggle">
<input v-model="draftAnalyze" type="checkbox" />
<div>
<strong>تحلیل با هوش مصنوعی</strong>
<p>پس از ذخیره، پیشنهاد کار بعدی و حافظه مشتری استخراج می‌شود.</p>
</div>
</label> </label>
</div> </div>
<label class="field"> <div class="chip-summary mobile-only-flex">
<span>یادآوری</span> <span v-for="(f, i) in draftFiles" :key="`mf-${i}`" class="tag-chip">{{ f.name }}</span>
<JalaliDateInput v-model="draftReminder" mode="datetime" icon="bell" /> <span v-for="t in parseTags(draftTags)" :key="t" class="tag-chip">#{{ t }}</span>
</label> <span v-if="draftPersonId" class="tag-chip">{{ personName(draftPersonId) }}</span>
<span v-if="draftDealId" class="tag-chip">معامله</span>
<label class="field"> <span v-if="draftLocation" class="tag-chip">{{ draftLocation }}</span>
<span>برچسب‌ها</span> </div>
<input
v-model="draftTags"
type="text"
placeholder="مثلاً قیمت جلسه"
/>
</label>
<label class="field">
<span>موقعیت</span>
<input v-model="draftLocation" type="text" placeholder="اختیاری" />
</label>
<label class="ai-toggle">
<input v-model="draftAnalyze" type="checkbox" />
<div>
<strong>تحلیل با هوش مصنوعی</strong>
<p>پس از ذخیره، پیشنهاد کار بعدی و حافظه مشتری استخراج می‌شود.</p>
</div>
</label>
<NoteAiSuggestionPanel <NoteAiSuggestionPanel
v-if="editingId" v-if="editingId"
@@ -1088,7 +1086,7 @@ onBeforeUnmount(() => {
/> />
</div> </div>
<footer class="panel-foot"> <footer class="panel-foot desktop-only-flex">
<button <button
type="button" type="button"
class="btn-primary" class="btn-primary"
@@ -1099,212 +1097,108 @@ onBeforeUnmount(() => {
</button> </button>
<button type="button" class="btn-ghost" @click="closeEditor">لغو</button> <button type="button" class="btn-ghost" @click="closeEditor">لغو</button>
</footer> </footer>
</aside>
</div>
</Teleport>
<!-- Mobile full-screen editor --> <nav class="mob-toolbar mobile-only-flex">
<Teleport to="body">
<div
v-if="editorOpen && mobileEditor"
class="mobile-editor"
:style="{ '--canvas': draftColorCss, background: draftColorCss }"
>
<header class="mob-head">
<button type="button" class="icon-btn" @click="closeEditor">
<UiIcon name="x" :size="22" />
</button>
<button
type="button"
class="btn-save"
:disabled="saving"
@click="saveNote"
>
{{ saving ? '…' : 'ذخیره' }}
</button>
</header>
<div class="mob-canvas">
<input
v-model="draftTitle"
class="title-input"
type="text"
placeholder="عنوان (اختیاری)"
/>
<textarea
ref="bodyTextarea"
v-model="draftBody"
class="body-canvas"
placeholder="یادداشت خود را بنویسید…"
/>
<div class="palette-row">
<div class="swatches" role="listbox" aria-label="رنگ یادداشت">
<button
v-for="sw in colorSwatches"
:key="`m-${sw.value}`"
type="button"
class="swatch"
:class="[`tone-${sw.value}`, { selected: draftColor === sw.value }]"
:style="{ backgroundColor: NOTE_COLOR_HEX[sw.value] }"
:title="sw.label"
:aria-label="sw.label"
:aria-selected="draftColor === sw.value"
@click="draftColor = sw.value"
>
<UiIcon
v-if="draftColor === sw.value"
name="check-plain"
:size="14"
/>
</button>
</div>
<button <button
type="button" type="button"
class="media-btn pin-btn" @click="
:class="{ on: draftPinned }" showChecklistEditor = !showChecklistEditor;
@click="onPinClick" if (showChecklistEditor && !draftChecklist.length)
draftChecklist = [newChecklistItem()];
"
> >
سنجاق <UiIcon name="check" :size="20" />
<span>چک‌لیست</span>
</button> </button>
</div> <div class="voice-slot">
<VoiceToTextButton
<div v-if="showChecklistEditor" class="checklist-ed"> variant="toolbar"
<div hide-error
v-for="(item, idx) in draftChecklist" @transcript="(t) => (draftBody = appendSpokenText(draftBody, t))"
:key="item.id"
class="check-row"
>
<input
type="checkbox"
:checked="item.done"
@change="toggleDraftCheck(item.id)"
/> />
<input v-model="draftChecklist[idx]!.text" type="text" placeholder="مورد" /> <button type="button" class="tiny" @click="audioInput?.click()">فایل صدا</button>
<button type="button" class="icon-btn" @click="removeChecklistRow(item.id)"> </div>
<UiIcon name="x" :size="16" /> <button type="button" @click="imageInput?.click()">
<UiIcon name="layers" :size="20" />
<span>عکس</span>
</button>
<button type="button" @click="fileInput?.click()">
<UiIcon name="document" :size="20" />
<span>فایل</span>
</button>
<button type="button" @click="promptLocation">
<UiIcon name="flag" :size="20" />
<span>موقعیت</span>
</button>
<button type="button" @click="openMoreSheet">
<UiIcon name="dots" :size="20" />
<span>بیشتر</span>
</button>
</nav>
<div v-if="moreSheetOpen" class="sheet-root">
<div class="sheet-backdrop" @click="moreSheetOpen = false" />
<div class="sheet">
<header>
<h3>جزئیات بیشتر</h3>
<button type="button" class="icon-btn" @click="moreSheetOpen = false">
<UiIcon name="x" :size="18" />
</button>
</header>
<label class="field">
<span>انتخاب مشتری</span>
<select v-model="draftPersonId">
<option value="">—</option>
<option v-for="p in people" :key="p.id" :value="p.id">{{ p.fullName }}</option>
</select>
</label>
<label class="field">
<span>معامله</span>
<select v-model="draftDealId">
<option value="">—</option>
<option v-for="d in deals" :key="d.id" :value="d.id">{{ d.title }}</option>
</select>
</label>
<label class="field">
<span>فعالیت</span>
<select v-model="draftActivityId">
<option value="">—</option>
<option v-for="a in activities" :key="a.id" :value="a.id">{{ a.title }}</option>
</select>
</label>
<label class="field">
<span>نوع یادداشت</span>
<select v-model="draftType">
<option
v-for="opt in noteTypeOptions"
:key="opt.value"
:value="opt.value"
>
{{ opt.label }}
</option>
</select>
</label>
<label class="field">
<span>یادآوری</span>
<JalaliDateInput v-model="draftReminder" mode="datetime" icon="bell" />
</label>
<label class="field">
<span>برچسب‌ها</span>
<input v-model="draftTags" type="text" placeholder="برچسب‌ها" />
</label>
<label class="ai-toggle">
<input v-model="draftAnalyze" type="checkbox" />
<div>
<strong>تحلیل با هوش مصنوعی</strong>
<p>پس از ذخیره اجرا می‌شود.</p>
</div>
</label>
<button type="button" class="btn-primary sheet-done" @click="moreSheetOpen = false">
تأیید
</button> </button>
</div> </div>
<button type="button" class="linkish" @click="addChecklistRow">+ مورد جدید</button>
</div> </div>
</aside>
<div class="chip-summary">
<span v-for="(f, i) in draftFiles" :key="`mf-${i}`" class="tag-chip">{{ f.name }}</span>
<span v-for="t in parseTags(draftTags)" :key="t" class="tag-chip">#{{ t }}</span>
<span v-if="draftPersonId" class="tag-chip">{{ personName(draftPersonId) }}</span>
<span v-if="draftDealId" class="tag-chip">معامله</span>
<span v-if="draftLocation" class="tag-chip">{{ draftLocation }}</span>
</div>
<NoteAiSuggestionPanel
v-if="editingId"
:note-id="editingId"
:has-person="Boolean(draftPersonId)"
@applied="load"
@dismissed="load"
/>
</div>
<nav class="mob-toolbar">
<button
type="button"
@click="
showChecklistEditor = !showChecklistEditor;
if (showChecklistEditor && !draftChecklist.length)
draftChecklist = [newChecklistItem()];
"
>
<UiIcon name="check" :size="20" />
<span>چک‌لیست</span>
</button>
<div class="voice-slot">
<VoiceToTextButton
variant="toolbar"
hide-error
@transcript="(t) => (draftBody = appendSpokenText(draftBody, t))"
/>
<button type="button" class="tiny" @click="audioInput?.click()">فایل صدا</button>
</div>
<button type="button" @click="imageInput?.click()">
<UiIcon name="layers" :size="20" />
<span>عکس</span>
</button>
<button type="button" @click="fileInput?.click()">
<UiIcon name="document" :size="20" />
<span>فایل</span>
</button>
<button type="button" @click="promptLocation">
<UiIcon name="flag" :size="20" />
<span>موقعیت</span>
</button>
<button type="button" @click="openMoreSheet">
<UiIcon name="dots" :size="20" />
<span>بیشتر</span>
</button>
</nav>
<div v-if="moreSheetOpen" class="sheet-root">
<div class="sheet-backdrop" @click="moreSheetOpen = false" />
<div class="sheet">
<header>
<h3>جزئیات بیشتر</h3>
<button type="button" class="icon-btn" @click="moreSheetOpen = false">
<UiIcon name="x" :size="18" />
</button>
</header>
<label class="field">
<span>انتخاب مشتری</span>
<select v-model="draftPersonId">
<option value="">—</option>
<option v-for="p in people" :key="p.id" :value="p.id">{{ p.fullName }}</option>
</select>
</label>
<label class="field">
<span>معامله</span>
<select v-model="draftDealId">
<option value="">—</option>
<option v-for="d in deals" :key="d.id" :value="d.id">{{ d.title }}</option>
</select>
</label>
<label class="field">
<span>فعالیت</span>
<select v-model="draftActivityId">
<option value="">—</option>
<option v-for="a in activities" :key="a.id" :value="a.id">{{ a.title }}</option>
</select>
</label>
<label class="field">
<span>نوع یادداشت</span>
<select v-model="draftType">
<option
v-for="opt in noteTypeOptions"
:key="opt.value"
:value="opt.value"
>
{{ opt.label }}
</option>
</select>
</label>
<label class="field">
<span>یادآوری</span>
<JalaliDateInput v-model="draftReminder" mode="datetime" icon="bell" />
</label>
<label class="field">
<span>برچسب‌ها</span>
<input v-model="draftTags" type="text" placeholder="برچسب‌ها" />
</label>
<label class="ai-toggle">
<input v-model="draftAnalyze" type="checkbox" />
<div>
<strong>تحلیل با هوش مصنوعی</strong>
<p>پس از ذخیره اجرا می‌شود.</p>
</div>
</label>
<button type="button" class="btn-primary sheet-done" @click="moreSheetOpen = false">
تأیید
</button>
</div>
</div>
</div> </div>
</Teleport> </Teleport>
</section> </section>
@@ -1544,8 +1438,10 @@ onBeforeUnmount(() => {
.notes-board.is-grid { .notes-board.is-grid {
margin-top: 1.1rem; margin-top: 1.1rem;
column-count: 3; display: grid;
column-gap: 0.9rem; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
gap: 0.85rem;
align-items: stretch;
} }
.notes-board.is-list { .notes-board.is-list {
margin-top: 1.1rem; margin-top: 1.1rem;
@@ -1554,21 +1450,28 @@ onBeforeUnmount(() => {
gap: 0.75rem; gap: 0.75rem;
} }
.notes-board.is-list .note-card { .notes-board.is-list .note-card {
break-inside: auto; aspect-ratio: auto;
min-height: 120px;
height: auto;
width: 100%; width: 100%;
} }
.note-card { .note-card {
break-inside: avoid; aspect-ratio: 1 / 1;
margin-bottom: 0.9rem; width: 100%;
min-height: 0;
margin: 0;
border-radius: var(--radius); border-radius: var(--radius);
box-shadow: var(--shadow); box-shadow: var(--shadow);
border: 1px solid rgba(15, 23, 42, 0.05); border: 1px solid rgba(15, 23, 42, 0.05);
padding: 0.85rem 0.9rem 0.75rem; padding: 0.75rem 0.8rem 0.65rem;
cursor: pointer; cursor: pointer;
position: relative; position: relative;
text-align: start; text-align: start;
transition: transform 0.12s ease, box-shadow 0.12s ease; transition: transform 0.12s ease, box-shadow 0.12s ease;
display: flex;
flex-direction: column;
overflow: hidden;
} }
.note-card:hover { .note-card:hover {
transform: translateY(-1px); transform: translateY(-1px);
@@ -1581,8 +1484,6 @@ onBeforeUnmount(() => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 0.4rem; gap: 0.4rem;
min-height: 140px;
width: 100%;
background: transparent; background: transparent;
border: 1.5px dashed #cbd5e1; border: 1.5px dashed #cbd5e1;
color: #64748b; color: #64748b;
@@ -1643,21 +1544,34 @@ onBeforeUnmount(() => {
.card-title { .card-title {
margin: 0 0 0.35rem; margin: 0 0 0.35rem;
font-size: 1rem; font-size: 0.95rem;
font-weight: 700; font-weight: 700;
color: #0f172a; color: #0f172a;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
} }
.card-body { .card-body {
margin: 0; margin: 0;
white-space: pre-wrap; white-space: pre-wrap;
color: #334155; color: #334155;
font-size: 0.9rem; font-size: 0.82rem;
line-height: 1.55; line-height: 1.45;
flex: 1;
min-height: 0;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 6;
-webkit-box-orient: vertical;
} }
.card-check { .card-check {
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
flex: 1;
min-height: 0;
overflow: hidden;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 0.35rem; gap: 0.35rem;
@@ -1676,15 +1590,16 @@ onBeforeUnmount(() => {
} }
.card-thumb { .card-thumb {
margin-top: 0.65rem; margin-top: 0.45rem;
border-radius: 12px; border-radius: 10px;
overflow: hidden; overflow: hidden;
max-height: 160px; flex-shrink: 0;
max-height: 72px;
} }
.card-thumb img { .card-thumb img {
display: block; display: block;
width: 100%; width: 100%;
height: 160px; height: 72px;
object-fit: cover; object-fit: cover;
} }
@@ -1723,11 +1638,12 @@ onBeforeUnmount(() => {
} }
.card-meta { .card-meta {
margin-top: 0.7rem;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 0.35rem; gap: 0.35rem;
align-items: center; align-items: center;
margin-top: 0.35rem;
flex-shrink: 0;
} }
.type-badge { .type-badge {
font-size: 0.72rem; font-size: 0.72rem;
@@ -1774,12 +1690,14 @@ onBeforeUnmount(() => {
} }
.card-foot { .card-foot {
margin-top: 0.55rem; margin-top: auto;
padding-top: 0.45rem;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
gap: 0.5rem; gap: 0.5rem;
font-size: 0.75rem; font-size: 0.72rem;
color: #94a3b8; color: #94a3b8;
flex-shrink: 0;
} }
.card-foot .person { .card-foot .person {
color: #64748b; color: #64748b;
@@ -1810,27 +1728,40 @@ onBeforeUnmount(() => {
position: fixed; position: fixed;
inset: 0; inset: 0;
z-index: 80; z-index: 80;
display: grid;
place-items: center;
padding: 1rem;
--note-sand: #fff8e1;
--note-rose: #fce4ec;
--note-sky: #e3f2fd;
--note-mint: #e0f2f1;
--note-lavender: #f3e5f5;
--note-default: #ffffff;
--teal: #0d9488;
--teal-soft: #ccfbf1;
} }
.panel-backdrop { .panel-backdrop {
position: absolute; position: absolute;
inset: 0; inset: 0;
background: rgba(15, 23, 42, 0.35); background: rgba(15, 23, 42, 0.45);
} }
.editor-panel { .editor-panel {
position: absolute; position: relative;
inset-block: 0; z-index: 1;
inset-inline-start: 0; width: min(520px, 100%);
width: min(420px, 94vw); max-height: min(92vh, 840px);
border-radius: 18px;
background: #fff; background: #fff;
box-shadow: 8px 0 40px rgba(15, 23, 42, 0.18); box-shadow: 0 24px 64px rgba(15, 23, 42, 0.28);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
animation: slide-in 0.22s ease; overflow: hidden;
animation: modal-in 0.2s ease;
} }
@keyframes slide-in { @keyframes modal-in {
from { from {
transform: translateX(-12px); transform: translateY(10px) scale(0.98);
opacity: 0.6; opacity: 0.55;
} }
to { to {
transform: none; transform: none;
@@ -1936,15 +1867,22 @@ onBeforeUnmount(() => {
background: #fffbeb; background: #fffbeb;
} }
.panel-root { .panel-head-actions {
--note-sand: #fff8e1; display: flex;
--note-rose: #fce4ec; align-items: center;
--note-sky: #e3f2fd; gap: 0.35rem;
--note-mint: #e0f2f1; }
--note-lavender: #f3e5f5;
--note-default: #ffffff; .desktop-only-flex {
--teal: #0d9488; display: flex !important;
--teal-soft: #ccfbf1; }
.mobile-only-flex {
display: none !important;
}
.desktop-fields {
display: flex;
flex-direction: column;
gap: 0.75rem;
} }
.media-row { .media-row {
@@ -2200,7 +2138,7 @@ onBeforeUnmount(() => {
@media (max-width: 1100px) { @media (max-width: 1100px) {
.notes-board.is-grid { .notes-board.is-grid {
column-count: 2; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
} }
} }
@@ -2208,6 +2146,17 @@ onBeforeUnmount(() => {
.desktop-only { .desktop-only {
display: none !important; display: none !important;
} }
.desktop-only-flex,
.desktop-fields {
display: none !important;
}
.mobile-only-flex {
display: flex !important;
}
.chip-summary.mobile-only-flex {
flex-wrap: wrap;
gap: 0.35rem;
}
.mobile-quick.mobile-only, .mobile-quick.mobile-only,
.chips.mobile-only { .chips.mobile-only {
display: flex !important; display: flex !important;
@@ -2216,18 +2165,24 @@ onBeforeUnmount(() => {
display: inline-flex !important; display: inline-flex !important;
} }
.notes-board.is-grid { .notes-board.is-grid {
column-count: 2; grid-template-columns: repeat(2, minmax(0, 1fr));
column-gap: 0.65rem; gap: 0.65rem;
} }
.note-card { .note-card {
padding: 0.7rem; padding: 0.65rem;
margin-bottom: 0.65rem;
} }
} .editor-panel {
width: min(100%, 520px);
@media (min-width: 861px) { max-height: 94vh;
.mobile-editor { border-radius: 16px;
display: none !important; }
.panel-root {
padding: 0.5rem;
place-items: center;
}
.btn-save.mobile-only-flex {
padding: 0.4rem 0.85rem;
font-size: 0.88rem;
} }
} }
</style> </style>