internal/web/static/style.css

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

1307 lines · 42665 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/* h1 on the repo home, p elsewhere so each page keeps its own h1 — but
 292   identical in size, because the tabs sit below this and navigation must
 293   not move when you use it */
 294.repotitle {
 295  margin: 0;
 296  font-size: var(--fs-4);
 297  font-weight: 700;
 298  letter-spacing: -0.02em;
 299  line-height: 1.3;
 300}
 301.repotitle a { color: var(--fg); }
 302.repotitle a.owner { color: var(--muted); font-weight: 400; }
 303.repotitle a:hover { color: var(--accent); text-decoration: none; }
 304.repotitle .sep { color: var(--muted); margin: 0 0.12em; font-weight: 400; }
 305.repodesc { margin: var(--sp-2) 0 0; color: var(--muted); font-size: var(--fs-2); max-width: 62ch; }
 306.repometa { margin: var(--sp-1) 0 0; color: var(--muted); font-size: var(--fs-1); }
 307.repohead .topics { margin: var(--sp-2) 0 0; }
 308
 309button.btn {
 310  font: inherit;
 311  font-size: var(--fs-1);
 312  font-weight: 600;
 313  padding: 0.15rem 0.7rem;
 314  border: 1px solid var(--line);
 315  border-radius: var(--r-sm);
 316  background: var(--bg);
 317  color: var(--fg);
 318  cursor: pointer;
 319}
 320button.btn:hover { border-color: var(--accent); color: var(--accent); }
 321button.btn[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }
 322form.inline { display: inline; }
 323
 324nav.tabs {
 325  display: flex;
 326  gap: var(--sp-1);
 327  margin-top: var(--sp-4);
 328  overflow-x: auto;
 329  scrollbar-width: none;
 330}
 331nav.tabs::-webkit-scrollbar { display: none; }
 332nav.tabs a {
 333  display: inline-flex;
 334  align-items: center;
 335  gap: var(--sp-2);
 336  padding: var(--sp-2) var(--sp-3) 0.6rem;
 337  color: var(--muted);
 338  font-size: var(--fs-2);
 339  white-space: nowrap;
 340  border-bottom: 2px solid transparent;
 341  margin-bottom: -1px;
 342}
 343nav.tabs a:hover { color: var(--fg); text-decoration: none; }
 344/* orange marks position here too */
 345nav.tabs a[aria-current] {
 346  color: var(--fg);
 347  font-weight: 700;
 348  border-bottom-color: var(--mark);
 349}
 350nav.tabs a i {
 351  font-style: normal;
 352  font-family: var(--mono);
 353  font-size: var(--fs-0);
 354  background: var(--hover);
 355  border-radius: var(--r-sm);
 356  padding: 0 0.35rem;
 357}
 358
 359/* ---- mobile: the rail becomes a single strip, not a wall of links ---- */
 360@media (max-width: 52rem) {
 361  .shell { display: block; }
 362  .rail {
 363    width: auto;
 364    height: auto;
 365    position: static;
 366    flex-direction: row;
 367    align-items: center;
 368    gap: var(--sp-2);
 369    border-right: 0;
 370    border-bottom: 1px solid var(--shell-line);
 371    overflow-x: auto;
 372  }
 373  a.brand { border-bottom: 0; padding-right: var(--sp-2); }
 374  .railbody { flex: 1; overflow: visible; padding: 0; display: flex; align-items: center; }
 375  /* pinned repos and the review queue both live on the dashboard, so the
 376     strip keeps only what has nowhere else to go */
 377  .railgroup { display: none; }
 378  ul.raillist { display: flex; }
 379  ul.raillist a { border-left: 0; border-bottom: 2px solid transparent; padding: var(--sp-2) var(--sp-3); }
 380  ul.raillist a[aria-current] { border-left: 0; border-bottom-color: var(--shell-mark); }
 381  .railfoot { border-top: 0; padding-left: var(--sp-2); }
 382  .content { padding: var(--sp-4) var(--sp-4) var(--sp-5); }
 383  .repohead { padding: var(--sp-3) var(--sp-4) 0; }
 384}
 385
 386/* tables */
 387table { border-collapse: collapse; width: 100%; }
 388td {
 389  padding: var(--sp-2) var(--sp-4) var(--sp-2) 0;
 390  border-bottom: 1px solid var(--faint);
 391  vertical-align: top;
 392  font-size: var(--fs-2);
 393}
 394td:last-child { padding-right: 0; }
 395td.size, td.mode { color: var(--muted); white-space: nowrap; }
 396
 397/* path bar on tree and blob pages */
 398.pathbar {
 399  display: flex;
 400  flex-wrap: wrap;
 401  align-items: center;
 402  gap: var(--sp-2) var(--sp-3);
 403  margin: var(--sp-3) 0;
 404  font-size: var(--fs-2);
 405}
 406.pathbar .spacer { flex: 1; }
 407.refchip {
 408  display: inline-flex;
 409  align-items: center;
 410  gap: 0.3rem;
 411  background: var(--surface);
 412  border: 1px solid var(--faint);
 413  border-radius: var(--r-md);
 414  padding: 0.1rem 0.55rem;
 415  font-family: var(--mono);
 416  font-size: var(--fs-1);
 417  color: var(--fg);
 418}
 419.pathbar .crumbs strong { color: var(--fg); }
 420details.refmenu { position: relative; }
 421details.refmenu summary { cursor: pointer; list-style: none; }
 422details.refmenu summary::-webkit-details-marker { display: none; }
 423details.refmenu summary::after { content: " ▾"; color: var(--muted); }
 424details.refmenu .refdrop {
 425  position: absolute;
 426  z-index: 10;
 427  top: calc(100% + 4px);
 428  left: 0;
 429  min-width: 12rem;
 430  max-height: 20rem;
 431  overflow-y: auto;
 432  background: var(--bg);
 433  border: 1px solid var(--line);
 434  border-radius: var(--r-md);
 435  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
 436  padding: var(--sp-1) 0;
 437}
 438details.refmenu .refdrop a {
 439  display: block;
 440  padding: var(--sp-1) var(--sp-3);
 441  color: var(--fg);
 442  font-family: var(--mono);
 443  font-size: var(--fs-1);
 444}
 445details.refmenu .refdrop a:hover { background: var(--hover); text-decoration: none; }
 446details.refmenu .refdrop a.allrefs { color: var(--accent); font-family: var(--sans); border-top: 1px solid var(--faint); margin-top: var(--sp-1); }
 447
 448/* file and refs tables: bordered cards, rows inside */
 449/* wide listings scroll inside their own box; the page never does */
 450.tablewrap { overflow-x: auto; max-width: 100%; }
 451
 452table.tree, table.refs {
 453  background: var(--surface);
 454  border: 1px solid var(--line);
 455  border-radius: var(--r-lg);
 456  border-collapse: separate;
 457  border-spacing: 0;
 458  overflow: hidden;
 459  margin-bottom: var(--sp-4);
 460}
 461table.tree td, table.refs td {
 462  padding: var(--sp-2) var(--sp-4);
 463  border-bottom: 1px solid var(--faint);
 464}
 465table.tree tr:last-child td, table.refs tr:last-child td { border-bottom: none; }
 466table.tree tr:hover td, table.refs tr:hover td { background: var(--hover); }
 467table.tree tr.cols th {
 468  text-align: left;
 469  font-weight: 500;
 470  font-size: var(--fs-1);
 471  color: var(--muted);
 472  padding: var(--sp-1) var(--sp-4);
 473  border-bottom: 1px solid var(--line);
 474  background: var(--bg);
 475}
 476table.tree tr.cols:hover th { background: var(--bg); }
 477table.tree th.size { text-align: right; }
 478table.tree td.name { width: 100%; }
 479table.tree td.name a { color: var(--fg); }
 480table.tree td.name a:hover { color: var(--accent); }
 481table.tree td.size { text-align: right; }
 482table.tree td.empty, table.refs td.empty, li.empty, ul.loglist li.empty { color: var(--muted); }
 483
 484/* refs page */
 485table.refs td.name { width: 100%; }
 486table.refs td.sha { color: var(--muted); }
 487
 488/* card header (README) */
 489.cardhead {
 490  font-family: var(--mono);
 491  font-size: var(--fs-1);
 492  color: var(--muted);
 493  border-bottom: 1px solid var(--faint);
 494  margin: calc(-1 * var(--sp-4)) calc(-1 * var(--sp-5)) var(--sp-4);
 495  padding: var(--sp-2) var(--sp-5);
 496  background: var(--bg);
 497  border-radius: var(--r-lg) var(--r-lg) 0 0;
 498}
 499
 500/* log */
 501ul.loglist {
 502  list-style: none;
 503  margin: var(--sp-3) 0;
 504  padding: 0;
 505  background: var(--surface);
 506  border: 1px solid var(--line);
 507  border-radius: var(--r-lg);
 508  overflow: hidden;
 509}
 510ul.loglist li {
 511  display: flex;
 512  align-items: baseline;
 513  gap: var(--sp-3);
 514  padding: var(--sp-2) var(--sp-4);
 515  border-bottom: 1px solid var(--faint);
 516}
 517ul.loglist li:last-child { border-bottom: none; }
 518ul.loglist li:hover { background: var(--hover); }
 519ul.loglist .commitmain { flex: 1; min-width: 0; }
 520ul.loglist p { margin: 0; }
 521ul.loglist .subject a { color: var(--fg); font-weight: 550; }
 522ul.loglist .subject a:hover { color: var(--accent); }
 523ul.loglist .commitside {
 524  display: flex;
 525  align-items: baseline;
 526  gap: var(--sp-2);
 527  white-space: nowrap;
 528}
 529p.pager { margin-top: var(--sp-4); }
 530
 531/* commit page */
 532.commithead p { margin: var(--sp-1) 0; }
 533.commithead h2 { margin-bottom: var(--sp-1); }
 534code.fullsha { color: var(--muted); overflow-wrap: anywhere; }
 535.empty-note { color: var(--muted); }
 536.crumbs { color: var(--muted); font-size: var(--fs-2); }
 537.desc, td.desc { color: var(--muted); }
 538.error {
 539  color: var(--fg);
 540  border: 1px solid var(--bad);
 541  border-left-width: 3px;
 542  border-radius: var(--r-sm);
 543  padding: var(--sp-2) var(--sp-3);
 544  margin-bottom: var(--sp-4);
 545}
 546/* branch picker on the new merge request form */
 547p.branchpick {
 548  display: flex;
 549  flex-wrap: wrap;
 550  align-items: center;
 551  gap: var(--sp-2);
 552}
 553p.branchpick label { color: var(--muted); font-size: var(--fs-2); }
 554p.branchpick select { flex: 1 1 12rem; }
 555
 556/* merge request actions in the aside: stacked controls, full width */
 557.aside form.actions {
 558  display: flex;
 559  flex-wrap: wrap;
 560  gap: var(--sp-2);
 561  margin-top: var(--sp-2);
 562}
 563.aside form.actions button { flex: 1 1 auto; }
 564.aside form.actions select { width: 100%; }
 565form.threadact { margin: var(--sp-1) 0 0; padding: 0 var(--sp-3) var(--sp-2); }
 566
 567.meta { color: var(--muted); font-size: var(--fs-1); }
 568svg.icon { vertical-align: -0.125em; }
 569.lede { font-size: var(--fs-3); margin: var(--sp-2) 0; }
 570
 571/* repo listings (explore, owner pages, dashboard): one row per repo */
 572ul.repolist {
 573  list-style: none;
 574  margin: var(--sp-3) 0 var(--sp-5);
 575  padding: 0;
 576  background: var(--surface);
 577  border: 1px solid var(--line);
 578  border-radius: var(--r-lg);
 579  overflow: hidden;
 580}
 581ul.repolist li { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--faint); }
 582/* pinned repos: a compact wrap of name pills, no description or meta */
 583ul.pinlist {
 584  list-style: none;
 585  margin: var(--sp-3) 0 var(--sp-5);
 586  padding: 0;
 587  display: flex;
 588  flex-wrap: wrap;
 589  gap: var(--sp-2);
 590}
 591ul.pinlist li {
 592  background: var(--surface);
 593  border: 1px solid var(--line);
 594  border-radius: var(--r-md);
 595  padding: var(--sp-1) var(--sp-3);
 596}
 597ul.pinlist li:hover { background: var(--hover); }
 598ul.pinlist li a { color: var(--fg); }
 599ul.pinlist li a:hover { color: var(--accent); text-decoration: none; }
 600ul.pinlist .sep { color: var(--muted); margin: 0 0.15em; }
 601ul.repolist li:last-child { border-bottom: none; }
 602ul.repolist li:hover { background: var(--hover); }
 603ul.repolist li.empty { color: var(--muted); }
 604ul.repolist p { margin: 0; }
 605ul.repolist .reponame { font-size: var(--fs-3); }
 606ul.repolist .reponame a { color: var(--fg); }
 607ul.repolist .reponame a strong { color: var(--accent); font-weight: 600; }
 608ul.repolist .reponame .sep { color: var(--muted); margin: 0 0.1em; }
 609ul.repolist .desc { margin-top: 0.1rem; }
 610ul.repolist .topics { margin-top: var(--sp-1); }
 611ul.repolist .meta { margin-top: var(--sp-1); }
 612
 613/* owner profile header */
 614.profilehead {
 615  border-bottom: 1px solid var(--faint);
 616  padding-bottom: var(--sp-4);
 617  margin-bottom: var(--sp-4);
 618}
 619.profilehead h1 { margin: var(--sp-4) 0 var(--sp-1); }
 620.profilehead .lede { margin: 0 0 var(--sp-1); }
 621.profilehead .meta { margin: var(--sp-1) 0 0; }
 622h2 .count { color: var(--muted); font-weight: 400; font-size: var(--fs-2); }
 623
 624/* activity graph: 53 week columns x 7 day rows, accent-tinted levels */
 625.actgraph-scroll { overflow-x: auto; padding-bottom: var(--sp-1); }
 626.actgraph { display: flex; gap: 3px; width: max-content; }
 627.actweek { display: flex; flex-direction: column; gap: 3px; }
 628.actday {
 629  width: 11px;
 630  height: 11px;
 631  border-radius: 2px;
 632  background: var(--faint);
 633}
 634.actday.pad { background: transparent; }
 635.actday.l1 { background: color-mix(in srgb, var(--accent) 25%, var(--bg)); }
 636.actday.l2 { background: color-mix(in srgb, var(--accent) 50%, var(--bg)); }
 637.actday.l3 { background: color-mix(in srgb, var(--accent) 75%, var(--bg)); }
 638.actday.l4 { background: var(--accent); }
 639
 640/* heading row with actions on the right */
 641.headrow {
 642  display: flex;
 643  align-items: baseline;
 644  gap: var(--sp-4);
 645  flex-wrap: wrap;
 646}
 647.headrow .spacer { flex: 1; }
 648
 649/* member and org chips on owner pages */
 650a.memberchip {
 651  display: inline-block;
 652  border: 1px solid var(--line);
 653  border-radius: var(--r-pill);
 654  padding: 0.05rem 0.6rem;
 655  color: var(--fg);
 656  font-size: var(--fs-1);
 657  margin: 0 0.15rem 0.15rem 0;
 658}
 659a.memberchip:hover { text-decoration: none; border-color: var(--accent); color: var(--accent); }
 660a.memberchip .role { color: var(--muted); }
 661
 662/* landing page */
 663.landing { max-width: 44rem; padding: var(--sp-6) 0; }
 664.landing h1 { font-size: 1.8rem; margin-bottom: var(--sp-3); }
 665.landing .lede { font-size: var(--fs-4); color: var(--muted); line-height: 1.7; margin: 0 0 var(--sp-4); }
 666pre.quickstart {
 667  background: var(--code-bg);
 668  border: 1px solid var(--line);
 669  border-radius: var(--r-md);
 670  padding: var(--sp-3) var(--sp-4);
 671  overflow-x: auto;
 672  margin: 0 0 var(--sp-4);
 673}
 674.landing .explorelink { font-weight: 550; }
 675
 676/* index toolbar */
 677p.toolbar { color: var(--muted); font-size: var(--fs-2); margin-top: var(--sp-4); }
 678form.inline { display: inline; }
 679button.linklike {
 680  background: none;
 681  border: none;
 682  color: var(--accent);
 683  padding: 0;
 684  font: inherit;
 685  font-size: var(--fs-2);
 686  cursor: pointer;
 687}
 688button.linklike:hover { text-decoration: underline; filter: none; }
 689
 690/* cards: README, comments */
 691.readme, .code {
 692  background: var(--surface);
 693  border: 1px solid var(--line);
 694  border-radius: var(--r-lg);
 695  padding: var(--sp-4) var(--sp-5);
 696  margin-top: var(--sp-4);
 697  overflow-x: auto;
 698}
 699/* Highlighting is class-based with a palette per scheme, so code blocks
 700   follow the site's own colors. */
 701.code { background: var(--code-bg); color: var(--fg); padding: var(--sp-3) var(--sp-4); border-color: var(--line); }
 702.code pre { margin: 0; background: transparent !important; }
 703@media (prefers-color-scheme: dark) {
 704  .code { border-color: var(--line); }
 705}
 706
 707/* rendered markdown / org / html */
 708.rendered { max-width: 100%; overflow-wrap: anywhere; }
 709.rendered pre {
 710  background: var(--code-bg);
 711  border: 1px solid var(--line);
 712  padding: var(--sp-3) var(--sp-4);
 713  border-radius: var(--r-md);
 714  overflow-x: auto;
 715}
 716.rendered code {
 717  background: var(--code-bg);
 718  border: 1px solid var(--line);
 719  padding: 0.05rem 0.3rem;
 720  border-radius: var(--r-sm);
 721}
 722.rendered pre code { background: transparent; border: none; padding: 0; }
 723.rendered blockquote {
 724  border-left: 3px solid var(--line);
 725  margin-left: 0;
 726  padding-left: var(--sp-4);
 727  color: var(--muted);
 728}
 729.rendered img { max-width: 100%; }
 730.rendered h1, .rendered h2 { border-bottom: 1px solid var(--faint); padding-bottom: var(--sp-1); }
 731.rendered table {
 732  border-collapse: collapse;
 733  margin: var(--sp-3) 0;
 734  display: block;
 735  max-width: 100%;
 736  overflow-x: auto;
 737}
 738.rendered th, .rendered td {
 739  border: 1px solid var(--line);
 740  padding: var(--sp-1) var(--sp-3);
 741  text-align: left;
 742  overflow-wrap: normal; /* scroll the table, don't shatter words */
 743}
 744.rendered th { background: var(--surface); font-weight: 600; }
 745.blobimage { text-align: center; }
 746.blobimage img {
 747  max-width: 100%;
 748  border: 1px solid var(--faint);
 749  border-radius: var(--r-md);
 750  background: var(--surface);
 751}
 752
 753pre.message {
 754  background: var(--code-bg);
 755  border: 1px solid var(--line);
 756  padding: var(--sp-3) var(--sp-4);
 757  border-radius: var(--r-md);
 758  white-space: pre-wrap;
 759  overflow-wrap: anywhere;
 760}
 761
 762/* diffs */
 763details.difffold summary {
 764  cursor: pointer;
 765  display: flex;
 766  align-items: baseline;
 767  gap: var(--sp-3);
 768  margin: var(--sp-5) 0 var(--sp-2);
 769  list-style: none;
 770}
 771details.difffold summary::-webkit-details-marker { display: none; }
 772/* flex summaries lose the native disclosure marker; draw our own */
 773details.difffold summary::before { content: "▸"; color: var(--muted); }
 774details.difffold[open] summary::before { content: "▾"; }
 775details.difffold summary h3 { display: inline; margin: 0; }
 776details.difffold summary .add { color: var(--ok); }
 777details.difffold summary .del { color: var(--bad); }
 778pre.diff {
 779  background: var(--code-bg);
 780  border: 1px solid var(--line);
 781  padding: var(--sp-3) var(--sp-4);
 782  border-radius: var(--r-md);
 783  overflow-x: auto;
 784  line-height: 1.5;
 785}
 786pre.diff .add { color: var(--ok); }
 787pre.diff .del { color: var(--bad); }
 788pre.diff .hunk { color: var(--accent); }
 789pre.diff .meta { color: var(--muted); }
 790
 791/* badges: signature and check states. Semantic colors stay distinct:
 792   green verified/success, amber pending/stale, red bad/failure, muted
 793   unsigned. */
 794.badge, .chip {
 795  --chip: var(--neutral);
 796  display: inline-block;
 797  padding: 0.05rem 0.55rem;
 798  border-radius: var(--r-pill);
 799  font-size: var(--fs-0);
 800  font-weight: 500;
 801  line-height: 1.5;
 802  color: var(--chip);
 803  border: 1px solid color-mix(in srgb, var(--chip) 35%, transparent);
 804  background: color-mix(in srgb, var(--chip) 7%, transparent);
 805  white-space: nowrap;
 806  vertical-align: middle;
 807}
 808.chip-open { --chip: var(--ok); }
 809.chip-closed { --chip: var(--bad); }
 810.chip-merged, .chip-done { --chip: var(--done); }
 811.chip-neutral, .chip-source_gone { --chip: var(--neutral); }
 812.chip-stale { --chip: var(--warn); }
 813.chip.label { font-weight: 500; }
 814.chip.topic { --chip: var(--accent); }
 815.repohead .topics { margin: 0 0 var(--sp-2); }
 816.repohead .mirrorline { margin: 0 0 var(--sp-2); }
 817.mirrorerr { color: var(--bad); }
 818.badge-verified { --chip: var(--ok); }
 819.badge-unsigned { --chip: var(--neutral); }
 820.badge-signed_unknown_key { --chip: var(--warn); }
 821.badge-signed_email_mismatch { --chip: var(--bad); }
 822.badge-signed_key_expired { --chip: var(--warn); }
 823.badge-signed_key_revoked { --chip: var(--bad); }
 824.badge-bad_signature { --chip: var(--bad); }
 825.badge.check-success { --chip: var(--ok); }
 826.badge.check-pending { --chip: var(--warn); }
 827.badge.check-failure, .badge.check-error { --chip: var(--bad); }
 828.badge.check-running, .chip.check-running { --chip: var(--warn); }
 829.chip.check-success { --chip: var(--ok); }
 830.chip.check-pending { --chip: var(--warn); }
 831.chip.check-failure { --chip: var(--bad); }
 832pre.buildlog { max-height: 40rem; overflow: auto; }
 833span.check-success { color: var(--ok); }
 834span.check-pending { color: var(--warn); }
 835span.check-failure, span.check-error { color: var(--bad); }
 836
 837/* issue and MR listings */
 838.listhead {
 839  display: flex;
 840  align-items: baseline;
 841  gap: var(--sp-4);
 842  flex-wrap: wrap;
 843}
 844.listhead h2 { margin-bottom: var(--sp-2); }
 845nav.filters { display: flex; gap: var(--sp-1); }
 846nav.filters a {
 847  color: var(--muted);
 848  font-size: var(--fs-2);
 849  padding: 0.05rem var(--sp-2);
 850  border-radius: var(--r-pill);
 851}
 852nav.filters a:hover { color: var(--fg); background: var(--hover); text-decoration: none; }
 853nav.filters a.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
 854
 855ul.issuelist {
 856  list-style: none;
 857  margin: var(--sp-2) 0;
 858  padding: 0;
 859  background: var(--surface);
 860  border: 1px solid var(--line);
 861  border-radius: var(--r-lg);
 862  overflow: hidden;
 863}
 864ul.issuelist li {
 865  display: flex;
 866  align-items: baseline;
 867  gap: var(--sp-3);
 868  padding: var(--sp-3) var(--sp-4);
 869  border-bottom: 1px solid var(--faint);
 870}
 871ul.issuelist li:last-child { border-bottom: none; }
 872ul.issuelist li:hover { background: var(--hover); }
 873ul.issuelist li.empty { display: block; color: var(--muted); }
 874ul.issuelist .issuemain { flex: 1; min-width: 0; }
 875ul.issuelist p { margin: 0; }
 876ul.issuelist .title a { color: var(--fg); font-weight: 550; }
 877ul.issuelist .title a:hover { color: var(--accent); }
 878
 879/* releases */
 880article.release {
 881  background: var(--surface);
 882  border: 1px solid var(--line);
 883  border-radius: var(--r-lg);
 884  padding: var(--sp-3) var(--sp-4);
 885  margin: var(--sp-4) 0;
 886}
 887.releasehead { background: none; border: 0; padding: 0; }
 888.releasehead h3 { margin: 0 0 var(--sp-1); }
 889.releasehead .meta { margin: 0 0 var(--sp-2); }
 890table.assets { margin-top: var(--sp-2); }
 891table.assets td.size { color: var(--muted); white-space: nowrap; text-align: right; }
 892table.assets td.name { width: 100%; font-family: var(--mono); font-size: var(--fs-1); }
 893
 894/* milestones */
 895ul.milestonelist {
 896  list-style: none;
 897  margin: var(--sp-2) 0;
 898  padding: 0;
 899  border: 1px solid var(--line);
 900  border-radius: var(--r-lg);
 901  overflow: hidden;
 902}
 903ul.milestonelist li { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--faint); }
 904ul.milestonelist li:last-child { border-bottom: none; }
 905ul.milestonelist li.empty { color: var(--muted); }
 906ul.milestonelist p { margin: 0; }
 907ul.milestonelist .title { font-weight: 550; }
 908.progress {
 909  height: 6px;
 910  background: var(--faint);
 911  border-radius: var(--r-pill);
 912  margin-top: var(--sp-2);
 913  overflow: hidden;
 914  max-width: 24rem;
 915}
 916.progress .bar { height: 100%; background: var(--ok); }
 917.listhead .spacer { flex: 1; }
 918
 919/* issue / MR detail */
 920h2.issuetitle { margin-bottom: var(--sp-1); font-size: var(--fs-5); }
 921.issuenumber { color: var(--muted); font-weight: 400; }
 922.issuemeta { color: var(--muted); font-size: var(--fs-2); margin-top: 0; }
 923.review { font-size: var(--fs-2); }
 924
 925/* comment cards; discussion stays at a readable measure */
 926article.comment, form.commentform {
 927  max-width: 48rem;
 928}
 929article.comment {
 930  border: 1px solid var(--faint);
 931  border-radius: var(--r-lg);
 932  margin: var(--sp-4) 0;
 933}
 934article.comment .commenthead {
 935  background: var(--surface);
 936  border-bottom: 1px solid var(--faint);
 937  border-radius: var(--r-lg) var(--r-lg) 0 0;
 938  padding: var(--sp-2) var(--sp-4);
 939  font-size: var(--fs-2);
 940}
 941article.comment .commenthead .when { color: var(--muted); }
 942article.comment .rendered { padding: 0 var(--sp-4); }
 943article.comment .rendered > :first-child { margin-top: var(--sp-3); }
 944article.comment .rendered > :last-child { margin-bottom: var(--sp-3); }
 945form.commentform { margin: var(--sp-4) 0; }
 946details.editbox { margin: var(--sp-2) 0; max-width: 48rem; }
 947details.editbox summary { cursor: pointer; color: var(--muted); font-size: var(--fs-2); }
 948details.editbox summary:hover { color: var(--accent); }
 949details.editbox input[type="text"] { width: 100%; }
 950.syscomment {
 951  max-width: 48rem;
 952  color: var(--muted);
 953  font-size: var(--fs-2);
 954  margin: var(--sp-3) 0;
 955  padding-left: var(--sp-4);
 956  border-left: 3px solid var(--faint);
 957}
 958.syscomment p { display: inline; margin: 0; }
 959
 960/* review threads under diff lines */
 961.thread {
 962  border: 1px solid var(--faint);
 963  border-left: 3px solid var(--accent);
 964  border-radius: var(--r-md);
 965  padding: var(--sp-2) var(--sp-4);
 966  margin: var(--sp-2) 0 var(--sp-2) var(--sp-6);
 967}
 968.thread.resolved { border-left-color: var(--ok); opacity: 0.75; }
 969.thread.stale { border-left-color: var(--warn); }
 970.thread p.commenthead { font-size: var(--fs-2); margin: var(--sp-2) 0 0; }
 971.thread .when { color: var(--muted); }
 972.thread .rendered p { margin: var(--sp-1) 0; }
 973.thread .threadstate { color: var(--muted); font-size: var(--fs-1); margin: var(--sp-1) 0 0; }
 974
 975/* forms: every control shares one shell, so a select reads as a sibling
 976   of the text inputs beside it rather than as an OS control dropped in */
 977input, textarea, button, select { font: inherit; color: inherit; }
 978input[type="text"], input[type="search"], input[type="email"],
 979input[type="password"], input:not([type]), textarea, select {
 980  background: var(--bg);
 981  color: var(--fg);
 982  border: 1px solid var(--line);
 983  border-radius: var(--r-md);
 984  padding: var(--sp-2) var(--sp-3);
 985  line-height: 1.4;
 986}
 987textarea { width: 100%; resize: vertical; }
 988textarea[name="content"] { font-family: var(--mono); font-size: var(--fs-1); }
 989/* the native arrow cannot be restyled, so draw our own and match the
 990   inputs exactly; --chev carries the stroke colour per scheme */
 991select {
 992  appearance: none;
 993  padding-right: 1.9rem;
 994  background-image: var(--chev);
 995  background-repeat: no-repeat;
 996  background-position: right 0.6rem center;
 997  background-size: 0.62rem;
 998  cursor: pointer;
 999}
1000input:hover, textarea:hover, select:hover { border-color: var(--muted); }
1001/* the global :focus-visible ring covers these; only the border moves */
1002input:focus, textarea:focus, select:focus { border-color: var(--accent); }
1003input[type="radio"], input[type="checkbox"] { accent-color: var(--fill); }
1004label:has(> input[type="radio"]), label:has(> input[type="checkbox"]),
1005label:has(> select) { display: inline-flex; align-items: center; gap: var(--sp-2); }
1006
1007/* Shape carries the meaning on these two and nothing else does: a circle
1008   takes one answer, a square takes any number. It survives colour being
1009   removed — greyscale, high contrast, colour blindness — so the native
1010   shapes stay and only the colour joins the system. Drawing them by hand
1011   would align the corners at the cost of the one cue that always works. */
1012input[type="radio"], input[type="checkbox"] { accent-color: var(--fill); }
1013
1014/* a segmented control for a small, mutually exclusive set: real radios
1015   underneath, so arrow keys and screen readers behave as they always did */
1016fieldset.segmented { border: 0; margin: 0 0 var(--sp-4); padding: 0; }
1017fieldset.segmented legend {
1018  padding: 0;
1019  margin-bottom: var(--sp-2);
1020  color: var(--muted);
1021  font-size: var(--fs-2);
1022}
1023fieldset.segmented .options { display: inline-flex; }
1024fieldset.segmented label { gap: 0; }
1025fieldset.segmented input {
1026  position: absolute;
1027  width: 1px;
1028  height: 1px;
1029  opacity: 0;
1030  pointer-events: none;
1031}
1032fieldset.segmented span {
1033  display: block;
1034  padding: var(--sp-2) var(--sp-4);
1035  border: 1px solid var(--line);
1036  font-size: var(--fs-2);
1037  cursor: pointer;
1038}
1039fieldset.segmented label + label span { border-left: 0; }
1040fieldset.segmented label:first-child span { border-radius: var(--r-sm) 0 0 var(--r-sm); }
1041fieldset.segmented label:last-child span { border-radius: 0 var(--r-sm) var(--r-sm) 0; }
1042fieldset.segmented span:hover { border-color: var(--muted); }
1043fieldset.segmented input:checked + span {
1044  background: var(--fill);
1045  border-color: var(--fill);
1046  color: #ffffff;
1047  font-weight: 600;
1048}
1049fieldset.segmented input:focus-visible + span {
1050  outline: 2px solid var(--accent);
1051  outline-offset: 2px;
1052}
1053
1054/* remaining input states */
1055::placeholder { color: var(--muted); opacity: 1; }
1056::selection { background: var(--fill); color: #ffffff; }
1057/* :user-invalid, not :invalid — a required field is invalid the moment
1058   the page loads, and colouring it red before anyone has typed is a
1059   scolding, not a hint */
1060input:user-invalid, textarea:user-invalid {
1061  border-color: var(--bad);
1062}
1063.hint { display: block; color: var(--muted); font-size: var(--fs-1); margin-top: var(--sp-1); }
1064button {
1065  background: var(--fill);
1066  color: #ffffff;
1067  border: none;
1068  border-radius: var(--r-md);
1069  padding: var(--sp-2) var(--sp-4);
1070  font-weight: 600;
1071  cursor: pointer;
1072}
1073button:hover { filter: brightness(1.15); }
1074
1075/* 404 */
1076.notfound { text-align: center; padding: var(--sp-6) 0; }
1077.notfound .bigcode {
1078  font-family: var(--mono);
1079  font-size: 4rem;
1080  color: var(--faint);
1081  -webkit-text-stroke: 1px var(--line);
1082  margin: 0;
1083  line-height: 1;
1084}
1085.notfound h1 { margin-top: var(--sp-3); }
1086
1087/* footer */
1088footer {
1089  border-top: 1px solid var(--faint);
1090  padding: var(--sp-4) var(--sp-5) var(--sp-5);
1091  max-width: 78rem;
1092  width: 100%;
1093  color: var(--muted);
1094  font-size: var(--fs-1);
1095}
1096footer p { margin: 0; }
1097footer a { color: var(--muted); text-decoration: underline; }
1098footer a:hover { color: var(--accent); }
1099
1100/* search */
1101form.searchform {
1102  display: flex;
1103  gap: var(--sp-2);
1104  margin: var(--sp-3) 0 var(--sp-4);
1105}
1106form.searchform input[type="search"] { flex: 1; max-width: 32rem; }
1107form.searchform.compact { margin: 0; }
1108form.searchform.compact input[type="search"] {
1109  padding: var(--sp-1) var(--sp-3);
1110  font-size: var(--fs-2);
1111  min-width: 18rem;
1112}
1113ul.matchlist { list-style: none; margin: var(--sp-3) 0; padding: 0; }
1114ul.matchlist li { margin-bottom: var(--sp-3); }
1115ul.matchlist .matchpath { font-family: var(--mono); font-size: var(--fs-1); }
1116pre.matchline {
1117  background: var(--code-bg);
1118  border: 1px solid var(--faint);
1119  border-radius: var(--r-md);
1120  padding: var(--sp-1) var(--sp-3);
1121  margin: var(--sp-1) 0 0;
1122  overflow-x: auto;
1123}
1124pre.matchline mark {
1125  background: color-mix(in srgb, var(--warn) 25%, transparent);
1126  color: inherit;
1127  border-radius: 2px;
1128}
1129
1130/* wiki */
1131.wikilayout { display: flex; gap: var(--sp-5); align-items: flex-start; }
1132.wikipage { flex: 1; min-width: 0; }
1133.wikinav { flex: none; width: 13rem; padding-top: var(--sp-4); }
1134.wikinav ul { list-style: none; margin: var(--sp-1) 0 var(--sp-4); padding: 0; }
1135.wikinav li a { display: block; padding: 0.15rem 0; color: var(--fg); }
1136.wikinav li a:hover { color: var(--accent); text-decoration: none; }
1137.wikinav li a.active { color: var(--accent); font-weight: 550; }
1138@media (max-width: 40rem) {
1139  /* Column direction + the desktop align-items:flex-start lets .wikipage
1140     take its content's intrinsic width, overflowing the viewport (and
1141     triggering iOS font inflation). Stretch pins it to the container. */
1142  .wikilayout { flex-direction: column; align-items: stretch; }
1143  .wikinav { width: auto; padding-top: 0; }
1144}
1145
1146/* blame */
1147.blame {
1148  border: 1px solid var(--line);
1149  border-radius: var(--rad-2, 6px);
1150  overflow: hidden;
1151}
1152.blamehunk {
1153  display: flex;
1154  gap: var(--sp-3);
1155  border-top: 1px solid var(--line);
1156  align-items: flex-start;
1157}
1158.blamehunk:first-child { border-top: none; }
1159.blameinfo {
1160  flex: none;
1161  width: 17rem;
1162  padding: var(--sp-2) var(--sp-3);
1163  min-width: 0;
1164}
1165.blameinfo .subject {
1166  margin: 0;
1167  font-size: var(--fs-1);
1168  white-space: nowrap;
1169  overflow: hidden;
1170  text-overflow: ellipsis;
1171}
1172.blameinfo .meta { margin: 0; font-size: var(--fs-1); color: var(--muted); }
1173.blamecode {
1174  flex: 1;
1175  margin: 0;
1176  padding: var(--sp-2) var(--sp-3) var(--sp-2) 0;
1177  overflow-x: auto;
1178  border-left: 1px solid var(--line);
1179  align-self: stretch;
1180}
1181.lineno {
1182  display: inline-block;
1183  min-width: 3.5em;
1184  padding-right: 1em;
1185  text-align: right;
1186  color: var(--muted);
1187  user-select: none;
1188}
1189
1190/* mobile */
1191@media (max-width: 40rem) {
1192  .container { padding-left: var(--sp-4); padding-right: var(--sp-4); }
1193  main.container { padding-top: var(--sp-2); }
1194  .repogrid { grid-template-columns: 1fr; }
1195  .thread { margin-left: var(--sp-3); }
1196  /* the commit subject is the widest thing in the listing and the one
1197     column a phone can do without: the tipbar above already names the
1198     latest commit. */
1199  table.tree td.lastcommit, table.tree th.lastcommit { display: none; }
1200  table.tree td.mode, table.tree th.mode { display: none; }
1201  .clone, .pathbar { overflow-wrap: anywhere; }
1202  .readme, .code { padding: var(--sp-3); }
1203  .blamehunk { flex-direction: column; gap: 0; }
1204  .blameinfo { width: auto; }
1205  .blamecode { border-left: none; padding-left: var(--sp-3); width: 100%; }
1206  .cardhead {
1207    margin: calc(-1 * var(--sp-3)) calc(-1 * var(--sp-3)) var(--sp-3);
1208    padding: var(--sp-2) var(--sp-3);
1209  }
1210}
1211
1212/* tree listing: the last commit is what a file table is scanned for, so
1213   it leads. The file's own facts moved to the blob page. */
1214.tipbar {
1215  display: flex;
1216  align-items: center;
1217  gap: var(--sp-3);
1218  padding: var(--sp-2) var(--sp-4);
1219  background: var(--hover);
1220  border: 1px solid var(--line);
1221  border-bottom: 0;
1222  border-radius: var(--r-lg) var(--r-lg) 0 0;
1223  font-size: var(--fs-2);
1224}
1225.tipbar .who { font-weight: 600; }
1226.tipbar .subject { color: var(--fg); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1227.tipbar .subject:hover { color: var(--accent); }
1228.tipbar .spacer { flex: 1; }
1229.tipbar .age { color: var(--muted); white-space: nowrap; }
1230.tipbar + table.tree { border-radius: 0 0 var(--r-lg) var(--r-lg); }
1231table.tree th.lastcommit, table.tree td.lastcommit { width: 55%; }
1232table.tree td.lastcommit a { color: var(--muted); display: block; overflow: hidden;
1233                             text-overflow: ellipsis; white-space: nowrap; }
1234table.tree td.lastcommit a:hover { color: var(--accent); }
1235table.tree th.age, table.tree td.age {
1236  text-align: right;
1237  white-space: nowrap;
1238  color: var(--muted);
1239  font-variant-numeric: tabular-nums;
1240}
1241table.tree td.name { width: 25%; white-space: nowrap; }
1242table.tree td.name.dir a { color: var(--accent); }
1243p.clone { margin: 0 0 var(--sp-3); }
1244p.filefacts { color: var(--muted); font-size: var(--fs-1); margin: 0 0 var(--sp-3); }
1245.pathbar .act { font-size: var(--fs-1); }
1246
1247/* merge request: a two-column split, so state has somewhere to live that
1248   is not a run-on sentence under the title */
1249.withaside {
1250  display: grid;
1251  grid-template-columns: minmax(0, 1fr) 15rem;
1252  gap: var(--sp-5);
1253  align-items: start;
1254}
1255.withaside .mainside { min-width: 0; }
1256@media (max-width: 62rem) { .withaside { grid-template-columns: 1fr; } }
1257
1258.aside { font-size: var(--fs-2); }
1259.aside .grp { border-top: 1px solid var(--line); padding: var(--sp-3) 0; }
1260.aside .grp:first-child { border-top: 0; padding-top: 0; }
1261.aside h2 {
1262  margin: 0 0 var(--sp-2);
1263  font-family: var(--mono);
1264  font-size: var(--fs-0);
1265  font-weight: 500;
1266  letter-spacing: 0.1em;
1267  text-transform: uppercase;
1268  color: var(--muted);
1269}
1270.aside .row { display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-1); flex-wrap: wrap; }
1271.aside .row:last-child { margin-bottom: 0; }
1272.aside .none { color: var(--muted); }
1273.aside .dot { width: 0.45rem; height: 0.45rem; flex: none; border-radius: 50%; background: var(--muted); }
1274.aside .dot.ok { background: var(--ok); }
1275.aside .dot.bad { background: var(--bad); }
1276.aside .dot.pend { background: var(--mark); }
1277
1278/* sub-navigation within an item; orange marks position as it does above */
1279nav.subtabs {
1280  display: flex;
1281  gap: var(--sp-4);
1282  border-bottom: 1px solid var(--line);
1283  margin: 0 0 var(--sp-4);
1284}
1285nav.subtabs a {
1286  display: inline-flex;
1287  align-items: center;
1288  gap: var(--sp-2);
1289  padding: 0 0 var(--sp-2);
1290  color: var(--muted);
1291  font-size: var(--fs-2);
1292  border-bottom: 2px solid transparent;
1293  margin-bottom: -1px;
1294}
1295nav.subtabs a:hover { color: var(--fg); text-decoration: none; }
1296nav.subtabs a[aria-current] { color: var(--fg); font-weight: 700; border-bottom-color: var(--mark); }
1297nav.subtabs a i {
1298  font-style: normal;
1299  font-family: var(--mono);
1300  font-size: var(--fs-0);
1301  background: var(--hover);
1302  border-radius: var(--r-sm);
1303  padding: 0 0.35rem;
1304}
1305p.diffstat { color: var(--muted); font-size: var(--fs-2); margin: 0 0 var(--sp-3); }
1306p.diffstat .add { color: var(--ok); }
1307p.diffstat .del { color: var(--bad); }