Finalize assets (#26)

* Add favicons and app images

* Add to root head: meta id elements, favicons

* Finish ship ready CSS/HTML

* Add static non-media assets
This commit is contained in:
Anders Englöf Ytterström 2024-10-18 09:30:28 +02:00 committed by GitHub
parent 27fb1b7a86
commit a14f206a2a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 642 additions and 123 deletions

12
assets/andersy.vcf Normal file
View file

@ -0,0 +1,12 @@
BEGIN:VCARD
VERSION:4.0
N:Ytterström;Anders;;Mr.;
FN:Anders Ytterström
ORG:Kundo
TITLE:Webbutvecklare/hårdrockare
PHOTO;MEDIATYPE=image/gif:https://madr.se/mugshot.jpg
TEL;TYPE=home,voice;VALUE=uri:tel:+46-70-216-9645
EMAIL:yttan@fastmail.se
REV:20191006T195243Z
x-qq:21588891
END:VCARD

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View file

@ -1,59 +1,150 @@
:root {
--color: #fff;
--bgcolor: #201;
--box-padding: 12px;
}
/*
Main CSS file for madr.se
If you have any questions regarding the CSS, feel free
to contact me: yttan at madr dot se
#leaflet {
aspect-ratio: 1;
Table of contents, 7-1 inspired
1. Base
2. Components
3. Layout
4. Pages
5. Themes
6. Vendors
7. Shame
*/
/* === 1. Base === */
/*
Normalize and resets.
Only properties, element and attribute selectors are allowed in this
section.
All dynamic values that should change according to user preferences
(dark or light color mode, reduced motion etc) and agent abilities
(small handheld screen, big desktop screen) are handled by properties
when appliable.
This is to avoid redeclarating CSS rules.
*/
:root {
/* colors, dark mode default */
--color: hsl(0 0 90%);
--bgcolor: hsl(180 75% 6%);
--tree-item-accent-color: dimgrey;
--panel-bg-color: hsla(0 0 50% / 0.16);
--monospace-color: springgreen;
--monospace-color-inline: seagreen;
/* typography, mobile first */
--base-font-size: 1.33em;
--page-title-font-size: 2em;
--tree-font-size: 0.85em;
--section-heading-lv2-font-size: 1.5em;
--section-heading-lv3-font-size: 1.2em;
--section-heading-lv4-font-size: 1em;
--system-serif-fonts: Cambria, Cochin, Georgia, Times, "Times New Roman",
serif;
--system-sansserif-fonts: apple-system, system-ui, BlinkMacSystemFont,
Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif;
--monospace-fonts: "JetBrains mono", monaco, menlo, meslo, "Courier New",
Courier, monospace;
/* whitespace */
--gap-sm: 0.5em;
--gap-md: 1em;
--gap-lg: 3em;
/* transitions */
--animation-duration: 0.5s;
/* dimensions and aspect ratios */
--map-ratio: 1;
@media (min-width: 666px) {
--base-font-size: 1.66em;
--tree-font-size: 0.67em;
}
}
html {
color: var(--color);
background-color: var(--bgcolor);
background-image: linear-gradient(#000, #201 333px);
font:
normal small/1.5 apple-system,
system-ui,
BlinkMacSystemFont,
Segoe UI,
Roboto,
Helvetica Neue,
Arial,
sans-serif;
font: normal var(--base-font-size) / 1.5 var(--system-sansserif-fonts);
}
body {
margin: 0;
min-height: 100vh;
> footer > p {
margin-top: var(--gap-lg);
color: #666;
font-size: 0.66em;
}
}
input,
button {
font-size: 1.2em;
padding: 0.25em;
}
h1,
h2,
h3 {
line-height: 1.1;
font-family: serif;
font-family: var(--system-serif-fonts);
}
main {
background-color: #000;
margin: 0 auto;
max-width: 40em;
box-sizing: border-box;
padding: 3em;
h1 {
margin: 0.5em 0;
line-height: 0.95;
font-size: var(--page-title-font-size);
@media (min-width: 666px) {
text-transform: lowercase;
margin-top: 0.5em;
margin-bottom: 0.5em;
text-align: right;
line-height: 0.9;
color: var(--tree-item-accent-color);
font-weight: normal;
}
}
h2,
h3 {
margin-top: 2em;
line-height: 1.1;
}
h2 {
font-size: var(--section-heading-lv2-font-size);
border-bottom: 3px solid var(--panel-bg-color);
}
h3 {
font-size: var(--section-heading-lv3-font-size);
}
h4 {
font-size: var(--section-heading-lv4-font-size);
}
pre {
margin: 2em 0;
background-color: #022;
color: var(--monospace-color);
overflow-y: auto;
padding: 0.33em;
box-shadow: 4px 4px 0 #333;
padding: 0.66em;
box-shadow: 4px 4px 0 var(--panel-bg-color);
position: relative;
line-height: 1.2;
font-size: 0.8em;
> button {
font-size: 0.75em;
position: absolute;
top: 0.25em;
right: 0.25em;
@ -61,30 +152,117 @@ pre {
}
code {
font-family: "JetBrains mono", monaco, menlo, meslo, "Courier New", Courier,
monospace;
font-family: var(--monospace-fonts);
&.inline {
color: var(--monospace-color-inline);
background: #f3f3f3;
font-size: 0.9em;
}
}
section {
position: relative;
& > h2 {
background: #000;
padding: 1em 0;
background: var(--bgcolor);
color: var(--color);
padding: 0.5em 0.25em;
border-bottom: 0;
}
}
.skiplink {
position: absolute;
top: -5em;
transition: top 0.4s ease-out;
padding: 0.25em 0.5em;
&:focus {
top: 1em;
}
img {
max-width: 100%;
display: block;
height: auto;
}
ul,
ol {
clear: left;
}
p {
margin: 1em 0;
}
article {
line-height: 1.33;
}
figure {
margin: 0;
}
figcaption {
text-align: center;
margin-top: 0.5em;
}
table {
width: 100%;
}
td,
th {
background-color: var(--background-color-l);
padding: 0.25em;
font-size: 0.8em;
border: 1px solid rgb(128, 128, 128, 0.5);
}
th {
background-color: var(--background-color-ll);
text-transform: uppercase;
color: var(--em-color);
font-weight: normal;
}
li {
color: var(--em-color);
margin: 0.25em 0;
}
li:first-child {
margin-top: 0;
}
li:last-child {
margin-bottom: 0;
}
li::marker {
color: var(--link-color);
}
blockquote {
color: var(--em-color);
font-size: 1.2em;
line-height: 1.2;
font-style: italic;
border-left: 5px solid var(--background-color-l);
margin: 1em 1em 1em 0;
padding-left: 1em;
}
blockquote p::after,
blockquote p::before {
content: '"';
}
/* === /Base === */
/* === 2. Components === */
/*
Use kebab case named classes to identify components, and nesting
to group subcomponents.
Element selectors are preferred as subcomponents, due to the simple
nature of this site. As a general rule though, classes are the most
versatile.
*/
.sr-only {
position: absolute;
left: -999em;
@ -96,32 +274,91 @@ section {
align-items: center;
}
.sticky {
position: sticky;
top: 0;
}
.interactive-map {
aspect-ratio: var(--map-ratio);
}
.home-h1 {
font-size: 1.33em;
}
.list-link {
&::after {
content: " →";
}
}
.feed-link {
&::after {
content: " ↗";
}
}
.skiplink {
position: absolute;
top: -5em;
transition: top var(--animation-duration) ease-out;
padding: 0.25em 0.5em;
&:focus {
top: 1em;
}
}
.tree {
color: crimson;
align-items: center;
justify-content: center;
margin: 1em auto;
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 0.5em;
gap: 0.66em;
font-size: var(--tree-font-size);
> * {
padding: 0.5em 1em;
border-radius: 5px;
background-color: rgba(128, 128, 128, 0.1);
> li {
display: flex;
align-items: center;
margin: 0;
gap: 0.5em;
padding: 1.33em 0.5em;
background-color: rgba(128, 128, 128, 0.16);
border-left: 6px solid var(--tree-item-accent-color);
&:focus-within {
background-color: rgba(128, 128, 128, 0.25);
}
> small {
opacity: 0.66;
font-family: var(--monospace-fonts);
font-size: 0.66em;
}
}
> :nth-child(even) {
text-align: right;
> .article {
--tree-item-accent-color: rebeccapurple;
}
> .album {
--tree-item-accent-color: goldenrod;
}
> .link {
--tree-item-accent-color: honeydew;
}
> .events {
--tree-item-accent-color: firebrick;
}
a {
color: #fff;
color: var(--color);
text-decoration: none;
flex: 1;
&:hover,
&:focus {
@ -131,45 +368,35 @@ section {
}
.landing {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 3em;
padding: 2em 0;
box-sizing: border-box;
gap: 3em;
gap: 1.66em;
}
.breadcrumbs {
list-style: none;
padding-left: 0;
display: block;
margin: var(--gap-sm) 0;
padding: var(--gap-sm);
border: 1px solid rgb(128, 128, 128, 0.25);
background-color: var(--panel-bg-color);
border-radius: 0;
> li {
> span {
display: inline;
&:after {
content: " /";
}
}
}
.article {
font-size: large;
box-sizing: border-box;
> footer {
font-style: italic;
text-align: right;
font-size: 0.8em;
a {
color: var(--color);
}
}
.sticky {
position: sticky;
top: 0;
}
.months {
grid-auto-flow: rows;
display: grid;
@ -177,7 +404,36 @@ section {
grid-template-columns: repeat(3, 1fr);
gap: 0.5em;
padding-left: 0;
margin: 3em 0;
margin: 2.75em 0;
> li {
margin: 0;
}
}
.article {
> div > p:first-child::first-letter {
@media (min-width: 500px) {
float: left;
font-size: 7em;
border: 8px double hsl(0 0 50%);
padding: 0.1em;
margin-right: 0.066em;
font-style: normal;
font-family: var(--system-serif-fonts);
}
}
> footer {
font-style: italic;
font-size: 0.8em;
text-align: right;
> p {
margin-top: 2.75em;
margin-bottom: 0;
}
}
}
.articles {
@ -197,7 +453,7 @@ section {
}
}
date {
time {
border-top: 1px solid crimson;
padding: 0.25em 0.5em;
}
@ -223,3 +479,88 @@ section {
aspect-ratio: 1;
}
}
.profiles {
display: flex;
gap: 1.66em;
list-style: none;
margin: 0;
> li {
margin: 0;
padding: 0;
}
}
/* === /Components === */
/* === 3. Layout === */
/*
Containers and wrappers for components.
Only class selectors allowed, with the following element selectors as
exceptions: aside, body, footer, header, main and nav.
*/
body {
margin: 0 auto;
max-width: 33em;
box-sizing: border-box;
min-height: 100vh;
padding: 0 0.5em;
}
/* === /Layout === */
/* === 4. Pages === */
/*
Styles that should only apply to certain pages.
*/
/* === /Pages === */
/* === 5. Themes === */
/*
Styles to create user-customized themes.
This section adapts the design to the following user preferences:
Color theme, reduced motion
*/
@media (prefers-color-scheme: light) {
:root {
--color: #000;
--bgcolor: #fff;
}
}
@media (prefers-reduced-motion) {
:root {
--animation-duration: 0;
}
}
@media (min-width: 800px) {
:root {
--map-ratio: 3 / 2;
}
}
@media (min-width: 1000px) {
:root {
--page-title-font-size: 4em;
}
}
/* === /Themes === */
/* === 6. Vendors === */
/*
Styles belonging to third-party components.
*/
.footnotes-list {
color: var(--aside-color);
font-size: 80%;
}
/* === /Vendors === */
/* === 7. Shame === */
/*
Styles necessary for specifity issues and for cutting corners
(breaking the rules in short terms in waiting for an opportunity
to rewrite or fix a problem for good).
madr.se has no reason to feel ashamed. Yet.
*/
/* === /Shame === */

BIN
assets/apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -0,0 +1 @@
body{background-color:#111;color:#aaa;font-size:large;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;padding:0;margin:0 auto;max-width:80em}a:link,a:visited{color:#a83}a:visited{text-decoration:line-through}a:focus,a:hover{color:#fff}a:active{transform:translate(2px,2px)}header{border-bottom:3px solid #a83;padding:.5em;margin-bottom:.5em;align-items:center}@media (min-width:500px){header{display:flex;justify-content:space-between;padding:.5em;margin:0}}@media (min-width:1200px){header{margin:.5em 0}}h1{text-transform:uppercase;margin:0;font-size:1.5em}p:first-child{margin-top:0}p:last-child{margin-bottom:0}.field{background-color:#333;color:#fff;border-width:0;border-radius:5px;font-size:large;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;padding:.5rem 1rem;display:block;width:100%;box-sizing:border-box;margin-top:.5em}.field:hover{background-color:#444}.field:focus{background-color:#fff;color:#000}@media (min-width:500px){.field{margin-top:0}input.field{min-width:17em}}.blur{filter:blur(25px)}.visuallyhidden{position:absolute;left:-9999em}.album{display:flex;align-items:start;padding:.5em;margin:.8em 0}@media (min-width:500px){.album{flex-direction:column;margin:0}}@media (min-width:1200px){.album{flex-direction:row;align-items:center}}.album:hover{background:#333;color:#fff}.album__cover{margin:0 .5em 0 0;padding-top:7px}@media (min-width:500px){.album__cover{margin:0 0 .5em;width:100%;padding-top:0}}@media (min-width:1200px){.album__cover{margin:0 1em 0 0;width:auto;padding-top:0}}.album__cover__media{width:25vw;height:25vw;position:relative}.album__cover__media:after{position:absolute;content:"";top:0;right:0;bottom:0;left:0;background-color:#fff;z-index:10}@media (min-width:500px){.album__cover__media{width:100%;height:100%}}@media (min-width:1200px){.album__cover__media{width:10vw;height:10vw}}@media (min-width:500px){.albums{display:grid;grid-template-columns:1fr 1fr 1fr;grid-gap:.5em;text-transform:uppercase;padding-bottom:2em}}.selected-album{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center}.selected-album__inner{overflow:auto;border:3px solid #a83;background:#000;padding:2em;max-height:80%;display:flex;flex-direction:column;align-items:center}.selected-album__summary{text-transform:uppercase;padding:.5em;margin-bottom:.5em}.selected-album__description{color:#fff;padding:0 .5rem 2em;margin:0 auto;max-width:40em}.selected-album__cover{display:none}@media (min-width:1200px){.selected-album__cover{display:block;width:75vh;max-width:900px;height:auto}.selected-album__media{width:100%;height:auto}}

1
assets/bl/index.html Normal file
View file

@ -0,0 +1 @@
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><link rel="stylesheet" href="brutal.f07f1821.css"><title>🤘 Brütal Legend 🤘</title></head><body> <div id="brutal"></div> </body><script src="src.fc45d0fd.js"></script></html>

129
assets/bl/src.fc45d0fd.js Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

BIN
assets/favicon-16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

BIN
assets/favicon-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
assets/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -1,26 +1,24 @@
<a href="#content" class="skiplink">Hoppa till innehållet</a>
<nav>
<div>
<span class="sr-only">Du är här:</span>
<span class="breadcrumbs" itemscope itemtype="https://schema.org/BreadcrumbList">
<span itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href="/" rel="home">
<span itemprop="name">madr.se</span>
</a>
<meta itemprop="position" content="1" />
</span>
<%= for {index, {parent_slug, parent_name}} <- breadcrumbs(@breadcrumbs) do %>
<span class="sr-only">&gt;</span>
<span itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href={parent_slug}>
<span itemprop="name"><%= parent_name %></span>
</a>
<meta itemprop="position" content={index} />
</span>
<% end %>
<span class="sr-only">Du är här:</span>
<span class="breadcrumbs" itemscope itemtype="https://schema.org/BreadcrumbList">
<span itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href="/" rel="home">
<span itemprop="name">madr.se</span>
</a>
<meta itemprop="position" content="1" />
</span>
</div>
<%= for {index, {parent_slug, parent_name}} <- breadcrumbs(@breadcrumbs) do %>
<span class="sr-only">&gt;</span>
<span itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href={parent_slug}>
<span itemprop="name"><%= parent_name %></span>
</a>
<meta itemprop="position" content={index} />
</span>
<% end %>
</span>
</nav>
<main id="content">
<%= @inner_content %>

View file

@ -2,9 +2,11 @@
<html lang="sv">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta name="csrf-token" content={get_csrf_token()} />
<title><%= assigns.page_title || "Anders Englöf Ytterström" %> | madr.se</title>
<meta name="viewport" content="width=device-width" />
<meta name="robots" content="noimageai" />
<meta name="robots" content="noai" />
<meta name="author" content="Anders Englöf Ytterström" />
<link rel="stylesheet" href={~p"/assets/app.css"} />
<link
href="/prenumerera.xml"
@ -15,6 +17,9 @@
<%= canonical(assigns) |> raw %>
<%= opengraph(assigns) |> raw %>
<%= robots(assigns) |> raw %>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
</head>
<body>
<%= @inner_content %>

View file

@ -9,7 +9,7 @@ defmodule Mse25Web.PageController do
def home(conn, _params) do
[most_recent_article, older_article] = Directus.get_articles!(limit: 2)
recent_event = Directus.get_events!(limit: 1)
upcoming_events = Directus.get_events!(limit: 1, upcoming: true)
upcoming_events = Directus.get_events!(limit: 2, upcoming: true)
brutal_legends = Directus.get_albums!(limit: 1)
render(conn, :home,
@ -61,7 +61,7 @@ defmodule Mse25Web.PageController do
render(conn, :articles,
page_title: page_title,
breadcrumbs: [{"webblogg", "Webblogg"}],
breadcrumbs: [],
articles: group_annually(articles),
q: params["q"],
nosearch?: params["q"] == nil or params["q"] == ""

View file

@ -4,7 +4,7 @@
<section id="map">
<h2>Geografisk utspridning</h2>
<figure>
<div id="leaflet"></div>
<div id="leaflet" class="interactive-map"></div>
</figure>
</section>
<p>

View file

@ -1,50 +1,64 @@
<main class="landing">
<img src={~p"/images/aey.svg"} width="120" alt="Anders Englöf Ytterström" />
<h1 class="sr-only">Anders Englöf Ytterström</h1>
<form method="get" action="/sok">
<label for="q">Sök innehåll</label>: <input size="9" type="search" id="q" name="q" />
<button>Sök</button>
</form>
<h1 class="home-h1">Anders Englöf Ytterström</h1>
<ul class="tree">
<li class="article">
Senast skrivet (<time><%= @recent_article["pubDate"] %></time>):<br />
<a href={"/" <> @recent_article["slug"]}>
<%= @recent_article["title"] %>
</a>
<small>(<time><%= @recent_article["pubDate"] %></time>)</small>
</li>
<li class="article">
Dessförinnan (<time><%= @older_article["pubDate"] %></time>):<br />
<a href={"/" <> @older_article["slug"]}>
<%= @older_article["title"] %>
</a>
<small>(<time><%= @older_article["pubDate"] %></time>)</small>
</li>
<li class="page">
<a href="/webblogg">Webbloggen</a>
<a href="/webblogg" class="list-link">Alla Webbloggens inlägg</a>
</li>
<%= for event <- @upcoming do %>
<li class="event">
Kommande: <a href={event["slug"]}><%= event["title"] %><br /><%= event["lead"] %></a>
<%= for event <- @recent_event do %>
<li class="events">
<a href={event["slug"]} title={event["lead"]}>
<%= event["title"] %> (<%= event["started_at"] %>)
</a>
<%= if event["poster"] do %>
<img
src={"https://n.madr.se/assets/" <> event["poster"] <> "?key=thumbnail"}
alt="affisch"
loading="lazy"
/>
<% end %>
</li>
<% end %>
<%= for event <- @recent_event do %>
<li class="event">
Upplevt: <a href={event["slug"]}><%= event["title"] %><br /><%= event["lead"] %></a>
<%= for event <- @upcoming do %>
<li class="events">
<a href={event["slug"]} title={event["lead"]}>
<%= event["title"] %> (<%= event["started_at"] %>)
</a>
<%= if event["poster"] do %>
<img
src={"https://n.madr.se/assets/" <> event["poster"] <> "?key=thumbnail"}
alt="affisch"
loading="lazy"
/>
<% end %>
</li>
<% end %>
<li class="feed events page">
<a href="/evenemang">Evenemangstidslinje</a>
<a href="/evenemang" class="list-link">Evenemangstidslinje</a>
</li>
<li class="feed ics">
<a href="/kommande-evenemang.ics">Kommande evenemang</a> (vcalendar)
<li class="feed events ics">
<a href="/kommande-evenemang.ics" class="feed-link">Kommande evenemang</a>
<small>(vcalendar)</small>
</li>
<li class="feed links">
<a href="/delningar">
<a href="/delningar" class="list-link">
Delningar
</a>
</li>
<%= for legend <- @brutal_legends do %>
<li class="album">
Införskaffat (<%= legend["purchased_at"] %>):<br />
<a href={"/" <> legend["purchase_year"] <> "/brutal-legend-" <> legend["externalId"]}>
<%= legend["artist"] %> - <%= legend["album"] %> (<%= legend["year"] %>)
</a>
@ -56,17 +70,35 @@
</a>
</li>
<li class="page">
Mer om:
<a href="/om">
Anders, 39, Hårdrockare
</a>
</li>
<li class="feed rss">
<a href="/prenumerera.xml">Prenumerera</a> (RSS 2.0)
<a href="/prenumerera.xml" class="feed-link">Prenumerera</a> <small>(RSS 2.0)</small>
</li>
<li class="page meta">
<li class="">
<a clasS="feed-link" href="aey.vcard">
Kontakt
</a>
<small>(vcard)</small>
</li>
</ul>
<form method="get" action="/sok">
<label for="q">Sök innehåll</label>: <input size="9" type="search" id="q" name="q" />
<button>Sök</button>
</form>
<ul class="profiles">
<li><a href="/cv.html">CV</a></li>
<li><a href="https://github.com/madr">Github</a></li>
<li>
<a href="https://www.discogs.com/user/madrse/collection?limit=250&sort=artist&sort_order=asc&layout=big">
Discogs
</a>
</li>
<li>
<a href="/colophon">
Kontakt &amp; Kolofon
Kolofon
</a>
</li>
</ul>