/* =============================================================================
   ANDREW CAYLOR — ADVENTURER'S RECORD
   A portfolio drawn as a physical tabletop character sheet.

   The conceit: a printed form lying on a dark desk. Everything the *printer*
   put on the page is sepia ink — hairline rules, boxed fields, tiny letter-
   spaced caps. Everything the *player* filled in afterwards is blue ballpoint
   in a hurried hand. Approvals and awards are red rubber stamp.

   Three ink layers, never mixed:
     .ink   printed form furniture   -> --ink / --rule
     .hand  filled in by the player  -> --pen   (Caveat, slight tilt)
     .stamp official / earned        -> --stamp (multiply blend)

   No JavaScript. No build step. One stylesheet.
   ========================================================================== */

/* =============================================================================
   1. TOKENS
   ========================================================================== */

:root {
  /* -- Surfaces ------------------------------------------------------------ */
  --desk: #17130f;
  --desk-lift: #2a221a;
  --paper: #f2e8d4;
  --paper-hi: #fbf6e8;
  --paper-shade: #e9dcc0;
  --paper-deep: #dccfae;

  /* -- Inks ---------------------------------------------------------------- */
  --ink: #241f17;
  --ink-soft: #5c5040;
  --ink-faint: #8a7b62;
  --rule: #c0af8d;
  --rule-soft: #d8cbac;
  --rule-strong: #6d5f47;

  --pen: #26406f;
  --pen-soft: #43608f;

  --stamp: #96301f;
  --stamp-soft: #bd5540;
  --gold: #a07c39;

  /* -- Type ---------------------------------------------------------------- */
  --face-display: "IM Fell English SC", "Cormorant Garamond", Georgia, serif;
  --face-form: "Alegreya Sans SC", "Trebuchet MS", sans-serif;
  --face-body: "Alegreya", Georgia, "Times New Roman", serif;
  --face-hand: "Caveat", "Segoe Script", cursive;

  /* -- Rhythm -------------------------------------------------------------- */
  --gap: 22px;
  --sheet-pad-y: 46px;
  --sheet-pad-x: 52px;
  --margin-rule: 30px; /* distance of the red margin rule from the paper edge */

  /* -- Depth --------------------------------------------------------------- */
  --lift-1: 0 1px 2px rgba(35, 25, 10, 0.14), 0 2px 6px rgba(35, 25, 10, 0.08);
  --lift-2: 0 2px 4px rgba(35, 25, 10, 0.18), 0 8px 20px rgba(35, 25, 10, 0.14);
  --sheet-lift:
    0 2px 4px rgba(0, 0, 0, 0.4), 0 18px 34px rgba(0, 0, 0, 0.42),
    0 44px 90px rgba(0, 0, 0, 0.4);

  /* -- Textures ------------------------------------------------------------ */
  /* Paper fibre — fine, close-woven. */
  --fiber: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23f)' opacity='0.055'/%3E%3C/svg%3E");
  /* Desk grain — film grain over the dark wood, not cloud blotches. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='d'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23d)' opacity='0.22'/%3E%3C/svg%3E");
  /* Coarse mottle — used only to bite holes in the rubber stamp. */
  --grit: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.06' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)' opacity='0.6'/%3E%3C/svg%3E");
}

/* Candlelit variant: the desk goes darker and the paper cools a shade rather
   than inverting — a character sheet is paper at every hour of the night. */
@media (prefers-color-scheme: dark) {
  :root {
    --desk: #0c0a08;
    --desk-lift: #1c1712;
    --paper: #e4d8c0;
    --paper-hi: #efe5ce;
    --paper-shade: #d9cbaf;
    --paper-deep: #cbbb9a;
    --ink: #1f1b14;
    --rule: #b3a17f;
    --pen: #223a66;
    --sheet-lift:
      0 2px 4px rgba(0, 0, 0, 0.6), 0 18px 34px rgba(0, 0, 0, 0.55),
      0 44px 100px rgba(0, 0, 0, 0.5);
  }
}

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

/* =============================================================================
   2. THE DESK
   ========================================================================== */

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  padding: 34px 20px 64px;
  font-family: var(--face-body);
  font-size: 1.075rem;
  line-height: 1.62;
  color: var(--ink);
  background-color: var(--desk);
  background-image: /* warm pool of lamplight above the sheet */
    radial-gradient(
      110% 55% at 50% -6%,
      rgba(198, 150, 82, 0.2),
      transparent 60%
    ),
    /* the table falls away into shadow at the edges */
    radial-gradient(80% 60% at 50% 115%, rgba(0, 0, 0, 0.7), transparent 62%),
    /* dark walnut grain */
    repeating-linear-gradient(
        94deg,
        rgba(255, 255, 255, 0.011) 0 2px,
        transparent 2px 9px,
        rgba(0, 0, 0, 0.035) 9px 11px,
        transparent 11px 21px
      ),
    var(--grain);
  background-attachment: fixed;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 20;
  padding: 10px 18px;
  background: var(--paper-hi);
  color: var(--stamp);
  font-family: var(--face-form);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--rule-strong);
}

.skip-link:focus {
  left: 16px;
  top: 16px;
}

/* =============================================================================
   3. THE SHEET
   ========================================================================== */

.sheet {
  position: relative;
  max-width: 900px;
  margin: 0 auto;
  padding: var(--sheet-pad-y) var(--sheet-pad-x);
  background-color: var(--paper);
  background-image:
    /* the faded red margin rule, drawn once and repeated infinitely down */
    linear-gradient(
      90deg,
      transparent calc(var(--margin-rule) - 1px),
      rgba(150, 48, 31, 0.4) calc(var(--margin-rule) - 1px),
      rgba(150, 48, 31, 0.4) var(--margin-rule),
      transparent var(--margin-rule)
    ),
    /* age blooms */
    radial-gradient(60% 40% at 8% 4%, rgba(255, 252, 240, 0.7), transparent 70%),
    radial-gradient(
      50% 30% at 92% 96%,
      rgba(133, 100, 52, 0.13),
      transparent 70%
    ),
    var(--fiber);
  border: 1px solid rgba(90, 72, 44, 0.5);
  box-shadow:
    inset 0 0 0 1px rgba(255, 251, 240, 0.5),
    inset 0 0 70px rgba(126, 96, 50, 0.16),
    var(--sheet-lift);
}

/* Two more sheets in the stack, peeking out from behind. Negative z-index puts
   them behind the parent's own background, so only their edges show. */
.sheet::before,
.sheet::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--paper-deep);
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.35);
}

.sheet::before {
  transform: rotate(-0.55deg) translate(-5px, 4px);
}

.sheet::after {
  transform: rotate(0.7deg) translate(6px, 7px);
  background: var(--paper-shade);
}

/* -- Staple, top-left ------------------------------------------------------ */
.staple {
  position: absolute;
  top: 18px;
  left: 16px;
  width: 26px;
  height: 9px;
  transform: rotate(-38deg);
  background: linear-gradient(180deg, #cdd0d4, #7e838a 55%, #5b6067);
  border-radius: 1px;
  box-shadow:
    0 1px 1px rgba(0, 0, 0, 0.45),
    0 2px 4px rgba(60, 45, 20, 0.4);
  pointer-events: none;
}

/* -- Decorative paper damage ---------------------------------------------- */
.stain {
  position: absolute;
  pointer-events: none;
  mix-blend-mode: multiply;
  opacity: 0.4;
}

.stain--ring {
  width: 118px;
  height: 110px;
  border-radius: 50%;
  transform: rotate(-12deg);
  background: radial-gradient(
    circle,
    transparent 0 56%,
    rgba(126, 86, 38, 0.3) 57% 63%,
    rgba(126, 86, 38, 0.12) 64% 70%,
    transparent 72%
  );
}

.stain--blot {
  width: 90px;
  height: 70px;
  border-radius: 48% 62% 55% 45% / 58% 44% 60% 42%;
  background: radial-gradient(
    circle at 42% 38%,
    rgba(30, 52, 95, 0.62),
    rgba(30, 52, 95, 0.24) 55%,
    transparent 74%
  );
  filter: blur(0.6px);
}

/* =============================================================================
   4. MASTHEAD — the top block of form fields
   ========================================================================== */

.masthead {
  margin-bottom: 26px;
}

.masthead__form {
  margin: 0 0 18px;
  font-family: var(--face-form);
  font-size: 0.68rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* The name: micro label above a ruled line, name written across it. */
.namefield {
  margin: 0 0 20px;
  padding-bottom: 4px;
  border-bottom: 1.5px solid var(--rule-strong);
  font-weight: 400;
}

.namefield__label {
  display: block;
  font-family: var(--face-form);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.namefield__value {
  display: block;
  font-family: var(--face-hand);
  font-size: clamp(3rem, 9.5vw, 5.2rem);
  font-weight: 700;
  line-height: 0.98;
  color: var(--pen);
  transform: rotate(-0.9deg);
  transform-origin: left bottom;
  mix-blend-mode: multiply;
}

/* The stat line: four small labelled fields on ruled lines. */
.statline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px 26px;
  margin: 0;
}

.statline > div {
  min-width: 0;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 2px;
}

.statline dt {
  font-family: var(--face-form);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.statline dd {
  margin: 0;
  font-family: var(--face-hand);
  font-size: 1.45rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--pen);
  mix-blend-mode: multiply;
}

.statline > div:nth-child(odd) dd {
  transform: rotate(-0.7deg);
}
.statline > div:nth-child(even) dd {
  transform: rotate(0.5deg);
}

/* =============================================================================
   5. TABS — divider tabs clipped to the top of the record
   ========================================================================== */

.tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 5px;
  margin: 0 0 30px;
  padding-left: 10px;
  border-bottom: 1.5px solid var(--rule-strong);
}

.tab {
  position: relative;
  margin-bottom: -1.5px;
  padding: 9px 17px 8px;
  font-family: var(--face-form);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-soft);
  background: linear-gradient(180deg, var(--paper-shade), var(--paper-deep));
  border: 1.5px solid var(--rule-strong);
  border-bottom: none;
  border-radius: 9px 9px 0 0;
  box-shadow: inset 0 1px 0 rgba(255, 250, 238, 0.5);
  transition:
    color 0.2s ease,
    background 0.2s ease,
    transform 0.2s ease;
}

.tab:hover,
.tab:focus-visible {
  color: var(--stamp);
  background: linear-gradient(180deg, var(--paper-hi), var(--paper-shade));
  transform: translateY(-2px);
}

.tab[aria-current="page"] {
  color: var(--stamp);
  background: var(--paper);
  border-bottom: 1.5px solid var(--paper);
  box-shadow: inset 0 2px 0 var(--stamp);
  transform: none;
}

/* A rotated U+2192. The literal ↗ (U+2197) has an emoji presentation that wins
   in most browsers and punches a colour hole in the ink. */
.tab--out::after,
.card--out .card__hint::after {
  content: "→";
  display: inline-block;
  margin-left: 0.45em;
  font-family: var(--face-form);
  transform: rotate(-45deg);
  opacity: 0.7;
}

/* =============================================================================
   6. BLOCKS — a titled region of the form
   ========================================================================== */

.block {
  position: relative;
  margin-bottom: var(--gap);
  padding: 20px 24px 22px;
  background: linear-gradient(
    180deg,
    rgba(255, 252, 242, 0.55),
    rgba(226, 213, 186, 0.35)
  );
  border: 1px solid var(--rule);
  border-radius: 2px;
  box-shadow:
    var(--lift-1),
    inset 0 1px 0 rgba(255, 252, 243, 0.75);
}

.block > :last-child {
  margin-bottom: 0;
}

.block__title {
  display: flex;
  align-items: center;
  gap: 0.7em;
  margin: 0 0 16px;
  padding-bottom: 7px;
  font-family: var(--face-display);
  font-size: clamp(1.2rem, 3vw, 1.5rem);
  font-weight: 400;
  letter-spacing: 0.045em;
  color: var(--ink);
  border-bottom: 3px double var(--rule);
}

/* Section index, hung in the red margin where a clerk would number it. */
.block__no {
  flex: 0 0 auto;
  font-family: var(--face-form);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--stamp);
  padding: 3px 7px 2px;
  border: 1px solid rgba(150, 48, 31, 0.45);
  border-radius: 2px;
}

/* Trailing nib ornament, pushed to the far right of the rule. */
.block__title::after {
  content: "";
  margin-left: auto;
  width: 8px;
  height: 8px;
  background: var(--stamp);
  transform: rotate(45deg);
  box-shadow: 0 0 0 2.5px rgba(150, 48, 31, 0.18);
}

.block h3 {
  margin: 22px 0 4px;
  font-family: var(--face-form);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--stamp);
}

.block h3:first-of-type {
  margin-top: 4px;
}

.block p {
  margin: 0 0 0.95em;
  max-width: 68ch;
}

/* Lead paragraph gets an inked drop cap. */
.lede::first-letter {
  float: left;
  margin: 6px 10px 0 0;
  font-family: var(--face-display);
  font-size: 3.6rem;
  line-height: 0.72;
  color: var(--stamp);
}

/* =============================================================================
   7. INK LAYERS
   ========================================================================== */

.hand {
  font-family: var(--face-hand);
  font-size: 1.32em;
  font-weight: 600;
  line-height: 1.25;
  color: var(--pen);
  mix-blend-mode: multiply;
}

/* Rubber stamp — double ring, tilted, bitten by the paper grain. */
.rubber-stamp {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  padding: 12px 20px;
  color: var(--stamp);
  border: 2.5px solid currentColor;
  border-radius: 4px;
  box-shadow:
    inset 0 0 0 1.5px var(--paper),
    inset 0 0 0 3.5px currentColor;
  transform: rotate(-7deg);
  opacity: 0.9;
  mix-blend-mode: multiply;
  pointer-events: none;
}

/* Ink that didn't take, scattered over the impression. */
.rubber-stamp::after {
  content: "";
  position: absolute;
  inset: -3px;
  background: var(--paper);
  mix-blend-mode: screen;
  opacity: 0.28;
  -webkit-mask-image: var(--grit);
  mask-image: var(--grit);
  -webkit-mask-size: 150px;
  mask-size: 150px;
}

.rubber-stamp b {
  font-family: var(--face-display);
  font-size: 1.15rem;
  letter-spacing: 0.1em;
  line-height: 1;
}

.rubber-stamp small {
  font-family: var(--face-form);
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.28em;
  text-transform: uppercase;
}

.stamp-slot {
  position: absolute;
  top: 12px;
  right: 18px;
  z-index: 2;
}

/* =============================================================================
   8. LINKS
   ========================================================================== */

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

.block a:not(.tab):not(.button):not(.card) {
  color: var(--pen);
  font-weight: 500;
  text-decoration: none;
  background-image: linear-gradient(var(--pen-soft), var(--pen-soft));
  background-size: 100% 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition:
    background-size 0.25s ease,
    color 0.2s ease;
}

.block a:not(.tab):not(.button):not(.card):hover,
.block a:not(.tab):not(.button):not(.card):focus-visible {
  color: var(--stamp);
  background-image: linear-gradient(var(--stamp), var(--stamp));
  background-size: 100% 2px;
}

:focus-visible {
  outline: 2px solid var(--stamp);
  outline-offset: 3px;
}

/* =============================================================================
   9. BUTTON — pressed like an official seal
   ========================================================================== */

.button {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: 11px 24px;
  font-family: var(--face-form);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--paper-hi);
  background: linear-gradient(180deg, #a8402c, var(--stamp) 55%, #7c2517);
  border: 1px solid #6a1f13;
  border-radius: 3px;
  box-shadow:
    inset 0 1px 0 rgba(255, 220, 205, 0.35),
    var(--lift-1);
  transition:
    transform 0.18s ease,
    box-shadow 0.18s ease,
    filter 0.18s ease;
}

.button:hover,
.button:focus-visible {
  transform: translateY(-2px);
  filter: brightness(1.08);
  box-shadow:
    inset 0 1px 0 rgba(255, 220, 205, 0.35),
    var(--lift-2);
}

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

/* =============================================================================
   10. PIP TRACKS — the shared rating primitive
   Set --pips (how many) and --fill (0-100). Both layers share identical
   geometry, so the filled layer is just the empty one clipped.
   ========================================================================== */

/* --pips and --fill are read with fallbacks rather than declared here: a
   declaration on .pips would shadow the value inherited from an ancestor
   (.score sets it on the box, .prof sets it inline on the track itself). */
.pips {
  display: block;
  position: relative;
  height: 13px;
  color: var(--rule);
  background-image: radial-gradient(
    circle at 50% 50%,
    currentColor 0 2.6px,
    transparent 3.1px
  );
  background-size: calc(100% / var(--pips, 10)) 100%;
}

.pips > i {
  display: block;
  height: 100%;
  color: var(--stamp);
  background-image: radial-gradient(
    circle at 50% 50%,
    currentColor 0 3.1px,
    transparent 3.6px
  );
  background-size: calc(100% / var(--pips, 10)) 100%;
  clip-path: inset(0 calc(100% - var(--fill, 0) * 1%) 0 0);
  animation: ink-in 1.05s cubic-bezier(0.22, 0.85, 0.24, 1) both;
  mix-blend-mode: multiply;
}

@keyframes ink-in {
  from {
    clip-path: inset(0 100% 0 0);
  }
  to {
    clip-path: inset(0 calc(100% - var(--fill, 0) * 1%) 0 0);
  }
}

/* =============================================================================
   11. ABILITY SCORES
   ========================================================================== */

.scores {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 30px 18px;
  margin-top: 8px;
}

.score {
  position: relative;
  padding: 10px 12px 24px;
  text-align: center;
  background: var(--paper-hi);
  border: 1.5px solid var(--rule-strong);
  border-radius: 3px;
  box-shadow: var(--lift-1);
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease;
}

.score:hover {
  transform: translateY(-3px);
  box-shadow: var(--lift-2);
}

.score__label {
  display: block;
  font-family: var(--face-form);
  font-size: 0.63rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.score__value {
  display: block;
  margin: 2px 0 8px;
  font-family: var(--face-display);
  font-size: 2.5rem;
  line-height: 1;
  color: var(--ink);
  text-shadow: 0 1px 0 rgba(255, 253, 245, 0.9);
}

/* The modifier bubble, straddling the bottom edge of the box. */
.score__mod {
  position: absolute;
  left: 50%;
  bottom: -15px;
  transform: translateX(-50%);
  min-width: 46px;
  padding: 3px 8px 2px;
  font-family: var(--face-form);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--paper-hi);
  background: var(--rule-strong);
  border-radius: 999px;
  box-shadow:
    0 0 0 3px var(--paper-hi),
    var(--lift-1);
}

.score__mod[data-sign="+"] {
  background: var(--pen);
}

.score__mod[data-sign="-"] {
  background: var(--stamp);
}

/* =============================================================================
   12. PROFICIENCIES — skill rows with rank pips
   ========================================================================== */

.profs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: 2px 34px;
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
}

.prof {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 9px 2px;
  border-bottom: 1px dotted var(--rule);
}

/* Filled proficiency bubble — the mark you make when you're trained. */
.prof__bubble {
  width: 11px;
  height: 11px;
  border: 1.5px solid var(--rule-strong);
  border-radius: 50%;
  background: var(--stamp);
  box-shadow: inset 0 0 0 1.5px var(--paper-hi);
}

.prof__name {
  font-family: var(--face-form);
  font-size: 0.94rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.prof__rank {
  display: flex;
  align-items: center;
  gap: 9px;
}

.prof__rank .pips {
  width: 62px;
  flex: 0 0 auto;
}

.prof__word {
  font-family: var(--face-hand);
  font-size: 1.22rem;
  font-weight: 600;
  color: var(--pen);
  white-space: nowrap;
  mix-blend-mode: multiply;
}

.prof:nth-child(odd) .prof__word {
  transform: rotate(-1deg);
}
.prof:nth-child(even) .prof__word {
  transform: rotate(0.8deg);
}

/* =============================================================================
   13. LEADER LISTS — inventory / loadout, dotted to the right margin
   ========================================================================== */

.leaders {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
  column-gap: 40px;
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
}

.leaders--single {
  grid-template-columns: 1fr;
}

/* key | dotted leader | value. The value column may shrink to nothing and wrap,
   which is what keeps long entries (the monitoring stack) on the paper. */
.leaders li {
  display: grid;
  grid-template-columns: auto minmax(14px, 1fr) minmax(0, auto);
  align-items: baseline;
  column-gap: 7px;
  padding: 6px 0;
  font-size: 1rem;
}

.leaders li > *:first-child {
  grid-area: 1 / 1;
}

.leaders li::after {
  content: "";
  grid-area: 1 / 2;
  align-self: center;
  height: 0;
  border-bottom: 1px dotted var(--rule);
}

.leaders li > .hand,
.leaders li > .leaders__val {
  grid-area: 1 / 3;
  font-family: var(--face-hand);
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.15;
  text-align: right;
  text-wrap: balance;
  overflow-wrap: anywhere;
  color: var(--pen);
  mix-blend-mode: multiply;
}

/* =============================================================================
   14. CHECKLISTS — quests and hobbies
   ========================================================================== */

.checklist {
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
}

.checklist li {
  position: relative;
  padding: 8px 0 8px 38px;
  border-bottom: 1px dotted var(--rule);
}

.checklist li:last-child {
  border-bottom: none;
}

/* The printed box... */
.checklist li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 11px;
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--rule-strong);
  border-radius: 2px;
  background: var(--paper-hi);
  box-shadow: inset 0 1px 2px rgba(90, 70, 40, 0.12);
}

/* ...and the tick scrawled into it, overshooting the way a real one does. */
.checklist li::after {
  content: "✓";
  position: absolute;
  left: 4px;
  top: 4px;
  font-family: var(--face-hand);
  font-size: 1.55rem;
  font-weight: 700;
  line-height: 1;
  color: var(--stamp);
  transform: rotate(-9deg);
  mix-blend-mode: multiply;
}

.checklist--tight {
  columns: 2;
  column-gap: 38px;
}

.checklist--tight li {
  break-inside: avoid;
  border-bottom: none;
}

/* =============================================================================
   15. CARDS — the "explore" destinations
   ========================================================================== */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 14px;
  margin-top: 4px;
}

.card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 18px 16px 16px;
  text-decoration: none;
  background: var(--paper-hi);
  border: 1.5px solid var(--rule-strong);
  border-radius: 3px;
  box-shadow: var(--lift-1);
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease,
    border-color 0.2s ease;
}

.card:hover,
.card:focus-visible {
  transform: translateY(-4px) rotate(-0.6deg);
  border-color: var(--stamp);
  box-shadow: var(--lift-2);
}

.card__no {
  font-family: var(--face-form);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  color: var(--ink-faint);
}

.card__name {
  font-family: var(--face-display);
  font-size: 1.22rem;
  line-height: 1.1;
  color: var(--ink);
}

/* Hints sit on a common baseline across the row, whatever the title wraps to. */
.card__hint {
  margin-top: auto;
  padding-top: 6px;
  font-family: var(--face-hand);
  font-size: 1.12rem;
  color: var(--pen);
  mix-blend-mode: multiply;
}

.card:hover .card__name {
  color: var(--stamp);
}

/* =============================================================================
   16. SERVICE RECORD — the resume timeline
   ========================================================================== */

.entry {
  position: relative;
  margin: 0 0 26px;
  padding-left: 22px;
  border-left: 1.5px solid var(--rule);
}

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

.entry::before {
  content: "";
  position: absolute;
  left: -5.5px;
  top: 8px;
  width: 9px;
  height: 9px;
  background: var(--stamp);
  transform: rotate(45deg);
  box-shadow: 0 0 0 3px var(--paper);
}

.entry h3 {
  margin: 0;
}

.entry__role {
  margin: 1px 0 2px !important;
  font-family: var(--face-body);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink);
}

.entry__meta {
  margin: 0 0 8px !important;
  font-family: var(--face-hand);
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--pen);
  transform: rotate(-0.5deg);
  transform-origin: left center;
  mix-blend-mode: multiply;
}

/* Prose bullets — a small gold lozenge, not loot */
.bullets {
  margin: 0;
  padding: 0;
  list-style: none;
}

.bullets li {
  position: relative;
  margin-bottom: 7px;
  padding-left: 20px;
  max-width: 74ch;
}

.bullets li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.62em;
  width: 6px;
  height: 6px;
  background: var(--gold);
  transform: rotate(45deg);
}

.grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
  gap: 20px 34px;
}

.grid-2 > div {
  min-width: 0;
  padding-top: 12px;
  border-top: 1px solid var(--rule);
}

.grid-2 > div > h3 {
  margin-top: 0;
}

/* =============================================================================
   17. CONTACT — a fill-in form of ways to reach the character
   ========================================================================== */

.contact-list {
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
}

.contact-list li {
  display: grid;
  grid-template-columns: 110px 1fr;
  align-items: baseline;
  gap: 4px 14px;
  padding: 12px 0 6px;
  border-bottom: 1px solid var(--rule);
}

.contact-list dt,
.contact-list .contact-key {
  font-family: var(--face-form);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* Grid blockifies the anchor, which would stretch its underline across the
   whole column — shrink it back to the width of the writing. */
.contact-list a {
  justify-self: start;
  font-family: var(--face-hand) !important;
  font-size: 1.5rem !important;
  font-weight: 600;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

.contact-list li:nth-child(odd) a {
  transform: rotate(-0.6deg);
  display: inline-block;
}

/* =============================================================================
   18. COLOPHON
   ========================================================================== */

.colophon {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 20px;
  margin-top: 30px;
  padding-top: 14px;
  border-top: 1.5px solid var(--rule-strong);
  font-family: var(--face-form);
  font-size: 0.62rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.colophon a {
  color: var(--ink-faint);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}

.colophon a:hover {
  color: var(--stamp);
}

/* =============================================================================
   19. ENTRANCE — the sheet is set down, then the sections are read
   ========================================================================== */

@keyframes drop-in {
  from {
    opacity: 0;
    transform: translateY(-26px) rotate(-1.2deg) scale(1.015);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes write-on {
  from {
    opacity: 0;
    transform: translateY(6px) rotate(-3deg);
  }
}

@keyframes press {
  from {
    opacity: 0;
    transform: rotate(-7deg) scale(1.7);
  }
  to {
    opacity: 0.82;
    transform: rotate(-7deg) scale(1);
  }
}

.sheet {
  animation: drop-in 0.75s cubic-bezier(0.2, 0.9, 0.25, 1) both;
}

.masthead,
.tabs,
.block {
  animation: rise 0.6s ease-out both;
}

.masthead {
  animation-delay: 0.16s;
}
.tabs {
  animation-delay: 0.24s;
}
.block:nth-of-type(1) {
  animation-delay: 0.3s;
}
.block:nth-of-type(2) {
  animation-delay: 0.38s;
}
.block:nth-of-type(3) {
  animation-delay: 0.46s;
}
.block:nth-of-type(4) {
  animation-delay: 0.54s;
}
.block:nth-of-type(5) {
  animation-delay: 0.62s;
}
.block:nth-of-type(6) {
  animation-delay: 0.7s;
}
.block:nth-of-type(n + 7) {
  animation-delay: 0.78s;
}

.namefield__value {
  animation: write-on 0.7s cubic-bezier(0.22, 0.9, 0.25, 1) 0.4s both;
}

.rubber-stamp {
  animation: press 0.42s cubic-bezier(0.3, 1.5, 0.5, 1) 0.95s both;
}

/* Stagger the score boxes so the sheet "rolls" its stats. */
.score {
  animation: rise 0.5s ease-out both;
}
.score:nth-child(1) {
  animation-delay: 0.42s;
}
.score:nth-child(2) {
  animation-delay: 0.47s;
}
.score:nth-child(3) {
  animation-delay: 0.52s;
}
.score:nth-child(4) {
  animation-delay: 0.57s;
}
.score:nth-child(5) {
  animation-delay: 0.62s;
}
.score:nth-child(6) {
  animation-delay: 0.67s;
}
.score:nth-child(7) {
  animation-delay: 0.72s;
}
.score:nth-child(8) {
  animation-delay: 0.77s;
}
.score:nth-child(9) {
  animation-delay: 0.82s;
}

.score:nth-child(1) .pips > i {
  animation-delay: 0.6s;
}
.score:nth-child(2) .pips > i {
  animation-delay: 0.68s;
}
.score:nth-child(3) .pips > i {
  animation-delay: 0.76s;
}
.score:nth-child(4) .pips > i {
  animation-delay: 0.84s;
}
.score:nth-child(5) .pips > i {
  animation-delay: 0.92s;
}
.score:nth-child(6) .pips > i {
  animation-delay: 1s;
}
.score:nth-child(7) .pips > i {
  animation-delay: 1.08s;
}
.score:nth-child(8) .pips > i {
  animation-delay: 1.16s;
}
.score:nth-child(9) .pips > i {
  animation-delay: 1.24s;
}

/* =============================================================================
   20. RESPONSIVE
   ========================================================================== */

@media (max-width: 760px) {
  :root {
    --sheet-pad-y: 30px;
    --sheet-pad-x: 26px;
    --margin-rule: 14px;
    --gap: 16px;
  }

  body {
    padding: 14px 10px 40px;
    font-size: 1.02rem;
  }

  .block {
    padding: 16px 15px 18px;
  }

  .leaders,
  .checklist--tight {
    grid-template-columns: 1fr;
    columns: 1;
  }

  /* Keep the ability boxes two-up rather than a single tall stack. */
  .scores {
    grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
    gap: 26px 12px;
  }

  .score {
    padding: 9px 8px 22px;
  }

  .score__value {
    font-size: 2.1rem;
  }

  .stain,
  .sheet::before,
  .sheet::after {
    display: none;
  }

  .stamp-slot {
    position: static;
    display: block;
    margin: 0 0 18px;
    text-align: center;
  }
}

@media (max-width: 560px) {
  /* Tabs stop pretending to be tabs and become a plain index. */
  .tabs {
    justify-content: center;
    gap: 6px 16px;
    padding: 0 0 12px;
  }

  .tab {
    margin: 0;
    padding: 2px 0;
    background: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
    font-size: 0.72rem;
  }

  .tab:hover,
  .tab:focus-visible {
    background: none;
    transform: none;
  }

  .tab[aria-current="page"] {
    background: none;
    border: none;
    box-shadow: 0 2px 0 var(--stamp);
  }

  .contact-list li {
    grid-template-columns: 1fr;
  }

  .prof {
    grid-template-columns: auto 1fr;
    row-gap: 4px;
  }

  .prof__rank {
    grid-column: 2;
    justify-content: flex-start;
  }
}

/* =============================================================================
   21. PRINT — it is a character sheet; it should print like one
   ========================================================================== */

@media print {
  @page {
    margin: 14mm;
  }

  body {
    padding: 0;
    background: #fff;
    color: #000;
    font-size: 10.5pt;
  }

  .sheet {
    max-width: none;
    margin: 0;
    padding: 0;
    background: #fff;
    border: none;
    box-shadow: none;
    animation: none;
  }

  .sheet::before,
  .sheet::after,
  .tabs,
  .staple,
  .stain,
  .skip-link,
  .colophon a[href^="http"] {
    display: none !important;
  }

  .block,
  .score,
  .card {
    background: #fff;
    box-shadow: none;
    animation: none;
  }

  /* Only the small units avoid breaking — a whole .block is often taller than
     a page, and avoiding it there just ejects a blank sheet. */
  .score,
  .card,
  .entry,
  .prof,
  .checklist li,
  .leaders li {
    break-inside: avoid;
  }

  .block__title,
  .block h3 {
    break-after: avoid;
  }

  p,
  .bullets li {
    orphans: 2;
    widows: 2;
  }

  /* These marks ARE the content, not decoration — force them through. */
  .pips,
  .pips > i,
  .prof__bubble,
  .score__mod,
  .block__no,
  .block__title::after,
  .bullets li::before,
  .entry::before,
  .rubber-stamp {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .pips > i {
    animation: none;
  }

  .rubber-stamp {
    animation: none;
    opacity: 1;
  }

  .rubber-stamp::after {
    display: none;
  }

  a {
    color: #000;
    background: none !important;
  }
}

/* =============================================================================
   22. REDUCED MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important;
    transition-duration: 0.001ms !important;
  }
}
