diff --git a/modules/forgejo-theme-gh-hc.css b/modules/forgejo-theme-gh-hc.css new file mode 100644 index 0000000..b88f4f7 --- /dev/null +++ b/modules/forgejo-theme-gh-hc.css @@ -0,0 +1,414 @@ +:root { + /* GitHub Dark High Contrast gray scale */ + --steel-900: #010409; + --steel-850: #0a0c10; + --steel-800: #0a0c10; + --steel-750: #151b23; + --steel-700: #1a1f29; + --steel-650: #272b33; + --steel-600: #353b45; + --steel-550: #3d444d; + --steel-500: #525964; + --steel-450: #656c76; + --steel-400: #7a828e; + --steel-350: #9ea7b3; + --steel-300: #b3bac3; + --steel-250: #c5cdd8; + --steel-200: #d9dee3; + --steel-150: #e6edf3; + --steel-100: #f0f3f6; + + --is-dark-theme: true; + + /* Primary: GitHub blue */ + --color-primary: #71b7ff; + --color-primary-contrast: #010409; + --color-primary-dark-1: #91c9ff; + --color-primary-dark-2: #aed4ff; + --color-primary-dark-3: #c8e1ff; + --color-primary-dark-4: #dceeff; + --color-primary-dark-5: #e8f2ff; + --color-primary-dark-6: #f0f7ff; + --color-primary-dark-7: #f8fbff; + --color-primary-light-1: #409eff; + --color-primary-light-2: #388bdb; + --color-primary-light-3: #316dca; + --color-primary-light-4: #264f91; + --color-primary-light-5: #1b3a6b; + --color-primary-light-6: #122b52; + --color-primary-light-7: #0c1d3d; + --color-primary-alpha-10: #409eff19; + --color-primary-alpha-20: #409eff33; + --color-primary-alpha-30: #409eff4b; + --color-primary-alpha-40: #409eff66; + --color-primary-alpha-50: #409eff80; + --color-primary-alpha-60: #409eff99; + --color-primary-alpha-70: #409effb3; + --color-primary-alpha-80: #409effcc; + --color-primary-alpha-90: #409effe1; + --color-primary-hover: var(--color-primary-light-1); + --color-primary-active: var(--color-primary-light-2); + + /* Secondary */ + --color-secondary: var(--steel-700); + --color-secondary-dark-1: var(--steel-550); + --color-secondary-dark-2: var(--steel-500); + --color-secondary-dark-3: var(--steel-450); + --color-secondary-dark-4: var(--steel-400); + --color-secondary-dark-5: var(--steel-350); + --color-secondary-dark-6: var(--steel-300); + --color-secondary-dark-7: var(--steel-250); + --color-secondary-dark-8: var(--steel-200); + --color-secondary-dark-9: var(--steel-150); + --color-secondary-dark-10: var(--steel-100); + --color-secondary-dark-11: var(--steel-100); + --color-secondary-dark-12: var(--steel-100); + --color-secondary-dark-13: var(--steel-100); + --color-secondary-light-1: var(--steel-650); + --color-secondary-light-2: var(--steel-700); + --color-secondary-light-3: var(--steel-750); + --color-secondary-light-4: var(--steel-800); + --color-secondary-alpha-10: #272b3319; + --color-secondary-alpha-20: #272b3333; + --color-secondary-alpha-30: #272b334b; + --color-secondary-alpha-40: #272b3366; + --color-secondary-alpha-50: #272b3380; + --color-secondary-alpha-60: #272b3399; + --color-secondary-alpha-70: #272b33b3; + --color-secondary-alpha-80: #272b33cc; + --color-secondary-alpha-90: #272b33e1; + --color-secondary-hover: var(--color-secondary-light-1); + --color-secondary-active: var(--color-secondary-light-2); + + /* Console */ + --color-console-fg: #f0f3f6; + --color-console-fg-subtle: #9ea7b3; + --color-console-bg: #010409; + --color-console-border: #3d444d; + --color-console-hover-bg: #ffffff16; + --color-console-active-bg: #353b45; + --color-console-menu-bg: #272b33; + --color-console-menu-border: #525964; + + /* GitHub Dark HC semantic colors */ + --color-red: #ff6a69; + --color-orange: #f0883e; + --color-yellow: #f0b72f; + --color-olive: #57ab5a; + --color-green: #26cd4d; + --color-teal: #39d5cf; + --color-blue: #71b7ff; + --color-violet: #cb7eff; + --color-purple: #cb7eff; + --color-pink: #f778ba; + --color-brown: #c69026; + --color-grey: var(--steel-500); + --color-black: #010409; + + --color-red-light: #ff9492; + --color-orange-light: #f7b267; + --color-yellow-light: #f7ce56; + --color-olive-light: #6bc46d; + --color-green-light: #4ae168; + --color-teal-light: #5fe3db; + --color-blue-light: #91c9ff; + --color-violet-light: #dbb7ff; + --color-purple-light: #dbb7ff; + --color-pink-light: #f99bce; + --color-brown-light: #d4a33b; + --color-grey-light: var(--steel-300); + --color-black-light: #151b23; + + --color-red-dark-1: #e5534b; + --color-orange-dark-1: #d4772c; + --color-yellow-dark-1: #d4a015; + --color-olive-dark-1: #46954a; + --color-green-dark-1: #1fae3e; + --color-teal-dark-1: #2db8b0; + --color-blue-dark-1: #409eff; + --color-violet-dark-1: #b15fef; + --color-purple-dark-1: #b15fef; + --color-pink-dark-1: #e05fa0; + --color-brown-dark-1: #ae7c14; + --color-black-dark-1: #010409; + + --color-red-dark-2: #cc3e3d; + --color-orange-dark-2: #b8621a; + --color-yellow-dark-2: #b8860d; + --color-olive-dark-2: #347d37; + --color-green-dark-2: #1a9133; + --color-teal-dark-2: #249e98; + --color-blue-dark-2: #316dca; + --color-violet-dark-2: #9745e0; + --color-purple-dark-2: #9745e0; + --color-pink-dark-2: #c44a87; + --color-brown-dark-2: #966a0b; + --color-black-dark-2: #010409; + + /* ANSI terminal colors */ + --color-ansi-black: #272b33; + --color-ansi-red: #ff9492; + --color-ansi-green: #26cd4d; + --color-ansi-yellow: #f0b72f; + --color-ansi-blue: #71b7ff; + --color-ansi-magenta: #cb7eff; + --color-ansi-cyan: #39d5cf; + --color-ansi-white: var(--color-console-fg-subtle); + --color-ansi-bright-black: #525964; + --color-ansi-bright-red: #ffb1af; + --color-ansi-bright-green: #4ae168; + --color-ansi-bright-yellow: #f7ce56; + --color-ansi-bright-blue: #91c9ff; + --color-ansi-bright-magenta: #dbb7ff; + --color-ansi-bright-cyan: #5fe3db; + --color-ansi-bright-white: var(--color-console-fg); + + --color-gold: #f0b72f; + --color-white: #f0f3f6; + --color-pure-black: #000000; + + /* Diff colors - high contrast */ + --color-diff-removed-word-bg: #cc3e3d80; + --color-diff-added-word-bg: #1a913380; + --color-diff-removed-row-bg: #cc3e3d26; + --color-diff-moved-row-bg: #ae7c1426; + --color-diff-added-row-bg: #1a913326; + --color-diff-removed-row-border: #ff6a69; + --color-diff-moved-row-border: #f0b72f; + --color-diff-added-row-border: #26cd4d; + --color-diff-inactive: var(--steel-650); + + /* Status colors - high contrast */ + --color-error-border: #ff6a69; + --color-error-bg: #5a1e1e; + --color-error-bg-active: #78302e; + --color-error-bg-hover: #78302e; + --color-error-text: #ffb1af; + + --color-success-border: #26cd4d; + --color-success-bg: #12361e; + --color-success-text: #4ae168; + + --color-warning-border: #f0b72f; + --color-warning-bg: #4e3b12; + --color-warning-text: #f7ce56; + + --color-info-border: #71b7ff; + --color-info-bg: #1a2e50; + --color-info-text: #91c9ff; + + /* Badges */ + --color-red-badge: #ff6a69; + --color-red-badge-bg: #ff6a6922; + --color-red-badge-hover-bg: #ff6a6944; + --color-green-badge: #26cd4d; + --color-green-badge-bg: #26cd4d22; + --color-green-badge-hover-bg: #26cd4d44; + --color-yellow-badge: #f0b72f; + --color-yellow-badge-bg: #f0b72f22; + --color-yellow-badge-hover-bg: #f0b72f44; + --color-orange-badge: #f0883e; + --color-orange-badge-bg: #f0883e22; + --color-orange-badge-hover-bg: #f0883e44; + + /* Thin colors */ + --thin-lightness: 0.75; + --regular-chroma: 0.22; + --color-thin-green: oklch(var(--thin-lightness) var(--regular-chroma) 145deg); + --color-thin-red: oklch(var(--thin-lightness) var(--regular-chroma) 27deg); + --color-thin-purple: oklch(var(--thin-lightness) var(--regular-chroma) 298deg); + --color-thin-orange: oklch(var(--thin-lightness) var(--regular-chroma) 41deg); + --thin-lightness-highlight: 0.82; + --color-thin-red-highlight: oklch(var(--thin-lightness-highlight) var(--regular-chroma) 27deg); + --bg-lightness: 0.26; + --bg-chroma: 0.05; + --color-danger-bg: oklch(var(--bg-lightness) var(--bg-chroma) 27deg); + + /* Layout surfaces */ + --color-body: var(--steel-800); + --color-box-header: var(--steel-700); + --color-box-body: var(--steel-750); + --color-box-body-highlight: var(--steel-650); + --color-text-dark: #f0f3f6; + --color-text: var(--steel-100); + --color-text-light: var(--steel-150); + --color-text-light-1: var(--steel-150); + --color-text-light-2: var(--steel-200); + --color-text-light-3: var(--steel-200); + --color-footer: var(--steel-900); + --color-timeline: var(--steel-600); + + /* Inputs */ + --color-input-text: var(--steel-100); + --color-input-background: var(--steel-750); + --color-input-toggle-background: var(--steel-650); + --color-input-border: var(--steel-500); + --color-input-border-hover: var(--steel-400); + + /* Header */ + --color-header-wrapper: var(--steel-900); + --color-header-wrapper-transparent: #0a0c1000; + + /* Surfaces */ + --color-light: #00000028; + --color-light-mimic-enabled: rgba(0, 0, 0, calc(40 / 255 * 222 / 255 / var(--opacity-disabled))); + --color-light-border: #f0f3f628; + --color-hover: var(--steel-600); + --color-active: var(--steel-650); + --color-menu: var(--steel-700); + --color-card: var(--steel-700); + --fancy-card-bg: var(--steel-650); + --fancy-card-border: var(--steel-500); + + /* Markup */ + --color-markup-table-row: #f0f3f606; + --color-markup-code-block: var(--steel-850); + --color-markup-code-inline: var(--steel-900); + + /* Misc UI */ + --color-button: var(--steel-600); + --color-code-bg: var(--steel-750); + --color-shadow: #00000080; + --color-secondary-bg: var(--steel-700); + --color-text-focus: #f0f3f6; + --color-expand-button: #353b45; + --color-placeholder-text: var(--color-text-light-3); + --color-editor-line-highlight: var(--steel-700); + --color-project-board-bg: var(--color-secondary-light-3); + --color-project-board-dark-label: var(--color-text-light-3); + --color-caret: var(--color-text); + + /* Reactions */ + --color-reaction-bg: #f0f3f612; + --color-reaction-active-bg: var(--color-primary-alpha-30); + --color-reaction-hover-bg: var(--color-primary-alpha-40); + + /* Tooltips */ + --color-tooltip-text: #f0f3f6; + --color-tooltip-bg: #010409f0; + + /* Navigation */ + --color-nav-bg: var(--steel-900); + --color-nav-hover-bg: var(--steel-600); + --color-secondary-nav-bg: var(--color-body); + + /* Labels */ + --color-label-text: #f0f3f6; + --color-label-bg: var(--steel-600); + --color-label-hover-bg: var(--steel-550); + --color-label-active-bg: var(--steel-500); + --color-label-bg-alt: var(--steel-550); + + /* Accents */ + --color-accent: var(--color-primary); + --color-small-accent: var(--color-primary-light-4); + --color-highlight-fg: var(--color-primary); + --color-highlight-bg: var(--color-primary-alpha-20); + + /* Overlay */ + --color-overlay-backdrop: #010409d0; + + /* Selection */ + --color-selection-bg: var(--steel-100); + --color-selection-fg: var(--color-pure-black); + + /* Checkerboard */ + --checkerboard-color-1: #3d444d; + --checkerboard-color-2: #272b33; + + accent-color: var(--color-accent); + color-scheme: dark; +} + +/* Emoji inversion for dark background readability */ +.emoji[aria-label="check mark"], +.emoji[aria-label="currency exchange"], +.emoji[aria-label="TOP arrow"], +.emoji[aria-label="END arrow"], +.emoji[aria-label="ON! arrow"], +.emoji[aria-label="SOON arrow"], +.emoji[aria-label="heavy dollar sign"], +.emoji[aria-label="copyright"], +.emoji[aria-label="registered"], +.emoji[aria-label="trade mark"], +.emoji[aria-label="multiply"], +.emoji[aria-label="plus"], +.emoji[aria-label="minus"], +.emoji[aria-label="divide"], +.emoji[aria-label="curly loop"], +.emoji[aria-label="double curly loop"], +.emoji[aria-label="wavy dash"], +.emoji[aria-label="paw prints"], +.emoji[aria-label="musical note"], +.emoji[aria-label="musical notes"] { + filter: invert(100%) hue-rotate(180deg); +} + +i.grey.icon.icon.icon.icon { + color: var(--steel-350) !important; +} + +.ui.secondary.vertical.menu { + border-radius: 0.28571429rem !important; + overflow: hidden; +} + +.ui.basic.primary.button.item { + background-color: var(--color-active) !important; + color: var(--color-text) !important; + box-shadow: none !important; +} + +.ui.red.label.notification_count, +.ui.primary.label, +.ui.primary.labels .label { + background-color: var(--color-primary-light-3) !important; +} + +.ui.labeled.icon.buttons > .button > .icon, +.ui.labeled.icon.button > .icon { + background-color: var(--color-light) !important; +} + +#review-box .review-comments-counter { + background-color: var(--color-shadow) !important; + color: var(--color-white) !important; + margin-left: 0.5em; +} + +.ui.basic.labels .primary.label, +.ui.ui.ui.basic.primary.label { + color: var(--color-text-dark) !important; +} + +.ui.yellow.label.pending-label { + color: var(--color-warning-text) !important; +} + +strong.attention-important, svg.attention-important { + color: var(--color-violet-light); +} + +strong.attention-note, svg.attention-note { + color: var(--color-blue-light); +} + +strong.attention-caution, svg.attention-caution { + color: var(--color-red-light); +} + +.ui.basic.red.button { + background-color: var(--color-red); + color: var(--color-pure-black); +} + +.ui.basic.red.button:hover, +.ui.basic.red.button:focus { + background-color: var(--color-red-dark-1); + color: var(--color-pure-black); +} + +.ui.basic.red.button:active { + background-color: var(--color-red-dark-2); + color: var(--color-pure-black); +} diff --git a/modules/forgejo.nix b/modules/forgejo.nix index 88c4d73..fe180e1 100644 --- a/modules/forgejo.nix +++ b/modules/forgejo.nix @@ -1,21 +1,69 @@ { config, pkgs, ... }: +let + customDir = "/var/lib/forgejo/custom"; + themeCSS = ./forgejo-theme-gh-hc.css; +in { services.forgejo = { enable = true; database.type = "postgres"; - # Enable support for Large File Storage lfs.enable = true; settings = { server = { DOMAIN = "git.extremist.software"; ROOT_URL = "https://git.extremist.software/"; HTTP_PORT = 3000; + LANDING_PAGE = "/jet"; }; - # You can configure SMTP here using secrets if needed + + service = { + DISABLE_REGISTRATION = true; + SHOW_REGISTRATION_BUTTON = false; + EXPLORE_REQUIRE_SIGNIN_VIEW = true; + }; + + "service.explore" = { + DISABLE_USERS_PAGE = true; + DISABLE_ORGANIZATIONS_PAGE = true; + }; + + repository = { + DISABLE_STARS = true; + }; + + ui = { + DEFAULT_THEME = "gh-hc"; + THEMES = "gh-hc,forgejo-auto,forgejo-light,forgejo-dark"; + SHOW_USER_EMAIL = true; + }; + + "ui.meta" = { + AUTHOR = "jet"; + DESCRIPTION = "Software extremist."; + KEYWORDS = "git,forgejo,jet,extremist"; + }; + + other = { + SHOW_FOOTER_VERSION = false; + }; + + openid = { + ENABLE_OPENID_SIGNIN = false; + ENABLE_OPENID_SIGNUP = false; + }; + }; database.passwordFile = config.age.secrets.forgejo-db.path; }; services.postgresql.enable = true; + + # Deploy custom theme CSS to Forgejo's custom directory + systemd.tmpfiles.rules = [ + "d ${customDir}/public 0755 forgejo forgejo -" + "d ${customDir}/public/assets 0755 forgejo forgejo -" + "d ${customDir}/public/assets/css 0755 forgejo forgejo -" + "C+ ${customDir}/public/assets/css/theme-gh-hc.css 0644 forgejo forgejo - ${themeCSS}" + ]; }