thunderbird-patch-review

Easy-to-use patch review interface for Thunderbird

Contribute: ~marcc/thunderbird-review-plugin@lists.sr.ht

git clone git://mccd.space/thunderbird-patch-review

review.css (10355B)

      1 :root {
      2   --bg: #ffffff;
      3   --fg: #1f2328;
      4   --muted: #656d76;
      5   --border: #d1d9e0;
      6   --surface: #f6f8fa;
      7   --accent: #0969da;
      8   --add-bg: #dafbe1;
      9   --add-gutter: #aceebb;
     10   --del-bg: #ffebe9;
     11   --del-gutter: #ffcecb;
     12   --hunk-bg: #ddf4ff;
     13   --comment-bg: #fff8c5;
     14 }
     15 
     16 @media (prefers-color-scheme: dark) {
     17   :root {
     18     --bg: #0d1117;
     19     --fg: #e6edf3;
     20     --muted: #8d96a0;
     21     --border: #30363d;
     22     --surface: #161b22;
     23     --accent: #4493f8;
     24     --add-bg: #12261e;
     25     --add-gutter: #1b4721;
     26     --del-bg: #25171c;
     27     --del-gutter: #542426;
     28     --hunk-bg: #121d2f;
     29     --comment-bg: #272115;
     30   }
     31 }
     32 
     33 * { box-sizing: border-box; }
     34 
     35 /* The hidden attribute must always win, even over display: flex rules. */
     36 [hidden] { display: none !important; }
     37 
     38 body {
     39   margin: 0;
     40   background: var(--bg);
     41   color: var(--fg);
     42   font: 13px/1.5 -apple-system, "Segoe UI", Cantarell, Ubuntu, sans-serif;
     43 }
     44 
     45 #topbar {
     46   display: flex;
     47   align-items: center;
     48   justify-content: space-between;
     49   gap: 1rem;
     50   padding: 0.5rem 1rem;
     51   border-bottom: 1px solid var(--border);
     52   background: var(--surface);
     53   position: sticky;
     54   top: 0;
     55   z-index: 2;
     56 }
     57 
     58 #series-nav {
     59   display: flex;
     60   align-items: center;
     61   justify-content: flex-start;
     62   gap: 0.4rem;
     63   flex-wrap: wrap;
     64   margin: 0.6rem 0;
     65 }
     66 
     67 #series-title {
     68   font-weight: 600;
     69   overflow: hidden;
     70   text-overflow: ellipsis;
     71   white-space: nowrap;
     72 }
     73 
     74 #actions {
     75   display: flex;
     76   align-items: center;
     77   gap: 0.5rem;
     78   flex-shrink: 0;
     79 }
     80 
     81 
     82 #repo-path {
     83   max-width: 18rem;
     84   padding: 0.3rem 0.6rem;
     85   border: 1px solid var(--border);
     86   border-radius: 6px;
     87   background: var(--bg);
     88   color: var(--fg);
     89   font-family: ui-monospace, monospace;
     90   white-space: nowrap;
     91   overflow: hidden;
     92   text-overflow: ellipsis;
     93   user-select: none;
     94   cursor: pointer;
     95   text-align: left;
     96 }
     97 
     98 #repo-path .repo-branch { color: var(--muted); }
     99 #repo-path.error .repo-sep,
    100 #repo-path.error .repo-branch { color: inherit; }
    101 #repo-path:hover { background: var(--hunk-bg); }
    102 #repo-path.error { cursor: pointer; }
    103 #repo-path.error {
    104   border-color: #cf222e;
    105   color: #cf222e;
    106 }
    107 @media (prefers-color-scheme: dark) {
    108   #repo-path.error { border-color: #f85149; color: #f85149; }
    109 }
    110 
    111 /* A joined cluster: the repo chip and the Apply split read as one control.
    112    Children sit flush; inner borders merge and inner corners flatten. */
    113 .cluster {
    114   display: flex;
    115   align-items: stretch;
    116 }
    117 .cluster > #repo-path {
    118   border-top-right-radius: 0;
    119   border-bottom-right-radius: 0;
    120 }
    121 .cluster > .split {
    122   border-top-left-radius: 0;
    123   border-bottom-left-radius: 0;
    124 }
    125 .cluster > .split > button:first-child {
    126   border-top-left-radius: 0;
    127   border-bottom-left-radius: 0;
    128   border-left: 0;
    129 }
    130 
    131 button {
    132   padding: 0.3rem 0.8rem;
    133   border: 1px solid var(--border);
    134   border-radius: 6px;
    135   background: var(--surface);
    136   color: var(--fg);
    137   cursor: pointer;
    138 }
    139 
    140 button:hover { background: var(--hunk-bg); }
    141 button:disabled { opacity: 0.5; cursor: not-allowed; }
    142 button:disabled:hover { background: inherit; opacity: 0.5; }
    143 button.primary:disabled { background: var(--accent); border-color: var(--accent); color: #fff; }
    144 button.primary:disabled:hover { opacity: 0.5; }
    145 
    146 .split .menu button.danger {
    147   color: #cf222e;
    148 }
    149 .split .menu button.danger:hover {
    150   background: #cf222e;
    151   color: #fff;
    152 }
    153 @media (prefers-color-scheme: dark) {
    154   .split .menu button.danger { color: #f85149; }
    155   .split .menu button.danger:hover { background: #f85149; color: #0d1117; }
    156 }
    157 button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
    158 button.primary:hover { color: #fff; opacity: 0.9; }
    159 
    160 .split {
    161   position: relative;
    162   display: flex;
    163 }
    164 
    165 .split > button:first-child {
    166   border-top-right-radius: 0;
    167   border-bottom-right-radius: 0;
    168 }
    169 
    170 .split > .menu-toggle {
    171   border-top-left-radius: 0;
    172   border-bottom-left-radius: 0;
    173   border-left-color: rgba(255, 255, 255, 0.35);
    174   padding: 0.3rem 0.45rem;
    175 }
    176 
    177 .split .menu {
    178   position: absolute;
    179   top: calc(100% + 4px);
    180   right: 0;
    181   display: flex;
    182   flex-direction: column;
    183   min-width: 12rem;
    184   border: 1px solid var(--border);
    185   border-radius: 6px;
    186   background: var(--surface);
    187   box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
    188   z-index: 4;
    189   overflow: hidden;
    190 }
    191 
    192 .split .menu button {
    193   border: 0;
    194   border-radius: 0;
    195   background: none;
    196   text-align: left;
    197   padding: 0.45rem 0.8rem;
    198 }
    199 
    200 .split .menu button:hover {
    201   background: var(--hunk-bg);
    202   color: var(--fg);
    203 }
    204 
    205 .patch-box {
    206   margin: 0 0 1rem;
    207   border: 1px solid var(--border);
    208   border-radius: 6px;
    209   background: var(--surface);
    210   overflow: hidden;
    211 }
    212 
    213 #series-nav .pill {
    214   padding: 0.2rem 0.7rem;
    215   border: 1px solid var(--border);
    216   border-radius: 999px;
    217   cursor: pointer;
    218   color: var(--muted);
    219 }
    220 
    221 #series-nav .pill.active {
    222   border-color: var(--accent);
    223   color: var(--accent);
    224   font-weight: 600;
    225 }
    226 
    227 #series-nav .pill .badge {
    228   display: inline-block;
    229   min-width: 1.2em;
    230   margin-left: 0.35em;
    231   border-radius: 999px;
    232   background: var(--accent);
    233   color: #fff;
    234   font-size: 11px;
    235   text-align: center;
    236 }
    237 
    238 #content { padding: 0 1rem 4rem; max-width: 72rem; margin: 0 auto; }
    239 
    240 .commit-message {
    241   position: relative;
    242   margin: 0;
    243   padding: 0.8rem 1rem;
    244   border: 0;
    245   border-bottom: 1px solid var(--border);
    246   border-radius: 0;
    247   background: transparent;
    248   white-space: pre-wrap;
    249   font-family: ui-monospace, monospace;
    250 }
    251 
    252 .commit-message .btn-general {
    253   display: block;
    254   margin: 0.6rem 0 0;
    255 }
    256 
    257 .commit-message .patch-headers {
    258   margin: 0 0 0.4rem;
    259   font-family: ui-monospace, "Cascadia Mono", "Source Code Pro", monospace;
    260   color: var(--fg);
    261 }
    262 .commit-message .patch-headers dt {
    263   display: inline;
    264   color: var(--fg);
    265   margin-right: 0.3em;
    266 }
    267 .commit-message .patch-headers dd {
    268   display: inline;
    269   margin: 0;
    270   color: var(--fg);
    271 }
    272 .commit-message .patch-headers code {
    273   font-family: inherit;
    274   color: var(--fg);
    275 }
    276 .commit-message .patch-headers > dt + dd::after { content: "\A"; white-space: pre; }
    277 
    278 .file {
    279   margin-bottom: 1rem;
    280   border: 1px solid var(--border);
    281   border-radius: 6px;
    282   overflow: hidden;
    283 }
    284 
    285 .file > summary {
    286   padding: 0.4rem 0.8rem;
    287   background: var(--surface);
    288   font-family: ui-monospace, monospace;
    289   font-weight: 600;
    290   cursor: pointer;
    291 }
    292 
    293 .file .file-note { padding: 0.4rem 0.8rem; color: var(--muted); }
    294 
    295 .binary-note {
    296   padding: 0.4rem 0.8rem 0.6rem;
    297   color: var(--muted);
    298   border-left: 3px solid #d1242f;
    299 }
    300 .binary-note .file-note { padding: 0; }
    301 .binary-note button { margin-top: 0.4rem; }
    302 .binary-note .binary-raw {
    303   margin: 0.5rem 0 0;
    304   padding: 0.5rem 0.7rem;
    305   max-height: 16rem;
    306   overflow: auto;
    307   border: 1px solid var(--border);
    308   border-radius: 6px;
    309   background: var(--bg);
    310   font: 11px/1.4 ui-monospace, monospace;
    311   white-space: pre-wrap;
    312   color: var(--muted);
    313 }
    314 
    315 table.diff {
    316   width: 100%;
    317   border-collapse: collapse;
    318   font: 12px/1.45 ui-monospace, "Cascadia Mono", "Source Code Pro", monospace;
    319 }
    320 
    321 table.diff td { padding: 0 0.5em; vertical-align: top; }
    322 
    323 td.gutter {
    324   width: 3em;
    325   min-width: 3em;
    326   text-align: right;
    327   color: var(--muted);
    328   user-select: none;
    329   border-right: 1px solid var(--border);
    330 }
    331 
    332 td.code { white-space: pre-wrap; word-break: break-all; width: 100%; }
    333 
    334 tr.hunk-header td {
    335   background: var(--hunk-bg);
    336   color: var(--muted);
    337   padding: 0.2em 0.5em;
    338 }
    339 
    340 tr.line { cursor: pointer; }
    341 tr.line:hover td.code { box-shadow: inset 2px 0 0 var(--accent); }
    342 tr.line.add td { background: var(--add-bg); }
    343 tr.line.add td.gutter { background: var(--add-gutter); }
    344 tr.line.del td { background: var(--del-bg); }
    345 tr.line.del td.gutter { background: var(--del-gutter); }
    346 tr.line.commented td.code { box-shadow: inset 3px 0 0 var(--accent); }
    347 
    348 /* Intra-line highlight: the span that actually changed within a line. */
    349 tr.line.add td.code .hl { background: var(--add-gutter); border-radius: 2px; }
    350 tr.line.del td.code .hl { background: var(--del-gutter); border-radius: 2px; }
    351 
    352 tr.comment-row td { padding: 0; }
    353 
    354 .comment-box {
    355   margin: 0.3rem 2rem 0.5rem 3.5rem;
    356   border: 1px solid var(--border);
    357   border-radius: 6px;
    358   background: var(--comment-bg);
    359   font-family: -apple-system, "Segoe UI", sans-serif;
    360 }
    361 
    362 .comment-box .comment-text { padding: 0.5rem 0.8rem; white-space: pre-wrap; }
    363 
    364 .comment-box textarea {
    365   display: block;
    366   width: 100%;
    367   min-height: 4.5em;
    368   padding: 0.5rem 0.8rem;
    369   border: 0;
    370   border-bottom: 1px solid var(--border);
    371   background: transparent;
    372   color: var(--fg);
    373   font: inherit;
    374   resize: vertical;
    375 }
    376 
    377 .comment-box .comment-actions {
    378   display: flex;
    379   gap: 0.4rem;
    380   justify-content: flex-end;
    381   padding: 0.3rem 0.5rem;
    382   /* The editor inherits the yellow comment-box bg; the action row should read
    383      as a distinct footer, not blend into the yellow. */
    384   background: var(--surface);
    385   border-radius: 0 0 5px 5px;
    386 }
    387 
    388 #send-confirm {
    389   position: fixed;
    390   inset: 0;
    391   display: flex;
    392   align-items: center;
    393   justify-content: center;
    394   background: rgba(0, 0, 0, 0.4);
    395   z-index: 5;
    396 }
    397 
    398 #send-confirm .modal-card {
    399   width: min(32rem, 90vw);
    400   border: 1px solid var(--border);
    401   border-radius: 8px;
    402   background: var(--bg);
    403   box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
    404   padding: 1.2rem 1.4rem;
    405 }
    406 
    407 #send-confirm h2 {
    408   margin: 0 0 0.4rem;
    409   font-size: 15px;
    410 }
    411 
    412 #send-confirm-summary {
    413   margin: 0 0 0.8rem;
    414   color: var(--muted);
    415   font-size: 12px;
    416 }
    417 
    418 #send-confirm #srht-status {
    419   display: flex;
    420   align-items: center;
    421   gap: 0.4rem;
    422   margin: 0 0 0.8rem;
    423   color: var(--muted);
    424 }
    425 
    426 #send-confirm #srht-status select {
    427   padding: 0.2rem 0.3rem;
    428   border: 1px solid var(--border);
    429   border-radius: 6px;
    430   background: var(--bg);
    431   color: var(--fg);
    432   font: inherit;
    433 }
    434 
    435 #send-confirm .modal-actions {
    436   display: flex;
    437   gap: 0.5rem;
    438   justify-content: flex-end;
    439 }
    440 
    441 #status {
    442   position: fixed;
    443   inset: auto 1rem 1rem auto;
    444   width: min(44rem, 90vw);
    445   max-height: 60vh;
    446   display: flex;
    447   flex-direction: column;
    448   border: 1px solid var(--border);
    449   border-radius: 6px;
    450   background: var(--surface);
    451   box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
    452   z-index: 3;
    453 }
    454 
    455 #status-text {
    456   margin: 0;
    457   padding: 0.8rem 1rem;
    458   overflow: auto;
    459   font: 12px/1.45 ui-monospace, monospace;
    460   white-space: pre-wrap;
    461 }
    462 
    463 #status-buttons {
    464   display: flex;
    465   gap: 0.5rem;
    466   justify-content: flex-end;
    467   padding: 0.5rem;
    468   border-top: 1px solid var(--border);
    469 }
    470 
    471 .error { color: #d1242f; }
    472 @media (prefers-color-scheme: dark) { .error { color: #ff7b72; } }