@font-face {
  font-family: 'Treasuremap';
  src: url('../fonts/Treasuremap.ttf') format('truetype');
  font-display: swap;
}
:root {
  --sea:      #16302f;
  --deep:     #0d1f1f;
  --foam:     #cfe3df;
  /* The accent, formerly #f2b632 gold. White reads cleaner against the sunset
     and the storm; the rgba() tints below track it by hand. */
  --gold:     #ffffff;
  --parch:    #f4e3c3;
  --ink:      #e8f0ed;
  --dim:      #93aaa5;
  --headerh:  60px;
  /* The hero's water at its foot is rgb(63,141,180); this is that colour taken
     down far enough to read body text on. The home page runs from it into
     --deep, so the page keeps descending from the sunset sea into the storm. */
  --tide-top: #1d4354;
  /* Same colour at zero alpha. Fading from the keyword `transparent` means
     fading from transparent BLACK, which dirties the middle of the ramp. */
  --tide-top-0: rgba(29,67,84,0);
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0; background: var(--deep); color: var(--ink);
  font: 16px/1.65 ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  overflow-x: hidden;
}
a { color: var(--gold); }
.display { font-family: 'Treasuremap', Georgia, serif; letter-spacing: .02em; }

/* --------------------------------------------------------------- header */
header {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  display: flex; align-items: center; gap: 1rem;
  padding: .7rem clamp(1rem, 4vw, 2.5rem);
  background: linear-gradient(to bottom, rgba(8,20,20,.92), rgba(8,20,20,0));
  backdrop-filter: blur(3px);
}
.brand { display: block; line-height: 0; }
.brand img { height: 42px; width: auto; }
nav { margin-left: auto; display: flex; gap: clamp(.7rem, 2vw, 1.9rem); }
nav a {
  color: var(--foam); text-decoration: none; font-size: .96rem;
  text-transform: uppercase; letter-spacing: .06em; white-space: nowrap;
}
nav a:hover { color: var(--gold); }
nav a.cta { color: var(--gold); font-weight: 700; }
nav a[aria-current="page"] { color: var(--gold); }

/* Hamburger. Hidden until the row would start colliding: with the Registry
   added the row is ten items, which overflow below about 1240px, and wrapping
   them ate the top of the hero. */
.burger {
  display: none; margin-left: auto; width: 42px; height: 38px; padding: 9px 8px;
  background: rgba(255,255,255,.05); border: 1px solid rgba(207,227,223,.18);
  border-radius: 9px; cursor: pointer;
}
.burger span {
  display: block; height: 2px; border-radius: 2px; background: var(--foam);
  transition: transform .22s ease, opacity .18s ease;
}
.burger span + span { margin-top: 5px; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 1240px) {
  header { padding: .6rem 1rem; background: rgba(8,20,20,.94); }
  .brand img { height: 34px; }
  .burger { display: block; }
  nav {
    position: absolute; top: 100%; left: 0; right: 0; margin: 0;
    flex-direction: column; gap: 0; align-items: stretch;
    background: rgba(8,20,20,.98); border-top: 1px solid rgba(207,227,223,.12);
    /* Collapsed by default; the panel animates on its own height so the page
       underneath never shifts. */
    max-height: 0; overflow: hidden; transition: max-height .28s ease;
  }
  /* Room to spare: the ten rows measure about 33rem, and a clipped last link is
     a far worse failure than a slightly slower slide. */
  nav.open { max-height: 42rem; }
  nav a {
    padding: .85rem 1.15rem; font-size: .92rem;
    border-bottom: 1px solid rgba(207,227,223,.08);
  }
  nav a:last-child { border-bottom: 0; }
}

/* ----------------------------------------------------------------- hero */
/* Layered, not one flat picture. The scene is assembled from the original
   cutouts over a cleaned sky-and-sea plate, so nothing has to be padded out
   sideways to fill a wide window — the plate simply covers, exactly like the
   mutant-sea band further down the page, and the crew, the yacht and the title
   keep their own places whatever shape the window is.
   The plate's horizon sits at 49.9% of its height, and `object-fit: cover` with
   a centred position keeps a given percentage of the image on the same
   percentage of the box, so the waterline is pinned at --water at every size. */
.hero {
  --water: 49.9%;
  position: relative; width: 100%; overflow: hidden;
  height: clamp(520px, 92svh, 940px);
  background: #eb87a4;
}
.hero > * { position: absolute; display: block; }
.hero-bg {
  inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center center;
}
/* Every layer is sized off the hero's HEIGHT, so the whole scene scales as one
   piece and only the empty sea to either side grows on a wide window.
   Width and height are set on the layer classes themselves — a `.hero img`
   shorthand outranks a single class and silently unsets them.
   Each layer also carries a max-width: on a tall window the height-driven size
   would run off both edges, and a replaced element with width:auto shrinks in
   proportion when max-width bites, so the scene simply gets smaller instead. */
.h-clouds-l { left: 0;  top: 6%; height: 20%; width: auto; max-width: 36%; }
.h-clouds-r { right: 0; top: 3%; height: 17%; width: auto; max-width: 22%; }
.h-yacht    { left: 6%; bottom: calc(var(--water) - 2.4%); height: 16%; width: auto; max-width: 30%; }
.h-crew {
  right: 3%; bottom: 7%; height: 62%; width: auto; max-width: 82%;
  filter: drop-shadow(0 12px 26px rgba(90,40,60,.35));
}

.h-title {
  left: 26%; top: 8%; height: 24%; width: auto; max-width: 46%;
  filter: drop-shadow(0 3px 14px rgba(90,40,60,.38))
          drop-shadow(0 1px 3px rgba(0,0,0,.28));
}
/* Short fade into the page. It lands on --tide-top rather than --deep so the
   hero's water and the gradient below it meet without a seam. */
.hero::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 20%;
  background: linear-gradient(to bottom, var(--tide-top-0), var(--tide-top));
  pointer-events: none; z-index: 3;
}

/* The stretch between the hero and the mutant sea: the water carries on
   darkening, so the page reads as one descent rather than three bands. */
.tide { background: linear-gradient(to bottom, var(--tide-top), var(--deep)); }

/* Wide and short: the sky band is thin, so the title drops to the left of the
   yacht rather than above it. */
@media (min-aspect-ratio: 2/1) {
  .h-title { left: 22%; top: 9%; height: 21%; }
  .h-crew  { height: 58%; }
}
/* Phone: the scene goes width-driven — a height-driven crew would clamp down to
   a toy — and the title takes the middle of the sky. The clouds come off
   altogether; at this width they leave the title nowhere clear to sit. */
@media (max-width: 640px) {
  /* svh is the SMALL viewport height — on iOS Safari it excludes the toolbars,
     so 78svh on a 844pt phone is about 476px, not 658. Sized off that alone the
     hero came out short and wide and the scene read enormous, so a vw floor
     guarantees enough sky above the crew whatever the browser chrome does. */
  .hero { height: max(clamp(440px, 78svh, 720px), 130vw); }
  .h-clouds-l, .h-clouds-r { display: none; }
  .h-crew {
    width: 92%; height: auto; max-width: none; right: 0; bottom: 7%;
  }
  .h-yacht {
    width: 32%; height: auto; max-width: none; left: 2%;
    bottom: calc(var(--water) - 1.4%);
  }
  /* Half width, tucked left. Centred at 76% it ran from the header down to 56%
     of the hero and sat squarely on the captain, who starts at 25%. */
  .h-title {
    width: 52%; height: auto; max-width: none;
    left: 5%; transform: none; top: calc(var(--headerh) + 1rem);
  }
}

/* ------------------------------------------------------------ page head */
/* Inner pages get a slim banner instead of the hero, so the nav always has
   something dark to sit on and the page announces itself. */
.pagehead {
  position: relative; overflow: hidden;
  padding: calc(var(--headerh) + clamp(2.2rem, 6vw, 4rem)) clamp(1rem, 5vw, 3rem)
           clamp(1.6rem, 4vw, 2.6rem);
  border-bottom: 1px solid rgba(207,227,223,.1);
}
/* Every page but Below Deck carries the water down from the home page's hero,
   so their banners stay transparent and let it through. Below Deck keeps the
   old dark banner — it is below the waterline, and should feel it. */
body.tide-page {
  background: linear-gradient(to bottom, var(--tide-top), var(--deep) 900px)
              no-repeat var(--deep);
}
body:not(.tide-page) .pagehead {
  background: linear-gradient(180deg, #0a1c1b, #12302e 60%, var(--deep));
}
.pagehead::before {
  content: ''; position: absolute; inset: 0;
  background: url('../img/crossbonebg.png') center/cover no-repeat;
  opacity: .07; pointer-events: none;
}
.pagehead .wrap { position: relative; }
.pagehead h1 {
  font-family: 'Treasuremap', Georgia, serif; font-weight: 400;
  font-size: clamp(2.2rem, 6vw, 3.6rem); margin: 0 0 .35rem; color: var(--parch);
}
.pagehead p { color: var(--dim); max-width: 62ch; margin: 0; }

/* ----------------------------------------------------------- sections */
section {
  padding: clamp(3rem, 8vw, 6rem) clamp(1rem, 5vw, 3rem);
  scroll-margin-top: 4.5rem;
}
section.tight { padding-top: clamp(2rem, 5vw, 3.2rem); }
.wrap { max-width: 1080px; margin: 0 auto; }
h2 {
  font-family: 'Treasuremap', Georgia, serif; font-weight: 400;
  font-size: clamp(2rem, 5vw, 3.1rem); margin: 0 0 .4rem; color: var(--parch);
}
.lede { color: var(--dim); max-width: 60ch; margin: 0 0 2.2rem; }

.fleet { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
/* The rum portions read as pairs, not a row of four: the two that leave your
   ape alone on top, the barrel and the toxic one below. */
.pairs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 620px) { .pairs { grid-template-columns: minmax(0, 1fr); } }

/* ----------------------------------------------------------- timeline */
.timeline { list-style: none; margin: 0; padding: 0; position: relative; }
.timeline::before {
  content: ''; position: absolute; left: 33px; top: .8rem; bottom: 2.4rem; width: 2px;
  background: linear-gradient(to bottom,
    rgba(255,255,255,.45), rgba(255,255,255,.22) 70%, transparent);
}
.timeline > li { position: relative; padding-left: 5.6rem; margin-bottom: 1.15rem; }
.timeline > li:last-child { margin-bottom: 0; }
.tl-when {
  position: absolute; left: 0; top: .35rem; width: 68px; text-align: center;
  font-family: 'Treasuremap', Georgia, serif; color: var(--gold);
  font-size: 1.12rem; line-height: 1.05;
}
.tl-when span {
  display: block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .66rem; letter-spacing: .1em; color: var(--dim); margin-top: .15rem;
}
.timeline > li::before {
  content: ''; position: absolute; left: 28px; top: 3.05rem;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--gold); box-shadow: 0 0 0 4px rgba(255,255,255,.14);
}
.card {
  background: rgba(255,255,255,.035); border: 1px solid rgba(207,227,223,.14);
  border-radius: 12px; padding: 1.4rem 1.5rem;
  min-width: 0;
}
.card h3 { font-family: 'Treasuremap', Georgia, serif; font-weight: 400;
           font-size: 1.55rem; margin: 0 0 .15rem; color: var(--parch); }

/* Collection artwork at the foot of a Fleet card, under the marketplace links.
   No fixed aspect-ratio: the banners differ (2.67:1 for the ales, 3:1 for the
   crew art) and cropping them to match would cut into the lettering. */
.banner {
  width: 100%; height: auto; display: block; border-radius: 9px;
  margin-top: 1.2rem; background: #0b1615;
  border: 1px solid rgba(207,227,223,.1);
}

/* Examples of the pair every crew needs: one Pirate Ape, one Sea Mutant.
   A grid rather than a flex row so they shrink together on a phone. */
.crew-pair {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .7rem; margin-top: 1.2rem; max-width: 420px;
}
.mutate .crew-pair img {
  /* Two classes deep on purpose: `.mutate img` sets width:92px for the barrel
     and sits later in this file, so a bare `.crew-pair img` loses the tie.
     flex:none stops the row squeezing them as well. */
  width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; display: block;
  border-radius: 10px; background: #0b1615; border: 1px solid rgba(207,227,223,.16);
}
.mutate .crew-rule { margin-top: 1.2rem; background: rgba(0,0,0,.28); }

.chead { display: flex; gap: .85rem; align-items: center; margin-bottom: .55rem; }
.chead > div { min-width: 0; }
.clogo {
  width: 58px; height: 58px; flex: none; border-radius: 11px; object-fit: cover;
  border: 1px solid rgba(207,227,223,.16); background: #0b1615; display: block;
}
.chead h3 { margin: 0; line-height: 1.15; font-size: 1.38rem; }
.card .count { color: var(--gold); font-size: .88rem; letter-spacing: .05em; }
.card p { color: var(--dim); font-size: .93rem; margin: .6rem 0 1rem; }

.links { display: flex; gap: .55rem; align-items: center; }
.links a {
  display: grid; place-items: center; width: 34px; height: 34px; margin: 0;
  border: 1px solid rgba(207,227,223,.16); border-radius: 8px;
  color: var(--foam); background: rgba(255,255,255,.03);
  transition: color .15s, border-color .15s, background .15s;
}
.links a:hover {
  color: var(--gold); border-color: rgba(255,255,255,.5);
  background: rgba(255,255,255,.1); text-decoration: none;
}
.links a:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.ico { width: 19px; height: 19px; fill: currentColor; display: block; }

.rum-art {
  width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; display: block;
  border-radius: 9px; background: #080808;
  border: 1px solid rgba(207,227,223,.1); margin-bottom: .95rem;
}
.card.spent { opacity: .85; }
.card.spent .count { color: var(--dim); }
.card.spent .rum-art { filter: saturate(.65); }
.card.retired { opacity: .72; }
.card.retired h3 { color: var(--dim); }
.tag {
  display: inline-block; vertical-align: middle; margin-left: .4rem;
  font-family: ui-sans-serif, system-ui, sans-serif; font-size: .58rem;
  letter-spacing: .08em; text-transform: uppercase; font-weight: 700;
  background: rgba(255,255,255,.13); color: var(--foam); padding: .12rem .38rem; border-radius: 3px;
}
.notice {
  border: 1px solid rgba(207,227,223,.16); border-left: 3px solid var(--gold);
  background: rgba(255,255,255,.03); border-radius: 8px;
  padding: 1rem 1.2rem; color: var(--dim); font-size: .9rem; max-width: 78ch;
}
.notice strong { color: var(--parch); }
.notice.warn { border-left-color: #d9663f; }
/* The retired-rum notice reads as a fifth portion, so its art is sized like the
   card art above it rather than as a thumbnail: the notice spans the full grid
   and the image takes roughly the same share a card's does. Source is a 900px
   re-export of the 2048px original — the old 260px copy could not carry this. */
.notice-img { display: flex; gap: 1.6rem; align-items: center; max-width: none; }
.notice-img img {
  width: min(46%, 482px); height: auto; aspect-ratio: 1; flex: none;
  border-radius: 9px; object-fit: cover;
  background: #080808; border: 1px solid rgba(207,227,223,.12);
  filter: saturate(.7); opacity: .9;
}
.notice-img p { margin: 0; max-width: 46ch; }
@media (max-width: 620px) {
  .notice-img { flex-direction: column; align-items: stretch; gap: 1rem; }
  .notice-img img { width: 100%; max-width: none; }
  .notice-img p { max-width: none; }
}

/* ------------------------------------------------------------ the ledger */
/* Mutation statistics. Every figure is read from mainnet logs, so the block is
   deliberately plain: numbers first, no decoration competing with them.
   Treasuremap is NOT used for digits anywhere — it is a display face and its
   numerals are barely legible at these sizes. */
.stats {
  display: grid; gap: .8rem; margin: 0 0 1.6rem;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.stat {
  border: 1px solid rgba(207,227,223,.14); border-radius: 11px;
  background: rgba(255,255,255,.035); padding: 1.1rem 1.2rem;
}
.stat b {
  display: block; font-size: clamp(1.9rem, 4.4vw, 2.5rem); line-height: 1.05;
  font-weight: 700; color: var(--parch); font-variant-numeric: tabular-nums;
}
.stat span {
  display: block; margin-top: .35rem; color: var(--dim);
  font-size: .82rem; letter-spacing: .05em; text-transform: uppercase;
}
.stat em { display: block; margin-top: .5rem; color: var(--dim);
  font-size: .85rem; font-style: normal; text-transform: none; letter-spacing: 0; }

/* ------------------------------------------------ the two percentages */
/* "76% mutated" and "44% mutated" are both correct and count against different
   totals, which reads as a contradiction if a page shows only one of them. So
   both are shown together, side by side, with their denominators spelled out
   and a line saying why they differ. This block is IDENTICAL on the Rum Club
   and the Registry on purpose — the two pages disagreeing was the problem. */
.pcts {
  display: grid; gap: 1rem 1.6rem; margin: 1.4rem 0 0;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  border: 1px solid rgba(207,227,223,.14); border-radius: 11px;
  background: rgba(255,255,255,.035); padding: 1.3rem 1.4rem;
}
.pcts > div { min-width: 0; }
.pcts b {
  display: block; font-size: clamp(2.1rem, 5vw, 2.9rem); line-height: 1.02;
  font-weight: 700; color: var(--parch); font-variant-numeric: tabular-nums;
}
.pcts span {
  display: block; margin-top: .3rem; color: var(--foam); font-size: .92rem;
}
.pcts em {
  display: block; margin-top: .25rem; color: var(--dim); font-style: normal;
  font-size: .8rem; letter-spacing: .06em; text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
/* The explanation runs under both figures rather than beside either one, so
   neither percentage looks like the one being qualified. */
.pcts p {
  grid-column: 1 / -1; margin: .2rem 0 0; color: var(--dim); font-size: .9rem;
  border-top: 1px solid rgba(207,227,223,.12); padding-top: .95rem; max-width: 76ch;
}
.pcts p strong { color: var(--parch); }

/* The table is wider than a phone; it scrolls inside its own box rather than
   pushing the page sideways. */
.scroller { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* iOS hides the scrollbar entirely, so on the widths where the table has to
   scroll, say so. Hidden by default and shown by the query, never the reverse. */
.swipe { display: none; }
@media (max-width: 620px) {
  .swipe:not([hidden]) { display: block; margin: .5rem 0 0; font-size: .78rem; }
}
.ledger {
  width: 100%; min-width: 560px; border-collapse: collapse;
  font-size: .92rem; font-variant-numeric: tabular-nums;
}
.ledger.years { min-width: 380px; }
.ledger th, .ledger td {
  padding: .62rem .7rem; text-align: right;
  border-bottom: 1px solid rgba(207,227,223,.1);
}
.ledger th:first-child, .ledger td:first-child { text-align: left; }
.ledger thead th {
  color: var(--dim); font-weight: 600; font-size: .74rem;
  letter-spacing: .07em; text-transform: uppercase; vertical-align: bottom;
}
/* Row headers are <th scope="row"> for screen readers, so they need the cell
   treatment back — the UA sheet centres and bolds them. */
.ledger tbody th { color: var(--foam); font-weight: 600; white-space: nowrap; }
/* The portion's own art beside its name. Same URLs the cards above already
   loaded, so these cost no extra request. */
.ledger .portion { display: flex; align-items: center; gap: .6rem; }
.ledger .portion img {
  width: 34px; height: 34px; flex: none; border-radius: 6px; object-fit: cover;
  background: #080808; border: 1px solid rgba(207,227,223,.12);
}
.ledger .retired-row .portion img { filter: saturate(.6); opacity: .8; }
.ledger tbody tr:hover td { background: rgba(255,255,255,.035); }
.ledger .held { color: var(--parch); font-weight: 700; }
.ledger .nil { color: #5f7773; }
.ledger tfoot td {
  border-top: 1px solid rgba(207,227,223,.28); border-bottom: 0;
  padding-top: .75rem; color: var(--parch); font-weight: 700;
}
.ledger .retired-row td, .ledger .retired-row th { color: var(--dim); }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.cap { color: var(--dim); font-size: .84rem; margin: .8rem 0 0; max-width: 74ch; }
/* Table footnotes. These were one dense paragraph and nobody was going to read
   it; one claim per line, each led by the thing it is about. */
.notes { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: .6rem; max-width: 76ch; }
.notes li {
  position: relative; padding-left: 1.1rem;
  color: var(--dim); font-size: .88rem; line-height: 1.6;
}
.notes li::before {
  content: ''; position: absolute; left: 0; top: .65em;
  width: 6px; height: 1px; background: rgba(255,255,255,.45);
}
.notes strong { color: var(--parch); font-weight: 600; }

/* Histogram. One series, so no legend — the heading names it — and every bar
   carries its own value rather than an axis of ticks. */
.hist { margin: .4rem 0 0; display: grid; gap: .34rem; }
/* Three tracks, not "bar then label": a full-width bar plus its label inline
   would push the longest bar's value outside the wrap. Values get their own
   column, which also lines the digits up. */
.hist .row {
  display: grid; grid-template-columns: 5.6rem minmax(0, 1fr) 3.4rem;
  align-items: center; gap: .7rem;
}
.hist .k { color: var(--dim); font-size: .82rem; text-align: right; font-variant-numeric: tabular-nums; }
.hist .bar { min-width: 0; }
.hist .bar i {
  display: block; height: 13px; border-radius: 0 4px 4px 0;
  background: rgba(255,255,255,.42);
}
.hist .row.peak .bar i { background: #d9663f; }
.hist .row.peak .v { color: var(--parch); }
.hist .v { color: var(--dim); font-size: .8rem; font-variant-numeric: tabular-nums; }
@media (max-width: 560px) {
  .hist .row { grid-template-columns: 4rem minmax(0, 1fr) 2.9rem; gap: .5rem; }
}

/* ------------------------------------------------------ mutation call-out */
.mutate {
  position: relative; border-radius: 14px; overflow: hidden;
  border: 1px solid rgba(255,255,255,.24);
  background: url('../img/mint-bg.png') center/cover no-repeat #12312e;
}
.mutate .body {
  position: relative; z-index: 2; padding: clamp(1.8rem, 4vw, 3rem);
  background: linear-gradient(to right, rgba(9,26,25,.95) 45%, rgba(9,26,25,.72));
  display: flex; gap: 2rem; align-items: center; flex-wrap: wrap;
}
.mutate img { width: 92px; height: auto; }
.mutate h2 { margin-bottom: .3rem; }
.btn {
  display: inline-block; margin-top: 1rem; background: var(--gold); color: #102a29;
  padding: .7rem 1.4rem; border-radius: 8px; font-weight: 700; text-decoration: none;
}
.btn:hover { filter: brightness(1.08); }
/* Artwork under the Tavern button. Two classes deep because `.mutate img` sets
   width:92px for the barrel beside it and would otherwise win the tie. */
.mutate .tavern-banner {
  width: 100%; max-width: 560px; height: auto; display: block; margin-top: 1.3rem;
  border-radius: 9px; background: #0b1615; border: 1px solid rgba(207,227,223,.14);
}

/* ---------------------------------------------------------- mutant sea */
.mutant-sea {
  position: relative; width: 100%; overflow: hidden;
  background: url('../img/bg-min.webp') 50% 42% / cover no-repeat #16302f;
  display: grid; place-items: end center;
  min-height: clamp(420px, 60svh, 760px);
}
.mutant-sea::before,
.mutant-sea::after {
  content: ''; position: absolute; left: 0; right: 0; pointer-events: none; z-index: 1;
}
.mutant-sea::before {
  top: 0; height: 26%;
  background: linear-gradient(to bottom, var(--deep), transparent);
}
.mutant-sea::after {
  bottom: 0; height: 20%;
  background: linear-gradient(to top, var(--deep), transparent);
}
.mutant-sea img {
  position: relative; z-index: 2; display: block;
  width: min(72%, 660px); height: auto; margin-bottom: 4%;
  filter: drop-shadow(0 14px 40px rgba(0,0,0,.6));
}
@media (max-aspect-ratio: 3/4) {
  .mutant-sea img { width: min(88%, 460px); }
}

/* --------------------------------------------------------- deck of cards */
/* The home page's index of the rest of the site. */
.decks { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.deck {
  display: flex; flex-direction: column; text-decoration: none; color: inherit;
  background: rgba(255,255,255,.035); border: 1px solid rgba(207,227,223,.14);
  border-radius: 12px; padding: 1.4rem 1.5rem;
  transition: border-color .15s, background .15s, transform .15s;
}
.deck:hover {
  border-color: rgba(255,255,255,.45); background: rgba(255,255,255,.07);
  transform: translateY(-2px);
}
.deck h3 {
  font-family: 'Treasuremap', Georgia, serif; font-weight: 400; font-size: 1.5rem;
  margin: 0 0 .3rem; color: var(--parch);
}
.deck p { color: var(--dim); font-size: .92rem; margin: 0; }
.deck .more {
  margin-top: .9rem; color: var(--gold); font-size: .8rem;
  letter-spacing: .09em; text-transform: uppercase;
}

/* ------------------------------------------------------ pirate council */
/* Three across on a full-width page, so nine members land as a clean 3×3 and
   each portrait gets the whole card rather than a 104px badge. */
.council { display: grid; gap: .9rem; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.member {
  background: rgba(255,255,255,.035); border: 1px solid rgba(207,227,223,.14);
  border-radius: 12px; padding: 1.3rem 1rem 1.15rem; text-align: center; min-width: 0;
  display: flex; flex-direction: column;
}
.member img {
  /* Portraits are 741–1024px square now, so the old 340px cap is gone and the
     image fills the card. 420 still leaves 2.4x for a retina phone. */
  width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; display: block;
  max-width: 420px; border-radius: 10px; margin: 0 auto .9rem;
  border: 1px solid rgba(255,255,255,.18); background: #0b1615;
}
.member h3 {
  font-family: 'Treasuremap', Georgia, serif; font-weight: 400; font-size: 1.28rem;
  margin: 0 0 .3rem; color: var(--parch);
}
.member p { color: var(--dim); font-size: .85rem; margin: 0 0 .85rem; }
.mlinks {
  display: flex; align-items: center; justify-content: center; gap: .6rem;
  flex-wrap: wrap; margin-top: auto; padding-top: .1rem;
}
.xlink {
  display: grid; place-items: center; width: 32px; height: 32px; flex: none;
  border: 1px solid rgba(207,227,223,.16); border-radius: 999px; color: var(--foam);
  background: rgba(255,255,255,.03); transition: color .15s, border-color .15s, background .15s;
}
.xlink:hover { color: var(--gold); border-color: rgba(255,255,255,.5); background: rgba(255,255,255,.1); }
.xlink:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.xlink .ico { width: 15px; height: 15px; }

/* --------------------------------------------------------- ship's log */
.log-shots { display: grid; grid-template-columns: 1fr 1fr; gap: .55rem; margin-top: 1rem; }
.log-shots img {
  width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; display: block;
  border-radius: 8px; border: 1px solid rgba(207,227,223,.12); background: #0b1615;
}
.timeline .card h3 { font-size: 1.42rem; margin-bottom: .3rem; }
.timeline .card p { color: var(--dim); font-size: .93rem; margin: .5rem 0 0; }
.timeline .card p a { text-decoration: none; }
.timeline .card p a:hover { text-decoration: underline; }

/* ------------------------------------------------------------- footer */
footer {
  border-top: 1px solid rgba(207,227,223,.12);
  padding: 2.5rem clamp(1rem, 5vw, 3rem) 3.5rem;
  background: #0a1818;
}
/* Sits under the contract list — the page links are already in the header. */
.social { margin-bottom: 1.8rem; }
.social a { width: 38px; height: 38px; }
.social .ico { width: 20px; height: 20px; }
.contracts { display: grid; gap: .45rem; margin: 0 0 1.6rem; }
.contracts div { font-size: .82rem; color: var(--dim); }
.contracts span { color: var(--foam); }
.contracts code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .78rem; word-break: break-all;
}
.fine { color: #6d8380; font-size: .8rem; line-height: 1.9; }

@media (max-width: 640px) {
  .timeline::before { left: 21px; }
  .timeline > li { padding-left: 3.5rem; }
  .timeline > li::before { left: 16px; top: 2.75rem; }
  .tl-when { width: 44px; font-size: .95rem; top: .35rem; }
  .tl-when span { font-size: .58rem; letter-spacing: .06em; }
  .clogo { width: 48px; height: 48px; }
  .chead h3 { font-size: 1.2rem; }
  .mutate .body { gap: 1.1rem; }
  .mutate img { width: 64px; }
}

.soon { color: var(--dim); font-style: italic; margin: .9rem 0 0; }

/* ========================================================== the registry */
/* Look up one id and see both halves of it. The art is the point, so the
   furniture around it stays quiet: no panel gets a border the artwork has to
   compete with, and nothing is tinted over the renders themselves. */

.reg-search { display: flex; gap: .6rem; flex-wrap: wrap; align-items: stretch; }
.reg-field {
  position: relative; flex: 1 1 220px; min-width: 0; display: flex; align-items: center;
}
/* The hash is decoration, so it is drawn rather than typed — a '#' the field
   accepted but had to strip is a small trap for anyone pasting an id. */
.reg-field::before {
  content: '#'; position: absolute; left: .95rem; color: var(--dim);
  font-size: 1.35rem; pointer-events: none;
}
.reg-field input {
  width: 100%; padding: .8rem 1rem .8rem 2.2rem;
  background: rgba(255,255,255,.05); color: var(--ink);
  border: 1px solid rgba(207,227,223,.22); border-radius: 9px;
  font: inherit; font-size: 1.35rem; font-variant-numeric: tabular-nums;
  -moz-appearance: textfield;
}
.reg-field input::-webkit-outer-spin-button,
.reg-field input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.reg-field input:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }

.reg-btn {
  font: inherit; font-weight: 700; cursor: pointer; white-space: nowrap;
  padding: .8rem 1.3rem; border-radius: 9px;
  background: var(--gold); color: #102a29; border: 1px solid transparent;
}
.reg-btn.ghost {
  background: rgba(255,255,255,.05); color: var(--foam);
  border-color: rgba(207,227,223,.22); font-weight: 600;
}
.reg-btn:hover:not(:disabled) { filter: brightness(1.08); }
.reg-btn.ghost:hover:not(:disabled) {
  background: rgba(255,255,255,.11); border-color: rgba(255,255,255,.5); color: var(--gold);
}
.reg-btn:disabled { opacity: .38; cursor: default; }
.reg-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.reg-err { color: #f0a58a; font-size: .88rem; margin: .7rem 0 0; }
.reg-empty { color: var(--dim); margin: 1.4rem 0 0; max-width: 60ch; }

/* ------------------------------------------------------------ the stage */
.reg-stage { --wipe: 50%; margin-top: 1.6rem; }
.reg-head {
  display: flex; gap: .7rem 1rem; align-items: baseline; flex-wrap: wrap;
  margin-bottom: .9rem;
}
.reg-head h2 { margin: 0; font-size: clamp(1.6rem, 4vw, 2.4rem); }
.reg-tools { margin-left: auto; display: flex; gap: .4rem; flex-wrap: wrap; }
.reg-tools .reg-btn { padding: .45rem .85rem; font-size: .82rem; font-weight: 600; }
.reg-tools .reg-btn[aria-pressed="true"] {
  background: rgba(255,255,255,.16); color: var(--gold); border-color: rgba(255,255,255,.5);
}

.reg-compare {
  position: relative; width: 100%; aspect-ratio: 1; overflow: hidden;
  border-radius: 14px; background: #0b1615; touch-action: pan-y;
  border: 1px solid rgba(207,227,223,.14); cursor: ew-resize; user-select: none;
}
.reg-compare img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block; -webkit-user-drag: none;
}
.reg-stage[data-view="wipe"] #reg-img-mut { clip-path: inset(0 0 0 var(--wipe)); }

/* The seam. Its own element rather than a border on the clip, because a
   clip-path edge cannot be given a colour. */
.reg-handle {
  position: absolute; top: 0; bottom: 0; left: var(--wipe);
  width: 2px; margin-left: -1px; background: rgba(255,255,255,.85);
  box-shadow: 0 0 12px rgba(0,0,0,.55); cursor: ew-resize;
}
.reg-handle::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 42px; height: 42px; margin: -21px 0 0 -21px; border-radius: 50%;
  background: rgba(10,24,24,.72); border: 2px solid rgba(255,255,255,.85);
  backdrop-filter: blur(2px);
}
/* Two chevrons drawn on the knob, so it reads as draggable standing still. */
.reg-handle span {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  z-index: 2; color: #fff; font-size: .92rem; letter-spacing: .1em; line-height: 1;
}
.reg-handle:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
/* A dashed seam whenever the right-hand half does not exist yet. */
.reg-stage.unmutated .reg-handle {
  background: repeating-linear-gradient(to bottom,
    rgba(255,255,255,.9) 0 9px, transparent 9px 17px);
}

.reg-tag {
  position: absolute; top: .8rem; z-index: 3; pointer-events: none;
  display: flex; gap: .45rem; align-items: center; flex-wrap: wrap;
  font-size: .7rem; letter-spacing: .11em; text-transform: uppercase; font-weight: 700;
}
.reg-tag.a { left: .8rem; }
.reg-tag.b { right: .8rem; justify-content: flex-end; }
.reg-tag i {
  font-style: normal; background: rgba(10,24,24,.72); color: var(--foam);
  padding: .3rem .55rem; border-radius: 5px; backdrop-filter: blur(2px);
}
.reg-badge { padding: .3rem .55rem; border-radius: 5px; backdrop-filter: blur(2px); }
.reg-badge.is-mutated { background: rgba(10,24,24,.72); color: var(--foam); }
.reg-badge.is-open { background: #d9663f; color: #150807; }

/* Side by side. The images stop being stacked layers and become two panels;
   everything positioned against the container keeps working because the tags
   were already pinned to its corners. */
.reg-stage[data-view="pair"] .reg-compare {
  display: grid; grid-template-columns: 1fr 1fr; gap: .55rem;
  aspect-ratio: 2 / 1; background: none; border: 0; cursor: default; overflow: visible;
}
.reg-stage[data-view="pair"] .reg-compare img {
  position: static; clip-path: none; border-radius: 12px;
  background: #0b1615; border: 1px solid rgba(207,227,223,.14);
}
.reg-stage[data-view="pair"].unmutated #reg-img-mut {
  border: 1px dashed rgba(217,102,63,.75);
}
.reg-stage[data-view="pair"] .reg-handle { display: none; }
@media (max-width: 620px) {
  .reg-stage[data-view="pair"] .reg-compare {
    grid-template-columns: 1fr; aspect-ratio: 1 / 2; gap: .5rem;
  }
}

/* ----------------------------------------------------------- the status */
.reg-status {
  display: grid; gap: 1.2rem; margin-top: 1.2rem;
  grid-template-columns: minmax(0, 1.65fr) minmax(0, 1fr);
}
@media (max-width: 760px) { .reg-status { grid-template-columns: minmax(0, 1fr); } }
.reg-status p { margin: 0; color: var(--dim); font-size: .95rem; }
.reg-status p strong { color: var(--parch); }
.reg-owners { display: grid; gap: .5rem; align-content: start; }
.reg-owners div {
  display: flex; justify-content: space-between; gap: 1rem;
  font-size: .88rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  border-bottom: 1px solid rgba(207,227,223,.1); padding-bottom: .45rem;
}
.reg-owners span {
  color: var(--dim); font-family: ui-sans-serif, system-ui, sans-serif;
  letter-spacing: .05em; text-transform: uppercase; font-size: .72rem;
}
.reg-owners a { text-decoration: none; }
.reg-owners a:hover { text-decoration: underline; }
.reg-nil { color: #6d8380; }

/* Marketplace links for both halves, side by side under the art. */
.reg-links { display: flex; gap: 1.4rem; flex-wrap: wrap; margin-top: 1.2rem; }
.reg-links > div { display: flex; gap: .55rem; align-items: center; }
.reg-links b {
  font-weight: 600; color: var(--dim); font-size: .74rem;
  letter-spacing: .08em; text-transform: uppercase;
}

.reg-note { color: var(--dim); font-size: .9rem; margin: 0 0 1rem; max-width: 74ch; }
.reg-note strong { color: var(--parch); }
.reg-warn { color: #f0a58a; font-size: .9rem; }

/* ----------------------------------------------------------- the traits */
/* Reuses .ledger so the table matches the Rum Club table. Only the change
   column is new: it is the whole reason to show both lists together. */
.reg-traits { min-width: 520px; }
.reg-traits .reg-arrow { color: #5f7773; width: 1.6rem; text-align: center; padding: 0; }
.reg-traits .reg-mark {
  font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; color: var(--dim);
}
.reg-traits tr.m-kept td:nth-child(2),
.reg-traits tr.m-kept td:nth-child(4) { color: var(--foam); }
.reg-traits tr.m-gone td:nth-child(2) { color: var(--dim); text-decoration: line-through; }
.reg-traits tr.m-gone td:nth-child(4) { color: #5f7773; }
.reg-traits tr.m-gone .reg-mark { color: #8a9c98; }
.reg-traits tr.m-changed td:nth-child(4),
.reg-traits tr.m-new td:nth-child(4) { color: #eaa085; }
.reg-traits tr.m-changed .reg-mark,
.reg-traits tr.m-new .reg-mark { color: #d9663f; }

/* ------------------------------------------------------- the rum ceiling */
/* What is left to drink, which is the real cap on the Sea Mutants. Narrower
   than the Rum Club's ledger — three columns, one of them a single number. */
.reg-rum { min-width: 420px; }
.reg-rum .reg-total th, .reg-rum .reg-total td {
  border-top: 1px solid rgba(207,227,223,.28); border-bottom: 0;
  padding-top: .75rem; color: var(--parch); font-weight: 700;
}
.reg-rum .retired-row .portion img { filter: saturate(.55); opacity: .7; }

/* --------------------------------------------------------------- the map */
/* 5,700 cells on a canvas. Every alternative — a paginated gallery, an
   infinite scroller — answers "is #1000 free" but not "how much is left",
   and the second question is the one people actually arrive with. */
.reg-map-wrap { position: relative; margin-top: 1.4rem; line-height: 0; }
#reg-map { display: block; cursor: pointer; touch-action: manipulation; }
.reg-map-tip {
  position: absolute; z-index: 5; pointer-events: none;
  transform: translate(-50%, -160%); white-space: nowrap;
  background: rgba(6,16,16,.94); border: 1px solid rgba(207,227,223,.2);
  border-radius: 6px; padding: .3rem .55rem; line-height: 1.3;
  font-size: .78rem; font-variant-numeric: tabular-nums; color: var(--foam);
}
.reg-key { display: flex; gap: 1.2rem; flex-wrap: wrap; margin: 1rem 0 0; }
.reg-key span {
  display: flex; align-items: center; gap: .45rem;
  color: var(--dim); font-size: .82rem;
}
.reg-key i { width: 11px; height: 11px; border-radius: 2px; flex: none; }
.reg-key i.free { background: rgba(244,227,195,.78); }
.reg-key i.done { background: rgba(207,227,223,.22); }
.reg-key i.here { background: transparent; box-shadow: inset 0 0 0 2px #d9663f; }

/* ---------------------------------------------------------- the lightbox */
.reg-zoom {
  position: fixed; inset: 0; z-index: 100; display: grid; place-items: center;
  gap: .8rem; padding: clamp(1rem, 4vw, 3rem); background: rgba(4,11,11,.95);
  grid-template-rows: 1fr auto;
}
.reg-zoom[hidden] { display: none; }
.reg-zoom img {
  max-width: 100%; max-height: 100%; width: auto; height: auto;
  border-radius: 10px; display: block; object-fit: contain;
}
.reg-zoom figcaption {
  color: var(--dim); font-size: .85rem; letter-spacing: .05em; text-align: center;
}
#reg-zoom-close {
  position: absolute; top: 1rem; right: 1rem; width: 44px; height: 44px;
  display: grid; place-items: center; font-size: 1.5rem; line-height: 1;
  border-radius: 50%; cursor: pointer; color: var(--foam);
  background: rgba(255,255,255,.07); border: 1px solid rgba(207,227,223,.22);
}
#reg-zoom-close:hover { color: var(--gold); border-color: rgba(255,255,255,.5); }
