/* Glimmerstone design system: Y2K candy revival. Chunky ink outlines, sticker cards with hard offset shadows,
   glossy pill buttons, per-land sky gradients. Reuse these classes; don't invent new ones for the same job:
   .card .btn .btn-alt .btn-small .btn-big .btn-danger .btn-row .grid(.grid-items/.grid-pets/.grid-2/.grid-3)
   .item-tile .pet-card .stat-bar .pill .flash .table .muted .lede .empty .head-row .hint */

:root {
  --ink: #2a1b4a;          /* outlines + body text */
  --muted: #5d5280;        /* secondary text, AA on white */
  --paper: #f4efff;        /* page */
  --card: #ffffff;
  --tint: #faf6ff;         /* table stripes, inset panels */
  --pink: #ff4f9a;
  --sun: var(--sun);
  --sky: #3fb8ff;
  --lime: #8fe03c;
  --grape: #7a4fe0;
  --link: #0a7a73;         /* deep lagoon teal, AA on white and paper; not pet-site purple */
  --ok-bg: #dcffe8;
  --hi: #eedcff;           /* selected, highlighted, "yours": glimmer lilac, not pet-site yellow */
  --hi-soft: #f8f0ff;      /* callouts, unread rows */
  --pick: #c9b3ff;         /* the current tab / pressed toggle */
  --tint-2: #ece5fb;       /* insets, bar tracks, locked things */
  --rule: #d8cdf3;         /* dashed dividers, table row lines */
  --price: #b3246a;        /* prices and jackpots, AA on white */
  --gain: #1f7a35;
  --loss: #b0243f;
  --err-bg: #ffe1e8;
  --land-from: #ffd6f0;
  --land-to: #bfe6ff;
  --land-accent: #e8338a;
  --page-ink: var(--ink);  /* text that sits straight on the page background */
  --night: #2e2452;         /* dark-land surface: the page background under .land-dark */
  --sun-soft: #fff5b0;     /* pale sun: highlight fills, sheens */
  --sun-glow: #ffe680;     /* warm sun: glowing tags, stars, flares */
  --sun-cream: #fff6c2;    /* creamy yellow: notes, paper, soft callouts */
  --pink-soft: #ffdcee;    /* pale pink: quest badges, tinted plates */
  --sky-soft: #dcf3ff;     /* pale sky: shop badges, water tints */
  --parchment: #fdf7e4;    /* aged paper: keepsakes, notes, scrapbook pages */

  /* One-off palette for component art in this file (sky charms, buttons, stat fills), named by role */
  --ui-sky-day-bg: #7fd3ff;
  --ui-sky-day-bg-2: #d6f3ff;
  --ui-sky-dusk-bg: #ff9fc9;
  --ui-sky-dusk-bg-2: #ffd98a;
  --ui-sky-dusk-ink: #6fbf3a;
  --ui-sky-night-bg: #24175e;
  --ui-sky-night-bg-2: #5b3fa6;
  --ui-sky-night-ink: #2f6b3a;
  --ui-btn-alt-b2: #c9f5e4;
  --ui-btn-danger-b1: #ffd0d8;
  --ui-btn-danger-b2: #ff8fa5;
  --ui-pill-sick-bg: #ffe1a8;
  --ui-event-banner-bg: #d9d0ff;
  --ui-ad-bg: #fffff0;
  --ui-stat-hunger-fill: #ffa63d;
  --ui-stat-hp-fill: #3fcf6a;
  --ui-stat-glow-fill: #7fe3f5;
  --ui-land-dark-bg: #180e30;
  --ui-townsfolk-bg: #d8f3ea;

  --line: 3px;
  --r-card: 22px;
  --r-tile: 16px;
  --shadow: 6px 6px 0 var(--ink);
  --shadow-sm: 3px 3px 0 var(--ink);
  --shadow-lift: 5px 5px 0 var(--ink);   /* --shadow-sm tiles on hover */
  --ease-out: cubic-bezier(.2, .8, .3, 1);
  --fs-xs: .82rem;              /* pills, captions, labels */
  --fs-sm: .94rem;         /* secondary text; stays >= 15px */
  --r-sm: 12px;            /* insets, chips inside cards */
  --display: 'Fredoka', 'Nunito', system-ui, sans-serif;
  --body: 'Nunito', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --gap: 18px;
  --gap-sm: 10px;
}

.land-dark {
  --paper: var(--night);
  --page-ink: #f4ecff;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font: 400 16px/1.55 var(--body);
  color: var(--ink);
  background-color: var(--paper);
  background-image:
    radial-gradient(circle at 20% 30%, color-mix(in oklab, var(--land-accent) 18%, transparent) 0 1.5px, transparent 2.5px),
    radial-gradient(circle at 70% 80%, color-mix(in oklab, var(--grape) 16%, transparent) 0 1.5px, transparent 2.5px);
  background-size: 46px 46px, 64px 64px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
img, svg { max-width: 100%; }
a { color: var(--link); text-decoration-thickness: 2px; text-underline-offset: 3px; }
a:hover { color: var(--pink); }
:focus-visible { outline: 3px solid var(--sky); outline-offset: 3px; border-radius: 6px; }
h1, h2, h3 { font-family: var(--display); line-height: 1.15; margin: 0 0 .5em; letter-spacing: .005em; text-wrap: balance; overflow-wrap: anywhere; } /* long usernames ("the_real_glimmerlord's keepsakes") break instead of widening the page */
h1 { font-size: clamp(1.8rem, 1.3rem + 2vw, 2.5rem); font-weight: 700; }
h2 { font-size: 1.45rem; font-weight: 600; }
h3 { font-size: 1.15rem; font-weight: 600; }
p { margin: 0 0 .8em; text-wrap: pretty; }
code { font-size: .9em; background: var(--tint); padding: .1em .35em; border-radius: 6px; }
.muted { color: var(--muted); }
.lede { font-size: 1.12rem; max-width: 62ch; }
.skip { position: absolute; left: -999px; top: 8px; z-index: 10; background: var(--sun); padding: 8px 14px; border: var(--line) solid var(--ink); border-radius: 999px; }
.skip:focus { left: 8px; }

/* ---------- Header ---------- */
.site-head {
  position: relative;
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 14px clamp(16px, 3vw, 32px) 18px;
  background:
    radial-gradient(circle at 12% 30%, #fff 0 2px, transparent 3px),
    radial-gradient(circle at 80% 20%, #fff 0 1.5px, transparent 2.5px),
    radial-gradient(circle at 55% 75%, #fff 0 1.5px, transparent 2.5px),
    linear-gradient(115deg, var(--land-from), var(--land-to));
  background-size: 120px 80px, 90px 70px, 150px 90px, auto;
  border-bottom: var(--line) solid var(--ink);
}
/* SVG logo: paint-order puts every glyph's outline under every fill, so thick strokes never cover the neighbouring letter */
.logo { display: inline-flex; text-decoration: none; filter: drop-shadow(0 4px 0 var(--ink)); }
.logo svg { height: clamp(44px, 34px + 2vw, 58px); width: auto; overflow: visible; }
.logo text { font: 700 60px var(--display); letter-spacing: -.5px; stroke: var(--ink); stroke-width: 7px; stroke-linejoin: round; paint-order: stroke fill; }
.logo:hover { filter: drop-shadow(0 4px 0 var(--ink)) brightness(1.05); }
.land-chip {
  font: 600 var(--fs-sm) var(--display);
  padding: 4px 14px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: color-mix(in oklab, var(--land-accent) 18%, #fff);
  color: var(--ink);
  text-decoration: none;
  box-shadow: var(--shadow-sm);
}
.land-dark .land-chip { background: var(--land-accent); }
.who { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.who form { margin: 0; }
/* Account menu: the avatar opens a small panel (a native <details>) */
.account { position: relative; }
.account summary { list-style: none; cursor: pointer; display: block; border: 2px solid var(--ink); border-radius: 50%; background: #fff; box-shadow: var(--shadow-sm); }
.account summary::-webkit-details-marker { display: none; }
.account summary svg { display: block; border-radius: 50%; }
.account[open] summary { background: var(--pick); }
.account-panel {
  position: absolute; right: 0; top: calc(100% + 10px); z-index: 30; width: 220px; padding: 8px; display: grid; gap: 2px;
  background: var(--card); border: var(--line) solid var(--ink); border-radius: var(--r-sm); box-shadow: var(--shadow-sm);
}
.account-panel a, .account-panel button {
  display: grid; width: 100%; padding: 8px 12px; text-align: left; font: 600 1rem var(--display); color: var(--ink);
  text-decoration: none; background: none; border: 0; border-radius: 8px; cursor: pointer; overflow-wrap: anywhere;
}
.account-panel small { font: 400 var(--fs-xs) var(--body); color: var(--muted); }
.account-panel a:hover, .account-panel button:hover { background: var(--hi); color: var(--ink); }
.account-panel form { margin: 0; padding-top: 4px; border-top: 2px dashed var(--rule); }
/* Header status cluster: coins, mail, bell and the sky clock, all 40px pills */
.charms { display: flex; align-items: center; gap: 8px; }
.charm { display: inline-flex; align-items: center; gap: 3px; min-width: 40px; min-height: 40px; justify-content: center; padding: 0 8px; color: var(--ink); text-decoration: none; background: #fff; border: 2px solid var(--ink); border-radius: 999px; box-shadow: var(--shadow-sm); font: 700 .95rem var(--display); }
.charm.has-new { background: var(--sun); }
.charm:hover { color: var(--ink); background: var(--hi); }
.sky-charm { display: block; flex: none; width: 58px; height: 40px; border: 2px solid var(--ink); border-radius: 999px; overflow: hidden; box-shadow: var(--shadow-sm); cursor: help; }
.sky-charm svg { display: block; }
.sky-day { background: linear-gradient(var(--ui-sky-day-bg), var(--ui-sky-day-bg-2)); color: var(--lime); }
.sky-dusk { background: linear-gradient(var(--ui-sky-dusk-bg), var(--ui-sky-dusk-bg-2)); color: var(--ui-sky-dusk-ink); }
.sky-night { background: linear-gradient(var(--ui-sky-night-bg), var(--ui-sky-night-bg-2)); color: var(--ui-sky-night-ink); }

/* ---------- Nav ---------- */
/* Sticker tabs hanging off the header's bottom edge, tinted with the land's accent. */
.site-nav { padding: 0 clamp(16px, 3vw, 32px); display: flex; align-items: flex-start; gap: 16px; }
.site-nav ul { list-style: none; margin: 0; padding: 0 4px 8px; display: flex; gap: 8px; overflow-x: auto; scrollbar-width: thin; flex: 1; min-width: 0; }
.site-nav a {
  display: block; white-space: nowrap;
  padding: 8px 14px 8px;
  font: 600 1rem var(--display); color: var(--ink); text-decoration: none;
  background: color-mix(in oklab, var(--land-accent) 14%, #fff);
  border: var(--line) solid var(--ink); border-top: 0; border-radius: 0 0 14px 14px;
  box-shadow: var(--shadow-sm);
}
.site-nav a:hover { color: var(--ink); background: #fff; }
.site-nav a[aria-current="page"] { background: var(--pick); }
.site-nav a:focus-visible { outline-offset: -4px; } /* the tab row scrolls (overflow), which would clip an outside ring */

/* ---------- Page body ---------- */
.site-body {
  flex: 1;
  width: 100%; max-width: 1180px; margin: 0 auto;
  padding: 16px clamp(16px, 3vw, 32px) 40px;
}
/* Signed in: the pet panel (after <main> in the DOM) sits in a left column; below 1000px it's a strip above the content. */
.has-side { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--gap); align-content: start; }
.has-side > .pet-panel { order: -1; }
/* Desktop width. --page-max caps .site-body, and the header and nav rows are padded in to the same edge so the logo, nav tabs and coins line up
   with the content column instead of hugging the window edges. Wide monitors (1700px+) get 1480px: 1320px left 300px empty either side at 1920. */
:root { --page-max: 1320px; }
@media (min-width: 1700px) { :root { --page-max: 1480px; } }
@media (min-width: 1000px) {
  .site-head, .site-nav { padding-inline: max(clamp(16px, 3vw, 32px), calc((100% - var(--page-max)) / 2 + 28px)); }
  .site-body { max-width: var(--page-max); }
  .has-side { grid-template-columns: 232px minmax(0, 1fr); align-items: start; }
  .has-side > .pet-panel { grid-column: 1; grid-row: 1; position: sticky; top: 16px; max-height: calc(100vh - 32px); overflow-y: auto; } /* short windows: the switcher stays reachable */
  .has-side > main { grid-column: 2; grid-row: 1; }
}
main { min-width: 0; display: grid; gap: var(--gap); align-content: start; }
main > h1, main > p { color: var(--page-ink); }

/* ---------- Cards ---------- */
.card {
  background: var(--card);
  border: var(--line) solid var(--ink);
  border-radius: var(--r-card);
  box-shadow: var(--shadow);
  padding: clamp(16px, 2.4vw, 24px);
  min-width: 0;
}
.card > :last-child { margin-bottom: 0; }
.head-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: .6em; }
.head-row h1, .head-row h2 { margin: 0; }
.empty { text-align: center; padding: 18px 8px; color: var(--muted); }
.empty .btn { margin-top: 6px; }
.empty .btn-row { justify-content: center; margin-top: 6px; }
.hint { background: var(--tint); border: 2px dashed color-mix(in oklab, var(--grape) 50%, #fff); border-radius: var(--r-sm); padding: 8px 12px; }

/* ---------- Buttons ---------- */
.btn {
  --b1: #f1e6ff; --b2: #a98bff; /* glimmer shimmer */
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 6px; text-align: center; /* a label that wraps ("Season 2 (locked)") stays centred */
  min-height: 44px; padding: 8px 24px;
  font: 600 1.02rem/1.1 var(--display); color: var(--ink); text-decoration: none; cursor: pointer;
  background: linear-gradient(180deg, var(--b1), var(--b2));
  border: var(--line) solid var(--ink); border-radius: 999px;
  box-shadow: 0 4px 0 var(--ink);
  transition: transform .08s, box-shadow .08s, filter .15s;
}
.btn::before { /* the gloss */
  content: ''; position: absolute; left: 12px; right: 12px; top: 3px; height: 38%;
  border-radius: 999px; background: linear-gradient(180deg, rgb(255 255 255 / .85), rgb(255 255 255 / .1));
  pointer-events: none;
}
@media (hover: hover) and (pointer: fine) { /* touch keeps no sticky hover */
  .btn:hover { color: var(--ink); filter: brightness(1.05) saturate(1.1);
    background: linear-gradient(115deg, color-mix(in srgb, var(--pink) 20%, transparent), transparent 45%, color-mix(in srgb, var(--sky) 22%, transparent)), linear-gradient(180deg, var(--b1), var(--b2)); } /* glimmerstone sheen */
}
.btn:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--ink); }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; box-shadow: 0 4px 0 var(--ink); }
.btn-alt { --b1: #ffffff; --b2: var(--ui-btn-alt-b2); }
.btn-danger { --b1: var(--ui-btn-danger-b1); --b2: var(--ui-btn-danger-b2); }
.btn-small { min-height: 36px; padding: 6px 14px; font-size: var(--fs-sm); box-shadow: 0 3px 0 var(--ink); }
.btn-small:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--ink); }
.btn-big { min-height: 54px; padding: 12px 32px; font-size: 1.2rem; }
.btn-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.btn-row form { margin: 0; }
.card > form.btn-row + p { margin-top: 12px; } /* a note under a lone action button */

/* ---------- Pills, flash, events ---------- */
.pill {
  display: inline-block; padding: 2px 12px;
  font: 600 var(--fs-xs)/1.5 var(--display);
  background: color-mix(in oklab, var(--land-accent) 14%, #fff);
  border: 2px solid var(--ink); border-radius: 999px; margin: 0;
}
.pill-sick { background: var(--ui-pill-sick-bg); }
.flash {
  border: var(--line) solid var(--ink); border-radius: var(--r-tile);
  padding: 12px 16px 12px 48px; position: relative; font-weight: 700;
  background: var(--ok-bg); box-shadow: var(--shadow-sm);
}
.flash::before { content: '✓'; position: absolute; left: 14px; top: 10px; font: 700 1.2rem var(--display); }
.flash-err { background: var(--err-bg); }
/* Delight: a pet's mood went up -> the flash badge becomes a heart and throws a little sparkle ring (so does the pet on its own page) */
.flash-joy { background: linear-gradient(110deg, var(--ok-bg), var(--hi) 80%); }
.flash-joy::before { content: '♥'; left: 15px; color: var(--pink); }
.flash-joy::after, .pet-joy .pet-profile-art::after {
  content: ''; position: absolute; left: 21px; top: 23px; width: 6px; height: 6px; margin: -3px; border-radius: 50%;
  pointer-events: none; opacity: 0; animation: sparkle-ring .75s var(--ease-out) .1s;
  box-shadow: 0 -18px var(--sun), 13px -13px var(--pink), 18px 0 var(--sky), 13px 13px var(--sun), 0 18px var(--pink), -13px 13px var(--sky), -18px 0 var(--sun), -13px -13px var(--pink);
}
.pet-joy .pet-profile-art::after {
  left: 50%; top: 45%; width: 12px; height: 12px; margin: -6px;
  box-shadow: 0 -80px var(--sun), 57px -57px var(--pink), 80px 0 var(--sky), 57px 57px var(--sun), 0 80px var(--pink), -57px 57px var(--sky), -80px 0 var(--sun), -57px -57px var(--pink);
}
.pet-joy .pet-profile-art > svg { animation: joy-hop .6s var(--ease-out) .1s; }
@keyframes sparkle-ring { from { opacity: 1; transform: scale(.35); } 55% { opacity: 1; } to { opacity: 0; transform: scale(1.5); } }
@keyframes joy-hop { 35% { transform: translateY(-14px); } }
.flash-err::before { content: '!'; left: 20px; }
.event-banner {
  position: relative;
  border: var(--line) solid var(--ink); border-radius: var(--r-card);
  padding: 16px 20px 14px 80px;
  background:
    radial-gradient(circle at 92% 25%, #fff 0 2px, transparent 3px),
    radial-gradient(circle at 80% 75%, #fff 0 1.5px, transparent 2.5px),
    linear-gradient(110deg, var(--sun-soft), var(--pink-soft) 55%, var(--ui-event-banner-bg));
  box-shadow: var(--shadow);
  animation: pop-in .5s cubic-bezier(.2, 1.6, .4, 1) both;
}
.event-banner::before {
  content: '★'; position: absolute; left: 16px; top: 50%; translate: 0 -50%;
  width: 46px; height: 46px; display: grid; place-items: center;
  font-size: 1.6rem; color: var(--ink); background: var(--sun);
  border: var(--line) solid var(--ink); border-radius: 50%;
}
.event-banner b { font: 700 1.25rem var(--display); display: block; }
.event-banner p { margin: 2px 0 0; font-weight: 600; }
@keyframes pop-in { from { transform: scale(.85); opacity: 0; } }
@keyframes bob { to { transform: translateY(-6px); } } /* sprites and pocket critters */

/* ---------- Coins (header charm) ---------- */
.coins {
  display: inline-flex; align-items: center; min-height: 40px; white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font: 700 1.05rem var(--display); color: var(--ink); text-decoration: none;
  background: linear-gradient(180deg, var(--sun-soft), var(--sun)); border: 2px solid var(--ink); border-radius: 999px; padding: 0 12px;
  box-shadow: var(--shadow-sm);
}
.coins:hover { color: var(--ink); }
/* Money: gl(n) in src/html.js prints <span class="gl">1,234<i></i></span>; the <i> is the glimmer shard (the pets' glim mark). */
.gl { white-space: nowrap; font-variant-numeric: tabular-nums; }
.gl > i {
  display: inline-block; width: .72em; height: .95em; margin-left: .18em; vertical-align: -.12em;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-6 -8 12 15'%3E%3Cpath d='M0 -7L5 -2L3 6L-3 6L-5 -2Z' fill='%238ff0ff' stroke='%232a1b4a' stroke-width='1.4' stroke-linejoin='round'/%3E%3Cpath d='M-5 -2H5M-2 -2L0 6L2 -2' fill='none' stroke='%233fb6d8' stroke-width='.8'/%3E%3Cpath d='M-3.6 -2L0 -5.6L-1.4 -2Z' fill='%23fff'/%3E%3C/svg%3E") center / contain no-repeat;
}
.coins .gl > i { width: .85em; height: 1.1em; }
/* Delight: Glimmers went up since the last page -> the pill pops, the coin flips, the gain floats off (tiny script in layout.js).
   The pill sits in the header, so the gain floats down into the page. */
.coins { position: relative; }
.coins-up { animation: coin-pop .45s var(--ease-out); }
.coins-up .gl > i { animation: coin-flip .7s var(--ease-out); }
.coins-up::after {
  content: attr(data-gain); position: absolute; right: 10px; bottom: -6px; pointer-events: none; opacity: 0;
  font: 700 var(--fs-sm) var(--display); color: var(--gain); text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 -1px 0 #fff;
  animation: coin-rise 1.6s var(--ease-out) .15s;
}
@keyframes coin-pop { 40% { transform: scale(1.07); } }
@keyframes coin-flip { to { transform: rotateY(360deg); } }
@keyframes coin-rise { 12%, 70% { opacity: 1; } to { opacity: 0; transform: translateY(22px); } }

/* ---------- Ad flyer: taped up at the foot of the page content ---------- */
.ad {
  --ad-hue: 300;
  position: relative; justify-self: center; width: min(100%, 620px); margin: 14px 0 4px;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px;
  padding: 18px 20px 16px;
  background: repeating-linear-gradient(135deg, hsl(var(--ad-hue) 100% 97%) 0 12px, hsl(var(--ad-hue) 100% 93%) 12px 24px); /* style-ok: colour computed from a per-element custom property */
  border: 2px solid var(--ink); border-radius: 6px; box-shadow: var(--shadow-sm);
  rotate: -1deg;
}
.ad::before, .ad::after { /* two strips of tape */
  content: ''; position: absolute; top: -11px; width: 70px; height: 22px;
  background: color-mix(in srgb, var(--ui-ad-bg) 70%, transparent); border: 1px solid color-mix(in srgb, var(--ink) 20%, transparent); rotate: -7deg;
}
.ad::before { left: 22px; }
.ad::after { right: 22px; rotate: 5deg; }
.ad > svg { flex: none; }
.ad div { flex: 1 1 240px; min-width: 0; }
.ad small { display: block; font-size: var(--fs-xs); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.ad b { font: 700 1.15rem/1.2 var(--display); }
.ad p { font-size: var(--fs-sm); margin: 2px 0 0; }
.ad .pill { background: hsl(var(--ad-hue) 90% 80%); } /* style-ok: colour computed from a per-element custom property */

/* ---------- Pet panel: a sticky sidebar card on wide screens, a strip above the content below 1000px (see Responsive) ---------- */
.pet-panel {
  display: grid; gap: 12px; padding: 14px; color: var(--ink); align-content: start;
  background: var(--card); border: var(--line) solid var(--ink); border-radius: var(--r-card); box-shadow: var(--shadow);
}
.pet-stage { /* the land-tinted backdrop, with a pedestal ellipse under the pet's feet */
  display: grid; place-items: center; padding: 14px 0 24px; border: 2px solid var(--ink); border-radius: var(--r-sm); position: relative; overflow: hidden;
  background: radial-gradient(ellipse 60% 14% at 50% 86%, color-mix(in oklab, var(--land-accent) 55%, #fff) 0 98%, transparent), linear-gradient(180deg, var(--land-from), var(--land-to));
}
.pet-stage svg { position: relative; display: block; max-width: 100%; height: auto; }
/* The pet's glow (logic/pets.js glowOf): a halo over the pedestal, --glow 0-1. A sick pet's glow flickers, fizzes or storms. */
.pet-stage::before {
  content: ''; position: absolute; left: 50%; bottom: 4%; width: 150px; aspect-ratio: 1; translate: -50% 0; border-radius: 50%;
  background: radial-gradient(circle, rgb(255 250 205 / calc(var(--glow, 0) * .95)) 0 22%, rgb(143 240 255 / calc(var(--glow, 0) * .55)) 48%, transparent 70%); /* style-ok: colour computed from a per-element custom property */
}
.glow-flickery::before { animation: glow-flicker 1.7s steps(1) infinite; }
.glow-fizzy::before { animation: glow-fizz .35s ease-in-out infinite alternate; }
.glow-stormy::before { filter: grayscale(.8) brightness(.8); animation: glow-storm 4s steps(1) infinite; }
@keyframes glow-flicker { 20%, 60% { opacity: .35; } 40%, 80% { opacity: 1; } }
@keyframes glow-fizz { to { scale: 1.08 .94; opacity: .7; } }
@keyframes glow-storm { 88% { filter: none; } 90% { filter: grayscale(.8) brightness(.8); } 93% { filter: none; } }
.reduce-motion .pet-stage::before { animation: none; }
.pet-panel { position: relative; }
.pet-level { /* the level, on a little fallen star in the stage's corner */
  position: absolute; top: 20px; right: 20px; display: grid; place-items: center; width: 34px; height: 34px;
  font: 700 .85rem var(--display); color: var(--ink); background: var(--sun-glow);
  clip-path: polygon(50% 0, 63% 33%, 98% 36%, 71% 58%, 80% 94%, 50% 74%, 20% 94%, 29% 58%, 2% 36%, 37% 33%);
}
.pet-id { text-align: center; }
.pet-id p { margin: 0; font-size: var(--fs-sm); color: var(--muted); }
.pet-name { display: block; font: 700 1.3rem/1.2 var(--display); color: var(--ink); text-decoration: none; overflow-wrap: anywhere; }
.pet-name:hover { color: var(--ink); text-decoration: underline; }
.pet-id .pill-sick { margin-top: 6px; }
.pet-meters { list-style: none; margin: 0; padding: 10px 12px; display: grid; gap: 8px; background: var(--tint); border: 2px solid var(--ink); border-radius: var(--r-sm); }
.pet-meters li { display: grid; grid-template-columns: auto 1fr auto; align-items: center; column-gap: 6px; row-gap: 3px; color: var(--fill); font-size: var(--fs-sm); }
.pet-meters svg path { stroke: var(--ink); }
.pet-meters b { color: var(--ink); font: 700 var(--fs-sm) var(--display); }
.pet-meters span:not(.stat-bar) { color: var(--ink); font-weight: 700; text-align: right; }
.pet-meters .stat-bar { grid-column: 1 / -1; height: 11px; }
.pet-actions { display: grid; gap: 8px; }
.pet-actions .btn { text-align: center; }
.pet-switch { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; padding-top: 10px; border-top: 2px dashed var(--rule); }
.pet-switch { align-items: center; }
.pet-switch small { flex: 1 0 100%; text-align: center; font-weight: 800; color: var(--muted); }
.pet-switch form { margin: 0; }
.pet-switch button { display: block; padding: 0; line-height: 0; cursor: pointer; background: #fff; border: 2px solid var(--ink); border-radius: 50%; box-shadow: var(--shadow-sm); }
.pet-switch button:hover { background: var(--hi); }
.pet-panel-empty { text-align: center; justify-items: center; background: var(--hi-soft); }
.pet-panel-empty b { font: 700 1.2rem var(--display); }
.pet-panel-empty p { margin: 0; }
.land-dark .pet-panel { color: var(--ink); } /* the card stays white in dark lands, so its text stays ink */

/* ---------- Stat bars ---------- */
/* Word + bar rows on pet cards (the name is left over from the old sidebar). */
.side-stats { display: grid; grid-template-columns: auto 1fr; gap: 2px 10px; margin: 10px 0 12px; text-align: left; font-size: var(--fs-sm); }
.side-stats dt { font-weight: 800; }
.side-stats dd { margin: 0; text-align: right; }
.side-stats .stat-bar { grid-column: 1 / -1; margin-bottom: 6px; }
.stat-bar { display: block; height: 13px; border: 2px solid var(--ink); border-radius: 999px; background: var(--tint-2); overflow: hidden; }
.stat-bar > span {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(180deg, rgb(255 255 255 / .55) 0 35%, transparent 36%), var(--fill, var(--lime));
}
.stat-hunger { --fill: var(--ui-stat-hunger-fill); }
.stat-mood { --fill: var(--pink); }
.stat-hp { --fill: var(--ui-stat-hp-fill); }
.stat-xp { --fill: var(--sky); }
.stat-glow { --fill: var(--ui-stat-glow-fill); }

/* ---------- Grids and tiles ---------- */
.grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.grid-items { grid-template-columns: repeat(auto-fill, minmax(124px, 1fr)); }
.grid-pets { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
.grid-species { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 10px; }
.grid-places { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--gap); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--gap); }
.item-tile {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 12px 8px 10px; text-align: center; width: 100%;
  font: inherit; color: var(--ink); text-decoration: none;
  background: #fff; border: 2px solid var(--ink); border-radius: var(--r-tile);
  box-shadow: var(--shadow-sm); cursor: pointer;
}
/* One hover lift for every clickable sticker: tiles, places, lots, daily and game cards */
a.item-tile, button.item-tile, .place, .lot, .daily-card {
  transition: transform .15s var(--ease-out), box-shadow .15s var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  a.item-tile:hover, button.item-tile:hover, .place:hover, .lot:hover { transform: translate(-2px, -2px); box-shadow: var(--shadow-lift); color: var(--ink); }
  a.daily-card:hover { transform: translate(-2px, -2px); box-shadow: 8px 8px 0 var(--ink); color: var(--ink); }
}
a.item-tile:active, button.item-tile:active, .place:active, .lot:active, a.daily-card:active { transform: translate(1px, 1px); box-shadow: 1px 1px 0 var(--ink); }
.item-tile svg { display: block; }
.item-tile b { font-weight: 800; line-height: 1.25; font-size: var(--fs-sm); }
.item-tile small { color: var(--muted); font-size: var(--fs-xs); }
.item-tile .qty { position: absolute; top: 6px; right: 8px; font: 700 var(--fs-xs) var(--display); background: var(--sun); border: 2px solid var(--ink); border-radius: 999px; padding: 0 8px; }
.item-tile .price { font: 700 1rem var(--display); color: var(--price); }
.item-tile form { margin-top: 4px; }
.item-use .btn { margin-top: auto; }
.item-use b { margin-bottom: 6px; }
.item-use { cursor: default; }
.item-cell { display: grid; } /* backpack tiles in a row share one height */

/* Item popover (native [popover], no JS) */
.item-pop { width: min(440px, calc(100vw - 32px)); margin: auto; color: var(--ink); overflow: visible; }
.item-pop::backdrop { background: color-mix(in srgb, var(--ink) 40%, transparent); }
.item-pop-head { display: flex; gap: 14px; align-items: center; margin-bottom: 8px; }
.item-pop-head h3 { margin: 0 0 4px; font-size: 1.35rem; }
.item-pop-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: end; margin-top: 12px; padding-top: 12px; border-top: 2px dashed var(--rule); }
.item-pop-actions label { font-weight: 700; display: grid; font-size: var(--fs-sm); }
.item-pop-actions input { width: 5.5em; }
.pop-close { position: absolute; top: -14px; right: -14px; width: 40px; height: 40px; border-radius: 50%; border: var(--line) solid var(--ink); background: var(--pink); color: #fff; font: 700 1.4rem/1 var(--display); cursor: pointer; box-shadow: 0 3px 0 var(--ink); }

/* ---------- Pet card ---------- */
.pet-card {
  background: #fff; border: var(--line) solid var(--ink); border-radius: var(--r-card);
  box-shadow: var(--shadow-sm); padding: 14px 16px 16px; text-align: center;
  background-image: radial-gradient(ellipse 70% 42% at 50% 30%, color-mix(in oklab, var(--land-from) 70%, #fff), transparent 70%);
}
.pet-card-art { display: block; }
.pet-card-art svg { display: block; margin: 0 auto; }
.pet-card h3 { margin: 4px 0 0; font-size: 1.3rem; }
.pet-card h3 a { color: var(--ink); text-decoration: none; }
.pet-card .muted { margin: 0; }
.pet-card .btn-row { justify-content: center; }
.pet-card-hp { font-size: var(--fs-sm); font-weight: 700; text-align: left; }

/* ---------- Tables ---------- */
.table { width: 100%; border-collapse: separate; border-spacing: 0; border: 2px solid var(--ink); border-radius: var(--r-tile); overflow: hidden; }
.table th, .table td { padding: 10px 12px; text-align: left; vertical-align: middle; }
.table thead th { background: var(--ink); box-shadow: 1px 0 0 var(--ink); color: #fff; /* the shadow covers the hairline seam between fractional-width cells */ font: 600 .98rem var(--display); }
.table tbody tr:nth-child(even) { background: var(--tint); }
.table tbody tr + tr > * { border-top: 1px solid var(--rule); }
.table { font-variant-numeric: tabular-nums; }
.table td:has(> svg:only-child) { width: 1%; } /* item icon columns hug their art */
.table-wrap { overflow-x: auto; position: relative; } /* relative: keeps absolute .visually-hidden labels inside the scroller */
.table-wrap .table { min-width: 460px; }
:where(.card, form) > :is(.grid, .table, .table-wrap) + * { margin-top: 14px; } /* breathing room under a grid or table, before its footer link/buttons */
.table .row-hi { background: var(--hi) !important; font-weight: 800; }
.table svg { display: block; max-width: none; }

/* ---------- Forms ---------- */
label { font-weight: 700; }
:where(input[type=checkbox], input[type=radio]) { accent-color: var(--grape); inline-size: 1.15em; block-size: 1.15em; vertical-align: middle; }
input:not([type=radio], [type=checkbox], [type=hidden]), select, textarea {
  display: block; width: 100%; margin-top: 4px;
  font: 600 1rem var(--body); color: var(--ink);
  padding: 10px 14px; background: #fff;
  border: var(--line) solid var(--ink); border-radius: var(--r-sm);
  box-shadow: inset 0 3px 0 var(--tint-2);
}
select { overflow: hidden; text-overflow: ellipsis; } /* Safari counts a long option's text past the box as page width: the sideways wiggle on phones */
select { -webkit-appearance: none; appearance: none; padding-right: 40px; /* Safari's native menulist ignores padding and draws 31px tall; this one is 44px+ like Chrome's */
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%232a1b4a' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 14px center / 12px 8px; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
fieldset { border: 2px dashed var(--rule); border-radius: var(--r-tile); padding: 12px 14px 14px; margin: 0 0 16px; min-width: 0; }
legend { font: 600 1.15rem var(--display); padding: 0 6px; }
.inline-form, .search-row { display: flex; gap: 8px; align-items: end; flex-wrap: wrap; }
.inline-form label { display: grid; font-size: var(--fs-sm); }
.inline-form input { width: 5.5em; margin: 0; }
.inline-form input:where(:not([type]), [type=text]) { width: 12em; max-width: 100%; } /* names and items, not quantities */
.search-row { margin-bottom: 14px; }
.search-row label { flex: 1 1 200px; }
.visually-hidden, .pick input, .swatch input { position: absolute; opacity: 0; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Radio "sticker" pickers */
.pick {
  position: relative; display: grid; justify-items: center; gap: 2px; padding: 8px 6px;
  border: 2px solid var(--ink); border-radius: var(--r-tile); background: #fff; cursor: pointer;
  font: 600 var(--fs-sm) var(--display); box-shadow: var(--shadow-sm);
}
.pick:has(input:checked) { background: var(--hi); box-shadow: 0 0 0 3px var(--pink), var(--shadow-sm); }
.pick:has(input:focus-visible), .swatch:has(input:focus-visible) { outline: 3px solid var(--sky); outline-offset: 3px; }
.pick-row { display: flex; flex-wrap: wrap; gap: 10px; }
.swatch {
  --swatch: #fff;
  position: relative; display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 6px 16px 6px 8px; border: 2px solid var(--ink); border-radius: 999px; background: #fff; font: 600 1rem var(--display);
}
.swatch::before { content: ''; width: 24px; height: 24px; border-radius: 50%; background: var(--swatch); border: 2px solid var(--ink); }
.swatch:has(input:checked) { background: var(--hi); box-shadow: 0 0 0 3px var(--pink); }
/* Non-colour swatches (difficulty, gender) have a plain white dot, so give the chosen one a filled centre. */
.swatch:not([style]):has(input:checked)::before { background: var(--ink); box-shadow: inset 0 0 0 5px #fff; }
.pick > span { text-align: center; } /* long names wrap centred, like the caption under them */

/* ---------- Auth ---------- */
.auth-wrap { display: grid; place-items: center; padding: 12px 0; }
.auth-card { width: min(440px, 100%); display: grid; gap: 14px; }
.auth-card h1, .auth-card p { margin: 0; }

/* ---------- Pets ---------- */
.create-form { display: grid; gap: 4px; }
.create-preview { display: grid; justify-items: center; gap: 4px; margin-bottom: 12px; padding: 12px; border-radius: var(--r-card);
  background: radial-gradient(ellipse 60% 55% at 50% 45%, #fff, color-mix(in oklab, var(--land-to) 60%, #fff)); border: 2px solid var(--ink); }
.pet-profile { display: grid; grid-template-columns: minmax(0, 300px) minmax(0, 1fr); gap: 24px; align-items: start; }
.pet-profile-art { position: relative; display: grid; justify-items: center; padding: 10px; border-radius: var(--r-card);
  background: radial-gradient(ellipse 65% 50% at 50% 42%, #fff, color-mix(in oklab, var(--land-from) 80%, #fff)); border: 2px solid var(--ink); }
.pet-petpet { position: absolute; right: 6px; bottom: 6px; display: grid; justify-items: center; font-weight: 800; }
.stats-table { margin: 8px 0 14px; }
.stats-table th { width: 32%; }
.stats-table td:last-child { width: 38%; }

/* ---------- Shops ---------- */
.shop-head { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 16px; align-items: center; }
.keeper { display: flex; align-items: center; gap: 4px; }
.keeper svg { flex: none; }
.speech {
  position: relative; background: var(--tint); border: 2px solid var(--ink); border-radius: 18px; padding: 10px 14px; max-width: 280px;
  animation: speech-in .3s var(--ease-out) .12s both; transform-origin: 0 40%;
}
/* Delight: every keeper line is freshly said: the keeper gives a little nod as the bubble pops out beside them */
.keeper > svg { transform-origin: 50% 100%; animation: keeper-nod .5s var(--ease-out); }
@keyframes speech-in { from { opacity: 0; transform: scale(.88) translateX(-8px); } }
@keyframes keeper-nod { 45% { transform: rotate(-4deg) translateY(-4px); } }
.speech::before { content: ''; position: absolute; left: -11px; top: 22px; border: 10px solid transparent; border-right-color: var(--ink); border-left: 0; }
.speech p { margin: 2px 0 0; }
/* Scene banners (src/art/scene.js): a full-bleed illustrated strip across the top of a shop's or daily's head card.
   The svg crops its sides below 560px wide. Only the classes below move; both reduced-motion rules stop them. */
.card > .scene { grid-column: 1 / -1; margin: calc(-1 * clamp(16px, 2.4vw, 24px)) calc(-1 * clamp(16px, 2.4vw, 24px)) 0;
  border-bottom: var(--line) solid var(--ink); border-radius: calc(var(--r-card) - var(--line)) calc(var(--r-card) - var(--line)) 0 0; overflow: hidden; }
.card:not(.shop-head) > .scene { margin-bottom: 16px; } /* .shop-head is a grid; its gap already spaces it */
.scene > svg { display: block; width: 100%; aspect-ratio: 4; min-height: 140px; }
.scene .sway { transform-origin: 50% 100%; animation: scene-sway 3.8s ease-in-out infinite alternate; }
.scene .bob { animation: scene-bob 2.4s ease-in-out infinite alternate; }
.scene .drift { animation: scene-drift 16s ease-in-out infinite alternate; }
.scene .twinkle { transform-origin: 50% 50%; animation: scene-twinkle 1.8s ease-in-out infinite alternate; }
.scene .steam { animation: scene-steam 2.8s ease-out infinite; }
/* Keep the delay after the animation shorthands, which otherwise reset it to zero. */
.scene :is(.sway, .bob, .drift, .twinkle, .steam) { transform-box: fill-box; animation-delay: var(--d, 0s); }
@keyframes scene-sway { from { rotate: -3deg; } to { rotate: 3deg; } }
@keyframes scene-bob { to { translate: 0 -5px; } }
@keyframes scene-drift { to { translate: 28px 0; } }
/* A twinkle can contain a whole constellation or an attached highlight. Keep it in place. */
@keyframes scene-twinkle { to { opacity: .45; } }
@keyframes scene-steam { from { opacity: .9; translate: 0 4px; } to { opacity: 0; translate: 0 -14px; } }
.haggle { display: grid; gap: 18px; }
.haggle-item { display: flex; gap: 18px; align-items: center; flex-wrap: wrap; }
.haggle-item h1 { margin-bottom: 6px; }
.haggle-item .pill { margin-bottom: 10px; }
.haggle-item svg { flex: none; }
.haggle-item > div { flex: 1 1 240px; }
.haggle-form { display: flex; flex-wrap: wrap; gap: 12px; align-items: end; }
.haggle-form label { flex: 0 1 240px; }
.haggle-form input { min-height: 54px; font-size: 1.15rem; } /* same height as the btn-big beside it */

/* ---------- Bank ---------- */
.bank-figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; margin: 14px 0; }
.bank-figures > div { display: grid; border: 2px solid var(--ink); border-radius: var(--r-tile); padding: 12px 16px; background: var(--tint); }
.bank-figures small { font-weight: 800; color: var(--muted); }
.bank-figures b { font: 700 1.6rem var(--display); }
.interest-box { border: var(--line) dashed var(--ink); border-radius: var(--r-tile); padding: 14px 18px; background: var(--hi-soft); }
.interest-box p { margin: 0 0 8px; }
.grid-2 > form { display: grid; gap: 10px; align-content: start; }
.grid-2 > form h2 { margin: 0; }

/* ---------- World (/world: map + popover, passport, land cards) ---------- */
.world-map { display: block; width: 100%; height: auto; border: var(--line) solid var(--ink); border-radius: var(--r-card); }
.map-wrap { position: relative; margin: 6px 0 0; }
.map-land { cursor: pointer; }
.map-landmark { transition: transform .2s cubic-bezier(.3, 1.6, .5, 1); transform-box: fill-box; transform-origin: center bottom; }
.map-land:hover .map-landmark, .map-land:focus-visible .map-landmark, .map-land[aria-expanded="true"] .map-landmark { transform: scale(1.12) translateY(-4px); }
.map-land:focus-visible { outline: none; }
.map-land:focus-visible rect { stroke: var(--sun); stroke-width: 5; }
.map-land:focus-visible .map-landmark { filter: drop-shadow(0 0 3px var(--sun)) drop-shadow(0 0 3px var(--sun)); }
.map-clouds { animation: drift 40s ease-in-out infinite alternate; }
@keyframes drift { to { transform: translateX(40px); } }

/* The popover: public/world.js fills it from a <template> and pins it under (or over) the land. */
.map-pop { position: absolute; z-index: 5; width: min(300px, calc(100% - 16px)); animation: map-pop-in .16s var(--ease-out); }
@keyframes map-pop-in { from { opacity: 0; transform: translateY(6px) scale(.97); } } /* own name: a second pop-in used to override the event banner's */
.map-pop-card {
  padding: 0 14px 14px; background: #fff; border: var(--line) solid var(--ink); border-radius: var(--r-tile);
  box-shadow: var(--shadow-sm); overflow: hidden;
}
.map-pop-name {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 -14px 8px; padding: 8px 14px;
  font: 600 1.25rem/1.2 var(--display); background: linear-gradient(115deg, var(--land-from), var(--land-to)); border-bottom: 2px solid var(--ink);
}
.map-pop-card.is-dark .map-pop-name { color: #fff; }
.map-pop-tag { font-size: var(--fs-sm); color: var(--muted); margin-bottom: 8px; }
.map-pop-places { list-style: none; margin: 0 0 10px; padding: 0; display: grid; gap: 2px; font-weight: 700; }
.map-pop-places a::before, .land-card-places a::before { content: '→ '; color: var(--land-accent); }
.map-pop .btn { width: 100%; }

/* What's-up badges: a glyph plus words, so they never rely on colour. */
.badges { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; padding: 0; }
.badge {
  display: inline-flex; align-items: center; gap: 4px; padding: 1px 10px 1px 6px; color: var(--ink);
  font: 600 var(--fs-xs)/1.5 var(--display); border: 2px solid var(--ink); border-radius: 999px; background: var(--hi);
}
.badge svg { flex: none; fill: none; stroke: var(--ink); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.badge-daily svg { fill: var(--sun); stroke-width: 1.6; }
.badge-shop { background: var(--sky-soft); }
.badge-quest { background: var(--pink-soft); }

/* Passport: a stamp per land; its art fills in (--fill, 0-1) as the land's places are stamped, and a finished land gets the double ring and tilt. */
.passport .stamps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 10px 8px; }
.stamp a {
  display: grid; justify-items: center; align-content: start; gap: 4px; height: 100%; padding: 10px 6px 8px;
  font: 600 var(--fs-xs)/1.2 var(--display); text-align: center; color: var(--muted); text-decoration: none;
  border: 2px dashed var(--rule); border-radius: 18px; transition: transform .15s var(--ease-out);
}
.stamp-art { width: 100%; max-width: 60px; height: auto; filter: grayscale(calc(1 - var(--fill, 0))); opacity: calc(.3 + .7 * var(--fill, 0)); }
.stamp.is-stamped a {
  color: var(--ink); border: 3px solid var(--land-accent); transform: rotate(var(--tilt));
  background: radial-gradient(circle at 50% 40%, #fff 30%, color-mix(in oklab, var(--land-from) 40%, #fff));
  box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 5px color-mix(in oklab, var(--land-accent) 55%, #fff);
}
.stamp.is-stamped .stamp-art { filter: none; opacity: 1; }
@media (hover: hover) and (pointer: fine) { .stamp a:hover { transform: rotate(0) scale(1.05); color: var(--ink); } }

/* Cover tiers (cover-0 plain ... cover-4 fully inked): stickers, foil edge, then glimshard ink that glows once the passport is full. */
.passport-count { margin: 0 0 10px; text-align: center; }
.passport-foot { margin: 10px 0 0; text-align: center; font-size: var(--fs-sm); }
.stamp span:not(.visually-hidden) { font-weight: 700; font-size: var(--fs-xs); }
.passport { --foil: color-mix(in oklab, var(--sun) 30%, var(--card)); }
.passport.cover-1, .passport.cover-2, .passport.cover-3, .passport.cover-4 { background-image: radial-gradient(circle at 12px 12px, var(--sun) 0 6px, transparent 7px), radial-gradient(circle at calc(100% - 12px) 12px, var(--pink) 0 6px, transparent 7px); }
.passport.cover-2, .passport.cover-3, .passport.cover-4 { border-color: var(--sun); box-shadow: inset 0 0 0 3px var(--foil), var(--shadow); }
.passport.cover-3, .passport.cover-4 { border-style: double; border-width: 6px; }
.passport.cover-4 { animation: ink-glow 3s ease-in-out infinite alternate; }
@keyframes ink-glow { from { box-shadow: inset 0 0 0 3px var(--foil), 0 0 6px 1px var(--sun); } to { box-shadow: inset 0 0 0 3px var(--foil), 0 0 18px 4px var(--sun); } }
@media (prefers-reduced-motion: reduce) { .passport.cover-4 { animation: none; box-shadow: inset 0 0 0 3px var(--foil), 0 0 14px 3px var(--sun); } }
.passport-land h2 { display: flex; align-items: center; gap: 8px; margin: 0; }
.passport-land .stamp-art { width: 32px; filter: none; opacity: 1; }
.passport-places { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr)); gap: 4px 12px; }
.passport-places li { display: flex; align-items: center; gap: 8px; min-height: 44px; color: var(--muted); }
.passport-places li::before { content: ""; flex: none; width: 16px; height: 16px; border: 2px dashed var(--rule); border-radius: 50%; }
.passport-places li.is-stamped { color: var(--ink); font-weight: 700; }
.passport-places li.is-stamped::before { border: 3px solid var(--land-accent); background: radial-gradient(circle, var(--land-accent) 30%, #fff 35%); }
.passport-places a { color: inherit; }

/* Land cards: the land's sky on top, its news and shortlist below. */
.lands-h { color: var(--page-ink); margin-top: 4px; }
.land-cards { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 290px), 1fr)); gap: var(--gap); }
.land-card {
  display: flex; flex-direction: column; min-width: 0; background: #fff; overflow: hidden;
  border: var(--line) solid var(--ink); border-radius: var(--r-card); box-shadow: var(--shadow);
}
.land-card.is-here { box-shadow: 0 0 0 4px var(--sun), var(--shadow); }
.land-card-head {
  position: relative; display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 10px; align-items: center;
  padding: 12px 14px; background: linear-gradient(120deg, var(--land-from), var(--land-to)); border-bottom: var(--line) solid var(--ink);
}
.land-card-head .landmark { width: 72px; height: auto; overflow: visible; }
.land-card-head h3 { margin: 0 0 2px; font-size: 1.3rem; }
.land-card-head h3 a { color: var(--ink); text-decoration: none; }
.land-card-head h3 a:hover { text-decoration: underline; }
.land-card-head p { margin: 0; font-size: var(--fs-sm); line-height: 1.35; }
.land-card.is-dark .land-card-head, .land-card.is-dark .land-card-head h3 a { color: #fff; }
.here-flag {
  flex: none; padding: 1px 10px; font: 600 var(--fs-xs)/1.5 var(--display); color: var(--ink); white-space: nowrap;
  background: var(--sun); border: 2px solid var(--ink); border-radius: 8px; box-shadow: 2px 2px 0 var(--ink); transform: rotate(3deg);
}
.land-card-head .here-flag { grid-column: 2; justify-self: start; margin-top: -4px; }
.land-card > .badges { margin: 12px 14px 0; }
.land-card-places { list-style: none; margin: 0; padding: 10px 14px 12px; display: grid; gap: 3px; font-weight: 700; }
.land-card-foot { margin-top: auto; display: flex; align-items: center; gap: 8px; min-height: 52px; padding: 8px 14px; border-top: 2px dashed var(--rule); font-size: var(--fs-sm); font-weight: 700; }
.around { display: flex; margin-left: auto; }
.around-face { display: block; border-radius: 50%; }
.around-face svg { display: block; border: 2px solid var(--ink); border-radius: 50%; background: #fff; }
.around .around-face + .around-face { margin-left: -8px; }
@media (hover: hover) and (pointer: fine) { .around-face { transition: transform .15s var(--ease-out); } .around-face:hover { transform: translateY(-3px); } }

/* ---------- Land pages (/land/:id) ---------- */
/* Banner: the land's wide scene, with a scrim on the left third under the name. */
.land-banner-wrap {
  position: relative; width: 100%; aspect-ratio: 4; min-height: 260px; margin-bottom: var(--gap); overflow: hidden; /* wider cards grow a little taller, so the 1200x360 art never crops more than ~30 off top and bottom */
  border: var(--line) solid var(--ink); border-radius: var(--r-card); box-shadow: var(--shadow);
  background: linear-gradient(120deg, var(--land-from), var(--land-to));
}
.land-banner-wrap > svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.land-banner-wrap::before {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(90deg, color-mix(in oklab, var(--land-from) 94%, transparent) 0 24%, color-mix(in oklab, var(--land-from) 55%, transparent) 42%, transparent 62%);
}
.land-dark .land-banner-wrap::before { background: linear-gradient(90deg, color-mix(in srgb, var(--ui-land-dark-bg) 88%, transparent) 0 24%, color-mix(in srgb, var(--ui-land-dark-bg) 50%, transparent) 42%, transparent 62%); }
.land-banner-text {
  position: relative; z-index: 2; height: 100%; max-width: min(48%, 460px);
  display: flex; flex-direction: column; justify-content: center; padding: 0 clamp(18px, 3vw, 34px);
}
.land-banner-text h1 { font-size: clamp(2rem, 1.3rem + 2.6vw, 3.2rem); margin-bottom: .15em; }
.land-banner-text p { margin: 0 0 10px; font-weight: 700; }
.land-banner-text .badges { margin: 0; }
.land-dark .land-banner-text { color: #fff; }
.land-dark .land-banner-text h1 { text-shadow: 0 3px 0 var(--ink); }

.around-strip {
  display: flex; align-items: center; gap: 8px 16px; flex-wrap: wrap; margin-bottom: var(--gap); padding: 10px 16px;
  background: #fff; border: 2px solid var(--ink); border-radius: var(--r-tile); box-shadow: var(--shadow-sm);
}
.around-strip h2 { font-size: 1.1rem; margin: 0; }
.around-strip p { margin: 0; }
.around-strip ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 14px; }
.around-strip li { display: grid; justify-items: center; gap: 2px; }
.around-strip small { font-size: var(--fs-xs); font-weight: 700; color: var(--muted); max-width: 9ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.land-places .kind + .kind { margin-top: 24px; padding-top: 18px; border-top: 2px dashed var(--rule); }
.kind h2 { display: flex; align-items: center; gap: 8px; }
.kind h2 small { font: 600 var(--fs-xs)/1.5 var(--display); padding: 0 8px; border: 2px solid var(--ink); border-radius: 999px; background: color-mix(in oklab, var(--land-accent) 14%, #fff); }
.place {
  display: flex; flex-direction: column; gap: 2px; padding: 14px 16px;
  border: 2px solid var(--ink); border-radius: var(--r-tile); background: #fff; color: var(--ink); text-decoration: none; box-shadow: var(--shadow-sm);
}
/* Places with a shopkeeper: keeper on the left so every card's title lines up at the top */
.place:has(> svg) { display: grid; grid-template-columns: 56px minmax(0, 1fr); column-gap: 12px; align-content: start; }
.place > svg { grid-row: span 2; width: 56px; height: 56px; margin: -4px 0 0 -4px; }
.place:has(> svg) > .badges { grid-column: 2; }
.place b { font: 600 1.15rem var(--display); color: var(--link); }
.place span { color: var(--muted); font-size: var(--fs-sm); }
.place > .badges { margin: 8px 0 0; }
.place.has-news { background: var(--hi-soft); }
.land-nav { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px; margin-top: var(--gap); }

@media (max-width: 560px) {
  .map-pop { position: static; width: auto; margin-top: 10px; } /* phones: a strip under the map, so it never covers the map */
  .land-banner-wrap { height: 180px; min-height: 0; border-radius: 22px; }
  .land-banner-wrap::before { background: linear-gradient(90deg, color-mix(in oklab, var(--land-from) 94%, transparent) 0 40%, color-mix(in oklab, var(--land-from) 50%, transparent) 62%, transparent 82%); }
  .land-dark .land-banner-wrap::before { background: linear-gradient(90deg, color-mix(in srgb, var(--ui-land-dark-bg) 88%, transparent) 0 40%, color-mix(in srgb, var(--ui-land-dark-bg) 50%, transparent) 62%, transparent 82%); }
  .land-banner-text { max-width: 72%; }
  .land-banner-text p { font-size: var(--fs-sm); line-height: 1.35; }
  .land-banner-text .badges { display: none; } /* the place cards below still show them */
  .passport .stamps { grid-template-columns: repeat(3, minmax(0, 1fr)); } /* eight lands: three, three, two */
}

/* ---------- Admin (Back Office) ---------- */
.admin-tools { grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); gap: var(--gap); }
.admin-tools .card { display: grid; gap: 12px; align-content: start; }
.admin-tools .card > * { margin: 0; }
.admin-tools form.inline-form:not(:first-of-type) { padding-top: 12px; border-top: 2px dashed var(--rule); }
.admin-note { font-size: var(--fs-sm); }
.admin-doctor .search-row label { flex: 0 1 auto; }
.admin-form input[type=number] { width: 8em; } /* the 10000 default clipped in the 5.5em quantity width */
.admin-db { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 0 18px; margin: 0; font-variant-numeric: tabular-nums; }
.admin-db div { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; padding: 6px 2px; border-bottom: 1px dashed var(--rule); }
.admin-db dd { margin: 0; font-weight: 800; }
.danger-zone { background: var(--err-bg); border-style: dashed; }
.danger-zone h2 { color: var(--loss); }
.danger-zone p { max-width: 62ch; }

/* ---------- Footer ---------- */
.site-foot { text-align: center; padding: 18px 16px 32px; color: var(--page-ink); font-size: var(--fs-sm); }
.site-foot p { margin: 0 auto 6px; max-width: 46rem; }
.site-foot a { margin: 0 8px; color: inherit; font-weight: 700; }

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  /* Tablet header: shrink the logo and pills so logo, land chip and status cluster keep one row down to ~700px. */
  .site-head { gap: 10px; }
  .logo svg { height: 38px; }
  .who { gap: 8px; flex-wrap: nowrap; }
  .charms { gap: 6px; }
  .charm { min-width: 36px; min-height: 36px; padding: 0 6px; }
  .coins { font-size: .9rem; }
  .sky-charm { width: 50px; height: 36px; }
  .pet-profile, .shop-head { grid-template-columns: minmax(0, 1fr); }
  .pet-profile-art { max-width: 320px; justify-self: center; width: 100%; }
}
/* Below 1000px the pet panel is a horizontal strip: the pet's face, name and level, the meters inline, actions at the end. */
@media (max-width: 999px) {
  .pet-panel {
    grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "face id act" "face meters act" "sw sw sw";
    align-items: center; gap: 4px 14px; padding: 10px 14px;
  }
  .pet-panel .pet-stage { grid-area: face; width: 84px; height: 84px; padding: 0; overflow: hidden; border-radius: 50%; align-self: center; }
  .pet-panel .pet-stage svg { width: 132px; max-width: none; height: auto; margin: 4px 0 0 -24px; }
  .pet-panel .pet-stage::before { width: 90px; bottom: -10%; }
  .pet-level { position: static; width: 28px; height: 28px; font-size: .75rem; align-self: center; }
  .pet-id { grid-area: id; text-align: left; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
  .pet-name { font-size: 1.15rem; }
  .pet-meters { grid-area: meters; display: flex; flex-wrap: wrap; gap: 4px 16px; padding: 0; background: none; border: 0; }
  .pet-meters li { grid-template-columns: auto auto auto; column-gap: 6px; white-space: nowrap; }
  .pet-meters .stat-bar { display: none; }
  .pet-actions { grid-area: act; grid-auto-flow: row; }
  .pet-actions .btn-alt { display: none; }
  .pet-switch small { flex: none; }
  .pet-switch { grid-area: sw; justify-content: flex-start; border-top: 2px dashed var(--rule); margin-top: 6px; }
  .pet-panel-empty { grid-template-columns: none; grid-template-areas: none; display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 14px; }
}
@media (max-width: 767px) {
  .site-head { padding-inline: 12px; gap: 8px; }
  .logo svg { height: 32px; }
  .land-chip { padding: 3px 10px; font-size: var(--fs-xs); }
}
@media (max-width: 560px) {
  /* Phone strip: face beside name and meters, "Feed & play" full width underneath. */
  .pet-panel { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "face id" "face meters" "act act" "sw sw"; }
  .pet-actions .btn { padding-block: 6px; }
  body { font-size: var(--fs-sm); }
  /* Phone header, tab bar and pet bar: shell.css. */
  .keeper { flex-direction: column; align-items: flex-start; }
  .keeper svg { width: 96px; height: 96px; }
  .speech::before { display: none; }
  .table th, .table td { padding: 8px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ---------- Idle pets: every petSvg breathes and blinks (src/art/pet.js adds .pet-idle / .pet-eyes and a per-pet --idle delay).
   Only the inner groups move, so outer svg animations (joy hop, keeper nod, parade) still apply.
   The global prefers-reduced-motion rule above switches both off. ---------- */
.pet-idle { transform-box: fill-box; transform-origin: 50% 100%; animation: pet-breathe 3.6s ease-in-out var(--idle, 0s) infinite alternate; }
.pet-eyes { transform-box: fill-box; transform-origin: 50% 50%; animation: pet-blink 5.3s linear calc(var(--idle, 0s) * 1.7) infinite; }
@keyframes pet-breathe { to { transform: scale(.99, 1.025); } }
@keyframes pet-blink { 0%, 95%, 100% { transform: none; } 97.5% { transform: scaleY(.12); } }

/* ---------- Rare item shimmer (tileClass() in src/layout.js) ----------
   Rare (rarity 80+) tiles get a gold ring and a slow light sweep; ultra-rare (95+) a candy ring, a quicker sweep and a
   twinkling star. Under reduced motion the rule above stops the sweep and twinkle, leaving the ring as a static glow. */
.tile-rare { box-shadow: 0 0 0 3px var(--sun), var(--shadow-sm); }
.tile-ultra { box-shadow: 0 0 0 3px var(--pink), 0 0 0 6px var(--sun), var(--shadow-sm); }
@media (hover: hover) and (pointer: fine) {
  :is(a, button).tile-rare:hover { box-shadow: 0 0 0 3px var(--sun), var(--shadow-lift); }
  :is(a, button).tile-ultra:hover { box-shadow: 0 0 0 3px var(--pink), 0 0 0 6px var(--sun), var(--shadow-lift); }
}
.tile-rare::after, .tile-ultra::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(110deg, transparent 38%, rgb(255 255 255 / .75) 50%, transparent 62%) 160% 0 / 260% 100% no-repeat;
  animation: tile-shimmer 4.5s ease-in-out infinite;
}
.tile-ultra::after { animation-duration: 3s; }
.tile-ultra::before {
  content: '✦'; position: absolute; top: 5px; left: 8px; pointer-events: none;
  font: 700 1.15rem/1 var(--display); color: var(--pink); text-shadow: 0 0 6px var(--sun);
  animation: tile-twinkle 1.8s ease-in-out infinite;
}
@keyframes tile-shimmer { 0%, 55% { background-position: 160% 0; } 100% { background-position: -60% 0; } }
@keyframes tile-twinkle { 50% { transform: scale(.6) rotate(45deg); opacity: .5; } }

/* ---------- Glimmery stickers (holo() in src/art/item.js, inside every itemSvg) ----------
   A light band sweeps across the foil once every 7s and the glitter specks twinkle as it passes; --holo staggers each sticker.
   Only small transformed groups, idle most of the cycle, so a page full of them stays smooth. Reduced motion (the global rules)
   stops both: the band rests off the sticker and the specks stay lit, a still rainbow foil. Glimshard catches starlight:
   the band is brighter while the header's sky clock shows night (.sky-charm.sky-night, src/layout.js). */
.holo-sweep { opacity: .75; animation: holo-sweep 7s ease-in-out var(--holo, 0s) infinite; }
body:has(.sky-charm.sky-night) .holo-sweep { opacity: 1; }
.holo-twinkle { transform-box: fill-box; transform-origin: center; animation: holo-twinkle 7s ease-in-out calc(var(--holo, 0s) + var(--holo-i, 0) * .3s) infinite; }
@keyframes holo-sweep { 0%, 55% { transform: translateX(0); } 100% { transform: translateX(200px); } }
@keyframes holo-twinkle { 0%, 62%, 100% { transform: none; opacity: 1; } 78% { transform: scale(.35) rotate(45deg); opacity: .4; } }

/* A title worn next to a player's name (services/trophies.js titleTag) */
.townsfolk { display: inline-block; margin-left: 4px; padding: 0 8px; border: 1.5px solid var(--ink); border-radius: 999px; background: var(--ui-townsfolk-bg); font: 600 .68rem/1.5 var(--display); color: var(--ink); vertical-align: middle; white-space: nowrap; }
.title-tag { display: inline-block; margin-left: 4px; padding: 0 8px; border: 1.5px solid var(--ink); border-radius: 999px; background: var(--sun-cream); font: 600 .78rem/1.5 var(--display); color: var(--ink); vertical-align: middle; white-space: nowrap; }

/* ---------- Phones (max 767px): 44px targets, 12px gaps, button rows, alignment by content type ---------- */
@media (max-width: 767px) {
  .btn-small, .pop-close, a.pill { min-height: 44px; }
  a.pill { display: inline-flex; align-items: center; }
  .pop-close { width: 44px; height: 44px; }
  :where(details:not(.account)) > summary { min-height: 44px; padding-block: 10px; box-sizing: border-box; cursor: pointer; }
  label:has(> input[type=checkbox], > input[type=radio]):not(.pick, .swatch, :has(svg, img)) { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; }
  :where(input[type=checkbox], input[type=radio]) { inline-size: 22px; block-size: 22px; flex: none; }

  /* gaps between stacked controls */
  .inline-form, .search-row, .item-pop-actions, .pick-row, .land-nav, .btn-row { gap: 12px; }
  .create-form, .grid-2 > form { gap: 12px; }
  .card > :is(p, form) + form { margin-top: 12px; }
  h2:has(+ :is(form, .btn-row, .inline-form, .search-row)) { margin-bottom: 14px; }

  /* button rows: the primary spans the row, the rest share the next one; small buttons just share evenly */
  .btn-row { gap: 12px; }
  .btn-row:has(> .btn-big) { align-items: stretch; }
  .btn-row:not(:is(table, .item-tile, .pet-card, .head-row) .btn-row) > :is(.btn, form) { flex: 1 1 40%; }
  .btn-row:not(:is(table, .item-tile, .pet-card, .head-row) .btn-row) > form > .btn:only-child { width: 100%; }
  .btn-row:not(:is(table, .item-tile, .pet-card, .head-row) .btn-row) > .btn:not(.btn-small, .btn-alt, .btn-danger):is(:first-child:has(~ .btn, ~ form), :only-child) { flex-basis: 100%; }

  /* centred: intro titles, the shop keeper, wrapped page headers */
  .card > .scene:first-child + h1, .card > .scene:first-child + h1 + .lede { text-align: center; margin-inline: auto; }
  .shop-head { text-align: center; }
  .keeper:not(.plot-say) { flex-direction: column; align-items: center; } /* every keeper: art centred above a centred bubble */
  .keeper:not(.plot-say) .speech { margin-inline: auto; text-align: center; }
  .keeper:not(.plot-say) .speech :is(p, b, .pill) { text-align: center; }
  .keeper:not(.plot-say) .speech::before { display: none; }
  .shop-head .lede { margin-inline: auto; }
  .shop-head :is(form, ul, ol, dl, table) { text-align: left; } /* short text centres with the head; forms and lists stay left */
  .head-row { justify-content: center; text-align: center; }
  .head-row:has(> :nth-child(2)) { flex-direction: column; align-items: center; gap: 8px; } /* title, then its pill or button on its own row */
  .card > :is(h1, h2):first-child, .card > .scene:first-child + :is(h1, h2) { text-align: center; } /* a card's own title, even without a head-row */
  .head-row + :is(.lede, p), h1 + .lede, h2 + .lede, p:has(> .pill:only-child) + .lede, .phone-center { text-align: center; margin-inline: auto; } /* the intro under a header or its pill; .phone-center for other short notes */
  p:has(> .pill:only-child) { text-align: center; }
  .album-tabs { justify-content: center; }
  .pet-card .btn-row { flex-direction: column; align-items: center; } /* Active Glimling pill and Visit on separate rows */
  .card > .scene:first-child + .head-row + .lede, .card > .scene:first-child + .head-row + .lede + p { text-align: center; margin-inline: auto; }
  .haggle-item { justify-content: center; text-align: center; } /* an Owlmanac entry's hero: art, name, badges */
  .admin-form :is(label, .btn) { flex: 1 1 100%; } /* admin tools: every field its own row, the submit full width */
  .admin-form input { width: 100%; box-sizing: border-box; }
  .search-row > .btn:last-child { flex: 1 1 100%; } /* the lone submit under a search field spans the row */
}

/* Set progress card (src/services/sets.js setCard): the four prizes for finishing, then the missing members as silhouettes. */
.set-prizes { list-style: none; padding: 0; margin: 12px 0 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; }
.set-prizes li { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 4px; padding: 10px; background: var(--tint); border-radius: var(--r-sm); }
.set-prizes small { color: var(--muted); font-size: var(--fs-xs); }
.set-won li { background: var(--hi-soft); }
.set-credit { font-family: var(--display); font-size: 1.45rem; line-height: 56px; color: var(--gain); }
.set-missing { background: var(--tint); border-style: dashed; }
.set-missing svg { filter: brightness(0) opacity(.22); }
.set-missing form { margin-top: auto; }

/* Desktop pet profile: art beside name/bubble, the long stats table spans the full card underneath (it used to leave the art column empty for 500px). */
@media (min-width: 1100px) {
  .pet-profile { grid-template-rows: auto auto 1fr; }
  .pet-profile-info { display: contents; }
  .pet-profile-info > .speech { align-self: start; }
  .pet-profile-art { grid-row: 1 / span 3; }
  .pet-profile-info > .stats-table, .pet-profile-info > .btn-row { grid-column: 1 / -1; }
  .pet-profile-info > .speech { max-width: 520px; }
}

/* Desktop reading width: plain paragraphs and .muted notes inside cards stop at 75ch. On wide screens they ran 90-140 characters per line
   (paragraphs with their own class, like .lede or the centred .empty, keep their own rules). */
@media (min-width: 1100px) { main .card p:not([class]), main .card p.muted { max-width: 75ch; } }
