/* injected into pierre's shadow dom through FileDiff's unsafeCSS option, which
lands in its last cascade layer. pierre guarantees nothing about this markup
between releases, patch ones included: https://diffs.com/docs#styling */
:host {
/* we render our own file header, pierre's is disabled */
--diffs-gap-block: 0;
--diffs-overflow-override: auto;
--diffs-selection-base: var(--color-border-focus);
}
/* page styles do not go into the shadow root */
::selection {
background-color: var(--color-background-info-subtle-hover);
}
[data-line],
[data-no-newline] {
--mix-light: 0%;
}
[data-gutter],
[data-column-number],
[data-gutter-buffer] {
background-color: var(--diffs-bg-gutter);
background-image: linear-gradient(var(--diffs-bg-gutter-wash), var(--diffs-bg-gutter-wash));
}
[data-line-type="change-addition"][data-column-number]::before,
[data-line-type="change-deletion"][data-column-number]::before {
width: 2px;
}
[data-line-type="change-addition"][data-column-number],
[data-line-type="change-deletion"][data-column-number] {
--diffs-bg-number-wash: 60%;
--mix-light: 0%;
--mix-dark: 0%;
--diffs-diff-line-mix-target: var(--diffs-bg);
background-image:
linear-gradient(var(--diffs-bg-number-tint), var(--diffs-bg-number-tint)),
linear-gradient(var(--diffs-bg-gutter-wash), var(--diffs-bg-gutter-wash));
}
[data-line-type="change-addition"][data-column-number] {
--diffs-bg-number-tint: color-mix(
in srgb,
var(--diffs-bg-addition-override) var(--diffs-bg-number-wash),
transparent
);
}
[data-line-type="change-deletion"][data-column-number] {
--diffs-bg-number-tint: color-mix(
in srgb,
var(--diffs-bg-deletion-override) var(--diffs-bg-number-wash),
transparent
);
}
[data-column-number][data-selected-line],
[data-gutter-buffer][data-selected-line] {
--diffs-computed-diff-line-bg: var(--diffs-bg-gutter);
background-color: var(--diffs-line-bg);
background-image: none;
}
[data-diff] {
border: 1px solid var(--color-border-default);
border-top: 0;
border-bottom-right-radius: var(--radius-md, 0.375rem);
border-bottom-left-radius: var(--radius-md, 0.375rem);
}
[data-code][data-unified] {
border-bottom-right-radius: calc(var(--radius-md, 0.375rem) - 1px);
border-bottom-left-radius: calc(var(--radius-md, 0.375rem) - 1px);
}
[data-code][data-deletions] {
border-bottom-left-radius: calc(var(--radius-md, 0.375rem) - 1px);
}
[data-code][data-additions] {
border-bottom-right-radius: calc(var(--radius-md, 0.375rem) - 1px);
}
[data-separator] {
block-size: calc(var(--diffs-font-size) * var(--diffs-line-height));
font-size: var(--diffs-font-size);
line-height: calc(var(--diffs-font-size) * var(--diffs-line-height));
color: var(--diffs-fg-number-override, #9ca3af);
}
[data-separator="line-info"] {
margin-block: 0;
}
[data-unified] [data-separator="line-info"] [data-separator-wrapper] {
padding-inline: 0;
}
[data-gutter] [data-separator="line-info"] [data-separator-wrapper] {
padding-left: 0;
}
/* pierre full-widths the unified separator and the split additions bar but not
the split deletions one, and that is the one carrying the count text */
[data-deletions] [data-gutter] [data-separator="line-info"] [data-separator-wrapper] {
width: 100cqi;
}
[data-separator="line-info"] [data-separator-content],
[data-separator="line-info"] [data-expand-button],
[data-additions] [data-gutter] [data-separator="line-info"] [data-separator-wrapper] {
border-radius: 0;
}
[data-separator-content] {
justify-content: center;
}
[data-separator="simple"] {
display: flex;
align-items: center;
justify-content: center;
}
[data-separator="simple"]::after {
content: "···";
}
[data-diff-type="split"][data-overflow="scroll"] {
& [data-deletions] {
border-right-color: var(--color-border-default);
}
& [data-additions] {
border-left: 0;
}
}
[data-diff-type="split"][data-overflow="wrap"] {
& [data-deletions] [data-content] {
border-right-color: var(--color-border-default);
}
& [data-additions] [data-gutter] {
border-left: 0;
}
}
[data-column-number],
[data-gutter-buffer],
[data-expand-button] {
border-right: 0;
}
/* pierre pads every line with a trailing 1ch, and the content column sizes to
max-content, so that pad rides into the scroll width: a file whose longest
line stops within 1ch of the edge scrolls sideways over nothing. wrap mode
keeps it, there the pad is the right inset of the text block */
[data-overflow="scroll"] [data-line],
[data-overflow="scroll"] [data-no-newline] {
padding-inline-end: 0;
}
/* firefox reserves an inline-end gutter for a vertical scrollbar that
overflow-y:hidden can never show, so the scrollport ends up ~11px narrower
than the box — but 100cqi, which pierre uses to full-width the separator
bars, still measures the full box. those 11px are a sideways scroll over
nothing. chromium never saw it: pierre zeroes its webkit scrollbar, so its
reserved gutter is already 0 */
[data-code] {
scrollbar-gutter: auto;
}
[data-expand-button] {
& > svg[data-icon] {
width: var(--diffs-font-size);
height: var(--diffs-font-size);
}
}
[data-separator-wrapper] [data-separator-multi-button] > [data-expand-button] {
border: none;
}
[data-line-type="change-deletion"]::before {
background-size: 2px 3px;
}
[data-gutter-utility-slot] {
right: unset;
left: 4px;
align-items: center;
justify-content: flex-start;
}
[data-utility-button] {
width: 18px;
height: 18px;
margin-right: 0;
border: 1px solid var(--color-border-strong);
background-color: var(--color-background-default);
color: var(--color-foreground-subtle);
box-shadow: var(--shadow-small);
transition:
color 150ms ease,
background-color 150ms ease,
transform 160ms var(--ease-out-strong);
& > svg[data-icon] {
display: none;
}
&::after {
content: "";
width: 14px;
height: 14px;
background-color: currentColor;
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M14 14a2 2 0 0 0 2-2V8h-2'/%3E%3Cpath d='M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z'/%3E%3Cpath d='M8 14a2 2 0 0 0 2-2V8H8'/%3E%3C/svg%3E")
center / contain no-repeat;
}
&:active {
transform: scale(0.97);
}
}
@media (hover: hover) and (pointer: fine) {
[data-utility-button]:hover {
background-color: var(--color-background-subtle);
color: var(--color-foreground-default);
}
}
@media (prefers-reduced-motion: reduce) {
[data-utility-button] {
transition:
color 150ms ease,
background-color 150ms ease;
&:active {
transform: none;
}
}
}
::highlight(line-search) {
background-color: var(--color-background-highlight);
color: var(--color-foreground-highlight);
}
::highlight(line-search-current) {
background-color: var(--color-foreground-highlight);
color: var(--color-background-highlight);
}