/* ============================================================
   Adventurers Needed — three acts, three grounds
   ============================================================ */

:root {
  /* Act I — night */
  --night-1: #06070d;
  --night-2: #0d1226;
  --moon: #f4f1e4;

  /* Act II — dusk */
  --dusk-1: #120a20;
  --dusk-2: #1b0d2a;
  --gold: #c9a227;
  --gold-soft: #e3c768;
  --ember: #c46531;
  --amethyst: #c3a0e6;

  /* Act III — parchment */
  --parch-1: #efe3cc;
  --parch-2: #e3d3b4;
  /* the flat colour at the bottom of assets/edge.png, so the torn edge
     meets Act III with no seam */
  --parch-edge: #eedabd;
  --ink: #241a10;
  --ink-soft: #5a4830;
  --blood: #7c1f1f;

  /* photographic grounds: 1856x2464, so one full-bleed width is 132.76vw tall */
  --bg-natural: 133vw;
  --bg-fade: clamp(140px, 24vh, 300px);
  --rip-height: clamp(92px, 11vw, 168px);
  /* how far Act III stays flat --parch-edge before the warm glows fade in —
     comfortably clear of the torn edge, so the two meet as one colour */
  --parch-top-fade: clamp(240px, 30vw, 440px);

  --measure: 62ch;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: "Spectral", Georgia, serif;
  font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
  line-height: 1.65;
  color: var(--moon);
  background: var(--night-1);
}

h1, h2, h3, legend, .btn, .eyebrow {
  font-family: "Cinzel", "Times New Roman", serif;
}

/* ---------- shared act scaffolding ---------- */

.act {
  position: relative;
  padding-block: clamp(4rem, 9vh, 7rem);
  padding-inline: 20px;
  overflow: hidden;
}

/* A photographic ground pinned to the top of its act. It is never taller than the
   image's own full-bleed height, so a long act gets image -> fade -> solid colour,
   and a short act crops the image and fades out before the act ends. */
.act__bg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 0;
  height: min(100%, var(--bg-natural));
  background-position: top center;
  background-repeat: no-repeat;
  background-size: cover;
  -webkit-mask-image: linear-gradient(to bottom, #000 0, #000 calc(100% - var(--bg-fade)), rgba(0, 0, 0, 0) 100%);
  mask-image: linear-gradient(to bottom, #000 0, #000 calc(100% - var(--bg-fade)), rgba(0, 0, 0, 0) 100%);
}

/* scrim, so the type stays readable over the picture */
.act__bg::after {
  content: "";
  position: absolute;
  inset: 0;
}

.act__inner {
  position: relative;
  z-index: 2;
  max-width: 1080px;
  margin-inline: auto;
}

.act__inner--hero {
  /* Act I's section is a flex row, so without this the inner shrinks to its
     content and the auto margins centre it — Act II's inner is a plain block
     filling the 1080px and starting at the left. This keeps the two acts aligned. */
  width: 100%;
  min-height: calc(100vh - 8rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(1.5rem, 4vh, 3rem);
}

.eyebrow {
  margin: 0 0 1rem;
  font-size: 1.44rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--gold-soft);
  opacity: 0.85;
}

.eyebrow--dark { color: var(--blood); opacity: 1; }

.act__title {
  margin: 0 0 0.6rem;
  font-size: clamp(2.25rem, 6vw, 4rem);
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.05;
  text-transform: uppercase;
}

.act__lede {
  max-width: var(--measure);
  margin: 0 0 clamp(2rem, 5vh, 3.5rem);
  font-size: 1.05rem;
  font-style: italic;
  opacity: 0.8;
}

/* ============================================================
   ACT I — THE SUMMONS
   ============================================================ */

.act--night {
  background: linear-gradient(180deg, var(--night-2) 0%, #0a0d1c 100%);
  min-height: 100vh;
  display: flex;
  align-items: center;
}

.act__bg--i {
  background-image: url("assets/act_i_bkg.jpg");
}

.act__bg--i::after {
  background: linear-gradient(180deg,
    rgba(6, 7, 13, 0.42) 0%,
    rgba(6, 7, 13, 0.28) 30%,
    rgba(6, 7, 13, 0.52) 100%);
}

.story {
  max-width: var(--measure);
  font-family: "Merienda", "IM Fell English", Georgia, serif;
  font-weight: 400;
  font-size: clamp(1rem, 0.92rem + 0.4vw, 1.2rem);
  line-height: 1.45;
}

.story p { margin: 0 0 1.1rem; }
.story em { font-style: italic; color: var(--gold-soft); }

/* same voice as Act I's prose, but standing in for a lede, so it keeps the
   breathing room the old .act__lede had before the steps */
.story--intro { margin-bottom: clamp(2rem, 5vh, 3.5rem); }
.story--intro p:last-child { margin-bottom: 0; }

/* --- the handbill --- */

/* geometry comes from assets/note_blank_2.png (1052x1264): the engraved frame sits
   at x 110-947, and the printed WANTED heading bottoms out at y 503 (39.8%), so the
   body starts below that. The signature trails the body by one paragraph margin
   rather than sitting at the foot of the frame — see the note on .notice__sign. */
.notice {
  position: relative;
  container-type: inline-size;
  /* sits inside .story, so 100% is the text area the paragraphs above and below
     it occupy; inset by --note-gap on the left and twice that on the right.
     Sizing off --measure instead would come up short — `ch` resolves against the
     handbill's own font, not the larger Merienda the story is set in. */
  --note-gap: 50px;
  width: calc(100% - var(--note-gap) * 3);
  max-width: none;
  margin: 2.25rem calc(var(--note-gap) * 2) 2.25rem var(--note-gap);
  padding: 0;
  aspect-ratio: 1052 / 1264;
  background: url("assets/note_blank_2.png") center / 100% 100% no-repeat;
  filter: drop-shadow(0 20px 36px rgba(0, 0, 0, 0.62));
  transform: rotate(-2.2deg);
}

/* a 50/100px inset eats a phone screen; the act's own 20px gutter already keeps
   the handbill off the edge, so the inset barely needs to be there */
@media (max-width: 560px) {
  .notice { --note-gap: 6px; }
}

/* the printed border and heading are part of the artwork now */
.notice::before,
.notice::after { content: none; }

.notice__body {
  position: absolute;
  inset: 46% 13% 16%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  font-family: "Caveat", "Segoe Script", cursive;
  font-weight: 600;
  line-height: 1.28;
  color: #18120a;
}

.notice__text {
  margin: 0;
  font-size: 6.1cqw;
}

.notice__sign {
  /* NOTE: this `auto` never applies — `.story p` (0,1,1) outranks `.notice__sign`
     (0,1,0) and sets `margin: 0 0 1.1rem`, so the signature trails the body text
     instead of being pushed to the foot of the frame. Raise the specificity
     (e.g. `.story .notice__sign`) to get the intended pinning. */
  margin: auto 0 0;
  font-size: 5.9cqw;
}

/* --- the question in the mirror --- */

/* The old glass had a sheen bar sweeping across it. The glass is gone, so the
   sweep now runs through the letterforms themselves: a highlight band in the
   background gradient, clipped to the glyphs, slid back and forth. */
.question {
  margin: clamp(0.25rem, 0.8vh, 0.75rem) 0 0;
  padding-bottom: 0.12em;
  font-family: "Arizonia", "Brush Script MT", cursive;
  font-size: clamp(2.25rem, 7.5vw, 4.875rem);
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.15;
  text-transform: none;
  color: #f2e9d4;
  background-image: linear-gradient(100deg,
    #cfc099 0%,
    #cfc099 38%,
    #f3e9ce 46%,
    #fffdf3 50%,
    #f3e9ce 54%,
    #cfc099 62%,
    #cfc099 100%);
  background-size: 300% 100%;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 2px 16px rgba(0, 0, 0, 0.8));
  animation: shine 9s ease-in-out infinite;
}

/* 0% parks the highlight off the right edge, 100% off the left. Staying inside
   0-100% matters: the gradient is no-repeat, so a position outside that range
   slides the painted tile off the glyphs and the letters vanish. */
@keyframes shine {
  0%, 70%, 100% { background-position: 0% 0; }
  35%           { background-position: 100% 0; }
}

/* no background-clip support: fall back to the flat warm white above */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .question {
    background-image: none;
    -webkit-text-fill-color: currentColor;
    animation: none;
  }
}

/* --- scroll cue --- */

.scroll-cue {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  align-self: center;
  margin-top: clamp(1.5rem, 5vh, 3rem);
  padding: 0.5rem 0.25rem;
  color: var(--gold-soft);
  font-family: "Cinzel", serif;
  font-size: 1rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  text-decoration: none;
  opacity: 0.85;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}

.scroll-cue:hover { opacity: 1; transform: translateY(2px); }
.scroll-cue svg { width: 24px; height: 24px; animation: bob 2.4s ease-in-out infinite; }
.scroll-cue--dark {
  display: flex;
  width: fit-content;
  margin-inline: auto;
  /* more air between the class cards and the cue out of Act II */
  margin-top: clamp(3rem, 8vh, 5rem);
}

/* Act I's cue carries the eye out of the hero, so it sits closer than the one at
   the foot of Act II. The type treatment is shared by both. */
.scroll-cue--lead {
  margin-top: clamp(0.25rem, 1vh, 0.75rem);
}

@keyframes bob {
  0%, 100% { transform: translateY(-2px); }
  50% { transform: translateY(4px); }
}

/* ============================================================
   ACT II — HOW TO PLAY
   ============================================================ */

.act--dusk {
  background: linear-gradient(180deg, var(--dusk-1) 0%, var(--dusk-2) 100%);
  border-top: 1px solid rgba(201, 162, 39, 0.22);
  padding-bottom: calc(clamp(4rem, 9vh, 7rem) + var(--rip-height));
}

.act__bg--ii {
  background-image: url("assets/act_ii_bkg.jpg");
}

.act__bg--ii::after {
  background: linear-gradient(180deg,
    rgba(12, 7, 22, 0.44) 0%,
    rgba(16, 9, 28, 0.27) 30%,
    rgba(27, 16, 48, 0.55) 100%);
}

/* ---------- the tear between Act II and Act III ---------- */

/* A photograph of a torn page edge (assets/edge.png): ragged fibres along the
   top, settling into flat --parch-edge further down — the colour Act III is
   painted in, so the two meet seamlessly. */
.rip {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 4;
  height: var(--rip-height);
  line-height: 0;
  pointer-events: none;
}

.rip--tear {
  bottom: -1px;
  /* The photo is scaled by width alone so the torn fibres keep their own
     proportions at any viewport, then washed into flat parchment before the
     strip ends. */
  background-image:
    linear-gradient(180deg, rgba(238, 218, 189, 0) 34%, var(--parch-edge) 94%),
    url("assets/edge.png");
  background-repeat: no-repeat;
  background-position: center bottom, center top;
  background-size: 100% 100%, 100% auto;
  filter: drop-shadow(0 -10px 18px rgba(0, 0, 0, 0.55));
}

/* --- the three preparations --- */

.script-head {
  margin: 0 0 1.5rem;
  font-family: "Arizonia", "Brush Script MT", cursive;
  font-size: clamp(1.75rem, 4.2vw, 2.75rem);
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.2;
  text-transform: none;
  color: #fffdf3;
}

.prep {
  counter-reset: prep;
  list-style: none;
  margin: 0 0 clamp(2.25rem, 6vh, 3.5rem);
  padding: 0;
  max-width: var(--measure);
  font-family: "Merienda", "IM Fell English", Georgia, serif;
  font-size: clamp(1rem, 0.92rem + 0.4vw, 1.2rem);
  line-height: 1.45;
}

.prep li {
  counter-increment: prep;
  position: relative;
  margin-bottom: 1.1rem;
  padding-left: 3rem;
}

.prep li:last-child { margin-bottom: 0; }

.prep li::before {
  content: counter(prep);
  position: absolute;
  top: 0.1em;
  left: 0;
  width: 1.85rem;
  height: 1.85rem;
  display: grid;
  place-items: center;
  font-family: "Cinzel", serif;
  font-size: 0.85rem;
  color: var(--gold);
  border: 1px solid rgba(201, 162, 39, 0.5);
  border-radius: 50%;
}

.prep__title { color: var(--gold-soft); }

.subhead {
  margin: 0 0 0.35rem;
  font-size: clamp(1.3rem, 3vw, 1.75rem);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.subhead__note {
  margin: 0 0 0.3rem;
  font-family: "Merienda", "IM Fell English", Georgia, serif;
  font-size: clamp(0.95rem, 0.88rem + 0.3vw, 1.1rem);
  line-height: 1.45;
  opacity: 0.85;
}

.subhead__note:not(:has(+ .subhead__note)) { margin-bottom: 1.75rem; }

/* with no note under it, the subhead has to carry that gap itself */
.subhead:not(:has(+ .subhead__note)) { margin-bottom: 1.75rem; }

/* the anchors the jump nav and the sheet's ? links land on — a little air so
   the heading does not sit flush against the top of the viewport */
.subhead[id], #sheet { scroll-margin-top: clamp(1rem, 4vh, 2.5rem); }

/* --- jump nav --- */

.jump {
  margin: 0 0 clamp(1.4rem, 3.5vh, 2rem);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.7rem;
  font-family: "Cinzel", serif;
  font-size: clamp(0.7rem, 0.66rem + 0.2vw, 0.82rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.jump__label { color: rgba(255, 255, 255, 0.5); }

.jump a {
  color: var(--amethyst);
  text-decoration: none;
  transition: color 0.2s var(--ease);
}

.jump a:hover,
.jump a:focus-visible {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 0.3em;
}

/* the rule between links — a border rather than a pseudo-element, so the
   separator is not part of anything clickable */
.jump a + a {
  border-left: 1px solid rgba(255, 255, 255, 0.22);
  padding-left: 0.7rem;
}

/* --- class table --- */

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

/* --- class cards --- */

.class-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(0.85rem, 2vw, 1.4rem);
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

.class-card {
  container-type: inline-size;
  cursor: pointer;
}

.class-card:focus-visible {
  outline: 2px solid var(--ember);
  outline-offset: 4px;
  border-radius: 6px;
}

/* the class currently on the sheet */
.class-card.is-chosen .class-card__face {
  box-shadow: 0 0 0 2px var(--ember), 0 10px 30px rgba(0, 0, 0, 0.5);
}

/* the two faces are stacked back to back and spun together */
.class-card__inner {
  position: relative;
  aspect-ratio: 928 / 1232;
  transform: perspective(1400px) rotateY(0deg);
  transform-style: preserve-3d;
  transition: transform 0.65s var(--ease);
}

.class-card.is-flipped .class-card__inner { transform: perspective(1400px) rotateY(180deg); }

.class-card__face {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 5px;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.class-card__face--front { background: #0b0710; }

.class-card__art {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* keeps the name and tagline legible over whatever the art is doing */
.class-card__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
    rgba(0, 0, 0, 0.8) 0%,
    rgba(0, 0, 0, 0.7) 14%,
    rgba(0, 0, 0, 0.44) 26%,
    rgba(0, 0, 0, 0.15) 38%,
    rgba(0, 0, 0, 0) 52%);
}

.class-card__label {
  position: absolute;
  left: 5.4%;
  bottom: 4.2%;
  right: 36%;
}

.class-card__name {
  margin: 0;
  font-family: "Cinzel", serif;
  font-size: 6.25cqw;
  font-weight: 400;
  letter-spacing: 0.04em;
  line-height: 1.1;
  text-transform: uppercase;
  color: #fff;
}

.class-card__tagline {
  margin: 0.35em 0 0;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 3.7cqw;
  font-style: italic;
  line-height: 1.25;
  text-wrap: pretty;
  color: rgba(255, 255, 255, 0.88);
}

.class-card__play {
  position: absolute;
  right: 5.4%;
  bottom: 4.2%;
  padding: 0.55em 1.4em;
  font-family: "Cinzel", serif;
  font-size: 4.3cqw;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ember);
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid var(--ember);
  border-radius: 10px;
  cursor: pointer;
  transition: color 0.2s var(--ease), background 0.2s var(--ease);
}

.class-card__play:hover,
.class-card__play:focus-visible { color: #140b06; background: var(--ember); }

/* --- the back --- */

.class-card__face--back {
  transform: rotateY(180deg);
  display: flex;
  flex-direction: column;
  padding: 7.8cqw;
  background: #000;
  border: 1px solid rgba(255, 255, 255, 0.55);
}

.class-card__face--back .class-card__name {
  font-size: 5.6cqw;
  margin-bottom: 0.55em;
}

.class-card__blurb {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 4.1cqw;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.92);
  overflow-y: auto;
}

.class-card__quote {
  margin: 0.8em 0 0;
  font-family: "Alegreya", serif;
  font-size: 4.4cqw;
  font-style: italic;
  color: rgba(255, 255, 255, 0.78);
}

.class-card__cta {
  margin: auto auto 0.6em;
  padding: 0.6em 1.4em;
  font-family: "Cinzel", serif;
  font-size: 3.7cqw;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #140b06;
  background: var(--ember);
  border: 1px solid var(--ember);
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.2s var(--ease);
}

.class-card__cta:hover,
.class-card__cta:focus-visible { background: #d87b45; }

.class-card__hint {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 2.8cqw;
  font-style: italic;
  text-align: center;
  color: #999;
}

@media (prefers-reduced-motion: reduce) {
  .class-card__inner { transition: none; }
}

/* --- alignment list --- */

/* .subhead carries no top margin, so a second overview block has to make its
   own gap below the one above it */
#class-overviews + .subhead,
#alignment-overviews + .subhead { margin-top: clamp(2.25rem, 6vh, 3.5rem); }

/* One double-ruled panel in the stat cards' idiom: an outer frame, an inner
   frame drawn inside it, and a gold stud on each of the inner frame's corners.
   The rows are divided by rules rather than set apart as cards. */
.align-panel {
  --align-gold: var(--gold-soft);

  background: rgba(0, 0, 0, 0.34);
  border: 1px solid rgba(227, 199, 104, 0.3);
  padding: 6px;
}

.align-panel__frame {
  position: relative;
  border: 1px solid rgba(227, 199, 104, 0.15);
  padding: 10px 0;
}

/* gold lozenges on the four corners of the inner frame, muted to read as trim
   the same way the stat cards' studs do */
.align-panel__stud {
  position: absolute;
  width: 7px;
  height: 7px;
  background: rgba(227, 199, 104, 0.45);
  transform: rotate(45deg);
}

.align-panel__stud--tl { top: -4px; left: -4px; }
.align-panel__stud--tr { top: -4px; right: -4px; }
.align-panel__stud--bl { bottom: -4px; left: -4px; }
.align-panel__stud--br { bottom: -4px; right: -4px; }

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

/* The rows are inset from the frame, so their separators stop short of its
   edges rather than running into the rule. */
.align-row {
  display: grid;
  grid-template-columns: clamp(56px, 5vw, 64px) minmax(0, 1fr);
  column-gap: clamp(1.125rem, 2.2vw, 1.75rem);
  margin: 0 clamp(1.25rem, 3.4vw, 2.25rem);
  padding: 1.625rem 0;
}

.align-row + .align-row { border-top: 1px solid rgba(227, 199, 104, 0.15); }

/* the line icon leads each row, hung level with the title's cap height */
.align-row__icon {
  align-self: start;
  justify-self: center;
  margin-top: 4px;
  width: clamp(38px, 3.6vw, 46px);
  height: clamp(38px, 3.6vw, 46px);
  color: var(--align-gold);
}

.align-row__text { min-width: 0; }

.align-row__name {
  margin: 0 0 0.375rem;
  font-family: "Cinzel", serif;
  font-size: clamp(1.3125rem, 1.15rem + 0.5vw, 1.5rem);
  font-weight: 400;
  letter-spacing: 0.04em;
  line-height: 1.2;
  color: #f4ecdf;
}

.align-row__desc {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: clamp(0.9rem, 0.85rem + 0.26vw, 1.0625rem);
  line-height: 1.6;
  text-wrap: pretty;
  color: #ddd3e0;
}

/* --- stat overviews --- */

/* Parchment cards on the dusk ground, so this section reads apart from the dark
   alignment panel above it. Each is a double-ruled frame with brass studs on the
   inner corners and a dark diamond medallion straddling its top edge — the
   medallion stays dark to keep the two sections related. It sits 36px proud of
   the frame, so the grid carries a matching top padding and row gap to clear it. */
.stat-grid {
  --stat-medallion: 56px;
  --stat-medallion-rise: 36px;
  --stat-gold: var(--gold-soft);

  /* aged paper: lit in the middle, darkening to the edges */
  --stat-parch-hi: var(--parch-1);
  --stat-parch-mid: #e6d3aa;
  --stat-parch-edge: #d8c08f;
  --stat-brass: #b8862f;
  --stat-stud: #9a6b24;
  --stat-ink-rule: rgba(110, 70, 30, 0.35);
  --stat-ink-divider: rgba(122, 74, 18, 0.7);
  --stat-ink-gem: #7a4a12;

  --stat-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  /* the ring the medallion punches through the card's top border: must match
     the act's ground behind the card, which this far down Act II is the tail of
     the dusk gradient */
  --stat-ground: #1a0d29;
  /* the medallion stays dark against the parchment rather than sharing its fill */
  --stat-medallion-fill: #120818;

  list-style: none;
  margin: 0;
  padding: calc(var(--stat-medallion-rise) + 32px) 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  column-gap: clamp(0.9rem, 1.9vw, 1.75rem);
  row-gap: calc(var(--stat-medallion-rise) + 32px);
}

/* the outer frame; .stat-card__frame draws the second one inside it */
.stat-card {
  background: radial-gradient(ellipse at 50% 40%,
              var(--stat-parch-hi) 0%, var(--stat-parch-mid) 70%, var(--stat-parch-edge) 100%);
  border: 1px solid var(--stat-brass);
  padding: 6px;
  box-shadow: var(--stat-shadow);
  transition: box-shadow 0.2s var(--ease);
}

/* hover lays a gold hairline outside the brass border, keeping the drop shadow */
.stat-card:hover { box-shadow: 0 0 0 1px var(--stat-gold), var(--stat-shadow); }

.stat-card__frame {
  position: relative;
  height: 100%;
  border: 1px solid var(--stat-ink-rule);
  padding: calc(var(--stat-medallion-rise) + 22px) clamp(1.1rem, 2.4vw, 2rem)
           clamp(1.3rem, 2.4vw, 2.125rem);
}

/* brass lozenges pinned to the four corners of the inner frame */
.stat-card__stud {
  position: absolute;
  width: 7px;
  height: 7px;
  background: var(--stat-stud);
  transform: rotate(45deg);
}

.stat-card__stud--tl { top: -4px; left: -4px; }
.stat-card__stud--tr { top: -4px; right: -4px; }
.stat-card__stud--bl { bottom: -4px; left: -4px; }
.stat-card__stud--br { bottom: -4px; right: -4px; }

/* The outer box-shadow ring is painted in the ground colour, so it reads as a
   gap cut through the card's top border rather than a disc laid over it. */
.stat-card__medallion {
  position: absolute;
  top: calc(var(--stat-medallion-rise) * -1);
  left: 50%;
  width: var(--stat-medallion);
  height: var(--stat-medallion);
  margin-left: calc(var(--stat-medallion) / -2);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--stat-medallion-fill);
  border: 1px solid var(--stat-gold);
  box-shadow: 0 0 0 5px var(--stat-ground), 0 0 0 6px rgba(227, 199, 104, 0.35);
  transform: rotate(45deg);
}

.stat-card__abbr {
  font-family: "Cinzel", serif;
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.06em;
  color: var(--stat-gold);
  transform: rotate(-45deg);
}

.stat-card__name {
  margin: 0;
  font-family: "Cinzel", serif;
  font-size: clamp(1.45rem, 1.1rem + 1.1vw, 1.875rem);
  font-weight: 400;
  letter-spacing: 0.04em;
  line-height: 1.2;
  text-align: center;
  color: #2a160c;
}

/* the rule under the title: two lines fading outward from a hollow gem */
.stat-card__rule {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 0.875rem 0 1.25rem;
}

.stat-card__rule-line {
  width: 56px;
  height: 1px;
  background: linear-gradient(to right, var(--stat-ink-divider), transparent);
}

.stat-card__rule-line:first-child {
  background: linear-gradient(to left, var(--stat-ink-divider), transparent);
}

.stat-card__rule-gem {
  width: 6px;
  height: 6px;
  border: 1px solid var(--stat-ink-gem);
  transform: rotate(45deg);
}

/* the tagline leads the description block, before the body copy */
.stat-card__tagline {
  margin: 0 0 0.625rem;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: clamp(0.95rem, 0.89rem + 0.3vw, 1.125rem);
  font-style: italic;
  font-weight: 700;
  line-height: 1.4;
  text-align: center;
  text-wrap: pretty;
  color: #8a3a14;
}

.stat-card__desc {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: clamp(0.9rem, 0.85rem + 0.26vw, 1.0625rem);
  line-height: 1.6;
  text-wrap: pretty;
  color: #3a261a;
}


/* ============================================================
   ACT III — THE SHEET
   ============================================================ */

/* The sheet is its own small design system, drawn in the parchment palette.
   Act III's ground and the torn edge above it are unchanged — these tokens
   only clothe the sheet itself. They sit on :root because the picker dialog
   renders at the end of the body, outside the act. */
:root {
  --s-ink: #2a1d12;
  --s-ink-soft: #6e5640;
  --s-label: #8e5a3c;
  --s-accent: #8e2b22;
  --s-legend-ink: #7e2a20;
  --s-card: rgba(249, 239, 224, 0.72);
  --s-card-border: #cdb69a;
  --s-field: #fdf9f2;
  --s-field-border: #c8b49b;
  --s-legend-fill: #e4cca4;
  --s-legend-border: #c2a37c;
  --s-dialog: #f6ead6;
  --s-tan: #b89a78;
  --s-dash: #d3bd9e;
  --s-dot: #bfa584;
  --s-btn: #221810;
  --s-btn-hover: #3a2a1c;
  --s-pos: #3d6b3f;
  --s-neg: #a3301f;
  --s-zero: #9a8064;
  --s-placeholder: #a8927a;
  --s-chosen: rgba(196, 168, 128, 0.18);
}

/* The upper glow reaches the top of the act, which left the top edge lighter on
   the right than on the left — and the torn edge above it washes out to flat
   --parch-edge, so any variation there reads as a seam. A band of that same
   flat colour sits over the glows and fades out below the tear, so the act
   starts as one colour and only then opens into the wash. */
.act--parchment {
  background:
    linear-gradient(to bottom, var(--parch-edge) 0, rgba(238, 218, 189, 0) var(--parch-top-fade)),
    radial-gradient(ellipse at 85% 30%, rgba(214, 178, 132, 0.35), transparent 55%),
    radial-gradient(ellipse at 10% 80%, rgba(214, 178, 132, 0.25), transparent 50%),
    var(--parch-edge);
  color: var(--s-ink);
}


/* ---------- section card ---------- */

.sheet-panel {
  margin: 0 0 28px;
  padding: 24px 22px;
  min-width: 0;
  background: var(--s-card);
  border: 1px solid var(--s-card-border);
  border-radius: 0;
  /* the double hairline just inside the card edge */
  box-shadow:
    inset 0 0 0 4px rgba(249, 239, 224, 0.6),
    inset 0 0 0 5px rgba(205, 182, 154, 0.5);
}

.sheet-grid > .sheet-panel,
.sheet-col > .sheet-panel { margin: 0; }

.legend {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  font-family: "Cinzel", serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.28em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--s-legend-ink);
  background: var(--s-legend-fill);
  border: 1px solid var(--s-legend-border);
  box-shadow:
    inset 0 0 0 2px var(--s-legend-fill),
    inset 0 0 0 3px rgba(142, 43, 34, 0.22);
}

/* --- the ornaments flanking a legend (script.js injects the spans) --- */

.orn { display: flex; align-items: center; gap: 4px; }
.orn > i { flex: none; display: block; }

.orn__rule {
  width: 18px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--s-legend-ink));
}

.orn__dot {
  width: 3px;
  height: 3px;
  background: var(--s-legend-ink);
  transform: rotate(45deg);
}

.orn__box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 7px;
  height: 7px;
  border: 1px solid var(--s-legend-ink);
  transform: rotate(45deg);
}

.orn__box > i { width: 3px; height: 3px; background: var(--s-legend-ink); }

/* the right-hand ornament mirrors the left: same spans, reversed, and the
   hairline fades the other way */
.orn--r { flex-direction: row-reverse; }
.orn--r .orn__rule { background: linear-gradient(270deg, transparent, var(--s-legend-ink)); }

/* ---------- shared fields ---------- */

.field-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: "Cinzel", serif;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--s-label);
}

.sheet-input {
  display: block;
  width: 100%;
  padding: 8px 10px;
  font-family: "Spectral", Georgia, serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--s-ink);
  background: var(--s-field);
  border: 1px solid var(--s-field-border);
  border-radius: 0;
  outline: none;
  transition: border-color 0.2s var(--ease);
}

.sheet-input:focus { border-color: var(--s-accent); }
textarea.sheet-input { resize: vertical; }

#sheet ::placeholder { color: var(--s-placeholder); font-style: italic; }

/* a ? beside a sheet label, linking back up to the matching overview */
.help {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  border: 1px solid rgba(142, 43, 34, 0.4);
  border-radius: 50%;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0;
  line-height: 1;
  text-decoration: none;
  color: var(--s-accent);
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}

.help:hover,
.help:focus-visible {
  color: var(--s-dialog);
  background: var(--s-accent);
  border-color: var(--s-accent);
}

/* ---------- buttons ---------- */

.btn-primary,
.btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 13px 22px;
  font-family: "Cinzel", serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border: 1px solid var(--s-btn);
  border-radius: 0;
  cursor: pointer;
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}

.btn-primary { color: var(--s-dialog); background: var(--s-btn); }
.btn-primary:hover { background: var(--s-btn-hover); }

.btn-secondary { color: var(--s-btn); background: transparent; }
.btn-secondary:hover { background: rgba(34, 24, 16, 0.06); }

/* greyed out but still readable, like the proficiencies past their limit */
.btn-primary:disabled,
.btn-secondary:disabled,
.btn-secondary[aria-disabled="true"] {
  opacity: 0.4;
  cursor: not-allowed;
}

.btn-primary:disabled:hover { background: var(--s-btn); }
.btn-secondary:disabled:hover,
.btn-secondary[aria-disabled="true"]:hover { background: transparent; }

.btn-link {
  padding: 8px;
  font-family: "Cinzel", serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--s-accent);
  background: none;
  border: none;
  text-decoration: underline;
  text-underline-offset: 4px;
  cursor: pointer;
}

.btn-link:hover { color: #5a2a6e; }

/* --- the original sheet buttons, kept for Download and Start over --- */

/* These two predate the sheet redesign and stay as they were: the PDF is the
   page's loudest action, and Start over stays quiet beside it. */
.btn {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  padding: 0.75rem 1.4rem;
  font-family: "Cinzel", "Times New Roman", serif;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--parch-1);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 2px;
  cursor: pointer;
  transition: transform 0.2s var(--ease), background 0.2s var(--ease), color 0.2s var(--ease);
}

.btn:hover { transform: translateY(-2px); background: #3a2a18; }
.btn:active { transform: translateY(0); }

.btn--primary {
  padding-inline: 2rem;
  font-size: 0.85rem;
  color: #fff8ea;
  background: var(--blood);
  border-color: var(--blood);
}

.btn--primary:hover { background: #992626; }

.btn--quiet {
  color: var(--ink-soft);
  background: transparent;
  border-color: transparent;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.btn--quiet:hover { color: var(--blood); background: transparent; }

/* ---------- 1. Identity ---------- */

.identity {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: flex-end;
}

/* The name gives ground to the pickers, but only so far: below this it would
   start clipping the name it is meant to display, so the pickers wrap to their
   own line instead. */
.identity__name {
  flex: 1 1 220px;
  min-width: 320px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  /* safe as a query container: its width comes from the flex basis, never from
     the name inside it */
  container-type: inline-size;
}

/* The pickers hug their content on desktop, so the name field absorbs the rest
   of the row and gives ground as the chosen values get longer. The row only
   wraps as a last resort — this site's races and backgrounds run long enough
   that four of them plus a name can outgrow the column. */
.identity__pickers {
  flex: 0 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: nowrap;
  gap: 16px;
}

.picker-field {
  flex: none;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
  text-align: left;
}

.name-input {
  width: 100%;
  height: 44px;
  padding: 0 13px;
  font-family: "Almendra", serif;
  font-weight: 400;
  /* 32px until the name outgrows the field — on a phone a long one would
     otherwise be cut off mid-word. --len is its length, set in script.js. */
  font-size: clamp(18px, calc((100cqw - 30px) / (var(--len, 4) * 0.5)), 32px);
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--s-ink);
  background: var(--s-field);
  border: 1px solid var(--s-field-border);
  border-radius: 0;
  outline: none;
}

.name-input:focus {
  border-color: var(--s-accent);
  box-shadow: 0 0 0 3px rgba(142, 43, 34, 0.12);
}

/* Once a name is set and the field is left alone it drops its box and reads as
   a name written on the page. */
.name-input.is-set {
  color: var(--s-accent);
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}

/* --- empty picker: a button dressed as an input --- */

/* No width here, and none on .pick-val: the column stretches them to its own
   width, and that width is the widest of the label and the button's content.
   A percentage width would collapse the field, since the column is sized from
   its content in the first place. */
.pick-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  height: 44px;
  padding: 0 12px;
  font-family: "Spectral", Georgia, serif;
  font-size: 15px;
  line-height: normal;
  text-align: left;
  color: #8a7560;
  background: var(--s-field);
  border: 1px solid var(--s-field-border);
  border-radius: 0;
  cursor: pointer;
  transition: border-color 0.2s var(--ease);
}

.pick-btn:hover { border-color: var(--s-accent); }
.pick-btn__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* the 2x2 grid of squares that marks a field as a picker */
.pick-btn__icon {
  flex: none;
  display: grid;
  grid-template-columns: 4px 4px;
  gap: 2px;
}

.pick-btn__icon > i { width: 4px; height: 4px; background: var(--s-tan); }

/* --- chosen picker: text on the page, faintly shaded --- */

.pick-val {
  display: block;
  height: 44px;
  padding: 0 12px;
  font-family: "Cinzel", serif;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.03em;
  line-height: 42px;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  color: var(--s-ink);
  background: var(--s-chosen);
  border: 1px solid transparent;
  border-radius: 0;
  cursor: pointer;
  transition: color 0.2s var(--ease);
}

.pick-val:hover { color: var(--s-accent); }

/* ---------- body columns ---------- */

.sheet-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr));
  gap: 28px;
  align-items: start;
  margin-bottom: 28px;
}

.sheet-col {
  display: flex;
  flex-direction: column;
  gap: 28px;
  min-width: 0;
}

/* ---------- 3. Ability scores & proficiencies ---------- */

.sheet-panel--abilities { padding-bottom: 18px; }

.roller {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}

/* Both buttons hold one line; they share the row rather than wrap. */
.roller > button {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
}

.roller__narrow { display: none; }

.ability-row {
  display: grid;
  grid-template-columns: 108px minmax(0, 1fr);
  gap: 18px;
  align-items: center;
  padding: 16px 0;
  border-top: 1px dashed var(--s-dash);
}

/* --- the octagonal score medallion --- */

/* An octagon nested inside a slightly larger one paints the 1.5px outline — a
   border would be cut away with the corners. */
.medallion {
  position: relative;
  width: 108px;
  height: 116px;
  background: var(--s-tan);
  clip-path: polygon(28% 0, 72% 0, 100% 20%, 100% 80%, 72% 100%, 28% 100%, 0 80%, 0 20%);
}

.medallion__inner {
  position: absolute;
  inset: 1.5px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  background: var(--s-field);
  clip-path: polygon(28% 0, 72% 0, 100% 20%, 100% 80%, 72% 100%, 28% 100%, 0 80%, 0 20%);
}

.medallion__name {
  font-family: "Cinzel", serif;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--s-accent);
}

.medallion__score {
  width: 64px;
  padding: 0;
  font-family: "Cinzel", serif;
  font-size: 34px;
  text-align: center;
  color: var(--s-ink);
  background: transparent;
  border: none;
  border-radius: 0;
  outline: none;
}

.medallion__score:focus { color: var(--s-accent); }

.medallion__bonus {
  font-family: "Cinzel", serif;
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
  color: var(--s-zero);
  cursor: help;
}

.medallion__bonus.is-pos { color: var(--s-pos); }
.medallion__bonus.is-neg { color: var(--s-neg); }

/* --- the proficiency list beside it --- */

.profs {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.profs__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  padding-bottom: 5px;
  border-bottom: 1px dotted var(--s-dot);
}

.profs__title {
  font-family: "Cinzel", serif;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--s-label);
}

.profs__count {
  font-family: "Alegreya", serif;
  font-size: 13px;
  font-style: italic;
  color: var(--s-ink-soft);
}

.profs__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 6px 12px;
}

.prof {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 0;
  font-family: "Spectral", Georgia, serif;
  font-size: 14px;
  text-align: left;
  color: var(--s-ink);
  background: none;
  border: none;
  cursor: pointer;
}

/* at the limit the unpicked entries stay readable but go inert */
.prof.is-locked { opacity: 0.4; cursor: not-allowed; }

/* the bonus a chosen proficiency carries, shown only once it is ticked */
.prof__bonus {
  display: none;
  font-family: "Alegreya", serif;
  font-size: 13px;
  font-style: italic;
  color: var(--s-pos);
}

.prof.is-on .prof__bonus { display: inline; }

.prof__box {
  flex: none;
  width: 14px;
  height: 14px;
  font-size: 10px;
  line-height: 12px;
  text-align: center;
  color: var(--s-dialog);
  background: var(--s-field);
  border: 1px solid var(--s-tan);
}

.prof.is-on .prof__box { background: var(--s-accent); border-color: var(--s-accent); }

/* ---------- 4. Saving throws ---------- */

.saves__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 12px;
}

.saves__caption {
  font-family: "Alegreya", serif;
  font-size: 15px;
  font-style: italic;
  color: var(--s-ink-soft);
}

.saves { display: flex; flex-direction: column; }

.save-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 44px;
  gap: 12px;
  align-items: center;
  padding: 8px 0;
  border-top: 1px dashed var(--s-dash);
}

.save-row__text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.save-row__name { font-size: 15px; }

/* the class's +2, on the two saves it is good at */
.save-row__note {
  font-family: "Alegreya", serif;
  font-size: 12px;
  font-style: italic;
  color: var(--s-accent);
}

.save-row__note:empty { display: none; }

/* the wax seal carrying the save's modifier */
.seal {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  font-family: "Cinzel", serif;
  font-size: 16px;
  font-weight: 600;
  color: var(--s-dialog);
  background: var(--s-accent);
  border-radius: 50%;
  box-shadow:
    inset 0 0 0 3px var(--s-accent),
    inset 0 0 0 4px rgba(246, 234, 214, 0.45);
}

/* ---------- panel footer: a pool and what is left of it ---------- */

/* The abilities' point total and proficiency tally. */
.panel-foot {
  display: flex;
  justify-content: flex-end;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px dashed var(--s-dash);
}

/* a second tally under the first shares its rule */
.panel-foot + .panel-foot { margin-top: 4px; padding-top: 0; border-top: 0; }

.panel-foot__label {
  font-family: "Cinzel", serif;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--s-label);
}

.panel-foot__status {
  font-family: "Alegreya", serif;
  font-size: 15px;
  font-style: italic;
  color: var(--s-ink-soft);
}

/* the pool is exactly spent */
.panel-foot__status.is-done { color: var(--s-pos); }

/* over the pool, or an edit refused for want of points */
.panel-foot__status.is-over { color: var(--s-neg); }

/* ---------- 6. Traits ---------- */

.traits-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 14px 12px;
  margin-bottom: 18px;
}

.trait { display: flex; flex-direction: column; gap: 6px; }

.traits__texts { display: flex; flex-direction: column; gap: 14px; }

/* a square the same height as the text inputs beside it */
.gender-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(1lh + 18px);
  height: calc(1lh + 18px);
  padding: 0;
  font-family: "Spectral", Georgia, serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--s-placeholder);
  background: var(--s-field);
  border: 1px solid var(--s-field-border);
  border-radius: 0;
  cursor: pointer;
  transition: border-color 0.2s var(--ease);
}

.gender-btn:hover { border-color: var(--s-accent); }
/* once chosen, the symbol stands on its own with no field behind it */
.gender-btn.is-set {
  color: var(--s-accent);
  background: transparent;
  border-color: transparent;
}

.gender-btn__glyph {
  font-family: "Segoe UI Symbol", "Noto Sans Symbols", serif;
  font-size: 18px;
  line-height: 1;
}

/* the symbol drawn in the picker, saved as a PNG */
.gender-btn__img {
  display: block;
  width: 22px;
  height: 22px;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

/* ---------- 7. Backstory ---------- */

/* The rules are painted on the textarea itself and scroll with the text
   (background-attachment: local), so they stay in step with the line boxes. */
.backstory {
  display: block;
  width: 100%;
  min-height: 280px;
  padding: 6px 16px;
  font-family: "Spectral", Georgia, serif;
  font-size: 16px;
  line-height: 30px;
  color: var(--s-ink);
  background-color: var(--s-field);
  /* One 30px tile repeated, rather than a repeating gradient sized to the box:
     left to size itself, the tile stretches with the textarea and the rules
     drift out of step with the lines. */
  background-image: linear-gradient(
    to bottom,
    transparent 0 29px,
    rgba(170, 138, 100, 0.35) 29px 30px
  );
  background-size: 100% 30px;
  background-repeat: repeat;
  background-attachment: local;
  background-position: 0 6px;
  border: 1px solid var(--s-field-border);
  border-radius: 0;
  outline: none;
  resize: vertical;
  transition: border-color 0.2s var(--ease);
}

.backstory:focus { border-color: var(--s-accent); }

/* ---------- footer actions ---------- */

.sheet-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 32px;
}

/* holds the buttons against the right edge whatever the message says */
.sheet-actions__note {
  margin-right: auto;
  font-family: "Alegreya", serif;
  font-size: 15px;
  font-style: italic;
  color: var(--s-ink-soft);
}

.footer-note {
  margin: clamp(3rem, 8vh, 5rem) 0 0;
  text-align: center;
  font-family: "IM Fell English", serif;
  font-size: 1.05rem;
  font-style: italic;
  color: var(--s-ink-soft);
}

/* ---------- 2. Picker dialog ---------- */

.picker-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(25, 11, 41, 0.6);
}

.picker-panel {
  width: 100%;
  max-width: 780px;
  max-height: 86vh;
  overflow: auto;
  padding: 28px;
  font-family: "Spectral", Georgia, serif;
  color: var(--s-ink);
  background: var(--s-dialog);
  border: 1px solid var(--s-tan);
  box-shadow:
    inset 0 0 0 4px var(--s-dialog),
    inset 0 0 0 5px rgba(184, 154, 120, 0.6),
    0 24px 60px rgba(25, 11, 41, 0.45);
}

.picker-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-bottom: 20px;
}

.picker-title {
  margin: 0;
  font-family: "Cinzel", serif;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--s-accent);
}

.picker-close {
  padding: 4px 8px;
  font-size: 24px;
  line-height: 1;
  color: var(--s-label);
  background: none;
  border: none;
  cursor: pointer;
}

.picker-close:hover { color: var(--s-accent); }

.picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 14px;
}

.tile {
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
  text-align: left;
  background: var(--s-field);
  border: 1px solid var(--s-field-border);
  border-radius: 0;
  cursor: pointer;
  transition: border-color 0.2s var(--ease);
}

.tile:hover { border-color: var(--s-accent); }
.tile.is-on { border-color: var(--s-accent); box-shadow: 0 0 0 2px var(--s-accent); }

.tile__art {
  display: flex;
  align-items: flex-end;
  width: 100%;
  aspect-ratio: 4 / 3;
  padding: 8px;
  /* the stripes stand in wherever no illustration exists yet */
  background: repeating-linear-gradient(135deg, #efe1c8 0 8px, #e7d5b7 8px 16px);
  font-family: ui-monospace, Menlo, monospace;
  font-size: 10px;
  color: #8e7356;
}

/* the classes already have their art, so their tiles show it */
/* sized to the picker's art (its artRatio in script.js) and fixed there, so a
   tile is the same shape before its lazy image arrives as after */
.tile__art--img {
  position: relative;
  aspect-ratio: var(--art-ratio, 4 / 3);
  padding: 0;
  overflow: hidden;
  background: #0b0710;
}
.tile__art--img > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* and the alignments already have their line icons */
.tile__art--icon {
  align-items: center;
  justify-content: center;
  padding: 14px;
  background: var(--s-dialog);
}

.tile__art--icon > svg { width: 56px; height: 56px; color: var(--s-accent); }

/* the gender tiles have a glyph where the others have a picture */
.tile__glyph {
  font-family: "Segoe UI Symbol", "Noto Sans Symbols", serif;
  font-size: 44px;
  line-height: 1;
  color: var(--s-accent);
}

.tile__cap {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  padding: 10px 12px;
  border-top: 1px solid #d8c4a6;
}

.tile__name {
  font-family: "Cinzel", serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--s-ink);
}

.tile__sub {
  font-family: "Alegreya", serif;
  font-size: 12px;
  font-style: italic;
  color: var(--s-label);
}

/* --- list layout: one row per item, its icon at the left --- */

/* rows sit flush, sharing their borders */
.picker-grid--list { grid-template-columns: 1fr; gap: 0; }
.picker-grid--list .tile + .tile { margin-top: -1px; }
.picker-grid--list .tile:hover { position: relative; z-index: 1; }

/* in a list the chosen row is filled rather than outlined */
.picker-grid--list .tile.is-on {
  background: var(--s-legend-fill);
  border-color: var(--s-field-border);
  box-shadow: none;
}
.picker-grid--list .tile.is-on .tile__art--icon { background: transparent; }

.picker-grid--list .tile { flex-direction: row; align-items: center; }

.picker-grid--list .tile__art {
  flex: none;
  width: 64px;
  aspect-ratio: 1;
  padding: 10px;
}

.picker-grid--list .tile__art--icon > svg { width: 40px; height: 40px; }

.picker-grid--list .tile__cap { border-top: 0; align-self: stretch; justify-content: center; }
.picker-grid--list .tile__art + .tile__cap { border-left: 1px solid #d8c4a6; }

/* --- the custom gender sketchpad --- */

.draw {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}

.draw__copy {
  font-family: "Alegreya", serif;
  font-size: 15px;
  font-style: italic;
  color: var(--s-ink-soft);
}

.draw__canvas {
  width: 260px;
  height: 260px;
  max-width: 100%;
  background: var(--s-field);
  border: 1px solid var(--s-field-border);
  box-shadow:
    inset 0 0 0 4px var(--s-field),
    inset 0 0 0 5px rgba(205, 182, 154, 0.5);
  touch-action: none;
  cursor: crosshair;
}

.draw__actions {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.draw__actions .btn-secondary,
.draw__actions .btn-primary { padding: 11px 18px; }

/* ---------- mobile (<700px) ---------- */

@media (max-width: 699px) {
  .identity { flex-wrap: wrap; }
  .identity__name { flex: 1 1 100%; min-width: 0; }
  .identity__pickers { flex: 1 1 100%; flex-wrap: wrap; }

  /* Two per row, so a field no longer hugs its value. Its width now comes from
     outside, which is what lets it act as a query container: --len is the
     value's character count, and a long value shrinks rather than truncating. */
  .picker-field {
    flex: 1 1 calc(50% - 8px);
    container-type: inline-size;
  }

  /* a value too long for half a row gets the whole one (see script.js) */
  .picker-field--long { flex: 1 1 100%; }

  .pick-val { font-size: clamp(11px, calc((100cqw - 26px) / (var(--len, 8) * 0.74)), 17px); }

  .ability-row { gap: 14px; }

  /* tightened so both buttons still share one line on a phone */
  .roller { gap: 8px; }
  .roller > button { padding-left: 12px; padding-right: 12px; letter-spacing: 0.08em; }
  .roller__wide { display: none; }
  .roller__narrow { display: inline; }

  /* likewise the footer buttons; a message gets its own line above them */
  .sheet-actions { gap: 8px; }
  .sheet-actions .btn { padding-inline: 1rem; letter-spacing: 0.08em; }
  .sheet-actions__note { order: -1; flex-basis: 100%; margin-right: 0; }
  .sheet-actions__note:empty { display: none; }

  /* the picker takes the whole screen rather than floating over a scrim */
  .picker-overlay { align-items: stretch; padding: 0; }
  .picker-panel {
    max-width: none;
    max-height: none;
    height: 100%;
    padding: 20px;
    border: 0;
    box-shadow: none;
  }
}

/* ---------- the copy photographed for the PDF ---------- */

.pdf-sheet {
  width: 960px;           /* PDF_WIDTH in script.js */
  color: var(--s-ink);
  background: var(--parch-edge);
}

.pdf-sheet .sheet-panel:last-child { margin-bottom: 0; }

/* a textarea's text, grown to its full length */
.pdf-text { white-space: pre-wrap; overflow-wrap: anywhere; }

/* ---------- print ---------- */

@media print {
  .picker-overlay,
  .sheet-actions,
  .roller,
  .scroll-cue { display: none; }

  .sheet-panel { break-inside: avoid; }
}

/* ---------- reveal on scroll ---------- */

.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}

.reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
  }
  .reveal { opacity: 1; transform: none; }
}
