/* ===========================================================================
   The god dialog - THE ten-page bestiary of the Shadowcorn pantheon.
   ===========================================================================

   WHAT CHANGED AND WHY, because the previous version was correct and still
   read badly:

   1. THE MISSING PORTRAIT WAS THE LOUDEST THING ON THE PAGE. Four of the ten
      gods had no render (07-10), and the pending state was a flat black box
      with a bullet and the words "Full portrait coming soon" - sitting in the
      1.2fr column, so the biggest single element in the dialog was an apology.
      It became a drafting sheet: plate lines, a survey grid and a stamped plate
      number, built entirely in CSS so it needs no asset and cannot 404 in its
      turn. An unfinished plate in a bestiary is an in-universe object. An empty
      box is a bug report.

      ALL TEN PLATES NOW EXIST (six painterly renders, four authored vector, see
      docs/shadowcorn-god-art-manifest.json), so in the shipped set nothing
      reaches the pending rule any more. It is kept, and must be: it is still
      the guard for a file that fails to decode or gets dropped from a deploy.
      The rule below is dormant, not dead - do not delete it because every god
      currently draws.

   2. THERE WAS NO TYPOGRAPHIC HIERARCHY. Beat headings were set at the same
      16px as the body they headed, so a page with three sections read as one
      long column. Headings are now small-caps, letterspaced and ruled, and the
      story opens on a drop cap - which also gives the eye somewhere to land on
      a paragraph that runs ten lines.

   3. THE ACCENT DOES NOT ALWAYS HAVE CONTRAST TO SPARE. The Crooked
      Cartographer's colour is #FBF3E7, a near-white parchment: as a title it is
      fine, as a 2px border on a dark panel it is a glare, and as italic body
      copy it is indistinguishable from the body text next to it. Accent use is
      now weighted - full strength for the title and rules, dialled back
      through colour-mix() for large fills - so a pale god and a saturated one
      both land.

   Everything here is presentation only. js/patron-dialog.js is unchanged in
   structure and every class name it writes still exists. */

:root {
  --god-ink: #fbf3e7;
  --god-muted: #c9badd;
  --god-base: #171020;
  --god-surface: #241a3d;
  --god-hover: #3a2f58;
  --god-gold: #f5c242;
  --god-scrim: rgb(8 5 16 / 82%);
  --god-shadow: 0 24px 80px rgb(0 0 0 / 60%);
  --god-radius: 16px;
  --god-gap: 24px;
  --god-padding: clamp(16px, 3vw, 32px);
  --god-width: 1120px;
  --god-icon: 68px;
  --god-small: 13px;
  --god-body: 16px;
  --god-heading: clamp(24px, 3vw, 32px);
  --god-target: 44px;
  --god-button-width: 160px;
  --god-edge: 2px;
  --god-focus: 3px;
  --god-tight: 8px;
  --god-copy-measure: 65ch;
  --god-font: 'Trebuchet MS', Verdana, sans-serif;

  /* A storybook serif for the display sizes. The pantheon is painterly fantasy
     and Trebuchet at 32px reads as a settings screen. Body copy stays on the
     sans, which is the more legible of the two at 16px on a dark ground. */
  --god-display: 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;

  /* Reading rhythm. 1.65 rather than 1.6 because these paragraphs are long and
     set light-on-dark, which needs marginally more air to stay tracked. */
  --god-leading: 1.65;
  --god-rule: rgb(251 243 231 / 14%);

  /* A fallback for the per-god accent. js/patron-dialog.js always sets
     --patron-accent on the dialog element, so this is never the value in use.
     It exists because color-mix() with an unresolved custom property makes the
     WHOLE declaration invalid, not just the colour: an accent that somehow went
     missing would take the panel's borders and rules with it. Declaring it here
     means the worst case is a gold-trimmed dialog rather than an untrimmed one. */
  --patron-accent: var(--god-gold);
}

.patron-dialog {
  box-sizing: border-box;
  width: min(var(--god-width), calc(100% - var(--god-gap)));
  max-width: none;
  max-height: calc(100dvh - var(--god-gap));
  margin: auto;
  padding: var(--god-padding);
  overflow: auto;
  overscroll-behavior: contain;
  color: var(--god-ink);
  /* A faint accent wash at the top edge so the panel picks up the god's colour
     without the whole surface being tinted. colour-mix keeps it at 8%, which
     survives a saturated orange and a near-white parchment equally. */
  background:
    radial-gradient(120% 60% at 50% 0%,
      color-mix(in srgb, var(--patron-accent) 8%, transparent) 0%,
      transparent 70%),
    linear-gradient(var(--god-surface), var(--god-base));
  border: var(--god-edge) solid color-mix(in srgb, var(--patron-accent) 55%, transparent);
  border-radius: var(--god-radius);
  box-shadow: var(--god-shadow);
  font-family: var(--god-font);
}
.patron-dialog::backdrop { background: var(--god-scrim); }
.patron-dialog * { box-sizing: border-box; }

/* ---------------------------------------------------------------- header -- */

.patron-dialog__header {
  text-align: center;
  margin-bottom: var(--god-gap);
  padding-bottom: var(--god-gap);
  border-bottom: 1px solid var(--god-rule);
}
.patron-dialog__sigil {
  width: var(--god-icon);
  height: var(--god-icon);
  /* Lifts the sigil off the flat panel and ties it to the god's colour. */
  filter: drop-shadow(0 0 14px color-mix(in srgb, var(--patron-accent) 45%, transparent));
}
.patron-dialog__title {
  margin: var(--god-tight) 0 6px;
  font-family: var(--god-display);
  font-size: var(--god-heading);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: 0.01em;
  color: var(--patron-accent);
}
.patron-dialog__epithet {
  margin: 0;
  font-size: var(--god-small);
  /* Small caps and tracking turn the epithet into a subtitle rather than a
     second, smaller sentence competing with the title above it. */
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--god-muted);
}

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

.patron-dialog__body { display: grid; gap: var(--god-gap); align-items: start; }

.patron-dialog__frame {
  margin: 0;
  padding: var(--god-tight);
  background: var(--god-base);
  border: 1px solid color-mix(in srgb, var(--patron-accent) 45%, transparent);
  border-radius: var(--god-radius);
  overflow: hidden;
}
.patron-dialog__art {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: contain;
  border-radius: calc(var(--god-radius) - var(--god-tight));
}

/* ------------------------------------------- the unfinished plate (dormant) --

   No god reaches this today; see note 1 in the header. It remains the fallback
   for a plate that fails to decode, and it is built to be worth looking at:

     - a survey grid, drawn with two repeating-linear-gradients, fading out to
       the edges through a mask so it reads as a sheet rather than as graph paper
     - plate rules inset from the frame, the way a real drawing plate is ruled
     - a compass mark and a plate number, so the empty space is captioned like
       an artefact instead of apologising like a placeholder

   It costs no asset, no request and no JS. The one thing it must never do is
   look like a loading failure.

   HISTORICAL NOTE, kept because it is the reason the Cartographer's portrait
   looks the way it does: this frame used to be what HIS page showed, and the
   observation at the time was that for the god whose entire domain is maps that
   are not finished being wrong, a drafting sheet was arguably more on-theme than
   any portrait would be. That turned out to be the design brief rather than a
   consolation - his shipped plate is a survey sheet, drawn on this same 34px
   grid. He no longer reaches this rule. */

.patron-dialog__frame--pending {
  display: grid;
  place-items: center;
  gap: 10px;
  aspect-ratio: 16 / 9;
  position: relative;
  padding: clamp(14px, 4%, 28px);
  color: var(--patron-accent);
  text-align: center;
  background:
    repeating-linear-gradient(0deg,
      var(--god-rule) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(90deg,
      var(--god-rule) 0 1px, transparent 1px 34px),
    radial-gradient(90% 70% at 50% 45%,
      color-mix(in srgb, var(--patron-accent) 10%, transparent) 0%,
      transparent 72%),
    var(--god-base);
}
/* The ruled plate border, inset from the frame edge. A pseudo-element rather
   than a second border on the frame so it can sit inside the padding. */
.patron-dialog__frame--pending::before {
  content: '';
  position: absolute;
  inset: 10px;
  border: 1px solid color-mix(in srgb, var(--patron-accent) 30%, transparent);
  border-radius: calc(var(--god-radius) - 10px);
  pointer-events: none;
}
.patron-dialog__art-pending-mark {
  margin: 0;
  font-size: clamp(26px, 5vw, 38px);
  line-height: 1;
  /* A drawn mark on a sheet, not a glowing icon. */
  text-shadow: 0 0 18px color-mix(in srgb, var(--patron-accent) 50%, transparent);
}
.patron-dialog__art-pending-text {
  margin: 0;
  max-width: 34ch;
  color: var(--god-muted);
  font-size: var(--god-small);
  text-transform: uppercase;
  letter-spacing: 0.16em;
  line-height: 1.5;
}

/* ------------------------------------------------------------------ copy -- */

.patron-dialog__copy {
  min-width: 0;
  max-width: var(--god-copy-measure);
  font-size: var(--god-body);
  line-height: var(--god-leading);
}

/* The one-liner is the god's voice. Pulled up to display size and ruled on the
   left so it reads as a pull quote rather than as the story's first sentence -
   which is exactly how it read before, at body size in the accent colour. */
.patron-dialog__quote {
  margin: 0 0 var(--god-gap);
  padding-left: 16px;
  border-left: 3px solid color-mix(in srgb, var(--patron-accent) 70%, transparent);
  font-family: var(--god-display);
  font-size: clamp(17px, 1.6vw, 20px);
  font-style: italic;
  line-height: 1.45;
  /* Mixed toward the ink rather than the raw accent: a near-white accent at
     italic body weight was invisible against the copy beside it. */
  color: color-mix(in srgb, var(--patron-accent) 78%, var(--god-ink));
}

.patron-dialog__story { margin: 0 0 var(--god-gap); }

/* The drop cap. These stories run eight to twelve lines as a single block, and
   an opening capital is the cheapest way to give that block a front door.
   ::first-letter is safe on a <p> and degrades to nothing if it is ever not. */
.patron-dialog__story::first-letter {
  float: left;
  margin: 4px 10px 0 0;
  font-family: var(--god-display);
  font-size: 3.1em;
  line-height: 0.82;
  font-weight: 600;
  color: var(--patron-accent);
}

.patron-dialog__domain {
  margin: 0;
  padding-top: var(--god-tight);
  border-top: 1px solid var(--god-rule);
  color: var(--god-muted);
  font-size: var(--god-small);
  text-transform: uppercase;
  letter-spacing: 0.14em;
}

/* --------------------------------------------------- the Cartographer page --

   Only one god carries `feature`, and it is a genuine second page of lore
   rather than an appendix, so it is set like one: a centred lead-in at display
   size, then the beats as numbered sheets across a ruled survey plate. See
   js/lore.js crooked_cartographer. */

/* THE PROBLEM THIS LAYOUT SOLVES. The feature spans the full 1120px dialog
   (grid-column 1 / -1), but every beat was capped at --god-copy-measure, 65ch.
   So on a desktop the Cartographer's own page was three paragraphs stacked in a
   ~600px ribbon hugging the left edge, with 450px of empty panel beside them.
   Three sections of real lore read as an afterthought bolted to the bottom of
   the dialog, which is the one impression this page must not give: it is the
   only god with a second page and it has to look like it earned it.

   So the beats now flow into COLUMNS and fill the plate. The measure is still
   protected - at three columns each beat sets to roughly 40 characters, which
   is a proper column measure, not a squeezed one - and the max-width is
   released only inside this grid, where the column itself is the constraint. */

.patron-dialog__feature {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--god-gap);
  margin-top: var(--god-tight);
  padding: var(--god-gap) clamp(14px, 2.5%, 26px) clamp(14px, 2.5%, 26px);
  border-top: 1px solid color-mix(in srgb, var(--patron-accent) 40%, transparent);
  border-radius: 0 0 calc(var(--god-radius) - 4px) calc(var(--god-radius) - 4px);

  /* The Cartographer's own survey sheet, reusing the exact grid the pending
     art plate is drawn with so the two read as the same artefact. Held at a
     34px pitch and --god-rule's 14% so it is texture the eye resolves on a
     second look, never ruling the copy competes with. */
  background:
    repeating-linear-gradient(0deg, var(--god-rule) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(90deg, var(--god-rule) 0 1px, transparent 1px 34px),
    radial-gradient(120% 80% at 50% 0%,
      color-mix(in srgb, var(--patron-accent) 7%, transparent) 0%,
      transparent 68%);

  /* Numbering runs across the beats. Reset on the section so the count starts
     at one every time the dialog is rebuilt for a different god. */
  counter-reset: beat;
}

.patron-dialog__feature-kicker {
  grid-column: 1 / -1;
  margin: 0 auto;
  max-width: 46ch;
  font-family: var(--god-display);
  /* A step DOWN from the old --god-heading. At 32px bold this was the same
     weight as the god's own name and fought it for the top of the page. */
  font-size: clamp(19px, 2.1vw, 25px);
  font-weight: 600;
  font-style: italic;
  line-height: 1.35;
  /* Centred now that it leads a spread rather than a left-aligned ribbon. It
     is the page's title line, and a title that starts hard left above three
     columns reads as the first column's heading instead. */
  text-align: center;
  text-wrap: balance;
  color: color-mix(in srgb, var(--patron-accent) 82%, var(--god-ink));
}

.patron-dialog__beat {
  counter-increment: beat;
  margin: 0;
  /* Released deliberately: inside this grid the COLUMN is the measure, and a
     65ch cap on a 330px column does nothing but sit there being confusing. */
  max-width: none;
  padding: 14px 16px 16px;
  background: color-mix(in srgb, var(--god-base) 72%, transparent);
  border: 1px solid var(--god-rule);
  border-radius: calc(var(--god-radius) - 6px);
}

/* The fix that does most of the work. These were 16px gold - the same size as
   the paragraph under them - so three sections read as one. Small caps,
   tracked, with a short rule under, makes the structure visible at a glance. */
.patron-dialog__beat-heading {
  margin: 0 0 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--god-rule);
  font-family: var(--god-font);
  font-size: var(--god-small);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  line-height: 1.35;
  color: var(--god-gold);
}

/* The section number, in the register the pending-art frame already established.
   Generated content, so js/patron-dialog.js stays untouched and a beat count
   that changes in js/lore.js renumbers itself. Decorative only: the heading
   text above it carries the meaning, so a screen reader that skips generated
   content loses nothing.

   'Sheet' AND NOT 'PLATE', deliberately. The pending portrait frame in this
   same dialog is captioned 'Plate 09 of 10' - that is the BESTIARY's numbering,
   one plate per god. Numbering the Cartographer's three story sections 'Plate I,
   II, III' would put two different, unrelated plate counts on one page. Sheets
   are what a surveyor's work comes in, so the word is both free of the clash and
   more his. */
.patron-dialog__beat-heading::before {
  content: 'Sheet ' counter(beat, upper-roman);
  display: block;
  margin-bottom: 6px;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.24em;
  color: color-mix(in srgb, var(--patron-accent) 60%, var(--god-muted));
}

.patron-dialog__beat-body { margin: 0; font-size: var(--god-body); line-height: var(--god-leading); }

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

.patron-dialog__footer {
  margin-top: var(--god-gap);
  padding-top: var(--god-gap);
  border-top: 1px solid var(--god-rule);
  text-align: center;
}
.patron-dialog__close {
  min-width: var(--god-button-width);
  min-height: var(--god-target);
  padding: var(--god-tight) var(--god-gap);
  border: var(--god-edge) solid color-mix(in srgb, var(--patron-accent) 60%, transparent);
  border-radius: var(--god-radius);
  background: var(--god-surface);
  color: var(--god-ink);
  font: inherit;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.patron-dialog__close:hover {
  background: var(--god-hover);
  border-color: var(--patron-accent);
}
.patron-dialog__close:focus-visible { outline: var(--god-focus) solid var(--god-gold); outline-offset: var(--god-focus); }

@media (min-width: 768px) {
  .patron-dialog__body { grid-template-columns: 1.2fr 1fr; }

  /* Two columns before three, so the beats never set narrower than about 38
     characters. Below this the single column above is still the right answer -
     a 340px phone split in two is two columns of nothing. */
  .patron-dialog__feature { grid-template-columns: repeat(2, 1fr); }
}

/* Three across, which is one clean row for the Cartographer's three beats and
   fills the plate edge to edge. Set at 1100px rather than at the dialog's own
   1120px max so the layout arrives just before the panel stops growing, and the
   final step is the columns settling rather than a wide gap opening up. */
@media (min-width: 1100px) {
  .patron-dialog__feature { grid-template-columns: repeat(3, 1fr); }
}

/* The drop cap is decoration, and at the narrowest widths it costs a line of
   measure it cannot pay back. Dropped below the single-column breakpoint. */
@media (max-width: 420px) {
  .patron-dialog__story::first-letter {
    float: none;
    margin: 0;
    font-size: inherit;
    line-height: inherit;
    color: inherit;
  }
}
