From acefcbec47fc3497307c4cfc2cad8a21953a0a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o?= Date: Wed, 23 Sep 2026 16:12:52 +0200 Subject: [PATCH] refactor(css): move email, calendar, notes and task styles to their own file Second step of splitting static/style.css by panel. This moves the email, calendar, notes and tasks rules that can move into static/css/email-calendar-notes-tasks.css. Same shape as the first step: eager ordered links, verbatim moves, no rendering change. The header comment in each split file lists the load order and the earlier file's header is updated so all of them agree. --- static/css/documents-gallery-editor.css | 1 + static/css/email-calendar-notes-tasks.css | 1572 +++++++++++++++++++++ static/index.html | 1 + static/style.css | 1554 +------------------- static/sw.js | 3 +- 5 files changed, 1577 insertions(+), 1554 deletions(-) create mode 100644 static/css/email-calendar-notes-tasks.css diff --git a/static/css/documents-gallery-editor.css b/static/css/documents-gallery-editor.css index 213808695..3ef2c067c 100644 --- a/static/css/documents-gallery-editor.css +++ b/static/css/documents-gallery-editor.css @@ -10,6 +10,7 @@ * order: * 1. static/style.css * 2. static/css/documents-gallery-editor.css + * 3. static/css/email-calendar-notes-tasks.css * * Rules were moved verbatim. A rule stays in style.css when its selector group * covers more than one panel, when the class is shared design language used by diff --git a/static/css/email-calendar-notes-tasks.css b/static/css/email-calendar-notes-tasks.css new file mode 100644 index 000000000..3f5cced50 --- /dev/null +++ b/static/css/email-calendar-notes-tasks.css @@ -0,0 +1,1572 @@ +/* Email, calendar, notes and tasks panels. + * + * Split out of style.css for maintainability, not for performance: this file + * is loaded eagerly from index.html immediately after style.css, so the rules + * land in the cascade in exactly the order they had inside the single file. + * Nothing here is lazy-loaded. + * + * LOAD ORDER IS PART OF THE CONTRACT. The tags in static/index.html and + * the PRECACHE list in static/sw.js must both list the stylesheets in this + * order: + * 1. static/style.css + * 2. static/css/documents-gallery-editor.css + * 3. static/css/email-calendar-notes-tasks.css + * + * Rules were moved verbatim. A rule stays in style.css when its selector group + * covers more than one panel, when the class is shared design language used by + * modules outside this panel, or when moving it would change which of two + * equally specific rules wins. + */ + +@keyframes email-notif-breathe { + 0%, 100% { + box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent, var(--red)) 60%, transparent); + opacity: 0.85; + } + 50% { + box-shadow: 0 0 6px 2px color-mix(in srgb, var(--accent, var(--red)) 55%, transparent); + opacity: 1; + } + } +.memory-item.task-paused:hover { + opacity: 0.85 !important; + filter: saturate(0.9); +} +.email-folder-picker .email-folder-select-control { + padding-left: 26px; +} +/* Email bulk-select mode owns the whole card. Sender names and tags must not + open search/filter actions until Select is cancelled. */ +#email-lib-grid.email-selecting .email-meta-sender, +#email-lib-grid.email-selecting .email-card-tags, +#email-lib-grid.email-selecting .email-card-favorite, +#email-lib-grid.email-selecting .email-card-nav-arrows, +#email-lib-grid.email-selecting .email-card-status, +#email-lib-grid.email-selecting .email-card-actions { + pointer-events: none !important; +} +.email-reader-actions-inline > .email-reader-more-wrap { order: 5; } +/* ── Tasks ── */ +#tool-tasks-btn.task-failure-pending, +#rail-tasks.task-failure-pending { + color: var(--red, #f87171); +} +#tool-tasks-btn.task-completion-pending, +#rail-tasks.task-completion-pending { + color: var(--accent, var(--green, #86efac)); +} +#tool-tasks-btn.task-failure-pending::after, +#rail-tasks.task-failure-pending::after, +#tool-tasks-btn.task-completion-pending::after, +#rail-tasks.task-completion-pending::after { + content: ''; + width: 7px; + height: 7px; + border-radius: 999px; + background: var(--red, #f87171); + box-shadow: 0 0 7px var(--red, #f87171), 0 0 3px var(--red, #f87171); + flex: 0 0 auto; +} +#tool-tasks-btn.task-completion-pending::after, +#rail-tasks.task-completion-pending::after { + background: var(--accent, var(--green, #86efac)); + box-shadow: 0 0 7px var(--accent, var(--green, #86efac)), 0 0 3px var(--accent, var(--green, #86efac)); +} +#tool-tasks-btn.task-failure-pending.task-completion-pending, +#rail-tasks.task-failure-pending.task-completion-pending { + color: var(--red, #f87171); +} +#tool-tasks-btn.task-failure-pending.task-completion-pending::after, +#rail-tasks.task-failure-pending.task-completion-pending::after { + background: var(--red, #f87171); + box-shadow: 0 0 7px var(--red, #f87171), 0 0 3px var(--red, #f87171); +} +#rail-tasks.task-failure-pending::after, +#rail-tasks.task-completion-pending::after { + position: absolute; + right: 8px; + top: 8px; +} +.tasks-activity-card, +.tasks-activity-list { + min-height: 0; +} +.tasks-activity-list { + overflow-y: auto; + -webkit-overflow-scrolling: touch; +} +.task-log-row.task-log-row-error .task-log-task-icon svg { + opacity: 0.82 !important; +} +.task-log-running-inline .task-log-running-label { font-weight: 500; } +.task-log-running-elapsed { + margin-left: 6px; + opacity: 0.6; + font-variant-numeric: tabular-nums; +} +.task-log-time { + opacity: 0.5; + font-variant-numeric: tabular-nums; +} +@keyframes task-log-pulse { + 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, #60a5fa 60%, transparent); } + 50% { box-shadow: 0 0 0 4px color-mix(in srgb, #60a5fa 0%, transparent); } +} +.task-log-row-body li { margin: 2px 0; } +.task-log-row-body hr { + border: none; + border-top: 1px solid color-mix(in srgb, var(--fg) 12%, transparent); + margin: 8px 0; +} +.task-log-row-toggle::before { + color: color-mix(in srgb, var(--accent, var(--fg)) 80%, transparent); + opacity: 0.8; +} +.task-log-row-toggle:hover::before { opacity: 1; } +/* A elements + can't carry ::before. The pseudo-element is ALWAYS rendered (so its + width is reserved and the placeholder doesn't jump left when the + hint hides); only the colour/animation toggle, not the layout. */ +.notes-quick-add::before { + content: '|'; + color: var(--accent, var(--red)); + margin-right: 6px; + font-weight: 500; + font-size: 13px; + animation: notes-quick-caret 1s steps(2, jump-none) infinite; + pointer-events: none; +} +/* Hide visually (keep space) on hover, focus, or once the input has any + text — prevents the layout shift the user reported when the hint + collapsed and the placeholder slid left. */ +.notes-quick-add:hover::before, +.notes-quick-add:focus-within::before, +.notes-quick-add:not(:has(.notes-quick-input:placeholder-shown))::before { + visibility: hidden; + animation: none; +} +@keyframes notes-quick-caret { + 0%, 49% { opacity: 1; } + 50%, 100%{ opacity: 0; } +} +.notes-quick-type-seg.is-todo::before { transform: translateX(100%); } +.notes-skeleton-card.short { height: 46px; } +@keyframes notes-skeleton-shimmer { + 0% { background-position: 200% 0; } + 100% { background-position: -200% 0; } +} +@keyframes cal-bell-jingle { + 0% { transform: rotate(0deg); } + 15% { transform: rotate(-22deg); } + 30% { transform: rotate(18deg); } + 45% { transform: rotate(-14deg); } + 60% { transform: rotate(10deg); } + 75% { transform: rotate(-6deg); } + 88% { transform: rotate(3deg); } + 100% { transform: rotate(0deg); } +} +.note-form-reminder-tags:empty { display: none; } +.note-reminder-day-chip.wide { padding: 0 6px; } +.note-form-type-seg::before { + content: ''; + position: absolute; + top: 0; + left: 0; + /* 3 pills now (note / todo / draw) — Goal was removed. Slider takes + 1/3 of the track and translates by full multiples of itself. */ + width: 33.3333%; + height: 100%; + background: color-mix(in srgb, var(--fg) 10%, transparent); + border-radius: 9px; + transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); + z-index: 0; +} +.note-form-type-seg.is-todo::before { transform: translateX(100%); } +.note-form-type-seg.is-draw::before { transform: translateX(200%); } +/* Bulk-bar appears under the search bar — inset its sides to match the + search bar's own 8px horizontal padding so the two visually align. */ +#notes-bulk-bar.memory-bulk-bar { + margin: 0 8px 4px; + position: relative; + top: 4px; +} +#tasks-filter-chips { + top: 0 !important; +} +.note-card-goal .note-card-header { + /* Goal cards reserve space for the pill so the title doesn't collide. */ + padding-left: 56px; +} +/* In select mode the left-side checkbox takes the pill's spot — drop it + so the row stays legible. */ +.note-card-selectmode.note-card-goal .note-goal-pill { display: none; } +.note-card-selectmode.note-card-goal .note-card-header { padding-left: 0; } +.note-form-goal-ai:disabled, +.note-form-goal-ai.busy { + opacity: 0.6; + cursor: wait; +} +/* Fresh goal form: hide the title input + tag input + reminder button so the + user only sees the single "what do you want to achieve?" textarea. */ +.note-form-goal-fresh ~ .note-form-actions-group { display: none; } +.note-form:has(.note-form-goal-fresh) .note-form-title, +.note-form:has(.note-form-goal-fresh) .note-form-label, +.note-form:has(.note-form-goal-fresh) .note-form-remind-btn, +.note-form-bespoke:has(.note-form-goal-fresh) .note-form-title, +.note-form-bespoke:has(.note-form-goal-fresh) .note-form-label, +.note-form-bespoke:has(.note-form-goal-fresh) .note-form-remind-btn { + display: none !important; +} +.note-form-goal-fresh .note-form-goal-desc { + font-size: 15px; + min-height: 90px; + padding: 12px 14px; +} +.note-form-goal-fresh.building .note-form-goal-desc { + opacity: 0.55; + pointer-events: none; +} +.note-form-goal-fresh.building::after { + content: 'AI is planning your goal…'; + display: block; + text-align: center; + font-size: 12px; + opacity: 0.7; + margin-top: 6px; + animation: note-goal-pulse 1.4s ease-in-out infinite; +} +@keyframes note-goal-pulse { + 0%, 100% { opacity: 0.5; } + 50% { opacity: 1; } +} +.notes-today-row.done { + opacity: 0.35; + transform: scale(0.98); +} +.notes-today-title:hover { text-decoration: underline; } +.notes-bulk-btn { + opacity: 0.6; +} +.notes-bulk-btn:hover { opacity: 1; } +.note-form-label.flash-once { + animation: noteLabelFlash 0.6s ease-out; +} +.note-form-label:not([value=""]) { opacity: 0.9; border-style: solid; } +.note-card-title:hover { opacity: 0.7; } +.note-card-title.empty::before { + content: 'No title'; + font-weight: 500; + opacity: 0.3; + font-style: italic; +} +/* Note card drag */ +.note-card { cursor: grab; } +.note-cl-row:hover .note-cl-grip { opacity: 0.6; } +.note-archive-btn:hover { opacity: 0.7; } +.note-checklist-preview > .note-checkbox:last-child .note-check-text { + /* Reserve room on the LAST row only for the bottom-right copy button so it + doesn't cover the final item's tail. Applied to the text — not to the + row — so the X delete button still reaches the same edge it does on + every other row. */ + padding-right: 30px; +} +.note-card.doclib-card-expanded .note-checklist-preview { + /* When the card is the expanded one in the grid, let the list use the + whole available height instead of the compact cap. */ + max-height: none; +} +.note-checklist-preview:empty::before { + content: 'No todos'; + font-size: 10px; + opacity: 0.3; + font-style: italic; +} +.note-card:hover .note-cl-quickadd, +.note-cl-quickadd:focus-within { + opacity: 1; + pointer-events: auto; +} +.note-cl-quickadd-input::placeholder { color: var(--fg); opacity: 0.5; } +.note-card-selectmode .note-cl-quickadd { display: none !important; } +.note-checkbox-rm { margin-left: auto; } +.note-checkbox-edit { margin-left: auto; } +.note-checkbox:hover .note-checkbox-edit, +.note-checkbox:hover .note-checkbox-rm { opacity: 0.55; } +.note-card-selectmode .note-checkbox-edit, +.note-card-selectmode .note-checkbox-rm { display: none; } +.note-check-dot::after { + content: ''; + position: absolute; + left: 50%; + top: 45%; + width: 7px; + height: 3.5px; + border-left: 1.75px solid #fff; + border-bottom: 1.75px solid #fff; + transform: translate(-50%, -50%) rotate(-45deg) scale(0); + transform-origin: center; + transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); +} +.notes-select-mode .note-checkbox { cursor: default; pointer-events: none; } +.note-checkbox:active .note-check-dot { + transform: scale(0.9); +} +.note-checkbox.done .note-check-dot::after { + transform: translate(-50%, -50%) rotate(-45deg) scale(1); +} +@keyframes note-check-pop { + 0% { transform: scale(1); } + 40% { transform: scale(1.35); } + 100% { transform: scale(1); } +} +.note-checkbox.done .note-check-text { + position: relative; + opacity: 0.4; +} +.note-checkbox.done .note-check-text::after { + content: ''; + position: absolute; + left: 0; + right: 0; + top: calc(50% - 1px); + height: 1px; + background: currentColor; + animation: note-strike 0.3s ease-out forwards; + transform-origin: left center; +} +@keyframes note-strike { + 0% { transform: scaleX(0); } + 100% { transform: scaleX(1); } +} +/* 3D top-edge highlight — an inset 2px stripe inside every note card that + reads as a lifted "glassy" lip. Each colored note gets a stronger stripe + in its own hue so the colour reads even before you focus on the card. */ +.note-card { box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--fg) 14%, transparent); } +.note-color-red { box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--red) 55%, transparent); } +.note-color-orange { box-shadow: inset 0 2px 0 0 color-mix(in srgb, #d19a66 60%, transparent); } +.note-color-yellow { box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--hl-string) 60%, transparent); } +.note-color-green { box-shadow: inset 0 2px 0 0 color-mix(in srgb, #98c379 60%, transparent); } +.note-color-blue { box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--hl-function) 60%, transparent); } +.note-color-purple { box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--hl-keyword) 60%, transparent); } +.note-card.note-standard-v0 { --note-accent: #db8576; } +.note-card.note-standard-v1 { --note-accent: #d2a45f; } +.note-card.note-standard-v2 { --note-accent: #72ad8d; } +.note-card.note-standard-v3 { --note-accent: #72a5cf; } +.note-card.note-standard-v4 { --note-accent: #aa86c7; } +.note-type-btn:hover { opacity: 0.8; } +.note-form-meta .note-form-label { + width: 112px; + flex: 0 1 140px; +} +/* After attachColorPicker swaps the input to type=text + .cp-swatch-input, + re-pin the swatch to a 24px circle (otherwise it inherits text-input + sizing and becomes a giant rectangle). */ +.note-form-draw-color.cp-swatch-input { + width: 24px !important; + height: 24px !important; + min-width: 24px !important; + max-width: 24px !important; + border-radius: 50%; + padding: 0; + box-sizing: border-box; +} +.note-form-draw-color::-webkit-color-swatch-wrapper { padding: 0; border-radius: 50%; } +.note-form-draw-color::-webkit-color-swatch { border: none; border-radius: 50%; } +.note-form-draw-color::-moz-color-swatch { border: none; border-radius: 50%; } +.note-form-draw-size:hover, +.note-form-draw-size:focus, +.note-form-draw-size:active { height: 10px; } +.note-form-draw-size::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 12px; height: 12px; + border-radius: 50%; + background: var(--red); + border: none; + cursor: pointer; + transition: width 0.12s ease, height 0.12s ease; +} +.note-form-draw-size::-moz-range-thumb { + width: 12px; height: 12px; + border-radius: 50%; + background: var(--red); + border: none; + cursor: pointer; + transition: width 0.12s ease, height 0.12s ease; +} +.note-form-draw-size:hover::-webkit-slider-thumb, +.note-form-draw-size:focus::-webkit-slider-thumb, +.note-form-draw-size:active::-webkit-slider-thumb { width: 18px; height: 18px; } +.note-form-draw-size:hover::-moz-range-thumb, +.note-form-draw-size:focus::-moz-range-thumb, +.note-form-draw-size:active::-moz-range-thumb { width: 18px; height: 18px; } +.note-form-draw-be::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 50%; + height: 100%; + background: var(--accent); + border-radius: 9px; + transition: transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1); + z-index: 0; +} +.note-form-draw-be.is-eraser::before { transform: translateX(100%); } +.note-form-draw-be-btn:focus { outline: none; } +.note-form-draw-text-badge:empty { display: none; } +.note-form-draw-shape-badge:empty { display: none; } +/* Reflect the chosen size in the icon itself, so the user sees at a glance + which size (S/M/L) is active without needing the tiny badge. */ +.note-form-draw-line.size-s svg line, +.note-form-draw-circle.size-s svg circle { stroke-width: 1.2; } +.note-form-draw-line.size-m svg line, +.note-form-draw-circle.size-m svg circle { stroke-width: 3; } +.note-form-draw-line.size-l svg line, +.note-form-draw-circle.size-l svg circle { stroke-width: 5; } +.note-form-draw-text.size-s { font-size: 13px; } +.note-form-draw-text.size-m { font-size: 18px; } +.note-form-draw-text.size-l { font-size: 23px; line-height: 1; } +/* Narrow widths: shrink the tag input to make room for the action group; + the hashtag-in-content shortcut still works, so the input can be tiny. */ +@media (max-width: 600px) { + .note-form-meta .note-form-label { width: 78px; flex-shrink: 1; min-width: 0; } +} +.note-form-due:not([value=""]) { opacity: 0.85; border-style: solid; } +.note-cl-add:hover { opacity: 0.7; } +/* Matching ↵ hint at the right of the event title while it's empty; hidden once + editing (the ✓ Done button takes over then). */ +/* Title placeholder overlay: the prompt text with a ↵ enter glyph right after + it (accent), so it's clear the field submits on Enter. Shown only while the + title is empty; the native placeholder is hidden in favour of this. */ +.cal-hero-title::placeholder { color: transparent; } +.cal-quickadd-input::placeholder { color: transparent; } +button.cal-nav.cal-toolbar-arrow:hover { + opacity: 1; + background: color-mix(in srgb, var(--bg) 76%, var(--fg) 24%); +} +.cal-side-nav-prev { left: 8px; } +.cal-side-nav-next { right: 8px; } +.cal-navigation-hidden .cal-side-nav { + display: none !important; +} +#cal-add { margin-left: auto; } +/* Mobile tap-spin: a gentle quarter-turn nudge before the form opens. + `.cal-add-plus` has a `padding-bottom: 2px` (and a translateY on the + small variant) that offsets the glyph for optical centering — those + shift the rotation pivot off the visual centre. Force the box to + match the glyph and pin the transform-origin during the spin. */ +.cal-add-plus.cal-add-spinning { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0; + width: 1em; + height: 1em; + line-height: 1; + transform-origin: 50% 50%; + animation: cal-add-spin 0.28s ease-out forwards; +} +@keyframes cal-add-spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(90deg); } +} +button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover { + padding: 0 8px 0 5px; + gap: 3px; +} +.email-reminder-toggle-inline:hover svg { + animation: none !important; + transform: none !important; +} +.email-search-options-menu[hidden], +.email-search-options-menu button.hidden { + display: none !important; +} +.email-search-date-panel[hidden] { display: none !important; } +.email-search-date-panel label { + display: grid; + grid-template-columns: 38px 1fr; + align-items: center; + gap: 6px; + margin: 0 0 6px; + color: color-mix(in srgb, var(--fg) 72%, transparent); + font-size: 10px; +} +.email-lib-filter-pill-icon-only .email-lib-filter-pill-label { display: none; } +.email-lib-filter-pill.email-lib-filter-pill-icon-only { padding-left: 5px !important; } +.email-search-options-menu .email-search-date-actions button { + width: auto; + min-width: 48px; + justify-content: center; + padding: 5px 8px; +} +.email-attach-toggle:not(.email-attach-toggle-inline):hover svg { + animation: email-undone-jiggle 0.45s ease-in-out; + transform-origin: 50% 50%; +} +@keyframes email-undone-jiggle { + 0% { transform: rotate(0deg); } + 20% { transform: rotate(-14deg); } + 40% { transform: rotate(10deg); } + 60% { transform: rotate(-6deg); } + 80% { transform: rotate(3deg); } + 100% { transform: rotate(0deg); } +} +.email-undone-toggle:not(.email-undone-toggle-inline):hover svg, +.email-compose-jiggle:hover svg { + animation: email-undone-jiggle 0.45s ease-in-out; + transform-origin: 50% 50%; +} +/* Account chips collapse to a single horizontally-scrollable strip + at every breakpoint, instead of stacking onto multiple rows when + there are several accounts. The compose "New" button stays outside + the scroller (it's a sibling of #email-lib-accounts inside + .email-accounts-row) so it remains pinned on the right. */ +#email-lib-accounts { + justify-content: flex-start; + flex-wrap: nowrap; + overflow-x: auto; + overflow-y: hidden; + scrollbar-width: none; + -ms-overflow-style: none; + scroll-snap-type: x proximity; + -webkit-overflow-scrolling: touch; +} +#email-lib-accounts::-webkit-scrollbar { display: none; height: 0; } +#email-lib-accounts > * { flex-shrink: 0; scroll-snap-align: start; } +.email-account-chip.email-account-has-unread:not(.active) { + border-color: var(--border); + background: transparent; + color: var(--fg); +} +#email-lib-grid { position: relative; } +#email-lib-grid .date-section-header.email-date-gap-break { + margin-top: 12px; + padding-top: 16px; +} +#email-lib-modal.email-reading .email-lib-sync-status { + display: none; +} +button.cal-view-btn { + display: inline-flex; + align-items: center; + justify-content: center; + background: transparent; + border: none; + color: var(--fg); + font-size: 11px; + font-family: inherit; + font-weight: 500; + padding: 2px 12px 2px 12px; + margin: 0; + cursor: pointer; + opacity: 0.45; + line-height: 1; + height: 24px; + box-sizing: border-box; +} +.cal-s-color::-webkit-color-swatch-wrapper { padding: 0; border-radius: 50%; } +.cal-s-color::-webkit-color-swatch { border: none; border-radius: 50%; } +.cal-s-color::-moz-color-swatch { border: none; border-radius: 50%; } +.cal-filter-item.cal-filter-off { opacity:0.25; text-decoration:line-through; } +.cal-filter-item.cal-filter-important.cal-filter-active { background:color-mix(in srgb, #e5a33a 18%, transparent); border-color:#e5a33a; } +.cal-week-row > .cal-day { padding-top: calc(4px + var(--bars, 0) * 12px); } +@keyframes cal-slide-from-right { + from { opacity:0; transform:translateX(20px); } + to { opacity:1; transform:translateX(0); } +} +@keyframes cal-slide-from-left { + from { opacity:0; transform:translateX(-20px); } + to { opacity:1; transform:translateX(0); } +} +@keyframes cal-event-enter { + from { opacity:0; transform:translateY(3px) scale(0.985); } + to { opacity:1; transform:translateY(0) scale(1); } +} +.cal-slide-in-right { animation: cal-slide-from-right 0.22s cubic-bezier(0.25, 0.8, 0.25, 1); } +.cal-slide-in-left { animation: cal-slide-from-left 0.22s cubic-bezier(0.25, 0.8, 0.25, 1); } +.cal-day.cal-today .cal-day-num { color:var(--bg); font-weight:800; background:var(--accent, var(--red)); border-radius:10px; padding:1px 6px; display:inline-block; opacity:1; line-height:1.3; } +/* Selected day — same square geometry as `.cal-today` so the two read as + peers, but rendered as an outline + softer fill instead of a solid + accent block. Today wins when both classes are on the same cell. */ +.cal-day.cal-selected:not(.cal-today) { + box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent, var(--fg)) 65%, transparent); + background: color-mix(in srgb, var(--accent, var(--fg)) 12%, var(--bg)); + border-radius: 8px; +} +.cal-day.cal-weekend:not(.cal-today) { background:color-mix(in srgb, var(--fg) 2.5%, var(--bg)); } +.cal-day.cal-empty-day::after { + content:''; + position:absolute; + left:8px; + right:8px; + bottom:8px; + height:1px; + background:color-mix(in srgb, var(--fg) 7%, transparent); + opacity:0.55; + pointer-events:none; +} +.cal-day.cal-other { opacity:0.34; } +.cal-event-row::after { + content:''; + width:3px; + height:11px; + margin-left:auto; + opacity:0; + flex:0 0 auto; + border-left:1px solid color-mix(in srgb, var(--fg) 34%, transparent); + border-right:1px solid color-mix(in srgb, var(--fg) 34%, transparent); + transition:opacity 0.15s; +} +.cal-event-row:hover::after { opacity:0.75; } +.cal-dragging { opacity:0.3; } +#cal-body.cal-events-full > :is(.cal-grid, .cal-wk-wrap) { + display: none; +} +#cal-body.cal-events-full > .cal-day-detail { + height: auto; + min-height: 0; + flex: 1 1 auto; +} +#cal-body.cal-calendar-full > .cal-day-detail { + display: none; +} +.cal-event-link-target { + animation: cal-event-link-target-flash 2.2s ease-out; + box-shadow: + inset 0 0 0 2px color-mix(in srgb, var(--accent, var(--red)) 88%, transparent), + 0 0 0 3px color-mix(in srgb, var(--accent, var(--red)) 20%, transparent), + 0 8px 20px color-mix(in srgb, var(--accent, var(--red)) 18%, transparent) !important; +} +@keyframes cal-event-link-target-flash { + 0%, 28% { + filter: brightness(1.18) saturate(1.12); + transform: translateY(-1px); + } + 100% { + filter: none; + transform: none; + } +} +.cal-event-loc a, .cal-event-time a { color:inherit; text-decoration:underline; text-decoration-color:color-mix(in srgb, currentColor 40%, transparent); } +.cal-event-loc a:hover, .cal-event-time a:hover { opacity:1; text-decoration-color:currentColor; } +#cal-settings > svg { + top: 3px !important; +} +.cal-wk-col.cal-wk-today .cal-wk-col-head { background: color-mix(in srgb, var(--accent, var(--red)) 12%, var(--bg)); } +.cal-wk-col.cal-wk-today .cal-wk-dn, +.cal-wk-col.cal-wk-today .cal-wk-dt { color: var(--accent, var(--red)); font-weight: 700; } +/* Sunday: a softer rest-day tint so the week edge reads visually, even + when today is mid-week. Falls back gracefully under the .cal-wk-today + rules above (today on a Sunday still gets the accent treatment). */ +.cal-wk-col.cal-wk-sun .cal-wk-col-head { background: color-mix(in srgb, var(--fg) 7%, var(--bg)); } +.cal-wk-col.cal-wk-sun .cal-wk-grid { background: color-mix(in srgb, var(--fg) 2.5%, var(--bg)); } +.cal-wk-col.cal-wk-sun .cal-wk-allday { background: color-mix(in srgb, var(--fg) 3%, var(--bg)); } +.cal-wk-col.cal-wk-sun .cal-wk-dn, +.cal-wk-col.cal-wk-sun .cal-wk-dt { color: color-mix(in srgb, var(--fg) 60%, transparent); } +.cal-wk-dt { font-variant-numeric: tabular-nums; opacity: 0.5; } +.cal-wk-allday::-webkit-scrollbar { display: none; } +.cal-wk-now::before { + content: ''; + position: absolute; + left: -3px; + top: -4px; + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--accent, var(--red, #f87171)); + box-shadow:0 0 0 3px color-mix(in srgb, var(--accent, var(--red)) 18%, transparent); +} +.cal-wk-now::after { + content:'now'; + position:absolute; + right:4px; + top:-10px; + padding:1px 5px; + border-radius:7px; + font-size:8px; + line-height:1.2; + font-weight:800; + text-transform:uppercase; + color:var(--bg); + background:var(--accent, var(--red)); + box-shadow:0 1px 4px color-mix(in srgb, #000 22%, transparent); +} +@keyframes cal-wk-hover-label-reveal { + 0%, 35% { opacity: 0; } + 100% { opacity: 1; } +} +.cal-wk-block:hover .cal-wk-block-resize::after { + content: ''; + position: absolute; + left: 30%; + right: 30%; + bottom: 1px; + height: 2px; + border-radius: 2px; + background: color-mix(in srgb, var(--fg) 35%, transparent); +} +.cal-wk-block::after { + content:''; + position:absolute; + top:6px; + right:5px; + width:3px; + height:14px; + opacity:0; + border-left:1px solid color-mix(in srgb, var(--fg) 35%, transparent); + border-right:1px solid color-mix(in srgb, var(--fg) 35%, transparent); + transition:opacity 0.15s; +} +.cal-wk-block:hover::after { opacity:0.75; } +.cal-wk-block-resize:hover::after { + background: color-mix(in srgb, var(--fg) 65%, transparent); +} +/* Body of a block while it's being repositioned: lifted shadow + above + siblings so the drop target reads clearly. */ +.cal-wk-block-ghost { + z-index: 6 !important; + box-shadow: 0 4px 12px color-mix(in srgb, var(--fg) 24%, transparent) !important; + cursor: grabbing; +} +.cal-wk-block { cursor: grab; } +.cal-wk-block:active { cursor: grabbing; } +.cal-wk-slot-selected-label { + pointer-events: none; +} +.cal-wk-slot-resize::after { + content: ''; + position: absolute; + left: 18%; + right: 18%; + top: 6px; + height: 3px; + border-radius: 2px; + background: var(--accent, var(--fg)); + box-shadow: 0 0 0 2px color-mix(in srgb, var(--bg) 75%, transparent); +} +.cal-wk-col.cal-wk-slot-day-selected .cal-wk-col-head { + color: var(--accent, var(--fg)); + box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--accent, var(--fg)) 70%, transparent); +} +.cal-year-month:hover .cal-year-month-title { opacity:1; color:var(--accent); } +.cal-year-day { cursor:pointer; opacity:0.5; } +.cal-search-input.cal-day-search:focus { width:100%; } +.cal-agenda-day::before { + content:''; + position:absolute; + left:4px; + top:22px; + bottom:-12px; + width:1px; + background:color-mix(in srgb, var(--fg) 12%, transparent); +} +.cal-agenda-day::after { + content:''; + position:absolute; + left:1px; + top:12px; + width:7px; + height:7px; + border-radius:50%; + background:color-mix(in srgb, var(--fg) 22%, var(--bg)); + box-shadow:0 0 0 3px var(--bg); +} +.cal-agenda-day.is-today::after { background:var(--accent, var(--red)); } +.cal-agenda-day.is-today .cal-agenda-date { opacity: 1; color: var(--accent, var(--red)); border-bottom-color: color-mix(in srgb, var(--accent, var(--red)) 35%, var(--border)); } +.cal-agenda-event:hover .cal-event-more, +.cal-event-item:hover .cal-event-more { opacity:0.6; } +button.cal-event-more { + background:transparent; + border:none; + color:var(--fg); + width:20px; height:20px; + cursor:pointer; + padding:0; + display:inline-flex; + align-items:center; + justify-content:center; + font-family:inherit; + flex-shrink:0; + margin-left:auto; + align-self:center; + transform:translateY(-4px); + transition:opacity 0.15s; +} +button.cal-event-more:hover { opacity:1 !important; } +/* Day-detail "+ New" button nudged down 2px. */ +#cal-add-day { position: relative; top: 2px; } +/* Accent the native date/time picker glyphs. We recolor the webkit indicator + by masking an accent fill through a calendar/clock SVG (same technique as the + mono icon picker). accent-color covers the spinner parts where supported. */ +.cal-form-bespoke input[type="date"], +.cal-form-bespoke input[type="time"], +.cal-form-bespoke input[type="datetime-local"] { accent-color: var(--accent, var(--red)); } +.cal-form-bespoke input[type="date"]::-webkit-datetime-edit-month-field, +.cal-form-bespoke input[type="date"]::-webkit-datetime-edit-day-field { + color: var(--accent, var(--red)); + font-weight: 600; +} +.cal-form-bespoke input[type="date"]::-webkit-datetime-edit-year-field { + color: var(--fg); + font-weight: 400; +} +.cal-form-bespoke input[type="date"]::-webkit-calendar-picker-indicator, +.cal-form-bespoke input[type="time"]::-webkit-calendar-picker-indicator, +.cal-form-bespoke input[type="datetime-local"]::-webkit-calendar-picker-indicator { + background-color: var(--accent, var(--red)); + background-image: none; + cursor: pointer; + width: 14px; height: 14px; +} +.cal-form-bespoke input[type="date"]::-webkit-calendar-picker-indicator, +.cal-form-bespoke input[type="datetime-local"]::-webkit-calendar-picker-indicator { + -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cline x1='16' y1='2' x2='16' y2='6'/%3E%3Cline x1='8' y1='2' x2='8' y2='6'/%3E%3Cline x1='3' y1='10' x2='21' y2='10'/%3E%3C/svg%3E") center/contain no-repeat; + mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cline x1='16' y1='2' x2='16' y2='6'/%3E%3Cline x1='8' y1='2' x2='8' y2='6'/%3E%3Cline x1='3' y1='10' x2='21' y2='10'/%3E%3C/svg%3E") center/contain no-repeat; +} +.cal-form-bespoke input[type="time"]::-webkit-calendar-picker-indicator { + -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E") center/contain no-repeat; + mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E") center/contain no-repeat; +} +/* Title underline + clock focus ring + primary button track --ev-color + when set; default to --accent / --fg otherwise. */ +.cal-form-bespoke .cal-input.cal-hero-title:focus { border-bottom-color: var(--ev-color, var(--accent, color-mix(in srgb, var(--fg) 60%, transparent))); } +.cal-form-bespoke[style*="--ev-color"] .cal-input.cal-hero-title { border-bottom-color: color-mix(in srgb, var(--ev-color) 35%, var(--border)); } +.cal-form-bespoke .cal-hero-time:focus-visible, +.cal-form-bespoke .cal-hero-date:focus-visible { outline-color: var(--ev-color, var(--accent, color-mix(in srgb, var(--fg) 50%, transparent))); } +/* Custom-BG events paint the form card with the uploaded image. Make sure + the action row + buttons stay clearly readable on top of it. */ +.cal-form-bespoke.cal-form-bg-image .cal-form-actions { + position: relative; + z-index: 2; + /* Solid backing strip so the Save/Cancel/Delete buttons don't fade into + the photo behind them. */ + background: color-mix(in srgb, var(--panel) 92%, transparent); + margin: 8px -14px -14px; + padding: 10px 14px; + border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent); + border-radius: 0 0 8px 8px; +} +.cal-form-today span { letter-spacing: 0.04em; text-transform: none; opacity: 0.85; font-weight: 500; } +.cal-hero-time .cal-hero-clock, +.cal-hero-time .cal-hero-ampm { line-height: 1; } +.cal-hero-time:focus-visible { outline: 2px solid var(--accent, color-mix(in srgb, var(--fg) 50%, transparent)); outline-offset: 2px; } +.cal-hero-date:focus-visible { outline: 2px solid var(--accent, color-mix(in srgb, var(--fg) 50%, transparent)); outline-offset: 2px; } +.cal-input.cal-hero-title:focus { + border-color: transparent; + border-bottom-color: var(--accent, color-mix(in srgb, var(--fg) 60%, transparent)); +} +.cal-form-bespoke.is-expanded .cal-form-details { + max-height: 720px; + opacity: 1; + margin-top: 4px; +} +.cal-form-bespoke .cal-form-actions { margin-top: 8px; justify-content: flex-end; } +.cal-form-bespoke .cal-form-row { margin-bottom: 8px; } +.cal-loc-input-wrap > input { height: 100%; } +.cal-loc-input-wrap > input::placeholder { color: transparent; } +.cal-loc-hint svg { color: var(--accent, var(--red)); } +.cal-loc-input-wrap > input:placeholder-shown ~ .cal-loc-hint { display: inline-flex; } +.cal-loc-map.is-disabled { opacity: 0.3; pointer-events: none; cursor: default; } +select.cal-input { appearance:auto; } +textarea.cal-input { resize:vertical; font-family:inherit; } +button.cal-btn.cal-btn-danger { color:var(--accent, var(--red)); border-color:var(--accent, var(--red)); background:transparent; } +button.cal-btn.cal-btn-danger:hover { background:var(--accent, var(--red)); color:var(--bg); } +/* Brief outline flash on a note card when it's the target of a + #note- link click from chat — same pattern as the cookbook + task flash, just scoped to .note-card. */ +.note-card-flash { + animation: note-card-flash-anim 1.6s ease-out; +} +@keyframes note-card-flash-anim { + 0% { box-shadow: 0 0 0 2px var(--accent, var(--red)); } + 100% { box-shadow: 0 0 0 2px transparent; } +} diff --git a/static/index.html b/static/index.html index be68a38a3..4fb035d1d 100644 --- a/static/index.html +++ b/static/index.html @@ -252,6 +252,7 @@ these files in this order, so they must stay in this order here and in the PRECACHE list in sw.js. None of them is lazy-loaded. --> + diff --git a/static/style.css b/static/style.css index 37abf35cb..c6e3f67bd 100644 --- a/static/style.css +++ b/static/style.css @@ -1328,17 +1328,7 @@ body.bg-pattern-ascii-fireflies { position: relative; top: 0.1px; } - @keyframes email-notif-breathe { - 0%, 100% { - box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent, var(--red)) 60%, transparent); - opacity: 0.85; - } - 50% { - box-shadow: 0 0 6px 2px color-mix(in srgb, var(--accent, var(--red)) 55%, transparent); - opacity: 1; - } - } - @media (prefers-reduced-motion: reduce) { + @media (prefers-reduced-motion: reduce) { #email-unread-dot.sidebar-notif-dot { animation: none; } } @media (max-width: 768px) { @@ -13470,10 +13460,6 @@ textarea.memory-add-input { color-mix(in srgb, var(--fg) 5%, transparent) 16px ) !important; } -.memory-item.task-paused:hover { - opacity: 0.85 !important; - filter: saturate(0.9); -} .task-status-badge { appearance: none; -webkit-appearance: none; @@ -14041,9 +14027,6 @@ textarea.memory-add-input { position: relative; top: 0; } -.email-folder-picker .email-folder-select-control { - padding-left: 26px; -} .email-folder-picker-icon { position: absolute; left: 8px; @@ -19536,16 +19519,6 @@ body:not(.email-doc-split-active) #email-lib-modal.email-lib-fullscreen:not(.mod } } -/* Email bulk-select mode owns the whole card. Sender names and tags must not - open search/filter actions until Select is cancelled. */ -#email-lib-grid.email-selecting .email-meta-sender, -#email-lib-grid.email-selecting .email-card-tags, -#email-lib-grid.email-selecting .email-card-favorite, -#email-lib-grid.email-selecting .email-card-nav-arrows, -#email-lib-grid.email-selecting .email-card-status, -#email-lib-grid.email-selecting .email-card-actions { - pointer-events: none !important; -} /* Mobile: only ONE scroll surface inside the cookbook modal. The modal-content is the scroller. Everything inside (cookbook-body, @@ -21350,7 +21323,6 @@ body:not(.email-doc-split-active) #email-lib-modal.email-lib-fullscreen:not(.mod .email-reader-actions-inline > [data-act="reply"] { order: 2; } .email-reader-actions-inline > [data-act="reply-all"] { order: 3; } .email-reader-actions-inline > [data-act="forward"] { order: 4; } -.email-reader-actions-inline > .email-reader-more-wrap { order: 5; } .email-reader-actions-inline.email-reader-actions-compact > .reader-action-overflowed { display: none !important; } @@ -27639,41 +27611,6 @@ body:not(.welcome-ready) #welcome-screen { } } -/* ── Tasks ── */ -#tool-tasks-btn.task-failure-pending, -#rail-tasks.task-failure-pending { - color: var(--red, #f87171); -} -#tool-tasks-btn.task-completion-pending, -#rail-tasks.task-completion-pending { - color: var(--accent, var(--green, #86efac)); -} -#tool-tasks-btn.task-failure-pending::after, -#rail-tasks.task-failure-pending::after, -#tool-tasks-btn.task-completion-pending::after, -#rail-tasks.task-completion-pending::after { - content: ''; - width: 7px; - height: 7px; - border-radius: 999px; - background: var(--red, #f87171); - box-shadow: 0 0 7px var(--red, #f87171), 0 0 3px var(--red, #f87171); - flex: 0 0 auto; -} -#tool-tasks-btn.task-completion-pending::after, -#rail-tasks.task-completion-pending::after { - background: var(--accent, var(--green, #86efac)); - box-shadow: 0 0 7px var(--accent, var(--green, #86efac)), 0 0 3px var(--accent, var(--green, #86efac)); -} -#tool-tasks-btn.task-failure-pending.task-completion-pending, -#rail-tasks.task-failure-pending.task-completion-pending { - color: var(--red, #f87171); -} -#tool-tasks-btn.task-failure-pending.task-completion-pending::after, -#rail-tasks.task-failure-pending.task-completion-pending::after { - background: var(--red, #f87171); - box-shadow: 0 0 7px var(--red, #f87171), 0 0 3px var(--red, #f87171); -} @media (min-width: 769px) { #tool-tasks-btn #assistant-notif-dot.sidebar-notif-dot, #tool-tasks-btn.task-failure-pending::after, @@ -27681,21 +27618,7 @@ body:not(.welcome-ready) #welcome-screen { transform: translateX(-2px); } } -#rail-tasks.task-failure-pending::after, -#rail-tasks.task-completion-pending::after { - position: absolute; - right: 8px; - top: 8px; -} .tasks-modal-content { max-width: 600px; width: min(600px, 92vw); background: var(--bg); font-size: 12px; } -.tasks-activity-card, -.tasks-activity-list { - min-height: 0; -} -.tasks-activity-list { - overflow-y: auto; - -webkit-overflow-scrolling: touch; -} .task-completed-preview-row { cursor: default; margin-bottom: 6px; @@ -27799,9 +27722,6 @@ body:not(.welcome-ready) #welcome-screen { .task-log-row.task-log-row-error .task-log-task-icon { color: var(--red, #f87171); } -.task-log-row.task-log-row-error .task-log-task-icon svg { - opacity: 0.82 !important; -} .task-log-task-icon svg { top: 0 !important; opacity: 0.46 !important; @@ -27844,12 +27764,6 @@ body:not(.welcome-ready) #welcome-screen { font-size: 11px; opacity: 0.75; } -.task-log-running-inline .task-log-running-label { font-weight: 500; } -.task-log-running-elapsed { - margin-left: 6px; - opacity: 0.6; - font-variant-numeric: tabular-nums; -} .task-log-force-run { appearance: none; box-sizing: border-box; @@ -27943,10 +27857,6 @@ body:not(.welcome-ready) #welcome-screen { border: 1px solid color-mix(in srgb, var(--accent, var(--red)) 35%, transparent); vertical-align: 1px; } -.task-log-time { - opacity: 0.5; - font-variant-numeric: tabular-nums; -} .task-log-status { width: 7px; height: 7px; @@ -27961,10 +27871,6 @@ body:not(.welcome-ready) #welcome-screen { .task-log-status-running { background: #60a5fa; animation: task-log-pulse 1.4s ease-in-out infinite; } .task-log-status-skipped { background: color-mix(in srgb, var(--fg) 20%, transparent); } .task-log-status-aborted { background: color-mix(in srgb, var(--fg) 30%, transparent); border: 1px dashed color-mix(in srgb, var(--fg) 50%, transparent); } -@keyframes task-log-pulse { - 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, #60a5fa 60%, transparent); } - 50% { box-shadow: 0 0 0 4px color-mix(in srgb, #60a5fa 0%, transparent); } -} .task-log-row-body { font-size: 12px; line-height: 1.5; @@ -27995,7 +27901,6 @@ body:not(.welcome-ready) #welcome-screen { margin: 4px 0; padding-left: 20px; } -.task-log-row-body li { margin: 2px 0; } /* Markdown headings inside a task result — without these, ## headings render at browser-default huge sizes and blow out the cramped row. */ .task-log-row-body h1, @@ -28014,11 +27919,6 @@ body:not(.welcome-ready) #welcome-screen { .task-log-row-body h1:first-child, .task-log-row-body h2:first-child, .task-log-row-body h3:first-child { margin-top: 0; } -.task-log-row-body hr { - border: none; - border-top: 1px solid color-mix(in srgb, var(--fg) 12%, transparent); - margin: 8px 0; -} .task-log-row-body blockquote { margin: 4px 0; padding: 2px 0 2px 10px; @@ -28147,13 +28047,8 @@ a.chat-link[href^="#research-"] { padding: 2px 0; color: transparent; /* hide raw "Show more" text */ } -.task-log-row-toggle::before { - color: color-mix(in srgb, var(--accent, var(--fg)) 80%, transparent); - opacity: 0.8; -} .task-log-row:not(.expanded) .task-log-row-toggle::before { content: 'Show more'; } .task-log-row.expanded .task-log-row-toggle::before { content: 'Show less'; } -.task-log-row-toggle:hover::before { opacity: 1; } .task-log-prompt { margin-top: 6px; font-size: 11px; @@ -28398,14 +28293,10 @@ a.chat-link[href^="#research-"] { max-width: 100%; min-width: 0; } -/* A with a clickable linkified span when the value contains a URL. */ @@ -40842,38 +40204,15 @@ body.notes-drag-mode .note-card-pin svg { color: var(--fg); cursor: text; } -.note-fullscreen-overlay .note-cl-text-reader a { - color: var(--accent, var(--red)); - text-decoration: underline; - text-underline-offset: 2px; -} -.note-fullscreen-overlay .note-cl-text-reader a:active { opacity: 0.7; } .note-fullscreen-overlay .note-cl-row.done .note-cl-text-reader { opacity: 0.5; text-decoration: line-through; } -/* Reminder bell + other header icon-buttons. Tightened down 2px so - the bell sits more proportionally next to the title field. */ -.note-fullscreen-overlay .note-form-icon-btn { - width: 36px; - height: 36px; -} .note-fullscreen-overlay .note-form-icon-btn svg { width: 16px; height: 16px; } -/* The plain-note textarea was rows="4" — fine for an in-grid card but - cramped in fullscreen. Let it grow to fill the available height so - writing feels like a real notepad, not a tweet box. The read-mode - reader inherits the same minimum so the layout doesn't jump when - the user taps to edit. */ -.note-fullscreen-overlay .note-form-content, -.note-fullscreen-overlay .note-form-content-reader { - min-height: 55vh; - font-size: 15px; - line-height: 1.55; -} /* Tags input is JS-relocated into the bottom actions row, pinned left of Cancel/Update. Style it as a dashed pill so it reads as @@ -40890,19 +40229,7 @@ body.notes-drag-mode .note-card-pin svg { text-align: left; } -/* Reorganized meta-row layout for fullscreen: color picker pinned to - the LEFT, type-toggle (Note/Todo/Draw) shoved to the RIGHT, with - the photo button next to the color picker. Tags are moved up into - the form header (next to the reminder bell) via JS. */ -.note-fullscreen-overlay .note-form-meta { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 8px; - padding-top: 8px; -} .note-fullscreen-overlay .note-color-picker { order: 1; } -.note-fullscreen-overlay .note-form-photo-btn { order: 2; } .note-fullscreen-overlay .note-form-type-seg { order: 3; margin-left: auto; /* shove right */ @@ -40920,10 +40247,6 @@ body.notes-drag-mode .note-card-pin svg { gap: 8px; margin-top: 6px; } -.note-fullscreen-overlay .note-form-actions-group .note-form-cancel, -.note-fullscreen-overlay .note-form-actions-group .note-form-save { - flex: 0 0 auto; -} .notes-mobile-grabber { display: none; } /* Notes panel: mounted like a window, docked to the right on desktop. */ @@ -40959,10 +40282,6 @@ body.notes-drag-mode .note-card-pin svg { backdrop-filter: none; -webkit-backdrop-filter: none; } -@keyframes notes-backdrop-fade-in { - from { opacity: 0; } - to { opacity: 1; } -} .notes-pane { display: flex; flex-direction: column; @@ -40993,22 +40312,6 @@ body.notes-drag-mode .note-card-pin svg { box-shadow: 4px 0 14px rgba(0, 0, 0, 0.18); transition: none !important; } -@keyframes notes-pane-enter { - from { transform: scale(0.96); opacity: 0; } - to { transform: scale(1); opacity: 1; } -} -.notes-pane.notes-pane-leaving { - animation: notes-pane-leave 160ms cubic-bezier(0.4, 0, 1, 1) both; - pointer-events: none; -} -@keyframes notes-pane-leave { - from { transform: scale(1); opacity: 1; } - to { transform: scale(0.96); opacity: 0; } -} -@media (prefers-reduced-motion: reduce) { - .notes-pane, - .notes-pane.notes-pane-leaving { animation: none; } -} .notes-pane-header { display: flex; align-items: center; @@ -41061,9 +40364,6 @@ body.notes-drag-mode .note-card-pin svg { border-radius: 10px; vertical-align: middle; } -/* Hide the "Add a to-do…" quick-add bar in archive view — you can't add - new items from the archive. */ -.notes-pane-archive .notes-quick-add { display: none !important; } .notes-pane-archive .note-card { background: color-mix(in srgb, #b48a4a 8%, var(--panel)); border-color: color-mix(in srgb, #b48a4a 25%, var(--border)); @@ -41230,7 +40530,6 @@ body.notes-drag-mode .note-card-pin svg { opacity: 0; transition: opacity 0.12s, color 0.12s; } -.note-checkbox:hover .note-checkbox-agent { opacity: 0.55; } .note-checkbox-agent:hover { background: transparent; opacity: 1 !important; @@ -41299,19 +40598,6 @@ body.notes-drag-mode .note-card-pin svg { .note-card.note-card-reminder-fired { animation: note-reminder-pulse 1.2s ease-in-out 2; } -@keyframes note-reminder-pulse { - 0%, 100% { - box-shadow: - inset 0 2px 0 0 color-mix(in srgb, var(--fg) 14%, transparent), - 0 0 0 0 color-mix(in srgb, var(--accent, var(--red)) 0%, transparent); - } - 50% { - box-shadow: - inset 0 2px 0 0 color-mix(in srgb, var(--fg) 14%, transparent), - 0 0 0 5px color-mix(in srgb, var(--accent, var(--red)) 26%, transparent), - 0 0 18px color-mix(in srgb, var(--accent, var(--red)) 30%, transparent); - } -} /* Sticky outside glow — applied to the exact note whose reminder fired. It stays until the user interacts with that card. */ .note-card.note-card-reminder-fired-sticky { @@ -41320,24 +40606,6 @@ body.notes-drag-mode .note-card-pin svg { outline-offset: 2px; animation: note-reminder-glow 1.6s ease-in-out infinite; } -@keyframes note-reminder-glow { - 0%, 100% { - box-shadow: - inset 0 2px 0 0 color-mix(in srgb, var(--fg) 14%, transparent), - 0 0 0 3px color-mix(in srgb, var(--accent, var(--red)) 14%, transparent), - 0 0 14px color-mix(in srgb, var(--accent, var(--red)) 18%, transparent); - } - 50% { - box-shadow: - inset 0 2px 0 0 color-mix(in srgb, var(--fg) 14%, transparent), - 0 0 0 6px color-mix(in srgb, var(--accent, var(--red)) 22%, transparent), - 0 0 26px color-mix(in srgb, var(--accent, var(--red)) 30%, transparent); - } -} -.note-card-selected { - outline: 2px solid var(--accent); - outline-offset: -2px; -} /* Hover-only buttons (Google Keep style) */ .note-card-select, @@ -41359,8 +40627,6 @@ body.notes-drag-mode .note-card-pin svg { z-index: 2; transition: opacity 0.15s, transform 0.15s, background 0.15s; } -.note-card-select { left: -8px; } -.note-card-pin { right: -8px; } /* Pencil + checkmark glyphs both have empty space along the top of their 24×24 viewBox, so flex-centering leaves them sitting visually high. Nudge the inner SVG down a touch to compensate. */ @@ -41451,15 +40717,6 @@ body.notes-drag-mode .note-card-pin svg { border-color: color-mix(in srgb, var(--fg) 18%, transparent); } } -/* Pin button on mobile — only reveal once the user has long-pressed to - enter rearrange (drag) mode. Outside drag mode the card stays clean. */ -body.notes-mobile-mode.notes-drag-mode .note-card-pin { - display: flex !important; - opacity: 0.7; -} -body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { - opacity: 1; -} /* Unarchive corner reuses the pencil's spot in archive view. */ .note-card-unarchive-corner:hover, .note-card-unarchive-corner:focus-visible { @@ -41512,9 +40769,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { border-color: color-mix(in srgb, var(--fg) 18%, transparent); } } -/* Edit + Done are now side-by-side at top-right by default — title-only - fallback no longer needed. */ -.note-card-selectmode .note-card-done { display: none !important; } /* Copy corner — bottom-right of the card. Same opaque-fill pattern as trash/unarchive so the underlying text/image never bleeds through. */ @@ -41539,7 +40793,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { z-index: 2; } .note-card-corner-copy svg { position: relative; top: 1px; opacity: 0.85; transition: opacity 0.15s; } -.note-card:hover .note-card-corner-copy { visibility: visible; } .note-card-corner-copy:hover, .note-card-corner-copy:focus-visible { background: color-mix(in srgb, var(--accent) 18%, var(--panel)); @@ -41551,10 +40804,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { .note-card-corner-copy { visibility: visible; } .note-card-corner-copy svg { opacity: 0.7; } } -/* Copy stays on every active card regardless of body shape — Edit + Done - live at the top-right pair, so the bottom-right copy slot is always - free. Hidden only in select mode. */ -.note-card-selectmode .note-card-corner-copy { display: none !important; } /* ── Archive view corners — trash (top-left) + unarchive (top-right) ── */ /* Background fill stays fully opaque (var(--panel)) so the note text or @@ -41582,10 +40831,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { } .note-card-corner-trash svg, .note-card-corner-unarchive svg { opacity: 0.85; transition: opacity 0.15s; } -.note-card-corner-trash { left: 6px; } -.note-card-corner-unarchive { right: 6px; } -.note-card:hover .note-card-corner-trash, -.note-card:hover .note-card-corner-unarchive { visibility: visible; } .note-card-corner-trash:hover, .note-card-corner-trash:focus-visible { background: color-mix(in srgb, var(--red) 18%, var(--panel)); @@ -41634,10 +40879,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { flex-shrink: 0; animation: note-ai-shine 2.4s ease-in-out infinite; } -@keyframes note-ai-shine { - 0%, 100% { opacity: 0.85; filter: drop-shadow(0 0 0 transparent); } - 50% { opacity: 1; filter: drop-shadow(0 0 4px color-mix(in srgb, var(--accent, var(--red)) 60%, transparent)); } -} .note-card-ai-solving { cursor: default; background: color-mix(in srgb, var(--fg) 8%, transparent); @@ -41660,11 +40901,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { height: 22px !important; animation: note-ai-shine 2.4s ease-in-out infinite; } -.note-form-improve-btn:disabled, -.note-form-improve-btn.busy { - opacity: 0.6; - cursor: wait; -} .note-form-improve-btn.busy svg { animation: spin 0.9s linear infinite; filter: none; @@ -41707,27 +40943,8 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { padding-left: 28px; cursor: pointer; } -/* In select mode the whole card is a checkbox — kill every hover affordance - that would otherwise suggest "preview" or "open" so users know exactly - what their tap will do (toggle selection). */ -.note-card-selectmode .note-card-pin, -.note-card-selectmode .note-card-actions { pointer-events: none; opacity: 0.4; } -.note-card-selectmode .note-card-edit-corner, -.note-card-selectmode .note-card-pin { - display: none !important; -} .note-card-selectmode:hover { background: color-mix(in srgb, var(--fg) 3%, transparent) !important; } -.note-card-selectmode .note-card-title:hover { opacity: 1 !important; } -.note-card-selectmode .note-card-edit-corner, -.note-card-selectmode:hover .note-card-edit-corner { opacity: 0 !important; } -/* The familiar home-screen edit-mode cue: mobile note cards gently jiggle - while Select mode is active, making it clear that the bar is now selecting - items rather than opening them. */ -@keyframes notes-select-jiggle { - 0%, 100% { transform: rotate(-0.3deg) translateY(0); } - 50% { transform: rotate(0.3deg) translateY(-0.25px); } -} @media (max-width: 768px) { body.notes-mobile-mode .note-card-selectmode { animation: notes-select-jiggle 0.34s cubic-bezier(0.42, 0, 0.58, 1) infinite; @@ -41802,7 +41019,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { border-radius: 3px; transition: opacity 0.15s, background 0.15s; } -.note-card-action svg { transform: translateY(2px); } /* Note image */ .note-card-image { @@ -41890,10 +41106,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { hovers or focuses it. */ animation: notes-quick-pulse 2.8s ease-in-out infinite; } -@keyframes notes-quick-pulse { - 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent, var(--red)) 0%, transparent); } - 50% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, var(--red)) 14%, transparent); } -} .notes-quick-add:hover { border-color: color-mix(in srgb, var(--accent, var(--red)) 55%, var(--border)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, var(--red)) 18%, transparent); @@ -41916,36 +41128,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { font-size: 12px; padding: 6px 0; } -.notes-quick-input::placeholder { - color: color-mix(in srgb, var(--fg) 45%, transparent); -} -/* Blinking text caret hint before the placeholder so empty + unfocused - reads as a live input. Sits on the wrapper because elements - can't carry ::before. The pseudo-element is ALWAYS rendered (so its - width is reserved and the placeholder doesn't jump left when the - hint hides); only the colour/animation toggle, not the layout. */ -.notes-quick-add::before { - content: '|'; - color: var(--accent, var(--red)); - margin-right: 6px; - font-weight: 500; - font-size: 13px; - animation: notes-quick-caret 1s steps(2, jump-none) infinite; - pointer-events: none; -} -/* Hide visually (keep space) on hover, focus, or once the input has any - text — prevents the layout shift the user reported when the hint - collapsed and the placeholder slid left. */ -.notes-quick-add:hover::before, -.notes-quick-add:focus-within::before, -.notes-quick-add:not(:has(.notes-quick-input:placeholder-shown))::before { - visibility: hidden; - animation: none; -} -@keyframes notes-quick-caret { - 0%, 49% { opacity: 1; } - 50%, 100%{ opacity: 0; } -} .notes-quick-icon { background: none; border: none; @@ -41989,7 +41171,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1); z-index: 0; } -.notes-quick-type-seg.is-todo::before { transform: translateX(100%); } .notes-quick-type-pill { background: none; border: none; @@ -42078,11 +41259,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { background-size: 200% 100%; animation: notes-skeleton-shimmer 1.4s ease-in-out infinite; } -.notes-skeleton-card.short { height: 46px; } -@keyframes notes-skeleton-shimmer { - 0% { background-position: 200% 0; } - 100% { background-position: -200% 0; } -} /* Type toggle (note vs todo) */ .note-form-type-row { @@ -42138,16 +41314,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { .note-form-remind-btn > svg.jingling { animation: cal-bell-jingle 0.65s cubic-bezier(0.36, 0, 0.66, -0.56) both; } -@keyframes cal-bell-jingle { - 0% { transform: rotate(0deg); } - 15% { transform: rotate(-22deg); } - 30% { transform: rotate(18deg); } - 45% { transform: rotate(-14deg); } - 60% { transform: rotate(10deg); } - 75% { transform: rotate(-6deg); } - 88% { transform: rotate(3deg); } - 100% { transform: rotate(0deg); } -} @media (prefers-reduced-motion: reduce) { .cal-remind-bell.jingling, .note-form-remind-btn > svg.jingling { animation: none; } @@ -42159,7 +41325,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { flex-wrap: wrap; gap: 4px; } -.note-form-reminder-tags:empty { display: none; } .note-reminder-tag { display: inline-flex; align-items: center; @@ -42346,7 +41511,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { transition: background 0.1s, border-color 0.1s, color 0.1s; padding: 0; } -.note-reminder-day-chip.wide { padding: 0 6px; } .note-reminder-day-chip:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); @@ -42385,22 +41549,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { position: relative; flex-shrink: 0; } -.note-form-type-seg::before { - content: ''; - position: absolute; - top: 0; - left: 0; - /* 3 pills now (note / todo / draw) — Goal was removed. Slider takes - 1/3 of the track and translates by full multiples of itself. */ - width: 33.3333%; - height: 100%; - background: color-mix(in srgb, var(--fg) 10%, transparent); - border-radius: 9px; - transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); - z-index: 0; -} -.note-form-type-seg.is-todo::before { transform: translateX(100%); } -.note-form-type-seg.is-draw::before { transform: translateX(200%); } .note-form-type-pill { background: none; border: none; @@ -42512,13 +41660,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { .notes-search-bar .memory-search-input:focus { border-color: var(--red); } -/* Bulk-bar appears under the search bar — inset its sides to match the - search bar's own 8px horizontal padding so the two visually align. */ -#notes-bulk-bar.memory-bulk-bar { - margin: 0 8px 4px; - position: relative; - top: 4px; -} /* Grid view: true CSS Grid plus JS-computed row spans, so cards masonry-pack vertically without the jumpy rebalancing of CSS columns. */ @@ -42649,9 +41790,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { .notes-pane-body .doclib-chip-scroll-arrow.right { top: calc(50% - 6px) !important; } -#tasks-filter-chips { - top: 0 !important; -} .doclib-chip-scroll-frame:has(> #tasks-filter-chips) .doclib-chip-scroll-arrow { top: calc(50% - 9px) !important; } @@ -42824,14 +41962,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { line-height: 1; z-index: 2; } -.note-card-goal .note-card-header { - /* Goal cards reserve space for the pill so the title doesn't collide. */ - padding-left: 56px; -} -/* In select mode the left-side checkbox takes the pill's spot — drop it - so the row stays legible. */ -.note-card-selectmode.note-card-goal .note-goal-pill { display: none; } -.note-card-selectmode.note-card-goal .note-card-header { padding-left: 0; } /* Description blurb above the checklist on goal cards */ .note-goal-desc { font-size: 12px; @@ -42886,48 +42016,10 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { background: color-mix(in srgb, var(--accent-warm) 26%, transparent); border-color: color-mix(in srgb, var(--accent-warm) 65%, transparent); } -.note-form-goal-ai:disabled, -.note-form-goal-ai.busy { - opacity: 0.6; - cursor: wait; -} .note-form-goal-hint { font-size: 11px; opacity: 0.55; } -/* Fresh goal form: hide the title input + tag input + reminder button so the - user only sees the single "what do you want to achieve?" textarea. */ -.note-form-goal-fresh ~ .note-form-actions-group { display: none; } -.note-form:has(.note-form-goal-fresh) .note-form-title, -.note-form:has(.note-form-goal-fresh) .note-form-label, -.note-form:has(.note-form-goal-fresh) .note-form-remind-btn, -.note-form-bespoke:has(.note-form-goal-fresh) .note-form-title, -.note-form-bespoke:has(.note-form-goal-fresh) .note-form-label, -.note-form-bespoke:has(.note-form-goal-fresh) .note-form-remind-btn { - display: none !important; -} -.note-form-goal-fresh .note-form-goal-desc { - font-size: 15px; - min-height: 90px; - padding: 12px 14px; -} -.note-form-goal-fresh.building .note-form-goal-desc { - opacity: 0.55; - pointer-events: none; -} -.note-form-goal-fresh.building::after { - content: 'AI is planning your goal…'; - display: block; - text-align: center; - font-size: 12px; - opacity: 0.7; - margin-top: 6px; - animation: note-goal-pulse 1.4s ease-in-out infinite; -} -@keyframes note-goal-pulse { - 0%, 100% { opacity: 0.5; } - 50% { opacity: 1; } -} /* ── Today view ──────────────────────────────────────────────────────── */ .notes-today-wrap { @@ -42963,10 +42055,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { border-radius: 8px; transition: opacity 0.2s, transform 0.2s; } -.notes-today-row.done { - opacity: 0.35; - transform: scale(0.98); -} .notes-today-row .note-check-dot { flex-shrink: 0; width: 18px; @@ -43001,7 +42089,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { text-overflow: ellipsis; white-space: nowrap; } -.notes-today-title:hover { text-decoration: underline; } .notes-today-step { font-size: 14px; color: var(--fg); @@ -43028,10 +42115,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { opacity: 0.6; margin-left: 4px; } -.notes-bulk-btn { - opacity: 0.6; -} -.notes-bulk-btn:hover { opacity: 1; } /* Form label input */ .note-form-label { @@ -43048,14 +42131,10 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { transition: opacity 0.15s, border-color 0.15s; } .note-form-label:hover, .note-form-label:focus { opacity: 1; border-color: var(--border); } -.note-form-label.flash-once { - animation: noteLabelFlash 0.6s ease-out; -} @keyframes noteLabelFlash { 0% { background: color-mix(in srgb, var(--accent) 35%, transparent); } 100% { background: transparent; } } -.note-form-label:not([value=""]) { opacity: 0.9; border-style: solid; } .note-card-header { display: flex; @@ -43073,13 +42152,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { text-overflow: ellipsis; white-space: nowrap; } -.note-card-title:hover { opacity: 0.7; } -.note-card-title.empty::before { - content: 'No title'; - font-weight: 500; - opacity: 0.3; - font-style: italic; -} .note-content-preview { font-size: 12px; @@ -43149,8 +42221,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { opacity: 1; font-weight: 600; } -/* Note card drag */ -.note-card { cursor: grab; } .note-card:active { cursor: grabbing; } /* Dragged card = "drop preview" — it already sits at the swap-target slot, so making it the most visible card on screen tells the user exactly where @@ -43195,7 +42265,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { justify-content: center; transition: opacity 0.15s; } -.note-cl-row:hover .note-cl-grip { opacity: 0.6; } .note-cl-row.dragging { opacity: 0.4; background: color-mix(in srgb, var(--accent) 8%, transparent); @@ -43228,7 +42297,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { .note-archive-btn { background: none; border: none; color: var(--fg); opacity: 0.2; cursor: pointer; padding: 2px; transition: opacity 0.15s; } -.note-archive-btn:hover { opacity: 0.7; } /* Checklist preview — cap height so cards with 30 items don't push the grid layout into oblivion; the inner list scrolls inside the card. */ @@ -43251,24 +42319,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { margin-right: -22px; padding-right: 4px; } -.note-checklist-preview > .note-checkbox:last-child .note-check-text { - /* Reserve room on the LAST row only for the bottom-right copy button so it - doesn't cover the final item's tail. Applied to the text — not to the - row — so the X delete button still reaches the same edge it does on - every other row. */ - padding-right: 30px; -} -.note-card.doclib-card-expanded .note-checklist-preview { - /* When the card is the expanded one in the grid, let the list use the - whole available height instead of the compact cap. */ - max-height: none; -} -.note-checklist-preview:empty::before { - content: 'No todos'; - font-size: 10px; - opacity: 0.3; - font-style: italic; -} .note-cl-quickadd { /* In flow now (was position:absolute), rendered AFTER the reminder badge so the "+ Add item" input sits underneath the reminder instead of @@ -43282,11 +42332,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { pointer-events: none; transition: opacity 0.15s; } -.note-card:hover .note-cl-quickadd, -.note-cl-quickadd:focus-within { - opacity: 1; - pointer-events: auto; -} .note-cl-quickadd-input { width: 100%; background: transparent; @@ -43300,9 +42345,7 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { opacity: 0.6; transition: opacity 0.15s, border-color 0.15s; } -.note-cl-quickadd-input::placeholder { color: var(--fg); opacity: 0.5; } .note-cl-quickadd-input:focus { opacity: 1; border-top-color: var(--border); } -.note-card-selectmode .note-cl-quickadd { display: none !important; } .note-checkbox { display: flex; align-items: center; @@ -43343,14 +42386,8 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { margin-left: 2px; transition: opacity 0.12s, background 0.12s, color 0.12s; } -.note-checkbox-rm { margin-left: auto; } -.note-checkbox-edit { margin-left: auto; } -.note-checkbox:hover .note-checkbox-edit, -.note-checkbox:hover .note-checkbox-rm { opacity: 0.55; } .note-checkbox-rm:hover { opacity: 1 !important; color: var(--red); background: color-mix(in srgb, var(--red) 12%, transparent); } .note-checkbox-edit:hover { opacity: 1 !important; color: var(--accent, var(--blue)); background: color-mix(in srgb, var(--accent, var(--blue)) 12%, transparent); } -.note-card-selectmode .note-checkbox-edit, -.note-card-selectmode .note-checkbox-rm { display: none; } .note-check-text[contenteditable="true"] { background: color-mix(in srgb, var(--fg) 8%, transparent); outline: 1px solid var(--accent, var(--blue)); @@ -43376,20 +42413,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { transform-origin: left center; transition: background 0.2s, border-color 0.2s, transform 0.15s cubic-bezier(0.34, 1.56, 0.64, 1); } -.note-check-dot::after { - content: ''; - position: absolute; - left: 50%; - top: 45%; - width: 7px; - height: 3.5px; - border-left: 1.75px solid #fff; - border-bottom: 1.75px solid #fff; - transform: translate(-50%, -50%) rotate(-45deg) scale(0); - transform-origin: center; - transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); -} -.notes-select-mode .note-checkbox { cursor: default; pointer-events: none; } .notes-select-mode .note-checkbox:hover { background: transparent; } .notes-select-mode .note-checkbox:hover .note-check-dot { transform: none; border-color: color-mix(in srgb, var(--fg) 35%, transparent); } .note-checkbox:hover .note-check-dot { @@ -43400,47 +42423,17 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { top: 0 !important; transform: translateY(2px) scale(1.15) !important; } -.note-checkbox:active .note-check-dot { - transform: scale(0.9); -} .note-checkbox.done .note-check-dot { background: var(--accent); border-color: var(--accent); animation: note-check-pop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1); } -.note-checkbox.done .note-check-dot::after { - transform: translate(-50%, -50%) rotate(-45deg) scale(1); -} -@keyframes note-check-pop { - 0% { transform: scale(1); } - 40% { transform: scale(1.35); } - 100% { transform: scale(1); } -} .note-check-text { transition: opacity 0.25s; line-height: 1.3; padding-right: 4px; word-break: break-word; } -.note-checkbox.done .note-check-text { - position: relative; - opacity: 0.4; -} -.note-checkbox.done .note-check-text::after { - content: ''; - position: absolute; - left: 0; - right: 0; - top: calc(50% - 1px); - height: 1px; - background: currentColor; - animation: note-strike 0.3s ease-out forwards; - transform-origin: left center; -} -@keyframes note-strike { - 0% { transform: scaleX(0); } - 100% { transform: scaleX(1); } -} /* Due date badge */ .note-due-badge { @@ -43466,16 +42459,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { .note-color-blue { background: color-mix(in srgb, var(--hl-function) 18%, var(--panel)); border-color: color-mix(in srgb, var(--hl-function) 30%, var(--border)); } .note-color-purple { background: color-mix(in srgb, var(--hl-keyword) 18%, var(--panel)); border-color: color-mix(in srgb, var(--hl-keyword) 30%, var(--border)); } -/* 3D top-edge highlight — an inset 2px stripe inside every note card that - reads as a lifted "glassy" lip. Each colored note gets a stronger stripe - in its own hue so the colour reads even before you focus on the card. */ -.note-card { box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--fg) 14%, transparent); } -.note-color-red { box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--red) 55%, transparent); } -.note-color-orange { box-shadow: inset 0 2px 0 0 color-mix(in srgb, #d19a66 60%, transparent); } -.note-color-yellow { box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--hl-string) 60%, transparent); } -.note-color-green { box-shadow: inset 0 2px 0 0 color-mix(in srgb, #98c379 60%, transparent); } -.note-color-blue { box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--hl-function) 60%, transparent); } -.note-color-purple { box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--hl-keyword) 60%, transparent); } /* Standard notes use a small identity palette when no color was selected. The variation is deliberately limited to the card tint, top edge, and @@ -43497,11 +42480,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { background: color-mix(in srgb, var(--note-accent) 10%, transparent); color: color-mix(in srgb, var(--note-accent) 86%, var(--fg)); } -.note-card.note-standard-v0 { --note-accent: #db8576; } -.note-card.note-standard-v1 { --note-accent: #d2a45f; } -.note-card.note-standard-v2 { --note-accent: #72ad8d; } -.note-card.note-standard-v3 { --note-accent: #72a5cf; } -.note-card.note-standard-v4 { --note-accent: #aa86c7; } /* Color picker dots */ .note-color-picker { @@ -43641,7 +42619,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { opacity: 1; background: color-mix(in srgb, var(--fg) 10%, transparent); } -.note-type-btn:hover { opacity: 0.8; } .note-form-content { background: transparent; @@ -43666,10 +42643,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { gap: 6px; flex-wrap: wrap; } -.note-form-meta .note-form-label { - width: 112px; - flex: 0 1 140px; -} .note-form-meta .note-color-picker { gap: 3px; } .note-form-actions-group { display: flex; @@ -43810,21 +42783,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { box-sizing: border-box; flex: 0 0 24px; } -/* After attachColorPicker swaps the input to type=text + .cp-swatch-input, - re-pin the swatch to a 24px circle (otherwise it inherits text-input - sizing and becomes a giant rectangle). */ -.note-form-draw-color.cp-swatch-input { - width: 24px !important; - height: 24px !important; - min-width: 24px !important; - max-width: 24px !important; - border-radius: 50%; - padding: 0; - box-sizing: border-box; -} -.note-form-draw-color::-webkit-color-swatch-wrapper { padding: 0; border-radius: 50%; } -.note-form-draw-color::-webkit-color-swatch { border: none; border-radius: 50%; } -.note-form-draw-color::-moz-color-swatch { border: none; border-radius: 50%; } .note-form-draw-size-wrap { width: 110px; display: inline-flex; align-items: center; } .note-form-photo-plus { font-size: 16px; @@ -43845,33 +42803,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { cursor: pointer; transition: height 0.15s ease; } -.note-form-draw-size:hover, -.note-form-draw-size:focus, -.note-form-draw-size:active { height: 10px; } -.note-form-draw-size::-webkit-slider-thumb { - -webkit-appearance: none; - appearance: none; - width: 12px; height: 12px; - border-radius: 50%; - background: var(--red); - border: none; - cursor: pointer; - transition: width 0.12s ease, height 0.12s ease; -} -.note-form-draw-size::-moz-range-thumb { - width: 12px; height: 12px; - border-radius: 50%; - background: var(--red); - border: none; - cursor: pointer; - transition: width 0.12s ease, height 0.12s ease; -} -.note-form-draw-size:hover::-webkit-slider-thumb, -.note-form-draw-size:focus::-webkit-slider-thumb, -.note-form-draw-size:active::-webkit-slider-thumb { width: 18px; height: 18px; } -.note-form-draw-size:hover::-moz-range-thumb, -.note-form-draw-size:focus::-moz-range-thumb, -.note-form-draw-size:active::-moz-range-thumb { width: 18px; height: 18px; } /* Brush | Eraser segmented toggle — sliding pill, same recipe as Note/Todo. */ .note-form-draw-be { display: inline-flex; @@ -43885,19 +42816,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { flex-shrink: 0; background: color-mix(in srgb, var(--fg) 5%, transparent); } -.note-form-draw-be::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 50%; - height: 100%; - background: var(--accent); - border-radius: 9px; - transition: transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1); - z-index: 0; -} -.note-form-draw-be.is-eraser::before { transform: translateX(100%); } .note-form-draw-be-btn { background: none; border: none; @@ -43916,7 +42834,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { .note-form-draw-be-btn:hover { color: var(--fg); } /* Active side picks up the theme accent so brush vs eraser is unmistakable. */ .note-form-draw-be-btn.active { color: var(--accent-primary, var(--red)); } -.note-form-draw-be-btn:focus { outline: none; } .note-form-draw-text, .note-form-draw-line, @@ -43963,7 +42880,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { defined accent so the S/M/L size badge actually shows in theme colour. */ color: var(--accent-primary, var(--red)); } -.note-form-draw-text-badge:empty { display: none; } .note-form-draw-shape-badge { position: absolute; right: 3px; @@ -43975,7 +42891,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { letter-spacing: 0.3px; color: var(--accent-primary, var(--red)); } -.note-form-draw-shape-badge:empty { display: none; } .note-form-draw-text:hover, .note-form-draw-line:hover, .note-form-draw-circle:hover, @@ -43992,22 +42907,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 50%, var(--border)); } -/* Reflect the chosen size in the icon itself, so the user sees at a glance - which size (S/M/L) is active without needing the tiny badge. */ -.note-form-draw-line.size-s svg line, -.note-form-draw-circle.size-s svg circle { stroke-width: 1.2; } -.note-form-draw-line.size-m svg line, -.note-form-draw-circle.size-m svg circle { stroke-width: 3; } -.note-form-draw-line.size-l svg line, -.note-form-draw-circle.size-l svg circle { stroke-width: 5; } -.note-form-draw-text.size-s { font-size: 13px; } -.note-form-draw-text.size-m { font-size: 18px; } -.note-form-draw-text.size-l { font-size: 23px; line-height: 1; } -/* Narrow widths: shrink the tag input to make room for the action group; - the hashtag-in-content shortcut still works, so the input can be tiny. */ -@media (max-width: 600px) { - .note-form-meta .note-form-label { width: 78px; flex-shrink: 1; min-width: 0; } -} .note-form-due { background: transparent; border: 1px dashed color-mix(in srgb, var(--border) 60%, transparent); @@ -44020,7 +42919,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { transition: opacity 0.15s, border-color 0.15s; } .note-form-due:hover, .note-form-due:focus { opacity: 0.9; border-color: var(--border); } -.note-form-due:not([value=""]) { opacity: 0.85; border-style: solid; } .note-form-actions { display: flex; @@ -44122,7 +43020,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { padding: 4px 0; text-align: left; } -.note-cl-add:hover { opacity: 0.7; } /* ── Calendar ── */ .cal-modal-content { width:min(680px, 94vw); max-height:88vh; overflow-x:hidden; position:relative; } @@ -44198,12 +43095,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { transition: opacity 0.18s ease; } .cal-quickadd-hint .qa-hint-example.qa-hint-fade { opacity: 0; } -/* Matching ↵ hint at the right of the event title while it's empty; hidden once - editing (the ✓ Done button takes over then). */ -/* Title placeholder overlay: the prompt text with a ↵ enter glyph right after - it (accent), so it's clear the field submits on Enter. Shown only while the - title is empty; the native placeholder is hidden in favour of this. */ -.cal-hero-title::placeholder { color: transparent; } .cal-title-hint { position: absolute; left: 0; @@ -44246,7 +43137,6 @@ body.notes-mobile-mode.notes-drag-mode .note-card-pin.active { height: 22px; padding: 0; } -.cal-quickadd-input::placeholder { color: transparent; } .cal-quickadd-status { font-size: 10px; opacity: 0.55; @@ -44290,10 +43180,6 @@ button.cal-nav.cal-toolbar-arrow { line-height: 1; opacity: 0.84; } -button.cal-nav.cal-toolbar-arrow:hover { - opacity: 1; - background: color-mix(in srgb, var(--bg) 76%, var(--fg) 24%); -} .cal-toolbar-arrow-glyph { position: relative; top: -1px; @@ -44386,11 +43272,6 @@ button.cal-nav.cal-toolbar-arrow:hover { padding: 0 0 3px; transition: opacity 0.12s ease, background 0.12s ease, transform 0.12s ease; } -.cal-side-nav-prev { left: 8px; } -.cal-side-nav-next { right: 8px; } -.cal-navigation-hidden .cal-side-nav { - display: none !important; -} .cal-modal-content:hover .cal-side-nav, .cal-side-nav:focus-visible { opacity: 0.84; @@ -44418,7 +43299,6 @@ button.cal-add-btn.cal-add-btn-text { margin-top: 0; transition: background 0.15s, border-color 0.15s; } -#cal-add { margin-left: auto; } /* Settings "+ Add server" matches the model-dir "+ Add" path button (22px). */ #cookbook-server-add.cal-add-btn-text { height: 28px; @@ -44446,26 +43326,6 @@ button.cal-add-btn.cal-add-btn-text:hover { button.cal-add-btn.cal-add-btn-text:hover .cal-add-plus { transform: rotate(180deg); } -/* Mobile tap-spin: a gentle quarter-turn nudge before the form opens. - `.cal-add-plus` has a `padding-bottom: 2px` (and a translateY on the - small variant) that offsets the glyph for optical centering — those - shift the rotation pivot off the visual centre. Force the box to - match the glyph and pin the transform-origin during the spin. */ -.cal-add-plus.cal-add-spinning { - display: inline-flex; - align-items: center; - justify-content: center; - padding: 0; - width: 1em; - height: 1em; - line-height: 1; - transform-origin: 50% 50%; - animation: cal-add-spin 0.28s ease-out forwards; -} -@keyframes cal-add-spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(90deg); } -} .cal-add-label { font-size:11px; font-weight:600; line-height:1; opacity:0.85; } /* Small variant of the toolbar's +New button. Inherits the .cal-add-btn-text styles (pill with "+" + "New" + spring-rotate on the +), so the @@ -44480,10 +43340,6 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm { gap: 0; transition: padding 0.25s ease, gap 0.25s ease, background 0.15s, border-color 0.15s; } -button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover { - padding: 0 8px 0 5px; - gap: 3px; -} /* Don't touch .cal-add-plus on the small variant — the toolbar +New is the reference and we want the same rotation centre / motion. The label is shrunk and hidden until hover so the pill is compact at rest. */ @@ -44721,10 +43577,6 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover .cal-add-label { opacity: 1; background: color-mix(in srgb, var(--fg) 10%, transparent) !important; } -.email-reminder-toggle-inline:hover svg { - animation: none !important; - transform: none !important; -} .email-reminder-toggle-inline.active { opacity: 1; background: color-mix(in srgb, var(--accent, var(--red)) 16%, transparent) !important; @@ -44789,10 +43641,6 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover .cal-add-label { opacity: 0.65; white-space: nowrap; } -.email-search-options-menu[hidden], -.email-search-options-menu button.hidden { - display: none !important; -} .email-search-options-menu button { width: 100%; border: 0; @@ -44833,16 +43681,6 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover .cal-add-label { padding: 6px 7px 5px; border-top: 1px solid color-mix(in srgb, var(--border) 65%, transparent); } -.email-search-date-panel[hidden] { display: none !important; } -.email-search-date-panel label { - display: grid; - grid-template-columns: 38px 1fr; - align-items: center; - gap: 6px; - margin: 0 0 6px; - color: color-mix(in srgb, var(--fg) 72%, transparent); - font-size: 10px; -} .email-search-date-panel input { width: 100%; height: 26px; @@ -44856,15 +43694,7 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover .cal-add-label { font: inherit; } .email-search-date-panel input:focus { border-color: var(--accent, var(--red)); } -.email-lib-filter-pill-icon-only .email-lib-filter-pill-label { display: none; } -.email-lib-filter-pill.email-lib-filter-pill-icon-only { padding-left: 5px !important; } .email-search-date-actions { display: flex; justify-content: flex-end; gap: 5px; } -.email-search-options-menu .email-search-date-actions button { - width: auto; - min-width: 48px; - justify-content: center; - padding: 5px 8px; -} .email-search-options-menu .email-search-date-actions [data-email-date-apply] { color: var(--accent, var(--red)); background: color-mix(in srgb, var(--accent, var(--red)) 12%, transparent); @@ -45031,23 +43861,6 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover .cal-add-label { height: 16px !important; } } -.email-attach-toggle:not(.email-attach-toggle-inline):hover svg { - animation: email-undone-jiggle 0.45s ease-in-out; - transform-origin: 50% 50%; -} -@keyframes email-undone-jiggle { - 0% { transform: rotate(0deg); } - 20% { transform: rotate(-14deg); } - 40% { transform: rotate(10deg); } - 60% { transform: rotate(-6deg); } - 80% { transform: rotate(3deg); } - 100% { transform: rotate(0deg); } -} -.email-undone-toggle:not(.email-undone-toggle-inline):hover svg, -.email-compose-jiggle:hover svg { - animation: email-undone-jiggle 0.45s ease-in-out; - transform-origin: 50% 50%; -} .email-accounts-row { display: flex; align-items: center; @@ -45058,23 +43871,6 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover .cal-add-label { /* Only the direct-child compose button gets pushed right; nested chips inside #email-lib-accounts pack to the left as normal flex items. */ .email-accounts-row > .memory-toolbar-btn { flex-shrink: 0; margin-left: auto; } -/* Account chips collapse to a single horizontally-scrollable strip - at every breakpoint, instead of stacking onto multiple rows when - there are several accounts. The compose "New" button stays outside - the scroller (it's a sibling of #email-lib-accounts inside - .email-accounts-row) so it remains pinned on the right. */ -#email-lib-accounts { - justify-content: flex-start; - flex-wrap: nowrap; - overflow-x: auto; - overflow-y: hidden; - scrollbar-width: none; - -ms-overflow-style: none; - scroll-snap-type: x proximity; - -webkit-overflow-scrolling: touch; -} -#email-lib-accounts::-webkit-scrollbar { display: none; height: 0; } -#email-lib-accounts > * { flex-shrink: 0; scroll-snap-align: start; } .email-account-chip { display: inline-flex; align-items: center; @@ -45085,11 +43881,6 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover .cal-add-label { background: color-mix(in srgb, var(--accent, var(--red)) 10%, transparent); color: color-mix(in srgb, var(--accent, var(--red)) 86%, var(--fg)); } -.email-account-chip.email-account-has-unread:not(.active) { - border-color: var(--border); - background: transparent; - color: var(--fg); -} .email-account-unread-dot { width: 6px; height: 6px; @@ -45146,7 +43937,6 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover .cal-add-label { text-align: center; pointer-events: none; } -#email-lib-grid { position: relative; } .date-section-header { display: flex; align-items: center; @@ -45191,10 +43981,6 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover .cal-add-label { #email-lib-grid .date-section-header { padding: 10px 5px 3px; } -#email-lib-grid .date-section-header.email-date-gap-break { - margin-top: 12px; - padding-top: 16px; -} #email-lib-modal .email-lib-sync-status { flex: 0 0 auto; min-height: 14px; @@ -45210,9 +43996,6 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover .cal-add-label { position: relative; top: 4px; } -#email-lib-modal.email-reading .email-lib-sync-status { - display: none; -} @media (max-width: 768px) { #email-lib-modal .email-lib-sync-status { min-height: 13px; @@ -45270,24 +44053,6 @@ button.cal-add-btn.cal-add-btn-text.cal-add-btn-sm:hover .cal-add-label { margin: 0; line-height: 1; } -button.cal-view-btn { - display: inline-flex; - align-items: center; - justify-content: center; - background: transparent; - border: none; - color: var(--fg); - font-size: 11px; - font-family: inherit; - font-weight: 500; - padding: 2px 12px 2px 12px; - margin: 0; - cursor: pointer; - opacity: 0.45; - line-height: 1; - height: 24px; - box-sizing: border-box; -} .cal-view-btn + .cal-view-btn { border-left: 1px solid var(--border); } .cal-view-btn:hover { opacity: 0.75; } .cal-view-btn.active { @@ -45315,14 +44080,9 @@ button.cal-view-btn { wraps a colored fill drawn by the browser; we need to round both the wrapper and the fill so it actually appears circular. */ .cal-s-color { border-radius: 50%; overflow: hidden; } -.cal-s-color::-webkit-color-swatch-wrapper { padding: 0; border-radius: 50%; } -.cal-s-color::-webkit-color-swatch { border: none; border-radius: 50%; } -.cal-s-color::-moz-color-swatch { border: none; border-radius: 50%; } .cal-filter-item { display:inline-flex; align-items:center; gap:4px; cursor:pointer; font-size:10px; padding:2px 8px; line-height:1.4; border-radius:10px; background:color-mix(in srgb, var(--bg) 72%, transparent); border:1px solid color-mix(in srgb, var(--fg) 12%, transparent); transition:opacity 0.15s, background 0.15s, border-color 0.15s, transform 0.15s; } .cal-filter-item:hover { background:color-mix(in srgb, var(--fg) 10%, transparent); } -.cal-filter-item.cal-filter-off { opacity:0.25; text-decoration:line-through; } .cal-filter-item.cal-filter-important { font-weight:700; color:#e5a33a; border-color:color-mix(in srgb, #e5a33a 40%, transparent); } -.cal-filter-item.cal-filter-important.cal-filter-active { background:color-mix(in srgb, #e5a33a 18%, transparent); border-color:#e5a33a; } /* Match the toolbar's other buttons (cal-nav, cal-view-btn, cal-add-btn-text): 24px tall, 11px font, 5px corners. */ .cal-filter-toggle { @@ -45364,21 +44124,6 @@ button.cal-view-btn { .cal-grid { display:flex; flex-direction:column; gap:1px; background:color-mix(in srgb, var(--fg) 8%, transparent); border-radius:6px; overflow:hidden; } .cal-week-headers { display:grid; grid-template-columns:repeat(7,1fr); gap:1px; } .cal-week-row { position:relative; display:grid; grid-template-columns:repeat(7,1fr); gap:1px; } -.cal-week-row > .cal-day { padding-top: calc(4px + var(--bars, 0) * 12px); } -@keyframes cal-slide-from-right { - from { opacity:0; transform:translateX(20px); } - to { opacity:1; transform:translateX(0); } -} -@keyframes cal-slide-from-left { - from { opacity:0; transform:translateX(-20px); } - to { opacity:1; transform:translateX(0); } -} -@keyframes cal-event-enter { - from { opacity:0; transform:translateY(3px) scale(0.985); } - to { opacity:1; transform:translateY(0) scale(1); } -} -.cal-slide-in-right { animation: cal-slide-from-right 0.22s cubic-bezier(0.25, 0.8, 0.25, 1); } -.cal-slide-in-left { animation: cal-slide-from-left 0.22s cubic-bezier(0.25, 0.8, 0.25, 1); } .cal-weekday { background:color-mix(in srgb, var(--fg) 5%, var(--bg)); text-align:center; font-size:10px; font-weight:600; opacity:0.4; padding:5px 0; } .cal-day { background: @@ -45397,33 +44142,11 @@ button.cal-view-btn { background: var(--bg); border-radius: 8px; } -.cal-day.cal-today .cal-day-num { color:var(--bg); font-weight:800; background:var(--accent, var(--red)); border-radius:10px; padding:1px 6px; display:inline-block; opacity:1; line-height:1.3; } -/* Selected day — same square geometry as `.cal-today` so the two read as - peers, but rendered as an outline + softer fill instead of a solid - accent block. Today wins when both classes are on the same cell. */ -.cal-day.cal-selected:not(.cal-today) { - box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent, var(--fg)) 65%, transparent); - background: color-mix(in srgb, var(--accent, var(--fg)) 12%, var(--bg)); - border-radius: 8px; -} .cal-day.cal-selected:not(.cal-today) .cal-day-num { color: var(--accent, var(--fg)); opacity: 1; font-weight: 700; } -.cal-day.cal-weekend:not(.cal-today) { background:color-mix(in srgb, var(--fg) 2.5%, var(--bg)); } -.cal-day.cal-empty-day::after { - content:''; - position:absolute; - left:8px; - right:8px; - bottom:8px; - height:1px; - background:color-mix(in srgb, var(--fg) 7%, transparent); - opacity:0.55; - pointer-events:none; -} -.cal-day.cal-other { opacity:0.34; } .cal-day.cal-drag-over { background:color-mix(in srgb, var(--accent) 18%, var(--bg)); } .cal-day.cal-range-select { background:color-mix(in srgb, var(--accent, var(--red)) 25%, var(--bg)); box-shadow:inset 0 0 0 1px var(--accent, var(--red)); } .cal-day-num { font-size:10px; font-weight:600; display:block; margin-bottom:1px; opacity:0.7; line-height:1.2; } @@ -45446,18 +44169,6 @@ button.cal-view-btn { transition:background 0.15s, box-shadow 0.15s, transform 0.15s; } .cal-event-row:hover { background:color-mix(in srgb, var(--fg) 10%, transparent); box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--fg) 14%, transparent); transform:translateY(-1px); } -.cal-event-row::after { - content:''; - width:3px; - height:11px; - margin-left:auto; - opacity:0; - flex:0 0 auto; - border-left:1px solid color-mix(in srgb, var(--fg) 34%, transparent); - border-right:1px solid color-mix(in srgb, var(--fg) 34%, transparent); - transition:opacity 0.15s; -} -.cal-event-row:hover::after { opacity:0.75; } .cal-event-row-dot { width:6px; height:6px; border-radius:50%; flex-shrink:0; box-shadow:0 0 0 1px color-mix(in srgb, var(--bg) 80%, transparent); } .cal-event-row-time { font-size:10px; opacity:0.72; font-variant-numeric:tabular-nums; flex-shrink:0; font-weight:600; } .cal-event-row-name { font-size:10px; opacity:0.96; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; flex:1; min-width:0; font-weight:600; } @@ -45551,7 +44262,6 @@ button.cal-view-btn { pointer-events: auto; box-shadow: 0 1px 2px color-mix(in srgb, #000 18%, transparent); } -.cal-dragging { opacity:0.3; } /* Splitter between the month/week grid and the day-tasks panel — drag vertically to give the day panel more room. Height clamped by the `--cal-detail-h` variable set on #cal-body by the splitter drag JS. */ @@ -45599,38 +44309,10 @@ button.cal-view-btn { overscroll-behavior: contain; flex-shrink: 0; } -#cal-body.cal-events-full > :is(.cal-grid, .cal-wk-wrap) { - display: none; -} -#cal-body.cal-events-full > .cal-day-detail { - height: auto; - min-height: 0; - flex: 1 1 auto; -} -#cal-body.cal-calendar-full > .cal-day-detail { - display: none; -} .cal-detail-header { display:flex; justify-content:space-between; align-items:center; font-size:12px; font-weight:600; margin-bottom:6px; padding-right:8px; } .cal-empty { font-size:11px; opacity:0.3; padding:4px 0; } .cal-event-item { display:flex; gap:9px; padding:8px 9px; border-radius:6px; cursor:pointer; align-items:flex-start; background:color-mix(in srgb, var(--fg) 3.5%, transparent); box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--fg) 6%, transparent); margin-bottom:4px; } .cal-event-item:hover { background:color-mix(in srgb, var(--fg) 8%, transparent); box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--fg) 12%, transparent); } -.cal-event-link-target { - animation: cal-event-link-target-flash 2.2s ease-out; - box-shadow: - inset 0 0 0 2px color-mix(in srgb, var(--accent, var(--red)) 88%, transparent), - 0 0 0 3px color-mix(in srgb, var(--accent, var(--red)) 20%, transparent), - 0 8px 20px color-mix(in srgb, var(--accent, var(--red)) 18%, transparent) !important; -} -@keyframes cal-event-link-target-flash { - 0%, 28% { - filter: brightness(1.18) saturate(1.12); - transform: translateY(-1px); - } - 100% { - filter: none; - transform: none; - } -} .cal-event-dot { width:9px; height:9px; border-radius:50%; flex-shrink:0; margin-top:4px; box-shadow:0 0 0 1px color-mix(in srgb, var(--bg) 80%, transparent); } .cal-event-info { flex:1; min-width:0; } .cal-event-name { font-size:13px; font-weight:700; line-height:1.25; color:color-mix(in srgb, var(--fg) 96%, transparent); overflow-wrap:anywhere; } @@ -45648,8 +44330,6 @@ button.cal-view-btn { } .cal-event-time { font-size:11px; opacity:0.68; line-height:1.35; margin-top:2px; font-weight:500; } .cal-event-loc { font-size:11px; opacity:0.58; line-height:1.35; margin-top:1px; } -.cal-event-loc a, .cal-event-time a { color:inherit; text-decoration:underline; text-decoration-color:color-mix(in srgb, currentColor 40%, transparent); } -.cal-event-loc a:hover, .cal-event-time a:hover { opacity:1; text-decoration-color:currentColor; } /* ── Week view: hour grid ────────────────────────────────────────── Vertical hour rail on the left, 7 day columns on the right with their own all-day strip and an absolute-positioned hour grid below it. */ @@ -45753,9 +44433,6 @@ button.cal-view-btn { opacity: 0.55; transition: opacity 0.15s, background 0.15s, border-color 0.15s; } -#cal-settings > svg { - top: 3px !important; -} .cal-wk-zoom:hover { opacity: 1; background: color-mix(in srgb, var(--fg) 8%, var(--bg)); @@ -45799,23 +44476,11 @@ button.cal-view-btn { top: 0; z-index: 40; } -.cal-wk-col.cal-wk-today .cal-wk-col-head { background: color-mix(in srgb, var(--accent, var(--red)) 12%, var(--bg)); } -.cal-wk-col.cal-wk-today .cal-wk-dn, -.cal-wk-col.cal-wk-today .cal-wk-dt { color: var(--accent, var(--red)); font-weight: 700; } -/* Sunday: a softer rest-day tint so the week edge reads visually, even - when today is mid-week. Falls back gracefully under the .cal-wk-today - rules above (today on a Sunday still gets the accent treatment). */ -.cal-wk-col.cal-wk-sun .cal-wk-col-head { background: color-mix(in srgb, var(--fg) 7%, var(--bg)); } -.cal-wk-col.cal-wk-sun .cal-wk-grid { background: color-mix(in srgb, var(--fg) 2.5%, var(--bg)); } -.cal-wk-col.cal-wk-sun .cal-wk-allday { background: color-mix(in srgb, var(--fg) 3%, var(--bg)); } -.cal-wk-col.cal-wk-sun .cal-wk-dn, -.cal-wk-col.cal-wk-sun .cal-wk-dt { color: color-mix(in srgb, var(--fg) 60%, transparent); } /* Today on a Sunday still wins the accent treatment. */ .cal-wk-col.cal-wk-today.cal-wk-sun .cal-wk-col-head { background: color-mix(in srgb, var(--accent, var(--fg)) 12%, var(--bg)); } .cal-wk-col.cal-wk-today.cal-wk-sun .cal-wk-dn, .cal-wk-col.cal-wk-today.cal-wk-sun .cal-wk-dt { color: var(--accent, var(--fg)); } .cal-wk-dn { font-weight: 600; opacity: 0.6; } -.cal-wk-dt { font-variant-numeric: tabular-nums; opacity: 0.5; } .cal-wk-allday { height: 24px; padding: 2px 4px; @@ -45833,7 +44498,6 @@ button.cal-view-btn { top: 32px; z-index: 39; } -.cal-wk-allday::-webkit-scrollbar { display: none; } .cal-wk-allday-event { font-size: 10.5px; font-weight: 700; @@ -45875,32 +44539,6 @@ button.cal-view-btn { z-index: 7; filter: drop-shadow(0 1px 3px color-mix(in srgb, var(--accent, var(--red)) 35%, transparent)); } -.cal-wk-now::before { - content: ''; - position: absolute; - left: -3px; - top: -4px; - width: 7px; - height: 7px; - border-radius: 50%; - background: var(--accent, var(--red, #f87171)); - box-shadow:0 0 0 3px color-mix(in srgb, var(--accent, var(--red)) 18%, transparent); -} -.cal-wk-now::after { - content:'now'; - position:absolute; - right:4px; - top:-10px; - padding:1px 5px; - border-radius:7px; - font-size:8px; - line-height:1.2; - font-weight:800; - text-transform:uppercase; - color:var(--bg); - background:var(--accent, var(--red)); - box-shadow:0 1px 4px color-mix(in srgb, #000 22%, transparent); -} /* Event blocks */ .cal-wk-block { position: absolute; @@ -45975,10 +44613,6 @@ button.cal-view-btn { overflow-wrap: anywhere; } } -@keyframes cal-wk-hover-label-reveal { - 0%, 35% { opacity: 0; } - 100% { opacity: 1; } -} @media (max-width: 768px) { /* Mobile week view: the hour rail already shows the time, so drop it from the card and let the title wrap to fill the freed space (more readable text). */ @@ -46038,41 +44672,6 @@ button.cal-view-btn { cursor: ns-resize; z-index: 3; } -.cal-wk-block:hover .cal-wk-block-resize::after { - content: ''; - position: absolute; - left: 30%; - right: 30%; - bottom: 1px; - height: 2px; - border-radius: 2px; - background: color-mix(in srgb, var(--fg) 35%, transparent); -} -.cal-wk-block::after { - content:''; - position:absolute; - top:6px; - right:5px; - width:3px; - height:14px; - opacity:0; - border-left:1px solid color-mix(in srgb, var(--fg) 35%, transparent); - border-right:1px solid color-mix(in srgb, var(--fg) 35%, transparent); - transition:opacity 0.15s; -} -.cal-wk-block:hover::after { opacity:0.75; } -.cal-wk-block-resize:hover::after { - background: color-mix(in srgb, var(--fg) 65%, transparent); -} -/* Body of a block while it's being repositioned: lifted shadow + above - siblings so the drop target reads clearly. */ -.cal-wk-block-ghost { - z-index: 6 !important; - box-shadow: 0 4px 12px color-mix(in srgb, var(--fg) 24%, transparent) !important; - cursor: grabbing; -} -.cal-wk-block { cursor: grab; } -.cal-wk-block:active { cursor: grabbing; } /* Drag-to-create ghost */ .cal-wk-ghost { position: absolute; @@ -46100,9 +44699,6 @@ button.cal-view-btn { pointer-events: auto; cursor: pointer; } -.cal-wk-slot-selected-label { - pointer-events: none; -} .cal-wk-slot-resize { position: absolute; left: 14%; @@ -46114,30 +44710,13 @@ button.cal-view-btn { touch-action: none; pointer-events: auto; } -.cal-wk-slot-resize::after { - content: ''; - position: absolute; - left: 18%; - right: 18%; - top: 6px; - height: 3px; - border-radius: 2px; - background: var(--accent, var(--fg)); - box-shadow: 0 0 0 2px color-mix(in srgb, var(--bg) 75%, transparent); -} -.cal-wk-col.cal-wk-slot-day-selected .cal-wk-col-head { - color: var(--accent, var(--fg)); - box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--accent, var(--fg)) 70%, transparent); -} .cal-year { display:grid; grid-template-columns:repeat(4, 1fr); gap:10px; } .cal-year-month { background:color-mix(in srgb, var(--fg) 3%, var(--bg)); border:1px solid var(--border); border-radius:6px; padding:6px; cursor:pointer; transition:background 0.15s, border-color 0.15s, transform 0.15s; } .cal-year-month:hover { background:color-mix(in srgb, var(--fg) 8%, var(--bg)); border-color:var(--accent); transform:translateY(-1px); } .cal-year-month-title { font-size:11px; font-weight:600; text-align:center; margin-bottom:4px; opacity:0.7; } -.cal-year-month:hover .cal-year-month-title { opacity:1; color:var(--accent); } .cal-year-grid { display:grid; grid-template-columns:repeat(7, 1fr); gap:1px; } .cal-year-wd { font-size:7px; text-align:center; opacity:0.3; padding:1px 0; } .cal-year-cell { font-size:8px; text-align:center; padding:2px 0; min-height:14px; border-radius:2px; transition:transform 0.12s, background 0.12s; } -.cal-year-day { cursor:pointer; opacity:0.5; } .cal-year-day:hover { background:var(--accent, var(--red)); color:#fff; opacity:1; transform:scale(1.15); font-weight:700; z-index:2; position:relative; } .cal-year-today { color:var(--accent, var(--red)); font-weight:700; opacity:1; } .cal-year-has { opacity:1; background:color-mix(in srgb, var(--accent) 15%, transparent); } @@ -46150,7 +44729,6 @@ button.cal-view-btn { .cal-search-input { background:color-mix(in srgb, var(--fg) 5%, var(--bg)); border:1px solid var(--border); border-radius:5px; padding:0 8px; height:24px; color:var(--fg); font-size:11px; font-family:inherit; width:120px; box-sizing:border-box; transition:width 0.15s; } .cal-search-input:focus { outline:none; border-color:var(--accent); width:180px; } .cal-search-input.cal-day-search { width:100%; margin-bottom:0; transition:none; padding-left: 28px; } -.cal-search-input.cal-day-search:focus { width:100%; } /* Wrap for the search input so the magnifying-glass icon can be absolute- positioned inside the field. */ .cal-search-wrap { @@ -46172,29 +44750,7 @@ button.cal-view-btn { /* Agenda view */ .cal-agenda { display:flex; flex-direction:column; gap:12px; flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; padding-left:4px; } .cal-agenda-day { display:flex; flex-direction:column; gap:5px; position:relative; padding-left:14px; } -.cal-agenda-day::before { - content:''; - position:absolute; - left:4px; - top:22px; - bottom:-12px; - width:1px; - background:color-mix(in srgb, var(--fg) 12%, transparent); -} -.cal-agenda-day::after { - content:''; - position:absolute; - left:1px; - top:12px; - width:7px; - height:7px; - border-radius:50%; - background:color-mix(in srgb, var(--fg) 22%, var(--bg)); - box-shadow:0 0 0 3px var(--bg); -} -.cal-agenda-day.is-today::after { background:var(--accent, var(--red)); } .cal-agenda-date { font-size:12px; font-weight:800; opacity:0.72; padding:5px 2px 3px; border-bottom:1px solid var(--border); } -.cal-agenda-day.is-today .cal-agenda-date { opacity: 1; color: var(--accent, var(--red)); border-bottom-color: color-mix(in srgb, var(--accent, var(--red)) 35%, var(--border)); } .cal-agenda-today-badge { display: inline-block; margin-left: 6px; @@ -46229,8 +44785,6 @@ button.cal-view-btn { } .cal-agenda-event .cal-event-more, .cal-event-item .cal-event-more { opacity:0; transition:opacity 0.15s; } -.cal-agenda-event:hover .cal-event-more, -.cal-event-item:hover .cal-event-more { opacity:0.6; } .cal-event-item { position:relative; } /* ── Personal Assistant ── */ @@ -46369,24 +44923,6 @@ button.cal-view-btn { margin: 0; } -button.cal-event-more { - background:transparent; - border:none; - color:var(--fg); - width:20px; height:20px; - cursor:pointer; - padding:0; - display:inline-flex; - align-items:center; - justify-content:center; - font-family:inherit; - flex-shrink:0; - margin-left:auto; - align-self:center; - transform:translateY(-4px); - transition:opacity 0.15s; -} -button.cal-event-more:hover { opacity:1 !important; } /* Empty state */ .cal-empty-state { display:flex; flex-direction:column; align-items:center; justify-content:center; padding:60px 20px; text-align:center; gap:10px; } .cal-empty-title { font-size:14px; font-weight:600; opacity:0.8; } @@ -46402,40 +44938,6 @@ button.cal-event-more:hover { opacity:1 !important; } /* Calendar-picker select sits 2px higher; its border-left/background tint is set in JS to the chosen calendar's colour. */ .cal-f-cal-select { position: relative; top: -4px; } -/* Day-detail "+ New" button nudged down 2px. */ -#cal-add-day { position: relative; top: 2px; } -/* Accent the native date/time picker glyphs. We recolor the webkit indicator - by masking an accent fill through a calendar/clock SVG (same technique as the - mono icon picker). accent-color covers the spinner parts where supported. */ -.cal-form-bespoke input[type="date"], -.cal-form-bespoke input[type="time"], -.cal-form-bespoke input[type="datetime-local"] { accent-color: var(--accent, var(--red)); } -.cal-form-bespoke input[type="date"]::-webkit-datetime-edit-month-field, -.cal-form-bespoke input[type="date"]::-webkit-datetime-edit-day-field { - color: var(--accent, var(--red)); - font-weight: 600; -} -.cal-form-bespoke input[type="date"]::-webkit-datetime-edit-year-field { - color: var(--fg); - font-weight: 400; -} -.cal-form-bespoke input[type="date"]::-webkit-calendar-picker-indicator, -.cal-form-bespoke input[type="time"]::-webkit-calendar-picker-indicator, -.cal-form-bespoke input[type="datetime-local"]::-webkit-calendar-picker-indicator { - background-color: var(--accent, var(--red)); - background-image: none; - cursor: pointer; - width: 14px; height: 14px; -} -.cal-form-bespoke input[type="date"]::-webkit-calendar-picker-indicator, -.cal-form-bespoke input[type="datetime-local"]::-webkit-calendar-picker-indicator { - -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cline x1='16' y1='2' x2='16' y2='6'/%3E%3Cline x1='8' y1='2' x2='8' y2='6'/%3E%3Cline x1='3' y1='10' x2='21' y2='10'/%3E%3C/svg%3E") center/contain no-repeat; - mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cline x1='16' y1='2' x2='16' y2='6'/%3E%3Cline x1='8' y1='2' x2='8' y2='6'/%3E%3Cline x1='3' y1='10' x2='21' y2='10'/%3E%3C/svg%3E") center/contain no-repeat; -} -.cal-form-bespoke input[type="time"]::-webkit-calendar-picker-indicator { - -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E") center/contain no-repeat; - mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E") center/contain no-repeat; -} /* ── Bespoke event form ──────────────────────────────────────────── Big clock-face date/time hero with the title under it. Details panel @@ -46462,29 +44964,10 @@ button.cal-event-more:hover { opacity:1 !important; } border-color: color-mix(in srgb, var(--ev-color) 55%, var(--border)); box-shadow: 0 8px 28px color-mix(in srgb, var(--ev-color) 22%, transparent); } -/* Title underline + clock focus ring + primary button track --ev-color - when set; default to --accent / --fg otherwise. */ -.cal-form-bespoke .cal-input.cal-hero-title:focus { border-bottom-color: var(--ev-color, var(--accent, color-mix(in srgb, var(--fg) 60%, transparent))); } -.cal-form-bespoke[style*="--ev-color"] .cal-input.cal-hero-title { border-bottom-color: color-mix(in srgb, var(--ev-color) 35%, var(--border)); } -.cal-form-bespoke .cal-hero-time:focus-visible, -.cal-form-bespoke .cal-hero-date:focus-visible { outline-color: var(--ev-color, var(--accent, color-mix(in srgb, var(--fg) 50%, transparent))); } .cal-form-bespoke[style*="--ev-color"] .cal-btn-primary { background: var(--ev-color); border-color: var(--ev-color); } -/* Custom-BG events paint the form card with the uploaded image. Make sure - the action row + buttons stay clearly readable on top of it. */ -.cal-form-bespoke.cal-form-bg-image .cal-form-actions { - position: relative; - z-index: 2; - /* Solid backing strip so the Save/Cancel/Delete buttons don't fade into - the photo behind them. */ - background: color-mix(in srgb, var(--panel) 92%, transparent); - margin: 8px -14px -14px; - padding: 10px 14px; - border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent); - border-radius: 0 0 8px 8px; -} .cal-form-bespoke.cal-form-bg-image .cal-btn-primary { background: var(--accent, var(--red)); border-color: var(--accent, var(--red)); @@ -46509,7 +44992,6 @@ button.cal-event-more:hover { opacity:1 !important; } opacity: 0.45; margin-bottom: 0; } -.cal-form-today span { letter-spacing: 0.04em; text-transform: none; opacity: 0.85; font-weight: 500; } /* Hero — clock face + date label. Spacing between the two lives entirely on the clock's bottom margin so it's predictable. */ @@ -46538,12 +45020,9 @@ button.cal-event-more:hover { opacity:1 !important; } line-height: 1; transition: background 0.15s, color 0.15s; } -.cal-hero-time .cal-hero-clock, -.cal-hero-time .cal-hero-ampm { line-height: 1; } /* The clock is a `