Compare commits
3 Commits
bd1974094c
...
19439a4b4d
Author | SHA1 | Date |
---|---|---|
Ryan Rix | 19439a4b4d | |
Ryan Rix | 7aefd9450a | |
Ryan Rix | 59a207e366 |
431
arcology.org
431
arcology.org
|
@ -9,7 +9,7 @@
|
|||
|
||||
#+begin_src python :tangle arcology/models.py
|
||||
from __future__ import annotations
|
||||
from typing import Optional
|
||||
from typing import Optional, List
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
|
||||
|
@ -137,29 +137,42 @@ class Page(models.Model):
|
|||
title = models.CharField(max_length=512)
|
||||
allow_crawl = models.BooleanField(default=False)
|
||||
|
||||
def urlize_self(self):
|
||||
site = self.site
|
||||
return site.urlize_page(self)
|
||||
|
||||
|
||||
def collect_keywords(self):
|
||||
return self.file.keyword_set
|
||||
|
||||
|
||||
def collect_links(self):
|
||||
link_objs = self.file.outbound_links.all()
|
||||
ret = dict()
|
||||
for el in link_objs:
|
||||
try:
|
||||
h = el.dest_heading
|
||||
page = h.path.page_set.first()
|
||||
site = page.site
|
||||
link = site.urlize_page(page)
|
||||
ret[h.node_id] = link
|
||||
logger.info(f"link {link} from {el}")
|
||||
url = h.to_url()
|
||||
ret[h.node_id] = url
|
||||
logger.info(f"link {url} from {el}")
|
||||
except roam.models.Heading.DoesNotExist:
|
||||
logger.info(f"{el} does not have dest")
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def collect_backlinks(self) -> List[Link]:
|
||||
my_headings = self.file.heading_set.all()
|
||||
return set(roam.models.Link.objects.filter(dest_heading__in=my_headings))
|
||||
|
||||
|
||||
def to_html(self, links):
|
||||
opts = native.ExportOptions(
|
||||
link_retargets=links
|
||||
)
|
||||
return native.htmlize_file(self.file.path, opts)
|
||||
|
||||
|
||||
@classmethod
|
||||
def create_from_arroyo(cls, doc: native.Document) -> Page:
|
||||
f = roam.models.File.objects.get(path=doc.path)
|
||||
|
@ -340,6 +353,35 @@ class Migration(migrations.Migration):
|
|||
]
|
||||
#+end_src
|
||||
|
||||
** NEXT admin
|
||||
|
||||
dont worry too much about these;
|
||||
they are just used to validate that the data is ingested properly, to be honest.
|
||||
|
||||
#+begin_src python :tangle arcology/admin.py
|
||||
from django.contrib import admin
|
||||
import arcology.models
|
||||
|
||||
|
||||
class DomainInline(admin.TabularInline):
|
||||
model = arcology.models.SiteDomain
|
||||
|
||||
|
||||
@admin.register(arcology.models.Site)
|
||||
class SiteAdmin(admin.ModelAdmin):
|
||||
inlines = [DomainInline]
|
||||
|
||||
|
||||
@admin.register(arcology.models.Page)
|
||||
class PageAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
@admin.register(arcology.models.Feed)
|
||||
class FeedAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
#+end_src
|
||||
|
||||
* NEXT the web server
|
||||
|
||||
"""arcology URL Configuration
|
||||
|
@ -367,16 +409,18 @@ from arcology import views
|
|||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("", views.index),
|
||||
path("sitemap", views.sitemap),
|
||||
path("sitemap", views.sitemap, name="sitemap"),
|
||||
path("sites.css", views.site_css, name="site-css"),
|
||||
# ensure these ones are last because they're greedy!
|
||||
re_path("(?P<key>[0-9a-zA-Z/_\-]+\.xml)", views.feed),
|
||||
re_path("(?P<key>[0-9a-zA-Z/_\-]+)", views.org_page),
|
||||
re_path("(?P<key>[0-9a-zA-Z/_\-]+\.xml)", views.feed, name="feed"),
|
||||
re_path("(?P<key>[0-9a-zA-Z/_\-]+)", views.org_page, name="org-page"),
|
||||
]
|
||||
#+end_src
|
||||
|
||||
#+begin_src python :tangle arcology/views.py
|
||||
import logging
|
||||
from django.http import HttpResponse, HttpResponseNotFound
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
|
||||
from arcology.models import Page, Feed, Site
|
||||
from roam.models import Link
|
||||
|
@ -409,14 +453,27 @@ def org_page(request, key):
|
|||
site = Site.from_request(request)
|
||||
if site.key == "localhost":
|
||||
full_key = key
|
||||
new_site_key = key.split("/")[0]
|
||||
site = Site.objects.filter(key=new_site_key).first()
|
||||
else:
|
||||
full_key = f"{site.key}/{key}"
|
||||
|
||||
the_page = Page.objects.get(route_key=full_key)
|
||||
the_page = get_object_or_404(Page, route_key=full_key)
|
||||
links = the_page.collect_links()
|
||||
|
||||
page_html = the_page.to_html(links)
|
||||
return HttpResponse(page_html)
|
||||
|
||||
logger.warn(site)
|
||||
|
||||
return render(request, "arcology/page.html", dict(
|
||||
site=site,
|
||||
page=the_page,
|
||||
|
||||
head_title=f"{the_page.title} - {site.title}",
|
||||
html_content=page_html,
|
||||
|
||||
backlinks=the_page.collect_backlinks(),
|
||||
keywords=the_page.collect_keywords().all(),
|
||||
))
|
||||
#+end_src
|
||||
|
||||
** NEXT sitemap
|
||||
|
@ -443,31 +500,331 @@ async def feed(request, key):
|
|||
return HttpResponse(f"feed for {the_feed.file.path}")
|
||||
#+end_src
|
||||
|
||||
** NEXT admin
|
||||
** Per-Site link color CSS endpoint
|
||||
|
||||
dont worry too much about these;
|
||||
they are just used to validate that the data is ingested properly, to be honest.
|
||||
This endpoint generates a dynamic CSS file that colorizes internal URLs based on the [[id:20231229T164611.256424][The Arcology's Site List]].
|
||||
|
||||
#+begin_src python :tangle arcology/admin.py
|
||||
from django.contrib import admin
|
||||
import arcology.models
|
||||
|
||||
|
||||
class DomainInline(admin.TabularInline):
|
||||
model = arcology.models.SiteDomain
|
||||
|
||||
|
||||
@admin.register(arcology.models.Site)
|
||||
class SiteAdmin(admin.ModelAdmin):
|
||||
inlines = [DomainInline]
|
||||
|
||||
|
||||
@admin.register(arcology.models.Page)
|
||||
class PageAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
@admin.register(arcology.models.Feed)
|
||||
class FeedAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
#+begin_src python :tangle arcology/views.py
|
||||
def site_css(request):
|
||||
sites = Site.objects.all()
|
||||
stanzas = []
|
||||
for site in sites:
|
||||
for domain in site.sitedomain_set.all():
|
||||
stanzas.append(f'''
|
||||
a[href*="{domain.domain}"] {{
|
||||
border-radius: 0.25em;
|
||||
padding: 0.1em;
|
||||
background-color: {site.link_color}66;
|
||||
}}
|
||||
a[href*="{domain.domain}"]:hover {{
|
||||
background-color: {site.link_color}FF !important;
|
||||
}}
|
||||
''')
|
||||
stanzas.append(f'''
|
||||
a[href*="/404"] {{
|
||||
color: var(--alert);
|
||||
text-decoration: line-through;
|
||||
}}
|
||||
a[href*="/404"]::after {{
|
||||
content: " ⚠";
|
||||
}}
|
||||
a[href*="/404"]::before {{
|
||||
content: "⚠ ";
|
||||
}}
|
||||
''')
|
||||
return HttpResponse(stanzas, content_type="text/css")
|
||||
#+end_src
|
||||
|
||||
** Templates
|
||||
|
||||
Okay, now comes the fun part; we have HTML rendering of the org pages themselves working, now to put them on a page looking slick. Idk what to do here; I kind of want to just Tufte-CSS-ify this thing, while still maintaining subtle color-themeing and my typographic choices. Oughta just try to sketch this out first, but I'm gonna just set up the scaffolding for injecting Site specific variables and a basic HTML template that the org docs can be dropped in to.
|
||||
|
||||
for now it's largely lifted from [[id:arcology/fastapi/base.html.j2][Base HTML Template]] and [[id:arcology/fastapi/page.html.j2][Page HTML Templates]] from the FastAPI prototype.
|
||||
|
||||
#+begin_src jinja2 :tangle arcology/templates/arcology/app.html :mkdirp yes
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{% load static %}
|
||||
<link rel="stylesheet" href="{% static 'arcology/css/app.css' %}"/>
|
||||
<link rel="stylesheet" href="{% static 'arcology/css/vulf.css' %}"/>
|
||||
<link rel="stylesheet" href="{% static 'arcology/css/default-colors.css' %}"/>
|
||||
<link rel="stylesheet" href="{% url 'site-css' %}"/>
|
||||
{% if site and site.css_file %}
|
||||
<link rel="stylesheet" href="{% static site.css_file %}"/>
|
||||
{% endif %}
|
||||
<meta name="author" content="Ryan Rix"/>
|
||||
<meta name="generator" content="Arcology Site Engine https://engine.arcology.garden/"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}{{head_title | default:"The Arcology Project" }}{% endblock %}</title>
|
||||
{% block extra_head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="header-content">
|
||||
{% block h1 %}
|
||||
<h1><a href='/'>{{ site.title }}</a></h1>
|
||||
<h2>{{ page.title }}</h2>
|
||||
{% endblock %}
|
||||
<div>
|
||||
• <a class="internal" href="https://thelionsrear.com">Life</a>
|
||||
• <a class="internal" href="https://arcology.garden">Tech</a>
|
||||
• <a class="internal" href="https://cce.whatthefuck.computer">Emacs</a>
|
||||
• <a class="internal" href="https://engine.arcology.garden">Arcology</a>
|
||||
•
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<hr/>
|
||||
© 02023 <a href="https://arcology.garden/people/rrix">Ryan Rix</a> <<a href="mailto:site@whatthefuck.computer">site@whatthefuck.computer</a>>
|
||||
|
||||
<br/>
|
||||
|
||||
<p>
|
||||
Care has been taken to publish accurate information to
|
||||
long-lived URLs, but context and content as well as URLs may
|
||||
change without notice.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This site collects no personal information from visitors, nor
|
||||
stores any identifying tokens. If you or your personal
|
||||
information ended up in public notes please email me for
|
||||
correction or removal. A single bit cookie may be stored on
|
||||
your device if you choose to change appearance settings below.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Email me with questions, comments, insights, kind criticism.
|
||||
blow horn, good luck.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="/sitemap/">View the Site Map</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="https://fediring.net/previous?host=arcology.garden">←</a>
|
||||
<a href="https://fediring.net/">Fediring</a>
|
||||
<a href="https://fediring.net/next?host=arcology.garden">→</a>
|
||||
</p>
|
||||
|
||||
<!--
|
||||
<p>
|
||||
<input type="checkbox" id="boredom-mode"><label for="boredom-mode">I do not like your aesthetic sensibilities!!</label>
|
||||
</p>
|
||||
|
||||
<script type="text/javascript">
|
||||
<<boredom>>
|
||||
</script>
|
||||
-->
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
#+end_src
|
||||
|
||||
#+begin_src jinja2 :tangle arcology/templates/arcology/page.html
|
||||
{% extends "arcology/app.html" %}
|
||||
|
||||
{% block title %}{{ head_title }}{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{% for feed in feeds %}
|
||||
<link rel="alternate" type="application/atom+xml" href="{{ feed.url }}" title="{{ feed.title }}" />
|
||||
{% endfor %}
|
||||
{% if page.allow_crawl is none or page.allow_crawl is '"nil"' %}
|
||||
<meta name="robots" content="noarchive noimageindex noindex nofollow"/>
|
||||
{% else %}
|
||||
<meta name="robots" content=""/>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ html_content | safe }}
|
||||
|
||||
<section class="sidebar">
|
||||
<div class="backlinks">
|
||||
<h3>Pages Linking Here</h3>
|
||||
<ul class="backlinks">
|
||||
{% for backlink in backlinks %}
|
||||
<li>{{ backlink.to_backlink_html|safe }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="keywords">
|
||||
<h3>Page Metadata Keywords</h3>
|
||||
<ul class="keywords">
|
||||
{% for keyword in keywords %}
|
||||
<li><pre>{{ keyword.keyword }} = {{ keyword.value }}</pre></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
#+end_src
|
||||
|
||||
*** CSS
|
||||
:PROPERTIES:
|
||||
:ID: 20231229T164608.815737
|
||||
:END:
|
||||
|
||||
this will be extended.
|
||||
|
||||
rather than using emoji for each site, it would be nice to subtly color them based on the link_color... will need to Do Some Bullshit to make that work though maybe.
|
||||
|
||||
#+begin_src css :tangle static/arcology/css/app.css :mkdirp yes
|
||||
body {
|
||||
font-family: "Vulf Mono", monospace;
|
||||
font-style: italic;
|
||||
font-size: medium;
|
||||
background-color: var(--white);
|
||||
color: var(--black);
|
||||
margin: 0;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src css :tangle static/arcology/css/app.css :mkdirp yes
|
||||
header {
|
||||
background-color: var(--light-gray);
|
||||
border-radius: 0.25em;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
header > .header-content {
|
||||
padding: 1em;
|
||||
max-width: 120ch;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
header h1, header h2 {
|
||||
margin-top: 0;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
header h2:before {
|
||||
content: " — ";
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src css :tangle static/arcology/css/app.css :mkdirp yes
|
||||
.content {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 1em;
|
||||
padding-top: 0;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
max-width: 120ch;
|
||||
}
|
||||
|
||||
.content > section, main {
|
||||
display: inline-block;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
flex-basis: 40em;
|
||||
padding: 1em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.content > section.sidebar {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
flex-basis: 30ch;
|
||||
}
|
||||
|
||||
section.sidebar {
|
||||
display: flex;
|
||||
flex-flow: column wrap;
|
||||
}
|
||||
|
||||
section.sidebar > div.backlinks {
|
||||
flex-grow: 1;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_src css :tangle static/arcology/css/app.css :mkdirp yes
|
||||
footer {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 120ch;
|
||||
font-size: smaller;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
footer a {
|
||||
font-weight: 500;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
Some [[https://medium.com/@massimo.cassandro/flexbox-separators-b284d6d7b747][hacks]].
|
||||
|
||||
#+begin_src css :tangle static/arcology/css/app.css :mkdirp yes
|
||||
.content::before {
|
||||
align-self: stretch;
|
||||
content: '';
|
||||
border: 1px dotted var(--medium-gray);
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.content > *:first-child {
|
||||
order: -1;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
a::visited {
|
||||
color: var(--secondary);
|
||||
}
|
||||
#+end_src
|
||||
|
||||
There are per-site CSS in [[id:20231229T164611.256424][The Arcology's Site List]].
|
||||
|
||||
*** Generataing =@font-face= rules for a bunch of fonts
|
||||
|
||||
[[id:cce/vulfpeck_fonts_are_fun][Vulfpeck Fonts]] are pulled in with this code-gen because writing =@font-face= rules does not bring joy and I don't have the right to redistribute these files, so I won't check it in at all.
|
||||
|
||||
#+NAME: font-face-tbl
|
||||
| VulfSans | Regular | 500 | |
|
||||
| VulfMono | Regular | 500 | |
|
||||
| VulfSans | Bold | 800 | |
|
||||
| VulfMono | Bold | 800 | |
|
||||
| VulfSans | Italic | 500 | italic |
|
||||
| VulfMono | Italic | 500 | italic |
|
||||
| VulfSans | Bold_Italic | 800 | italic |
|
||||
| VulfMono | Bold_Italic | 800 | italic |
|
||||
| VulfSans | Light | 300 | |
|
||||
| VulfMono | Light | 300 | |
|
||||
| VulfSans | Light_Italic | 500 | italic |
|
||||
| VulfMono | Light_Italic | 500 | italic |
|
||||
|
||||
#+NAME: gen_font_faces
|
||||
#+begin_src elisp :var tbl=font-face-tbl :results none
|
||||
(with-temp-buffer
|
||||
(-map (pcase-lambda (`(,first ,second ,weight ,style))
|
||||
(insert
|
||||
(s-join "\n" (list
|
||||
"@font-face {"
|
||||
"font-family: " (if (equal first "VulfMono")
|
||||
"\"Vulf Mono\""
|
||||
"\"Vulf Sans\"")
|
||||
"; src:"
|
||||
(concat "url('/static/arcology/fonts/" first "-" second ".woff') format('woff'),")
|
||||
(concat "url('/static/arcology/fonts/" first "-" second ".woff2') format('woff2'),")
|
||||
(concat "url('/static/arcology/fonts/" first "-" second ".ttf') format('truetype');")
|
||||
"font-weight: " (number-to-string weight) ";"
|
||||
(unless (equal style "")
|
||||
(concat "font-style: " style ";"))
|
||||
"}"))))
|
||||
tbl)
|
||||
(write-file "~/org/arcology-django/static/arcology/css/vulf.css"))
|
||||
#+end_src
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# [[file:../arcology.org::*Data Models for routing to org-roam pages][Data Models for routing to org-roam pages:1]]
|
||||
from __future__ import annotations
|
||||
from typing import Optional
|
||||
from typing import Optional, List
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
|
||||
|
@ -71,29 +71,42 @@ class Page(models.Model):
|
|||
title = models.CharField(max_length=512)
|
||||
allow_crawl = models.BooleanField(default=False)
|
||||
|
||||
def urlize_self(self):
|
||||
site = self.site
|
||||
return site.urlize_page(self)
|
||||
|
||||
|
||||
def collect_keywords(self):
|
||||
return self.file.keyword_set
|
||||
|
||||
|
||||
def collect_links(self):
|
||||
link_objs = self.file.outbound_links.all()
|
||||
ret = dict()
|
||||
for el in link_objs:
|
||||
try:
|
||||
h = el.dest_heading
|
||||
page = h.path.page_set.first()
|
||||
site = page.site
|
||||
link = site.urlize_page(page)
|
||||
ret[h.node_id] = link
|
||||
logger.info(f"link {link} from {el}")
|
||||
url = h.to_url()
|
||||
ret[h.node_id] = url
|
||||
logger.info(f"link {url} from {el}")
|
||||
except roam.models.Heading.DoesNotExist:
|
||||
logger.info(f"{el} does not have dest")
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def collect_backlinks(self) -> List[Link]:
|
||||
my_headings = self.file.heading_set.all()
|
||||
return set(roam.models.Link.objects.filter(dest_heading__in=my_headings))
|
||||
|
||||
|
||||
def to_html(self, links):
|
||||
opts = native.ExportOptions(
|
||||
link_retargets=links
|
||||
)
|
||||
return native.htmlize_file(self.file.path, opts)
|
||||
|
||||
|
||||
@classmethod
|
||||
def create_from_arroyo(cls, doc: native.Document) -> Page:
|
||||
f = roam.models.File.objects.get(path=doc.path)
|
||||
|
|
|
@ -151,6 +151,19 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||
|
||||
STATIC_URL = "/static/"
|
||||
|
||||
STORAGES = {
|
||||
"default": {
|
||||
"BACKEND": "django.core.files.storage.FileSystemStorage",
|
||||
},
|
||||
"staticfiles": {
|
||||
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
|
||||
},
|
||||
}
|
||||
STATICFILES_DIRS = [
|
||||
BASE_DIR / "arcology" / "static",
|
||||
BASE_DIR / "static",
|
||||
]
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
[{"title":"The Lion's Rear","key":"lionsrear","css_file":"lionsrear.css","link_color":"#87af87","domains":["thelionsrear.com","rix.si"]},{"title":"The Arcology Garden","key":"garden","css_file":"garden.css","link_color":"#a6dc68","domains":["arcology.garden","whatthefuck.computer"]},{"title":"The Complete Computer","key":"cce","css_file":"cce.css","link_color":"#cc9660","domains":["cce.whatthefuck.computer","cce.rix.si"]},{"title":"The Arcology Site Engine","key":"arcology","css_file":"arcology.css","link_color":"#67b4f8","domains":["engine.arcology.garden"]},{"title":"Local Dev Environment","key":"localhost","css_file":"arcology.css","link_color":"#67b4f8","domains":["127.0.0.1:8000","localhost:8000"]}]
|
||||
[{"title":"The Lion's Rear","key":"lionsrear","css_file":"arcology/css/lionsrear.css","link_color":"#006f00","domains":["thelionsrear.com","rix.si"]},{"title":"The Arcology Garden","key":"garden","css_file":"arcology/css/garden.css","link_color":"#444fcf","domains":["arcology.garden","whatthefuck.computer"]},{"title":"The Complete Computer","key":"cce","css_file":"arcology/css/cce.css","link_color":"#dd0020","domains":["cce.whatthefuck.computer","cce.rix.si"]},{"title":"The Arcology Site Engine","key":"arcology","css_file":"arcology/css/arcology.css","link_color":"#8448aa","domains":["engine.arcology.garden"]},{"title":"Local Dev Environment","key":"localhost","css_file":"arcology/css/arcology.css","link_color":"#075192","domains":["127.0.0.1:8000","localhost:8000"]}]
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
{# [[file:../../../arcology.org::*Templates][Templates:1]] #}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{% load static %}
|
||||
<link rel="stylesheet" href="{% static 'arcology/css/app.css' %}"/>
|
||||
<link rel="stylesheet" href="{% static 'arcology/css/vulf.css' %}"/>
|
||||
<link rel="stylesheet" href="{% static 'arcology/css/default-colors.css' %}"/>
|
||||
<link rel="stylesheet" href="{% url 'site-css' %}"/>
|
||||
{% if site and site.css_file %}
|
||||
<link rel="stylesheet" href="{% static site.css_file %}"/>
|
||||
{% endif %}
|
||||
<meta name="author" content="Ryan Rix"/>
|
||||
<meta name="generator" content="Arcology Site Engine https://engine.arcology.garden/"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}{{head_title | default:"The Arcology Project" }}{% endblock %}</title>
|
||||
{% block extra_head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="header-content">
|
||||
{% block h1 %}
|
||||
<h1><a href='/'>{{ site.title }}</a></h1>
|
||||
<h2>{{ page.title }}</h2>
|
||||
{% endblock %}
|
||||
<div>
|
||||
• <a class="internal" href="https://thelionsrear.com">Life</a>
|
||||
• <a class="internal" href="https://arcology.garden">Tech</a>
|
||||
• <a class="internal" href="https://cce.whatthefuck.computer">Emacs</a>
|
||||
• <a class="internal" href="https://engine.arcology.garden">Arcology</a>
|
||||
•
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<hr/>
|
||||
© 02023 <a href="https://arcology.garden/people/rrix">Ryan Rix</a> <<a href="mailto:site@whatthefuck.computer">site@whatthefuck.computer</a>>
|
||||
|
||||
<br/>
|
||||
|
||||
<p>
|
||||
Care has been taken to publish accurate information to
|
||||
long-lived URLs, but context and content as well as URLs may
|
||||
change without notice.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This site collects no personal information from visitors, nor
|
||||
stores any identifying tokens. If you or your personal
|
||||
information ended up in public notes please email me for
|
||||
correction or removal. A single bit cookie may be stored on
|
||||
your device if you choose to change appearance settings below.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Email me with questions, comments, insights, kind criticism.
|
||||
blow horn, good luck.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="/sitemap/">View the Site Map</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="https://fediring.net/previous?host=arcology.garden">←</a>
|
||||
<a href="https://fediring.net/">Fediring</a>
|
||||
<a href="https://fediring.net/next?host=arcology.garden">→</a>
|
||||
</p>
|
||||
|
||||
<!--
|
||||
<p>
|
||||
<input type="checkbox" id="boredom-mode"><label for="boredom-mode">I do not like your aesthetic sensibilities!!</label>
|
||||
</p>
|
||||
|
||||
<script type="text/javascript">
|
||||
<<boredom>>
|
||||
</script>
|
||||
-->
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
{# Templates:1 ends here #}
|
|
@ -0,0 +1,40 @@
|
|||
{# [[file:../../../arcology.org::*Templates][Templates:2]] #}
|
||||
{% extends "arcology/app.html" %}
|
||||
|
||||
{% block title %}{{ head_title }}{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{% for feed in feeds %}
|
||||
<link rel="alternate" type="application/atom+xml" href="{{ feed.url }}" title="{{ feed.title }}" />
|
||||
{% endfor %}
|
||||
{% if page.allow_crawl is none or page.allow_crawl is '"nil"' %}
|
||||
<meta name="robots" content="noarchive noimageindex noindex nofollow"/>
|
||||
{% else %}
|
||||
<meta name="robots" content=""/>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ html_content | safe }}
|
||||
|
||||
<section class="sidebar">
|
||||
<div class="backlinks">
|
||||
<h3>Pages Linking Here</h3>
|
||||
<ul class="backlinks">
|
||||
{% for backlink in backlinks %}
|
||||
<li>{{ backlink.to_backlink_html|safe }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="keywords">
|
||||
<h3>Page Metadata Keywords</h3>
|
||||
<ul class="keywords">
|
||||
{% for keyword in keywords %}
|
||||
<li><pre>{{ keyword.keyword }} = {{ keyword.value }}</pre></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
{# Templates:2 ends here #}
|
|
@ -7,9 +7,10 @@ from arcology import views
|
|||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("", views.index),
|
||||
path("sitemap", views.sitemap),
|
||||
path("sitemap", views.sitemap, name="sitemap"),
|
||||
path("sites.css", views.site_css, name="site-css"),
|
||||
# ensure these ones are last because they're greedy!
|
||||
re_path("(?P<key>[0-9a-zA-Z/_\-]+\.xml)", views.feed),
|
||||
re_path("(?P<key>[0-9a-zA-Z/_\-]+)", views.org_page),
|
||||
re_path("(?P<key>[0-9a-zA-Z/_\-]+\.xml)", views.feed, name="feed"),
|
||||
re_path("(?P<key>[0-9a-zA-Z/_\-]+)", views.org_page, name="org-page"),
|
||||
]
|
||||
# the web server:1 ends here
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# [[file:../arcology.org::*the web server][the web server:2]]
|
||||
import logging
|
||||
from django.http import HttpResponse, HttpResponseNotFound
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
|
||||
from arcology.models import Page, Feed, Site
|
||||
from roam.models import Link
|
||||
|
@ -22,14 +23,27 @@ def org_page(request, key):
|
|||
site = Site.from_request(request)
|
||||
if site.key == "localhost":
|
||||
full_key = key
|
||||
new_site_key = key.split("/")[0]
|
||||
site = Site.objects.filter(key=new_site_key).first()
|
||||
else:
|
||||
full_key = f"{site.key}/{key}"
|
||||
|
||||
the_page = Page.objects.get(route_key=full_key)
|
||||
the_page = get_object_or_404(Page, route_key=full_key)
|
||||
links = the_page.collect_links()
|
||||
|
||||
page_html = the_page.to_html(links)
|
||||
return HttpResponse(page_html)
|
||||
|
||||
logger.warn(site)
|
||||
|
||||
return render(request, "arcology/page.html", dict(
|
||||
site=site,
|
||||
page=the_page,
|
||||
|
||||
head_title=f"{the_page.title} - {site.title}",
|
||||
html_content=page_html,
|
||||
|
||||
backlinks=the_page.collect_backlinks(),
|
||||
keywords=the_page.collect_keywords().all(),
|
||||
))
|
||||
# org-page:1 ends here
|
||||
|
||||
# [[file:../arcology.org::*sitemap][sitemap:1]]
|
||||
|
@ -46,3 +60,34 @@ async def feed(request, key):
|
|||
the_feed = Feed.objects.get(route_key=full_key)
|
||||
return HttpResponse(f"feed for {the_feed.file.path}")
|
||||
# feed:1 ends here
|
||||
|
||||
# [[file:../arcology.org::*Per-Site link color CSS endpoint][Per-Site link color CSS endpoint:1]]
|
||||
def site_css(request):
|
||||
sites = Site.objects.all()
|
||||
stanzas = []
|
||||
for site in sites:
|
||||
for domain in site.sitedomain_set.all():
|
||||
stanzas.append(f'''
|
||||
a[href*="{domain.domain}"] {{
|
||||
border-radius: 0.25em;
|
||||
padding: 0.1em;
|
||||
background-color: {site.link_color}66;
|
||||
}}
|
||||
a[href*="{domain.domain}"]:hover {{
|
||||
background-color: {site.link_color}FF !important;
|
||||
}}
|
||||
''')
|
||||
stanzas.append(f'''
|
||||
a[href*="/404"] {{
|
||||
color: var(--alert);
|
||||
text-decoration: line-through;
|
||||
}}
|
||||
a[href*="/404"]::after {{
|
||||
content: " ⚠";
|
||||
}}
|
||||
a[href*="/404"]::before {{
|
||||
content: "⚠ ";
|
||||
}}
|
||||
''')
|
||||
return HttpResponse(stanzas, content_type="text/css")
|
||||
# Per-Site link color CSS endpoint:1 ends here
|
||||
|
|
|
@ -9,18 +9,21 @@
|
|||
|
||||
user-configuration ; these could be generated from org tables if i'm feeling like a proper sicko. They should at least be much more legible but that's true of all the code i'm pulling in here..
|
||||
|
||||
* The Site List
|
||||
* The Arcology's Site List
|
||||
:PROPERTIES:
|
||||
:ID: 20231229T164611.256424
|
||||
:END:
|
||||
|
||||
These can be customized by the user:
|
||||
|
||||
#+NAME: sites-config
|
||||
| title | key | css file | link color |
|
||||
|--------------------------+-----------+---------------+------------|
|
||||
| The Lion's Rear | lionsrear | lionsrear.css | #87af87 |
|
||||
| The Arcology Garden | garden | garden.css | #a6dc68 |
|
||||
| The Complete Computer | cce | cce.css | #cc9660 |
|
||||
| The Arcology Site Engine | arcology | arcology.css | #67b4f8 |
|
||||
| Local Dev Environment | localhost | arcology.css | #67b4f8 |
|
||||
| The Lion's Rear | lionsrear | lionsrear.css | #006f00 |
|
||||
| The Arcology Garden | garden | garden.css | #444fcf |
|
||||
| The Complete Computer | cce | cce.css | #dd0020 |
|
||||
| The Arcology Site Engine | arcology | arcology.css | #8448aa |
|
||||
| Local Dev Environment | localhost | arcology.css | #075192 |
|
||||
|
||||
#+NAME: domains-config
|
||||
| key | domain |
|
||||
|
@ -44,7 +47,7 @@ Oh we doing some code gen in here, this is just gonna generate some JSON for now
|
|||
(pcase-let* ((`(,title ,key ,css ,link) siterow))
|
||||
`((title . ,title)
|
||||
(key . ,key)
|
||||
(css_file . ,css)
|
||||
(css_file . ,(format "arcology/css/%s" css))
|
||||
(link_color . ,link)
|
||||
(domains . ,(-map #'cadr
|
||||
(-filter (pcase-lambda (`(,dkey ,domain))
|
||||
|
@ -59,6 +62,62 @@ That generates JSON that goes in to =arcology/settings/sites.json= for the [[id:
|
|||
<<elisp-join-tables()>>
|
||||
#+end_src
|
||||
|
||||
** NEXT How to re-seed these if you change the configuration?
|
||||
** Per-site CSS
|
||||
|
||||
These are generated from a table, too, because I have brainworms.
|
||||
Note that they're basically the same, but you can customize it further to your satisfaction.
|
||||
|
||||
#+NAME: site-colors
|
||||
| Site | alert | primary | secondary | success | warning | white | gray2 | gray3 | gray4 | black |
|
||||
|----------------+---------+---------+-----------+---------+---------+---------+---------+---------+---------+---------|
|
||||
| default-colors | #cc6960 | #707231 | #ebbe7b | #67b4f8 | #7e5c41 | #fcf6ed | #f6e5cb | #baad9b | #82796c | #211f1c |
|
||||
| garden | #cc6960 | #707231 | #ebbe7b | #67b4f8 | #7e5c41 | #fcf6ed | #f6e5cb | #baad9b | #82796c | #211f1c |
|
||||
| lionsrear | #cc6960 | #707231 | #ebbe7b | #67b4f8 | #7e5c41 | #cfdcc2 | #87af87 | #a0aa96 | #82796c | #211f1c |
|
||||
| cce | #cc6960 | #707231 | #ebbe7b | #67b4f8 | #7e5c41 | #fcfcfc | #dcdcec | #cacada | #808090 | #211f1c |
|
||||
| arcology | #cc6960 | #707231 | #ebbe7b | #67b4f8 | #7e5c41 | #fcf6ed | #f6e5cb | #baad9b | #82796c | #211f1c |
|
||||
|
||||
#+NAME: mk-site-colors
|
||||
#+begin_src emacs-lisp :var colors=site-colors :var site="default-colors" :results none
|
||||
(pcase-let ((`((,name ,alert ,primary ,secondary ,success ,warning ,white ,gray2 ,gray3 , gray4 ,black))
|
||||
(-filter (lambda (row)
|
||||
(equal (first row) site))
|
||||
colors)))
|
||||
(s-join "\n"
|
||||
(list ":root {"
|
||||
(concat " --alert: " alert ";")
|
||||
(concat " --primary: " primary ";")
|
||||
(concat " --secondary: " secondary ";")
|
||||
(concat " --success: " success ";")
|
||||
(concat " --warning: " warning ";")
|
||||
(concat " --white: " white ";")
|
||||
(concat " --light-gray: " gray2 ";")
|
||||
(concat " --medium-gray: " gray3 ";")
|
||||
(concat " --dark-gray: " gray4 ";")
|
||||
(concat " --black: " black ";")
|
||||
"}")))
|
||||
#+end_src
|
||||
|
||||
#+begin_src css :tangle static/arcology/css/default-colors.css :noweb yes
|
||||
<<mk-site-colors(site-colors, "default-colors")>>
|
||||
#+end_src
|
||||
|
||||
#+begin_src css :tangle static/arcology/css/cce.css :noweb yes
|
||||
<<mk-site-colors(site-colors, "cce")>>
|
||||
#+end_src
|
||||
|
||||
#+begin_src css :tangle static/arcology/css/lionsrear.css :noweb yes
|
||||
<<mk-site-colors(site-colors, "lionsrear")>>
|
||||
#+end_src
|
||||
|
||||
#+begin_src css :tangle static/arcology/css/garden.css :noweb yes
|
||||
<<mk-site-colors(site-colors, "garden")>>
|
||||
#+end_src
|
||||
|
||||
#+begin_src css :tangle static/arcology/css/arcology.css :noweb yes
|
||||
<<mk-site-colors(site-colors, "arcology")>>
|
||||
#+end_src
|
||||
|
||||
* Service Configuration
|
||||
:PROPERTIES:
|
||||
:ID: 20231217T155611.177995
|
||||
|
@ -372,6 +431,19 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||
|
||||
STATIC_URL = "/static/"
|
||||
|
||||
STORAGES = {
|
||||
"default": {
|
||||
"BACKEND": "django.core.files.storage.FileSystemStorage",
|
||||
},
|
||||
"staticfiles": {
|
||||
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
|
||||
},
|
||||
}
|
||||
STATICFILES_DIRS = [
|
||||
BASE_DIR / "arcology" / "static",
|
||||
BASE_DIR / "static",
|
||||
]
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
|
||||
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1703734847,
|
||||
"lastModified": 1703908423,
|
||||
"narHash": "sha256-55zlSQULXCmUf88tPSGc/g7RiYnuCo14eaP1kcA6V00=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "f7f944d0afb9b790cbc33bf023a1ca4cbcc0b134",
|
||||
"revCount": 127,
|
||||
"rev": "26a7bfe085b01fff19b287191e4f2b989d363667",
|
||||
"revCount": 129,
|
||||
"type": "git",
|
||||
"url": "https://code.rix.si/rrix/arroyo"
|
||||
},
|
||||
|
|
21
roam.org
21
roam.org
|
@ -118,6 +118,15 @@ class Heading(models.Model):
|
|||
through_fields=("dest_heading", "source_heading"),
|
||||
)
|
||||
|
||||
def to_url(self) -> str:
|
||||
page = self.path.page_set.first()
|
||||
page_url = page.urlize_self()
|
||||
if self.level == 0:
|
||||
return page_url
|
||||
else:
|
||||
return f"{page_url}#{self.node_id}"
|
||||
|
||||
|
||||
@classmethod
|
||||
def create_from_arroyo(cls, doc: native.Document) -> List[Heading]:
|
||||
return [
|
||||
|
@ -213,6 +222,18 @@ class Link(models.Model):
|
|||
to_field="node_id",
|
||||
)
|
||||
|
||||
def to_backlink_html(self) -> str:
|
||||
try:
|
||||
h = self.source_heading
|
||||
page = h.path.page_set.first()
|
||||
url = h.to_url()
|
||||
title = page.title
|
||||
return f'''<a class="internal" href="{url}">{title}</a>'''
|
||||
except Heading.DoesNotExist:
|
||||
logger.info(f"{self} does not have dest heading.")
|
||||
return f'''<a class="dead-link" href="/404?text={self.title|iriencode}">{self.title}</a>'''
|
||||
|
||||
|
||||
@classmethod
|
||||
def create_from_arroyo(cls, doc: native.Document) -> List[Link]:
|
||||
ret = []
|
||||
|
|
|
@ -98,6 +98,15 @@ class Heading(models.Model):
|
|||
through_fields=("dest_heading", "source_heading"),
|
||||
)
|
||||
|
||||
def to_url(self) -> str:
|
||||
page = self.path.page_set.first()
|
||||
page_url = page.urlize_self()
|
||||
if self.level == 0:
|
||||
return page_url
|
||||
else:
|
||||
return f"{page_url}#{self.node_id}"
|
||||
|
||||
|
||||
@classmethod
|
||||
def create_from_arroyo(cls, doc: native.Document) -> List[Heading]:
|
||||
return [
|
||||
|
@ -187,6 +196,18 @@ class Link(models.Model):
|
|||
to_field="node_id",
|
||||
)
|
||||
|
||||
def to_backlink_html(self) -> str:
|
||||
try:
|
||||
h = self.source_heading
|
||||
page = h.path.page_set.first()
|
||||
url = h.to_url()
|
||||
title = page.title
|
||||
return f'''<a class="internal" href="{url}">{title}</a>'''
|
||||
except Heading.DoesNotExist:
|
||||
logger.info(f"{self} does not have dest heading.")
|
||||
return f'''<a class="dead-link" href="/404?text={self.title|iriencode}">{self.title}</a>'''
|
||||
|
||||
|
||||
@classmethod
|
||||
def create_from_arroyo(cls, doc: native.Document) -> List[Link]:
|
||||
ret = []
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/* [[file:../../../arcology.org::*CSS][CSS:1]] */
|
||||
body {
|
||||
font-family: "Vulf Mono", monospace;
|
||||
font-style: italic;
|
||||
font-size: medium;
|
||||
background-color: var(--white);
|
||||
color: var(--black);
|
||||
margin: 0;
|
||||
}
|
||||
/* CSS:1 ends here */
|
||||
|
||||
/* [[file:../../../arcology.org::*CSS][CSS:2]] */
|
||||
header {
|
||||
background-color: var(--light-gray);
|
||||
border-radius: 0.25em;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
header > .header-content {
|
||||
padding: 1em;
|
||||
max-width: 120ch;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
header h1, header h2 {
|
||||
margin-top: 0;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
header h2:before {
|
||||
content: " — ";
|
||||
}
|
||||
/* CSS:2 ends here */
|
||||
|
||||
/* [[file:../../../arcology.org::*CSS][CSS:3]] */
|
||||
.content {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 1em;
|
||||
padding-top: 0;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
max-width: 120ch;
|
||||
}
|
||||
|
||||
.content > section, main {
|
||||
display: inline-block;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
flex-basis: 40em;
|
||||
padding: 1em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.content > section.sidebar {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
flex-basis: 30ch;
|
||||
}
|
||||
|
||||
section.sidebar {
|
||||
display: flex;
|
||||
flex-flow: column wrap;
|
||||
}
|
||||
|
||||
section.sidebar > div.backlinks {
|
||||
flex-grow: 1;
|
||||
}
|
||||
/* CSS:3 ends here */
|
||||
|
||||
/* [[file:../../../arcology.org::*CSS][CSS:4]] */
|
||||
footer {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 120ch;
|
||||
font-size: smaller;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
footer a {
|
||||
font-weight: 500;
|
||||
}
|
||||
/* CSS:4 ends here */
|
||||
|
||||
/* [[file:../../../arcology.org::*CSS][CSS:5]] */
|
||||
.content::before {
|
||||
align-self: stretch;
|
||||
content: '';
|
||||
border: 1px dotted var(--medium-gray);
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.content > *:first-child {
|
||||
order: -1;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
a::visited {
|
||||
color: var(--secondary);
|
||||
}
|
||||
/* CSS:5 ends here */
|
|
@ -0,0 +1,14 @@
|
|||
/* [[file:../../../configuration.org::*Per-site CSS][Per-site CSS:6]] */
|
||||
:root {
|
||||
--alert: #cc6960;
|
||||
--primary: #707231;
|
||||
--secondary: #ebbe7b;
|
||||
--success: #67b4f8;
|
||||
--warning: #7e5c41;
|
||||
--white: #fcf6ed;
|
||||
--light-gray: #f6e5cb;
|
||||
--medium-gray: #baad9b;
|
||||
--dark-gray: #82796c;
|
||||
--black: #211f1c;
|
||||
}
|
||||
/* Per-site CSS:6 ends here */
|
|
@ -0,0 +1,14 @@
|
|||
/* [[file:../../../configuration.org::*Per-site CSS][Per-site CSS:3]] */
|
||||
:root {
|
||||
--alert: #cc6960;
|
||||
--primary: #707231;
|
||||
--secondary: #ebbe7b;
|
||||
--success: #67b4f8;
|
||||
--warning: #7e5c41;
|
||||
--white: #fcfcfc;
|
||||
--light-gray: #dcdcec;
|
||||
--medium-gray: #cacada;
|
||||
--dark-gray: #808090;
|
||||
--black: #211f1c;
|
||||
}
|
||||
/* Per-site CSS:3 ends here */
|
|
@ -0,0 +1,14 @@
|
|||
/* [[file:../../../configuration.org::*Per-site CSS][Per-site CSS:2]] */
|
||||
:root {
|
||||
--alert: #cc6960;
|
||||
--primary: #707231;
|
||||
--secondary: #ebbe7b;
|
||||
--success: #67b4f8;
|
||||
--warning: #7e5c41;
|
||||
--white: #fcf6ed;
|
||||
--light-gray: #f6e5cb;
|
||||
--medium-gray: #baad9b;
|
||||
--dark-gray: #82796c;
|
||||
--black: #211f1c;
|
||||
}
|
||||
/* Per-site CSS:2 ends here */
|
|
@ -0,0 +1,14 @@
|
|||
/* [[file:../../../configuration.org::*Per-site CSS][Per-site CSS:5]] */
|
||||
:root {
|
||||
--alert: #cc6960;
|
||||
--primary: #707231;
|
||||
--secondary: #ebbe7b;
|
||||
--success: #67b4f8;
|
||||
--warning: #7e5c41;
|
||||
--white: #fcf6ed;
|
||||
--light-gray: #f6e5cb;
|
||||
--medium-gray: #baad9b;
|
||||
--dark-gray: #82796c;
|
||||
--black: #211f1c;
|
||||
}
|
||||
/* Per-site CSS:5 ends here */
|
|
@ -0,0 +1,14 @@
|
|||
/* [[file:../../../configuration.org::*Per-site CSS][Per-site CSS:4]] */
|
||||
:root {
|
||||
--alert: #cc6960;
|
||||
--primary: #707231;
|
||||
--secondary: #ebbe7b;
|
||||
--success: #67b4f8;
|
||||
--warning: #7e5c41;
|
||||
--white: #cfdcc2;
|
||||
--light-gray: #87af87;
|
||||
--medium-gray: #a0aa96;
|
||||
--dark-gray: #82796c;
|
||||
--black: #211f1c;
|
||||
}
|
||||
/* Per-site CSS:4 ends here */
|
|
@ -0,0 +1,133 @@
|
|||
@font-face {
|
||||
font-family:
|
||||
"Vulf Sans"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfSans-Regular.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfSans-Regular.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfSans-Regular.ttf') format('truetype');
|
||||
font-weight:
|
||||
500
|
||||
;
|
||||
|
||||
}@font-face {
|
||||
font-family:
|
||||
"Vulf Mono"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfMono-Regular.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfMono-Regular.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfMono-Regular.ttf') format('truetype');
|
||||
font-weight:
|
||||
500
|
||||
;
|
||||
|
||||
}@font-face {
|
||||
font-family:
|
||||
"Vulf Sans"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfSans-Bold.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfSans-Bold.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfSans-Bold.ttf') format('truetype');
|
||||
font-weight:
|
||||
800
|
||||
;
|
||||
|
||||
}@font-face {
|
||||
font-family:
|
||||
"Vulf Mono"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfMono-Bold.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfMono-Bold.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfMono-Bold.ttf') format('truetype');
|
||||
font-weight:
|
||||
800
|
||||
;
|
||||
|
||||
}@font-face {
|
||||
font-family:
|
||||
"Vulf Sans"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfSans-Italic.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfSans-Italic.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfSans-Italic.ttf') format('truetype');
|
||||
font-weight:
|
||||
500
|
||||
;
|
||||
font-style: italic;
|
||||
}@font-face {
|
||||
font-family:
|
||||
"Vulf Mono"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfMono-Italic.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfMono-Italic.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfMono-Italic.ttf') format('truetype');
|
||||
font-weight:
|
||||
500
|
||||
;
|
||||
font-style: italic;
|
||||
}@font-face {
|
||||
font-family:
|
||||
"Vulf Sans"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfSans-Bold_Italic.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfSans-Bold_Italic.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfSans-Bold_Italic.ttf') format('truetype');
|
||||
font-weight:
|
||||
800
|
||||
;
|
||||
font-style: italic;
|
||||
}@font-face {
|
||||
font-family:
|
||||
"Vulf Mono"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfMono-Bold_Italic.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfMono-Bold_Italic.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfMono-Bold_Italic.ttf') format('truetype');
|
||||
font-weight:
|
||||
800
|
||||
;
|
||||
font-style: italic;
|
||||
}@font-face {
|
||||
font-family:
|
||||
"Vulf Sans"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfSans-Light.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfSans-Light.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfSans-Light.ttf') format('truetype');
|
||||
font-weight:
|
||||
300
|
||||
;
|
||||
|
||||
}@font-face {
|
||||
font-family:
|
||||
"Vulf Mono"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfMono-Light.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfMono-Light.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfMono-Light.ttf') format('truetype');
|
||||
font-weight:
|
||||
300
|
||||
;
|
||||
|
||||
}@font-face {
|
||||
font-family:
|
||||
"Vulf Sans"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfSans-Light_Italic.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfSans-Light_Italic.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfSans-Light_Italic.ttf') format('truetype');
|
||||
font-weight:
|
||||
500
|
||||
;
|
||||
font-style: italic;
|
||||
}@font-face {
|
||||
font-family:
|
||||
"Vulf Mono"
|
||||
; src:
|
||||
url('/static/arcology/fonts/VulfMono-Light_Italic.woff') format('woff'),
|
||||
url('/static/arcology/fonts/VulfMono-Light_Italic.woff2') format('woff2'),
|
||||
url('/static/arcology/fonts/VulfMono-Light_Italic.ttf') format('truetype');
|
||||
font-weight:
|
||||
500
|
||||
;
|
||||
font-style: italic;
|
||||
}
|
Loading…
Reference in New Issue