/* gitbay stylesheet. Tokens first, on :root and again in the dark media query; components use tokens only. Two accents with separate jobs: blue is what you can do (links, primary buttons, focus, pressed toggles), orange is where you are and what wants you (current tab, rail counts, pending state, unverified signatures). Orange is never a button ground. internal/web/tokens_test.go measures every token; internal/web/classes_test.go checks every template class has a rule. No external requests: fonts are served from this origin. */ @font-face { font-family: "Atkinson Hyperlegible Next"; font-style: normal; font-weight: 400 700; font-display: swap; src: url(/static/fonts/atkinson-next-roman.woff2) format("woff2"); } @font-face { font-family: "Atkinson Hyperlegible Next"; font-style: italic; font-weight: 400 700; font-display: swap; src: url(/static/fonts/atkinson-next-italic.woff2) format("woff2"); } @font-face { font-family: "Atkinson Hyperlegible Mono"; font-style: normal; font-weight: 400 600; font-display: swap; src: url(/static/fonts/atkinson-mono-roman.woff2) format("woff2"); } :root { /* declare native light+dark support: correct form controls and scrollbars per scheme, and opt out of browser auto-darkening */ color-scheme: light dark; /* grounds: canvas, surface and inset are three steps, not one */ --canvas: #ffffff; --surface: #ebedf1; --inset: #ffffff; --hover: #e1e4ea; --line: #8d939c; /* 3.09:1 on canvas — a border you can see */ --faint: #d8dce2; /* ink */ --fg: #1c1f24; --muted: #5a6270; --neutral: var(--muted); /* blue: what you can do. --link is text, --fill is a ground; one blue cannot clear 4.5:1 as text and 3:1 as a ground in both schemes. */ --link: #0033d6; --fill: #0000f0; --fill-fg: #ffffff; --focus: var(--link); /* orange: where you are, what wants you. Two cuts because the floor differs by size: --mark for bars, --warn at text size. */ --mark: #e4572e; --warn: #b8400f; /* state */ --ok: #0a7536; --bad: #c62828; --done: #6b21a8; /* diff row tints: enough to scan, light enough that the syntax palette stays legible on them (TestSyntaxPaletteContrast) */ --diff-add: #e4f6ea; --diff-del: #fdeaea; /* the rail is black in both schemes: the one brand constant */ --shell-bg: #000000; --shell-fg: #f2f2f2; --shell-muted: #8f8f8f; --shell-line: #1c1c1c; --shell-hover: #141414; --shell-mark: #ff6b3d; /* the languages' own colours; the same in both schemes */ --lang-go: #00add8; --lang-rust: #dea584; --lang-c: #555555; --lang-python: #3572a5; --lang-javascript: #f1e05a; --lang-typescript: #3178c6; --lang-shell: #89e051; --lang-ruby: #701516; --lang-java: #b07219; --lang-swift: #f05138; --lang-html: #e34c26; --lang-css: #563d7c; --lang-org: #77aa99; --lang-markdown: #083fa1; --lang-emacs-lisp: #c065db; --lang-nix: #7e7eff; --lang-sql: #e38c00; --sans: "Atkinson Hyperlegible Next", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; --mono: "Atkinson Hyperlegible Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; /* 12, 13, 14, 16, 20, 24, 32 */ --fs-0: 0.75rem; --fs-1: 0.8125rem; --fs-2: 0.875rem; --fs-3: 1rem; --fs-4: 1.25rem; --fs-5: 1.5rem; --fs-6: 2rem; /* 4, 8, 12, 16, 24, 32, 48 */ --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --r-ctl: 4px; /* controls and chips */ --r-card: 6px; /* cards, lists, code blocks */ --shadow: 0 4px 16px rgba(0, 0, 0, 0.12); /* the native select arrow cannot be restyled, so draw our own; --chev carries the stroke colour per scheme */ --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='%235a6270' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); } @media (prefers-color-scheme: dark) { :root { --canvas: #101114; --surface: #212429; --inset: #0b0c0e; --hover: #2b2f36; --line: #61666f; --faint: #2f333a; --fg: #e9eaec; --muted: #a3a9b3; --neutral: var(--muted); --link: #8b9bff; --fill: #4d61f0; --fill-fg: #ffffff; --focus: var(--link); --mark: #ff6b3d; --warn: #ff8a63; --ok: #3fce7a; --bad: #ff6b6b; --done: #c084fc; --diff-add: #0d2a18; --diff-del: #2c1113; --shell-bg: #000000; --shell-fg: #f2f2f2; --shell-muted: #8f8f8f; --shell-line: #1c1c1c; --shell-hover: #141414; --shell-mark: #ff6b3d; /* the languages' own colours; the same in both schemes */ --lang-go: #00add8; --lang-rust: #dea584; --lang-c: #555555; --lang-python: #3572a5; --lang-javascript: #f1e05a; --lang-typescript: #3178c6; --lang-shell: #89e051; --lang-ruby: #701516; --lang-java: #b07219; --lang-swift: #f05138; --lang-html: #e34c26; --lang-css: #563d7c; --lang-org: #77aa99; --lang-markdown: #083fa1; --lang-emacs-lisp: #c065db; --lang-nix: #7e7eff; --lang-sql: #e38c00; --shadow: 0 4px 16px rgba(0, 0, 0, 0.5); --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='%23a3a9b3' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); } } /* ---- base ---- */ * { box-sizing: border-box; } html { font-size: 16px; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; } body { margin: 0; background: var(--canvas); color: var(--fg); font: var(--fs-3)/1.5 var(--sans); min-height: 100vh; } h1, h2, h3 { line-height: 1.25; font-weight: 600; } h1 { font-size: var(--fs-5); margin: 0 0 var(--sp-3); text-wrap: balance; } h2 { font-size: var(--fs-4); margin: var(--sp-6) 0 var(--sp-3); } h3 { font-size: var(--fs-3); margin: var(--sp-5) 0 var(--sp-2); } p { margin: 0 0 var(--sp-3); } a { color: var(--link); text-decoration: none; } a:hover { text-decoration: underline; } a.xref { color: var(--link); text-decoration: none; } code, pre, .mono, .code, td.mode, td.size { font-family: var(--mono); font-size: var(--fs-1); } .mono { overflow-wrap: anywhere; } /* ---- focus: one authored ring, so keyboard position is never the browser's guess ---- */ :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 1px; } /* the rail is black in both schemes and --focus is a dark blue in the light one — a ring nobody could see there */ .rail :focus-visible { outline-color: var(--shell-mark); } /* visually hidden, still read aloud */ .vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; clip-path: inset(50%); overflow: hidden; white-space: nowrap; } /* ---- skip link: the rail runs ahead of the content in source order ---- */ a.skip { position: absolute; left: var(--sp-3); top: -3rem; z-index: 50; background: var(--fill); color: var(--fill-fg); padding: var(--sp-2) var(--sp-4); font-weight: 600; } a.skip:focus { top: var(--sp-3); text-decoration: none; } /* ---- rail ---- */ .rail { flex: none; width: 14rem; background: var(--shell-bg); color: var(--shell-fg); border-right: 1px solid var(--shell-line); position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; } a.brand { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-4) var(--sp-4) var(--sp-3); color: var(--shell-fg); font-weight: 600; font-size: var(--fs-3); } a.brand:hover { text-decoration: none; } a.brand svg.mark { display: block; flex: none; } a.brand span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .railbody { flex: 1; overflow-y: auto; padding: 0 var(--sp-3); } /* search is reachable from every page, so it sits above the rail's links rather than on one page of its own */ form.railsearch { margin-bottom: var(--sp-3); } form.railsearch input[type="search"] { width: 100%; background: var(--shell-hover); border: 1px solid var(--shell-line); color: var(--shell-fg); border-radius: var(--r-ctl); padding: 6px 10px; height: 32px; font: inherit; font-size: var(--fs-2); } form.railsearch input[type="search"]::placeholder { color: var(--shell-muted); } ul.raillist { list-style: none; margin: 0 0 var(--sp-4); padding: 0; } ul.raillist a { display: flex; align-items: center; gap: var(--sp-2); padding: 5px var(--sp-2); color: var(--shell-fg); font-size: var(--fs-2); border-radius: var(--r-ctl); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } ul.raillist a:hover { background: var(--shell-hover); text-decoration: none; } /* orange marks position — the rail's only accent */ ul.raillist a[aria-current] { background: var(--shell-hover); box-shadow: inset 3px 0 0 var(--shell-mark); font-weight: 600; } ul.raillist .owner { color: var(--shell-muted); } ul.raillist.wide a { white-space: normal; display: block; } ul.raillist.wide b { display: block; font-weight: 500; font-size: var(--fs-1); } ul.raillist.wide .owner { display: block; font-size: var(--fs-0); } .railgroup { margin-bottom: var(--sp-4); } .raillabel { display: flex; align-items: center; gap: var(--sp-2); margin: 0 var(--sp-2) var(--sp-1); font-size: var(--fs-0); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--shell-muted); } .count { font-size: var(--fs-0); font-weight: 600; letter-spacing: 0; background: var(--shell-mark); color: var(--shell-bg); padding: 0 5px; border-radius: var(--r-ctl); margin-left: auto; } /* pinned above the account cell: always reachable, never scrolled away */ .railpinned { flex: none; padding: var(--sp-2) var(--sp-3); margin: 0; border-top: 1px solid var(--shell-line); } .railfoot { flex: none; border-top: 1px solid var(--shell-line); padding: var(--sp-3) var(--sp-4); display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); font-size: var(--fs-2); } .railfoot a { color: var(--shell-fg); } a.railuser { display: inline-flex; align-items: center; gap: var(--sp-2); } /* a descendant cannot cancel an ancestor's underline, so the link carries none and the name draws its own */ a.railuser:hover { text-decoration: none; } a.railuser:hover .uname { text-decoration: underline; } .railfoot form { margin-left: auto; } .railfoot button.linklike { color: var(--shell-muted); text-decoration: underline; } .railfoot button.linklike:hover { color: var(--shell-fg); } .avatar { display: inline-grid; place-items: center; width: 22px; height: 22px; flex: none; border-radius: 50%; background: var(--fill); color: var(--fill-fg); font-size: var(--fs-0); font-weight: 600; } /* ---- shell ---- */ .shell { display: flex; align-items: stretch; min-height: 100vh; } .pane { flex: 1; min-width: 0; display: flex; flex-direction: column; } main.content { flex: 1; width: 100%; padding: var(--sp-5) var(--sp-6) var(--sp-7); } main.wide { max-width: none; } main.reading { max-width: calc(72rem + 2 * var(--sp-6)); } main.bounded { max-width: calc(48rem + 2 * var(--sp-6)); } footer { width: 100%; padding: var(--sp-4) var(--sp-6); border-top: 1px solid var(--faint); color: var(--muted); font-size: var(--fs-1); } footer p { margin: 0; } footer a { color: var(--muted); text-decoration: underline; } footer a:hover { color: var(--link); } /* ---- repository header ---- */ .repohead { padding: var(--sp-4) var(--sp-6) 0; border-bottom: 1px solid var(--line); } .identity { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; } .grow { flex: 1; } /* h1 on the repo home, p elsewhere so each page keeps its own h1 — but identical in size, because the tabs sit below and navigation must not move when you use it */ .repotitle { margin: 0; font-size: var(--fs-4); font-weight: 600; line-height: 1.25; } .repotitle a { color: var(--fg); } .repotitle a.owner { color: var(--muted); font-weight: 400; } .repotitle a:hover { color: var(--link); text-decoration: none; } .repotitle .sep { color: var(--muted); margin: 0 2px; font-weight: 400; } .repodesc { margin: var(--sp-2) 0 0; color: var(--fg); font-size: var(--fs-2); display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; } .repometa { margin: var(--sp-1) 0 0; color: var(--muted); font-size: var(--fs-1); } .toggles { margin: var(--sp-2) 0 0; color: var(--muted); font-size: var(--fs-1); } nav.tabs { display: flex; gap: var(--sp-1); margin-top: var(--sp-3); overflow-x: auto; /* with overflow-y left visible the browser computes it to auto, which is a vertical drag on touch; the strip scrolls sideways only */ overflow-y: hidden; scrollbar-width: none; } nav.tabs::-webkit-scrollbar { display: none; } nav.tabs a { display: inline-flex; align-items: center; gap: var(--sp-1); padding: var(--sp-2) var(--sp-3) 10px; color: var(--muted); font-size: var(--fs-2); white-space: nowrap; border-bottom: 2px solid transparent; margin-bottom: -1px; } nav.tabs a:hover { color: var(--fg); text-decoration: none; } nav.tabs a[aria-current] { color: var(--fg); font-weight: 600; border-bottom-color: var(--mark); } /* a count in a tab is plain metadata, not a badge */ nav.tabs a i { font-style: normal; color: var(--muted); margin-left: 4px; } /* ---- page heads ---- */ .pagehead, .listhead, .headrow { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-5); } .pagehead h1, .listhead h1, .headrow h1, .listhead h2, .headrow h2 { margin: 0; } .pagehead .grow, .listhead .spacer, .headrow .spacer { flex: 1; } .issuetitle { margin: 0 0 var(--sp-2); font-size: var(--fs-5); } .issuenumber { color: var(--muted); font-weight: 400; } .issuemeta { color: var(--muted); font-size: var(--fs-2); margin: 0 0 var(--sp-4); } .commithead p { margin: var(--sp-1) 0; } .commithead h2 { margin-top: 0; margin-bottom: var(--sp-1); } nav.filters { display: inline-flex; gap: var(--sp-2); flex-wrap: wrap; } nav.filters a { display: inline-flex; align-items: center; height: 32px; padding: 0 var(--sp-3); background: var(--canvas); border: 1px solid var(--line); border-radius: var(--r-ctl); color: var(--fg); font-size: var(--fs-2); font-weight: 500; } nav.filters a:hover { background: var(--hover); text-decoration: none; } nav.filters a.active { background: var(--surface); border-color: var(--link); color: var(--link); } form.searchform, form.logfilter, form.compareform { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin: 0 0 var(--sp-4); } form.searchform input[type="search"], form.logfilter input { flex: 1; min-width: 12rem; max-width: 32rem; } form.searchform.compact { margin: 0; } form.searchform.compact input[type="search"] { min-width: 18rem; } form.compareform label { display: inline-flex; align-items: center; gap: var(--sp-2); margin: 0; } /* ---- buttons: one family, 32px tall, so a row of them lines up ---- */ button, .button { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 32px; padding: 0 var(--sp-3); font: inherit; font-size: var(--fs-2); font-weight: 500; border: 1px solid transparent; border-radius: var(--r-ctl); cursor: pointer; text-decoration: none; white-space: nowrap; /* a bare