/* ==========================================================================
   DEATH NOTE — a shrine
   Palette : void / bone / ash / paper / apple / link
   Type    : UnifrakturMaguntia (display) · Times (body) · Verdana (chrome)
             · Comic Sans (the sign-off, exactly once) · Courier (the FTP index)
   Rhythm  : the notebook page rules on a 30px pitch. Body line-height is
             locked to that pitch so the text sits ON the ruling. If you
             change --pitch, change nothing else — everything derives from it.
   ========================================================================== */

:root {
  --void:  #000000;
  --bone:  #ffffff;
  --ash:   #9c9c9c;
  --paper: #0a0a0a;   /* the notebook page: near-black, not black */
  --ink:   #e8e6e0;   /* what is written on it */
  --rule:  #242424;   /* the ruling: it guides, it does not compete */
  --apple: #b00000;   /* Ryuk's apple. Used three times on this page. */
  --link:  #5c9dff;   /* every hyperlink, clicked or not */

  --pitch: 30px;      /* one ruled line */
  --column: 760px;    /* the 800×600 assumption, kept */

  /* Nothing on the other end of it. Drawn twice, black under white, so it
     reads over the stars as well as over whatever it is refusing. */
  --cursor-dead: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cg stroke-linecap='round'%3E%3Cpath d='M3 3 L13 13 M13 3 L3 13' stroke='%23000' stroke-width='5'/%3E%3Cpath d='M3 3 L13 13 M13 3 L3 13' stroke='%23fff' stroke-width='2.5'/%3E%3C/g%3E%3C/svg%3E") 8 8, not-allowed;

  --display: 'UnifrakturMaguntia', 'Old English Text MT', 'Cloister Black', serif;
  --body: 'Times New Roman', Times, serif;
  --chrome: Verdana, Geneva, Tahoma, sans-serif;
  --mono: 'Courier New', Courier, monospace;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 0 16px 64px;
  background-color: var(--void);
  background-image: url("assets/stars.png");
  background-repeat: repeat;
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: var(--pitch);
}

.column {
  max-width: var(--column);
  margin: 0 auto;
}

/* A page with nothing above it needs its own air, or the notebook sits flush
   against the top of the window. Matches the gap the banner leaves on /. */
.column-bare { padding-top: 44px; }

a { color: var(--link); }

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--bone);
  outline-offset: 2px;
}

/* --- scrolling news bar ---------------------------------------------------- */

.ticker {
  margin: 0 -16px 28px;
  padding: 5px 0;
  overflow: hidden;
  border-bottom: 1px solid #2a2a2a;
  background: #050505;
  font-family: var(--chrome);
  font-size: 11px;
  line-height: 1.6;
  letter-spacing: 0.06em;
  color: var(--ash);
  white-space: nowrap;
}

.ticker-track {
  display: flex;
  width: max-content;
  animation: slide 38s linear infinite;
}

.ticker-run { padding-right: 3em; }

@keyframes slide {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* --- the big header -------------------------------------------------------- */

.banner {
  margin: 0 0 22px;
  padding: 30px 24px 26px;
  border: 1px solid #262626;
  background: rgba(0, 0, 0, 0.86);
  text-align: center;
}

.banner-eyebrow {
  margin: 0 0 14px;
  font-family: var(--chrome);
  font-size: 10px;
  line-height: 1.4;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: #6e6e6e;
}

.banner-title {
  /* The one loud thing on the page. It is allowed to crowd its own box. */
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(58px, 15.5vw, 138px);
  line-height: 0.9;
  letter-spacing: -0.02em;
  color: var(--bone);
  text-shadow: 0 0 24px rgba(255, 255, 255, 0.12);
}

.banner-word { display: inline-block; }
.banner-word + .banner-word { margin-left: 0.1em; }

/* the write-on: each letter set down in turn, the way a name is written */
.banner-title b {
  display: inline-block;
  font-weight: inherit;
  opacity: 0;
  animation: write 0.42s ease-out forwards;
}

/* --i is the letter's place in the title, numbered by the template across the
   whole line. Any title of any length keeps the same cadence. */
.banner-title b { animation-delay: calc(0.1s + var(--i, 0) * 0.12s); }

@keyframes write {
  from { opacity: 0; transform: translateY(-0.16em); filter: blur(5px); }
  to   { opacity: 1; transform: none; filter: none; }
}

.banner-rule {
  width: 52%;
  margin: 22px auto 16px;
  border: 0;
  border-top: 1px solid #3c3c3c;
}

.banner-creed {
  margin: 0 0 10px;
  font-size: 15px;
  line-height: 1.55;
  font-style: italic;
  color: #c9c7c2;
}

.banner-by {
  margin: 0;
  font-family: var(--chrome);
  font-size: 10px;
  line-height: 1.5;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #5c5c5c;
}

/* --- nav: beveled buttons -------------------------------------------------- */

.nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 5px;
  margin: 0 0 20px;
}

.nav-btn {
  padding: 5px 13px;
  border: 2px outset #6a6a6a;
  background: #171717;
  font-family: var(--chrome);
  font-size: 11px;
  line-height: 1.6;
  letter-spacing: 0.05em;
  color: var(--ink);
  text-decoration: none;
}

.nav-btn:hover { background: #262626; color: var(--bone); }
.nav-btn:active { border-style: inset; }

/* The sections that burned. They keep their place in the row and nothing else:
   the bevel goes flat, so there is no raised face to press, the label is struck
   through and dimmed to say why, and the pointer carries an X over it. Only the
   sections that survived still look like buttons. */
.nav-btn-dead {
  border: 2px solid #2b2b2b;
  background: #0b0b0b;
  color: #6a6a6a;
  text-decoration: line-through;
  text-decoration-color: #4a4a4a;
  cursor: var(--cursor-dead);
  user-select: none;
}

/* Nothing happens on hover or on the way down, because nothing happens. */
.nav-btn-dead:hover { background: #0b0b0b; color: #6a6a6a; }
.nav-btn-dead:active { border-style: solid; }

.nav-btn-on {
  border-style: inset;
  background: #2e2e2e;
  color: var(--bone);
}

/* One button where the nav row would have been, on the pages that have no nav.
   Left-aligned, not centred: it is a way out, not a set of choices. */
.back {
  display: flex;
  margin: 0 0 20px;
}

/* --- star divider ---------------------------------------------------------- */

.divider {
  height: 22px;
  margin: 20px 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='22'%3E%3Cpath d='M22 4l1.7 4.9L28.7 9l-4 3.2 1.4 5-4.1-3-4.1 3 1.4-5-4-3.2 5-.1z' fill='%23ffffff'/%3E%3Ccircle cx='4' cy='11' r='1' fill='%237a7a7a'/%3E%3Ccircle cx='40' cy='11' r='1' fill='%237a7a7a'/%3E%3C/svg%3E");
  background-repeat: repeat-x;
  background-position: center;
  opacity: 0.75;
}

/* --- SIGNATURE: the notebook page ------------------------------------------ */

.page {
  margin: 0;
  padding: 26px 30px 20px;
  border: 6px solid var(--bone);
  outline: 1px solid #000;
  background: var(--paper);
  box-shadow: 0 0 40px rgba(0, 0, 0, 0.9);
}

.page-head {
  margin: 0 0 22px;
  padding-bottom: 14px;
  border-bottom: 1px solid #2e2e2e;
  text-align: center;
}

.page-mark {
  margin: 0 0 4px;
  font-family: var(--display);
  font-size: 30px;
  line-height: 1.1;
  color: var(--bone);
}

.page-label {
  margin: 0;
  font-family: var(--chrome);
  font-size: 10px;
  line-height: 1.5;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: #767676;
}

/* The ruled field. Text sits on the ruling because line-height == --pitch and
   the rule is drawn 4px under the baseline inside each band. */
.page-body {
  padding-left: 20px;
  border-left: 1px solid #2b2b2b;
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 24px,
    var(--rule) 24px,
    var(--rule) 25px,
    transparent 25px,
    transparent var(--pitch)
  );
}

.page-body p {
  margin: 0 0 var(--pitch);
  font-size: 17px;
  line-height: var(--pitch);
  color: var(--ink);
}

.page-body p:last-child { margin-bottom: 0; }

/* Nothing was handwritten here: no ruling to sit on, and no margin line to
   write up against. */
.page-body-plain {
  padding-left: 0;
  border-left: 0;
  background-image: none;
}

.page-folio {
  margin: 18px 0 0;
  font-family: var(--chrome);
  font-size: 10px;
  line-height: 1.5;
  letter-spacing: 0.24em;
  text-align: right;
  color: #4f4f4f;
}

/* --- directory index: the dump, served the way a 1998 daemon would ---------- */

.ftp {
  overflow-x: auto;   /* the columns are fixed-width; let narrow screens pan */
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink);
}

.ftp-head {
  margin: 0 0 10px;
  font-size: 15px;
  font-weight: 700;
  color: var(--bone);
}

/* Apache fenced the listing top and bottom. Both rules come from here. */
.ftp-rule {
  margin: 0;
  border: 0;
  border-top: 1px solid #2e2e2e;
}

.ftp-table {
  width: 100%;
  margin: 0;
  border-collapse: collapse;
  text-align: left;
}

.ftp-table th {
  padding: 7px 18px 7px 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #7f7f7f;
  white-space: nowrap;
}

.ftp-table td {
  padding: 2px 18px 2px 0;
  white-space: nowrap;
  color: #8d8d8d;   /* mtime and size are metadata; they stay quiet */
}

/* The name column takes the slack so mtime and size sit hard against the right. */
.ftp-table td:first-child { width: 100%; color: var(--ink); }

.ftp-table th:last-child,
.ftp-table td:last-child {
  padding-right: 0;
  text-align: right;
}

/* The server drew each row's type in the left margin. Keep it. */
.ftp-icon { color: #6e6e6e; }

.ftp-link { color: var(--link); text-decoration: underline; }
.ftp-link:hover { background: #1e1e1e; color: var(--bone); }

/* One directory is not like the others. Apple red, its third and last use. */
.ftp-link-flag { color: var(--apple); font-weight: 700; }
.ftp-link-flag:hover { background: #1e1e1e; color: #ff4a4a; }

/* The way back out, drawn as the listing's first row would have been. */
.ftp-up { margin: 6px 0 0; }

/* A directory holding words instead of directories. Still the server's type,
   just given a measure and a leading that prose can be read at. */
.ftp-text {
  max-width: 74ch;
  margin: 0;
  padding: 18px 0 6px;
  font-size: 14px;
  line-height: 1.8;
}

.ftp-text > :first-child { margin-top: 0; }
.ftp-text > :last-child { margin-bottom: 0; }

.ftp-text p,
.ftp-text ul,
.ftp-text ol { margin: 0 0 1.5em; }

.ftp-text h1,
.ftp-text h2,
.ftp-text h3 {
  margin: 2em 0 0.8em;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--bone);
}

.ftp-text a { color: var(--link); }
.ftp-text a:hover { background: #1e1e1e; color: var(--bone); }
.ftp-text strong { color: var(--bone); }
.ftp-text em { color: #c9c7c2; }

.ftp-text blockquote {
  margin: 0 0 1.5em;
  padding-left: 14px;
  border-left: 1px solid #2e2e2e;
  color: #8d8d8d;
}

.ftp-sig {
  margin: 10px 0 0;
  font-size: 11px;
  color: #4f4f4f;
}

/* --- a file the dump is holding back --------------------------------------- */

/* The prompt is the daemon talking, so it is the daemon's type at the
   daemon's size. Nothing here is decoration: the visitor is at a terminal
   being asked for a word. */
.vault-form {
  margin: 22px 0 0;
  padding: 16px 18px;
  border: 1px solid #2e2e2e;
  background: #060606;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.7;
}

/* Apple red, and the only place on the page it appears. The listing already
   marks this directory in it; the lock finishes the sentence. */
.vault-title {
  margin: 0 0 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--apple);
}

/* Label, field and button on one line, wrapping as a unit on narrow screens. */
.vault-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0;
}

.vault-label { color: #8d8d8d; }

/* A field, drawn the way the rest of the page draws a rule: one line under
   the text and nothing else. Letter-spacing because it is being typed one
   character at a time and read back the same way.

   Width is the character count, not a round number: --vault-len is set on the
   element by the build, and the rule below measures out exactly that many
   letters plus the space the letter-spacing puts after each one. The box is
   the length hint -- it should look like somewhere a six-letter word goes. */
.vault-key {
  flex: 0 0 auto;
  width: calc(var(--vault-len, 12) * (1ch + 0.22em) + 0.5ch);
  padding: 4px 2px;
  border: 0;
  border-bottom: 1px solid #3a3a3a;
  background: transparent;
  color: var(--bone);
  font-family: inherit;
  font-size: inherit;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.vault-key:focus {
  outline: 0;
  border-bottom-color: var(--apple);
}

.vault-key::placeholder { color: #3a3a3a; }

.vault-go {
  padding: 4px 14px;
  border: 1px solid #3a3a3a;
  background: #141414;
  color: var(--ink);
  font-family: inherit;
  font-size: inherit;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}

.vault-go:hover {
  border-color: var(--apple);
  background: #1e1e1e;
  color: var(--bone);
}

/* Nothing to submit yet: the button recedes to the colour the page uses for
   its own furniture, keeps the border it had, and stops answering the pointer.
   It is off, not missing -- the shape stays put so the row doesn't move when
   the last letter lands. */
.vault-go:disabled {
  border-color: #262626;
  background: #0d0d0d;
  color: #4f4f4f;
  cursor: not-allowed;
}

.vault-go:disabled:hover {
  border-color: #262626;
  background: #0d0d0d;
  color: #4f4f4f;
}

/* Mid-request the whole widget goes quiet rather than just the button, so it
   is obvious the answer is in flight and not that the click was missed. The
   button is disabled then too, but for a different reason, so it says so with
   a different cursor. */
.vault.is-working .vault-form { opacity: 0.55; }
.vault.is-working .vault-go:disabled { cursor: wait; }

.vault-hint {
  margin: 8px 0 0;
  font-size: 11px;
  color: #4f4f4f;
}

/* Empty until there is something to say, and it takes no room until then --
   an always-reserved line would leave a gap under the hint on first paint. */
.vault-status:empty { display: none; }

.vault-status {
  margin: 8px 0 0;
  color: var(--apple);
}

/* A vault whose tags were left empty has no notice to give, so the element
   holding it collapses rather than propping a gap open above the prompt, and
   the prompt gives up the margin it was keeping clear of it. Both stop
   applying the moment the file opens into the element and it is no longer
   empty -- which is why this is :empty and not a class the build sets. */
.vault-cipher:empty { display: none; }
.vault-cipher:empty + .vault-form { margin-top: 0; }

/* The file, once it is open. Marked so a future page can treat a decrypted
   body differently from the notice it replaced; today it just reads as text. */
.vault-cipher.is-open { color: var(--ink); }

/* --- the last will: four envelopes, dealt 2 x 2 ----------------------------- */

/* Sits on the ruled page, so each button carries its own ground -- the ruling
   would otherwise run straight through the envelope. */
.letters {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin: 0 0 var(--pitch);
}

/* The nav button, given room to hold a picture: same bevel, same chrome type. */
.letter-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 96px;
  padding: 16px 12px;
  border: 2px outset #6a6a6a;
  background: #171717;
  font-family: var(--chrome);
  font-size: 11px;
  line-height: 1.6;
  letter-spacing: 0.05em;
  color: #cfcfcf;
  text-align: center;
  text-decoration: none;
}

.letter-btn:hover { background: #262626; color: var(--bone); }
.letter-btn:active { border-style: inset; }

/* Drawn in currentColor, so the envelope brightens with the label under it. */
.letter-icon {
  display: block;
  width: 40px;
  height: 28px;
}

/* One unread letter is red the way one directory in the dump is red. */
.letter-btn:hover .letter-icon { color: var(--apple); }

.letter-name { display: block; }

/* --- the fanfic archive: an index that outlived the things it indexes ------- */

/* The header an archive puts over a listing: how much of it you are looking
   at, and what it was sorted by. On the ruled page, so it carries its own
   ground the way the envelopes do. */
.fics-index {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 2px 16px;
  margin: 0 0 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid #2e2e2e;
  background: var(--paper);
  font-family: var(--chrome);
  font-size: 11px;
  line-height: 1.7;
  letter-spacing: 0.05em;
  color: #7f7f7f;
}

.fics-index .fics-count,
.fics-index .fics-sort { margin: 0; font: inherit; line-height: inherit; }

.fics-index .fics-count { color: var(--bone); }

.fics {
  margin: 0 0 var(--pitch);
  padding: 0;
  list-style: none;
}

/* One work, one record: bordered and backed, so the ruling stops at its edge
   and each fic reads as its own row of the index. */
.fic {
  padding: 12px 14px;
  border: 1px solid #262626;
  background: #101010;
}

.fic + .fic { margin-top: 8px; }

/* Title, byline and verdict on one line, the verdict pushed to the far end. */
.fic .fic-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 10px;
  margin: 0 0 10px;
  font-size: 17px;
  line-height: 1.5;
}

/* Drawn as links because that is what they were, but red instead of the blue
   every live link on this site is drawn in -- the same lit red the dump paints
   its one flagged directory on hover. They refuse the way the burned nav
   buttons do: no href behind them, and the X under the pointer saying so
   before the click. Lit, not --apple: #b00000 on this near-black record is too
   dark to read a title through. */
.fic-title {
  color: #ff4a4a;
  text-decoration: underline;
  cursor: var(--cursor-dead);
  user-select: none;
}

/* What the archive found when it went looking. Courier, so it reads as a stamp
   the machine put there rather than anything Wes wrote. */
.fic-gone {
  margin-left: auto;
  padding: 1px 7px;
  border: 1px solid #2e2e2e;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: #6e6e6e;
}

.fic-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The keywords, boxed one apiece. Chrome type at nav-button size: they are
   labels on a record, not part of the prose. */
.fic-tag {
  padding: 2px 8px;
  border: 1px solid #2b2b2b;
  background: #171717;
  font-family: var(--chrome);
  font-size: 11px;
  line-height: 1.6;
  color: #a9a9a9;
}

/* --- wes note: the author, interrupting ------------------------------------- */

/* Self-contained on purpose. It sits on the ruled notebook page and inside the
   FTP listing both, so it brings its own type, its own ground, and its own
   frame rather than inheriting whichever page it landed on. */
.wesnote {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin: var(--pitch) 0;
  padding: 14px 16px;
  border: 1px solid #333;
  background: #101010;
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.6;
  text-align: left;
  color: #c9c7c2;
}

/* Framed the way the notebook page and the whois portrait are framed. */
.wesnote-pic {
  flex: none;
  width: 72px;
  height: 72px;
  border: 3px solid var(--bone);
  outline: 1px solid #000;
  background: var(--paper);
}

.wesnote-said { min-width: 0; }   /* let long words wrap instead of stretching the box */

.wesnote .wesnote-label {
  margin: 0 0 5px;
  font-family: var(--chrome);
  font-size: 9px;
  line-height: 1.5;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #7f7f7f;
}

.wesnote-body > :first-child { margin-top: 0; }
.wesnote-body > :last-child { margin-bottom: 0; }

.wesnote .wesnote-body p,
.wesnote .wesnote-body ul,
.wesnote .wesnote-body ol {
  margin: 0 0 0.9em;
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.6;
  color: #c9c7c2;
}

.wesnote-body a { color: var(--link); }
.wesnote-body a:hover { color: var(--bone); }
.wesnote-body strong { color: var(--bone); }
.wesnote-body em { color: #d4d2cc; }

@media (max-width: 620px) {
  .wesnote { flex-direction: column; gap: 10px; }
}

/* --- footer junk drawer ---------------------------------------------------- */

.attic {
  margin-top: 4px;
  padding: 24px 20px 22px;
  border: 1px solid #262626;
  background: rgba(0, 0, 0, 0.86);
  font-family: var(--chrome);
  font-size: 11px;
  line-height: 1.7;
  text-align: center;
  color: #9e9e9e;
}

.attic-row {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  justify-content: center;
  gap: 14px;
  margin-bottom: 22px;
}

.attic-row > * {
  display: grid;
  align-content: center;
}

.counter {
  padding: 7px 10px;
  border: 2px inset #555;
  background: #0d0d0d;
}

.counter-label {
  display: block;
  margin-bottom: 5px;
  font-size: 9px;
  letter-spacing: 0.12em;
  color: #8a8a8a;
}

.counter-digits { display: flex; gap: 2px; }

.counter-digits i {
  padding: 2px 5px;
  background: var(--bone);
  font-style: normal;
  font-weight: 700;
  font-family: var(--chrome);
  font-size: 15px;
  color: var(--void);
}

/* Only the digits that actually changed flash, so a tick reads like an
   odometer rolling rather than the whole number repainting. */
.counter-digits i.is-ticking { animation: ticked 0.42s ease-out; }

@keyframes ticked {
  from { background: var(--void); color: var(--bone); }
  to   { background: var(--bone); color: var(--void); }
}

.badge {
  margin: 0;
  padding: 6px 10px;
  border: 1px solid #3a3a3a;
  font-size: 9px;
  line-height: 1.5;
  letter-spacing: 0.06em;
  color: #8d8d8d;
}

.hazard {
  margin: 0;
  padding: 9px 14px;
  border-top: 7px solid transparent;
  border-bottom: 7px solid transparent;
  background:
    linear-gradient(#0d0d0d, #0d0d0d) padding-box,
    repeating-linear-gradient(45deg, #ffffff 0 7px, #101010 7px 14px) border-box;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: #d6d6d6;
}

.ring {
  margin: 0 auto 18px;
  padding: 10px 14px;
  max-width: 340px;
  border: 1px solid #333;
  background: rgba(0, 0, 0, 0.7);
}

.ring-name {
  margin: 0 0 6px;
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #7f7f7f;
}

.ring-nav { margin: 0; }

.ring-link {
  color: var(--link);
  font-size: 11px;
  text-decoration: underline;
}

.ring-link + .ring-link { margin-left: 10px; }
.ring-link:hover { color: var(--bone); }

.blinker { margin: 0 0 14px; font-size: 11px; }

.blink {
  color: var(--apple);
  font-weight: 700;
  animation: blink 1.1s steps(1, end) infinite;
}

@keyframes blink {
  0%, 55% { opacity: 1; }
  56%, 100% { opacity: 0; }
}

.attic-note { margin: 0 0 22px; font-size: 10px; color: #7a7a7a; }

/* The signature block: framed the same way the notebook page is, so the
   portrait reads as belonging to the document rather than sitting beside it. */
.whois {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  text-align: left;
}

.whois-pic {
  flex: none;
  width: 104px;
  height: 104px;
  border: 4px solid var(--bone);
  outline: 1px solid #000;
  background: var(--paper);
}

.whois-said { max-width: 46ch; }

.whois-label {
  margin: 0 0 5px;
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #7f7f7f;
}

.signoff {
  margin: 0;
  font-family: 'Comic Sans MS', 'Comic Neue', cursive;  /* Comic Neue stands in where Comic Sans isn't installed */
  font-size: 12px;
  line-height: 1.7;
  color: #949494;
}

.signoff-link { color: var(--link); }

/* --- small screens: the fixed column gives way, nothing else changes -------- */

@media (max-width: 620px) {
  body { background-attachment: scroll; }
  .column-bare { padding-top: 10px; }
  .banner { padding: 24px 14px 20px; }
  .page { padding: 20px 16px 16px; border-width: 4px; }
  .ftp { font-size: 12px; }
  .ftp-table th,
  .ftp-table td { padding-right: 12px; }
  .page-body { padding-left: 14px; }
  .letter-btn { min-height: 84px; padding: 12px 8px; }
  .fic { padding: 10px 10px; }
  .fic-gone { margin-left: 0; }
  .whois { flex-direction: column; text-align: center; gap: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .ticker-track { animation: none; }
  .banner-title b { opacity: 1; animation: none; }
  .blink { animation: none; }
  .counter-digits i.is-ticking { animation: none; }
}
