@font-face {
  font-family: "Spectral";
  src: url("assets/fonts/spectral-400-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Spectral";
  src: url("assets/fonts/spectral-400italic-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Spectral";
  src: url("assets/fonts/spectral-600-latin.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Special Elite";
  src: url("assets/fonts/special-elite-400-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Architects Daughter";
  src: url("assets/fonts/architects-daughter-400-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --paper-0: #ece0c6;
  --paper-1: #e3d6b9;
  --paper-2: #d9caab;
  --edge: rgba(94, 76, 50, 0.26);
  --edge-2: rgba(94, 76, 50, 0.42);
  --ink: #4a3f31;
  --ink-2: #5e5142;
  --ink-dim: rgba(74, 63, 49, 0.68);
  --ink-mute: rgba(74, 63, 49, 0.48);
  --accent: #5c8038;
  --accent-deep: #405e24;
  --accent-wash: rgba(92, 128, 56, 0.15);
  --tape: rgba(202, 178, 118, 0.6);

  --font-body: "Spectral", Georgia, "Times New Roman", serif;
  --font-type: "Special Elite", "Courier Prime", "Courier New", monospace;
  --font-hand: "Architects Daughter", "Segoe Script", cursive;

  --ease: cubic-bezier(0.33, 1, 0.68, 1);


  /* Borrowed by the options panel, which came over from legal. Values are

     the blog's own paper and ink rather than legal's, so the dialog reads as

     part of this site while keeping the shape of that one. */

  --paper-edge: rgba(94, 76, 50, 0.22);

  --ink-faint: rgba(74, 63, 49, 0.34);

  --brass: #9a8452;

  --brass-hi: #c2a86a;

  --font-serif: var(--font-body);

  --ease-soft: cubic-bezier(0.33, 1, 0.68, 1);

  --ease-heavy: cubic-bezier(0.16, 1, 0.3, 1);
  --col: 720px;
  --side: 250px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--paper-1);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: var(--accent-deep);
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

h1,
h2,
h3,
p,
ul,
ol {
  margin: 0;
  padding: 0;
}

ul {
  list-style: none;
}

::selection {
  background: var(--accent-wash);
}

:focus-visible {
  outline: 2px dashed var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

body {
  background-image:
    radial-gradient(
      ellipse 120% 90% at 50% 0%,
      rgba(255, 250, 236, 0.5),
      rgba(255, 250, 236, 0) 60%
    ),
    radial-gradient(
      ellipse 100% 80% at 50% 108%,
      rgba(94, 76, 50, 0.16),
      rgba(94, 76, 50, 0) 62%
    );
  background-attachment: fixed;
}

.sheet {
  position: relative;
  box-shadow:
    0 1px 0 rgba(255, 250, 236, 0.55) inset,
    0 22px 44px -30px rgba(40, 26, 10, 0.62),
    0 3px 9px -6px rgba(40, 26, 10, 0.28);
}

@media (prefers-reduced-motion: reduce) {
  body {
    background-attachment: scroll;
  }
}
.masthead {
  flex: none;
  border-bottom: 2px solid var(--ink);
  background-color: var(--paper-0);
}

.masthead__in {
  margin: 0;
  padding: 12px clamp(16px, 4vw, 46px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}

.masthead__brand {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
  text-decoration: none;
  transition: opacity 0.2s var(--ease);
}

.masthead__brand:hover {
  opacity: 0.85;
}

.masthead__mark {
  display: inline-block;
  flex: none;
  width: clamp(52px, 5vw, 68px);
  transform-origin: 50% 88%;
  cursor: pointer;
  filter: drop-shadow(0 3px 8px rgba(94, 76, 50, 0.28));
  transition: transform 0.3s var(--ease), filter 0.3s var(--ease);
}

.masthead__mark img {
  width: 100%;
  height: auto;
  /* Each site carries its own mark artwork, and the variants are not all the
     same ratio. Pinning the box ratio keeps the masthead row exactly the same
     height on every site, so the menu button lands on the same baseline;
     object-fit letterboxes an odd variant rather than stretching it. */
  aspect-ratio: 1243 / 848;
  object-fit: contain;
  transform-origin: 50% 88%;
  transform: rotate(-3deg);
}

.masthead__mark:hover {
  transform: scale(1.12);
  filter: drop-shadow(0 6px 12px rgba(94, 76, 50, 0.36));
}

.masthead__mark:active {
  transform: scale(0.93);
}

.masthead__text {
  min-width: 0;
  line-height: 1;
}

.masthead__name {
  display: block;
  margin: -2.5px 0;
  font-family: var(--font-hand);
  font-size: clamp(21px, 3vw, 30px);
  font-weight: 400;
  line-height: 1.15;
  color: var(--ink);
}

.masthead__tag {
  display: block;
  margin-top: 5px;
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--ink-mute);
}

.masthead__nav {
  display: flex;
  align-items: center;
  gap: 12px;
}

.ghost {
  /* pinned so the button is the same box on every site: the four inherit
     four different body line-heights, which is what made blog 39px tall
     where the others were 38 */
  line-height: 1.65;
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  border: 1.8px solid color-mix(in srgb, var(--ink) 26%, transparent);
  background: color-mix(in srgb, var(--paper-0) 55%, transparent);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  border-radius: 9px;
  font-family: var(--font-type);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-decoration: none;
  white-space: nowrap;
  transition:
    transform 0.18s var(--ease),
    color 0.18s var(--ease),
    border-color 0.2s var(--ease),
    box-shadow 0.2s var(--ease);
}

.ghost:hover,
.ghost:focus-visible {
  transform: translateY(-1px);
  color: var(--ink);
  border-color: var(--accent);
  background: color-mix(in srgb, var(--paper-0) 82%, transparent);
  box-shadow: 0 6px 16px -10px var(--accent);
}

.ghost:active {
  transform: translateY(0);
}

.wrap {
  flex: 1;
  width: 100%;
  max-width: calc(var(--col) + var(--side) + 96px);
  margin: 0 auto;
  padding: clamp(18px, 3vw, 32px) clamp(14px, 3vw, 28px) 56px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--side);
  gap: clamp(20px, 3vw, 40px);
  align-items: start;
}

.sheet {
  min-width: 0;
  padding: clamp(20px, 3vw, 34px) clamp(18px, 3vw, 34px) clamp(24px, 3vw, 38px);
  background-color: var(--paper-0);
  border: 1px solid var(--edge);
  border-radius: 12px;
}

.langnote {
  position: relative;
  margin: 0 0 26px;
  padding: 18px 20px 16px;
  background-color: var(--paper-0);
  border: 1px solid var(--edge);
  border-radius: 3px;
  transform: rotate(-0.5deg);
  animation: noteIn 0.3s var(--ease);
}

@keyframes noteIn {
  from {
    transform: rotate(-0.5deg) translateY(-8px);
  }
}

.langnote__tape {
  position: absolute;
  top: -9px;
  left: 50%;
  width: 92px;
  height: 20px;
  margin-left: -46px;
  background: var(--tape);
  transform: rotate(-1.6deg);
}

.langnote__head {
  font-family: var(--font-type);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent-deep);
}

.langnote__body {
  margin-top: 6px;
  font-size: 15px;
  color: var(--ink-2);
}

.langnote__close {
  margin-top: 10px;
  font-family: var(--font-type);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
  border-bottom: 1px solid var(--edge);
}

.langnote__close:hover {
  color: var(--ink);
}

.langnote.is-falling {
  pointer-events: none;
  animation: leafFall 1.1s cubic-bezier(0.4, 0, 0.7, 1) forwards;
}

@keyframes leafFall {
  0% {
    opacity: 1;
    transform: rotate(-0.5deg) translate(0, 0);
  }
  35% {
    opacity: 1;
    transform: rotate(7deg) translate(18px, 60px);
  }
  70% {
    opacity: 0.55;
    transform: rotate(-9deg) translate(-14px, 150px);
  }
  100% {
    opacity: 0;
    transform: rotate(12deg) translate(22px, 260px);
  }
}

.entry {
  position: relative;
  padding: 18px 20px 20px;
  margin-bottom: 18px;
  border: 1px solid transparent;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease),
    transform 0.2s var(--ease);
}

.entry::after {
  content: "";
  position: absolute;
  left: 20px;
  right: 20px;
  bottom: -9px;
  border-bottom: 1px solid var(--edge);
  transition: opacity 0.2s var(--ease);
}

.entry:hover::after,
.entry:focus-visible::after,
.entry:hover + .entry::after,
.entry:focus-visible + .entry::after {
  opacity: 0;
}

.entry:last-child {
  margin-bottom: 0;
}

.entry:last-child::after {
  border-bottom: 0;
}

/* Hover lifts the card and warms it, and the read-more caret slides out to
   meet the pointer. Small numbers on purpose: this is a page of paper, and a
   card that jumps at you reads as a button rather than as a sheet on a desk.

   Only under (hover: hover). A touch device reports a tap as a hover and then
   leaves the state stuck on the last thing tapped, so without the guard a card
   stays lifted after you have navigated away from it. */
@media (hover: hover) and (pointer: fine) {
  .entry:hover,
  .entry:focus-visible {
    background-color: var(--paper-0);
    border-color: var(--edge);
    transform: translateY(-2px);
    box-shadow: 0 10px 22px -18px rgba(60, 46, 26, 0.55);
  }

  .entry:hover .entry__more,
  .entry:focus-visible .entry__more {
    transform: translateX(3px);
  }

  .entry__more {
    transition: transform 0.22s var(--ease);
  }
}

/* Keyboard users get the lift with no pointer involved. */
.entry:focus-visible {
  background-color: var(--paper-0);
  border-color: var(--edge);
  transform: translateY(-2px);
}

.entry.is-opening {
  animation: cardOpen 0.24s cubic-bezier(0.3, 0, 0.2, 1) forwards;
  z-index: 2;
}

@keyframes cardOpen {
  from {
    transform: translateY(-2px) scale(1);
  }
  to {
    transform: translateY(-6px) scale(1.035);
  }
}

.entry__more {
  font-family: var(--font-type);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-deep);
  opacity: 0;
  transition: opacity 0.2s var(--ease);
}

.entry:hover .entry__more,
.entry:focus-visible .entry__more {
  opacity: 1;
}

.empty {
  padding: 40px 4px;
  font-family: var(--font-hand);
  font-size: 20px;
  color: var(--ink-mute);
  text-align: center;
}

.feedend {
  margin: 26px 0 4px;
  font-family: var(--font-type);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  text-align: center;
}

.feedend:not(.is-done) {
  animation: feedPulse 1.7s var(--ease) infinite;
}

@keyframes feedPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.42; }
}

.entry__date {
  font-family: var(--font-type);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.entry__title {
  margin-top: 8px;
  font-family: var(--font-hand);
  font-size: clamp(23px, 3vw, 29px);
  line-height: 1.2;
}

.entry__title a {
  color: var(--ink);
  text-decoration: none;
}

.entry__title a:hover {
  color: var(--accent-deep);
}

.entry__excerpt {
  margin-top: 10px;
  color: var(--ink-2);
}

.entry__foot {
  margin-top: 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.entry__mins {
  font-family: var(--font-type);
  font-size: 10.5px;
  color: var(--ink-mute);
  margin-left: auto;
}

.side {
  position: sticky;
  top: 24px;
  display: flex;
  flex-direction: column;
  gap: 26px;
  font-size: 14px;
}

.side__head {
  font-family: var(--font-type);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-mute);
  padding-bottom: 7px;
  margin-bottom: 10px;
  border-bottom: 1px solid var(--edge);
}

.side__list li {
  padding: 3px 0;
}

.side__list a {
  color: var(--ink-2);
  text-decoration: none;
}

.side__list a:hover,
.side__list a.is-on {
  color: var(--accent-deep);
}

.side__count {
  color: var(--ink-mute);
  font-family: var(--font-type);
  font-size: 11px;
}

.search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border: 1.5px solid var(--edge-2);
  border-radius: 999px;
  background-color: var(--paper-0);
}

.search input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--ink);
}

.search input:focus {
  outline: none;
}

.search input::placeholder {
  color: var(--ink-mute);
}

.post__body {
  margin-top: 22px;
  font-size: 16px;
}

.post__body p,
.post__body li,
.post__body blockquote {
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
}

.post__body h2,
.post__body h3,
.post__body figcaption,
.post__body pre,
.post__body code {
  text-align: left;
  hyphens: manual;
  -webkit-hyphens: manual;
}

.entry__excerpt {
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
}
.post__body p {
  margin-bottom: 18px;
}

.post__body h2 {
  margin: 30px 0 10px;
  font-family: var(--font-hand);
  font-size: 24px;
  line-height: 1.25;
}

.post__body h3 {
  margin: 24px 0 8px;
  font-family: var(--font-type);
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-deep);
}

.post__body ul {
  list-style: disc;
  padding-left: 22px;
  margin-bottom: 18px;
}

.post__body li {
  margin-bottom: 6px;
}

.post__body blockquote {
  margin: 20px 0;
  padding: 4px 0 4px 18px;
  border-left: 3px solid var(--accent);
  font-style: italic;
  color: var(--ink-2);
}

.post__body code {
  font-family: var(--font-type);
  font-size: 14px;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--paper-2);
}

.post__body pre {
  margin-bottom: 18px;
  padding: 14px 16px;
  overflow-x: auto;
  border-radius: 6px;
  border: 1px solid var(--edge);
  background: var(--paper-2);
}

.post__body pre code {
  padding: 0;
  background: none;
}

.post__body img {
  margin: 20px 0;
  border-radius: 4px;
  border: 1px solid var(--edge);
}

.footer {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 18px clamp(16px, 4vw, 46px) 22px;
  border-top: 1px solid var(--edge);
  background-color: var(--paper-0);
  font-family: var(--font-type);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--ink-mute);
}

.footer__made {
  min-width: 0;
}

.legal {
  display: flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  margin-left: auto;
}

.legal a {
  color: var(--ink-mute);
  text-decoration: none;
  font-size: 10px;
  letter-spacing: 0.05em;
}

.legal a:hover {
  color: var(--accent-deep);
}

.legal__sep {
  opacity: 0.4;
}

.legal__all {
  display: none;
}

@media (max-width: 560px) {
  .legal__sep,
  .legal .legal__link:not(.legal__all) {
    display: none;
  }

  .legal__all {
    display: inline;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

.post__body figure {
  margin: 24px 0;
}

.post__body figure img {
  width: 100%;
  border-radius: 6px;
  border: 1px solid var(--edge);
}

.post__body figcaption {
  margin-top: 8px;
  font-family: var(--font-type);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--ink-mute);
  text-align: center;
}

.post__pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px;
  margin: 24px 0;
}

.post__pair figure {
  margin: 0;
}

.post__body .post__wide {
  margin: 30px calc(clamp(10px, 4vw, 62px) * -1);
}

.wrap--post {
  max-width: 1180px;
  padding-top: clamp(46px, 5vw, 64px);
}

.wrap--post .sheet {
  position: relative;
  padding:
    clamp(30px, 3vw, 44px)
    clamp(20px, 5vw, 84px)
    clamp(30px, 3vw, 46px);
  border: 2px solid var(--ink);
  animation: postRise 0.32s var(--ease) both;
}

.post__tab {
  position: absolute;
  left: clamp(16px, 3vw, 42px);
  bottom: 100%;
  margin-bottom: -6px;
  max-width: calc(100% - clamp(32px, 6vw, 84px));
  padding: 9px 22px 12px;
  background: var(--paper-2);
  border: 2px solid var(--ink);
  border-bottom: none;
  border-radius: 10px 10px 0 0;
  transform: rotate(-0.8deg);
  transform-origin: 0 100%;
  animation: tabSettle 0.38s var(--ease) 0.04s both;
}

.post__kicker {
  font-family: var(--font-type);
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.post__title {
  margin-top: 4px;
  font-family: var(--font-hand);
  font-size: clamp(19px, 2.1vw, 27px);
  font-weight: 400;
  line-height: 1.14;
  color: var(--ink);
}

.wrap--post .post__body {
  max-width: 70ch;
  margin-inline: auto;
  animation: bodyLift 0.34s var(--ease) 0.08s both;
}

@keyframes postRise {
  from { transform: translateY(16px); }
  to { transform: none; }
}

@keyframes tabSettle {
  0% { transform: rotate(-5deg) translateY(11px); }
  62% { transform: rotate(0.9deg) translateY(0); }
  100% { transform: rotate(-0.8deg); }
}

@keyframes bodyLift {
  from { transform: translateY(11px); }
  to { transform: none; }
}

@media (max-width: 900px) {
  .wrap {
    grid-template-columns: minmax(0, 1fr);
  }

  .side {
    position: static;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 20px;
    padding: 20px clamp(18px, 3vw, 34px);
    background: var(--paper-0);
    border: 1px solid var(--edge);
    border-radius: 12px;
  }
}

@media (max-width: 620px) {
  .masthead__in {
    align-items: center;
    gap: 12px;
    padding: 14px 16px 12px;
  }

  .masthead__mark {
    width: 52px;
  }

  .masthead__nav {
    width: 100%;
  }

  .ghost {
    font-size: 10px;
    padding: 8px 12px;
  }

  .wrap {
    padding: 14px 12px 40px;
    gap: 16px;
  }

  .sheet {
    padding: 18px 16px 22px;
    border-radius: 10px;
  }

  .entry {
    padding: 14px 14px 16px;
  }

  .entry::after {
    left: 14px;
    right: 14px;
  }

  .post__body {
    font-size: 16px;
  }

  .post__body .post__wide {
    margin-left: -16px;
    margin-right: -16px;
  }

  .post__body {
    font-size: 17px;
  }

  .wrap--post {
    padding-top: 40px;
  }

  .post__tab {
    left: 14px;
    max-width: calc(100% - 28px);
    padding: 7px 15px 9px;
  }

  .footer {
    justify-content: center;
    text-align: center;
    gap: 10px;
  }

  .legal {
    margin-left: 0;
    justify-content: center;
    flex-wrap: wrap;
    white-space: normal;
  }

  .side {
    grid-template-columns: minmax(0, 1fr);
  }
}

:root {
  --sb-size: 12px;
  --sb-mid: #7a8f5c;
  --sb-hi: #5c7040;
  --sb-rail: rgba(94, 76, 50, 0.2);
  --sb-grip: rgba(236, 224, 198, 0.6);
}

::-webkit-scrollbar {
  width: var(--sb-size);
  height: var(--sb-size);
}

::-webkit-scrollbar-track {
  background-color: transparent;
  background-image: linear-gradient(var(--sb-rail), var(--sb-rail));
  background-repeat: no-repeat;
  background-position: center;
  background-size: 1px 84%;
}

::-webkit-scrollbar-track:horizontal {
  background-size: 84% 1px;
}

::-webkit-scrollbar-thumb {
  min-height: 44px;
  border: 2px solid transparent;
  border-radius: 99px;
  background-clip: padding-box;
  background-color: var(--sb-mid);
  background-image:
    linear-gradient(var(--sb-grip), var(--sb-grip)),
    linear-gradient(var(--sb-grip), var(--sb-grip)),
    linear-gradient(var(--sb-grip), var(--sb-grip));
  background-repeat: no-repeat;
  background-position: center calc(50% - 4px), center 50%, center calc(50% + 4px);
  background-size: 4px 1px;
  transition: background-color 0.18s ease;
}

::-webkit-scrollbar-thumb:horizontal {
  min-height: 0;
  min-width: 44px;
  background-position: calc(50% - 4px) center, 50% center, calc(50% + 4px) center;
  background-size: 1px 4px;
}

::-webkit-scrollbar-thumb:hover {
  background-color: var(--sb-hi);
}

::-webkit-scrollbar-corner {
  background: transparent;
}

@supports not selector(::-webkit-scrollbar) {
  html {
    scrollbar-width: thin;
    scrollbar-color: var(--sb-mid) transparent;
  }
}

.postnav {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 20px;
  padding: 8px 16px 8px 12px;
  border: 1.5px solid var(--edge);
  border-radius: 99px;
  background: var(--paper-1);
  font-family: var(--font-type);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-decoration: none;
  transition: color 0.18s var(--ease), border-color 0.18s var(--ease),
    transform 0.18s var(--ease), box-shadow 0.2s var(--ease);
}

.postnav:hover,
.postnav:focus-visible {
  color: var(--ink);
  border-color: var(--accent);
  transform: translateX(-3px);
  box-shadow: 0 6px 16px -12px var(--accent);
}

.postnav__arrow {
  display: inline-block;
  font-size: 13px;
  line-height: 1;
  transition: transform 0.22s var(--ease);
}

.postnav:hover .postnav__arrow {
  transform: translateX(-4px);
}

.postends {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
  margin-top: 36px;
  padding-top: 26px;
  border-top: 1px solid var(--edge);
}

.postend {
  display: block;
  padding: 14px 16px;
  border: 1px solid var(--edge);
  border-radius: 10px;
  background: var(--paper-1);
  text-decoration: none;
  transition: transform 0.2s var(--ease), border-color 0.2s var(--ease),
    background 0.2s var(--ease);
}

.postend:hover,
.postend:focus-visible {
  transform: translateY(-3px);
  border-color: var(--accent);
  background-color: var(--paper-0);
}

.postend--next {
  text-align: right;
}

.postend__dir {
  display: block;
  font-family: var(--font-type);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-deep);
}

.postend__title {
  display: block;
  margin-top: 6px;
  font-family: var(--font-hand);
  font-size: 17px;
  line-height: 1.25;
  color: var(--ink);
}

.sheet.is-closing {
  animation: postClose 0.28s cubic-bezier(0.4, 0, 0.7, 1) forwards;
}

@keyframes postClose {
  to {
    transform: scale(0.985);
  }
}

@media (max-width: 620px) {
  .postends {
    grid-template-columns: minmax(0, 1fr);
  }

  .postend--next {
    text-align: left;
  }
}

.totop {
  position: fixed;
  right: clamp(14px, 2.4vw, 28px);
  bottom: clamp(14px, 2.4vw, 28px);
  z-index: 60;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--paper-2);
  color: var(--ink);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition:
    opacity 0.22s var(--ease),
    transform 0.22s var(--ease),
    visibility 0s linear 0.22s,
    background 0.18s var(--ease);
  box-shadow: 0 8px 18px -12px rgba(40, 26, 10, 0.7);
}

.totop.is-up {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s, 0s, 0s, 0s;
}

.totop:hover {
  background-color: var(--paper-0);
}

.totop:active {
  transform: scale(0.92);
}

@media (prefers-reduced-motion: reduce) {
  .totop {
    transition: opacity 0.01s, visibility 0s;
  }
}

body {
  -webkit-user-select: none;
  user-select: none;
}

input,
textarea {
  -webkit-user-select: text;
  user-select: text;
}

img {
  -webkit-user-drag: none;
  user-drag: none;
}

.ctx {
  position: fixed;
  z-index: 9500;
  min-width: 244px;
  max-width: 292px;
  padding: 18px 10px 20px;
  background-color: #f2e9d2;
  background-image:
    repeating-linear-gradient(180deg, transparent 0 25px, rgba(64, 52, 42, 0.055) 25px 26px),
    radial-gradient(120% 80% at 12% 0%, rgba(255, 252, 242, 0.85), transparent 60%);
  clip-path: polygon(0% 2.2%, 6% 0.5%, 13% 1.8%, 21% 0.3%, 29% 1.6%, 38% 0.4%, 47% 1.7%, 56% 0.5%, 65% 1.8%, 74% 0.4%, 83% 1.6%, 92% 0.6%, 100% 2%, 98.9% 12%, 100% 24%, 98.6% 36%, 100% 48%, 98.8% 60%, 100% 72%, 98.7% 84%, 100% 96%, 93% 98.4%, 85% 100%, 76% 98.2%, 67% 99.8%, 58% 98.4%, 49% 100%, 40% 98.5%, 31% 99.9%, 22% 98.3%, 13% 99.8%, 5% 98.4%, 0% 97%, 1.2% 86%, 0% 74%, 1.4% 62%, 0% 50%, 1.1% 38%, 0% 26%, 1.3% 14%);
  filter: drop-shadow(0 16px 26px rgba(20, 12, 4, 0.6));
  opacity: 0;
  visibility: hidden;
  transform: scale(0.95) rotate(-0.7deg);
  transform-origin: top left;
  pointer-events: none;
  transition: opacity 0.15s cubic-bezier(0.33, 1, 0.68, 1),
    transform 0.15s cubic-bezier(0.33, 1, 0.68, 1),
    visibility 0s linear 0.15s;
}

.ctx.is-open {
  opacity: 1;
  visibility: visible;
  transform: scale(1) rotate(-0.7deg);
  pointer-events: auto;
  transition-delay: 0s;
}

.ctx.is-flip-x { transform-origin: top right; }
.ctx.is-flip-y { transform-origin: bottom left; }
.ctx.is-flip-x.is-flip-y { transform-origin: bottom right; }

.ctx__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 14px 11px;
  font-family: "Special Elite", "Courier Prime", "Courier New", monospace;
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #8a5a2e;
}

.ctx__item {
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  text-align: left;
  padding: 8px 14px;
  border-radius: 7px;
  font-family: "Spectral", Georgia, serif;
  font-size: 14.5px;
  color: #241f18;
  background: none;
  border: 0;
  cursor: pointer;
  transition: background 0.16s cubic-bezier(0.33, 1, 0.68, 1),
    color 0.16s cubic-bezier(0.33, 1, 0.68, 1),
    transform 0.16s cubic-bezier(0.33, 1, 0.68, 1);
}

.ctx__item:hover,
.ctx__item:focus-visible {
  background: rgba(138, 90, 46, 0.14);
  color: #5d3a17;
  transform: translateX(3px);
}

.ctx__ico {
  flex: none;
  width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  text-align: center;
  font-size: 13px;
  opacity: 0.72;
}

.ctx__svg {
  width: 15px;
  height: 15px;
  display: block;
}

.ctx__item:hover .ctx__ico {
  opacity: 1;
}

.ctx__ext {
  margin-left: auto;
  font-family: "Special Elite", "Courier Prime", "Courier New", monospace;
  font-size: 9px;
  letter-spacing: 0.08em;
  color: rgba(36, 31, 24, 0.45);
}

.ctx__sep {
  height: 2px;
  margin: 8px 12px;
  background: repeating-linear-gradient(90deg, rgba(28, 26, 22, 0.22) 0 5px, transparent 5px 12px);
}

.toast {
  position: fixed;
  left: 50%;
  bottom: 32px;
  z-index: 9600;
  transform: translate(-50%, 14px);
  padding: 11px 20px;
  font-family: var(--font-type);
  font-size: 11.5px;
  letter-spacing: 0.06em;
  color: var(--paper-0);
  background: var(--ink);
  border: 1px solid var(--ink-2);
  border-radius: 255px 14px 225px 14px / 14px 225px 14px 255px;
  box-shadow: 0 22px 40px -18px rgba(40, 26, 10, 0.7);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}

.toast.is-open {
  opacity: 1;
  transform: translate(-50%, 0);
}

.shield-host {
  position: relative;
}

.img-shield {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: block;
  background: transparent;
  pointer-events: auto;
}

.ns {
  --ns-bg: #13100d;
  --ns-card: #efe3c6;
  --ns-ink: #2a2118;
  --ns-dim: rgba(42, 33, 24, 0.62);
  --ns-line: rgba(110, 84, 52, 0.26);
  --ns-acc: #7a4b3a;
  --ns-hover: rgba(122, 75, 58, 0.08);
  --ns-font: "Spectral", Georgia, serif;
  --ns-head: "Architects Daughter", "Patrick Hand", cursive;
}

.ns {
  position: fixed;
  inset: 0;
  z-index: 99999;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow: auto;
  padding: clamp(16px, 5vw, 56px) clamp(14px, 4vw, 32px);
  background: var(--ns-bg);
  color: var(--ns-ink);
  font-family: var(--ns-font);
  line-height: 1.6;
  -webkit-text-size-adjust: 100%;
}

.ns__card {
  width: 100%;
  max-width: 620px;
  margin: auto;
  padding: clamp(26px, 5vw, 44px) clamp(20px, 5vw, 40px);
  border: 1px solid var(--ns-line);
  border-radius: 14px;
  background: var(--ns-card);
  box-shadow: 0 24px 60px -30px rgba(0, 0, 0, 0.7);
}

.ns__brand {
  margin: 0;
  font-family: var(--ns-head);
  font-size: clamp(24px, 5vw, 31px);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--ns-ink);
}

.ns__kicker {
  margin: 8px 0 0;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ns-acc);
}

.ns__lede {
  margin: 18px 0 0;
  font-size: 14.5px;
  color: var(--ns-dim);
}

.ns__rule {
  height: 1px;
  margin: 24px 0;
  border: 0;
  background: var(--ns-line);
}

.ns__label {
  margin: 0 0 10px;
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ns-dim);
}

.ns__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ns__nav a {
  font-size: 14px;
  color: var(--ns-ink);
  text-decoration: none;
  border-bottom: 1px solid var(--ns-line);
}

.ns__nav a:hover,
.ns__nav a:focus-visible {
  color: var(--ns-acc);
  border-bottom-color: var(--ns-acc);
}

.ns__socials {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(122px, 1fr));
  gap: 6px 10px;
}

.ns__soc {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: 8px;
  font-size: 13px;
  color: var(--ns-ink);
  text-decoration: none;
}

.ns__soc:hover,
.ns__soc:focus-visible {
  border-color: var(--ns-line);
  color: var(--ns-acc);
  background: var(--ns-hover);
}

.ns__cta {
  display: inline-block;
  margin-top: 4px;
  padding: 11px 22px;
  border-radius: 999px;
  background: var(--ns-acc);
  color: var(--ns-card);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}

.ns__cta:hover,
.ns__cta:focus-visible {
  filter: brightness(1.08);
}

.ns__foot {
  margin: 22px 0 0;
  font-size: 12px;
  color: var(--ns-dim);
}

.ns__foot a {
  color: var(--ns-dim);
}

@media (prefers-reduced-motion: no-preference) {
  .ns__soc,
  .ns__nav a,
  .ns__cta {
    transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease, filter 0.18s ease;
  }
}

.ns__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin: 16px 0 0;
  font-size: 12.5px;
}

.ns__legal a {
  color: var(--ns-dim);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.ns__legal a:hover,
.ns__legal a:focus-visible {
  color: var(--ns-acc);
  border-bottom-color: var(--ns-acc);
}

.ns {
  position: static;
  inset: auto;
  z-index: auto;
  display: block;
  min-height: 0;
  padding: 0 clamp(16px, 4vw, 46px) 40px;
  background: none;
}

.ns__card {
  margin: 0 auto;
  box-shadow: 0 18px 40px -30px rgba(40, 26, 10, 0.6);
}

.catbar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 22px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--edge);
}

.catlink {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 13px;
  border: 1px solid transparent;
  border-radius: 99px;
  font-family: var(--font-type);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-decoration: none;
  transition: background 0.18s var(--ease), border-color 0.18s var(--ease),
    color 0.18s var(--ease);
}

.catlink:hover {
  background: var(--paper-0);
  border-color: var(--edge);
  color: var(--ink);
}

.catlink.is-on {
  background: var(--accent-wash);
  border-color: var(--accent);
  color: var(--accent-deep);
}

.catlink__n {
  font-size: 9.5px;
  opacity: 0.6;
}

.entry__cat {
  font-family: var(--font-type);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-deep);
}

.entry__tags {
  display: inline-flex;
  gap: 5px;
  flex-wrap: wrap;
}

.tag {
  padding: 2px 8px;
  border: 1px solid var(--edge);
  border-radius: 99px;
  font-family: var(--font-type);
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--ink-mute);
}

.sidepanel + .sidepanel {
  margin-top: 26px;
}

.side__head {
  margin-bottom: 9px;
}

.sidelink {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 3px 0;
  color: var(--ink-2);
  text-decoration: none;
  transition: color 0.16s var(--ease);
}

.sidelink:hover,
.sidelink.is-on {
  color: var(--accent-deep);
}

.pin {
  display: block;
  padding: 13px 14px;
  border: 1px solid var(--edge);
  border-radius: 10px;
  background: var(--paper-0);
  text-decoration: none;
  transition: border-color 0.18s var(--ease), transform 0.18s var(--ease);
}

.pin:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}

.pin__title {
  display: block;
  font-family: var(--font-hand);
  font-size: 17px;
  line-height: 1.2;
  color: var(--ink);
}

.pin__excerpt {
  display: block;
  margin-top: 6px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink-dim);
}

.pin__more {
  display: block;
  margin-top: 8px;
  font-family: var(--font-type);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-deep);
}

.card + .card {
  margin-top: 12px;
}

.card {
  padding: 13px 14px 14px;
  border: 1px solid var(--edge);
  border-radius: 10px;
  background: var(--paper-0);
  transition: border-color 0.18s var(--ease);
}

.card:hover {
  border-color: color-mix(in srgb, var(--brand) 45%, var(--edge));
}

.card__top {
  display: flex;
  align-items: center;
  gap: 10px;
}

.card__mark {
  flex: none;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 9px;
  background: color-mix(in srgb, var(--brand) 16%, transparent);
  color: var(--brand);
}

.brandmark {
  width: 21px;
  height: 21px;
  display: block;
}

.card__meta {
  min-width: 0;
}

.card__name {
  display: block;
  font-family: var(--font-type);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
}

.card__handle {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--ink-dim);
}

.card__stat {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  font-family: var(--font-type);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  color: var(--ink-mute);
}

.card__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #3ba55d;
}

.card__blurb {
  margin: 10px 0 12px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-dim);
}

.card__cta {
  display: block;
  padding: 9px 12px;
  border-radius: 7px;
  background: var(--brand);
  color: #fff;
  font-family: var(--font-type);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-align: center;
  text-decoration: none;
  transition: filter 0.16s var(--ease), transform 0.16s var(--ease);
}

.card__cta:hover {
  filter: brightness(1.08);
  transform: translateY(-1px);
}

.card__cta:active {
  transform: translateY(0);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.chip {
  padding: 5px 11px;
  border: 1px solid var(--edge);
  border-radius: 99px;
  font-family: var(--font-type);
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--ink-2);
  text-decoration: none;
  transition: border-color 0.16s var(--ease), color 0.16s var(--ease),
    background 0.16s var(--ease);
}

.chip:hover {
  border-color: var(--accent);
  background: var(--accent-wash);
  color: var(--accent-deep);
}

@media (max-width: 620px) {
  .catbar {
    margin-bottom: 16px;
  }

  .catlink {
    padding: 6px 11px;
    font-size: 10px;
  }
}

@media (max-width: 620px) {
  .totop {
    bottom: 92px;
    right: 12px;
    width: 40px;
    height: 40px;
  }
}

.progress {
  position: fixed;
  inset: 0 0 auto;
  z-index: 55;
  height: 3px;
  pointer-events: none;
}

.progress i {
  display: block;
  height: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: var(--accent);
  opacity: 0.75;
}

.post__body h2,
.post__body h3 {
  position: relative;
}

.anchor {
  margin-left: 8px;
  font-size: 0.62em;
  color: var(--ink-mute);
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.16s var(--ease);
}

h2:hover .anchor,
h3:hover .anchor,
.anchor:focus-visible {
  opacity: 1;
}

.lightbox[hidden] {
  display: none;
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 9400;
  display: grid;
  place-items: center;
  padding: clamp(16px, 4vw, 56px);
  background: rgba(38, 30, 18, 0.86);
  opacity: 0;
  transition: opacity 0.22s var(--ease);
  cursor: zoom-out;
}

.lightbox.is-open {
  opacity: 1;
}

/* The stage carries the grow-from-thumbnail move; the image inside carries
   the hover tilt. Keeping them on separate elements means one transform never
   overwrites the other, which is what happens if you animate both on the img. */
.lightbox__stage {
  display: grid;
  place-items: center;
  max-width: 100%;
  max-height: 100%;
  transform-origin: center;
  transition:
    transform 0.34s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.26s ease;
  will-change: transform;
}

.lightbox img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  border-radius: 4px;
  box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.9);
  transform: perspective(1400px) rotateX(var(--tiltX, 0deg)) rotateY(var(--tiltY, 0deg));
  transition: transform 0.28s var(--ease), box-shadow 0.28s var(--ease);
}

/* Lit from above as it tips, so the tilt reads as a physical object catching
   the light rather than as a div being rotated. */
.lightbox.is-open img:hover {
  box-shadow:
    0 40px 80px -34px rgba(0, 0, 0, 0.95),
    0 0 0 1px rgba(255, 248, 230, 0.09);
}

@media (prefers-reduced-motion: reduce) {
  .lightbox__stage {
    transition: opacity 0.2s ease;
  }
  .lightbox img {
    transform: none;
    transition: none;
  }
}

.lightbox__shut {
  position: absolute;
  top: clamp(10px, 2vw, 22px);
  right: clamp(10px, 2vw, 22px);
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 250, 236, 0.14);
  color: #f4ecd8;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

html.is-boxed {
  overflow: hidden;
}

.post__body figure img {
  cursor: zoom-in;
}

.lost {
  padding: 40px 0 30px;
  text-align: center;
}

@media (min-width: 1600px) {
  :root {
    --col: 800px;
    --side: 290px;
  }
}

@media print {
  @page {
    margin: 18mm 16mm 20mm;
  }

  body {
    background: #fff !important;
    color: #000;
    -webkit-user-select: text !important;
    user-select: text !important;
  }

  .masthead__nav,
  .side,
  .catbar,
  .postnav,
  .postends,
  .totop,
  .progress,
  .langnote,
  .feedend,
  #loadMore,
  .ctx,
  .toast,
  .lightbox,
  .img-shield,
  .footer .legal {
    display: none !important;
  }

  .wrap,
  .wrap--post {
    display: block;
    max-width: none;
    padding: 0;
  }

  .sheet {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: #fff !important;
    background-image: none !important;
    padding: 0;
  }

  .post__tab {
    position: static;
    max-width: none;
    margin: 0 0 14px;
    padding: 0;
    border: 0;
    background: none;
    transform: none;
    animation: none;
  }

  .post__body {
    font-size: 11pt;
    max-width: none;
    animation: none;
  }

  .post__body a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
    color: #555;
    word-break: break-all;
  }

  .post__body figure {
    break-inside: avoid;
  }

  .anchor {
    display: none;
  }
}

.sheet {
  background-color: var(--paper-0);
  background-image:

    linear-gradient(107deg, transparent 0 38%, rgba(94, 76, 50, 0.045) 38.4%, transparent 38.9% 100%),
    linear-gradient(263deg, transparent 0 61%, rgba(94, 76, 50, 0.038) 61.3%, transparent 61.8% 100%),
    linear-gradient(84deg, transparent 0 73%, rgba(255, 252, 242, 0.5) 73.3%, transparent 73.7% 100%),

    radial-gradient(130% 100% at 50% 45%, rgba(255, 252, 242, 0.4), rgba(255, 252, 242, 0) 58%),
    radial-gradient(120% 95% at 50% 50%, transparent 62%, rgba(94, 76, 50, 0.07) 100%),

    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='700' height='700'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012' numOctaves='3' seed='7'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeGaussianBlur stdDeviation='1.4'/%3E%3C/filter%3E%3Crect width='700' height='700' filter='url(%23m)' opacity='0.16'/%3E%3C/svg%3E"),

    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23p)' opacity='0.05'/%3E%3C/svg%3E");
  background-size:
    100% 100%,
    100% 100%,
    100% 100%,
    100% 100%,
    100% 100%,
    700px 700px,
    300px 300px;
  background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, repeat, repeat;
  background-blend-mode: normal, normal, normal, normal, normal, multiply, normal;
}

/* ---- CRT overlay ---------------------------------------------------------
   Ported from hub. Same scanline pitch and the same multiply blend, so the two
   sites read as one screen. Driven by is-crt, which BlogXP sets from the hub
   cookie at the same moment it raises the desktop. */
.crt {
  position: fixed;
  inset: 0;
  z-index: 8000;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s var(--ease);
  background:
    repeating-linear-gradient(180deg, rgba(40, 30, 20, 0.16) 0 1px, transparent 1px 3px),
    radial-gradient(ellipse 100% 90% at 50% 50%, transparent 55%, rgba(50, 36, 22, 0.3) 100%);
  mix-blend-mode: multiply;
}

html.is-crt .crt {
  opacity: 1;
  animation: crtFlicker 5.5s steps(1) infinite;
}

/* Opens at full opacity, so a paused animation in a background tab cannot
   leave the overlay invisible. */
@keyframes crtFlicker {
  0%, 94%, 100% { opacity: 1; }
  96% { opacity: 0.86; }
  98% { opacity: 0.95; }
}

@media (prefers-reduced-motion: reduce) {
  html.is-crt .crt {
    animation: none;
  }
}

@media print {
  .crt {
    display: none !important;
  }
}

/* ---- CRT easter egg: the desktop ----------------------------------------
   Only ever visible with html.is-xp. Everything here is period pastiche drawn
   from scratch: no borrowed artwork, no font file. The pixelated feel comes
   from switching antialiasing off, which hardens every glyph edge, plus hard
   1px bevels instead of soft shadows. */
html.is-xp,
html.is-xp body {
  overflow: hidden;
}

/* The paper page still exists in the DOM, moved inside the browser window, so
   it must not also paint its own background behind the desktop. */
html.is-xp body {
  background: #3a6ea5;
}

.xp {
  position: fixed;
  inset: 0;
  z-index: 7000;
  display: flex;
  flex-direction: column;
  font-family: Tahoma, "MS Sans Serif", "Microsoft Sans Serif", Geneva, sans-serif;
  font-size: 11px;
  color: #000;
  -webkit-font-smoothing: none;
  -moz-osx-font-smoothing: unset;
  text-rendering: optimizeSpeed;
}

.xp__art {
  display: block;
  flex: none;
  image-rendering: pixelated;
}

/* A plain two-stop sky rather than the photograph, because the photograph is
   not ours to ship. */
.xp__screen {
  position: relative;
  flex: 1;
  min-height: 0;
  background:
    radial-gradient(ellipse 120% 70% at 50% 100%, #7fae52 0 38%, transparent 39%),
    linear-gradient(180deg, #1f4f86 0%, #3a6ea5 45%, #6f9fd0 100%);
}

.xp__icons {
  position: absolute;
  top: 8px;
  left: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  z-index: 1;
}

.xp__icon {
  width: 76px;
  padding: 5px 3px 6px;
  display: grid;
  justify-items: center;
  gap: 4px;
  border: 1px dotted transparent;
  background: none;
  color: #fff;
  font-size: 11px;
  line-height: 1.25;
  text-align: center;
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.7);
  cursor: default;
}

.xp__icon:hover,
.xp__icon:focus-visible {
  border-color: rgba(255, 255, 255, 0.6);
  background: rgba(49, 106, 197, 0.45);
  outline: none;
}

/* ---- taskbar ------------------------------------------------------------- */
.xp__bar {
  flex: none;
  height: 30px;
  display: flex;
  align-items: stretch;
  gap: 4px;
  padding: 2px 3px;
  background: linear-gradient(180deg, #3f8be8 0 8%, #245edb 12% 88%, #1941a5 100%);
  border-top: 1px solid #6ba4e8;
}

.xp__start {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 0 14px 0 8px;
  border: 0;
  border-radius: 0 8px 8px 0;
  background: linear-gradient(180deg, #59a94b 0 10%, #3c8a33 14% 86%, #2c6b26 100%);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  font-style: italic;
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5);
  cursor: default;
}

.xp__start:hover {
  filter: brightness(1.1);
}

.xp__tasks {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 3px;
  overflow: hidden;
}

.xp__task {
  max-width: 170px;
  padding: 4px 9px;
  border: 1px solid #1941a5;
  background: linear-gradient(180deg, #4a90e2, #2f6fc4);
  color: #fff;
  font-size: 11px;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: default;
}

.xp__task svg {
  display: none;
}

.xp__tray {
  flex: none;
  display: flex;
  align-items: center;
  padding: 0 10px;
  background: linear-gradient(180deg, #1a8ad4, #1567b0);
  border-left: 1px solid #4a9fdd;
  color: #fff;
}

/* ---- windows -------------------------------------------------------------
   Hard 1px bevels, no border-radius beyond the title bar, no soft shadows.
   That combination is most of what makes it read as the period. */
.xpwin {
  position: absolute;
  z-index: 40;
  min-width: 240px;
  width: 420px;
  max-width: calc(100vw - 48px);
  display: flex;
  flex-direction: column;
  background: #ece9d8;
  border: 1px solid #0831d9;
  border-radius: 6px 6px 0 0;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.35);
}

.xpwin__bar {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 3px 4px 4px 6px;
  border-radius: 5px 5px 0 0;
  background: linear-gradient(180deg, #0058ee 0 8%, #3f8ef7 12%, #0058ee 40%, #003ec9 100%);
  color: #fff;
  cursor: default;
  touch-action: none;
}

.xpwin:not(.is-front) .xpwin__bar {
  background: linear-gradient(180deg, #7ba2df 0 8%, #a8c2e8 12%, #7ba2df 100%);
}

.xpwin__name {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 700;
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.45);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.xpwin__btn {
  width: 19px;
  height: 18px;
  display: grid;
  place-items: center;
  border: 1px solid #f7c8bd;
  border-radius: 3px;
  background: linear-gradient(180deg, #f08a6a, #d63e12);
  color: #fff;
  font-size: 12px;
  line-height: 1;
  cursor: default;
}

.xpwin__btn:hover {
  filter: brightness(1.12);
}

.xpwin__body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 8px;
  background: #ece9d8;
  border-top: 1px solid #0831d9;
}

/* ---- the browser, and the real page inside it ---------------------------- */
.xpbrowser {
  height: 100%;
  display: flex;
  flex-direction: column;
  margin: -8px;
}

.xpbrowser__chrome {
  flex: none;
  background: #ece9d8;
  border-bottom: 1px solid #9a9584;
}

.xpbrowser__menu {
  display: flex;
  gap: 12px;
  padding: 3px 8px;
  border-bottom: 1px solid #d6d2c2;
}

.xpbrowser__menu span {
  cursor: default;
}

.xpbrowser__addr {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
}

.xpbrowser__addr label {
  color: #4a4a4a;
}

.xpbrowser__addr input {
  flex: 1;
  min-width: 0;
  padding: 2px 5px;
  border: 1px solid #7f9db9;
  background: #fff;
  font-family: inherit;
  font-size: 11px;
  color: #000;
}

/* The viewport. The paper page is moved in here, and it keeps its own design:
   an old machine showing a modern site, not the site pretending to be old. */
.xpbrowser__page {
  flex: 1;
  min-height: 0;
  overflow: auto;
  background: var(--paper-1);
  border-top: 1px solid #fff;
}

.xpbrowser__page .masthead,
.xpbrowser__page .wrap,
.xpbrowser__page .footer {
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
}

/* Inside a window the page is a column, not a viewport-height layout. */
.xpbrowser__page .wrap {
  grid-template-columns: minmax(0, 1fr);
  max-width: none;
}

.xpbrowser__page .side {
  position: static;
}

.xpbrowser__status {
  flex: none;
  display: flex;
  justify-content: space-between;
  padding: 3px 8px;
  background: #ece9d8;
  border-top: 1px solid #9a9584;
  color: #4a4a4a;
}

/* ---- app contents -------------------------------------------------------- */
.xptext {
  margin: 0;
  padding: 6px;
  background: #fff;
  border: 1px solid #7f9db9;
  font-family: "Lucida Console", "Courier New", monospace;
  font-size: 11px;
  line-height: 1.55;
  white-space: pre-wrap;
  color: #000;

  /* Left, deliberately, while the case file is justified.

     These windows hold transcripts and logs, and their speaker labels are
     lined up with runs of spaces. Justifying stretches the gaps between words,
     which pulls those columns apart, and pre-wrap cannot be swapped for
     pre-line to fix the hanging space without collapsing the very runs doing
     the aligning. A machine-typed log has a ragged edge anyway; a dossier is
     the thing that was typeset. */
  text-align: left;
  hyphens: none;
  -webkit-hyphens: none;
  overflow-wrap: break-word;
}

.xpfiles {
  background: #fff;
  border: 1px solid #7f9db9;
  padding: 6px;
  min-height: 96px;
}

.xpfiles__row {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 3px 4px;
  cursor: default;
}

.xpfiles__row:hover {
  background: #316ac5;
  color: #fff;
}

.xpfiles__row.is-dim {
  color: #8a8a8a;
  font-style: italic;
}

.xpfound {
  display: grid;
  justify-items: center;
  gap: 7px;
  padding: 16px 12px 18px;
  text-align: center;
}

/* The dev panel and the back-to-top button belong to the paper site, not to
   the machine, so they step out of the way while it is on. */
html.is-xp .totop {
  display: none;
}

@media (max-width: 700px) {
  .xpwin,
  .xpwin--wide {
    left: 8px !important;
    top: 8px !important;
    width: calc(100vw - 16px);
    height: calc(100vh - 96px);
  }

  .xp__icons {
    flex-direction: row;
    flex-wrap: wrap;
    width: calc(100vw - 16px);
  }
}

/* ---- the machine, second pass -------------------------------------------
   Repainted from consumer blue to something that belongs to somebody who does
   not want it found. Overrides the earlier block rather than replacing it in
   place, so the geometry there still holds and only the surface changes. */
.xp__screen {
  background:
    radial-gradient(ellipse 90% 60% at 50% 120%, rgba(127, 156, 107, 0.14) 0 40%, transparent 41%),
    linear-gradient(180deg, #0d1310 0%, #141c18 55%, #0a0f0d 100%);
}

/* The studio mark, sunk into the wallpaper rather than presented. Low contrast
   on purpose: it should read as a stencil on government hardware. */
.xp__mark {
  position: absolute;
  inset: 0;
  background-image: url("assets/img/mark.webp");
  background-repeat: no-repeat;
  background-position: center 42%;
  background-size: min(360px, 42vw) auto;
  opacity: 0.07;
  filter: grayscale(1) contrast(1.4);
  pointer-events: none;
}

.xp__icon {
  color: #cbd6c2;
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.85);
}

.xp__icon:hover,
.xp__icon:focus-visible {
  border-color: rgba(127, 156, 107, 0.55);
  background: rgba(127, 156, 107, 0.16);
}

.xp__bar {
  background: linear-gradient(180deg, #24302a 0 8%, #17201c 12% 88%, #0d1310 100%);
  border-top: 1px solid #3c4b41;
}

.xp__start {
  background: linear-gradient(180deg, #4d6141 0 10%, #3a4c31 14% 86%, #29371f 100%);
  font-style: normal;
  letter-spacing: 0.06em;
  text-transform: lowercase;
}

.xp__task {
  border-color: #0d1310;
  background: linear-gradient(180deg, #2d3a32, #1d2721);
  color: #cbd6c2;
}

.xp__task.is-off {
  background: linear-gradient(180deg, #202a24, #161d19);
  color: #7f8b78;
}

.xp__tray {
  background: linear-gradient(180deg, #1b241f, #121917);
  border-left: 1px solid #3c4b41;
  color: #a9b8a0;
}

/* ---- windows ------------------------------------------------------------- */
.xpwin {
  background: #d8d4c4;
  border: 1px solid #26332c;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);
}

.xpwin__bar {
  background: linear-gradient(180deg, #33463a 0 8%, #4a6152 12%, #2c3d33 40%, #1c2721 100%);
}

.xpwin:not(.is-front) .xpwin__bar {
  background: linear-gradient(180deg, #566257 0 8%, #6b776b 12%, #4a544b 100%);
}

.xpwin__btns {
  display: flex;
  gap: 2px;
}

.xpwin__btn {
  border: 1px solid #8d9a88;
  background: linear-gradient(180deg, #6d7c69, #4c5949);
}

.xpwin__btn--shut {
  border-color: #d0a79b;
  background: linear-gradient(180deg, #a8543f, #7b3323);
}

.xpwin__body {
  background: #d8d4c4;
  border-top: 1px solid #26332c;
}

/* Maximised fills the screen above the taskbar. */
.xpwin.is-max {
  left: 0 !important;
  top: 0 !important;
  width: 100% !important;
  max-width: none !important;
  max-height: none !important;
  height: 100% !important;
  border-radius: 0;
}

.xpwin.is-max .xpwin__bar {
  border-radius: 0;
}

/* ---- menu bar ------------------------------------------------------------ */
.xpbrowser__chrome {
  background: #d8d4c4;
  border-bottom: 1px solid #7d8878;
}

.xpbrowser__menu {
  border-bottom: 1px solid #c2bda9;
}

.xpmenu {
  position: relative;
  cursor: default;
}

.xpmenu__label {
  padding: 2px 5px;
}

.xpmenu.is-open .xpmenu__label,
.xpmenu__label:hover {
  background: #3d5142;
  color: #eef2e9;
}

.xpmenu__drop {
  position: absolute;
  left: 0;
  top: 100%;
  z-index: 30;
  min-width: 190px;
  display: none;
  flex-direction: column;
  padding: 2px;
  background: #ded9c8;
  border: 1px solid #26332c;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4);
}

.xpmenu.is-open .xpmenu__drop {
  display: flex;
}

.xpmenu__row {
  padding: 4px 10px;
  white-space: nowrap;
  cursor: default;
}

.xpmenu__row:hover {
  background: #3d5142;
  color: #eef2e9;
}

/* ---- tabs ---------------------------------------------------------------- */
.xptabs {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  padding: 4px 6px 0;
  background: #cfcab8;
  border-bottom: 1px solid #7d8878;
  overflow-x: auto;
}

.xptab {
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: 190px;
  padding: 4px 6px 4px 9px;
  border: 1px solid #7d8878;
  border-bottom: 0;
  border-radius: 4px 4px 0 0;
  background: linear-gradient(180deg, #c3bfae, #b2ae9d);
  font-size: 11px;
  cursor: default;
}

.xptab.is-on {
  background: linear-gradient(180deg, #ecead9, #d8d4c4);
  padding-bottom: 5px;
}

.xptab__name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.xptab__x {
  width: 14px;
  height: 14px;
  flex: none;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 2px;
  background: none;
  font-size: 12px;
  line-height: 1;
  color: #4a4a42;
  cursor: default;
}

.xptab__x:hover {
  background: #a8543f;
  color: #fff;
}

.xptabs__pad {
  flex: 1;
}

/* ---- panes --------------------------------------------------------------- */
.xppane {
  min-height: 100%;
}

.xppane[hidden] {
  display: none;
}

.xppane__wait {
  padding: 40px 20px;
  text-align: center;
  font-family: "Lucida Console", "Courier New", monospace;
  font-size: 11px;
  color: #4a4a42;
}

/* A post opened in a tab is the real article, so it keeps the paper look but
   needs its own padding: it is no longer sitting in the page grid. */
.xppane .sheet {
  margin: 14px;
}

.xpbrowser__status {
  background: #d8d4c4;
  border-top: 1px solid #7d8878;
  color: #4a4a42;
}

/* ---- app contents -------------------------------------------------------- */
.xptext,
.xpfiles {
  background: #10160f;
  border: 1px solid #3c4b41;
  color: #9fba8b;
}

.xpfiles__row:hover {
  background: #2d4030;
  color: #d6e6c9;
}

.xpfiles__row.is-dim {
  color: #5e6b58;
}

.xpstatic {
  height: 96px;
  display: grid;
  place-items: center;
  margin-bottom: 6px;
  border: 1px solid #3c4b41;
  background:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.04) 0 1px, transparent 1px 2px),
    #0b0f0a;
  color: #7f9c6b;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.xpfound {
  background: #10160f;
  border: 1px solid #3c4b41;
  color: #9fba8b;
}

/* ---- the machine's context menu ------------------------------------------ */
.xpctx {
  position: fixed;
  z-index: 9000;
  min-width: 186px;
  display: none;
  flex-direction: column;
  padding: 2px;
  background: #ded9c8;
  border: 1px solid #26332c;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.45);
  font-size: 11px;
}

.xpctx.is-open {
  display: flex;
}

.xpctx__row {
  padding: 5px 11px;
  white-space: nowrap;
  cursor: default;
}

.xpctx__row:hover {
  background: #3d5142;
  color: #eef2e9;
}

/* The paper site's own menu is suppressed while the machine is on. */
html.is-xp .ctx {
  display: none !important;
}

/* ---- window resize grips -------------------------------------------------
   Invisible strips on the right edge, bottom edge and corner. 6px is about the
   smallest a pointer reliably finds; the corner gets a wider bite because that
   is the one people aim for. */
.xpgrip {
  position: absolute;
  z-index: 3;
}

.xpgrip--e {
  top: 22px;
  right: -3px;
  bottom: 12px;
  width: 7px;
  cursor: ew-resize;
}

.xpgrip--s {
  left: 12px;
  right: 12px;
  bottom: -3px;
  height: 7px;
  cursor: ns-resize;
}

.xpgrip--se {
  right: -3px;
  bottom: -3px;
  width: 15px;
  height: 15px;
  cursor: nwse-resize;
}

/* A maximised window has nothing to resize. */
.xpwin.is-max .xpgrip {
  display: none;
}

/* Maximise is disabled on the dialogs: only the browser fills the screen. */
.xpwin__btn.is-off {
  opacity: 0.4;
  cursor: default;
}

/* The taskbar shows which window is actually in front. */
.xp__task.is-front {
  background: linear-gradient(180deg, #1a241e, #2a382f);
  border-color: #4d6141;
  box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.5);
  font-weight: 700;
}

/* ---- start menu ---------------------------------------------------------- */
.xpstartmenu {
  position: absolute;
  left: 3px;
  bottom: 32px;
  z-index: 60;
  width: 214px;
  display: none;
  flex-direction: column;
  background: #1b241f;
  border: 1px solid #4d6141;
  box-shadow: 3px -3px 0 rgba(0, 0, 0, 0.5);
  color: #cbd6c2;
}

.xp.is-menu .xpstartmenu {
  display: flex;
}

.xpstartmenu__head {
  padding: 9px 11px;
  background: linear-gradient(180deg, #3a4c31, #24301f);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #a9c092;
}

.xpstartmenu__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 11px;
  border: 0;
  background: none;
  color: #cbd6c2;
  font-family: inherit;
  font-size: 11px;
  text-align: left;
  cursor: default;
}

.xpstartmenu__row:hover {
  background: #3d5142;
  color: #eef2e9;
}

/* ---- shutting down ------------------------------------------------------- */
html.is-bye .xp {
  filter: brightness(0.5) saturate(0.4);
}

.xpbye {
  position: fixed;
  inset: 0;
  z-index: 9200;
  display: grid;
  place-items: center;
  background: rgba(6, 9, 7, 0.86);
}

.xpbye__box {
  padding: 22px 34px;
  border: 1px solid #4d6141;
  background: #10160f;
  color: #a9c092;
  font-family: Tahoma, "MS Sans Serif", sans-serif;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-align: center;
  -webkit-font-smoothing: none;
}

/* A tube losing its deflection: the picture squeezes to a bright line, the
   line squeezes to a dot, the dot fades. Scale only, so it stays cheap. */
.xpcollapse {
  position: fixed;
  inset: 0;
  z-index: 9300;
  background: #000;
  pointer-events: none;
}

.xpcollapse::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 3px;
  margin-top: -1.5px;
  background: #eaf6e2;
  box-shadow: 0 0 18px 6px rgba(210, 240, 200, 0.75);
  transform-origin: 50% 50%;
  animation: crtCollapse 0.62s cubic-bezier(0.5, 0, 0.75, 0) forwards;
}

@keyframes crtCollapse {
  0% { transform: scaleX(1) scaleY(1); opacity: 1; }
  45% { transform: scaleX(1) scaleY(1); opacity: 1; }
  80% { transform: scaleX(0.06) scaleY(1); opacity: 1; }
  100% { transform: scaleX(0.004) scaleY(0.4); opacity: 0; }
}

.xpflash {
  position: fixed;
  inset: 0;
  z-index: 9300;
  pointer-events: none;
  background: radial-gradient(ellipse 70% 60% at 50% 50%, rgba(224, 245, 215, 0.5), transparent 70%);
  animation: crtWake 0.85s ease-out forwards;
}

@keyframes crtWake {
  0% { opacity: 1; transform: scaleY(0.02); }
  30% { opacity: 1; transform: scaleY(1); }
  100% { opacity: 0; transform: scaleY(1); }
}

/* ---- the room, machine off ----------------------------------------------
   Dim, one lamp off to the side and a heavy vignette, the same treatment the
   socials desk uses. The pull-back is small on purpose: far enough to reach the
   power button, not so far that you are looking at furniture. */
html.is-off .xp,
html.is-off .crt {
  display: none;
}

.xproom {
  position: fixed;
  inset: 0;
  z-index: 9100;
  display: grid;
  place-items: center;
  overflow: hidden;
  background:
    radial-gradient(ellipse 60% 50% at 22% 8%, rgba(120, 104, 72, 0.16), transparent 60%),
    linear-gradient(180deg, #0a0b0a 0%, #121311 55%, #070807 100%);
}

.xproom__cone {
  position: absolute;
  left: -8%;
  top: -20%;
  width: 62%;
  height: 120%;
  background: linear-gradient(168deg, rgba(214, 196, 148, 0.13), rgba(214, 196, 148, 0) 62%);
  filter: blur(22px);
  animation: roomFlicker 7.5s steps(1) infinite;
}

/* Opens at full opacity, so a paused animation cannot leave the room black. */
@keyframes roomFlicker {
  0%, 92%, 100% { opacity: 1; }
  94% { opacity: 0.82; }
  97% { opacity: 0.93; }
}

.xproom__vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 78% 70% at 50% 48%, transparent 42%, rgba(0, 0, 0, 0.82) 100%);
}

.xproom__rig {
  position: relative;
  z-index: 2;
  transform: scale(1.12) translateY(2%);
  transition: transform 0.55s cubic-bezier(0.33, 1, 0.68, 1);
}

.xproom.is-back .xproom__rig {
  transform: scale(0.9) translateY(-1%);
}

.xpmon {
  width: min(66vw, 620px);
  border-radius: 22px 22px 12px 12px;
  padding: 18px 18px 0;
  background: linear-gradient(168deg, #d9d2bd 0%, #c6bfa9 42%, #a89f88 100%);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.45),
    0 40px 60px -30px rgba(0, 0, 0, 0.9);
}

.xpmon__face {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 34% / 26%;
  overflow: hidden;
  background:
    radial-gradient(ellipse 80% 70% at 50% 42%, #14191a 0%, #0a0d0e 60%, #050707 100%);
  box-shadow: inset 0 0 0 6px #8f8874, inset 0 0 34px 14px rgba(0, 0, 0, 0.85);
}

/* Head and shoulders, sitting where you would be. Blurred hard, because a
   reflection in dark glass has no edges. */
.xpmon__ghost {
  position: absolute;
  left: 50%;
  bottom: -6%;
  width: 56%;
  height: 78%;
  transform: translateX(-50%);
  filter: blur(7px);
  opacity: 0.72;
}

.xpmon__head {
  position: absolute;
  left: 50%;
  top: 4%;
  width: 34%;
  aspect-ratio: 1 / 1.14;
  transform: translateX(-50%);
  border-radius: 50%;
  background: #000;
}

.xpmon__torso {
  position: absolute;
  left: 50%;
  top: 40%;
  width: 100%;
  height: 70%;
  transform: translateX(-50%);
  border-radius: 46% 46% 0 0 / 62% 62% 0 0;
  background: #000;
}

.xpmon__sheen {
  position: absolute;
  inset: 0;
  background: linear-gradient(148deg, rgba(226, 236, 226, 0.1) 0 18%, transparent 34%);
  pointer-events: none;
}

.xpmon__chin {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 14px 12px;
}

.xpmon__brand {
  font-family: Tahoma, "MS Sans Serif", sans-serif;
  font-size: 10px;
  letter-spacing: 0.34em;
  color: #6f6857;
  -webkit-font-smoothing: none;
}

.xpmon__power {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: 1px solid #8f8874;
  border-radius: 50%;
  background: linear-gradient(180deg, #cdc6b1, #ada695);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 2px 3px rgba(0, 0, 0, 0.35);
  cursor: pointer;
}

.xpmon__power:hover {
  filter: brightness(1.06);
}

.xpmon__power:active {
  transform: translateY(1px);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.4);
}

.xpmon__led {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #4a5340;
  box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.6);
  animation: ledWait 2.6s ease-in-out infinite;
}

@keyframes ledWait {
  0%, 100% { background: #4a5340; }
  50% { background: #7f9c6b; box-shadow: 0 0 6px 1px rgba(127, 156, 107, 0.6); }
}

.xproom__base {
  height: 20px;
  margin: 0 auto;
  width: 74%;
  border-radius: 0 0 8px 8px;
  background: linear-gradient(180deg, #b3ab94, #8b8471);
  box-shadow: 0 26px 30px -22px rgba(0, 0, 0, 0.9);
}

.xproom__hint {
  position: absolute;
  bottom: 5%;
  left: 0;
  right: 0;
  z-index: 3;
  text-align: center;
  font-family: Tahoma, "MS Sans Serif", sans-serif;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(180, 196, 170, 0.4);
  -webkit-font-smoothing: none;
}

@media (prefers-reduced-motion: reduce) {
  .xproom__cone,
  .xpmon__led {
    animation: none;
  }

  .xproom__rig {
    transition: none;
  }
}

/* One shape passing behind his right shoulder, on his right as he sits, which
   is screen left in a reflection. Deliberately brief and heavily blurred: the
   point is that you are not sure you saw it. */
.xpmon__over {
  position: absolute;
  left: 4%;
  bottom: -14%;
  width: 34%;
  height: 92%;
  border-radius: 44% 44% 0 0 / 58% 58% 0 0;
  background: #000;
  filter: blur(11px);
  opacity: 0;
  pointer-events: none;
  animation: overShoulder 1.5s cubic-bezier(0.4, 0, 0.5, 1) forwards;
}

@keyframes overShoulder {
  0% { opacity: 0; transform: translateX(-30%) scaleY(0.94); }
  18% { opacity: 0.92; }
  62% { opacity: 0.88; transform: translateX(-4%) scaleY(1); }
  84% { opacity: 0.7; }
  100% { opacity: 0; transform: translateX(14%) scaleY(1); }
}

/* ---- the locked file ----------------------------------------------------- */
.xplogin {
  padding: 14px 16px 16px;
  background: #10160f;
  border: 1px solid #3c4b41;
  color: #9fba8b;
}

.xplogin__head {
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid #6b2d22;
  color: #c0553f;
  font-size: 11px;
  letter-spacing: 0.22em;
}

.xplogin__row {
  display: grid;
  grid-template-columns: 88px 1fr;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 10px;
  letter-spacing: 0.14em;
}

.xplogin__row input {
  padding: 4px 6px;
  border: 1px solid #3c4b41;
  background: #060a06;
  color: #cfe3bd;
  font-family: "Lucida Console", "Courier New", monospace;
  font-size: 12px;
  letter-spacing: 0.1em;
}

.xplogin__row input:focus {
  outline: none;
  border-color: #7f9c6b;
}

.xplogin__go {
  width: 100%;
  margin-top: 4px;
  padding: 6px;
  border: 1px solid #4d6141;
  background: linear-gradient(180deg, #2d3a32, #1d2721);
  color: #cbd6c2;
  font-family: inherit;
  font-size: 10px;
  letter-spacing: 0.18em;
  cursor: pointer;
}

.xplogin__go:hover {
  filter: brightness(1.15);
}

.xplogin__err {
  margin-top: 10px;
  padding: 7px 9px;
  border: 1px solid #6b2d22;
  background: rgba(120, 40, 28, 0.16);
  color: #d97a63;
  font-size: 10px;
  line-height: 1.5;
  letter-spacing: 0.1em;
}

.xplogin__ref {
  margin-top: 12px;
  padding-top: 9px;
  border-top: 1px solid #26332c;
  font-size: 9.5px;
  letter-spacing: 0.1em;
  color: #5e6b58;
}

/* ---- the snippet --------------------------------------------------------
   A Polaroid, which is a new shape for the shelf: the others are objects, this
   one is a photograph of one. The frame is built here and the photograph drops
   into .polaroid__img when it exists; until then it is the blank white square a
   Polaroid shows before it develops. */
.polaroid {
  width: 176px;
  margin: 0 0 12px;
  padding: 9px 9px 34px;
  background: linear-gradient(180deg, #f6f3e7, #e6e1cf);
  box-shadow: 0 10px 20px -10px rgba(0, 0, 0, 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.7);
  transform: rotate(-1.6deg);
}

.polaroid__img {
  aspect-ratio: 1 / 1;
  /* Longhands. The shorthand resets background-image, and doing this the lazy
     way has already wiped a picture on this sheet once. */
  background-color: #fdfdf8;
  background-image: url("assets/img/platform.webp");
  background-size: cover;
  background-position: center;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12), inset 0 2px 10px rgba(0, 0, 0, 0.16);
}

/* A rule between groups in the machine's menu, cut short of the edges the way
   a period menu draws it. */
.xpctx__sep {
  display: block;
  height: 1px;
  margin: 3px 7px;
  
  background: linear-gradient(90deg, #9a9584, #c9c4b2);
}

/* ---- cursors -------------------------------------------------------------
   The machine gets the period pointer, drawn rather than borrowed: a hard
   two-tone arrow with no antialiasing to it. Hotspots are set to the actual
   tip and the actual centre, so clicks land where the drawing points.

   The room gets something else entirely. Out there you are not driving a
   mouse, you are a person looking at a dead screen, so the pointer stops being
   an arrow and becomes a soft ring: attention rather than control. */
html.is-xp .xp,
html.is-xp .xpwin,
html.is-xp .xp *,
html.is-xp .xpwin * {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='19'%3E%3Cpath d='M1 1v15l3.4-3.4 2.3 4.9 2.2-1-2.2-4.7H11z' fill='%23fff' stroke='%23000' stroke-width='1.2' stroke-linejoin='miter'/%3E%3C/svg%3E") 1 1, default;
}

/* Anything you can act on gets the pointing hand. */
html.is-xp .xp__icon,
html.is-xp .xp__task,
html.is-xp .xp__start,
html.is-xp .xpwin__btn,
html.is-xp .xptab,
html.is-xp .xptab__x,
html.is-xp .xpmenu__label,
html.is-xp .xpmenu__row,
html.is-xp .xpctx__row,
html.is-xp .xpstartmenu__row,
html.is-xp .xpfiles__row,
html.is-xp .xplogin__go,
html.is-xp .xpbrowser__page a,
html.is-xp .xpbrowser__page .entry {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='19'%3E%3Cpath d='M5 1v8l-1.6.7L2 13l2 5h9l1.5-6.5V8h-2V7h-2V6H8V1z' fill='%23fff' stroke='%23000' stroke-width='1.2' stroke-linejoin='round'/%3E%3C/svg%3E") 5 1, pointer;
}

html.is-xp .xplogin__row input,
html.is-xp .xpbrowser__addr input {
  cursor: text;
}

/* The window edges keep the system arrows, because those read as resize
   affordances more clearly than anything drawn here would. */
html.is-xp .xpgrip--e { cursor: ew-resize; }
html.is-xp .xpgrip--s { cursor: ns-resize; }
html.is-xp .xpgrip--se { cursor: nwse-resize; }

/* ---- out in the room ----------------------------------------------------- */
.xproom,
.xproom * {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22'%3E%3Ccircle cx='11' cy='11' r='7.5' fill='none' stroke='%23c9d6bd' stroke-width='1.1' opacity='.55'/%3E%3Ccircle cx='11' cy='11' r='1.6' fill='%23e6efdd' opacity='.8'/%3E%3C/svg%3E") 11 11, default;
}

/* Over the power button the ring closes up, the only thing in the room that
   answers to you. */
.xproom .xpmon__power,
.xproom .xpmon__power * {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22'%3E%3Ccircle cx='11' cy='11' r='8.5' fill='none' stroke='%23a9c092' stroke-width='1.6'/%3E%3Ccircle cx='11' cy='11' r='3' fill='%23a9c092'/%3E%3C/svg%3E") 11 11, pointer;
}

/* THE house rule, hit again: a CSS display always beats the hidden attribute,
   and .xpwin sets display: flex. Minimise and close were setting hidden and
   the window stayed exactly where it was. */
.xpwin[hidden] {
  display: none !important;
}

/* Only the label highlights, not the whole menu wrapper. The old rule matched
   every span in the bar, so hovering lit the lot as one block. */
.xpbrowser__menu > span:hover {
  background: none;
  color: inherit;
}

/* Nothing on the desktop resizes except the browser. */
.xpwin:not([data-win="browser"]) .xpgrip {
  display: none;
}

/* The refusal page. Deliberately looks like the machine's own error, not the
   site's. */
.xpblock {
  padding: 46px 24px;
  text-align: center;
  background: #10160f;
  color: #9fba8b;
  min-height: 100%;
}

.xpblock__code {
  font-size: 44px;
  letter-spacing: 0.1em;
  color: #c0553f;
}

.xpblock__line {
  max-width: 40ch;
  margin: 14px auto 0;
  font-size: 12px;
  line-height: 1.6;
}

.xpblock__url {
  margin-top: 16px;
  font-family: "Lucida Console", "Courier New", monospace;
  font-size: 11px;
  color: #5e6b58;
  word-break: break-all;
}

/* ---- retro scrollbars, machine only -------------------------------------
   Scoped under html.is-xp so the paper site keeps the hairline bar it has
   everywhere else. Square, stepped, with hard bevels and arrow buttons drawn
   as data URIs: the period look is the bevel, not the colour. */
html.is-xp ::-webkit-scrollbar {
  width: 16px;
  height: 16px;
}

html.is-xp ::-webkit-scrollbar-track {
  background-color: #cfcab8;
  background-image:
    repeating-conic-gradient(#c3bfae 0 25%, #d8d4c4 0 50%);
  background-size: 2px 2px;
  border: 0;
}

html.is-xp ::-webkit-scrollbar-thumb {
  min-height: 24px;
  border: 0;
  border-radius: 0;
  background: #d8d4c4;
  box-shadow:
    inset 1px 1px 0 #f2efe2,
    inset -1px -1px 0 #6f6a5c,
    inset 2px 2px 0 #e6e2d3,
    inset -2px -2px 0 #a29d8d;
  background-image: none;
}

html.is-xp ::-webkit-scrollbar-thumb:hover {
  background: #e0dccd;
}

html.is-xp ::-webkit-scrollbar-thumb:active {
  box-shadow:
    inset 1px 1px 0 #6f6a5c,
    inset -1px -1px 0 #f2efe2;
}

/* Stepper buttons at both ends, the giveaway detail a modern bar does not have. */
html.is-xp ::-webkit-scrollbar-button:single-button {
  display: block;
  height: 16px;
  width: 16px;
  background-color: #d8d4c4;
  background-repeat: no-repeat;
  background-position: center;
  box-shadow: inset 1px 1px 0 #f2efe2, inset -1px -1px 0 #6f6a5c;
}

html.is-xp ::-webkit-scrollbar-button:single-button:vertical:decrement {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='6'%3E%3Cpath d='M4 1l3 4H1z' fill='%23342f26'/%3E%3C/svg%3E");
}

html.is-xp ::-webkit-scrollbar-button:single-button:vertical:increment {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='6'%3E%3Cpath d='M4 5L1 1h6z' fill='%23342f26'/%3E%3C/svg%3E");
}

html.is-xp ::-webkit-scrollbar-button:single-button:horizontal:decrement {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='8'%3E%3Cpath d='M1 4l4-3v6z' fill='%23342f26'/%3E%3C/svg%3E");
}

html.is-xp ::-webkit-scrollbar-button:single-button:horizontal:increment {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='8'%3E%3Cpath d='M5 4L1 7V1z' fill='%23342f26'/%3E%3C/svg%3E");
}

html.is-xp ::-webkit-scrollbar-corner {
  background: #cfcab8;
}

/* Firefox has no stepper buttons to give, so it gets the colours only. */
@supports not selector(::-webkit-scrollbar) {
  html.is-xp * {
    scrollbar-width: auto;
    scrollbar-color: #d8d4c4 #cfcab8;
  }
}

/* Selected icon, the dotted marquee a desktop draws around it. */
.xp__icon.is-picked {
  border-color: rgba(255, 255, 255, 0.7);
  background: rgba(127, 156, 107, 0.3);
}

/* Once an icon has been dragged the shelf stops laying them out and lets each
   one keep the position it was left in. */
.xp__icons.is-loose {
  position: static;
  display: block;
}

.xp__icons.is-loose .xp__icon {
  position: absolute;
}

/* The refusal page fills the pane and looks like the machine, not the web. */
.xpblock {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 100%;
  padding: 30px 24px;
  background: #d8d4c4;
  color: #241f18;
  font-family: Tahoma, "MS Sans Serif", sans-serif;
  -webkit-font-smoothing: none;
}

.xpblock__code {
  order: 2;
  margin-top: 14px;
  font-size: 11px;
  letter-spacing: 0.18em;
  color: #7b3323;
}

.xpblock__line {
  order: 1;
  max-width: 44ch;
  padding: 14px 18px;
  border: 1px solid #7d8878;
  background: #ece9d8;
  box-shadow: inset 1px 1px 0 #fff, inset -1px -1px 0 #9a9584;
  font-size: 12px;
  line-height: 1.6;
  text-align: center;
}

.xpblock__url {
  order: 3;
  margin-top: 10px;
  font-family: "Lucida Console", "Courier New", monospace;
  font-size: 11px;
  color: #6b6250;
  word-break: break-all;
}

/* Options that exist and refuse. */
.xpstartmenu__row.is-dead {
  color: #6f7d68;
}

.xpstartmenu__row.is-dead:hover {
  background: #2a352c;
  color: #8a9a80;
}

/* The signed-in line will not hold still. Two offset copies in the channel
   colours, nudged on a stutter, which is cheaper and nastier than a filter. */
.glitch {
  position: relative;
  display: inline-block;
}

.glitch::before,
.glitch::after {
  content: attr(data-t);
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  overflow: hidden;
  pointer-events: none;
}

.glitch::before {
  color: #7fd8c4;
  animation: glitchA 3.7s steps(1) infinite;
}

.glitch::after {
  color: #d8607f;
  animation: glitchB 4.3s steps(1) infinite;
}

/* Both open on zero offset, so a paused animation shows clean text rather than
   a permanently broken line. */
@keyframes glitchA {
  0%, 88%, 100% { transform: none; opacity: 0; }
  90% { transform: translate(-2px, -1px); opacity: 0.8; }
  93% { transform: translate(1px, 1px); opacity: 0.6; }
}

@keyframes glitchB {
  0%, 82%, 100% { transform: none; opacity: 0; }
  84% { transform: translate(2px, 1px); opacity: 0.75; }
  87% { transform: translate(-1px, 0); opacity: 0.5; }
}

/* ---- the recordings ------------------------------------------------------
   Every tape opens and every tape is empty. The eye is the only thing in the
   frame, breathing slightly so the window never looks like a still image. */
.xptape {
  margin: -8px;
}

.xptape__screen {
  aspect-ratio: 4 / 3;
  display: grid;
  place-content: center;
  gap: 14px;
  justify-items: center;
  background:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.035) 0 1px, transparent 1px 3px),
    radial-gradient(ellipse 70% 60% at 50% 45%, #12180f, #050704 75%);
  color: #5f7a4e;
}

.xptape__eye {
  width: 92px;
  height: 58px;
  animation: tapeBreathe 5.5s ease-in-out infinite;
}

/* Opens at full opacity so a paused animation still shows the eye. */
@keyframes tapeBreathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

.xptape__msg {
  font-family: Tahoma, "MS Sans Serif", sans-serif;
  font-size: 11px;
  letter-spacing: 0.24em;
  text-align: center;
  line-height: 1.9;
  white-space: pre-line;
  -webkit-font-smoothing: none;
}

.xptape__bar {
  display: flex;
  justify-content: space-between;
  padding: 4px 8px;
  background: #d8d4c4;
  border-top: 1px solid #7d8878;
  font-size: 10px;
  color: #4a4a42;
}

/* The bin lights up while something is held over it, then refuses it. */
.xp__icon.is-target {
  border-color: rgba(201, 162, 79, 0.9);
  background: rgba(201, 162, 79, 0.22);
}

/* The walk back. Transition rather than animation, so it eases from wherever
   the icon happened to be dropped rather than from a fixed keyframe. */
.xp__icon.is-refused {
  transition: left 0.36s cubic-bezier(0.33, 1, 0.68, 1), top 0.36s cubic-bezier(0.33, 1, 0.68, 1);
}

@media (prefers-reduced-motion: reduce) {
  .xp__icon.is-refused {
    transition: none;
  }
}

/* ---- the dark camera ----------------------------------------------------
   Black, not empty. Animated static, a sync roll crawling up the frame, and an
   error line that keeps rewriting itself. Nothing is ever visible in it, which
   is the point: the feed is live and shows you nothing. */
.xptape--dark .xptape__screen {
  position: relative;
  overflow: hidden;
  background: #000;
  color: #7a8a72;
}

/* Static, from a single tiled turbulence so it costs no request. The tile is
   nudged around rather than regenerated, which is what sells it as noise. */
.xptape__snow {
  position: absolute;
  inset: -20%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  opacity: 0.24;
  animation: snowShift 0.24s steps(3) infinite;
}

@keyframes snowShift {
  0% { transform: translate(0, 0); }
  33% { transform: translate(-9px, 6px); }
  66% { transform: translate(7px, -8px); }
  100% { transform: translate(-4px, -3px); }
}

/* The sync bar an untuned tape drags up the picture. */
.xptape__roll {
  position: absolute;
  left: 0;
  right: 0;
  height: 22%;
  background: linear-gradient(180deg, transparent, rgba(255, 255, 255, 0.07) 45%, transparent);
  animation: rollUp 6.5s linear infinite;
}

@keyframes rollUp {
  0% { top: 100%; }
  100% { top: -24%; }
}

.xptape__err {
  position: relative;
  z-index: 2;
  align-self: center;
  justify-self: center;
  font-family: Tahoma, "MS Sans Serif", sans-serif;
  font-size: 11px;
  letter-spacing: 0.28em;
  color: #8c9a84;
  text-shadow: 0 0 8px rgba(0, 0, 0, 0.9);
  animation: errFlicker 3.1s steps(1) infinite;
  -webkit-font-smoothing: none;
}

/* Opens visible, so a paused animation never leaves the line blank. */
@keyframes errFlicker {
  0%, 62%, 100% { opacity: 1; }
  66% { opacity: 0.25; }
  70% { opacity: 1; }
  88% { opacity: 0.4; }
}

@keyframes recBlink {
  0%, 55%, 100% { opacity: 1; }
  60%, 95% { opacity: 0.25; }
}

@media (prefers-reduced-motion: reduce) {
  .xptape__snow,
  .xptape__roll,
  .xptape__err,
  .xptape__rec {
    animation: none;
  }
}

/* The legacy rule from the first pass, `.xpbrowser__menu span:hover`, matches
   every descendant span. The dropdown is a span and so is every row inside it,
   so hovering a single row also painted the container behind all of them.
   Only the label and the individual row may ever highlight. */
.xpbrowser__menu .xpmenu:hover,
.xpbrowser__menu .xpmenu__drop:hover,
.xpbrowser__menu .xpmenu__drop {
  background: #ded9c8;
  color: #241f18;
}

.xpbrowser__menu .xpmenu:hover {
  background: none;
}

.xpbrowser__menu .xpmenu__label:hover,
.xpmenu.is-open .xpmenu__label {
  background: #3d5142;
  color: #eef2e9;
}

.xpbrowser__menu .xpmenu__row:hover {
  background: #3d5142;
  color: #eef2e9;
}

/* The browser's own menu: tighter than the desktop's and harder edged, so the
   two never read as the same object. */
.xpctx--browser {
  min-width: 164px;
  font-size: 10.5px;
}

.xpctx--browser .xpctx__row {
  padding: 4px 10px;
}

/* The photo sits in the far corner on its own, away from the work icons. */
.xp__corner {
  position: absolute;
  right: 14px;
  bottom: 14px;
  z-index: 1;
}

.xp__corner .xp__icon {
  width: 92px;
}

.xpphoto {
  padding: 4px;
}

/* The picture drops in here as a background. Until then it is the grey a photo
   viewer shows while it decides whether the file is really there. */
.xpphoto__frame {
  aspect-ratio: 4 / 3;
  /* Longhands, not the shorthand. background: resets background-image, and a
     later shorthand here has silently wiped the picture before. */
  background-color: #1a1d18;
  background-image: url("assets/img/birthday.webp");
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  border: 1px solid #3c4b41;
  box-shadow: inset 0 0 24px rgba(0, 0, 0, 0.7);
}

/* Files in the bin. Greyed, with the reason sitting on the row rather than
   hidden behind a click, because the refusal is the content. */
.xpfiles__row.is-gone {
  color: #6b7a64;
  cursor: pointer;
}

.xpfiles__row.is-gone:hover {
  background: #2d4030;
  color: #9fba8b;
}

/* ---- the case document --------------------------------------------------- */
.xpdoc {
  margin: -8px;
  background: #6e6a5c;
  padding: 12px;

  /* A container, so the page below can ask how wide it actually is. The window
     is resizable by drag, so a viewport media query would be answering the
     wrong question. */
  container-type: inline-size;
  container-name: doc;
}

.xpdoc__page {
  max-width: none;
  margin: 0 auto;
  padding: 44px 46px 56px;
  background: #f4f1e6;
  color: #241f18;
  font-family: "Lucida Console", "Courier New", monospace;
  font-size: 14px;
  line-height: 2;

  /* pre-line, not pre-wrap. Both keep the author's newlines, but pre-wrap also
     keeps the space a line was broken at, and renders it: every justified line
     ended with one monospace character hanging past the right margin, and a
     redaction that happened to end on a space painted a black stub out there.

     pre-line collapses those instead, so the lines land flush. Safe here
     because the case file uses single spaces throughout; nothing in it is
     aligned by padding with runs of spaces. */
  white-space: pre-line;
  box-shadow: 0 10px 26px -14px rgba(0, 0, 0, 0.7);

  /* Justified, because a typed dossier has a flush right edge.

     hyphens stays none: no word is ever broken across a line. The document is
     monospace, so a hyphen inserted mid-word reads as a typo rather than as
     typesetting.

     break-word is the guard that keeps the text inside the page. It only acts
     on something that cannot fit a line on its own, which here means a long
     redaction; ordinary prose never triggers it. pre-wrap keeps the author's
     own line breaks, so headers and the signature block stay ragged and only
     the paragraphs justify. */
  text-align: justify;
  text-align-last: left;
  hyphens: none;
  -webkit-hyphens: none;
  overflow-wrap: break-word;
}

/* Justification needs room. With no hyphenation the only way to fill a line is
   to stretch the spaces, and in a monospace face every stretched space is a
   whole character wide, so the damage shows immediately.

   Measured on this document: at 966px of text width no line ends up stretched
   across three words or fewer, at 506px four lines do, and at 266px it is
   eighty-eight. Narrow enough and it stops reading as typesetting and starts
   reading as a bug, which is what dragging the window small used to produce.
   
   So below roughly 600px of column the page goes ragged right, which is what a
   narrow measure wants anyway. */
@container doc (max-width: 620px) {
  .xpdoc__page {
    text-align: left;
  }
}

/* Digital redaction: a solid bar with real characters underneath it, so
   selecting one gives you letters rather than nothing.

   It has to be able to wrap. A redaction long enough to outrun the line is
   exactly what a censored dossier looks like, and forcing it onto one line
   either pushes it past the page edge or bumps it whole to the next line,
   leaving three stretched words behind it on the one before.

   So it stays inline and breaks: at the spaces the generator already puts in
   the gibberish, and anywhere at all if a run has none. box-decoration-break
   clone is what makes that read correctly, giving each line its own bar with
   its own padding and rounded ends, rather than one shape smeared across the
   line break. */
.ink {
  background: #14110c;
  color: #14110c;

  /* No horizontal padding. It was 2px, and on a justified line the bar ends
     flush with the margin, so those 2px were the one thing still sticking out
     past it. The weight moved to the vertical instead, which the line box has
     room for at line-height 2 and which cannot affect the right edge. */
  padding: 3px 0;
  border-radius: 1px;
  user-select: text;
  overflow-wrap: anywhere;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

.ink::selection {
  background: #14110c;
  color: #3a3226;
}

.xpdoc__end {
  margin-top: 40px;
  padding-top: 26px;
  border-top: 1px solid #c3bfae;
  display: flex;
  justify-content: center;
}

/* The operator name sits in the middle of the status bar, where a browser puts
   the thing you never read. */
.xpbrowser__who {
  flex: 1;
  text-align: center;
  color: #6b6250;
  letter-spacing: 0.04em;
}

/* ---- fetching -----------------------------------------------------------
   The wait between the password and the file. Three dots on a stagger, which
   is enough to say the machine is slow without a spinner, which would be the
   wrong decade. */
.xpwait {
  min-height: 130px;
  display: grid;
  place-items: center;
  background: #10160f;
  border: 1px solid #3c4b41;
  color: #9fba8b;
}

.xpwait__msg {
  font-family: "Lucida Console", "Courier New", monospace;
  font-size: 12px;
  letter-spacing: 0.14em;
}

.xpwait__dots i {
  display: inline-block;
  width: 4px;
  height: 4px;
  margin-left: 3px;
  border-radius: 50%;
  background: #7f9c6b;
  animation: waitDot 1.2s steps(1) infinite;
}

.xpwait__dots i:nth-child(2) { animation-delay: 0.2s; }
.xpwait__dots i:nth-child(3) { animation-delay: 0.4s; }

/* Opens visible, so a paused animation leaves three dots rather than none. */
@keyframes waitDot {
  0%, 60%, 100% { opacity: 1; }
  70%, 95% { opacity: 0.2; }
}

/* ---- system properties --------------------------------------------------- */
.xpprops {
  background: #ece9d8;
  color: #241f18;
  font-family: Tahoma, "MS Sans Serif", sans-serif;
  -webkit-font-smoothing: none;
}

.xpprops__head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  background: linear-gradient(180deg, #fff, #dcd8c6);
  border-bottom: 1px solid #9a9584;
}

.xpprops__os {
  font-size: 14px;
  font-weight: 700;
}

.xpprops__sub {
  margin-top: 3px;
  font-size: 11px;
  color: #5b5546;
}

.xpprops__list {
  display: grid;
  grid-template-columns: 128px 1fr;
  gap: 5px 12px;
  margin: 0;
  padding: 14px 16px;
  font-size: 11.5px;
}

.xpprops__list dt {
  color: #5b5546;
}

.xpprops__list dd {
  margin: 0;
  font-weight: 700;
}

.xpprops__foot {
  padding: 10px 16px 14px;
  border-top: 1px solid #c3bfae;
  font-size: 11px;
  color: #7b3323;
}

/* ---- start menu, the two-column shape ------------------------------------
   A banner across the top with the account on it, the list under it, and the
   power row on its own darker strip at the bottom. That silhouette is what
   makes it read as the period rather than as a dropdown. */
.xpstartmenu {
  width: 238px;
  padding: 0;
  border: 1px solid #1941a5;
  border-radius: 6px 6px 0 0;
  overflow: hidden;
}

.xpstartmenu__head {
  margin: 0;
  padding: 11px 12px;
  background: linear-gradient(180deg, #2f6fc4 0 12%, #1c4f9c 16% 84%, #143d7d 100%);
  color: #fff;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: none;
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5);
  border-bottom: 2px solid #e8a33d;
}

.xpstartmenu__row {
  padding: 8px 12px;
  background: #f3f2ea;
  color: #241f18;
  border-bottom: 1px solid #e4e1d4;
}

.xpstartmenu__row:hover {
  background: #316ac5;
  color: #fff;
}

/* The power strip sits apart, the way it does on a real one. */
.xpstartmenu__sep {
  height: 0;
  margin: 0;
  background: none;
}

.xpstartmenu__row.is-dead {
  background: linear-gradient(180deg, #d8e2f2, #c3d1e8);
  color: #5b6577;
  border-bottom: 1px solid #b3c1da;
}

.xpstartmenu__row.is-dead:hover {
  background: linear-gradient(180deg, #c9d7ee, #b2c2de);
  color: #48505f;
}

/* ---- the cursors that were still the system's ---------------------------- */
html.is-xp .xpgrip--e {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='23' height='13'%3E%3Cpath d='M6 3L1 6.5 6 10V7.5h11V10l5-3.5L17 3v2.5H6z' fill='%23fff' stroke='%23000' stroke-width='1.1' stroke-linejoin='round'/%3E%3C/svg%3E") 11 6, ew-resize;
}

html.is-xp .xpgrip--s {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='23'%3E%3Cpath d='M3 6L6.5 1 10 6H7.5v11H10l-3.5 5L3 17h2.5V6z' fill='%23fff' stroke='%23000' stroke-width='1.1' stroke-linejoin='round'/%3E%3C/svg%3E") 6 11, ns-resize;
}

html.is-xp .xpgrip--se {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='19' height='19'%3E%3Cpath d='M3 8l5-5v3h5v5h3l-5 5v-3H6V8z' fill='%23fff' stroke='%23000' stroke-width='1.1' stroke-linejoin='round'/%3E%3C/svg%3E") 9 9, nwse-resize;
}

/* The I-beam, drawn rather than borrowed so it matches the rest. */
html.is-xp .xplogin__row input,
html.is-xp .xpbrowser__addr input,
html.is-xp .xpdoc__page,
html.is-xp .xptext {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='19'%3E%3Cpath d='M2 1h5M2 18h5M4.5 1v17' stroke='%23000' stroke-width='2.4' fill='none'/%3E%3Cpath d='M2 1h5M2 18h5M4.5 1v17' stroke='%23fff' stroke-width='1' fill='none'/%3E%3C/svg%3E") 4 9, text;
}

/* Busy, for the moment the file is being fetched. */
html.is-xp .xpwait,
html.is-xp .xpwait * {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='24'%3E%3Cpath d='M3 2h12v5l-6 5 6 5v5H3v-5l6-5-6-5z' fill='%23fff' stroke='%23000' stroke-width='1.3' stroke-linejoin='round'/%3E%3C/svg%3E") 9 12, progress;
}

/* ---- snippet recovered --------------------------------------------------
   The studio's own notice, not the machine's. Green, and deliberately outside
   the terminal's visual language so it reads as the site stepping forward. */
.snipnote {
  position: fixed;
  left: 50%;
  bottom: 54px;
  z-index: 9700;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 22px;
  border: 1px solid #7fbf5a;
  border-radius: 10px;
  background: linear-gradient(180deg, #2f5c26, #1d3f18);
  color: #e6f5db;
  font-family: var(--font-type);
  font-size: 12px;
  letter-spacing: 0.08em;
  box-shadow: 0 18px 34px -18px rgba(0, 0, 0, 0.85), inset 0 1px 0 rgba(255, 255, 255, 0.18);
  opacity: 0;
  transform: translate(-50%, 16px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}

.snipnote.is-up {
  opacity: 1;
  transform: translate(-50%, 0);
}

.snipnote__mark {
  font-size: 15px;
  color: #a8dd85;
}

/* The photograph stands alone: no caption, no explanation, just the print on
   the brown of the panel it sits in. */
.xpfound {
  padding: 18px 12px 20px;
}

.xpfound .polaroid {
  margin: 0 auto;
}

/* The error line stays out of the way until the camera has had time to say
   nothing for a while. */
.xptape__err.is-late {
  opacity: 0;
  animation: none;
}


/* ---- options panel -------------------------------------------------------
   Identical on legal, blog and socials, deliberately. Every colour and size is
   literal rather than a var(), because this block used to inherit each site's
   palette and so rendered a different colour and a different height on each of
   them. A settings dialog belongs to the studio, not to the page behind it.

   If you restyle it, restyle it in all three or it drifts again. */
.opt {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: grid;
  place-items: center;
  font-family: inherit;
}

.opt[hidden] {
  display: none;
}

.opt__scrim {
  position: absolute;
  inset: 0;
  background: rgba(20, 16, 10, 0.52);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

.opt__panel {
  position: relative;
  width: min(92vw, 360px);
  box-sizing: border-box;
  padding: 22px 22px 18px;
  border-radius: 6px;
  background: #f7efd9;
  border: 1px solid rgba(120, 96, 54, 0.16);
  box-shadow: 0 26px 60px -30px rgba(20, 16, 10, 0.8);
  color: #1c1a16;
}

.opt__head {
  margin: 0 0 16px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #1c1a16;
}

.opts {
  margin: 0;
  padding: 0;
  list-style: none;
}

.opt-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  min-height: 38px;
  padding: 7px 0;
  border-bottom: 1px solid rgba(120, 96, 54, 0.14);
}

.opt-row:last-child {
  border-bottom: 0;
}

.opt__text {
  min-width: 0;
}

.opt__name {
  font-size: 13.5px;
  color: #1c1a16;
}

.opt__ctl {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

/* the switch */
.tickbox {
  position: relative;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  flex: none;
}

.tickbox__box {
  position: absolute;
  inset: 0;
  border-radius: 4px;
  border: 1px solid rgba(28, 26, 22, 0.4);
  background: rgba(255, 253, 244, 0.7);
  transition: border-color 0.2s ease, background 0.2s ease;
}

.tickbox__tick {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 15px;
  line-height: 1;
  color: #456628;
  opacity: 0;
  transform: scale(0.7);
  transition: opacity 0.18s ease, transform 0.18s ease;
}

.tickbox[aria-checked="true"] .tickbox__tick {
  opacity: 1;
  transform: none;
}

.tickbox[aria-checked="true"] .tickbox__box {
  border-color: #5f8a3a;
  background: rgba(95, 138, 58, 0.14);
}

.tickbox:hover .tickbox__box {
  border-color: rgba(28, 26, 22, 0.7);
}

.tickbox:focus-visible {
  outline: 2px solid #5f8a3a;
  outline-offset: 3px;
  border-radius: 5px;
}

/* the volume dial */
.dial {
  -webkit-appearance: none;
  appearance: none;
  width: 116px;
  height: 20px;
  flex: none;
  background: none;
  cursor: pointer;
}

.dial::-webkit-slider-runnable-track {
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(90deg, #a8842f, rgba(120, 96, 54, 0.24));
}

.dial::-moz-range-track {
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(90deg, #a8842f, rgba(120, 96, 54, 0.24));
}

.dial::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  margin-top: -6px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #e3c07a, #a8842f);
  border: 1px solid rgba(28, 26, 22, 0.35);
}

.dial::-moz-range-thumb {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #e3c07a, #a8842f);
  border: 1px solid rgba(28, 26, 22, 0.35);
}

.dial:focus-visible {
  outline: 2px solid #5f8a3a;
  outline-offset: 4px;
}

.dial__val {
  min-width: 2.6ch;
  font-size: 11.5px;
  color: rgba(28, 26, 22, 0.62);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.opt__foot {
  margin: 14px 0 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: rgba(28, 26, 22, 0.62);
}

.opt__credit {
  margin: 10px 0 0;
  font-size: 11.5px;
  color: rgba(28, 26, 22, 0.42);
}

.opt__close {
  margin-top: 16px;
  width: 100%;
  padding: 9px 12px;
  border-radius: 4px;
  border: 1px solid rgba(28, 26, 22, 0.4);
  background: rgba(255, 253, 244, 0.6);
  color: #1c1a16;
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}

.opt__close:hover {
  background: rgba(95, 138, 58, 0.12);
  border-color: #5f8a3a;
}

.opt__close:focus-visible {
  outline: 2px solid #5f8a3a;
  outline-offset: 2px;
}




/* ---- now playing ---------------------------------------------------------
   The card that slides in bottom-right when a track starts, matching hub's.
   pointer-events: none throughout - it is an announcement, not a control, and
   it must never sit between the reader and a link underneath it. */
.nowplaying {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 48;
  display: flex;
  align-items: center;
  gap: 11px;
  max-width: min(78vw, 320px);
  padding: 9px 15px 9px 12px;
  border-radius: 12px;
  pointer-events: none;
  background: var(--paper-0);
  border: 1.6px solid var(--edge);
  box-shadow: 0 12px 26px -16px rgba(20, 14, 4, 0.7);
  opacity: 0;
  transform: translateX(-42px) rotate(0.4deg);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.nowplaying.is-on {
  opacity: 1;
  transform: translateX(0) rotate(0.4deg);
}
.nowplaying.is-out {
  opacity: 0;
  transform: translateX(28px) rotate(0.4deg);
}
.nowplaying__eq {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  width: 22px;
  height: 18px;
  flex: none;
}
.nowplaying__eq i {
  flex: 1;
  background: var(--accent);
  border-radius: 1px;
  height: 30%;
  transition: height 0.06s linear;
}
.nowplaying__meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.2;
  gap: 1px;
}
.nowplaying__top {
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
}
.nowplaying__kicker {
  font-family: var(--font-type);
  font-size: 8.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  flex: none;
}
.nowplaying__source {
  font-family: var(--font-type);
  font-size: 8.5px;
  letter-spacing: 0.06em;
  color: var(--ink-mute);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nowplaying__title {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .nowplaying { transition: opacity 0.2s linear; transform: none; }
  .nowplaying.is-on, .nowplaying.is-out { transform: none; }
  .nowplaying__eq i { transition: none; }
}
@media (max-width: 620px) {
  .nowplaying { right: 12px; bottom: 12px; max-width: min(86vw, 280px); }
}
