internal/web/static/style.css

1790a024c2586d46bfb1b57f69adc529e7f78282
gitbay/internal/web/static/style.css history · blame · raw

1274 lines · 41459 bytes

   1/* gitbay stylesheet — Harbor: black and white ground, two accents with
   2   separate jobs. Blue is what you can do (links, buttons, focus); orange
   3   is where you are and what wants you (active nav, counts, pending state,
   4   unverified signatures). Orange is never a button, so the two never
   5   compete. One file, light and dark via prefers-color-scheme. Tokens
   6   first; components use tokens only. No external requests: Atkinson
   7   Hyperlegible is served from this origin. */
   8
   9@font-face {
  10  font-family: "Atkinson Hyperlegible Next";
  11  font-style: normal;
  12  font-weight: 400 700;
  13  font-display: swap;
  14  src: url(/static/fonts/atkinson-next-roman.woff2) format("woff2");
  15}
  16@font-face {
  17  font-family: "Atkinson Hyperlegible Next";
  18  font-style: italic;
  19  font-weight: 400 700;
  20  font-display: swap;
  21  src: url(/static/fonts/atkinson-next-italic.woff2) format("woff2");
  22}
  23@font-face {
  24  font-family: "Atkinson Hyperlegible Mono";
  25  font-style: normal;
  26  font-weight: 400 600;
  27  font-display: swap;
  28  src: url(/static/fonts/atkinson-mono-roman.woff2) format("woff2");
  29}
  30
  31:root {
  32  /* declare native light+dark support: correct form controls and
  33     scrollbars per scheme, and opt out of browser auto-darkening */
  34  color-scheme: light dark;
  35
  36  /* ground and ink */
  37  --bg: #ffffff;
  38  --fg: #0d0d0d;
  39  --muted: #595959;          /* 7.00:1 on white */
  40  --faint: #eaeaea;          /* hairlines, row separators */
  41  --line: #d4d4d4;           /* control borders, table edges */
  42  --surface: #ffffff;
  43  --hover: #f5f5f5;
  44  --code-bg: #f5f5f5;
  45
  46  /* blue: what you can do */
  47  --accent: #0000f0;         /* links, focus — 9.30:1 on white */
  48  --accent-fg: #ffffff;
  49  --fill: #0000f0;           /* button grounds; white on it is 9.30:1 */
  50
  51  /* orange: where you are, what wants you */
  52  --mark: #e4572e;           /* bars and underlines — non-text, 3.0 bar */
  53  --warn: #c2410c;           /* the same orange at text size — 5.18:1 */
  54
  55  /* semantic */
  56  --ok: #0a7d3c;
  57  --bad: #c62828;
  58  --done: #6b21a8;           /* merged */
  59  --neutral: #595959;
  60
  61  /* the rail is black in both schemes: the one brand constant */
  62  --shell-bg: #000000;
  63  --shell-fg: #f2f2f2;
  64  --shell-muted: #8f8f8f;
  65  --shell-line: #1c1c1c;
  66  --shell-hover: #141414;
  67  --shell-mark: #ff6b3d;     /* 7.42:1 on black, both schemes */
  68
  69  /* type */
  70  --sans: "Atkinson Hyperlegible Next", -apple-system, BlinkMacSystemFont,
  71          "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  72  --mono: "Atkinson Hyperlegible Mono", ui-monospace, "SF Mono",
  73          SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  74  --fs-0: 0.78rem;
  75  --fs-1: 0.85rem;
  76  --fs-2: 0.92rem;
  77  --fs-3: 1rem;
  78  --fs-4: 1.2rem;
  79  --fs-5: 1.6rem;
  80
  81  /* spacing */
  82  --sp-1: 0.25rem;
  83  --sp-2: 0.5rem;
  84  --sp-3: 0.75rem;
  85  --sp-4: 1rem;
  86  --sp-5: 1.5rem;
  87  --sp-6: 2.5rem;
  88
  89  --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23595959' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  90
  91  /* radii: 2px everywhere — chart plates, not pills */
  92  --r-sm: 2px;
  93  --r-md: 2px;
  94  --r-lg: 2px;
  95  --r-pill: 2px;
  96}
  97@media (prefers-color-scheme: dark) {
  98  :root {
  99    --bg: #0a0a0a;
 100    --fg: #f2f2f2;
 101    --muted: #a1a1a1;        /* 7.66:1 on #0a0a0a */
 102    --faint: #1c1c1c;
 103    --line: #2e2e2e;
 104    --surface: #0f0f0f;
 105    --hover: #161616;
 106    --code-bg: #050505;
 107    --accent: #5b6bff;       /* 4.71:1 — pure #0000f0 is 2.13:1 here */
 108    --accent-fg: #ffffff;
 109    --fill: #0000f0;         /* fills stay pure; white on it clears 9:1 */
 110    --mark: #ff6b3d;
 111    --warn: #ff6b3d;
 112    --ok: #3fce7a;
 113    --bad: #ff6b6b;
 114    --done: #c084fc;
 115    --neutral: #a1a1a1;
 116    --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23a1a1a1' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
 117  }
 118}
 119
 120* { box-sizing: border-box; }
 121html { font-size: 15px; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
 122body {
 123  margin: 0;
 124  background: var(--bg);
 125  color: var(--fg);
 126  font: var(--fs-3)/1.6 var(--sans);
 127  min-height: 100vh;
 128}
 129
 130a { color: var(--accent); text-decoration: none; }
 131a:hover { text-decoration: underline; }
 132
 133/* one authored focus ring, so keyboard position is never the browser's
 134   guess. Blue, because focus is an interactive state. */
 135:focus-visible {
 136  outline: 2px solid var(--accent);
 137  outline-offset: 2px;
 138  border-radius: 1px;
 139}
 140
 141/* visually hidden, still read aloud: for headings a sighted reader gets
 142   from the layout but a screen reader would otherwise miss */
 143.vh {
 144  position: absolute;
 145  width: 1px; height: 1px;
 146  margin: -1px; padding: 0; border: 0;
 147  clip-path: inset(50%);
 148  overflow: hidden;
 149  white-space: nowrap;
 150}
 151/* the rail runs ahead of the content in source order, so give keyboard
 152   and screen-reader users a way past it */
 153a.skip {
 154  position: absolute;
 155  left: var(--sp-3); top: -3rem;
 156  z-index: 50;
 157  background: var(--fill);
 158  color: #ffffff;
 159  padding: var(--sp-2) var(--sp-4);
 160  font-weight: 600;
 161}
 162a.skip:focus { top: var(--sp-3); text-decoration: none; }
 163
 164h1 { font-size: var(--fs-5); font-weight: 700; line-height: 1.18;
 165     margin: 0 0 var(--sp-3); letter-spacing: -0.025em; text-wrap: balance; }
 166h2 { font-size: var(--fs-4); font-weight: 700; line-height: 1.3;
 167     margin: var(--sp-5) 0 var(--sp-3); letter-spacing: -0.015em; }
 168h3 { font-size: var(--fs-3); font-weight: 600; margin: var(--sp-5) 0 var(--sp-2); }
 169
 170code, pre, .code, td.mode, td.size {
 171  font-family: var(--mono);
 172  font-size: var(--fs-1);
 173}
 174
 175/* ---- shell: black rail, content pane ---- */
 176.shell { display: flex; align-items: stretch; min-height: 100vh; }
 177
 178.rail {
 179  flex: none;
 180  width: 13rem;
 181  background: var(--shell-bg);
 182  color: var(--shell-fg);
 183  border-right: 1px solid var(--shell-line);
 184  position: sticky;
 185  top: 0;
 186  height: 100vh;
 187  display: flex;
 188  flex-direction: column;
 189}
 190a.brand {
 191  display: flex;
 192  align-items: center;
 193  gap: var(--sp-2);
 194  padding: var(--sp-3) var(--sp-4);
 195  color: var(--shell-fg);
 196  font-weight: 700;
 197  font-size: var(--fs-3);
 198  letter-spacing: -0.02em;
 199  border-bottom: 1px solid var(--shell-line);
 200}
 201a.brand:hover { text-decoration: none; color: #ffffff; }
 202a.brand svg.mark { display: block; flex: none; }
 203a.brand span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
 204
 205.railbody { flex: 1; overflow-y: auto; padding: var(--sp-3) 0; }
 206ul.raillist { list-style: none; margin: 0; padding: 0; }
 207ul.raillist a {
 208  display: block;
 209  padding: 0.28rem var(--sp-4);
 210  color: var(--shell-fg);
 211  font-size: var(--fs-2);
 212  border-left: 3px solid transparent;
 213  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
 214}
 215ul.raillist a:hover { background: var(--shell-hover); text-decoration: none; }
 216/* orange marks position — the rail's only accent */
 217ul.raillist a[aria-current] {
 218  border-left-color: var(--shell-mark);
 219  background: var(--shell-hover);
 220  font-weight: 600;
 221}
 222ul.raillist .owner { color: var(--shell-muted); }
 223ul.raillist.wide a { white-space: normal; padding-top: var(--sp-1); padding-bottom: var(--sp-1); }
 224ul.raillist.wide b { display: block; font-weight: 500; font-size: var(--fs-1); }
 225ul.raillist.wide .owner { font-size: var(--fs-0); }
 226
 227.raillabel {
 228  display: flex;
 229  align-items: center;
 230  gap: var(--sp-2);
 231  margin: var(--sp-4) 0 var(--sp-1);
 232  padding: 0 var(--sp-4);
 233  font-family: var(--mono);
 234  font-size: var(--fs-0);
 235  font-weight: 500;
 236  letter-spacing: 0.1em;
 237  text-transform: uppercase;
 238  color: var(--shell-muted);
 239}
 240.raillabel .count {
 241  font-family: var(--sans);
 242  font-size: var(--fs-0);
 243  font-weight: 700;
 244  letter-spacing: 0;
 245  background: var(--shell-mark);
 246  color: #000000;
 247  padding: 0 0.35rem;
 248  border-radius: var(--r-sm);
 249}
 250.railfoot {
 251  flex: none;
 252  border-top: 1px solid var(--shell-line);
 253  padding: var(--sp-2) var(--sp-4);
 254  display: flex;
 255  align-items: center;
 256  gap: var(--sp-3);
 257  font-size: var(--fs-2);
 258}
 259.railfoot a { color: var(--shell-fg); }
 260a.railuser { display: inline-flex; align-items: center; gap: var(--sp-2); }
 261.railfoot .linklike {
 262  background: none; border: 0; padding: 0; cursor: pointer;
 263  color: var(--shell-muted); font: inherit; text-decoration: underline;
 264}
 265.railfoot .linklike:hover { color: var(--shell-fg); }
 266.avatar {
 267  width: 1.4rem; height: 1.4rem; flex: none;
 268  display: inline-grid; place-items: center;
 269  background: var(--fill);
 270  color: #ffffff;
 271  font-size: var(--fs-0);
 272  font-weight: 700;
 273  border-radius: var(--r-sm);
 274}
 275
 276.pane { flex: 1; min-width: 0; display: flex; flex-direction: column; }
 277.content {
 278  flex: 1;
 279  padding: var(--sp-5) var(--sp-5) var(--sp-6);
 280  max-width: 78rem;
 281  width: 100%;
 282}
 283
 284/* ---- repo header: identity and tabs on every page, the rest once ---- */
 285.repohead {
 286  padding: var(--sp-4) var(--sp-5) 0;
 287  border-bottom: 1px solid var(--line);
 288}
 289.repohead .identity { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
 290.repohead .identity .grow { flex: 1; }
 291.repotitle {
 292  margin: 0;
 293  font-size: var(--fs-4);
 294  font-weight: 700;
 295  letter-spacing: -0.02em;
 296  line-height: 1.3;
 297}
 298h1.repotitle { font-size: var(--fs-5); }
 299.repotitle a { color: var(--fg); }
 300.repotitle a.owner { color: var(--muted); font-weight: 400; }
 301.repotitle a:hover { color: var(--accent); text-decoration: none; }
 302.repotitle .sep { color: var(--muted); margin: 0 0.12em; font-weight: 400; }
 303.repodesc { margin: var(--sp-2) 0 0; color: var(--muted); font-size: var(--fs-2); max-width: 62ch; }
 304.repometa { margin: var(--sp-1) 0 0; color: var(--muted); font-size: var(--fs-1); }
 305.repohead .topics { margin: var(--sp-2) 0 0; }
 306
 307button.btn {
 308  font: inherit;
 309  font-size: var(--fs-1);
 310  font-weight: 600;
 311  padding: 0.15rem 0.7rem;
 312  border: 1px solid var(--line);
 313  border-radius: var(--r-sm);
 314  background: var(--bg);
 315  color: var(--fg);
 316  cursor: pointer;
 317}
 318button.btn:hover { border-color: var(--accent); color: var(--accent); }
 319button.btn[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }
 320form.inline { display: inline; }
 321
 322nav.tabs {
 323  display: flex;
 324  gap: var(--sp-1);
 325  margin-top: var(--sp-4);
 326  overflow-x: auto;
 327  scrollbar-width: none;
 328}
 329nav.tabs::-webkit-scrollbar { display: none; }
 330nav.tabs a {
 331  display: inline-flex;
 332  align-items: center;
 333  gap: var(--sp-2);
 334  padding: var(--sp-2) var(--sp-3) 0.6rem;
 335  color: var(--muted);
 336  font-size: var(--fs-2);
 337  white-space: nowrap;
 338  border-bottom: 2px solid transparent;
 339  margin-bottom: -1px;
 340}
 341nav.tabs a:hover { color: var(--fg); text-decoration: none; }
 342/* orange marks position here too */
 343nav.tabs a[aria-current] {
 344  color: var(--fg);
 345  font-weight: 700;
 346  border-bottom-color: var(--mark);
 347}
 348nav.tabs a i {
 349  font-style: normal;
 350  font-family: var(--mono);
 351  font-size: var(--fs-0);
 352  background: var(--hover);
 353  border-radius: var(--r-sm);
 354  padding: 0 0.35rem;
 355}
 356
 357/* ---- mobile: the rail becomes a single strip, not a wall of links ---- */
 358@media (max-width: 52rem) {
 359  .shell { display: block; }
 360  .rail {
 361    width: auto;
 362    height: auto;
 363    position: static;
 364    flex-direction: row;
 365    align-items: center;
 366    gap: var(--sp-2);
 367    border-right: 0;
 368    border-bottom: 1px solid var(--shell-line);
 369    overflow-x: auto;
 370  }
 371  a.brand { border-bottom: 0; padding-right: var(--sp-2); }
 372  .railbody { flex: 1; overflow: visible; padding: 0; display: flex; align-items: center; }
 373  /* pinned repos and the review queue both live on the dashboard, so the
 374     strip keeps only what has nowhere else to go */
 375  .railgroup { display: none; }
 376  ul.raillist { display: flex; }
 377  ul.raillist a { border-left: 0; border-bottom: 2px solid transparent; padding: var(--sp-2) var(--sp-3); }
 378  ul.raillist a[aria-current] { border-left: 0; border-bottom-color: var(--shell-mark); }
 379  .railfoot { border-top: 0; padding-left: var(--sp-2); }
 380  .content { padding: var(--sp-4) var(--sp-4) var(--sp-5); }
 381  .repohead { padding: var(--sp-3) var(--sp-4) 0; }
 382}
 383
 384/* tables */
 385table { border-collapse: collapse; width: 100%; }
 386td {
 387  padding: var(--sp-2) var(--sp-4) var(--sp-2) 0;
 388  border-bottom: 1px solid var(--faint);
 389  vertical-align: top;
 390  font-size: var(--fs-2);
 391}
 392td:last-child { padding-right: 0; }
 393td.size, td.mode { color: var(--muted); white-space: nowrap; }
 394
 395/* path bar on tree and blob pages */
 396.pathbar {
 397  display: flex;
 398  flex-wrap: wrap;
 399  align-items: center;
 400  gap: var(--sp-2) var(--sp-3);
 401  margin: var(--sp-3) 0;
 402  font-size: var(--fs-2);
 403}
 404.pathbar .spacer { flex: 1; }
 405.refchip {
 406  display: inline-flex;
 407  align-items: center;
 408  gap: 0.3rem;
 409  background: var(--surface);
 410  border: 1px solid var(--faint);
 411  border-radius: var(--r-md);
 412  padding: 0.1rem 0.55rem;
 413  font-family: var(--mono);
 414  font-size: var(--fs-1);
 415  color: var(--fg);
 416}
 417.pathbar .crumbs strong { color: var(--fg); }
 418details.refmenu { position: relative; }
 419details.refmenu summary { cursor: pointer; list-style: none; }
 420details.refmenu summary::-webkit-details-marker { display: none; }
 421details.refmenu summary::after { content: " ▾"; color: var(--muted); }
 422details.refmenu .refdrop {
 423  position: absolute;
 424  z-index: 10;
 425  top: calc(100% + 4px);
 426  left: 0;
 427  min-width: 12rem;
 428  max-height: 20rem;
 429  overflow-y: auto;
 430  background: var(--bg);
 431  border: 1px solid var(--line);
 432  border-radius: var(--r-md);
 433  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
 434  padding: var(--sp-1) 0;
 435}
 436details.refmenu .refdrop a {
 437  display: block;
 438  padding: var(--sp-1) var(--sp-3);
 439  color: var(--fg);
 440  font-family: var(--mono);
 441  font-size: var(--fs-1);
 442}
 443details.refmenu .refdrop a:hover { background: var(--hover); text-decoration: none; }
 444details.refmenu .refdrop a.allrefs { color: var(--accent); font-family: var(--sans); border-top: 1px solid var(--faint); margin-top: var(--sp-1); }
 445
 446/* file and refs tables: bordered cards, rows inside */
 447table.tree, table.refs {
 448  background: var(--surface);
 449  border: 1px solid var(--line);
 450  border-radius: var(--r-lg);
 451  border-collapse: separate;
 452  border-spacing: 0;
 453  overflow: hidden;
 454  margin-bottom: var(--sp-4);
 455}
 456table.tree td, table.refs td {
 457  padding: var(--sp-2) var(--sp-4);
 458  border-bottom: 1px solid var(--faint);
 459}
 460table.tree tr:last-child td, table.refs tr:last-child td { border-bottom: none; }
 461table.tree tr:hover td, table.refs tr:hover td { background: var(--hover); }
 462table.tree tr.cols th {
 463  text-align: left;
 464  font-weight: 500;
 465  font-size: var(--fs-1);
 466  color: var(--muted);
 467  padding: var(--sp-1) var(--sp-4);
 468  border-bottom: 1px solid var(--line);
 469  background: var(--bg);
 470}
 471table.tree tr.cols:hover th { background: var(--bg); }
 472table.tree th.size { text-align: right; }
 473table.tree td.name { width: 100%; }
 474table.tree td.name a { color: var(--fg); }
 475table.tree td.name a:hover { color: var(--accent); }
 476table.tree td.size { text-align: right; }
 477table.tree td.empty, table.refs td.empty, li.empty, ul.loglist li.empty { color: var(--muted); }
 478
 479/* refs page */
 480table.refs td.name { width: 100%; }
 481table.refs td.sha { color: var(--muted); }
 482
 483/* card header (README) */
 484.cardhead {
 485  font-family: var(--mono);
 486  font-size: var(--fs-1);
 487  color: var(--muted);
 488  border-bottom: 1px solid var(--faint);
 489  margin: calc(-1 * var(--sp-4)) calc(-1 * var(--sp-5)) var(--sp-4);
 490  padding: var(--sp-2) var(--sp-5);
 491  background: var(--bg);
 492  border-radius: var(--r-lg) var(--r-lg) 0 0;
 493}
 494
 495/* log */
 496ul.loglist {
 497  list-style: none;
 498  margin: var(--sp-3) 0;
 499  padding: 0;
 500  background: var(--surface);
 501  border: 1px solid var(--line);
 502  border-radius: var(--r-lg);
 503  overflow: hidden;
 504}
 505ul.loglist li {
 506  display: flex;
 507  align-items: baseline;
 508  gap: var(--sp-3);
 509  padding: var(--sp-2) var(--sp-4);
 510  border-bottom: 1px solid var(--faint);
 511}
 512ul.loglist li:last-child { border-bottom: none; }
 513ul.loglist li:hover { background: var(--hover); }
 514ul.loglist .commitmain { flex: 1; min-width: 0; }
 515ul.loglist p { margin: 0; }
 516ul.loglist .subject a { color: var(--fg); font-weight: 550; }
 517ul.loglist .subject a:hover { color: var(--accent); }
 518ul.loglist .commitside {
 519  display: flex;
 520  align-items: baseline;
 521  gap: var(--sp-2);
 522  white-space: nowrap;
 523}
 524p.pager { margin-top: var(--sp-4); }
 525
 526/* commit page */
 527.commithead p { margin: var(--sp-1) 0; }
 528.commithead h2 { margin-bottom: var(--sp-1); }
 529code.fullsha { color: var(--muted); overflow-wrap: anywhere; }
 530.empty-note { color: var(--muted); }
 531.crumbs { color: var(--muted); font-size: var(--fs-2); }
 532.desc, td.desc { color: var(--muted); }
 533.error {
 534  color: var(--fg);
 535  border: 1px solid var(--bad);
 536  border-left-width: 3px;
 537  border-radius: var(--r-sm);
 538  padding: var(--sp-2) var(--sp-3);
 539  margin-bottom: var(--sp-4);
 540}
 541.meta { color: var(--muted); font-size: var(--fs-1); }
 542svg.icon { vertical-align: -0.125em; }
 543.lede { font-size: var(--fs-3); margin: var(--sp-2) 0; }
 544
 545/* repo listings (explore, owner pages, dashboard): one row per repo */
 546ul.repolist {
 547  list-style: none;
 548  margin: var(--sp-3) 0 var(--sp-5);
 549  padding: 0;
 550  background: var(--surface);
 551  border: 1px solid var(--line);
 552  border-radius: var(--r-lg);
 553  overflow: hidden;
 554}
 555ul.repolist li { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--faint); }
 556/* pinned repos: a compact wrap of name pills, no description or meta */
 557ul.pinlist {
 558  list-style: none;
 559  margin: var(--sp-3) 0 var(--sp-5);
 560  padding: 0;
 561  display: flex;
 562  flex-wrap: wrap;
 563  gap: var(--sp-2);
 564}
 565ul.pinlist li {
 566  background: var(--surface);
 567  border: 1px solid var(--line);
 568  border-radius: var(--r-md);
 569  padding: var(--sp-1) var(--sp-3);
 570}
 571ul.pinlist li:hover { background: var(--hover); }
 572ul.pinlist li a { color: var(--fg); }
 573ul.pinlist li a:hover { color: var(--accent); text-decoration: none; }
 574ul.pinlist .sep { color: var(--muted); margin: 0 0.15em; }
 575ul.repolist li:last-child { border-bottom: none; }
 576ul.repolist li:hover { background: var(--hover); }
 577ul.repolist li.empty { color: var(--muted); }
 578ul.repolist p { margin: 0; }
 579ul.repolist .reponame { font-size: var(--fs-3); }
 580ul.repolist .reponame a { color: var(--fg); }
 581ul.repolist .reponame a strong { color: var(--accent); font-weight: 600; }
 582ul.repolist .reponame .sep { color: var(--muted); margin: 0 0.1em; }
 583ul.repolist .desc { margin-top: 0.1rem; }
 584ul.repolist .topics { margin-top: var(--sp-1); }
 585ul.repolist .meta { margin-top: var(--sp-1); }
 586
 587/* owner profile header */
 588.profilehead {
 589  border-bottom: 1px solid var(--faint);
 590  padding-bottom: var(--sp-4);
 591  margin-bottom: var(--sp-4);
 592}
 593.profilehead h1 { margin: var(--sp-4) 0 var(--sp-1); }
 594.profilehead .lede { margin: 0 0 var(--sp-1); }
 595.profilehead .meta { margin: var(--sp-1) 0 0; }
 596h2 .count { color: var(--muted); font-weight: 400; font-size: var(--fs-2); }
 597
 598/* activity graph: 53 week columns x 7 day rows, accent-tinted levels */
 599.actgraph-scroll { overflow-x: auto; padding-bottom: var(--sp-1); }
 600.actgraph { display: flex; gap: 3px; width: max-content; }
 601.actweek { display: flex; flex-direction: column; gap: 3px; }
 602.actday {
 603  width: 11px;
 604  height: 11px;
 605  border-radius: 2px;
 606  background: var(--faint);
 607}
 608.actday.pad { background: transparent; }
 609.actday.l1 { background: color-mix(in srgb, var(--accent) 25%, var(--bg)); }
 610.actday.l2 { background: color-mix(in srgb, var(--accent) 50%, var(--bg)); }
 611.actday.l3 { background: color-mix(in srgb, var(--accent) 75%, var(--bg)); }
 612.actday.l4 { background: var(--accent); }
 613
 614/* heading row with actions on the right */
 615.headrow {
 616  display: flex;
 617  align-items: baseline;
 618  gap: var(--sp-4);
 619  flex-wrap: wrap;
 620}
 621.headrow .spacer { flex: 1; }
 622
 623/* member and org chips on owner pages */
 624a.memberchip {
 625  display: inline-block;
 626  border: 1px solid var(--line);
 627  border-radius: var(--r-pill);
 628  padding: 0.05rem 0.6rem;
 629  color: var(--fg);
 630  font-size: var(--fs-1);
 631  margin: 0 0.15rem 0.15rem 0;
 632}
 633a.memberchip:hover { text-decoration: none; border-color: var(--accent); color: var(--accent); }
 634a.memberchip .role { color: var(--muted); }
 635
 636/* landing page */
 637.landing { max-width: 44rem; padding: var(--sp-6) 0; }
 638.landing h1 { font-size: 1.8rem; margin-bottom: var(--sp-3); }
 639.landing .lede { font-size: var(--fs-4); color: var(--muted); line-height: 1.7; margin: 0 0 var(--sp-4); }
 640pre.quickstart {
 641  background: var(--code-bg);
 642  border: 1px solid var(--line);
 643  border-radius: var(--r-md);
 644  padding: var(--sp-3) var(--sp-4);
 645  overflow-x: auto;
 646  margin: 0 0 var(--sp-4);
 647}
 648.landing .explorelink { font-weight: 550; }
 649
 650/* index toolbar */
 651p.toolbar { color: var(--muted); font-size: var(--fs-2); margin-top: var(--sp-4); }
 652form.inline { display: inline; }
 653button.linklike {
 654  background: none;
 655  border: none;
 656  color: var(--accent);
 657  padding: 0;
 658  font: inherit;
 659  font-size: var(--fs-2);
 660  cursor: pointer;
 661}
 662button.linklike:hover { text-decoration: underline; filter: none; }
 663
 664/* cards: README, comments */
 665.readme, .code {
 666  background: var(--surface);
 667  border: 1px solid var(--line);
 668  border-radius: var(--r-lg);
 669  padding: var(--sp-4) var(--sp-5);
 670  margin-top: var(--sp-4);
 671  overflow-x: auto;
 672}
 673/* Highlighting is class-based with a palette per scheme, so code blocks
 674   follow the site's own colors. */
 675.code { background: var(--code-bg); color: var(--fg); padding: var(--sp-3) var(--sp-4); border-color: var(--line); }
 676.code pre { margin: 0; background: transparent !important; }
 677@media (prefers-color-scheme: dark) {
 678  .code { border-color: var(--line); }
 679}
 680
 681/* rendered markdown / org / html */
 682.rendered { max-width: 100%; overflow-wrap: anywhere; }
 683.rendered pre {
 684  background: var(--code-bg);
 685  border: 1px solid var(--line);
 686  padding: var(--sp-3) var(--sp-4);
 687  border-radius: var(--r-md);
 688  overflow-x: auto;
 689}
 690.rendered code {
 691  background: var(--code-bg);
 692  border: 1px solid var(--line);
 693  padding: 0.05rem 0.3rem;
 694  border-radius: var(--r-sm);
 695}
 696.rendered pre code { background: transparent; border: none; padding: 0; }
 697.rendered blockquote {
 698  border-left: 3px solid var(--line);
 699  margin-left: 0;
 700  padding-left: var(--sp-4);
 701  color: var(--muted);
 702}
 703.rendered img { max-width: 100%; }
 704.rendered h1, .rendered h2 { border-bottom: 1px solid var(--faint); padding-bottom: var(--sp-1); }
 705.rendered table {
 706  border-collapse: collapse;
 707  margin: var(--sp-3) 0;
 708  display: block;
 709  max-width: 100%;
 710  overflow-x: auto;
 711}
 712.rendered th, .rendered td {
 713  border: 1px solid var(--line);
 714  padding: var(--sp-1) var(--sp-3);
 715  text-align: left;
 716  overflow-wrap: normal; /* scroll the table, don't shatter words */
 717}
 718.rendered th { background: var(--surface); font-weight: 600; }
 719.blobimage { text-align: center; }
 720.blobimage img {
 721  max-width: 100%;
 722  border: 1px solid var(--faint);
 723  border-radius: var(--r-md);
 724  background: var(--surface);
 725}
 726
 727pre.message {
 728  background: var(--code-bg);
 729  border: 1px solid var(--line);
 730  padding: var(--sp-3) var(--sp-4);
 731  border-radius: var(--r-md);
 732  white-space: pre-wrap;
 733  overflow-wrap: anywhere;
 734}
 735
 736/* diffs */
 737details.difffold summary {
 738  cursor: pointer;
 739  display: flex;
 740  align-items: baseline;
 741  gap: var(--sp-3);
 742  margin: var(--sp-5) 0 var(--sp-2);
 743  list-style: none;
 744}
 745details.difffold summary::-webkit-details-marker { display: none; }
 746/* flex summaries lose the native disclosure marker; draw our own */
 747details.difffold summary::before { content: "▸"; color: var(--muted); }
 748details.difffold[open] summary::before { content: "▾"; }
 749details.difffold summary h3 { display: inline; margin: 0; }
 750details.difffold summary .add { color: var(--ok); }
 751details.difffold summary .del { color: var(--bad); }
 752pre.diff {
 753  background: var(--code-bg);
 754  border: 1px solid var(--line);
 755  padding: var(--sp-3) var(--sp-4);
 756  border-radius: var(--r-md);
 757  overflow-x: auto;
 758  line-height: 1.5;
 759}
 760pre.diff .add { color: var(--ok); }
 761pre.diff .del { color: var(--bad); }
 762pre.diff .hunk { color: var(--accent); }
 763pre.diff .meta { color: var(--muted); }
 764
 765/* badges: signature and check states. Semantic colors stay distinct:
 766   green verified/success, amber pending/stale, red bad/failure, muted
 767   unsigned. */
 768.badge, .chip {
 769  --chip: var(--neutral);
 770  display: inline-block;
 771  padding: 0.05rem 0.55rem;
 772  border-radius: var(--r-pill);
 773  font-size: var(--fs-0);
 774  font-weight: 500;
 775  line-height: 1.5;
 776  color: var(--chip);
 777  border: 1px solid color-mix(in srgb, var(--chip) 35%, transparent);
 778  background: color-mix(in srgb, var(--chip) 7%, transparent);
 779  white-space: nowrap;
 780  vertical-align: middle;
 781}
 782.chip-open { --chip: var(--ok); }
 783.chip-closed { --chip: var(--bad); }
 784.chip-merged, .chip-done { --chip: var(--done); }
 785.chip-neutral, .chip-source_gone { --chip: var(--neutral); }
 786.chip-stale { --chip: var(--warn); }
 787.chip.label { font-weight: 500; }
 788.chip.topic { --chip: var(--accent); }
 789.repohead .topics { margin: 0 0 var(--sp-2); }
 790.repohead .mirrorline { margin: 0 0 var(--sp-2); }
 791.mirrorerr { color: var(--bad); }
 792.badge-verified { --chip: var(--ok); }
 793.badge-unsigned { --chip: var(--neutral); }
 794.badge-signed_unknown_key { --chip: var(--warn); }
 795.badge-signed_email_mismatch { --chip: var(--bad); }
 796.badge-signed_key_expired { --chip: var(--warn); }
 797.badge-signed_key_revoked { --chip: var(--bad); }
 798.badge-bad_signature { --chip: var(--bad); }
 799.badge.check-success { --chip: var(--ok); }
 800.badge.check-pending { --chip: var(--warn); }
 801.badge.check-failure, .badge.check-error { --chip: var(--bad); }
 802.badge.check-running, .chip.check-running { --chip: var(--warn); }
 803.chip.check-success { --chip: var(--ok); }
 804.chip.check-pending { --chip: var(--warn); }
 805.chip.check-failure { --chip: var(--bad); }
 806pre.buildlog { max-height: 40rem; overflow: auto; }
 807span.check-success { color: var(--ok); }
 808span.check-pending { color: var(--warn); }
 809span.check-failure, span.check-error { color: var(--bad); }
 810
 811/* issue and MR listings */
 812.listhead {
 813  display: flex;
 814  align-items: baseline;
 815  gap: var(--sp-4);
 816  flex-wrap: wrap;
 817}
 818.listhead h2 { margin-bottom: var(--sp-2); }
 819nav.filters { display: flex; gap: var(--sp-1); }
 820nav.filters a {
 821  color: var(--muted);
 822  font-size: var(--fs-2);
 823  padding: 0.05rem var(--sp-2);
 824  border-radius: var(--r-pill);
 825}
 826nav.filters a:hover { color: var(--fg); background: var(--hover); text-decoration: none; }
 827nav.filters a.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
 828
 829ul.issuelist {
 830  list-style: none;
 831  margin: var(--sp-2) 0;
 832  padding: 0;
 833  background: var(--surface);
 834  border: 1px solid var(--line);
 835  border-radius: var(--r-lg);
 836  overflow: hidden;
 837}
 838ul.issuelist li {
 839  display: flex;
 840  align-items: baseline;
 841  gap: var(--sp-3);
 842  padding: var(--sp-3) var(--sp-4);
 843  border-bottom: 1px solid var(--faint);
 844}
 845ul.issuelist li:last-child { border-bottom: none; }
 846ul.issuelist li:hover { background: var(--hover); }
 847ul.issuelist li.empty { display: block; color: var(--muted); }
 848ul.issuelist .issuemain { flex: 1; min-width: 0; }
 849ul.issuelist p { margin: 0; }
 850ul.issuelist .title a { color: var(--fg); font-weight: 550; }
 851ul.issuelist .title a:hover { color: var(--accent); }
 852
 853/* releases */
 854article.release {
 855  background: var(--surface);
 856  border: 1px solid var(--line);
 857  border-radius: var(--r-lg);
 858  padding: var(--sp-3) var(--sp-4);
 859  margin: var(--sp-4) 0;
 860}
 861.releasehead { background: none; border: 0; padding: 0; }
 862.releasehead h3 { margin: 0 0 var(--sp-1); }
 863.releasehead .meta { margin: 0 0 var(--sp-2); }
 864table.assets { margin-top: var(--sp-2); }
 865table.assets td.size { color: var(--muted); white-space: nowrap; text-align: right; }
 866table.assets td.name { width: 100%; font-family: var(--mono); font-size: var(--fs-1); }
 867
 868/* milestones */
 869ul.milestonelist {
 870  list-style: none;
 871  margin: var(--sp-2) 0;
 872  padding: 0;
 873  border: 1px solid var(--line);
 874  border-radius: var(--r-lg);
 875  overflow: hidden;
 876}
 877ul.milestonelist li { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--faint); }
 878ul.milestonelist li:last-child { border-bottom: none; }
 879ul.milestonelist li.empty { color: var(--muted); }
 880ul.milestonelist p { margin: 0; }
 881ul.milestonelist .title { font-weight: 550; }
 882.progress {
 883  height: 6px;
 884  background: var(--faint);
 885  border-radius: var(--r-pill);
 886  margin-top: var(--sp-2);
 887  overflow: hidden;
 888  max-width: 24rem;
 889}
 890.progress .bar { height: 100%; background: var(--ok); }
 891.listhead .spacer { flex: 1; }
 892
 893/* issue / MR detail */
 894h2.issuetitle { margin-bottom: var(--sp-1); font-size: var(--fs-5); }
 895.issuenumber { color: var(--muted); font-weight: 400; }
 896.issuemeta { color: var(--muted); font-size: var(--fs-2); margin-top: 0; }
 897.review { font-size: var(--fs-2); }
 898
 899/* comment cards; discussion stays at a readable measure */
 900article.comment, form.commentform {
 901  max-width: 48rem;
 902}
 903article.comment {
 904  border: 1px solid var(--faint);
 905  border-radius: var(--r-lg);
 906  margin: var(--sp-4) 0;
 907}
 908article.comment .commenthead {
 909  background: var(--surface);
 910  border-bottom: 1px solid var(--faint);
 911  border-radius: var(--r-lg) var(--r-lg) 0 0;
 912  padding: var(--sp-2) var(--sp-4);
 913  font-size: var(--fs-2);
 914}
 915article.comment .commenthead .when { color: var(--muted); }
 916article.comment .rendered { padding: 0 var(--sp-4); }
 917article.comment .rendered > :first-child { margin-top: var(--sp-3); }
 918article.comment .rendered > :last-child { margin-bottom: var(--sp-3); }
 919form.commentform { margin: var(--sp-4) 0; }
 920details.editbox { margin: var(--sp-2) 0; max-width: 48rem; }
 921details.editbox summary { cursor: pointer; color: var(--muted); font-size: var(--fs-2); }
 922details.editbox summary:hover { color: var(--accent); }
 923details.editbox input[type="text"] { width: 100%; }
 924.syscomment {
 925  max-width: 48rem;
 926  color: var(--muted);
 927  font-size: var(--fs-2);
 928  margin: var(--sp-3) 0;
 929  padding-left: var(--sp-4);
 930  border-left: 3px solid var(--faint);
 931}
 932.syscomment p { display: inline; margin: 0; }
 933
 934/* review threads under diff lines */
 935.thread {
 936  border: 1px solid var(--faint);
 937  border-left: 3px solid var(--accent);
 938  border-radius: var(--r-md);
 939  padding: var(--sp-2) var(--sp-4);
 940  margin: var(--sp-2) 0 var(--sp-2) var(--sp-6);
 941}
 942.thread.resolved { border-left-color: var(--ok); opacity: 0.75; }
 943.thread.stale { border-left-color: var(--warn); }
 944.thread p.commenthead { font-size: var(--fs-2); margin: var(--sp-2) 0 0; }
 945.thread .when { color: var(--muted); }
 946.thread .rendered p { margin: var(--sp-1) 0; }
 947.thread .threadstate { color: var(--muted); font-size: var(--fs-1); margin: var(--sp-1) 0 0; }
 948
 949/* forms: every control shares one shell, so a select reads as a sibling
 950   of the text inputs beside it rather than as an OS control dropped in */
 951input, textarea, button, select { font: inherit; color: inherit; }
 952input[type="text"], input[type="search"], input[type="email"],
 953input[type="password"], input:not([type]), textarea, select {
 954  background: var(--bg);
 955  color: var(--fg);
 956  border: 1px solid var(--line);
 957  border-radius: var(--r-md);
 958  padding: var(--sp-2) var(--sp-3);
 959  line-height: 1.4;
 960}
 961textarea { width: 100%; resize: vertical; }
 962textarea[name="content"] { font-family: var(--mono); font-size: var(--fs-1); }
 963/* the native arrow cannot be restyled, so draw our own and match the
 964   inputs exactly; --chev carries the stroke colour per scheme */
 965select {
 966  appearance: none;
 967  padding-right: 1.9rem;
 968  background-image: var(--chev);
 969  background-repeat: no-repeat;
 970  background-position: right 0.6rem center;
 971  background-size: 0.62rem;
 972  cursor: pointer;
 973}
 974input:hover, textarea:hover, select:hover { border-color: var(--muted); }
 975/* the global :focus-visible ring covers these; only the border moves */
 976input:focus, textarea:focus, select:focus { border-color: var(--accent); }
 977input[type="radio"], input[type="checkbox"] { accent-color: var(--fill); }
 978label:has(> input[type="radio"]), label:has(> input[type="checkbox"]),
 979label:has(> select) { display: inline-flex; align-items: center; gap: var(--sp-2); }
 980
 981/* Shape carries the meaning on these two and nothing else does: a circle
 982   takes one answer, a square takes any number. It survives colour being
 983   removed — greyscale, high contrast, colour blindness — so the native
 984   shapes stay and only the colour joins the system. Drawing them by hand
 985   would align the corners at the cost of the one cue that always works. */
 986input[type="radio"], input[type="checkbox"] { accent-color: var(--fill); }
 987
 988/* a segmented control for a small, mutually exclusive set: real radios
 989   underneath, so arrow keys and screen readers behave as they always did */
 990fieldset.segmented { border: 0; margin: 0 0 var(--sp-4); padding: 0; }
 991fieldset.segmented legend {
 992  padding: 0;
 993  margin-bottom: var(--sp-2);
 994  color: var(--muted);
 995  font-size: var(--fs-2);
 996}
 997fieldset.segmented .options { display: inline-flex; }
 998fieldset.segmented label { gap: 0; }
 999fieldset.segmented input {
1000  position: absolute;
1001  width: 1px;
1002  height: 1px;
1003  opacity: 0;
1004  pointer-events: none;
1005}
1006fieldset.segmented span {
1007  display: block;
1008  padding: var(--sp-2) var(--sp-4);
1009  border: 1px solid var(--line);
1010  font-size: var(--fs-2);
1011  cursor: pointer;
1012}
1013fieldset.segmented label + label span { border-left: 0; }
1014fieldset.segmented label:first-child span { border-radius: var(--r-sm) 0 0 var(--r-sm); }
1015fieldset.segmented label:last-child span { border-radius: 0 var(--r-sm) var(--r-sm) 0; }
1016fieldset.segmented span:hover { border-color: var(--muted); }
1017fieldset.segmented input:checked + span {
1018  background: var(--fill);
1019  border-color: var(--fill);
1020  color: #ffffff;
1021  font-weight: 600;
1022}
1023fieldset.segmented input:focus-visible + span {
1024  outline: 2px solid var(--accent);
1025  outline-offset: 2px;
1026}
1027
1028/* remaining input states */
1029::placeholder { color: var(--muted); opacity: 1; }
1030::selection { background: var(--fill); color: #ffffff; }
1031/* :user-invalid, not :invalid — a required field is invalid the moment
1032   the page loads, and colouring it red before anyone has typed is a
1033   scolding, not a hint */
1034input:user-invalid, textarea:user-invalid {
1035  border-color: var(--bad);
1036}
1037.hint { display: block; color: var(--muted); font-size: var(--fs-1); margin-top: var(--sp-1); }
1038button {
1039  background: var(--fill);
1040  color: #ffffff;
1041  border: none;
1042  border-radius: var(--r-md);
1043  padding: var(--sp-2) var(--sp-4);
1044  font-weight: 600;
1045  cursor: pointer;
1046}
1047button:hover { filter: brightness(1.15); }
1048
1049/* 404 */
1050.notfound { text-align: center; padding: var(--sp-6) 0; }
1051.notfound .bigcode {
1052  font-family: var(--mono);
1053  font-size: 4rem;
1054  color: var(--faint);
1055  -webkit-text-stroke: 1px var(--line);
1056  margin: 0;
1057  line-height: 1;
1058}
1059.notfound h1 { margin-top: var(--sp-3); }
1060
1061/* footer */
1062footer {
1063  border-top: 1px solid var(--faint);
1064  padding: var(--sp-4) 0;
1065  color: var(--muted);
1066  font-size: var(--fs-1);
1067}
1068footer p { margin: 0; }
1069footer a { color: var(--muted); text-decoration: underline; }
1070footer a:hover { color: var(--accent); }
1071
1072/* search */
1073form.searchform {
1074  display: flex;
1075  gap: var(--sp-2);
1076  margin: var(--sp-3) 0 var(--sp-4);
1077}
1078form.searchform input[type="search"] { flex: 1; max-width: 32rem; }
1079form.searchform.compact { margin: 0; }
1080form.searchform.compact input[type="search"] {
1081  padding: var(--sp-1) var(--sp-3);
1082  font-size: var(--fs-2);
1083  min-width: 18rem;
1084}
1085ul.matchlist { list-style: none; margin: var(--sp-3) 0; padding: 0; }
1086ul.matchlist li { margin-bottom: var(--sp-3); }
1087ul.matchlist .matchpath { font-family: var(--mono); font-size: var(--fs-1); }
1088pre.matchline {
1089  background: var(--code-bg);
1090  border: 1px solid var(--faint);
1091  border-radius: var(--r-md);
1092  padding: var(--sp-1) var(--sp-3);
1093  margin: var(--sp-1) 0 0;
1094  overflow-x: auto;
1095}
1096pre.matchline mark {
1097  background: color-mix(in srgb, var(--warn) 25%, transparent);
1098  color: inherit;
1099  border-radius: 2px;
1100}
1101
1102/* wiki */
1103.wikilayout { display: flex; gap: var(--sp-5); align-items: flex-start; }
1104.wikipage { flex: 1; min-width: 0; }
1105.wikinav { flex: none; width: 13rem; padding-top: var(--sp-4); }
1106.wikinav ul { list-style: none; margin: var(--sp-1) 0 var(--sp-4); padding: 0; }
1107.wikinav li a { display: block; padding: 0.15rem 0; color: var(--fg); }
1108.wikinav li a:hover { color: var(--accent); text-decoration: none; }
1109.wikinav li a.active { color: var(--accent); font-weight: 550; }
1110@media (max-width: 40rem) {
1111  /* Column direction + the desktop align-items:flex-start lets .wikipage
1112     take its content's intrinsic width, overflowing the viewport (and
1113     triggering iOS font inflation). Stretch pins it to the container. */
1114  .wikilayout { flex-direction: column; align-items: stretch; }
1115  .wikinav { width: auto; padding-top: 0; }
1116}
1117
1118/* blame */
1119.blame {
1120  border: 1px solid var(--line);
1121  border-radius: var(--rad-2, 6px);
1122  overflow: hidden;
1123}
1124.blamehunk {
1125  display: flex;
1126  gap: var(--sp-3);
1127  border-top: 1px solid var(--line);
1128  align-items: flex-start;
1129}
1130.blamehunk:first-child { border-top: none; }
1131.blameinfo {
1132  flex: none;
1133  width: 17rem;
1134  padding: var(--sp-2) var(--sp-3);
1135  min-width: 0;
1136}
1137.blameinfo .subject {
1138  margin: 0;
1139  font-size: var(--fs-1);
1140  white-space: nowrap;
1141  overflow: hidden;
1142  text-overflow: ellipsis;
1143}
1144.blameinfo .meta { margin: 0; font-size: var(--fs-1); color: var(--muted); }
1145.blamecode {
1146  flex: 1;
1147  margin: 0;
1148  padding: var(--sp-2) var(--sp-3) var(--sp-2) 0;
1149  overflow-x: auto;
1150  border-left: 1px solid var(--line);
1151  align-self: stretch;
1152}
1153.lineno {
1154  display: inline-block;
1155  min-width: 3.5em;
1156  padding-right: 1em;
1157  text-align: right;
1158  color: var(--muted);
1159  user-select: none;
1160}
1161
1162/* mobile */
1163@media (max-width: 40rem) {
1164  .container { padding-left: var(--sp-4); padding-right: var(--sp-4); }
1165  main.container { padding-top: var(--sp-2); }
1166  .repogrid { grid-template-columns: 1fr; }
1167  .thread { margin-left: var(--sp-3); }
1168  table.tree td.mode, table.tree th.mode { display: none; }
1169  .readme, .code { padding: var(--sp-3); }
1170  .blamehunk { flex-direction: column; gap: 0; }
1171  .blameinfo { width: auto; }
1172  .blamecode { border-left: none; padding-left: var(--sp-3); width: 100%; }
1173  .cardhead {
1174    margin: calc(-1 * var(--sp-3)) calc(-1 * var(--sp-3)) var(--sp-3);
1175    padding: var(--sp-2) var(--sp-3);
1176  }
1177}
1178
1179/* tree listing: the last commit is what a file table is scanned for, so
1180   it leads. The file's own facts moved to the blob page. */
1181.tipbar {
1182  display: flex;
1183  align-items: center;
1184  gap: var(--sp-3);
1185  padding: var(--sp-2) var(--sp-4);
1186  background: var(--hover);
1187  border: 1px solid var(--line);
1188  border-bottom: 0;
1189  border-radius: var(--r-lg) var(--r-lg) 0 0;
1190  font-size: var(--fs-2);
1191}
1192.tipbar .who { font-weight: 600; }
1193.tipbar .subject { color: var(--fg); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1194.tipbar .subject:hover { color: var(--accent); }
1195.tipbar .spacer { flex: 1; }
1196.tipbar .age { color: var(--muted); white-space: nowrap; }
1197.tipbar + table.tree { border-radius: 0 0 var(--r-lg) var(--r-lg); }
1198table.tree th.lastcommit, table.tree td.lastcommit { width: 55%; }
1199table.tree td.lastcommit a { color: var(--muted); display: block; overflow: hidden;
1200                             text-overflow: ellipsis; white-space: nowrap; }
1201table.tree td.lastcommit a:hover { color: var(--accent); }
1202table.tree th.age, table.tree td.age {
1203  text-align: right;
1204  white-space: nowrap;
1205  color: var(--muted);
1206  font-variant-numeric: tabular-nums;
1207}
1208table.tree td.name { width: 25%; white-space: nowrap; }
1209table.tree td.name.dir a { color: var(--accent); }
1210p.clone { margin: 0 0 var(--sp-3); }
1211p.filefacts { color: var(--muted); font-size: var(--fs-1); margin: 0 0 var(--sp-3); }
1212.pathbar .act { font-size: var(--fs-1); }
1213
1214/* merge request: a two-column split, so state has somewhere to live that
1215   is not a run-on sentence under the title */
1216.withaside {
1217  display: grid;
1218  grid-template-columns: minmax(0, 1fr) 15rem;
1219  gap: var(--sp-5);
1220  align-items: start;
1221}
1222.withaside .mainside { min-width: 0; }
1223@media (max-width: 62rem) { .withaside { grid-template-columns: 1fr; } }
1224
1225.aside { font-size: var(--fs-2); }
1226.aside .grp { border-top: 1px solid var(--line); padding: var(--sp-3) 0; }
1227.aside .grp:first-child { border-top: 0; padding-top: 0; }
1228.aside h2 {
1229  margin: 0 0 var(--sp-2);
1230  font-family: var(--mono);
1231  font-size: var(--fs-0);
1232  font-weight: 500;
1233  letter-spacing: 0.1em;
1234  text-transform: uppercase;
1235  color: var(--muted);
1236}
1237.aside .row { display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-1); flex-wrap: wrap; }
1238.aside .row:last-child { margin-bottom: 0; }
1239.aside .none { color: var(--muted); }
1240.aside .dot { width: 0.45rem; height: 0.45rem; flex: none; border-radius: 50%; background: var(--muted); }
1241.aside .dot.ok { background: var(--ok); }
1242.aside .dot.bad { background: var(--bad); }
1243.aside .dot.pend { background: var(--mark); }
1244
1245/* sub-navigation within an item; orange marks position as it does above */
1246nav.subtabs {
1247  display: flex;
1248  gap: var(--sp-4);
1249  border-bottom: 1px solid var(--line);
1250  margin: 0 0 var(--sp-4);
1251}
1252nav.subtabs a {
1253  display: inline-flex;
1254  align-items: center;
1255  gap: var(--sp-2);
1256  padding: 0 0 var(--sp-2);
1257  color: var(--muted);
1258  font-size: var(--fs-2);
1259  border-bottom: 2px solid transparent;
1260  margin-bottom: -1px;
1261}
1262nav.subtabs a:hover { color: var(--fg); text-decoration: none; }
1263nav.subtabs a[aria-current] { color: var(--fg); font-weight: 700; border-bottom-color: var(--mark); }
1264nav.subtabs a i {
1265  font-style: normal;
1266  font-family: var(--mono);
1267  font-size: var(--fs-0);
1268  background: var(--hover);
1269  border-radius: var(--r-sm);
1270  padding: 0 0.35rem;
1271}
1272p.diffstat { color: var(--muted); font-size: var(--fs-2); margin: 0 0 var(--sp-3); }
1273p.diffstat .add { color: var(--ok); }
1274p.diffstat .del { color: var(--bad); }