diff --git a/Dockerfile b/Dockerfile index c50d268f..60b16eac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,10 +31,9 @@ ENV PATH=${POETRY_HOME}/bin:$PATH \ PORT=8000 RUN env -# Install litestream (https://litestream.io/install/debian/) -ARG PLATFORM=amd64 -RUN wget https://github.com/benbjohnson/litestream/releases/download/v0.3.9/litestream-v0.3.9-linux-$PLATFORM.deb -RUN dpkg -i litestream-v0.3.9-linux-$PLATFORM.deb +# Install litestream +COPY ./scripts/install-litestream.sh ./scripts/ +RUN ./scripts/install-litestream.sh # Install poetry RUN curl -sSL https://install.python-poetry.org | python3 - diff --git a/README.md b/README.md index 431a913b..39bb6af6 100644 --- a/README.md +++ b/README.md @@ -134,11 +134,11 @@ Once your app is working, and you have TLS in place, you also configure: This project is using SQLite as it's database -- even in production 😱. Using SQLite is often discouraged to be used in production. -Those concerns a usually based on the abilitiy to handle multiple writes and how to backup the database. +Those concerns a usually based on the ability to handle multiple writes and how to backup the database. For container deployments on a platform as a service (such as Heroku) there is also the problem of persisting the database between container restarts. The write ability is not really an issue for this application. -Since this app is mainly a content site with few editors working simulaneously (if ever) it is much more read-heavy than write-heavy. +Since this app is mainly a content site with few editors working simultaneously (if ever), it is much more read-heavy than write-heavy. Reads are easy for SQLite to handle. The persistence problem does apply to this app though. diff --git a/docker-compose.yaml b/docker-compose.yaml index 2ddf9074..5d0c8ea0 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -3,8 +3,6 @@ services: build: context: . target: backend-development - args: - - PLATFORM=arm64 command: ["tail", "-f", "/dev/null"] env_file: - .env diff --git a/lpld/core/blocks.py b/lpld/core/blocks.py index 09ff364a..5871c72b 100644 --- a/lpld/core/blocks.py +++ b/lpld/core/blocks.py @@ -1,5 +1,6 @@ from wagtail import blocks from wagtail.admin import panels +from wagtail.templatetags import wagtailcore_tags class HeadingBlock(blocks.StructBlock): @@ -8,9 +9,15 @@ class HeadingBlock(blocks.StructBlock): panels = [panels.FieldPanel("text", classname="full")] class Meta: - template = "atoms/heading/heading-block.html" + template = "atoms/heading/heading.html" icon = "title" + def get_context(self, value, parent_context=None): + return { + "level": 2, + "children": value.get("text"), + } + class SubheadingBlock(blocks.StructBlock): text = blocks.CharBlock(required=True) @@ -18,5 +25,103 @@ class SubheadingBlock(blocks.StructBlock): panels = [panels.FieldPanel("text")] class Meta: - template = "atoms/heading/subheading-block.html" + template = "atoms/heading/heading.html" icon = "title" + + def get_context(self, value, parent_context=None): + return { + "level": 3, + "children": value.get("text"), + } + + +class PageLinkBlock(blocks.StructBlock): + page = blocks.PageChooserBlock(required=True) + text = blocks.CharBlock( + required=False, + help_text="Text for the link. Defaults to page title.", + ) + + class Meta: + icon = "doc-full" + template = "atoms/link/link.html" + + def get_context(self, value, parent_context=None): + page = value.get("page") + text = value.get("text") + return { + "text": text or page.title, + "href": page.get_url(), + } + + +class LinkStream(blocks.StreamBlock): + """ + Stream of links. + + Each item should return context objects containing the keys `"text"` and `"href"` + from their `get_context` method. + """ + + page_link = PageLinkBlock() + + class Meta: + icon = "list-ul" + template = "molecules/link-listing/link-listing.html" + min_num = 1 + + def get_context(self, value, parent_context=None): + links = [bb.block.get_context(bb.value) for bb in value] + return {"links": links} + + +class LinkBlock(LinkStream): + """ + Link stream with max 1 item. + + Can be used as a flexible link block. + """ + + class Meta: + icon = "link" + template = "atoms/link/link.html" + min_num = 1 + max_num = 1 + + def get_context(self, value, parent_context=None): + bound_block = value[0] + return bound_block.block.get_context(bound_block.value) + + +class SimpleProseRichtext(blocks.RichTextBlock): + def __init__(self, *args, **kwargs): + if "features" not in kwargs: + kwargs["features"] = ["link", "bold", "italics"] + super().__init__(*args, **kwargs) + + class Meta: + template = "organisms/prose/prose.html" + + def get_context(self, value, parent_context=None) -> dict[str, str]: + return {"children": wagtailcore_tags.richtext(value)} + + +class SectionBlock(blocks.StructBlock): + heading = HeadingBlock() + body = blocks.StreamBlock( + local_blocks=[ + ("paragraph", SimpleProseRichtext()), + ("link_list", LinkStream()), + ], + min_rum=1, + required=False, + ) + + panels = [ + panels.FieldPanel("heading"), + panels.FieldPanel("body"), + ] + + class Meta: + template = "molecules/section/section-block.html" + icon = "bars" diff --git a/lpld/core/models.py b/lpld/core/models.py index 3bb6c5a1..863df33c 100644 --- a/lpld/core/models.py +++ b/lpld/core/models.py @@ -4,8 +4,6 @@ from wagtail import models as wagtail_models from wagtail.admin import panels -from lpld.navigation import utils as nav_utils - class BasePage(wagtail_models.Page): class Meta(wagtail_models.Page.Meta): @@ -15,10 +13,22 @@ class Meta(wagtail_models.Page.Meta): def title_tag_content(self): return self.get_title_tag_content() - def get_title_tag_content(self): - title_text = self.seo_title or self.title - title_text = f"{ title_text } · lpld.io" - return title_text + def get_title_tag_content(self) -> str: + parts = self.get_title_tag_parts() + sep = self.get_title_separator() + return sep.join(parts) + + def get_title_tag_parts(self) -> list[str]: + title = self.seo_title or self.title + last = self.get_title_tag_last_part() + return [title, last] + + def get_title_tag_last_part(self) -> str: + """Return the last part for the title tag.""" + return "lpld.io" + + def get_title_separator(self) -> str: + return " · " @func_utils.cached_property def meta_description(self): @@ -27,13 +37,6 @@ def meta_description(self): def get_meta_description(self): return self.search_description or "" - def get_context(self, request): - context = super().get_context(request) - context["primary_navigation_links"] = nav_utils.get_primary_navigation_links( - request - ) - return context - class AbstractLink(models.Model): page = models.ForeignKey( diff --git a/lpld/home/migrations/0004_homepage_body.py b/lpld/home/migrations/0004_homepage_body.py new file mode 100644 index 00000000..cee2b6f4 --- /dev/null +++ b/lpld/home/migrations/0004_homepage_body.py @@ -0,0 +1,43 @@ +# Generated by Django 4.1.13 on 2024-03-09 00:37 + +from django.db import migrations + +import wagtail.blocks +import wagtail.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("home", "0003_homepage_profile_image"), + ] + + operations = [ + migrations.AddField( + model_name="homepage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "section", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.StructBlock( + [ + ( + "text", + wagtail.blocks.CharBlock(required=True), + ) + ] + ), + ) + ] + ), + ) + ], + blank=True, + use_json_field=True, + ), + ), + ] diff --git a/lpld/home/migrations/0005_homepage_subtitle_alter_homepage_body.py b/lpld/home/migrations/0005_homepage_subtitle_alter_homepage_body.py new file mode 100644 index 00000000..69e49b2e --- /dev/null +++ b/lpld/home/migrations/0005_homepage_subtitle_alter_homepage_body.py @@ -0,0 +1,90 @@ +# Generated by Django 4.1.13 on 2024-07-07 23:51 + +from django.db import migrations, models + +import wagtail.blocks +import wagtail.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("home", "0004_homepage_body"), + ] + + operations = [ + migrations.AddField( + model_name="homepage", + name="subtitle", + field=models.CharField(blank=True, max_length=50), + ), + migrations.AlterField( + model_name="homepage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "section", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.StructBlock( + [ + ( + "text", + wagtail.blocks.CharBlock(required=True), + ) + ] + ), + ), + ( + "body", + wagtail.blocks.StreamBlock( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=["link", "bold", "italics"] + ), + ), + ( + "link_list", + wagtail.blocks.StreamBlock( + [ + ( + "page_link", + wagtail.blocks.StructBlock( + [ + ( + "page", + wagtail.blocks.PageChooserBlock( + required=True + ), + ), + ( + "text", + wagtail.blocks.CharBlock( + help_text="Text for the link. Defaults to page title.", + required=False, + ), + ), + ] + ), + ) + ] + ), + ), + ], + min_rum=1, + required=False, + ), + ), + ] + ), + ) + ], + blank=True, + use_json_field=True, + ), + ), + ] diff --git a/lpld/home/migrations/0006_update_paragraph_block.py b/lpld/home/migrations/0006_update_paragraph_block.py new file mode 100644 index 00000000..da79ec65 --- /dev/null +++ b/lpld/home/migrations/0006_update_paragraph_block.py @@ -0,0 +1,85 @@ +# Generated by Django 4.1.13 on 2024-07-12 03:38 + +from django.db import migrations + +import wagtail.blocks +import wagtail.fields + +import lpld.core.blocks + + +class Migration(migrations.Migration): + dependencies = [ + ("home", "0005_homepage_subtitle_alter_homepage_body"), + ] + + operations = [ + migrations.AlterField( + model_name="homepage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "section", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.StructBlock( + [ + ( + "text", + wagtail.blocks.CharBlock(required=True), + ) + ] + ), + ), + ( + "body", + wagtail.blocks.StreamBlock( + [ + ( + "paragraph", + lpld.core.blocks.SimpleProseRichtext(), + ), + ( + "link_list", + wagtail.blocks.StreamBlock( + [ + ( + "page_link", + wagtail.blocks.StructBlock( + [ + ( + "page", + wagtail.blocks.PageChooserBlock( + required=True + ), + ), + ( + "text", + wagtail.blocks.CharBlock( + help_text="Text for the link. Defaults to page title.", + required=False, + ), + ), + ] + ), + ) + ] + ), + ), + ], + min_rum=1, + required=False, + ), + ), + ] + ), + ) + ], + blank=True, + use_json_field=True, + ), + ), + ] diff --git a/lpld/home/models.py b/lpld/home/models.py index bfa1b0a5..e85b107f 100644 --- a/lpld/home/models.py +++ b/lpld/home/models.py @@ -1,4 +1,3 @@ -from django.apps import apps from django.db import models from django.utils import html as html_utils @@ -6,6 +5,7 @@ from wagtail import images as wagtail_images from wagtail.admin import panels +from lpld.core import blocks as core_blocks from lpld.core import models as core_models @@ -15,6 +15,11 @@ class HomePage(core_models.BasePage): max_count = 1 template = "pages/home/home.html" + subtitle = models.CharField( + max_length=50, + blank=True, + null=False, + ) introduction = fields.RichTextField(features=["link"], null=True, blank=True) profile_image = models.ForeignKey( wagtail_images.get_image_model_string(), @@ -22,19 +27,24 @@ class HomePage(core_models.BasePage): blank=True, on_delete=models.SET_NULL, ) + body = fields.StreamField( + block_types=[ + ("section", core_blocks.SectionBlock()), + ], + null=False, + blank=True, + use_json_field=True, + ) content_panels = core_models.BasePage.content_panels + [ + panels.FieldPanel("subtitle"), panels.FieldPanel("introduction"), panels.FieldPanel("profile_image"), + panels.FieldPanel("body"), ] - def get_context(self, request): - context = super().get_context(request) - - ProjectPage = apps.get_model("projects", "ProjectPage") - context["projects"] = ProjectPage.objects.all() - - return context + def get_title_tag_parts(self) -> list[str]: + return [self.title, self.subtitle, self.get_title_tag_last_part()] def get_meta_description(self): return self.search_description or self.get_introduction_without_tags() or "" diff --git a/lpld/index/migrations/0002_indexpage_introduction.py b/lpld/index/migrations/0002_indexpage_introduction.py new file mode 100644 index 00000000..25d4c1a7 --- /dev/null +++ b/lpld/index/migrations/0002_indexpage_introduction.py @@ -0,0 +1,19 @@ +# Generated by Django 4.1.13 on 2024-07-18 03:57 + +from django.db import migrations + +import wagtail.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("index", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="indexpage", + name="introduction", + field=wagtail.fields.RichTextField(blank=True, max_length=500), + ), + ] diff --git a/lpld/index/models.py b/lpld/index/models.py index 55f023d2..92e4846c 100644 --- a/lpld/index/models.py +++ b/lpld/index/models.py @@ -1,12 +1,21 @@ from typing import Any +from wagtail import fields as wagtail_fields +from wagtail.admin import panels + from lpld.core import models as core_models class IndexPage(core_models.BasePage): template = "pages/index/index-page.html" parent_page_types = ["home.HomePage"] - subpage_types = ["articles.ArticlePage"] + subpage_types = ["articles.ArticlePage", "projects.ProjectPage"] + + introduction = wagtail_fields.RichTextField(max_length=500, null=False, blank=True) + + content_panels = tuple(core_models.BasePage.content_panels) + ( + panels.FieldPanel("introduction"), + ) def get_context(self, request, *args, **kwargs): context = super().get_context(request, *args, **kwargs) @@ -18,8 +27,8 @@ def get_index_entries(self) -> tuple[dict[str, Any], ...]: for child in self.get_children().live().public(): index_entries.append( { - "title": child.title, - "url": child.get_url(), + "text": child.title, + "href": child.get_url(), } ) return tuple(index_entries) diff --git a/lpld/navigation/utils.py b/lpld/navigation/utils.py index b02febda..56979f50 100644 --- a/lpld/navigation/utils.py +++ b/lpld/navigation/utils.py @@ -13,10 +13,4 @@ def get_primary_navigation_links(request): PrimaryNavigationSetting = apps.get_model("navigation.PrimaryNavigationSetting") links.extend(list(PrimaryNavigationSetting.for_request(request).links.all())) - links.extend( - [ - Link(text="Projects", href="/#projects"), - Link(text="Contact", href="#contact"), - ] - ) return links diff --git a/lpld/projects/models.py b/lpld/projects/models.py index 9810db40..54bb179e 100644 --- a/lpld/projects/models.py +++ b/lpld/projects/models.py @@ -11,7 +11,7 @@ class ProjectPage(core_models.BasePage): - parent_page_types = ["home.HomePage"] + parent_page_types = ["home.HomePage", "index.IndexPage"] template = "pages/project-page/project-page.html" image = models.ForeignKey( diff --git a/lpld/static/public/fonts/inter/Inter-Black.woff2 b/lpld/static/public/fonts/inter/Inter-Black.woff2 new file mode 100644 index 00000000..18b35db7 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-Black.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-BlackItalic.woff2 b/lpld/static/public/fonts/inter/Inter-BlackItalic.woff2 new file mode 100644 index 00000000..02c9d8ec Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-BlackItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-Bold.woff2 b/lpld/static/public/fonts/inter/Inter-Bold.woff2 new file mode 100644 index 00000000..0f1b1576 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-Bold.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-BoldItalic.woff2 b/lpld/static/public/fonts/inter/Inter-BoldItalic.woff2 new file mode 100644 index 00000000..bc50f24c Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-BoldItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-ExtraBold.woff2 b/lpld/static/public/fonts/inter/Inter-ExtraBold.woff2 new file mode 100644 index 00000000..b1133688 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-ExtraBold.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-ExtraBoldItalic.woff2 b/lpld/static/public/fonts/inter/Inter-ExtraBoldItalic.woff2 new file mode 100644 index 00000000..a5b76ca8 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-ExtraBoldItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-ExtraLight.woff2 b/lpld/static/public/fonts/inter/Inter-ExtraLight.woff2 new file mode 100644 index 00000000..1d77ae8d Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-ExtraLight.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-ExtraLightItalic.woff2 b/lpld/static/public/fonts/inter/Inter-ExtraLightItalic.woff2 new file mode 100644 index 00000000..8c684920 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-ExtraLightItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-Italic.woff2 b/lpld/static/public/fonts/inter/Inter-Italic.woff2 new file mode 100644 index 00000000..4c24ce28 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-Italic.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-Light.woff2 b/lpld/static/public/fonts/inter/Inter-Light.woff2 new file mode 100644 index 00000000..dbe61437 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-Light.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-LightItalic.woff2 b/lpld/static/public/fonts/inter/Inter-LightItalic.woff2 new file mode 100644 index 00000000..a40d0421 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-LightItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-Medium.woff2 b/lpld/static/public/fonts/inter/Inter-Medium.woff2 new file mode 100644 index 00000000..0fd2ee73 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-Medium.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-MediumItalic.woff2 b/lpld/static/public/fonts/inter/Inter-MediumItalic.woff2 new file mode 100644 index 00000000..96767155 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-MediumItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-Regular.woff2 b/lpld/static/public/fonts/inter/Inter-Regular.woff2 new file mode 100644 index 00000000..b8699af2 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-Regular.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-SemiBold.woff2 b/lpld/static/public/fonts/inter/Inter-SemiBold.woff2 new file mode 100644 index 00000000..95c48b18 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-SemiBold.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-SemiBoldItalic.woff2 b/lpld/static/public/fonts/inter/Inter-SemiBoldItalic.woff2 new file mode 100644 index 00000000..ddfe19e8 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-SemiBoldItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-Thin.woff2 b/lpld/static/public/fonts/inter/Inter-Thin.woff2 new file mode 100644 index 00000000..07909608 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-Thin.woff2 differ diff --git a/lpld/static/public/fonts/inter/Inter-ThinItalic.woff2 b/lpld/static/public/fonts/inter/Inter-ThinItalic.woff2 new file mode 100644 index 00000000..a7bf2138 Binary files /dev/null and b/lpld/static/public/fonts/inter/Inter-ThinItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-Black.woff2 b/lpld/static/public/fonts/inter/InterDisplay-Black.woff2 new file mode 100644 index 00000000..8138123c Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-Black.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-BlackItalic.woff2 b/lpld/static/public/fonts/inter/InterDisplay-BlackItalic.woff2 new file mode 100644 index 00000000..735ba21f Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-BlackItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-Bold.woff2 b/lpld/static/public/fonts/inter/InterDisplay-Bold.woff2 new file mode 100644 index 00000000..11c67196 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-Bold.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-BoldItalic.woff2 b/lpld/static/public/fonts/inter/InterDisplay-BoldItalic.woff2 new file mode 100644 index 00000000..5b6a1fb0 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-BoldItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-ExtraBold.woff2 b/lpld/static/public/fonts/inter/InterDisplay-ExtraBold.woff2 new file mode 100644 index 00000000..9058e986 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-ExtraBold.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-ExtraBoldItalic.woff2 b/lpld/static/public/fonts/inter/InterDisplay-ExtraBoldItalic.woff2 new file mode 100644 index 00000000..4cd61c06 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-ExtraBoldItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-ExtraLight.woff2 b/lpld/static/public/fonts/inter/InterDisplay-ExtraLight.woff2 new file mode 100644 index 00000000..8621b299 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-ExtraLight.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-ExtraLightItalic.woff2 b/lpld/static/public/fonts/inter/InterDisplay-ExtraLightItalic.woff2 new file mode 100644 index 00000000..689c8d9c Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-ExtraLightItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-Italic.woff2 b/lpld/static/public/fonts/inter/InterDisplay-Italic.woff2 new file mode 100644 index 00000000..11f20bc8 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-Italic.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-Light.woff2 b/lpld/static/public/fonts/inter/InterDisplay-Light.woff2 new file mode 100644 index 00000000..446301c3 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-Light.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-LightItalic.woff2 b/lpld/static/public/fonts/inter/InterDisplay-LightItalic.woff2 new file mode 100644 index 00000000..f6881961 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-LightItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-Medium.woff2 b/lpld/static/public/fonts/inter/InterDisplay-Medium.woff2 new file mode 100644 index 00000000..29160b2c Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-Medium.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-MediumItalic.woff2 b/lpld/static/public/fonts/inter/InterDisplay-MediumItalic.woff2 new file mode 100644 index 00000000..ef1bcbe3 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-MediumItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-Regular.woff2 b/lpld/static/public/fonts/inter/InterDisplay-Regular.woff2 new file mode 100644 index 00000000..a6c04f68 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-Regular.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-SemiBold.woff2 b/lpld/static/public/fonts/inter/InterDisplay-SemiBold.woff2 new file mode 100644 index 00000000..2b4db239 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-SemiBold.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-SemiBoldItalic.woff2 b/lpld/static/public/fonts/inter/InterDisplay-SemiBoldItalic.woff2 new file mode 100644 index 00000000..59091db3 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-SemiBoldItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-Thin.woff2 b/lpld/static/public/fonts/inter/InterDisplay-Thin.woff2 new file mode 100644 index 00000000..dc0b9486 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-Thin.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterDisplay-ThinItalic.woff2 b/lpld/static/public/fonts/inter/InterDisplay-ThinItalic.woff2 new file mode 100644 index 00000000..96439c0c Binary files /dev/null and b/lpld/static/public/fonts/inter/InterDisplay-ThinItalic.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterVariable-Italic.woff2 b/lpld/static/public/fonts/inter/InterVariable-Italic.woff2 new file mode 100644 index 00000000..f22ec255 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterVariable-Italic.woff2 differ diff --git a/lpld/static/public/fonts/inter/InterVariable.woff2 b/lpld/static/public/fonts/inter/InterVariable.woff2 new file mode 100644 index 00000000..22a12b04 Binary files /dev/null and b/lpld/static/public/fonts/inter/InterVariable.woff2 differ diff --git a/lpld/static/public/fonts/inter/inter.css b/lpld/static/public/fonts/inter/inter.css new file mode 100644 index 00000000..413e1976 --- /dev/null +++ b/lpld/static/public/fonts/inter/inter.css @@ -0,0 +1,57 @@ +/* Variable fonts usage: +:root { font-family: "Inter", sans-serif; } +@supports (font-variation-settings: normal) { + :root { font-family: "InterVariable", sans-serif; font-optical-sizing: auto; } +} */ +@font-face { + font-family: InterVariable; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url("InterVariable.woff2") format("woff2"); +} +@font-face { + font-family: InterVariable; + font-style: italic; + font-weight: 100 900; + font-display: swap; + src: url("InterVariable-Italic.woff2") format("woff2"); +} + +/* static fonts */ +@font-face { font-family: "Inter"; font-style: normal; font-weight: 100; font-display: swap; src: url("Inter-Thin.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: italic; font-weight: 100; font-display: swap; src: url("Inter-ThinItalic.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: normal; font-weight: 200; font-display: swap; src: url("Inter-ExtraLight.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: italic; font-weight: 200; font-display: swap; src: url("Inter-ExtraLightItalic.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: normal; font-weight: 300; font-display: swap; src: url("Inter-Light.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: italic; font-weight: 300; font-display: swap; src: url("Inter-LightItalic.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; src: url("Inter-Regular.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: italic; font-weight: 400; font-display: swap; src: url("Inter-Italic.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap; src: url("Inter-Medium.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: italic; font-weight: 500; font-display: swap; src: url("Inter-MediumItalic.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; src: url("Inter-SemiBold.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: italic; font-weight: 600; font-display: swap; src: url("Inter-SemiBoldItalic.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; src: url("Inter-Bold.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: italic; font-weight: 700; font-display: swap; src: url("Inter-BoldItalic.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: normal; font-weight: 800; font-display: swap; src: url("Inter-ExtraBold.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: italic; font-weight: 800; font-display: swap; src: url("Inter-ExtraBoldItalic.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: normal; font-weight: 900; font-display: swap; src: url("Inter-Black.woff2") format("woff2"); } +@font-face { font-family: "Inter"; font-style: italic; font-weight: 900; font-display: swap; src: url("Inter-BlackItalic.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 100; font-display: swap; src: url("InterDisplay-Thin.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 100; font-display: swap; src: url("InterDisplay-ThinItalic.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 200; font-display: swap; src: url("InterDisplay-ExtraLight.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 200; font-display: swap; src: url("InterDisplay-ExtraLightItalic.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 300; font-display: swap; src: url("InterDisplay-Light.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 300; font-display: swap; src: url("InterDisplay-LightItalic.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 400; font-display: swap; src: url("InterDisplay-Regular.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 400; font-display: swap; src: url("InterDisplay-Italic.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 500; font-display: swap; src: url("InterDisplay-Medium.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 500; font-display: swap; src: url("InterDisplay-MediumItalic.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 600; font-display: swap; src: url("InterDisplay-SemiBold.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 600; font-display: swap; src: url("InterDisplay-SemiBoldItalic.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 700; font-display: swap; src: url("InterDisplay-Bold.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 700; font-display: swap; src: url("InterDisplay-BoldItalic.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 800; font-display: swap; src: url("InterDisplay-ExtraBold.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 800; font-display: swap; src: url("InterDisplay-ExtraBoldItalic.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 900; font-display: swap; src: url("InterDisplay-Black.woff2") format("woff2"); } +@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 900; font-display: swap; src: url("InterDisplay-BlackItalic.woff2") format("woff2"); } diff --git a/lpld/static/src/style.css b/lpld/static/src/style.css index 90f73828..d7276d8d 100644 --- a/lpld/static/src/style.css +++ b/lpld/static/src/style.css @@ -2,25 +2,30 @@ @tailwind components; @tailwind utilities; -@layer components { - .heading-lg { - @apply font-bold text-neutral-700 text-4xl sm:text-5xl xl:text-6xl - } - .heading-md { - @apply font-bold text-neutral-700 text-3xl sm:text-4xl xl:text-5xl +@layer base { + :root { + @apply font-sans; } + @supports (font-variation-settings: normal) { + :root { + @apply font-sans-var; + font-optical-sizing: auto; + } + } +} - .heading-sm { - @apply font-bold text-neutral-700 text-2xl sm:text-3xl xl:text-4xl +@layer components { + .link { + @apply font-medium text-neutral-500 underline underline-offset-[0.1em] decoration-1 hover:decoration-2 hover:text-neutral-800 active:text-neutral-900 } - .heading-xs { - @apply font-bold text-neutral-700 text-xl sm:text-2xl xl:text-3xl + .heading { + @apply font-bold text-neutral-600 tracking-tight } - .link { - @apply text-neutral-500 underline underline-offset-2 decoration-1 hover:decoration-2 hover:text-neutral-800 active:text-neutral-900 + h1, h2, h3, h4, h5, h6 { + @apply heading } } @@ -29,7 +34,7 @@ Anchor links (in headings) in prose blocks should not get the prose link style, but keep the heading style. This needs to be defined outside of a layer so it does not get tree-shaken, because the class is only used in the Markdown config. */ + @apply font-bold; color: inherit; text-decoration: inherit; - font-weight: inherit; } diff --git a/lpld/templates/atoms/chevron-link/chevron-link.html b/lpld/templates/atoms/chevron-link/chevron-link.html new file mode 100644 index 00000000..e15ec0ba --- /dev/null +++ b/lpld/templates/atoms/chevron-link/chevron-link.html @@ -0,0 +1,16 @@ +{% load slippers heroicons lpldutils %} +{% spaceless %} + + {% for word in text|split %} + {% if not forloop.last %} + {{ word }} + {% else %} + {# Span wrapper to avoid line-break between icon and last word. #} + + {{ word }} + {% heroicon_mini "chevron-right" class="transition ease-linear group-hover:translate-x-0.5 delay-[10] duration-[10]" %} + + {% endif %} + {% endfor %} + +{% endspaceless %} diff --git a/lpld/templates/atoms/chevron-link/chevron-link.yaml b/lpld/templates/atoms/chevron-link/chevron-link.yaml new file mode 100644 index 00000000..d675a445 --- /dev/null +++ b/lpld/templates/atoms/chevron-link/chevron-link.yaml @@ -0,0 +1,3 @@ +context: + text: 'Listing link title' + href: 'https://www.example.com' diff --git a/lpld/templates/atoms/heading/heading-block.html b/lpld/templates/atoms/heading/heading-block.html deleted file mode 100644 index 92859f8b..00000000 --- a/lpld/templates/atoms/heading/heading-block.html +++ /dev/null @@ -1,2 +0,0 @@ -{% load slippers %} -{% #heading level="2" size="md" %}{{ value.text }}{% /heading %} diff --git a/lpld/templates/atoms/heading/heading-block.yaml b/lpld/templates/atoms/heading/heading-block.yaml deleted file mode 100644 index f4527a84..00000000 --- a/lpld/templates/atoms/heading/heading-block.yaml +++ /dev/null @@ -1,3 +0,0 @@ -context: - value: - text: 'Heading' diff --git a/lpld/templates/atoms/heading/heading.html b/lpld/templates/atoms/heading/heading.html index 6321afd5..d7d58cfe 100644 --- a/lpld/templates/atoms/heading/heading.html +++ b/lpld/templates/atoms/heading/heading.html @@ -1,19 +1,11 @@ {% load slippers %} {% var level=level|default:"1" %} -{% var size=size|default:"lg" %} {% spaceless %} diff --git a/lpld/templates/atoms/heading/subheading-block.html b/lpld/templates/atoms/heading/subheading-block.html deleted file mode 100644 index 206f82cd..00000000 --- a/lpld/templates/atoms/heading/subheading-block.html +++ /dev/null @@ -1,2 +0,0 @@ -{% load slippers %} -{% #heading level="3" size="sm" %}{{ value.text }}{% /heading %} diff --git a/lpld/templates/atoms/heading/subheading-block.yaml b/lpld/templates/atoms/heading/subheading-block.yaml deleted file mode 100644 index f4527a84..00000000 --- a/lpld/templates/atoms/heading/subheading-block.yaml +++ /dev/null @@ -1,3 +0,0 @@ -context: - value: - text: 'Heading' diff --git a/lpld/templates/atoms/link/link.html b/lpld/templates/atoms/link/link.html new file mode 100644 index 00000000..252f37fc --- /dev/null +++ b/lpld/templates/atoms/link/link.html @@ -0,0 +1 @@ +{{ text }} \ No newline at end of file diff --git a/lpld/templates/atoms/link/link.yaml b/lpld/templates/atoms/link/link.yaml new file mode 100644 index 00000000..88a860cf --- /dev/null +++ b/lpld/templates/atoms/link/link.yaml @@ -0,0 +1,3 @@ +context: + text: "The link title" + href: "https://example.com" diff --git a/lpld/templates/atoms/listing-link/listing-link.html b/lpld/templates/atoms/listing-link/listing-link.html deleted file mode 100644 index 0cebc482..00000000 --- a/lpld/templates/atoms/listing-link/listing-link.html +++ /dev/null @@ -1,15 +0,0 @@ -{% load slippers heroicons lpldutils %} -{% #heading size="xs" level="2" extra_class="hover:underline hover:decoration-3" %} - - {% for word in title|split %} - {% if not forloop.last %} - {{ word }} - {% else %} - - {{ word }} - {% heroicon_outline "chevron-right" size=30 stroke_width=4 stroke_linecap="square" stroke_linejoin="round" class="inline-block max-w-[0.9rem] sm:max-w-[1.0rem] xl:max-w-[1.25rem] ml-1 sm:ml-2" %} - - {% endif %} - {% endfor %} - -{% /heading %} diff --git a/lpld/templates/atoms/listing-link/listing-link.yaml b/lpld/templates/atoms/listing-link/listing-link.yaml deleted file mode 100644 index 0138fef4..00000000 --- a/lpld/templates/atoms/listing-link/listing-link.yaml +++ /dev/null @@ -1,3 +0,0 @@ -context: - title: 'Listing link title' - url: 'https://www.example.com' diff --git a/lpld/templates/atoms/pill/pill.html b/lpld/templates/atoms/pill/pill.html new file mode 100644 index 00000000..7e461037 --- /dev/null +++ b/lpld/templates/atoms/pill/pill.html @@ -0,0 +1,12 @@ +{{ label|lower }} diff --git a/lpld/templates/atoms/tech-pill/tech-pill.yaml b/lpld/templates/atoms/pill/pill.yaml similarity index 100% rename from lpld/templates/atoms/tech-pill/tech-pill.yaml rename to lpld/templates/atoms/pill/pill.yaml diff --git a/lpld/templates/atoms/profile-image/profile-image.html b/lpld/templates/atoms/profile-image/profile-image.html new file mode 100644 index 00000000..ff38ead4 --- /dev/null +++ b/lpld/templates/atoms/profile-image/profile-image.html @@ -0,0 +1,24 @@ +{% load wagtailimages_tags %} +
+ + {% image image fill-96x96 as profile_fallback %} + {% image_url image "fill-96x96|format-webp" as profile_96 %} + {% image_url image "fill-128x128|format-webp" as profile_128 %} + {% image_url image "fill-192x192|format-webp" as profile_192 %} + {% image_url image "fill-256x256|format-webp" as profile_256 %} + {% image_url image "fill-384x384|format-webp" as profile_384 %} + {% image_url image "fill-512x512|format-webp" as profile_512 %} + + + + + + +
diff --git a/lpld/templates/atoms/profile-image/profile-image.yaml b/lpld/templates/atoms/profile-image/profile-image.yaml new file mode 100644 index 00000000..c389ac40 --- /dev/null +++ b/lpld/templates/atoms/profile-image/profile-image.yaml @@ -0,0 +1,37 @@ +tags: + image: + # Profile image + "image fill-96x96 as profile_fallback": + target_var: "profile_fallback" + raw: + url: "https://via.placeholder.com/96/" + width: 96 + height: 96 + # Project images + "project.image width-96 as project_image_fallback": + target_var: "project_image_fallback" + raw: + url: "https://via.placeholder.com/96x120/" + width: 96 + height: 120 + image_url: + # Profile image + 'image "fill-96x96|format-webp" as profile_96': + target_var: "profile_96" + raw: "https://via.placeholder.com/96/" + 'image "fill-128x128|format-webp" as profile_128': + target_var: "profile_128" + raw: "https://via.placeholder.com/128/" + 'image "fill-192x192|format-webp" as profile_192': + target_var: "profile_192" +# raw: "https://via.placeholder.com/192/" + raw: "/static/img/profile.jpg" + 'image "fill-256x256|format-webp" as profile_256': + target_var: "profile_256" + raw: "https://via.placeholder.com/256/" + 'image "fill-384x384|format-webp" as profile_384': + target_var: "profile_384" + raw: "https://via.placeholder.com/384/" + 'image "fill-512x512|format-webp" as profile_512': + target_var: "profile_512" + raw: "https://via.placeholder.com/512/" diff --git a/lpld/templates/atoms/social-link/social-link.html b/lpld/templates/atoms/social-link/social-link.html index 0d5d7f15..cd03cbd3 100644 --- a/lpld/templates/atoms/social-link/social-link.html +++ b/lpld/templates/atoms/social-link/social-link.html @@ -1,4 +1,25 @@ -{% load static %} - - {% include icon %} +{% load static heroicons %} + + {% if icon %} + {% include icon %} + {% endif %} + {% if heroicon %} + {% heroicon_solid heroicon size=42 %} + {% endif %} diff --git a/lpld/templates/atoms/tech-pill/tech-pill.html b/lpld/templates/atoms/tech-pill/tech-pill.html deleted file mode 100644 index ab813a38..00000000 --- a/lpld/templates/atoms/tech-pill/tech-pill.html +++ /dev/null @@ -1,12 +0,0 @@ -{{ label|lower }} diff --git a/lpld/templates/base-page.html b/lpld/templates/base-page.html index 7fa0917b..9eaee63c 100644 --- a/lpld/templates/base-page.html +++ b/lpld/templates/base-page.html @@ -2,7 +2,7 @@ {% load static %} {% block body %} -
+
{% block header %} {% include "organisms/header/header.html" with links=primary_navigation_links %} {% endblock header %} @@ -10,11 +10,13 @@ {% block content %} {% endblock content %} - {% block contact %} - {% include "organisms/contact/contact.html" with id="contact" class="mt-16 pt-24 md:pt-44 pb-44" %} - {% endblock contact %} + {% block footer %} +
+
+
+ {% include "organisms/contact/contact.html" with id="contact" class="my-20" %} + {% include "organisms/footer/footer.html" with extra_class="mb-10" %} +
+ {% endblock footer %}
- {% block footer %} - {% include "organisms/footer/footer.html" %} - {% endblock footer %} {% endblock body %} diff --git a/lpld/templates/base.html b/lpld/templates/base.html index d4688381..d1678aa7 100644 --- a/lpld/templates/base.html +++ b/lpld/templates/base.html @@ -6,12 +6,13 @@ antialiased bg-neutral-50 text-neutral-500 + font-[450] {% block extra_html_class %}{% endblock extra_html_class %} " > - + {% sentry_meta %} {% if page.meta_description %} @@ -20,7 +21,8 @@ - + + {% if plausible_settings.PLAUSIBLE_DOMAIN %} {% plausible domain=plausible_settings.PLAUSIBLE_DOMAIN script="script.js" %} {% endif %} diff --git a/lpld/templates/components.yaml b/lpld/templates/components.yaml index 05c7a570..d7b1ac5c 100644 --- a/lpld/templates/components.yaml +++ b/lpld/templates/components.yaml @@ -3,9 +3,12 @@ components: button_link: "atoms/button-link/button-link.html" heading: "atoms/heading/heading.html" social_link: "atoms/social-link/social-link.html" - tech_pill: "atoms/tech-pill/tech-pill.html" + pill: "atoms/pill/pill.html" # Molecules # Organisms heading_with_intro: "organisms/heading-with-intro/heading-with-intro.html" prose: "organisms/prose/prose.html" + content_centered: "organisms/layout/content-centered.html" + content_full: "organisms/layout/content-full.html" + content_vertical_spacing: "organisms/layout/content-vertical-spacing.html" diff --git a/lpld/templates/molecules/link-listing/link-listing--elaborate.html b/lpld/templates/molecules/link-listing/link-listing--elaborate.html new file mode 100644 index 00000000..84722ac6 --- /dev/null +++ b/lpld/templates/molecules/link-listing/link-listing--elaborate.html @@ -0,0 +1,7 @@ + diff --git a/lpld/templates/molecules/link-listing/link-listing--elaborate.yaml b/lpld/templates/molecules/link-listing/link-listing--elaborate.yaml new file mode 100644 index 00000000..7e23b034 --- /dev/null +++ b/lpld/templates/molecules/link-listing/link-listing--elaborate.yaml @@ -0,0 +1,8 @@ +context: + links: + - text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit' + href: 'https://www.example.com' + - text: 'Morbi in metus vitae sem molestie rutrum convallis a nunc' + href: 'https://www.example.com' + - text: 'Cras tempus nisi in ullamcorper vestibulum' + href: 'https://www.example.com' diff --git a/lpld/templates/molecules/link-listing/link-listing.html b/lpld/templates/molecules/link-listing/link-listing.html index 03eb403b..05b82574 100644 --- a/lpld/templates/molecules/link-listing/link-listing.html +++ b/lpld/templates/molecules/link-listing/link-listing.html @@ -1,7 +1,7 @@ -
diff --git a/lpld/templates/molecules/section/section-block.html b/lpld/templates/molecules/section/section-block.html new file mode 100644 index 00000000..db67e8db --- /dev/null +++ b/lpld/templates/molecules/section/section-block.html @@ -0,0 +1,12 @@ +{% load wagtailcore_tags wagtailadmin_tags %} +
+
+ {% include_block value.heading %} +
+ +
+ {% for block in value.body %} + {% include_block block %} + {% endfor %} +
+
diff --git a/lpld/templates/organisms/contact/contact.html b/lpld/templates/organisms/contact/contact.html index eb7cb843..02e01236 100644 --- a/lpld/templates/organisms/contact/contact.html +++ b/lpld/templates/organisms/contact/contact.html @@ -1,20 +1,14 @@ -{% load slippers heroicons %} +{% load slippers %}
- {% #heading level="2" size="md" extra_class="max-w-md xl:max-w-2xl" %}Let's build something together{% /heading %} + {% #heading level="2" size="md" extra_class="sr-only" %}Contact{% /heading %} -
- {% #button_link href="mailto:tibor@lpld.io" large=True %} - {% spaceless %} - {% heroicon_solid "mail" size=40 class="inline-block h-6 xl:h-8 w-6 xl:w-8 mr-3 xl:mr-4" %} - Send me an email - {% endspaceless %} - {% /button_link %} -
- -
diff --git a/lpld/templates/organisms/footer/footer.html b/lpld/templates/organisms/footer/footer.html index ebfad997..685df714 100644 --- a/lpld/templates/organisms/footer/footer.html +++ b/lpld/templates/organisms/footer/footer.html @@ -1,3 +1,3 @@ -