diff --git a/content/posts/arcaea.dj b/content/posts/arcaea.dj
index c4b68f3..f153b41 100644
--- a/content/posts/arcaea.dj
+++ b/content/posts/arcaea.dj
@@ -5,8 +5,6 @@ created_at = "2024-11-02T05:13:44+01:00"
 
 # Why I love arcaea
 
-_Tuesday, October 10, 2024_
-
 ## What is arcaea
 - explain the base mechanics
 
diff --git a/content/posts/games/index.dj b/content/posts/games/index.dj
index 4db5c16..88ea19a 100644
--- a/content/posts/games/index.dj
+++ b/content/posts/games/index.dj
@@ -4,9 +4,11 @@ This article contains a highly subjective tier list of most of the games I've pl
 
 { role="tier-list" }
 ``` =yaml
+id: games-tier-list
+tiers:
 - name: Beyond
   id: beyond
-  elements:
+  members:
   - alt: Arcaea
     id: arcaea
     image: arcaea.png
@@ -19,6 +21,42 @@ This article contains a highly subjective tier list of most of the games I've pl
   - alt: Noita
     id: noita
     image: noita.png
+- name: Masterpiece
+  id: masterpiece
+  members:
+  - alt: Tunic
+    id: tunic
+    image: tunic.ico
+  - alt: Ultrakill
+    id: ultrakill
+    image: ultrakill.png
+  - alt: The Talos Principle
+    id: talos
+    image: thetalosprinciple.jpg
+- name: Amazing
+  id: amazing
+  members:
+  - alt: Celeste
+    id: celeste
+    image: celeste.png
+  - alt: "Rain World: Downpour"
+    id: downpour
+    image: downpour.jpg
+  - alt: Hollow Knight
+    id: hollow-knight
+    image: hollow-knight.png
+  - alt: Slay the Spire
+    id: slay-the-spire
+    image: slaythespire.png
+  - alt: Hade
+    id: hades
+    image: hades.ico
+  - alt: Portal 2
+    id: portal2
+    image: portal2.png
+  - alt: Baba is you
+    id: baba
+    image: babaisyou.png
 ```
 
 ``` =html
@@ -141,4 +179,4 @@ Ultrakill is a game all about doing cool shit. There's so many instances where y
 
 After each level, the game rates you on three axes: kills, time, and style. Improving until you can chain together stylish combos in order to P-rank (i.e. perfect) a hard level is super fun. Ultrakill has some of my favourite boss fights in all of gaming, all to the tune of a soundtrack that goes incredibly hard.
 
-The game has some technical issues (it often forgets the resolution you configure in the settings after alt-tabbing around, but this seems to be an issue a lot of Unity games have, so I'll add it to the ever-growing list of justicications for me hating engines). The community seems to be a bit predisposed to spoiling people on gameplay elements, so if you want to go in blind, I recommend staying away from any kind of content related to the game.
+The game has some technical issues (it often forgets the resolution you configure in the settings after alt-tabbing around, but this seems to be an issue a lot of Unity games have, so I'll add it to the ever-growing list of justicications for me hating engines). The community seems to be a bit predisposed to spoiling people on gameplay elements, so if you want to go in blind, I recommend staying away from any kind of content related to the game.^
diff --git a/public/styles.css b/public/styles.css
index 93c4c52..9032288 100644
--- a/public/styles.css
+++ b/public/styles.css
@@ -1,6 +1,6 @@
 body {
   font: 100%/1.6 sans-serif;
-  max-width: 70ch;
+  max-width: 43em;
   margin: auto;
   padding: 1em;
 }
@@ -25,10 +25,16 @@ h6 {
   a {
     display: inline-block;
     text-decoration: none;
+    /* Note: I need to check whether this only aligns things better with the font I use */
     transform: translateY(-2px);
   }
 }
 
+.article-content {
+  max-width: 40em;
+  margin: auto;
+}
+
 /* {{{ Asides*/
 .aside {
   margin: 1.5rem 0;
@@ -95,7 +101,7 @@ img.aside-icon {
 }
 
 /* }}}*/
-
+/* {{{ Tier lists*/
 .tier-list {
   background: #444;
 
@@ -194,3 +200,4 @@ img.aside-icon {
   }
   /* }}}*/
 }
+/* }}}*/
diff --git a/src/html.rs b/src/html.rs
index 6b58ced..0beb240 100644
--- a/src/html.rs
+++ b/src/html.rs
@@ -161,7 +161,7 @@ impl<'s> Writer<'s> {
 							if matches!(ty, LinkType::Email) {
 								out.write_str("mailto:")?;
 							}
-							write_attr(dst, &mut out)?;
+							write_attr_contents(dst, &mut out)?;
 							out.write_char('"')?;
 						}
 					}
@@ -215,7 +215,7 @@ impl<'s> Writer<'s> {
 
 								character
 									.parts()
-									.try_for_each(|part| write_attr(part, &mut out))?;
+									.try_for_each(|part| write_attr_contents(part, &mut out))?;
 								renderer.next(&mut out)?;
 							} else if label == "title" {
 								let title = attrs.get_value("title").ok_or_else(|| {
@@ -224,7 +224,7 @@ impl<'s> Writer<'s> {
 
 								title
 									.parts()
-									.try_for_each(|part| write_attr(part, &mut out))?;
+									.try_for_each(|part| write_attr_contents(part, &mut out))?;
 								renderer.next(&mut out)?;
 							} else {
 								break;
@@ -253,28 +253,29 @@ impl<'s> Writer<'s> {
 					Container::LinkDefinition { .. } => return Ok(()),
 				}
 
-				let mut write_attribs = true;
+				let mut write_attr_contentsibs = true;
 				if matches!(
 					c,
 					Container::Div {
 						class: "aside" | "long-aside" | "char-aside"
 					}
 				) {
-					write_attribs = false;
+					write_attr_contentsibs = false;
 				}
 
-				if write_attribs {
+				if write_attr_contentsibs {
 					// {{{ Write attributes
 					let mut id_written = false;
 					let mut class_written = false;
 
-					if write_attribs {
+					if write_attr_contentsibs {
 						for (a, v) in attrs.unique_pairs() {
 							let is_class = a == "class";
 							let is_id = a == "id";
 							if (!is_id || !id_written) && (!is_class || !class_written) {
 								write!(out, r#" {}=""#, a)?;
-								v.parts().try_for_each(|part| write_attr(part, &mut out))?;
+								v.parts()
+									.try_for_each(|part| write_attr_contents(part, &mut out))?;
 								out.write_char('"')?;
 
 								id_written |= is_id;
@@ -284,32 +285,31 @@ impl<'s> Writer<'s> {
 					}
 					// }}}
 					// {{{ Write default ids/classes
-					if let Container::Heading {
-						id,
-						has_section: false,
-						..
-					}
-					| Container::Section { id } = &c
-					{
-						if !id_written {
-							out.write_str(r#" id=""#)?;
-							write_attr(id, &mut out)?;
+					match c {
+						Container::Heading { id, .. } if !id_written => {
+							write_attr("id", id, &mut out)?;
+						}
+						Container::Section { id, .. } => {
+							write_attr("aria-labeledby", id, &mut out)?;
+						}
+						Container::Div { class } if !class.is_empty() && !class_written => {
+							out.write_str(r#" class=""#)?;
+							write_class(c, false, &mut out)?;
 							out.write_char('"')?;
 						}
-					// TODO: do I not want this to add onto the provided class?
-					} else if (matches!(c, Container::Div { class } if !class.is_empty())
-						|| matches!(
-							c,
-							Container::Math { .. }
-								| Container::List {
-									kind: ListKind::Task(..),
-									..
-								} | Container::TaskListItem { .. }
-						)) && !class_written
-					{
-						out.write_str(r#" class=""#)?;
-						write_class(c, false, &mut out)?;
-						out.write_char('"')?;
+						Container::Math { .. }
+						| Container::List {
+							kind: ListKind::Task(..),
+							..
+						}
+						| Container::TaskListItem { .. }
+							if !class_written =>
+						{
+							out.write_str(r#" class=""#)?;
+							write_class(c, false, &mut out)?;
+							out.write_char('"')?;
+						}
+						_ => {}
 					}
 					// }}}
 
@@ -333,7 +333,7 @@ impl<'s> Writer<'s> {
 								out.write_str("><code>")?;
 							} else {
 								out.write_str(r#"><code class="language-"#)?;
-								write_attr(language, &mut out)?;
+								write_attr_contents(language, &mut out)?;
 								out.write_str(r#"">"#)?;
 							}
 						}
@@ -357,7 +357,7 @@ impl<'s> Writer<'s> {
 				match &c {
 					Container::Heading { id, .. } => {
 						out.write_str(r##"<a href="#"##)?;
-						write_attr(id, &mut out)?;
+						write_attr_contents(id, &mut out)?;
 						out.write_str(r#"">◇</a> "#)?;
 					}
 					Container::Image(..) => {
@@ -411,7 +411,7 @@ impl<'s> Writer<'s> {
 					Container::Image(src, ..) => {
 						if !src.is_empty() {
 							out.write_str(r#"" src=""#)?;
-							write_attr(src, &mut out)?;
+							write_attr_contents(src, &mut out)?;
 						}
 
 						out.write_str(r#"">"#)?;
@@ -483,13 +483,18 @@ impl<'s> Writer<'s> {
 										if wc < 400 {
 											write!(&mut out, "{}", wc)?;
 										} else if wc < 1000 {
+											write!(&mut out, "{}", wc / 10 * 10)?;
+										} else if wc < 2000 {
 											write!(&mut out, "{}", wc / 100 * 100)?;
 										} else {
 											write!(&mut out, "{} thousand", wc / 1000)?;
 										}
 									} else if label == "reading_duration" {
 										let minutes = meta.word_count / 200;
-										if minutes < 10 {
+										if minutes == 0 {
+											let seconds = meta.word_count * 60 / 200;
+											write!(&mut out, "very short {seconds} second")?;
+										} else if minutes < 10 {
 											write!(&mut out, "short {minutes} minute")?;
 										} else if minutes < 20 {
 											write!(&mut out, "somewhat short {minutes} minute")?;
@@ -533,7 +538,7 @@ impl<'s> Writer<'s> {
 			// }}}
 			// {{{ Raw string
 			Event::Str(s) => match self.states.last() {
-				Some(State::TextOnly) => write_attr(s, &mut out)?,
+				Some(State::TextOnly) => write_attr_contents(s, &mut out)?,
 				Some(State::Raw) => out.write_str(s)?,
 				Some(State::Math(display)) => {
 					let config = pulldown_latex::RenderConfig {
@@ -590,7 +595,8 @@ impl<'s> Writer<'s> {
 				out.write_str("<hr")?;
 				for (a, v) in attrs.unique_pairs() {
 					write!(out, r#" {}=""#, a)?;
-					v.parts().try_for_each(|part| write_attr(part, &mut out))?;
+					v.parts()
+						.try_for_each(|part| write_attr_contents(part, &mut out))?;
 					out.write_char('"')?;
 				}
 				out.write_str(">")?;
@@ -683,10 +689,18 @@ fn write_text(s: &str, out: impl std::fmt::Write) -> std::fmt::Result {
 }
 
 #[inline]
-fn write_attr(s: &str, out: impl std::fmt::Write) -> std::fmt::Result {
+fn write_attr_contents(s: &str, out: impl std::fmt::Write) -> std::fmt::Result {
 	write_escape(s, true, out)
 }
 
+#[inline]
+fn write_attr(attr: &str, content: &str, mut out: impl std::fmt::Write) -> std::fmt::Result {
+	write!(&mut out, r#" {attr}=""#)?;
+	write_attr_contents(content, &mut out)?;
+	out.write_char('"')?;
+	Ok(())
+}
+
 fn write_escape(
 	mut s: &str,
 	escape_quotes: bool,
@@ -721,8 +735,8 @@ fn write_datetime<T: TimeZone>(
 	let datetime = datetime.to_utc();
 	write!(
 		&mut out,
-		"<time datetime={}>{}</time>",
-		datetime,
+		r#"<time datetime="{}">{}</time>"#,
+		datetime.to_rfc3339(),
 		datetime.format("%a, %d %b %Y")
 	)
 }
diff --git a/src/templates/post.html b/src/templates/post.html
index 225a83e..7c2dec1 100644
--- a/src/templates/post.html
+++ b/src/templates/post.html
@@ -17,5 +17,5 @@
     <hr />
   </header>
 
-  {{content}}
+  <section class="article-content">{{content}}</section>
 </article>