commit a004fc57edb799a7078804ad8ff0166e6030ebfd Author: didericis Date: Wed May 6 14:47:10 2026 -0400 Initial commit — Fell Gitea theme Parchment body, near-black starfield nav, teal (#42b983) accent. Includes IM Fell Type fonts (regular, italic, small-caps) and a README covering installation on TrueNAS Scale and plain Docker. Co-Authored-By: Claude Sonnet 4.6 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..024cc6a --- /dev/null +++ b/README.md @@ -0,0 +1,100 @@ +# Fell — a Gitea theme + +A Gitea theme inspired by [dideric.is](https://dideric.is). Parchment body, near-black nav, teal accent, and [IM Fell Type](https://iginomarini.com/fell/) throughout. + +![Fell theme screenshot](https://gitea.dideric.is/didericis/gitea-fell-theme/raw/branch/main/preview.png) + +## What's in the box + +``` +public/ + assets/ + css/ + theme-fell.css ← the theme (all 244 Gitea CSS variables) + fonts/ + IMFePIrm29P.ttf ← Fell Type regular + IMFePIit29P.ttf ← Fell Type italic + IMFeDPsc29P.ttf ← Fell Type small caps (headings/nav) +``` + +The fonts are served from the same custom directory as the CSS, so no external CDN is needed. + +--- + +## Installing on TrueNAS Scale + +TrueNAS Scale runs Gitea as a Docker container via the app catalog. The custom directory (`GITEA_CUSTOM`) is set to `/data/gitea` inside the container. Custom theme files go at: + +``` +$GITEA_CUSTOM/public/assets/css/theme-fell.css +$GITEA_CUSTOM/public/assets/fonts/*.ttf +``` + +### 1. Copy the theme files + +Open a shell into the Gitea container. In the TrueNAS web UI, go to **Apps → Gitea → ⋮ → Shell**, then: + +```sh +# Create directories if they don't exist +mkdir -p /data/gitea/public/assets/css +mkdir -p /data/gitea/public/assets/fonts +``` + +Then from your TrueNAS host shell (or via SCP), copy the files from this repo into those paths. If your Gitea data is on a host-path dataset (e.g. `/mnt/tank/gitea`), you can copy directly on the host: + +```sh +# On the TrueNAS host — adjust the dataset path to match your setup +GITEA_DATA=/mnt/tank/gitea + +mkdir -p "$GITEA_DATA/public/assets/css" +mkdir -p "$GITEA_DATA/public/assets/fonts" + +cp public/assets/css/theme-fell.css "$GITEA_DATA/public/assets/css/" +cp public/assets/fonts/*.ttf "$GITEA_DATA/public/assets/fonts/" +``` + +> **ixVolume vs host path**: If Gitea is using an ixVolume (the TrueNAS default), the data lives inside the opaque volume store. Use the container shell method in that case, or switch the Gitea app to use a host-path dataset so you can manage files directly. + +### 2. Register the theme in app.ini + +Edit `/data/gitea/conf/app.ini` inside the container (or the `conf/app.ini` file in your dataset on the host): + +```ini +[ui] +THEMES = gitea-light,gitea-dark,fell +DEFAULT_THEME = fell +``` + +Add `fell` to whatever list of themes you already have — don't remove the built-ins. + +### 3. Restart Gitea + +In the TrueNAS web UI: **Apps → Gitea → ⋮ → Restart**. + +### 4. Select the theme + +Go to **User Settings → Appearance**, pick **Fell** from the theme dropdown, and click **Update Theme**. + +--- + +## Installing on a plain Docker / docker-compose instance + +Mount the `public/` directory from this repo into your container at `$GITEA_CUSTOM/public/`: + +```yaml +services: + gitea: + image: gitea/gitea:latest + volumes: + - ./gitea-data:/data + - ./public:/data/gitea/public # ← this repo's public/ dir + environment: + - GITEA__ui__THEMES=gitea-light,gitea-dark,fell + - GITEA__ui__DEFAULT_THEME=fell +``` + +--- + +## Font credit + +The Fell Types are digitally reproduced by [Igino Marini](https://iginomarini.com/fell/) and are used here under their original license terms. diff --git a/public/assets/css/theme-fell.css b/public/assets/css/theme-fell.css new file mode 100644 index 0000000..0cc6f11 --- /dev/null +++ b/public/assets/css/theme-fell.css @@ -0,0 +1,468 @@ +/* ================================================================ + Fell — Gitea theme inspired by dideric.is + Parchment body · Starfield nav · Teal accent · Fell Type + ================================================================ */ + +@font-face { + font-family: 'FellType'; + src: url('../fonts/IMFePIrm29P.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'FellType'; + src: url('../fonts/IMFePIit29P.ttf') format('truetype'); + font-weight: normal; + font-style: italic; +} + +@font-face { + font-family: 'FellTypeFormal'; + src: url('../fonts/IMFeDPsc29P.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} + +/* ---- Theme meta ---- */ +gitea-theme-meta-info { + --theme-display-name: "Fell"; + --theme-color-scheme: "light"; +} + +:root { + --is-dark-theme: false; + color-scheme: light; + + /* Primary: teal #42b983 */ + --color-primary: #42b983; + --color-primary-contrast: #ffffff; + --color-primary-dark-1: #3aaa77; + --color-primary-dark-2: #329966; + --color-primary-dark-3: #2a8855; + --color-primary-dark-4: #227744; + --color-primary-dark-5: #1a6633; + --color-primary-dark-6: #0f4422; + --color-primary-dark-7: #062211; + --color-primary-light-1: #55c490; + --color-primary-light-2: #68cf9d; + --color-primary-light-3: #7bdaaa; + --color-primary-light-4: #8ee5b7; + --color-primary-light-5: #b2f0d3; + --color-primary-light-6: #d4f7e8; + --color-primary-light-7: #f0fff8; + --color-primary-alpha-10: #42b98319; + --color-primary-alpha-20: #42b98333; + --color-primary-alpha-30: #42b9834b; + --color-primary-alpha-40: #42b98366; + --color-primary-alpha-50: #42b98380; + --color-primary-alpha-60: #42b98399; + --color-primary-alpha-70: #42b983b3; + --color-primary-alpha-80: #42b983cc; + --color-primary-alpha-90: #42b983e1; + --color-primary-hover: var(--color-primary-dark-1); + --color-primary-active: var(--color-primary-dark-2); + + /* Secondary: warm parchment-tan */ + --color-secondary: #c8b89a; + --color-secondary-dark-1: #bba98b; + --color-secondary-dark-2: #ae9a7c; + --color-secondary-dark-3: #9a8265; + --color-secondary-dark-4: #876c50; + --color-secondary-dark-5: #74583d; + --color-secondary-dark-6: #61452c; + --color-secondary-dark-7: #4e341c; + --color-secondary-dark-8: #3c250e; + --color-secondary-dark-9: #2a1803; + --color-secondary-dark-10: #1a0c00; + --color-secondary-dark-11: #0c0400; + --color-secondary-dark-12: #050100; + --color-secondary-dark-13: #020000; + --color-secondary-light-1: #d4c8b0; + --color-secondary-light-2: #dfd8c4; + --color-secondary-light-3: #eae7d8; + --color-secondary-light-4: #f5f0e8; + --color-secondary-alpha-10: #c8b89a19; + --color-secondary-alpha-20: #c8b89a33; + --color-secondary-alpha-30: #c8b89a4b; + --color-secondary-alpha-40: #c8b89a66; + --color-secondary-alpha-50: #c8b89a80; + --color-secondary-alpha-60: #c8b89a99; + --color-secondary-alpha-70: #c8b89ab3; + --color-secondary-alpha-80: #c8b89acc; + --color-secondary-alpha-90: #c8b89ae1; + --color-secondary-button: var(--color-secondary-dark-4); + --color-secondary-hover: var(--color-secondary-dark-5); + --color-secondary-active: var(--color-secondary-dark-6); + + /* Console */ + --color-console-fg: #1a1008; + --color-console-fg-subtle: #5a3e22; + --color-console-bg: #fef9f0; + --color-console-border: #c8b89a; + --color-console-hover-bg: #f5ead5; + --color-console-active-bg: #e8d9aa; + --color-console-menu-bg: #fdf6e3; + --color-console-menu-border: #c8b89a; + --color-console-link: #42b983; + + /* Named colors */ + --color-red: #c0392b; + --color-orange: #d35400; + --color-yellow: #f39c12; + --color-olive: #8e9b0f; + --color-green: #27ae60; + --color-teal: #42b983; + --color-blue: #2980b9; + --color-violet: #6c3483; + --color-purple: #8e44ad; + --color-pink: #c0135b; + --color-brown: #7b4a1e; + --color-black: #1a1008; + --color-red-light: #e06c5c; + --color-orange-light: #e8845a; + --color-yellow-light: #f7c35c; + --color-olive-light: #b8c840; + --color-green-light: #4cc87a; + --color-teal-light: #68cf9d; + --color-blue-light: #5da8d6; + --color-violet-light: #9b6bb5; + --color-purple-light: #b56ac8; + --color-pink-light: #d85a90; + --color-brown-light: #a87040; + --color-black-light: #504030; + --color-red-dark-1: #a93226; + --color-orange-dark-1: #be4c00; + --color-yellow-dark-1: #d48c10; + --color-olive-dark-1: #7c880d; + --color-green-dark-1: #229c55; + --color-teal-dark-1: #3aaa77; + --color-blue-dark-1: #2472a6; + --color-violet-dark-1: #5c2c72; + --color-purple-dark-1: #7c3b99; + --color-pink-dark-1: #a80f4e; + --color-brown-dark-1: #663d18; + --color-black-dark-1: #0e0804; + --color-red-dark-2: #922a20; + --color-orange-dark-2: #a34200; + --color-yellow-dark-2: #b87b0e; + --color-olive-dark-2: #6a740b; + --color-green-dark-2: #1d8a4a; + --color-teal-dark-2: #329966; + --color-blue-dark-2: #1f6491; + --color-violet-dark-2: #4c2460; + --color-purple-dark-2: #6a3085; + --color-pink-dark-2: #900b42; + --color-brown-dark-2: #4f3010; + --color-black-dark-2: #050302; + + /* ANSI */ + --color-ansi-black: #1a1008; + --color-ansi-red: #c0392b; + --color-ansi-green: #27ae60; + --color-ansi-yellow: #f39c12; + --color-ansi-blue: #2980b9; + --color-ansi-magenta: #8e44ad; + --color-ansi-cyan: #42b983; + --color-ansi-white: var(--color-console-fg-subtle); + --color-ansi-bright-black: #5a3e22; + --color-ansi-bright-red: #d44234; + --color-ansi-bright-green: #2ecc71; + --color-ansi-bright-yellow: #f5a623; + --color-ansi-bright-blue: #3498db; + --color-ansi-bright-magenta: #9b59b6; + --color-ansi-bright-cyan: #55c490; + --color-ansi-bright-white: var(--color-console-fg); + + /* Other */ + --color-grey: #7a6a56; + --color-grey-light: #9a8a76; + --color-gold: #9a7c2a; + --color-white: #ffffff; + + /* Diff */ + --color-diff-added-fg: #27ae60; + --color-diff-added-linenum-bg: #d4f7e4; + --color-diff-added-row-bg: #e8fff0; + --color-diff-added-row-border: #b2f0d3; + --color-diff-added-word-bg: #a8f0cc; + --color-diff-moved-row-bg: #f5f0d4; + --color-diff-moved-row-border: #d8cc80; + --color-diff-removed-fg: #c0392b; + --color-diff-removed-linenum-bg: #ffd8d4; + --color-diff-removed-row-bg: #fff0ee; + --color-diff-removed-row-border: #f0c8c0; + --color-diff-removed-word-bg: #ffc8c0; + --color-diff-inactive: #ede8dc; + + /* Semantic */ + --color-error-border: #c0392b66; + --color-error-bg: #fff0ee; + --color-error-bg-active: #ffd0cc; + --color-error-bg-hover: #ffe0dc; + --color-error-text: #9b2318; + --color-success-border: #42b98366; + --color-success-bg: #e8fff0; + --color-success-text: #1a7a44; + --color-warning-border: #f39c1266; + --color-warning-bg: #fff8e0; + --color-warning-text: #8a5a00; + --color-info-border: #2980b966; + --color-info-bg: #e8f4fd; + --color-info-text: #1a5c8a; + --color-priority-border: #8e44ad66; + --color-priority-bg: #f5e8ff; + --color-priority-text: #6c3483; + + /* Badges */ + --color-red-badge: #c0392b; + --color-red-badge-bg: #c0392b1a; + --color-red-badge-hover-bg: #c0392b4d; + --color-green-badge: #27ae60; + --color-green-badge-bg: #27ae601a; + --color-green-badge-hover-bg: #27ae604d; + --color-yellow-badge: #f39c12; + --color-yellow-badge-bg: #f39c121a; + --color-yellow-badge-hover-bg: #f39c124d; + --color-orange-badge: #d35400; + --color-orange-badge-bg: #d354001a; + --color-orange-badge-hover-bg: #d354004d; + + /* Branding */ + --color-git: #f05133; + --color-logo: #42b983; + + /* ---- Core UI ---- */ + --color-body: #fef4dc; + --color-box-header: #e8d9aa; + --color-box-body: #fef9f0; + --color-box-body-highlight:#eef7f2; + + --color-text-dark: #0e0803; + --color-text: #2d1f0e; + --color-text-light: #4a3018; + --color-text-light-1:#5a3e22; + --color-text-light-2:#7a5a38; + --color-text-light-3:#9a7a58; + + --color-nav-bg: #0d0b08; + --color-nav-hover-bg: #1e1810; + --color-nav-text: #e8dfc4; + --color-secondary-nav-bg:#f5ead5; + + --color-footer: var(--color-nav-bg); + + --color-timeline: #c8b89a; + + --color-input-text: var(--color-text-dark); + --color-input-background: #fffff8; + --color-input-toggle-background: #c8b89a; + --color-input-border: #c8b89a; + + --color-light: #2d1f0e06; + --color-light-border: #2d1f0e1d; + --color-hover: #2d1f0e08; + --color-hover-opaque: #f5ead5; + --color-active: #2d1f0e14; + + --color-menu: #fdf6e3; + --color-card: #fdf6e3; + + --color-markup-table-row: #42b9830a; + --color-markup-code-block: #42b98310; + --color-markup-code-inline: #2d1f0e0e; + + --color-button: #f5ead5; + + --color-code-bg: #f0e6c8; + + --color-shadow: #2d1f0e26; + --color-shadow-opaque: #c8b89a; + + --color-secondary-bg: #f5ead5; + + --color-expand-button: #d4f7e8; + + --color-placeholder-text: var(--color-text-light-3); + --color-editor-line-highlight: var(--color-secondary-alpha-30); + --color-editor-selection: var(--color-primary-alpha-30); + + --color-project-column-bg: var(--color-secondary-light-4); + + --color-caret: var(--color-text-dark); + + --color-reaction-bg: #2d1f0e0a; + --color-reaction-hover-bg: var(--color-primary-light-5); + --color-reaction-active-bg: var(--color-primary-light-6); + + --color-tooltip-text: #fdf6e3; + --color-tooltip-bg: #0d0b08f0; + + --color-label-text: var(--color-text); + --color-label-bg: #7a5a384b; + --color-label-hover-bg: #7a5a38a0; + --color-label-active-bg: #7a5a38ff; + + --color-accent: var(--color-primary-light-1); + --color-small-accent: var(--color-primary-light-6); + + --color-highlight-fg: #9a7c2a; + --color-highlight-bg: #f5efc5; + + --color-overlay-backdrop: #0d0b08c0; + + --color-danger: var(--color-red); + + --color-transparency-grid-light: #fdf6e3; + --color-transparency-grid-dark: #e8d9aa; + + --color-workflow-edge-hover: #c8b89a; + + /* Syntax — warm earthy tones on parchment */ + --color-syntax-keyword: #7c2d12; + --color-syntax-bool: #065f46; + --color-syntax-control: #78350f; + --color-syntax-name: #713f12; + --color-syntax-type: #881337; + --color-syntax-number: #1e3a8a; + --color-syntax-operator: #7c2d12; + --color-syntax-regexp: #5b21b6; + --color-syntax-string: #365314; + --color-syntax-comment: #78716c; + --color-syntax-invalid: #991b1b; + --color-syntax-link: var(--color-primary); + --color-syntax-tag: #7c2d12; + --color-syntax-attribute: #5b21b6; + --color-syntax-property: #1e3a8a; + --color-syntax-variable: #7c2d12; + --color-syntax-string-special: #78350f; + --color-syntax-escape: #713f12; + --color-syntax-entity: #5b21b6; + --color-syntax-preproc: #14532d; + --color-syntax-preproc-file: #1e3a8a; + --color-syntax-decorator: #14532d; + --color-syntax-namespace: #6b7280; + --color-syntax-name-pseudo: #5b21b6; + --color-syntax-comment-special: #5b21b6; + --color-syntax-text: inherit; + --color-syntax-text-alt: #5a3e22; + --color-syntax-punctuation: inherit; + --color-syntax-whitespace: #c8b89a; + --color-syntax-diff-fg: #2d1f0e; + --color-syntax-deleted-bg: #ffd5d0; + --color-syntax-inserted-bg: #d5f5e3; + --color-syntax-emph: #78350f; + --color-syntax-strong: inherit; + --color-syntax-heading: #713f12; + --color-syntax-subheading: #365314; + --color-syntax-output: #78716c; + --color-syntax-prompt: #7c2d12; + --color-syntax-traceback: #991b1b; + --color-syntax-matching-bracket-bg: #42b98338; + --color-syntax-nonmatching-bracket-bg: #c0392b38; + + accent-color: var(--color-accent); +} + +/* ================================================================ + Typography + ================================================================ */ + +body, +.ui, +p, +td, +th, +li, +label, +input, +textarea, +select { + font-family: 'FellType', 'IM Fell English', Georgia, 'Times New Roman', serif; + font-size: 15px; +} + +/* Small caps for headings and nav items — faithful to the site */ +h1, h2, h3, h4, h5, h6, +.ui.header, +.repository .header { + font-family: 'FellTypeFormal', 'IM Fell English SC', Georgia, serif; + letter-spacing: 0.03em; + font-weight: normal; +} + +/* Nav uses the formal small-caps face */ +#navbar .item, +#navbar a, +.navbar .item, +.navbar a, +.ui.menu .item { + font-family: 'FellTypeFormal', Georgia, serif; + letter-spacing: 0.04em; + font-style: normal; +} + +/* Links italic — matches the site's link style */ +a:not(.ui.button):not(.label):not(.tag):not(.item) { + font-style: italic; +} + +/* Code stays monospace — legibility */ +code, +pre, +kbd, +samp, +.CodeMirror, +.monaco-editor, +.diff-file-box { + font-family: 'SFMono-Regular', 'Cascadia Mono', 'Consolas', 'Liberation Mono', monospace !important; + font-style: normal !important; +} + +/* ================================================================ + Nav — dark starfield bar + ================================================================ */ + +#navbar, +.navbar { + background-color: var(--color-nav-bg) !important; + border-bottom: 1px solid rgba(232, 223, 196, 0.12) !important; +} + +#navbar *, +.navbar * { + color: var(--color-nav-text) !important; +} + +#navbar a:hover, +.navbar a:hover, +#navbar .item:hover, +.navbar .item:hover { + background-color: var(--color-nav-hover-bg) !important; + color: #ffffff !important; +} + +/* ================================================================ + Footer — same dark bar as nav + ================================================================ */ + +#footer, +footer { + background-color: var(--color-nav-bg) !important; + color: var(--color-nav-text) !important; +} + +#footer a, +footer a { + color: var(--color-primary-light-2) !important; +} + +/* ================================================================ + Buttons + ================================================================ */ + +.ui.primary.button, +.ui.green.button { + font-family: 'FellTypeFormal', Georgia, serif; + letter-spacing: 0.04em; +} diff --git a/public/assets/fonts/IMFeDPsc29P.ttf b/public/assets/fonts/IMFeDPsc29P.ttf new file mode 100644 index 0000000..ec141a0 Binary files /dev/null and b/public/assets/fonts/IMFeDPsc29P.ttf differ diff --git a/public/assets/fonts/IMFePIit29P.ttf b/public/assets/fonts/IMFePIit29P.ttf new file mode 100644 index 0000000..5572611 Binary files /dev/null and b/public/assets/fonts/IMFePIit29P.ttf differ diff --git a/public/assets/fonts/IMFePIrm29P.ttf b/public/assets/fonts/IMFePIrm29P.ttf new file mode 100644 index 0000000..d73e413 Binary files /dev/null and b/public/assets/fonts/IMFePIrm29P.ttf differ