diff --git a/build-assets/epub-metadata.txt b/build-assets/epub-metadata.yaml
similarity index 62%
rename from build-assets/epub-metadata.txt
rename to build-assets/epub-metadata.yaml
index aaefcb9..c7cb8c9 100644
--- a/build-assets/epub-metadata.txt
+++ b/build-assets/epub-metadata.yaml
@@ -1,5 +1,2 @@
----
-author: Stacktrace / David Reed
 rights: Creative Commons Attribution-ShareAlike 4.0
 language: en-US
----
diff --git a/build-assets/epub.css b/build-assets/epub.css
new file mode 100644
index 0000000..235391b
--- /dev/null
+++ b/build-assets/epub.css
@@ -0,0 +1,84 @@
+.canonical-link {
+    display: inline-block !important;
+}
+
+h1,
+h2,
+h3, summary {
+    font-family: 'Arial Black';
+    font-weight: bold;
+    text-align: left;
+    padding: 0;
+}
+
+summary {
+    padding-top: 2em;
+}
+
+h1 {
+    font-size: 14pt;
+    border-bottom: 3pt solid;
+    border-bottom-color: black;
+    padding-bottom: 2pt;
+}
+
+h2, summary {
+    font-size: 13pt;
+}
+
+h3 {
+    font-size: 12pt;
+}
+
+h4 {
+    font-size: 11pt;
+}
+
+h5 {
+    font-size: 10.5pt;
+}
+
+html {
+    margin: 0;
+    padding: 0;
+    font-size: 10pt;
+    line-height: normal !important;
+}
+
+
+dl {
+    margin: 0;
+    padding: 0;
+}
+
+dl dd {
+    display: inline;
+    margin: 0;
+    padding: 0;
+    margin-right: 2rem;
+}
+
+dl dt {
+    display: inline;
+    font-style: italic;
+    color: inherit;
+    margin: 0;
+    padding: 0;
+    margin-right: 1rem;
+}
+
+abbr {
+    font-size: 80%;
+    text-decoration: none !important;
+}
+
+body {
+    font-size: 1.15rem;
+    line-height: 1.3;
+    font-family: serif;
+}
+
+a {
+    color: inherit;
+    text-decoration: none;
+}
\ No newline at end of file
diff --git a/build-assets/epub.lua b/build-assets/epub.lua
new file mode 100644
index 0000000..218249e
--- /dev/null
+++ b/build-assets/epub.lua
@@ -0,0 +1,50 @@
+function Div(el)
+    -- Discard the internal Div representing the header.
+    if el.classes[2] == "header" then
+        return {}
+    end
+
+    -- Find a Plain with content "Table of Contents"
+    -- followed by a BulletList, and drop them both if found.
+    local filteredBlocks = {}
+    if el.content then
+        for i, v in ipairs(el.content) do
+            if v.tag == "BulletList" and i > 1 then
+                previousTag = el.content[i-1]
+                if pandoc.utils.stringify(previousTag.content) == "Table of Contents" then
+                    -- Omit the previous tag and this tag
+                    table.remove(filteredBlocks)
+                else
+                    table.insert(filteredBlocks, v)
+                end
+            else
+                table.insert(filteredBlocks, v)
+            end
+        end
+
+        el.content = filteredBlocks
+    end
+
+    return el
+end
+
+function Pandoc(el)
+    -- Retain only the Div that has the role `main`.
+    -- Discard all other top-level elements, which
+    -- are HTML-only.
+
+    -- Promote this Div's own contents to top-level
+    -- This prevents Pandoc from getting confused
+    -- and adding an extra H1 to our doc.
+    -- See https://github.com/jgm/pandoc/blob/main/src/Text/Pandoc/Writers/EPUB.hs#L556
+
+    for i, v in ipairs(el.blocks) do
+        if v.tag == "Div" and v.attributes["role"] == "main" then
+            newEl = el:clone()
+            newEl.blocks = v.content
+            return newEl
+        end
+    end
+
+    return el
+end
diff --git a/build-assets/print.css b/build-assets/print.css
index e94524a..302453f 100644
--- a/build-assets/print.css
+++ b/build-assets/print.css
@@ -43,6 +43,14 @@ h3 {
     font-size: 12pt;
 }
 
+h4 {
+    font-size: 11pt;
+}
+
+h5 {
+    font-size: 10.5pt;
+}
+
 @page {
     size: letter;
     margin: 1in;
diff --git a/content/guides/jam-timer.md b/content/guides/jam-timer.md
index fffb4b0..987c260 100644
--- a/content/guides/jam-timer.md
+++ b/content/guides/jam-timer.md
@@ -1,6 +1,6 @@
 ---
 title: "Jam Timer"
-date: "2024-08-28"
+date: "2024-09-23"
 template: "guide.html"
 extra:
     author: "David Reed / Stacktrace"
@@ -223,6 +223,8 @@ In all of these situations, whistle an Official Time Out instead of starting the
 
 Keep in mind that whistling an official time out instead of starting the jam often results in skater confusion, and some may begin skating in derby direction. Ensure that you're not in a position to be struck.
 
+Sometimes the jam is started incorrectly when it _should_ have gone into an Official Time Out. See [Officiating Procedures 6.1.1](https://resources.wftda.org/officiating/standards-and-procedures/), which specifies that a jam started in error should be allowed to conclude naturally in a situation where a queued skater is not lined up, before transitioning into an Official Time Out to issue the penalty. The jam started in error _must_ be whistled dead if an injured skater returns to play too early.
+
 #### Are the medics present and attending to the game?
 
 At least one medic must be available to treat skaters and attending to the track at all times, per the WFTDA Risk Management Guidelines (section 5.2). It's fine if one medic is tending to an injured skater provided that the other medic is in position and attending.
diff --git a/content/guides/penalty-box-manager.md b/content/guides/penalty-box-manager.md
index a8d3a7d..1446aa7 100644
--- a/content/guides/penalty-box-manager.md
+++ b/content/guides/penalty-box-manager.md
@@ -51,7 +51,7 @@ Blockers and pivots should be seated on the two outer seats of each team's box,
 
 Visual cues used to direct skaters are not standardized. Most Penalty Box Managers use one arm to signal each side of the box (i.e., the skaters from one team). The arm is raised to draw the skater's attention and then lowered to point to the desired seat, repeatedly. 
 
-If the seated skater is a jammer, the Penalty Box Manager is responsible for timing their penalty.However, the Penalty Box Timer for the relevant team actually records the penalty on their paperwork. For instruction on how to perform penalty timing, reference WFTDA Online Learning's [Intro to Penalty Box Training for Officials](https://learning.wftda.org/courses/intro-to-penalty-box-training-for-officials). This guide does not cover these core procedures in deference to this resource.
+If the seated skater is a jammer, the Penalty Box Manager is responsible for timing their penalty. However, the Penalty Box Timer for the relevant team actually records the penalty on their paperwork. For instruction on how to perform penalty timing, reference WFTDA Online Learning's [Intro to Penalty Box Training for Officials](https://learning.wftda.org/courses/intro-to-penalty-box-training-for-officials). This guide does not cover these core procedures in deference to this resource.
 
 An example series of events in the penalty box might look like this:
 
@@ -213,17 +213,15 @@ If a skater in the box is bleeding, vomiting, or in a state where they cannot sa
 
 The Penalty Box Manager is empowered to assess relevant penalties unless forbidden by the Head Referee. Typically, the Penalty Box Manager will assess penalties related to entry and exit of the penalty box and to skater conduct within the penalty box.
 
-Leaving the penalty box early is an Illegal Procedure.
+- Leaving the penalty box early is an Illegal Procedure.
 
-Removing gear other than the mouthguard while seated is an Illegal Procedure - Equipment Violation ([Rules 4.4](https://rules.wftda.com/04_penalties.html#enforcing-penalties)).
+- Removing gear other than the mouthguard while seated is an Illegal Procedure - Equipment Violation ([Rules 4.4](https://rules.wftda.com/04_penalties.html#enforcing-penalties)).
 
-Anyone other than a penalized skater (such as a coach or teammate) entering the box is an Illegal Procedure. (Rules [2.1](https://rules.wftda.com/02_gameplay.html#the-track) and [4.4](https://rules.wftda.com/04_penalties.html#enforcing-penalties)). Note that putting a foot or skate into the box, or reaching into the box to hand an item to a penalized skater, does not count as entering the box. See [Casebook C4.2.4.F](https://rules.wftda.com/casebook/04_c_penalties.html#other-illegal-procedures).
+- Anyone other than a penalized skater (such as a coach or teammate) entering the box is an Illegal Procedure. (Rules [2.1](https://rules.wftda.com/02_gameplay.html#the-track) and [4.4](https://rules.wftda.com/04_penalties.html#enforcing-penalties)). Note that putting a foot or skate into the box, or reaching into the box to hand an item to a penalized skater, does not count as entering the box. See [Casebook C4.2.4.F](https://rules.wftda.com/casebook/04_c_penalties.html#other-illegal-procedures).
 
-Profanity or abusive language may be penalizable. In a WFTDA game, profanity directed at an official or audible by the audience is a Misconduct. See [Casebook C4.3.F](https://rules.wftda.com/casebook/04_c_penalties.html#penalties-for-unsporting-conduct-misconduct). 
+- Profanity or abusive language may be penalizable. In a WFTDA game, profanity directed at an official or audible by the audience is a Misconduct. See [Casebook C4.3.F](https://rules.wftda.com/casebook/04_c_penalties.html#penalties-for-unsporting-conduct-misconduct). 
 
-JRDA conduct rules are considerably stricter than WFTDA. Review [JRDA Rules](https://www.juniorrollerderby.org/rules) section J4.3.1-2 for a description of conduct violations you might observe.
-
-All profanity merits a Misconduct penalty in JRDA games, even if non-directed. See [JRDA Casebook JC4.3.1.B](https://www.juniorrollerderby.org/rules) and [JRDA Code of Conduct 5.8](https://www.juniorrollerderby.org/rules).
+  JRDA conduct rules are considerably stricter than WFTDA. Review [JRDA Rules](https://www.juniorrollerderby.org/rules) section J4.3.1-2 for a description of conduct violations you might observe. All profanity merits a Misconduct penalty in JRDA games, even if non-directed. See [JRDA Casebook JC4.3.1.B](https://www.juniorrollerderby.org/rules) and [JRDA Code of Conduct 5.8](https://www.juniorrollerderby.org/rules).
 
 When you assess a penalty, write the skater's number and the penalty code on the appropriate side of your whiteboard. Circle the penalty code to indicate that you are assessing the penalty. Hold your whiteboard up until acknowledged by the Penalty Lineup Tracker.
 
diff --git a/content/guides/penalty-lineup-tracker.md b/content/guides/penalty-lineup-tracker.md
new file mode 100644
index 0000000..32965b5
--- /dev/null
+++ b/content/guides/penalty-lineup-tracker.md
@@ -0,0 +1,246 @@
+---
+title: "Penalty Lineup Tracker"
+date: "2024-09-26"
+template: "guide.html"
+extra:
+    author: "David Reed / Stacktrace"
+---
+
+## Introduction
+
+The Penalty Lineup Tracker is arguably the broadest off-skates officiating role. The PLT is responsible for
+
+- recording a single team's lineup each jam, including any Star Passes that occur;
+- tracking entries to and exits from the Penalty Box;
+- recording the type and number of penalties for each skater on their assigned team;
+- confirming with the Penalty Box staff as each skater approaches and reaches the foul-out threshold.
+
+Because they are stationed in the center of the track and highly mobile, the PLT may also play supporting roles, such as communicating changes to the score table and penalty box. The PLT's broad responsibilities mean that the role requires excellent game knowledge and track awareness, the ability to complete complex paperwork under stress, and good communication skills. The PLT role is a good one for the Head NSO.
+
+The PLT role combines the older Penalty Tracker (PT) and Lineup Tracker (LT) roles. These roles are rarely staffed today; a full complement of one PT and two LTs is more difficult to staff than two PLTs.
+
+The Penalty Lineup Tracker's paperwork satisfies two specific requirements to sanction a roller derby game:
+
+- Per [Rules 5.1 and 5.2](https://rules.wftda.com/05_officiating.html#staffing), the officials must be staffed to track:
+  - > Which Skaters have been assessed how many penalties, and which have been served
+  - > Which Skaters are not allowed to skate (for example, due to expulsion, fouling out, or having a Jam called for their injury)
+- Per the [WFTDA Sanctioning Policy](https://static.wftda.com/sanctioning/wftda-sanctioning-policy.pdf), sections "Game Requirements for Sanctioned Games" and "Score Reporting and Games Data Requirements", the officials must be staffed to track the data required by the Statsbook sheets
+  - Penalties
+  - Lineups
+
+Hence, the Rules require tracking of penalties, and the Sanctioning Policy requires tracking of both penalties and lineups. The Penalty Lineup Tracker role is a good illustration of a near-universal convention about how to officiate in a way that meets the rules and standards. 
+
+PLTs work in the center of the track. They can move freely.
+
+### Resources
+
+- [The Rules of Flat Track Roller Derby](https://rules.wftda.com/)
+- [WFTDA Statsbook Manual](https://resources.wftda.org/competition/statsbook/)
+- [WFTDA Officiating Procedures](https://static.wftda.com/officiating/wftda-officiating-procedures.pdf)
+- [WFTDA Officiating Cues, Codes, and Signals](https://static.wftda.com/officiating/wftda-officiating-cues-codes-and-signals.pdf)
+- [WFTDA Sanctioning Policy](https://static.wftda.com/sanctioning/wftda-sanctioning-policy.pdf)
+- [WFTDA Online Learning: Intro to Penalty and Lineup Tracking Training for Officials](https://learning.wftda.org/courses/intro-to-penalty-and-lineup-tracking-training-for-officials)
+- [JRDA Rules, Casebook, and Code of Conduct](https://www.juniorrollerderby.org/rules)
+
+## Equipment
+
+The only equipment used by the PLT is a clipboard and pencil, unless [ePLT](#eplt) is being used.
+
+PLTs can work in face masks.
+
+## The Basic Routine
+
+The Penalty Lineup Tracker is active throughout the game, but moves between multiple aspects of the role. 
+
+### During the Lineup Period
+
+As your team lines up for the jam, record the player numbers in the Lineup section of your paperwork. Follow the guidance in the [Statsbook Manual](https://resources.wftda.org/competition/statsbook/) to complete the paperwork correctly. This guide defers to the Statsbook Manual and does not cover the basics of the Penalty Lineup Tracker paperwork.
+
+Make sure you're aware of the notation for less-common situations. If the team does not field a pivot, make sure to mark the _noPivot_ box for the jam. Mark the box for any blocker not fielded with "n/a" to be clear that it wasn't simply _missed_, but actually not fielded. If you do miss a skater, mark a "?".
+
+While you record the lineup, ensure that the players on the track are eligible to skate:
+
+- Any skater whose injury alters the flow of the game (including a jam being called for injury, which is recorded on the PLT paperwork, as well as penalty box substitutions) must sit for three jams before playing again. (See Rules [1.2](https://rules.wftda.com/01_params.html)).
+   - If the same skater's injury alters the flow of the game more than once in the same period, they may not skate for the rest of the period.
+   - Keep in mind that the skater must _sit for three full jams_. So, for example, if a skater's injury results in Jam 13 being called off, they are eligible to skate again in Jam 17, but _not_ in Jam 16. They must sit for the three full Jams 14, 15, and 16.
+- Skaters whose numbers are not on the roster, or who are wearing incorrect numbers, should not be allowed to skate.
+   - Enforcing this rubric is mandatory for sanctioned games, for which charters must be submitted in advance. Your local convention may permit some flexibility for non-sanctioned games.
+
+Only the PLT's paperwork tracks this information. You hold the primary and nearly sole responsibility for this duty, as other officials are unlikely to remember the specific timing of injury-related stoppages or have access to the full roster.
+
+Ensure that any players _required_ to be on the track are in fact on the track:
+
+- At least one Blocker from each team.
+- Exactly one Jammer from each team.
+- Any skater who is in the queue to report to the Penalty Box, in the position in which they're required to report. The Penalty Box Manager signals this status by holding up their white board.
+
+The [Jam Timer](@/guides/jam-timer.md#are-the-right-skaters-present-on-the-track-at-the-jam-start-whistle) and referees should also be watching for signals from the Penalty Box Manager, but you are most likely to have a yes-no answer as to whether queued skaters are on the track.
+
+If there is an issue with the skaters on track (or missing from the track), advise the Jam Timer and Head Referee. The jam should not start and a penalty may be assessed.
+
+If the jam does start when it should not have started, it may be called off immediately and transition into an Official Time Out. Consult with the Head NSO and the other officials whose paperwork or software tracks jam numbers (the Scorekeepers, the Penalty Box Timers, and the Scoreboard Operator) to ensure that you're all in sync with the jam number. In most cases, the jam that should not have been started will be struck from the sequence.
+
+See also [Officiating Procedures 6.1.1](https://resources.wftda.org/officiating/standards-and-procedures/), which specifies that a jam started in error should be allowed to conclude naturally in a situation where a queued skater is not lined up. The jam started in error _must_ be whistled dead if an injured skater returns to play too early.
+
+### During the Jam
+
+#### Capture Penalties, Entrances, and Exits
+
+Listen for whistled penalty calls. As you hear each penalty, record it in the Penalties section of your paperwork, as described by the Statsbook Manual. 
+
+Acknowledge each penalty call you hear. Conventions vary: some PLTs echo the entire call, while others call "Got it!" You can also echo the hand signal to ensure the referee and all onlookers know what penalty was caught. Acknowledging calls lets referees know their penalty was accurately caught and that they do not need to seek you out after the jam. It also allows onlookers who may or may not see the referee to observe the penalty call.
+
+As skaters enter and exit the Penalty Box, record these events in the Lineups section of your paperwork, as instructed by the Statsbook Manual.
+
+If you can do so without impacting your own duties, you can also support your other PLT by supplying information they missed, or echoing penalty signals for them while they are occupied. In some regions, a role called the Penalty Wrangler may provide this support. Some Jam Timers also support PLTs by helping catch information. Communicate with your inside-track crew and get a comfortable rhythm set up.
+
+##### Handling Missed Information
+
+Sometimes, you may only have a portion of the information you need for a call. A Forearm was called in Turn 2, but you couldn't see or hear the skater's number. Or Black 84 reported to the box, but you didn't see the call. Or an OPR called "White 949, cut!" but gave the hand signal for a Direction penalty. Or three penalties were called at once, and you're not sure which one goes with which skater.
+
+**Write down what you have**. You can go ahead and record a penalty and box entry with a "?" code, or make notes in the margin of your paperwork. Get down what you can as quickly as possible so that you do not fall further behind as the jam continues. If you can observe missing information, like a skater's number as they sit in the box, do so. Then, when the jam ends, go to the referees. Tell them what information you have and what you need. ("Who had the call on Black 84 in Turn 3? I need the penalty.") If you're aware of where the penalty was called, such as by a jam referee or an outside pack referee, go directly to the relevant official.
+
+If you need to, you can call an Official Time Out to stop play until you gather all of the required penalty information and are sure your paperwork is correct.
+
+To be effective in this duty, you must know the penalty cues and signals. Make sure you're completely comfortable with the [WFTDA Officiating Cues, Codes, and Signals](https://resources.wftda.org/officiating/standards-and-procedures/) document.
+
+#### Capture Star Passes
+
+Like Scorekeepers, Penalty Lineup Trackers need to record the Star Passes of both teams. Star Passes are entered only in the Lineups section of the paperwork. See the [Statsbook Manual](https://resources.wftda.org/competition/statsbook/), pages 19 and 20, for examples of the notation.
+
+The reason for capturing Star Passes for both teams is that Lineups data is entered into the Statsbook with a single row representing the data for _both_ teams in each jam. Recording the other team's Star Passes ensures that jams continue to "line up" horizontally when entered into the Statsbook.
+
+While your paperwork looks like this, during a Star Pass for your own team:
+
+{% plt() %}
+10 - 34 - - - 98 - - - 465 - - - 12 - - - 82 - - -
+SP X 34 - - - 98 - - - 465 - - - 12 - - - 82 - - -
+{% end %}
+
+when entered into the Statsbook, it'll look like this (abbreviated to one blocker to show the structure more clearly). Note how the data for a single jam occupies a full row, with one team on the left and one on the right.
+
+{% plt_full() %}
+10 - 34 - - - 98 - - - - 10 - 002 - - - 21 - - -
+SP X 98 - - - 34 - - - - SP* - 002 - - - 21 - - -
+{% end %}
+
+If a Penalty Lineup Tracker misses the Star Pass, the result rapidly becomes confusing:
+
+{% plt_full() %}
+10 - 34 - - - 98 - - - - 10 - 002 - - - 21 - - -
+SP X 98 - - - 32 - - - - 11 - 999 - - - 21 - - -
+{% end %}
+
+In this situation, the data for Away Team's Jam 11 is conflated with the Home Team's Star Pass in Jam 10. Further jams will continue not to line up correctly, until the situation is corrected by the Head NSO or stats crew.
+
+If you do miss a Star Pass, it's not the end of the world. Make a margin note in your paperwork so that this is easily caught. It's generally not a good idea to try to erase and rewrite much data after the fact.
+
+
+#### Record Injuries
+
+If a jam is called due to injury, make sure that the player whose injury caused the call-off is marked with the "3" code as instructed by the Statsbook Manual. You'll use this notation to ensure that this skater does not line up until they've sat out for their required 3 jams (see under ["During the Lineup Period"](#during-the-lineup-period)).
+
+You may use the nonstandard cue for "called due to injury" by making finger guns and touching the tips of your index fingers together in a horizontal line, to ensure this information is relayed to the score table. Referees may also use such cues to communicate to you.
+
+If you're unsure whether a jam was called due to injury or not, ask the referees.
+
+#### Communication with the Penalty Box
+
+The Penalty Box needs to know when a double penalty occurs so that they sit the skater for the right amount of time. The Penalty Lineup Tracker and the referee assessing the penalty will often both signal this. Use the cue defined in the [Cues, Codes, and Signals document](https://resources.wftda.org/officiating/standards-and-procedures/) (page 3), and ensure that the box staff acknowledge the signal before you proceed.
+
+Most double penalties, though by no means all, are an initial penalty followed by either an Illegal Procedure or a Misconduct for an illegal exit. As you're watching the penalty call, you can often anticipate double penalties by observing the skater's exit.
+
+---
+
+Because foulouts are incredibly impactful on the game, the Penalty Lineup Tracker and the Penalty Box staff invest considerable effort to verify penalty counts. During play, the Penalty Lineup Tracker should signal to the Penalty Box when each player reaches five, six, and seven penalties. The signals used are widespread but not formally documented, and consist of a hand placed over the chest with five fingers extended (five penalties), one finger extended (six penalties), or two fingers extended (seven penalties / foulout). See also the discussion below about verification during [stoppages of play](#play-stoppages-and-end-of-period).
+
+In many cases, the Penalty Box Manager will be responsible for receiving and acknowledging this signal, because they are likely to have their heads up while Penalty Box Timers may be focused on their clocks. However, it's fine for any Penalty Box official to acknowledge the signal, and crews vary in their preferences.
+
+If your counts do not line up with the Penalty Box, call an Official Time Out and use this time to resolve the discrepancy. Because penalty counts are highly impactful, it's justified to pause play until you're clear.
+
+---
+
+When a foulout or an expulsion does occur, make sure it is marked as such on your paperwork.
+
+In many cases, you will be the official best positioned to communicate that a substitute is or is not required to serve the balance of a penalty after a foulout. The Penalty Box Manager or Timer should provide you this information, but you're typically much more mobile than they are and can either directly tell the team to send a substitute or delegate a referee to do so.
+
+It's possible to handle a foulout with substitution without a stoppage of play (during the lineup period following the jam in which the foulout occurred) if the penalty management officials are proactive and the team responds quickly. If necessary, ask the Jam Timer for an Official Time Out to get a substitute seated.
+
+### Play Stoppages and End-of-Period
+
+During timeouts and Official Reviews, as well as after each period ends, verify your penalty counts with the Penalty Box Timer for your team. During play stoppages, you can choose to verify the total count (i.e., "I have 3 total penalties for this half"), or go down the roster and confirm penalties by skater, based on how much time you have available and how complex the gameplay has been.
+
+At the end of a period, you should always verify the penalty count for each skater individually. You may choose (depending on your local convention and your crew expectations) to verify more data, such as when the skater entered for each penalty and which penalties involved a "Sat Between Jams" entry. The author of this guide feels that verification beyond the penalty count per-skater is rarely worth the effort. Check with your Head NSO if you're unsure about expectations.
+
+---
+
+At halftime, follow the instructions in the Statsbook Manual to prepare your paperwork for the second period. 
+
+Once you've verified your penalty count with the Penalty Box Timer for each period, provide the total penalty count to the Head NSO, who enters it on the IGRF.
+
+If you have time, you can also verify Star Pass counts with the other Penalty Tracker and a Scorekeeper. Bear in mind, however, that the primary impact of Star Pass agreement on paperwork is after the game when the Statsbook is being prepared. Make sure to get your penalty counts and other duties taken care of first, because they have immediate game impact.
+
+There is an unofficial signal: touch your head with one hand, and hold up a number of fingers to indicate the star pass count. If you want to use a signal convention, talk to the scorekeepers before the game to ensure you're on the same page.
+
+## Paperwork and Operational Nuances
+
+### Penalties versus Box Entries
+
+The PLT paperwork makes more sense when you understand that it is the fusion of two older forms of the paperwork, for the Penalty Tracker and Lineup Tracker roles. Those older forms are the source of the two distinct ways in which penalties are recorded on the PLT paperwork.
+
+The left-hand side of the PLT paperwork tracks _lineups_, and comes from the old Lineup Tracker position. In lineup-tracking mode, you record _box entries and exits_. Your concern in this mode is not when the penalty was assessed (or even how many penalties were assessed), but in when the skater physically entered and exited the penalty box. Your paperwork here aligns with the Penalty Box Timer's, which also records entries and exits.
+
+The right-hand side of the PLT paperwork tracks _penalties_, and comes from the old Penalty Tracker position. In penalty-tracking mode, you record _penalties assessed_. In this mode, you care about what kind of penalty was assessed and the jam in which it was assessed, but not when it was served.
+
+As a result of these distinct rubrics, you may record the same event in different jams on the left- and right-hand side of your paperwork, and you may have different numbers of entries on those sides as well.
+
+Imagine that Black 34 receives two penalties in Jam 10, a Back Block and an Illegal Procedure for failing to leave the track. By the time Black 34 reaches the Penalty Box, the jam has concluded (they sit between jams). You'd record that event like this:
+
+{% plt() %}
+10 - 34 - - - - - - - - - - - - - - - - - - -
+11 - 34 S - - - - - - - - - - - - - - - - - -
+12 - 34 $ - - - - - - - - - - - - - - - - - -
+{% end %}
+
+{% plt_penalties() %}
+34 B10 I10 - - - - - - - -
+{% end %}
+
+Notice that the event is shown in Jam 10 under the Penalty Tracking side, but Jam 11 under the Lineup Tracking side (with an "S" indicating the skater sat between jams). Further, the double penalty is shown on the Penalty Tracking side, but the Lineup Tracking side records only a single box entry.
+
+Marginal notes can help you keep track of double penalties, so that your count of box entries can continue to align with the count of penalties recorded. This is a useful self-check to ensure that you don't miss any data entry.
+
+### Substitutions in the Penalty Box
+
+There is no special notation for a substitution in the penalty box. Simply record the new skater's number in the appropriate box as a _continuation_ of the previous penalty (not a new box entry).
+
+### ePLT
+
+"ePLT" refers to using a tablet to complete Penalty Lineup Tracker data entry. The tablet is linked to the CRG Scoreboard software, meaning that data is integrated with the entries of the Scoreboard Operator.
+
+Even in a venue that consistently uses ePLT, you should always be prepared to execute PLT responsibilities on paper. Technology fails; batteries drain; tablets get lost or broken. 
+
+This section isn't a complete guide to ePLT, but intends to highlight significant differences for skilled paper-based PLTs. For more information, review the CRG Scoreboard documentation for [Lineup Tracking](https://github.com/rollerderby/scoreboard/wiki/Lineup-Tracking) and [Penalty Tracking](https://github.com/rollerderby/scoreboard/wiki/Penalty-Tracking).
+
+#### Coordinating with the Scoreboard Operator
+
+Because ePLT is connected to the scoreboard, some data entry overlaps with the [Scoreboard Operator](@/guides/scoreboard-operator.md):
+
+- Jammer numbers
+- Pivot numbers
+- Star Passes
+
+ePLTs only enter their own Star Passes.
+
+Coordinate with the Scoreboard Operator on how these data will be entered so that you don't trip over one another or overwrite existing data entry.
+
+#### User Interface
+
+When you record a penalty, you'll tap the Penalties section of the UI and select the penalty code. Then, use the Box button next to the skater to record both the entry and exit event. The button will change color to show you what state the skater's trip is in. The software will construct the "-", "+", "S", and "$" codes for you.
+
+Tap in the paperwork section to mark "n/a" for a skater who's not fielded. Note that the touch target is quite small; make sure you hit the correct cell.
+
+The ePLT screen uses color and boldface extensively to denote information. While it presents a total penalty count for the game, no penalty total by period is presented. If you verify with the Penalty Box Timers using the total count for the period, make sure to count second-period penalties manually.
+
+Be aware that the order of operations is important. Data that you enter by hand in the paperwork, such as whether a skater entered the Penalty Box betweeen jams, is _inferred_ by the software. Aim to preserve the chronological order of events as you enter them.
+
diff --git a/content/guides/scorekeeper.md b/content/guides/scorekeeper.md
index 7e2430e..de078a0 100644
--- a/content/guides/scorekeeper.md
+++ b/content/guides/scorekeeper.md
@@ -11,7 +11,7 @@ extra:
 
 As with all officiating positions in roller derby, it’s important to be aware that Scorekeeping is a combination of *what the rules explicitly say*, *how the rules are interpreted by the community*, and *common practices that are not rule-driven*.
 
-Scorekeeping, in particular, is driven by the needs of the WFTDA Statsbook. 
+Scorekeeping, in particular, is driven by the needs of the WFTDA Statsbook. TODO
 
 ## Resources
 
@@ -28,7 +28,7 @@ Scorekeepers are typically seated on each side of the scoreboard operator, but t
 
 Watch your Jam Referee and Jammer (in that order) during each jam. Follow the Statsbook Manual's instructions to record points and jam events (Lost Lead, Lead, Call, Injury, No Initial; Star Passes). **This guide deliberately does not cover the paperwork, because the Statsbook Manual is the authority**.
 
-When each event happens, or when points are awarded, verbally communicate it to the Scoreboard Operator. The Scoreboard Operator will often echo this back to you to indicate that they received it.
+When each event happens, or when points are awarded, verbally communicate it to the Scoreboard Operator. The Scoreboard Operator should echo this back to you to indicate that they received it.
 
 For example, a jam might go like this:
 
@@ -59,7 +59,7 @@ For example, a jam might go like this:
 
 The conversation doesn't have to go exactly like this. Nobody needs to use these exact phrases. The scorekeepers could confirm the total rather than the scoreboard operator. Someone might miss an event and hear it from a colleague. 
 
-What's important in this example is that the two scorekeepers and the scoreboard operator are _talking constantly_. They make sure that everyone has the information they need to do their jobs. They acknowledge that a game environment is noisy and fast-moving by acknowledging what they hear. And they make sure to confirm their most important job - keeping the visible score accurate - constantly, so that problems are caught right away while the rules still permit a correction.
+What's important in this example is that the two scorekeepers and the scoreboard operator are _talking constantly_. They make sure that everyone has the information they need to do their jobs. They acknowledge that a game environment is noisy and fast-moving by confirming what they hear. And they make sure to check their most important job - keeping the visible score accurate - constantly, so that problems are caught right away while the rules still permit a correction.
 
 Why call out these specific pieces of information?
 
@@ -67,6 +67,16 @@ Why call out these specific pieces of information?
 - The scorekeepers _both_ record star passes for _both_ teams. Since each scorekeeper is watching their own Jam Referee, they need to make sure their counterparts receive notice when a star pass occurs for the other team.
 - Redundancy - the two scorekeepers plus that data in the scoreboard - increases the likelihood that a correct game record can be achieved during statsbook data entry. 
 
+---
+
+Your Jam Referee will signal points to you starting when the jammer leaves the Engagement Zone (TODO reference). Many Jam Referees will continue to signal until the jammer enters the Engagement Zone for their next scoring trip. You should do the same. Remember that your signal may be seen by others throughout the venue, not just by your Jam Referee confirming that you've caught the points.
+
+You do not need to echo other signals, such as the Lead sign or No Pass-No Penalty. Some scorekeepers do, but it may provoke confusion.
+
+### Start-of-Game Check-ins
+
+Before the game, your assigned Jammer Referee should meet with you to show you their hand signals. Echo the signals back to them as they make them. Make sure to ask the Jammer Referee what signal they use for "No Initial Trip": there is no standard signal for this, and a number of different conventions are in wide use.
+
 ### End-of-Period and End-of-Game Responsibilities
 
 At the end of each period, the scorekeeper should perform a series of steps to validate their points and paperwork.
@@ -79,12 +89,6 @@ At the end of each period, the scorekeeper should perform a series of steps to v
 
 ### Jam Referee
 
-Your Jam Referee will signal points to you starting when the jammer leaves the Engagement Zone (TODO reference). Many Jam Referees will continue to signal until the jammer enters the Engagement Zone for their next scoring trip. You should do the same. Remember that your signal may be seen by others throughout the venue, not just by your Jam Referee confirming that you've caught the points.
-
-You do not need to echo other signals, such as the Lead sign. Some scorekeepers do, but it may provoke confusion.
-
-There is no standardized hand signal for "no initial trip". There are several widespread conventions with more or less equal popularity. You should always ask your Jam Referee before the game how they signal a "no initial" to you, and be prepared to echo using the same signal.
-
 There is no standard signal for "a star pass occurred". It is very common for referees and NSOs based in the center of the track to signal this by touching their hands and raising their hands repeatedly, sometimes with a plucking motion. This may indicate a star pass for _either_ team. You may echo this signal but don't need to.
 
 _Always_ make sure that your co-scorekeeper and scoreboard operator are aware of the star pass.
@@ -99,9 +103,11 @@ Confirming star pass count
 
 ## Paperwork Beyond the Manual
 
-Many experienced scorekeepers go beyond what's specified in the Statsbook Manual.
+Many experienced scorekeepers go beyond what's specified in the Statsbook Manual. The conventions you adopt should always be _additive_, not _contrastive_: you can write down more information than the Statsbook Manual requires in the margins or un-marked areas of your paperwork, but do not make non-standard marks in standard spaces. This will produce confusion for your Head NSO when they complete the statsbook.
+
+Writing down the pivot's number in the margin of your score sheet, to the left of the Jam column, is a very common and useful convention. This ensures that when a star pass occurs, you have the pivot number you need at hand; you may not be able to see the pivot when the star pass actually takes place. It also allows your paperwork to support the Penalty Lineup Tracker's during statsbook data entry.
 
-It's a good idea to always write down your pivot's number in the margin of your score sheet, to the left of the Jam column. This ensures that when a star pass occurs, you have the information at hand. It also allows your paperwork to support the Penalty Lineup Tracker's during statsbook data entry.
+It may be useful to mark the margin of your paperwork with a symbol, such as a horizontal line, on each jam in which a Star Pass occurs. This makes it easier for you to rapidly count Star Passes to confirm that you are in sync with the other scorekeeper or with a Penalty Lineup Tracker.
 
 Some scorekeepers use "Dot System". Dot System is a way to annotate your paperwork with more information about the progress of the jam, which can help you keep track of scoring trips. This guide deliberately does not cover Dot System. You can read about it [here](TODO). We neither encourage nor discourage the Dot System. We encourage reviewing it and experimenting to find what makes you most effective.
 
@@ -111,6 +117,57 @@ Some scorekeepers use "Dot System". Dot System is a way to annotate your paperwo
 
 ## Common Paperwork Mistakes
 
+### Star Passes and Trips
+
+Notating Star Passes is often confusing for newer scorekeepers. The key principles to remember are:
+
+1. The _meanings_ of all of the boxes on your paperwork stay the same.
+1. A completed scoring trip belongs to the jammer who finished the trip.
+
+For example, suppose that White 32 passes the star to the pivot, White 494, during the initial trip. White 494 is unable to clear the pack, and never starts their first scoring trip. You'd record it like this:
+
+{% score() %}
+1 32 - - - - X - - - - - - - - 0 0
+SP 494 - - - - X - - - - - - - - 0 0
+{% end %}
+
+The definition of the "No Initial Trip" box stays the same. _Both_ jammers failed to complete an initial pass, so it's marked for both.
+
+What if White 494 _had_ gotten out of the pack, but the opposing jammer called the jam before they could score any points?
+
+{% score() %}
+1 32 - - - - X - - - - - - - - 0 0
+SP 494 - - - - - 0 - - - - - - - 0 0
+{% end %}
+
+The definitions stay the same: White 32 had no initial trip, but White 494 did complete the initial trip. White 494 started the scoring trip, so the 0 belongs to them and goes on the Star Pass row.
+
+Take a different scenario. Blue 02 gets Lead status. They score 4 points on the first scoring trip. During the second scoring trip, they get stuck and pass the star to Blue 999, who completes the second and third scoring trips. We'd complete the paperwork thus:
+
+{% score() %}
+1 02 X X - - - 4 - - - - - - - 4 4
+SP 999 - - - - - - 4 3 - - - - - 7 11
+{% end %}
+
+Definitions stay the same. Jammer 02 got Lead, and then Lost Lead by removing their helmet cover. Both of those marks belong to the row for Jam 1. The Jam Total and Game Total columns function just like they do elsewhere: total up the points for each row, and maintain the running total.
+
+Jammer 02 completed the first scoring trip _before_ they passed the star, so the first 4 belongs to their row. However, Blue 02 did _not_ complete the second scoring trip; Blue 999 did. The points for scoring trips 2 and 3 _both_ go in the row for Blue 999, the Star Pass row. It's irrelevant if Blue 02 actually earned some points before handing off the star. The record of the scoring trip belongs to the skater who completed the trip.
+
+The Statsbook Manual offers many examples of how to complete Star Pass paperwork correctly. Apply these two principles consistently and you'll be able to handle any in-game situation.
+
+### Missed Star Passes
+
+{% score() %}
+1 32 - X X - - 4 - - - - - - - 4 4
+2 99 - X X - - 4 4 - - - - - - 8 12
+{% end %}
+
+### Closing Zero Trips
+
+### Lost Lead
+
+### Math Errors
+
 ## Score Corrections
 
 Mistakes happen all the time. Roller derby is not a precise science!
@@ -139,3 +196,4 @@ It's very common for scorekeepers to have limited experience in the position. Cr
 In many cases, but certainly not all, the scoreboard operator is a more experienced non-skating official. (The scoreboard is not difficult to operate, but has many challenges and edge cases). If that's your situation, take advantage of their expertise. Draw on your other scorekeeper too, or lend them your expertise if they need it. However, always make sure to do your own job first.
 
 When the NSO crew is very limited, it's possible to go with a single scorekeeper and a scoreboard operator. In extreme circumstances, it's possible even to have the scoreboard operator catch points for both teams. While this situation _could_ meet the standards for a sanctioned game (which does not require a specific position count for NSOs), it's very risky and not recommended.
+.
\ No newline at end of file
diff --git a/flake.nix b/flake.nix
index 6dcf167..a8fb638 100644
--- a/flake.nix
+++ b/flake.nix
@@ -9,7 +9,7 @@
       let pkgs = import nixpkgs { system = system; config.allowUnfree = true; }; in
       {
         devShells.default = pkgs.mkShell {
-          packages = with pkgs; [ zola just python312Packages.weasyprint inotify-tools pandoc corefonts ];
+          packages = with pkgs; [ zola just python312Packages.weasyprint inotify-tools pandoc corefonts yq-go ];
           # See https://discourse.nixos.org/t/ensure-fonts-in-development-environment/20649/4
           FONTCONFIG_FILE = pkgs.makeFontsConf {
             fontDirectories = [ pkgs.corefonts ];
diff --git a/justfile b/justfile
index 7d7b788..e0bd1f8 100644
--- a/justfile
+++ b/justfile
@@ -5,12 +5,17 @@ render: build
 	#!/usr/bin/env bash
 	for guide in public/guides/*/index.html; do
 		base="$(basename $(dirname $guide))"
-		weasyprint "$guide" "$(dirname $guide)/$base.pdf" -s build-assets/print.css		
-		pandoc -r commonmark+yaml_metadata_block \
-			   -w epub --toc --css build-assets/print.css \
-			   --metadata-file build-assets/epub-metadata.txt \
+		weasyprint "$guide" "$(dirname $guide)/$base.pdf" \
+			-s build-assets/print.css -s static/statsbook.css	
+		pandoc -r html -w epub \
+				--toc --lua-filter build-assets/epub.lua \
+				--css build-assets/epub.css \
+			    --css static/statsbook.css \
+			    --metadata-file build-assets/epub-metadata.yaml \
 				-M "publisher=https://nonskating.club/guides/$base/" \
-			   "content/guides/$base.md" -o "$(dirname $guide)/$base.epub"
+				-M "author=$(yq --front-matter=extract '.extra.author' content/guides/$base.md)" \
+				-M "date=$(yq --front-matter=extract '.date' content/guides/$base.md)" \
+			    "$guide" -o "$(dirname $guide)/$base.epub"
 	done
 
 watch:
@@ -19,5 +24,7 @@ watch:
 		--exclude "(.*\\.pdf$)|public|justfile|\\.git" \
 		-e close_write,move,create,delete \
 	| while read -r directory events filename; do
+		pkill -f zola
 		just render
+		zola serve
 	done
diff --git a/static/statsbook.css b/static/statsbook.css
new file mode 100644
index 0000000..730bd2a
--- /dev/null
+++ b/static/statsbook.css
@@ -0,0 +1,210 @@
+:root {
+    --pink: #F8A4A7;
+    --light-pink: #fcd2d4;
+    --light-blue: #eeeef6;
+    --blue: #d3d2e7;
+    --box-blue: #cbcae3;
+    --light-green: #e9f5da;
+    --green: #d3ecb5;
+}
+
+table.nso {
+    border-collapse: collapse;
+    margin-left: auto;
+    margin-right: auto;
+    page-break-inside: avoid;
+    margin-top: 2em;
+    margin-bottom: 2em;
+}
+
+table.nso thead th {
+    background-color: black !important;
+    color: white;
+    font-size: 50%;
+}
+
+table.nso tr,
+table.nso td,
+table.nso th {
+    border: 1px black solid;
+    color: black;
+    text-align: center;
+}
+
+/* PLT */
+
+/* Highlight the Box columns in darker blue */
+table.plt td:nth-of-type(4n+4),
+table.plt td:nth-of-type(4n+5),
+table.plt td:nth-of-type(4n+6) {
+    background-color: var(--box-blue);
+    width: 1em;
+    max-width: 1em;
+    min-width: 1em;
+    padding: 0.1em;
+}
+
+table.plt tr:nth-of-type(even) {
+    background-color: var(--light-blue);
+}
+
+table.plt tr:nth-of-type(odd) {
+    background-color: white;
+}
+
+/* PLT - Full Width*/
+
+/* Highlight the Box columns in darker blue */
+table.plt-full td.home:nth-of-type(4n+4),
+table.plt-full td.home:nth-of-type(4n+5),
+table.plt-full td.home:nth-of-type(4n+6) {
+    background-color: var(--box-blue);
+    width: 1em;
+    max-width: 1em;
+    min-width: 1em;
+    padding: 0.1em;
+}
+
+/* Highlight the Box columns in darker blue */
+table.plt-full td.away:nth-of-type(4n+15),
+table.plt-full td.away:nth-of-type(4n+16),
+table.plt-full td.away:nth-of-type(4n+17) {
+    background-color: var(--box-blue);
+    width: 1em;
+    max-width: 1em;
+    min-width: 1em;
+    padding: 0.1em;
+}
+
+
+table.plt-full tr:nth-of-type(even) {
+    background-color: var(--light-blue);
+}
+
+table.plt-full tr:nth-of-type(odd) {
+    background-color: white;
+}
+
+
+/* PLT Penalties */
+
+table.plt-penalties tr:nth-of-type(even) {
+    border-bottom: 2px black solid;
+}
+
+table.plt-penalties tr td {
+    height: 1.5em;
+}
+
+table.plt-penalties tr td:not(:first-child) {
+    min-width: 2em;
+    width: 2em;
+    max-width: 2em;
+}
+
+/* White-backed rows */
+table.plt-penalties tr:nth-of-type(4n-2) td,
+table.plt-penalties tr:nth-of-type(4n-3) td {
+    background-color: white;
+}
+
+/* Skater number */
+table.plt-penalties tr:nth-of-type(4n-2) th,
+table.plt-penalties tr:nth-of-type(4n-3) th {
+    background-color: var(--light-pink);
+}
+
+
+/* Pink-backed rows */
+table.plt-penalties tr:nth-of-type(4n) td,
+table.plt-penalties tr:nth-of-type(4n-1) td {
+    background-color: var(--light-pink);
+}
+
+/* Skater number */
+table.plt-penalties tr:nth-of-type(4n) th,
+table.plt-penalties tr:nth-of-type(4n-1) th {
+    background-color: var(--pink);
+}
+
+/* Heavier stroke at the foulout point */
+table.plt-penalties td:nth-of-type(7) {
+    border-left: 4px solid black;
+}
+
+/* and at the FO/EXP line */
+table.plt-penalties td:nth-of-type(10) {
+    border-left: 2px solid black;
+    background-color: var(--pink) !important;
+}
+
+/* Score */
+
+/* The five flags (LOST LEAD CALL INJ. N.I.) 
+   Render the headers with vertical text.
+   Make the columns slim and the same width.
+*/
+table.score th:nth-of-type(3),
+table.score th:nth-of-type(4),
+table.score th:nth-of-type(5),
+table.score th:nth-of-type(6),
+table.score th:nth-of-type(7) {
+    writing-mode: vertical-lr;
+    width: 1em;
+    max-width: 1em;
+    min-width: 1em;
+    padding: 0.1em;
+}
+
+table.score td:nth-of-type(3),
+table.score td:nth-of-type(4),
+table.score td:nth-of-type(5),
+table.score td:nth-of-type(6),
+table.score td:nth-of-type(7) {
+    width: 1em;
+    max-width: 1em;
+    min-width: 1em;
+    padding: 0.1em;
+}
+
+/* Table row backgrounds. Start white and alternate with light green */
+table.score tr:nth-of-type(even) td {
+    background-color: var(--light-green);
+}
+
+table.score tr:nth-of-type(odd) td {
+    background-color: white;
+}
+
+/* Darker backgrounds used on the Jam and flag columns */
+
+/* For white rows */
+table.score tr:nth-of-type(odd) td:nth-of-type(1),
+table.score tr:nth-of-type(odd) td:nth-of-type(3),
+table.score tr:nth-of-type(odd) td:nth-of-type(4),
+table.score tr:nth-of-type(odd) td:nth-of-type(5),
+table.score tr:nth-of-type(odd) td:nth-of-type(6),
+table.score tr:nth-of-type(odd) td:nth-of-type(7) {
+    background-color: var(--light-green);
+}
+
+/* For green rows */
+table.score tr:nth-of-type(even) td:nth-of-type(1),
+table.score tr:nth-of-type(even) td:nth-of-type(3),
+table.score tr:nth-of-type(even) td:nth-of-type(4),
+table.score tr:nth-of-type(even) td:nth-of-type(5),
+table.score tr:nth-of-type(even) td:nth-of-type(6),
+table.score tr:nth-of-type(even) td:nth-of-type(7) {
+    background-color: var(--green);
+}
+
+
+/* Darker background used on the Game Total column */
+
+table.score td:nth-last-of-type(1) {
+    background-color: var(--green) !important;
+}
+
+table.score tr td {
+    height: 1.5em;
+}
\ No newline at end of file
diff --git a/templates/guide.html b/templates/guide.html
index 9533451..0923fbd 100644
--- a/templates/guide.html
+++ b/templates/guide.html
@@ -2,6 +2,10 @@
 
 {% import "ns-macros.html" as macros %}
 
+{% block css %}
+<link rel="stylesheet" type="text/css" href="/statsbook.css">
+{% endblock %}
+
 {% block content %}
 
 <style>
diff --git a/templates/shortcodes/plt.html b/templates/shortcodes/plt.html
new file mode 100644
index 0000000..d574cab
--- /dev/null
+++ b/templates/shortcodes/plt.html
@@ -0,0 +1,27 @@
+<table class="nso plt">
+    <thead>
+    <tr>
+        <th>Jam</th>
+        <th>noPivot</th>
+        <th>Jammer</th>
+        <th colspan="3">Box</th>
+        <th>Pivot</th>
+        <th colspan="3">Box</th>
+        <th>Blocker</th>
+        <th colspan="3">Box</th>
+        <th>Blocker</th>
+        <th colspan="3">Box</th>
+        <th>Blocker</th>
+        <th colspan="3">Box</th>
+    </tr>
+    </thead>
+    {% set rows = body | split(pat="\n") %}
+    {% for row in rows %}
+    <tr>
+        {% set values = row | split(pat=" ") %}
+        {% for elem in values %}
+        <td>{% if elem != "-"%}{{ elem }}{% endif %}</td>
+        {% endfor %}
+    </tr>
+    {% endfor %}
+</table>
diff --git a/templates/shortcodes/plt_full.html b/templates/shortcodes/plt_full.html
new file mode 100644
index 0000000..c8c4447
--- /dev/null
+++ b/templates/shortcodes/plt_full.html
@@ -0,0 +1,28 @@
+<table class="nso plt-full">
+    <thead>
+    <tr>
+        <th>Jam</th>
+        <th>noPivot</th>
+        <th>Jammer</th>
+        <th colspan="3">Box</th>
+        <th>Pivot</th>
+        <th colspan="3">Box</th>
+        <th>Roster</th>
+        <th>Jam</th>
+        <th>noPivot</th>
+        <th>Jammer</th>
+        <th colspan="3">Box</th>
+        <th>Pivot</th>
+        <th colspan="3">Box</th>
+    </tr>
+    </thead>
+    {% set rows = body | split(pat="\n") %}
+    {% for row in rows %}
+    <tr>
+        {% set values = row | split(pat=" ") %}
+        {% for elem in values %}
+        <td class="{% if loop.index <= 10 %}home{% else %}away{%endif%}">{% if elem != "-"%}{{ elem }}{% endif %}</td>
+        {% endfor %}
+    </tr>
+    {% endfor %}
+</table>
diff --git a/templates/shortcodes/plt_penalties.html b/templates/shortcodes/plt_penalties.html
new file mode 100644
index 0000000..a4b8c77
--- /dev/null
+++ b/templates/shortcodes/plt_penalties.html
@@ -0,0 +1,36 @@
+<table class="nso plt-penalties">
+    <thead>
+        <tr>
+            <th>Roster</th>
+            <th colspan="9">Penalties</th>
+            <th><abbr title="Foulout/Expulsion">FO/EXP</abbr></th>
+        </tr>
+    </thead>
+    {% set rows = body | split(pat="\n") %}
+    {% for row in rows %}
+    <tr>
+        {% set values = row | split(pat=" ") %}
+        {% for elem in values %}
+        {% if loop.index == 1 %}
+        <th rowspan="2">
+            {{ elem }}
+        </th>
+        {% else %}
+        {% set penalty_code = elem | truncate(length=1, end="") %}
+        <td>{% if penalty_code != "-"%}{{ penalty_code }}{% endif %}</td>
+        {% endif %}
+        {% endfor %}
+    </tr>
+    <tr>
+        {% set values = row | split(pat=" ") %}
+        {% for elem in values %}
+        {% if loop.index == 1 %}
+        {% else %}
+        {% set penalty_code = elem | truncate(length=1, end="") %}
+        {% set jam_number = elem | replace(from=penalty_code, to="") %}
+        <td>{% if penalty_code != "-"%}{{ jam_number }}{% endif %}</td>
+        {% endif %}
+        {% endfor %}
+    </tr>
+    {% endfor %}
+</table>
diff --git a/templates/shortcodes/score.html b/templates/shortcodes/score.html
new file mode 100644
index 0000000..e80cba8
--- /dev/null
+++ b/templates/shortcodes/score.html
@@ -0,0 +1,17 @@
+<table class="nso score">
+    <thead>
+        <tr>
+            <th>JAM</th><th>Jammer's Number</th><th>LOST</th><th>LEAD</th><th>CALL</th><th><abbr title="Injury">INJ.</abbr></th><th><abbr title="No Initial Trip">N.I.</abbr></th>
+            <th>Trip 2</th><th>Trip 3</th><th>Trip 4</th><th>Trip 5</th><th>Trip 6</th><th>Trip 7</th><th>Trip 8</th><th>Trip 9</th><th>Jam Total</th><th>Game Total</th>
+        </tr>
+    </thead>
+    {% set rows = body | split(pat="\n") %}
+    {% for row in rows %}
+    <tr>
+        {% set values = row | split(pat=" ") %}
+        {% for elem in values %}
+        <td>{% if elem != "-" %}{{ elem }}{% endif %}</td>
+        {% endfor %}
+    </tr>
+    {% endfor %}
+</table>