diff --git a/src/assets/themes/lines.css b/src/assets/themes/lines.css index e7468020fb..398bb8742c 100644 --- a/src/assets/themes/lines.css +++ b/src/assets/themes/lines.css @@ -16,10 +16,15 @@ body task:last-of-type { border-bottom: 1px solid var(--separator-color); } -/* No separators on sub-tasks — they form a connected indented block under the parent */ -body .sub-tasks task, -body .sub-tasks task:last-of-type { +/* Subtasks get separator lines between them. + Suppress only the boundaries so the indented block reads as part of its parent: + no top line on the first subtask (header → block flows together), no bottom line + on the last subtask (parent's bottom border or next parent's top closes it). */ +body .sub-tasks task:first-of-type { border-top: none; +} + +body .sub-tasks task:last-of-type { border-bottom: none; } @@ -44,16 +49,19 @@ body task.isSelected .sub-tasks .box { background: transparent !important; } -/* === Planner: tight list with horizontal separator lines === */ +/* === Planner & Boards: tight list with horizontal separator lines === */ -/* Remove the per-row gap so lines act as the only separator */ +/* Remove the per-row gap so lines act as the only separator. + `.task-items` is the board column list — same treatment. */ body .normal-tasks-items > *, body .deadline-items > *, -body .scheduled-items > * { +body .scheduled-items > *, +body .task-items > planner-task { margin-bottom: 0 !important; + margin-right: 0 !important; } -/* Strip box-style chrome from every planner item host */ +/* Strip box-style chrome from every planner/board item host */ body planner-task, body planner-deadline-task, body planner-repeat-projection, @@ -71,14 +79,16 @@ body planner-repeat-projection > div { border-radius: 0 !important; } -/* Top separator on every direct child of the normal/deadline lists */ +/* Top separator on every direct child of the normal/deadline/board lists */ body .normal-tasks-items > *, -body .deadline-items > * { +body .deadline-items > *, +body .task-items > planner-task { border-top: 1px solid var(--separator-color) !important; } body .normal-tasks-items > *:last-child, -body .deadline-items > *:last-child { +body .deadline-items > *:last-child, +body .task-items > planner-task:last-child { border-bottom: 1px solid var(--separator-color) !important; } @@ -91,3 +101,102 @@ body .scheduled-items > .scheduled-item { body .scheduled-items > .scheduled-item:last-child { border-bottom: 1px solid var(--separator-color); } + +/* === Row hover: subtle tint so the list feels responsive === */ + +/* Wrap in @media (hover: hover) — on touch, :hover sticks on the last-tapped row. */ +@media (hover: hover) { + /* Use :has() so hovering a subtask doesn't also highlight its parent row. + The .box is the absolute-positioned background layer of a task. */ + body task:hover:not(:has(task:hover)) > swipe-block > .inner-wrapper > .box { + background: rgba(0, 0, 0, 0.04) !important; + } + + body.isDarkTheme + task:hover:not(:has(task:hover)) + > swipe-block + > .inner-wrapper + > .box { + background: rgba(255, 255, 255, 0.03) !important; + } + + body planner-task:hover { + background: rgba(0, 0, 0, 0.04) !important; + } + + body.isDarkTheme planner-task:hover { + background: rgba(255, 255, 255, 0.03) !important; + } + + /* Selection wins over hover */ + body task.isSelected:hover > swipe-block > .inner-wrapper > .box { + background: var(--c-dark-10) !important; + } + + body.isDarkTheme task.isSelected:hover > swipe-block > .inner-wrapper > .box { + background: var(--c-light-05) !important; + } +} + +/* === Current task: suppress inherited border === */ + +/* The base theme paints a dashed accent border around the current task's box — + too noisy for a hairline-only list. The task component already renders a + progress bar below the title, which is enough indication. */ +body task.isCurrent .box, +body task.isCurrent.isCurrent.isCurrent.isCurrent.isCurrent .box { + border-color: transparent !important; + box-shadow: none !important; +} + +/* Planner/board tasks don't render a progress bar — without an indicator the + running task disappears. Use a faint accent tint instead of a border. */ +body planner-task.isCurrent { + border: none !important; + background: color-mix(in srgb, var(--c-accent) 10%, transparent) !important; +} + +/* === Drop indicator: ghost slot with an accent top line === */ + +/* Default opacity is 0.1 — too faint between hairlines. Bump to 0.3 so the + ghost is visible and add a 2px accent top line marking the drop position. */ +body task.cdk-drag-placeholder, +body planner-task.cdk-drag-placeholder { + opacity: 0.3 !important; + border-top: 2px solid var(--c-accent) !important; +} + +/* === Keyboard focus: explicit outline so focus is never invisible === */ + +body task:focus-visible { + outline: 2px solid var(--palette-primary-400) !important; + outline-offset: -2px; +} + +body planner-task:focus-visible { + outline: 2px solid var(--palette-primary-400) !important; + outline-offset: -2px; +} + +/* === Worklog: switch dashed dividers to solid for visual consistency === */ +body worklog .year, +body worklog .month { + border-top-style: solid; +} + +/* === Issue panel suggestions: hairline-separated list === */ + +body issue-provider-tab .item-list { + gap: 0 !important; +} + +body issue-preview-item { + background: transparent !important; + box-shadow: none !important; + border-radius: 0 !important; + border-top: 1px solid var(--separator-color); +} + +body issue-preview-item:last-of-type { + border-bottom: 1px solid var(--separator-color); +} diff --git a/src/assets/themes/zen.css b/src/assets/themes/zen.css index 6cc6ab15da..ae768746b2 100644 --- a/src/assets/themes/zen.css +++ b/src/assets/themes/zen.css @@ -255,3 +255,14 @@ body .week-month-btn:not(.active) { app-root.isWorkViewScrolled task.isCurrent .box { background: var(--bg) !important; } + +/* Banner: zen normally hides chrome; give it a neutral elevated bg so it + reads as distinct from the page without re-introducing primary color. */ +body banner .content-wrapper { + background: rgba(0, 0, 0, 0.06) !important; + box-shadow: none !important; +} + +body.isDarkTheme banner .content-wrapper { + background: rgba(255, 255, 255, 0.05) !important; +} diff --git a/src/styles/page.scss b/src/styles/page.scss index 676457fe64..dc232bc8e9 100644 --- a/src/styles/page.scss +++ b/src/styles/page.scss @@ -1,4 +1,3 @@ -@use 'angular-material-css-vars' as mat-css-vars; @use '../_common'; @use './mixins/media-queries'; @@ -139,16 +138,17 @@ body { opacity: 0; } - &.isLightTheme { + // Soft primary-tinted gradient backdrop. Light and dark want different + // recipes — the same single corner-glow that reads as warm on dark looks + // smudgy on white, so light gets two larger diffuse glows (primary + + // accent) for subtle depth without flat-tint feel. + // Themes that want a different/no backdrop hide body:before (dark-base, + // arc, nord-snow-storm, dracula, velvet do this). + &.isLightTheme, + &.isDarkTheme { color: var(--text-color); background: var(--bg); - &:before { - display: block; - opacity: 1; - filter: saturate(0.8); - background: mat-css-vars.mat-css-color(50, 1); - } &.isDisableBackgroundTint { background: var(--bg); &:before { @@ -158,23 +158,39 @@ body { } } - &.isDarkTheme { - color: var(--text-color); - background: var(--bg); + &.isLightTheme:before { + display: block; + opacity: 1; + // Two glows in different primary shades — primary-200 (soft pastel) + // for the top-left highlight, primary-400 (deeper) for bottom-right + // depth. Single-hue keeps the light-mode wash calm. + background: + radial-gradient( + ellipse 120% 80% at 0% -10%, + color-mix(in srgb, var(--palette-primary-200) 40%, transparent) 0%, + transparent 65% + ), + radial-gradient( + ellipse 80% 60% at 100% 100%, + color-mix(in srgb, var(--palette-primary-400) 15%, transparent) 0%, + transparent 60% + ); + } - &:before { - display: block; - opacity: 1; - filter: brightness(0.1); - background: mat-css-vars.mat-css-color(900, 1); - } - &.isDisableBackgroundTint { - background: var(--bg); - &:before { - display: none; - opacity: 0; - } - } + &.isDarkTheme:before { + display: block; + opacity: 1; + background: + radial-gradient( + ellipse 80% 60% at 10% -10%, + color-mix(in srgb, var(--c-primary) 10%, transparent) 0%, + transparent 55% + ), + linear-gradient( + 180deg, + color-mix(in srgb, var(--c-primary) 4%, transparent) 0%, + transparent 100% + ); } // also hide material dialogs while import is in progress