internal/web/static/style.css

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