/* 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 * 4. static/css/cookbook-research-memory-settings.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; } }