Bug? Background color leaks between projects

I am using background colors to make my projects stand out. It’s working great, but for one problem.

When two projects are directly above/below each other (one or both is collapsed) the background color stretches between them. Even if there are multiple carriage returns after the first project, the background color continues all the way down to the next project.

Example

Just getting to this now… can you please post an example TaskPaper document and stylesheet to reproduce this? I’m not able to reproduce the problem.

In this example I first have two collapsed projects right next to each other… and the red background color does touch… but that’s expected. I then have copied the two projects and added newlines between them… and in that case the colors don’t touch:

Screen Shot 2020-04-06 at 8.25.26 AM

Apologies for my own lateness in getting back to this. Here is my stylesheet.

// Base -----------------------------------
@font-family: Hack, Source Code Pro;
@font-family: -apple-user;
@font-family: Lato;
@base-font-size: 16;
@user-font-size: $USER_FONT_SIZE;
@ui-scale: @user-font-size / @base-font-size;
@line-height-multiple: 1.4;
@handle-size: floor(9 * @ui-scale);

@bg_color: #0c0c0c;
@_current-line: lighten(@bg_color, 4%);
@_selection: lighten(@bg_color, 10%);
@fg_color: #cccccc;
@neutral: #808080;

@1____: #f2777a;
@2____: #f99157;
@3____: #ffcc66;
@4____: #99cc99;
@5____: #66cccc;
@6____: #6699cc;
@7____: #cc99cc;


// Base colors -----------------------------------
@project-color: #000000;
@project-bg-color: #555555;
@text-color: @fg_color;
@bg-color: @bg_color;
@message-color: mix(@text-color, @bg-color, 50%);
@tag-color: fade(@fg_color, 65%);

// UI Colors -----------------------------------
@tint-color: @1____;
@interface-color: @tint-color;
@selection-color: @_selection;
@invisibles-color: fade(@tint-color, 50%);
@guide-color: darken(@fg_color, 26%);

window {
  appearance: NSAppearanceNameVibrantDark;
}

searchbar {
  background-color: #3b3b3b;
  placeholder-color: fade(@text-color, 65%);
  color: @text-color;
  secondary-text-color: @4____;
  error-text-color: @1____;
}


editor {
    color: @text-color;
    font-size: @user-font-size;
    font-family: @font-family;
    background-color: @bg-color;
    line-height-multiple: @line-height-multiple;
    // item-handle-size: 6;
    item-indent: 15px * @ui-scale;
    caret-width: floor(2 * @ui-scale);
    // caret-color: @1____;
    caret-color: #0000ff;
    handle-color: @guide-color;
    drop-indicator-color: @tint-color;
    invisibles-color: @invisibles-color;
    selection-background-color: @selection-color;
    guide-line-width: floor(0.5 * @ui-scale);
    guide-line-color: mix(@guide-color,@bg-color, 40%);
    message-color: @message-color;
    // top-padding-percent: 20%; // Pad top of editor with 25% of viewport height
    bottom-padding-percent: 40%; // Pad bottom of editor with 25% of viewport height
    // editor-wrap-to-column: 80; // Wrap editor text at 80 columns, center if extra space
    // item-wrap-to-column: 60; // Wrap item text at 60 columns (smaller value them above means item text doesn't rewrap when item is indented
    typewriter-scroll-percent: 50%; // Scroll edit location to 50% location in viewport when possible
}

item[data-type=project] {
  font-size: floor(26 * @ui-scale);
}

item[depth=1][data-type=project] {
    font-weight: 900;
    color: @project-color;
    background-color: @project-bg-color;
    paragraph-spacing-before: 20;
    paragraph-spacing-after: 20;
    line-height-multiple: 1.0;
    > run[content] {
      text-baseline-offset: 0;
      // text-decoration: underline;
    }
}
item[depth=2][data-type=project] {
    font-weight: 900;
    font-size: floor(20 * @ui-scale);
    // font-size: 17;
    color: fade(@project-color, 100%);
    background-color: fade(@project-bg-color, 80%);
    paragraph-spacing-before: 5;
    paragraph-spacing-after: 5;
}
item[depth=3][data-type=project] {
    font-weight: 900;
    font-size: floor(18 * @ui-scale);
    color: fade(@project-color, 100%);
    background-color: fade(@project-bg-color, 60%);
    paragraph-spacing-before: 5;
    paragraph-spacing-after: 5;
}
item[depth=4][data-type=project] {
    font-weight: 900;
    font-size: floor(16 * @ui-scale);
    color: fade(@project-color, 100%);
    background-color: fade(@project-bg-color, 40%);
    paragraph-spacing-before: 20;
    paragraph-spacing-after: 3;
}
item[depth=5][data-type=project] {
    font-weight: 900;
    font-size: floor(16 * @ui-scale);
    color: fade(@project-color, 100%);
    background-color: fade(@project-bg-color, 60%);
    paragraph-spacing-before: 20;
    paragraph-spacing-after: 3;
}
item[data-ol][data-type=project],
item[data-ul][data-type=project] {
    font-weight: 900;
    font-size: floor(16 * @ui-scale);
    color: @text-color;
    paragraph-spacing-before: 0;
    paragraph-spacing-after: 0;
}
item[data-type="task"] {
    font-style: normal;
    background-color: #000000;
}
item[data-type="note"] {
    // font-size: 14;
    // color: @neutral;
    color: #6666ff;
    line-height-multiple: 2;
    paragraph-spacing-after: 5;
    font-style: italic;
}

// Project Styles
item[data-section][data-type=project] {
  > run[tag] {
    color: @bg_color;
    text-decoration: none;
  }
}
item[data-metadata][data-type=project] {
  color: @neutral;
  font-size: floor(18 * @ui-scale);
  > run[tag] {
    color: @bg_color;
  }
}
item[data-status="open"][data-type=project],
item[data-status="active"][data-type=project],
item[data-status="ongoing"][data-type=project] {
  color: @4____;
}
item[data-status="hold"][data-type=project] {
  color: @7____;
}
item[data-defer][data-type=project] {
  color: fade(@7____, 35%);
}
item[data-dueToday][data-type=project] {
  color: @2____;
}
item[data-dueTomorrow][data-type=project] {
  color: @3____;
}
item[data-pastDue][data-type=project] {
  color: @1____;
}
item[data-status="cancelled"][data-type=project] {
  color: fade(@1____, 35%);
  > run[content] {
      text-strikethrough: NSUnderlineStyleSingle;
      text-strikethrough-color: fade(@1____, 10%);
      color: fade(@1____, 35%);
  }
  > run[tag] {
      text-strikethrough: NSUnderlineStyleSingle;
      text-strikethrough-color: fade(@1____, 10%);
      color: fade(@1____, 35%);
  }
}
item[data-status="closed"][data-type=project],
item[data-status="delivered"][data-type=project],
item[data-status="completed"][data-type=project] {
  color: fade(@text-color, 35%);
  > run[content] {
      text-strikethrough: NSUnderlineStyleSingle;
      text-strikethrough-color: fade(@text-color, 10%);
      color: fade(@text-color, 35%);
  }
  > run[tag] {
      text-strikethrough: NSUnderlineStyleSingle;
      text-strikethrough-color: fade(@text-color, 10%);
      color: fade(@text-color, 35%);
  }
}


// Handle styles -----------------------------------
item {
  handle-size: floor(12 * @ui-scale);
  handle-color: #000000;
  handle-border-color: @guide-color ;
  // handle-border-width: 0.5;
  handle-border-width: floor(10 * @ui-scale);
}

item[collapsed] {
  handle-color: @6____;
  handle-border-color: @6____;a
  font-size: 20;
}

item[filtered] {
  handle-color: @tag-color;
  handle-border-color: @tag-color;
}

item[empty] {
  handle-color: none;
  handle-border-color: none;
}

item[leaf] {
  handle-size: none; //floor(7 * @ui-scale);
  handle-color: none;// @guide-color;
  // handle-border-color: @guide-color;
  // handle-border-width: floor(1 * @ui-scale);
}


item[mouseOverHandle] {
  handle-size: @handle-size + (1.5 * @ui-scale);
}

// Tag styles -----------------------------------

item[data-ol][data-context][data-type=project],
item[data-ul][data-context][data-type=project],
item[data-context] {
    > run[tag] {
        color: fade(@text-color, 65%);
    }
    > run[tagvalue] {
      color: fade(@text-color, 100%);
    }
    > run[tagvalue="home"] {
      color: fade(@4____, 100%);
    }
    > run[tagvalue="work"] {
      color: fade(@6____, 100%);
    }
    > run[tagvalue="IO"] {
      color: fade(@7____, 100%);
    }
    > run[tagvalue="errands"] {
      color: fade(@3____, 100%);
    }
}
item[data-ol][data-due][data-type=project],
item[data-ul][data-due][data-type=project],
item[data-due] {
    font-size: @user-font-size;
    // font-style: normal;
    // font-weight: normal;
    color: @text-color;
    > run[tag] {
        // color: fade(@3____, 65%);
    }
    > run[tagvalue] {
      color: @text-color;
    }
}
item[data-ol][data-flag][data-type=project],
item[data-ul][data-flag][data-type=project],
item[data-flag] {
    font-size: @user-font-size;
    // font-style: normal;
    // font-weight: normal;
    color: @5____;
    > run[tag] {
        color: fade(@5____, 65%);
    }
    > run[tagvalue] {
      color: @text-color;
    }
}
item[data-ol][data-today][data-type=project],
item[data-ul][data-today][data-type=project],
item[data-today],
item[data-ol][data-dueToday][data-type=project],
item[data-ul][data-dueToday][data-type=project],
item[data-dueToday] {
    font-size: @user-font-size;
    // font-style: normal;
    // font-weight: normal;
    color: @2____;
    > run[tag] {
        color: fade(@2____, 65%);
    }
    > run[tagvalue] {
      color: @text-color;
    }
}
item[data-ol][data-dueTomorrow][data-type=project],
item[data-ul][data-dueTomorrow][data-type=project],
item[data-dueTomorrow] {
    font-size: @user-font-size;
    // font-style: normal;
    // font-weight: normal;
    color: @3____;
    > run[tag] {
        color: fade(@3____, 65%);
    }
    > run[tagvalue] {
      color: @text-color;
    }
}
item[data-ol][data-overdue][data-type=project],
item[data-ul][data-overdue][data-type=project],
item[data-overdue],
item[data-ol][data-pastDue][data-type=project],
item[data-ul][data-pastDue][data-type=project],
item[data-pastDue] {
    font-size: @user-font-size;
    // font-style: normal;
    // font-weight: normal;
    color: @1____;
    > run[tag] {
        color: fade(@1____, 65%);
    }
    // Just the tag values (between the parentheses).
    > run[tagvalue] {
      color: fade(@text-color, 100%);
    }
    > run[tagvalue="home"] {
      color: fade(@4____, 100%);
    }
    > run[tagvalue="work"] {
      color: fade(@6____, 100%);
    }
    > run[tagvalue="IO"] {
      color: fade(@7____, 100%);
    }
    > run[tagvalue="errands"] {
      color: fade(@3____, 100%);
    }
}
item[data-ol][data-priority][data-type=project],
item[data-ul][data-priority][data-type=project],
item[data-priority] {
    font-size: @user-font-size;
    // font-style: normal;
    // font-weight: normal;
    color: @1____;
    > run[tag] {
        color: fade(@1____, 65%);
    }
    // Just the tag values (between the parentheses).
    > run[tagvalue] {
      color: fade(@text-color, 100%);
    }
    > run[tagvalue="home"] {
      color: fade(@4____, 100%);
    }
    > run[tagvalue="work"] {
      color: fade(@6____, 100%);
    }
    > run[tagvalue="IO"] {
      color: fade(@7____, 100%);
    }
    > run[tagvalue="errands"] {
      color: fade(@3____, 100%);
    }
    > run[tagvalue=high],
    > run[tagvalue="1"],
    > run[tagvalue="2"],
    > run[tagvalue="3"],
    > run[tagvalue="4"],
    > run[tagvalue="5"] {
      color: #f00;
      font-weight: bold;
    }
}
item[data-ol][data-waitingFor][data-type=project],
item[data-ul][data-waitingFor][data-type=project],
item[data-waitingFor],
item[data-ol][data-f_up][data-type=project],
item[data-ul][data-f_up][data-type=project],
item[data-f_up],
item[data-ol][data-agenda][data-type=project],
item[data-ul][data-agenda][data-type=project],
item[data-agenda] {
    font-size: @user-font-size;
    // font-style: normal;
    // font-weight: normal;
    color: fade(@7____, 65%);
    > run[tag] {
        // color: fade(@7____, 65%);
    }
}
item[data-ol][data-defer][data-type=project],
item[data-ul][data-defer][data-type=project],
item[data-defer] {
    font-size: @user-font-size;
    // font-style: normal;
    // font-weight: normal;
    color: fade(@7____, 35%);
    > run[tag] {
        // color: fade(@7____, 35%);
    }
}
item[data-ol][data-maybe][data-type=project],
item[data-ul][data-maybe][data-type=project],
item[data-maybe] {
    font-size: @user-font-size;
    // font-style: normal;
    // font-weight: normal;
    color: fade(@text-color, 35%);
    > run[tag] {
        color: fade(@text-color, 35%);
    }
}
item[data-ol][data-search][data-type=project],
item[data-ul][data-search][data-type=project],
item[data-search] {
    font-size: @user-font-size;
    // font-style: normal;
    // font-weight: normal;
    color: @text-color;
    > run[tag] {
        color: fade(@text-color, 65%);
    }
}
 item[data-ol][data-done][data-type=project],
 item[data-ul][data-done][data-type=project],
item[data-done] {
    > run[content] {
        text-strikethrough: NSUnderlineStyleSingle;
        text-strikethrough-color: fade(@text-color, 35%);
        color: fade(@text-color, 35%);
    }
    > run[link^="button"] {
       font-family: TaskPaper;
       font-weight: bold;
       font-size: 16;
       text-expansion: 0.0; // reset value from default stylesheet
       // text-strikethrough: NSUnderlinePatternDash;
       // text-strikethrough: NSUnderlineStyleDouble;
       // text-strikethrough-color: red;
    }
    > run[tag] {
        text-strikethrough: NSUnderlineStyleSingle;
        text-strikethrough-color: fade(@text-color, 35%);
        color: fade(@text-color, 35%);
    }
}
run[link] {
    cursor: pointer;
    color: #1EAEDB;
    text-underline: NSUnderlineStyleSingle;
}
run[lead] {
    color: fade(@text-color, 50%);
    text-underline: NSUnderlineStyleNone;
}
// run[link^="button"] {
//   color: @text-color;
//   text-underline: NSUnderlineStyleNone;
//   font-weight: 100;
// }
run[link^="filter"] {
    color: @text-color;
    text-underline: NSUnderlineStyleNone;
}
run[tag] {
    font-size: @user-font-size;
    font-style: normal;
    font-weight: normal;
    color: fade(@text-color, 65%);
    text-underline: NSUnderlineStyleNone;
}
run[tagvalue] {
  color: fade(@text-color, 100%);
}

item[data-stats] {
    font-size: @user-font-size;
    font-family: hack;
    color: @text-color;
    font-style: normal;
    > run[content] {
        text-strikethrough: none;
        color: @text-color;
    }
    > run[tag] {
        text-strikethrough: none;
        color: fade(@text-color, 65%);
    }
    > run[tagvalue] {
      color: @text-color;
    }
}

item[data-break] {
  color: @background-color;
  > run[content] {
    text-strikethrough: NSUnderlineStyleThick;
    text-strikethrough-color: lightgray;
  }
  > run[link^="button"] {
    color: @background-color;
  }
  > run[tag] {
    color: @background-color;
    text-strikethrough: NSUnderlineStyleThick;
    text-strikethrough-color: lightgray;
  }
}

run[link^="button"] {
 font-family: TaskPaper;
 font-weight: regular;
 font-size: 16;
 text-expansion: 0.0; // reset value from default stylesheet
}

window {
  appearance: NSAppearanceNameVibrantDark;
}

sidebar {
  appearance: NSAppearanceNameVibrantDark;
}
searchbar {
  appearance: NSAppearanceNameVibrantDark;
}

Thanks, I can reproduce the problem now… but I don’t see an easy fix. Not sure if the bug is on my side or cocoa… I’m rendering styles into attributed string and then asking cocoa to display. It doesn’t seem to like background colors mixed with paragraph-spacing.

Generally I would try to get rid of all paragraph-spacing attributes (I shouldn’t have added in first place I think). Try to use line-height-multiple, font sizes, etc to create a similar visual hierarchy. You won’t be able to get exact same, but should still be possible to create visual hierarchy I think.