/* Wardery -- its own visual world, deliberately unlike the rest of
   FindTheCool. Scoped entirely under .wardery-world so nothing here can
   leak into the site's own header/bottom-nav chrome (styles.css owns
   those, unchanged) and nothing in styles.css can leak in here either.
   Palette, type, and every component below trace directly to the
   owner's own published design charter for this feature -- not invented
   here. See WARDERY-DEV-PLAN.md section 7 for the engineering spec this
   implements. */

.wardery-world {
  --vellum: #ede3cc;
  --vellum-shadow: #d9c9a3;
  --panel: #f4ecd8;
  --ink: #2b2018;
  --seal: #7a2331;
  --seal-deep: #4f1620;
  --seal-bright: #9c3a4a;
  --brass: #8c6a2e;
  --forest: #2f4a38;
  --teal: #2f6a66;
  --muted: #6b5d45;
  --rule: #c3b28c;
  --unstaked: #9a8a63;
}
/* DELIBERATELY LIGHT-ONLY -- please don't reintroduce a dark mode here.
   Three reasons, in order of weight:
   1. wardery.css was the ONLY file on the whole site with a
      prefers-color-scheme block. styles.css, the Crawl pages,
      /quickadd, /moderate and /account are all light-only, so a dark
      Wardery made ONE page flip against the rest -- a light site
      dropping into a dark one, under FindTheCool's own light header.
      That fights the "you are still inside FindTheCool" rule.
   2. This world is a PAPER record -- vellum, ink, a wax seal,
      rubricated capitals, blind embossing, hatching. Every one of those
      metaphors assumes a light sheet. Dark mode inverts paper into
      not-paper; "dark parchment" isn't a thing.
   3. It was a live bug factory. The hatch shipped invisible (1.54:1
      against the dark ground) purely because a value chosen against
      vellum got token-flipped onto a dark one -- and that failure mode
      recurs for every ornamental value: wash, emboss, mottle, seal. */

.wardery-world {
  box-sizing: border-box;
  position: relative; /* the frame's inner rule and corner scrollwork hang off this */
  background: var(--vellum);
  /* Paper, in three layers rather than one flat fill: a fine grain tile
     on top, a vignette drawing the edges down, then the two existing
     stains. The grain is a 140px SVG tile rather than a live filter over
     the whole page -- feTurbulence across a full-height document is
     genuinely expensive on a phone, whereas a tile is rasterised once
     and repeated for free. */
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E"),
    radial-gradient(ellipse at 50% 38%, transparent 55%, rgba(107,93,69,0.13) 100%),
    radial-gradient(ellipse at 12% 6%, rgba(140,106,46,0.10), transparent 40%),
    radial-gradient(ellipse at 92% 88%, rgba(122,35,49,0.07), transparent 45%);
  color: var(--ink);
  font-family: "EB Garamond", Georgia, "Times New Roman", serif;
  font-size: 17px;
  line-height: 1.6;
  padding: 40px clamp(16px, 4vw, 48px) 90px;
}
.wardery-world *, .wardery-world *::before, .wardery-world *::after { box-sizing: border-box; }
.wardery-world ::selection { background: var(--seal); color: var(--panel); }
.wardery-world a { color: var(--seal); }
.wardery-world button { font-family: inherit; }
.wardery-world :focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

/* Firefox + WebKit scrollbar theming for any internal scroll region */
.wardery-world .wardery-scroll {
  scrollbar-width: thin;
  scrollbar-color: var(--brass) var(--vellum-shadow);
}
.wardery-world .wardery-scroll::-webkit-scrollbar { width: 9px; height: 9px; }
.wardery-world .wardery-scroll::-webkit-scrollbar-track { background: var(--vellum-shadow); }
.wardery-world .wardery-scroll::-webkit-scrollbar-thumb { background: var(--brass); border-radius: 5px; }

.wardery-world .smallcaps { font-family: "IM Fell English SC", "EB Garamond", serif; }
.wardery-kicker {
  font-family: "IM Fell English SC", serif; font-size: 13px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--seal);
  border-bottom: 1px solid var(--rule); padding-bottom: 8px; margin: 0 0 6px;
  max-width: 900px;
}
.wardery-world h1 {
  font-family: "IM Fell Great Primer", serif; font-weight: 400; font-size: clamp(40px, 7vw, 68px);
  line-height: 0.92; margin: 6px 0 4px; color: var(--seal-deep);
  text-shadow: 1px 1px 0 rgba(140,106,46,0.22); text-wrap: balance;
}
.wardery-world h2 {
  font-family: "IM Fell Great Primer", serif; font-weight: 400; font-size: 30px; line-height: 1;
  margin: 0 0 4px; color: var(--seal-deep); text-wrap: balance;
}
.wardery-world h3 {
  font-family: "IM Fell English SC", serif; font-size: 19px; font-weight: 400;
  letter-spacing: 0.01em; margin: 0 0 4px;
}
.wardery-tagline { font-size: 17px; font-style: italic; color: var(--muted); max-width: 56ch; margin: 0 0 28px; }

.wardery-panel {
  background: var(--panel); border: 1px solid var(--rule);
  box-shadow: 0 1px 0 var(--rule), inset 0 0 0 1px rgba(140,106,46,0.10);
  padding: 20px 22px;
}

.wardery-explainer { padding: 0; margin-bottom: 28px; }
.wardery-explainer-summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  cursor: pointer; list-style: none; padding: 16px 22px;
  font-family: "IM Fell English SC", serif; font-size: 15px; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--seal);
}
.wardery-explainer-summary::-webkit-details-marker { display: none; }
.wardery-explainer-summary::after {
  content: "\2767"; font-size: 15px; color: var(--brass); flex-shrink: 0;
  transition: transform 200ms ease;
}
.wardery-explainer[open] .wardery-explainer-summary::after { transform: rotate(90deg); }
.wardery-explainer-summary:hover { color: var(--seal-deep); }
.wardery-explainer-body { padding: 0 22px 24px; border-top: 1px solid var(--rule); }
.wardery-explainer-lede { font-size: 15.5px; color: var(--ink); margin: 18px 0 22px; max-width: 62ch; }
.wardery-explainer-heading {
  font-family: "IM Fell English SC", serif; font-size: 14px; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--brass); margin: 24px 0 10px;
  border-bottom: 1px solid var(--rule); padding-bottom: 6px;
}
.wardery-explainer-heading:first-of-type { margin-top: 0; }
.wardery-explainer-text { font-size: 14.5px; color: var(--ink); margin: 0; max-width: 62ch; }
.wardery-glossary { margin: 0; }
.wardery-glossary-row { padding: 11px 0; border-top: 1px solid var(--rule); }
.wardery-glossary-row:first-of-type { border-top: none; }
.wardery-glossary-row dt {
  font-family: "IM Fell English SC", serif; font-size: 13px; letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--seal); margin: 0 0 3px;
}
.wardery-glossary-row dd { margin: 0; font-size: 14.5px; color: var(--ink); }

.wardery-button {
  font-family: "IM Fell English SC", serif; font-size: 16px; letter-spacing: 0.02em;
  color: var(--panel); background: linear-gradient(160deg, var(--seal), var(--seal-deep));
  border: 1px solid var(--seal-deep); border-radius: 2px; padding: 11px 20px;
  cursor: pointer; box-shadow: 0 2px 4px rgba(0,0,0,0.2);
  transition: transform 120ms ease-out, box-shadow 120ms ease-out;
}
.wardery-button:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 4px 8px rgba(0,0,0,0.25); }
.wardery-button:active:not(:disabled) { transform: translateY(0); }
.wardery-button:disabled { opacity: 0.55; cursor: default; box-shadow: none; }
.wardery-button-quiet {
  font-family: "IM Fell English SC", serif; font-size: 14.5px; color: var(--muted);
  background: transparent; border: 1px solid var(--rule); border-radius: 2px;
  padding: 8px 14px; cursor: pointer;
}
.wardery-button-quiet:hover { color: var(--ink); border-color: var(--brass); }

.wardery-status { font-size: 15px; color: var(--muted); font-style: italic; }
.wardery-status.wardery-status-error { color: var(--seal); font-style: normal; }

/* ---------- Layout: map + docked House detail ---------- */
.wardery-shire-layout {
  display: grid; grid-template-columns: 1fr 340px; gap: 22px;
  margin-bottom: 46px; align-items: start;
}
@media (max-width: 900px) {
  .wardery-shire-layout { grid-template-columns: 1fr; }
}

/* Forces the shared site header fully opaque while the Shire Map is
   scrolled up underneath it -- toggled by wardery.js based on scroll
   position (see wardery_syncHeaderOpacityOverMap). Higher specificity
   than styles.css's own bare .site-header rule, so no !important
   needed; this page only, every other page's header is untouched. */
.site-header.wardery-header-solid {
  background: #fff;
  backdrop-filter: none;
}

/* Leaflet's own tile/marker panes are GPU-composited (transform:
   translate3d, for pan/zoom performance) and carry internal z-index
   values from 200 to 700 -- all far above the shared site header's
   z-index: 20. Neither .wardery-map-frame nor Leaflet's own
   .leaflet-container ever established a real stacking context
   (position: relative alone, with z-index: auto, does not), so nothing
   contained those values to the map itself. Logical stacking (DOM
   z-index) still resolved correctly on inspection, but the browser's
   own compositor could still paint the map's separately-composited
   layer over the header's sticky one -- a real, documented Chromium
   quirk between position: sticky and transform-composited siblings,
   not a CSS logic bug (which is why it never showed up in
   getBoundingClientRect/elementFromPoint checks, only in what actually
   painted on a real screen). Found live: the owner's own screenshots
   kept showing the header disappearing specifically over the map
   portion of the page, never over plain content beside it.
   Two-part fix: contain Leaflet's own z-index values to the map itself
   (a real stacking context this time, via position + z-index together,
   not position alone), and force the header onto its own explicit
   GPU layer so the compositor can never re-order it relative to
   Leaflet's composited layers. wardery.css only loads on this page, so
   this .site-header rule can never affect any other page's header. */
.site-header { transform: translateZ(0); }

/* ---------- Map ---------- */
/* A ruled double-border, like a plate bound into an atlas or a roll --
   drawn with inset box-shadows so it can never clip Leaflet's own
   controls (a clip-path here would risk cutting off the zoom/locate
   buttons Leaflet positions right at the frame's own edges). */
.wardery-map-frame {
  border: 1px solid var(--rule); padding: 8px; background: var(--panel);
  position: relative; z-index: 0;
  box-shadow: inset 0 0 0 4px var(--panel), inset 0 0 0 5px var(--brass);
}
#wardery-map {
  width: 100%; height: clamp(360px, 52vw, 520px); display: block;
  background: var(--vellum-shadow);
}
@media (max-width: 600px) { #wardery-map { height: 340px; } }

/* Tint the real OSM tile layer into an aged-parchment reading, rather
   than replacing it with an illustration -- this is a real, working map.
   Scoped to .leaflet-tile-pane, NOT the whole .leaflet-container: Leaflet
   renders markers into a sibling .leaflet-marker-pane inside the same
   container, so a container-wide filter was aging the Order pins right
   alongside the tiles -- especially brightness(0.42) in dark mode, which
   crushed every pin toward near-black regardless of its own colour,
   defeating the whole point of colour-coding Houses by controlling Order.
   Confirmed live: with the filter scoped here instead, pins render at
   their real, distinct palette values while the tiles stay just as aged. */
.wardery-map-frame .leaflet-container {
  background: var(--vellum-shadow);
}
/* Pushed further back than the original aged-parchment tint, because the
   tiles are no longer the top layer of the drawing: the hatched ground
   sits over them now, and OSM at its old contrast fought that hatch into
   mud. Lower contrast and a little transparency turn the streets into
   the faint tracery a survey sheet draws UNDER its own hatching, which
   is what makes the plate read as one drawing instead of a web map with
   a texture on top. Still the real OSM layer, still pans and zooms. */
.wardery-map-frame .leaflet-tile-pane {
  filter: sepia(0.55) saturate(0.3) brightness(1.06) contrast(0.8) opacity(0.55);
}

/* ---------- The cartographic plate ---------- */
/* Both of these are Leaflet paths, so Leaflet writes fill/stroke onto
   them as SVG PRESENTATION ATTRIBUTES. Styling them from CSS instead is
   deliberate and load-bearing twice over: a pattern fill has to be
   url(#id) and every colour here is a custom property, and neither one
   survives as a presentation attribute -- and because presentation
   attributes lose to every CSS rule, Leaflet's own restyles on
   pan/zoom/setLatLngs can never clobber what's set here. */
.wardery-world .wardery-ground-hatch {
  fill: url(#wardery-hatch);
  stroke: none;
}
.wardery-world .wardery-realm-wash {
  fill: url(#wardery-realm-wash);
  stroke: var(--seal);
  stroke-width: 1.6;
  stroke-opacity: 0.72;
}

/* The pattern definitions themselves. Referenced by url(#id) from the
   Leaflet paths above -- an SVG paint reference resolves across the
   whole document, so these can live in their own hidden <svg> rather
   than being injected into Leaflet's own <svg> on every redraw. */
.wardery-plate-defs {
  position: absolute; width: 0; height: 0; overflow: hidden;
}

/* ---------- The plate's marginalia ---------- */
/* Positioned on the FRAME rather than inside the map, so it holds still
   while the ground pans under it -- the furniture belongs to the sheet,
   not to the territory.
   z-index 850 clears Leaflet's popups (700) but stays under its control
   containers (1000), so the zoom and locate buttons always win a fight
   over the same pixel. Everything here is pointer-events: none except
   the key, which is the one piece a reader actually operates -- none of
   it may ever intercept a drag meant for the map. */
.wardery-map-frame > .wardery-plate-cartouche,
.wardery-map-frame > .wardery-plate-key,
.wardery-map-frame > .wardery-plate-rose {
  position: absolute; z-index: 850;
}
.wardery-plate-cartouche, .wardery-plate-rose { pointer-events: none; }

.wardery-plate-cartouche {
  top: 20px; left: 20px; max-width: 296px;
  background: var(--panel); border: 1px solid var(--brass);
  padding: 13px 17px 12px;
}
/* The inner of the two rules -- a drawn double border, the same
   convention as the map frame's own, at cartouche scale. */
.wardery-plate-cartouche::after {
  content: ""; position: absolute; inset: 3px;
  border: 1px solid var(--rule); pointer-events: none;
}
.wardery-plate-kicker {
  font-family: "IM Fell English SC", serif; font-size: 10.5px;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--brass);
  position: relative;
}
.wardery-plate-fleuron {
  display: block; width: 100%; height: 12px; margin: 8px 0 8px;
  color: var(--brass); position: relative;
}
.wardery-plate-note {
  margin: 0; font-size: 13px; line-height: 1.45; color: var(--ink); position: relative;
}

.wardery-plate-key {
  left: 20px; bottom: 20px; max-width: 264px;
  background: var(--panel); border: 1px solid var(--brass);
  pointer-events: auto;
}
.wardery-plate-key-summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 10px;
  /* 44px, not 40: this is the only piece of the furniture anyone
     operates, and on a phone it's operated with a thumb. */
  min-height: 44px; padding: 0 14px;
  font-family: "IM Fell English SC", serif; font-size: 11.5px;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--brass);
}
.wardery-plate-key-summary::-webkit-details-marker { display: none; }
/* The same brass fleuron the explainer's own disclosure uses, rotating
   rather than a generic chevron -- one disclosure idiom for the world. */
.wardery-plate-key-summary::after {
  content: "\2767"; margin-left: auto; font-size: 13px;
  transition: transform 0.18s ease;
}
.wardery-plate-key[open] .wardery-plate-key-summary::after { transform: rotate(90deg); }
.wardery-plate-key-summary:hover { color: var(--seal); }
.wardery-plate-key-body {
  margin: 0; padding: 8px 14px 12px; border-top: 1px solid var(--rule);
}
.wardery-plate-key-row { display: flex; align-items: center; gap: 10px; padding: 5px 0 0; }
.wardery-plate-key-row dt { flex: 0 0 22px; display: flex; align-items: center; justify-content: center; }
.wardery-plate-key-row dt svg { width: 22px; height: 22px; overflow: visible; }
.wardery-plate-key-row dd { margin: 0; font-size: 12.5px; line-height: 1.35; color: var(--ink); }

.wardery-plate-rose {
  right: 20px; bottom: 46px; width: 54px; height: 54px; color: var(--brass);
}

/* Leaflet's OWN scale control, restyled -- never a drawn one. A fixed
   scale bar on a map that zooms would be a decoration that lies. */
.wardery-map-frame .leaflet-control-scale { margin: 0 20px 22px 0; }
.wardery-map-frame .leaflet-control-scale-line {
  background: var(--panel); border: 1px solid var(--ink); border-top: none;
  border-radius: 0; box-shadow: none; padding: 1px 7px 2px; line-height: 1.35;
  font-family: "IM Fell English SC", serif; font-size: 10.5px; letter-spacing: 0.08em;
  color: var(--ink);
}
.wardery-map-frame .leaflet-control-attribution {
  background: var(--panel); color: var(--muted);
  font-family: "EB Garamond", Georgia, serif; font-size: 10.5px;
}
.wardery-map-frame .leaflet-control-attribution a { color: var(--seal); }

/* On a 340px map the furniture must not eat the ground it explains: the
   cartouche goes to a single full-width band, the key stays collapsed
   (it is a <details>, so that costs nothing), and the rose stands down
   entirely -- north being up is the least urgent thing on a phone. */
@media (max-width: 600px) {
  .wardery-plate-cartouche {
    top: 12px; left: 12px; right: 12px; max-width: none; padding: 10px 13px 9px;
  }
  .wardery-plate-note { font-size: 12.5px; }
  .wardery-plate-fleuron { margin: 6px 0; }
  .wardery-plate-key { left: 12px; bottom: 12px; max-width: calc(100% - 24px); }
  .wardery-plate-rose { display: none; }
  .wardery-map-frame .leaflet-control-scale { margin: 0 12px 18px 0; }
}
.wardery-map-frame .leaflet-control-zoom a {
  background: var(--panel); color: var(--ink); border: 1px solid var(--rule) !important;
  font-family: "EB Garamond", serif;
}
.wardery-map-frame .leaflet-control-zoom a:hover { background: var(--vellum-shadow); }
.wardery-map-frame .leaflet-popup-content-wrapper {
  background: var(--panel); border: 1px solid var(--rule); border-radius: 2px;
  box-shadow: 0 3px 10px rgba(0,0,0,0.28);
}
.wardery-map-frame .leaflet-popup-content {
  font-family: "EB Garamond", serif; color: var(--ink); margin: 12px 14px; font-size: 15px;
}
.wardery-map-frame .leaflet-popup-content strong { font-family: "IM Fell English SC", serif; color: var(--seal); font-weight: 400; }
.wardery-map-frame .leaflet-popup-tip { background: var(--panel); }

.wardery-locate-control {
  width: 34px; height: 34px; background: var(--panel); border: 1px solid var(--rule);
  color: var(--ink); display: flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0;
}
.wardery-locate-control:hover { background: var(--vellum-shadow); }
.wardery-locate-control svg { width: 18px; height: 18px; }

/* A hand-drawn manor-house glyph, not a plain colour dot -- see
   wardery_pinIcon() in wardery.js for the actual SVG shape. A
   drop-shadow filter (not box-shadow) so the shade follows the house's
   own silhouette instead of its rectangular bounding box. */
.wardery-pin { filter: drop-shadow(0 1px 2px rgba(0,0,0,0.4)); }
.wardery-pin.wardery-pin-selected { filter: drop-shadow(0 2px 3px rgba(0,0,0,0.5)); }

.wardery-map-legend {
  display: flex; flex-wrap: wrap; gap: 10px 20px; margin-top: 10px;
  font-family: "IM Fell English SC", serif; font-size: 13.5px; color: var(--muted);
}
.wardery-map-legend span { display: inline-flex; align-items: center; gap: 6px; }
.wardery-legend-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.25); }

/* ---------- House detail panel ---------- */
/* top: 92px, not 16px -- the shared site header is sticky too, 76px
   tall at every width where this panel is even sticky (it drops to
   position: static entirely below 900px, well above the 780px
   breakpoint where the header itself shrinks to 68px, so 76px is the
   only header height this panel ever needs to clear). Without this
   offset the panel stuck at 16px from the viewport top -- underneath
   the header, which sits on top of it (later in paint order) -- so the
   panel's own first line of text was genuinely hidden behind the
   header, not just hazy through it. Found live: the header fix in
   wardery_syncHeaderOpacityOverMap solved a real but different problem
   (the header's own translucency); this is a separate sticky-offset
   bug that survived that fix untouched. */
.wardery-house-panel { align-self: start; position: sticky; top: 92px; }
@media (max-width: 900px) { .wardery-house-panel { position: static; } }
.wardery-house-empty { font-style: italic; color: var(--muted); margin: 0; }
.wardery-house-row {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 10px 0; border-top: 1px solid var(--rule); font-size: 15px;
}
.wardery-house-row:first-of-type { border-top: none; }
.wardery-house-row dt { font-family: "IM Fell English SC", serif; color: var(--seal); flex-shrink: 0; }
.wardery-house-row dd { margin: 0; text-align: right; color: var(--ink); }
.wardery-house-row dd.wardery-muted { color: var(--muted); font-style: italic; }
.wardery-stake-button { width: 100%; margin-top: 16px; }

/* Every House always carries the same seven Titles in the same order --
   a fixed roll, not a re-sorting leaderboard -- but they were all one
   flat size regardless of standing. Tiered by how much a Title is
   actively contested/held: Keeper and Warden (the live-ranked capstone)
   read largest, the two permanent historical Titles (Discoverer/
   Tastemaker, which can never change hands) read smallest, the rest
   sit between -- so the roll's own typography tells you which lines
   matter most at a glance, the way a real manor roll gave its holder's
   own name the largest hand on the page. */
.wardery-house-row.wardery-tier-1 dt { font-size: 17px; }
.wardery-house-row.wardery-tier-1 dd { font-size: 16px; font-weight: 600; }
.wardery-house-row.wardery-tier-3 dt,
.wardery-house-row.wardery-tier-3 dd { font-size: 13.5px; color: var(--muted); }
.wardery-house-row.wardery-tier-3 dt { color: var(--muted); }

/* A stat is a claim's own provenance -- exactly when, exactly how many
   renewals -- not just a bare number, so it's set apart as its own
   ticket rather than run into the sentence. */
.wardery-ticket {
  display: inline-block; font-style: italic; font-size: 12.5px;
  border: 1px dashed var(--rule); border-radius: 2px; padding: 1px 7px;
  margin-left: 6px; color: var(--muted);
}

/* ---------- Tier II: the fuller Title roster + Rite of Contest ---------- */
.wardery-title-name { display: flex; align-items: baseline; gap: 6px; }
.wardery-challenge-button {
  font-family: "IM Fell English SC", serif; font-size: 12.5px; color: var(--brass);
  background: transparent; border: 1px solid var(--rule); border-radius: 2px;
  padding: 3px 9px; cursor: pointer; margin-left: 6px;
}
.wardery-challenge-button:hover { color: var(--seal); border-color: var(--brass); }
.wardery-contest-badge {
  display: inline-block; margin-top: 5px; font-size: 12.5px; font-style: italic;
  color: var(--seal); background: var(--vellum-shadow); border: 1px solid var(--rule);
  border-radius: 2px; padding: 3px 8px;
}
.wardery-contest-badge::before { content: "⚔ "; font-style: normal; }

/* ---------- The Realm ---------- */
.wardery-realm-section { margin-bottom: 46px; }
.wardery-realm-locked { text-align: center; }
.wardery-realm-locked p { margin: 0 0 14px; color: var(--muted); font-style: italic; }
.wardery-realm-stats {
  display: flex; flex-wrap: wrap; gap: 10px 30px; margin-bottom: 20px;
  font-family: "IM Fell English SC", serif;
}
.wardery-realm-stat b {
  display: block; font-family: "IM Fell Great Primer", serif; font-size: 26px; color: var(--seal); line-height: 1;
}
.wardery-realm-stat span { font-size: 12.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.wardery-cities { display: flex; flex-direction: column; gap: 11px; }
.wardery-city-row { display: grid; grid-template-columns: 120px 1fr 44px; gap: 12px; align-items: center; }
@media (max-width: 480px) { .wardery-city-row { grid-template-columns: 88px 1fr 40px; } }
.wardery-city-name { font-family: "IM Fell English SC", serif; font-size: 14.5px; }
.wardery-bar-track { height: 9px; background: var(--vellum-shadow); border: 1px solid var(--rule); position: relative; }
.wardery-bar-fill { height: 100%; background: linear-gradient(90deg, var(--brass), var(--seal)); }
.wardery-city-pct { font-family: "IM Fell English SC", serif; font-size: 13px; color: var(--muted); text-align: right; }

.wardery-muster-tagline { margin-bottom: 18px; }

/* ---------- Charter of Claim ---------- */
.wardery-charter-backdrop {
  position: fixed; inset: 0; background: rgba(20, 15, 8, 0.55);
  display: flex; align-items: center; justify-content: center; padding: 20px;
  z-index: 1000; opacity: 0; animation: wardery-fade-in 220ms ease-out forwards;
}
.wardery-charter-backdrop[hidden] { display: none; }
@keyframes wardery-fade-in { to { opacity: 1; } }

.wardery-charter {
  background: var(--panel); border: 2px solid var(--brass); padding: 34px 30px 30px;
  position: relative; text-align: center; max-width: 420px; width: 100%;
  transform: translateY(10px); opacity: 0;
  animation: wardery-charter-rise 320ms 60ms cubic-bezier(.22,1,.36,1) forwards;
}
@keyframes wardery-charter-rise { to { transform: translateY(0); opacity: 1; } }
.wardery-charter::before, .wardery-charter::after { content: "❧"; color: var(--brass); font-size: 17px; display: block; }
.wardery-charter-close {
  position: absolute; top: 8px; right: 10px; background: none; border: none;
  font-size: 22px; color: var(--muted); cursor: pointer; line-height: 1; padding: 6px;
}
.wardery-charter-close:hover { color: var(--seal); }
.wardery-charter-title {
  font-family: "IM Fell English SC", serif; font-size: 13px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); margin: 8px 0 16px;
}
.wardery-charter-name { font-family: "IM Fell Great Primer", serif; font-size: 30px; color: var(--seal-deep); margin: 0 0 6px; text-wrap: balance; }
.wardery-charter-body {
  font-size: 16px; font-style: italic; max-width: 42ch; margin: 0 auto 22px;
  text-align: left; text-align-last: left;
}
/* Rubrication: the opening letter of the Charter's own text, set as a
   real illuminated drop cap -- upright (not italic, unlike the body it
   opens), rendered in the wax-seal red the same way a scribe reserved
   red ink for a section's first letter. Pure CSS, no markup change --
   the text itself is plain, JS-set content. */
.wardery-charter-body::first-letter {
  font-family: "IM Fell Great Primer", serif; font-style: normal;
  font-size: 44px; line-height: 0.7; color: var(--seal);
  float: left; padding: 4px 4px 0 0;
}

.wardery-seal-wrap { display: flex; flex-direction: column; align-items: center; }
.wardery-seal {
  width: 76px; height: 76px; border-radius: 50%; margin: 0 auto;
  background: radial-gradient(circle at 34% 28%, var(--seal-bright), var(--seal) 55%, var(--seal-deep) 100%);
  box-shadow: 0 3px 6px rgba(0,0,0,0.35), inset 0 0 0 3px rgba(0,0,0,0.18);
  display: flex; align-items: center; justify-content: center; position: relative;
  transform: scale(2.3) rotate(-10deg); opacity: 0;
  animation: wardery-seal-stamp 420ms 180ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes wardery-seal-stamp { to { transform: scale(1) rotate(0deg); opacity: 1; } }
.wardery-seal::before { content: ""; position: absolute; inset: 6px; border-radius: 50%; border: 1px dashed rgba(244,236,216,0.35); }
.wardery-seal .wardery-glyph { font-family: "IM Fell Great Primer", serif; font-size: 27px; color: #f2e6c8; text-shadow: 0 1px 1px rgba(0,0,0,0.4); }

/* The seal hangs from a parchment tag, the way a real wax seal was
   pendant from a folded strip of the document itself (or a separate
   tag) rather than sitting flush on the page -- what actually made a
   mediaeval/early-modern seal a seal, not a stamp. A trapezoid tapering
   to a torn point via clip-path; no extra asset. */
.wardery-seal-tag {
  width: 22px; height: 30px; margin-top: -4px; background: var(--panel);
  border: 1px solid var(--brass); border-top: none;
  clip-path: polygon(0 0, 100% 0, 100% 65%, 50% 100%, 0 65%);
  opacity: 0; animation: wardery-tag-drop 260ms 480ms ease-out forwards;
}
@keyframes wardery-tag-drop { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }

@media (prefers-reduced-motion: reduce) {
  .wardery-charter, .wardery-seal, .wardery-charter-backdrop, .wardery-seal-tag { animation: none !important; opacity: 1 !important; transform: none !important; }
}

/* ---------- The ornate frame and its furniture ---------- */
/* The reference direction the owner set is ornate AND restrained: the
   ornament is heavy, but it is ONE system repeated with discipline --
   one frame, one corner motif, one fleuron, one monogram. That is why
   everything below is a handful of reusable pieces rather than
   per-section decoration. */

/* The plate's own double rule: a brass outer border on the world itself,
   and a hairline inner rule set in from it. Drawn with ::after rather
   than a second border so it can sit INSIDE the padding without
   changing the layout box or reflowing a single line of text. */
/* SCOPED TO main ON PURPOSE, and it matters: the Charter backdrop also
   carries .wardery-world (it has to -- every heraldic colour here is a
   custom property scoped to that class, and the Charter renders outside
   <main>). Its own rules override background and position, but they say
   nothing about border, so an unscoped `.wardery-world { border }` here
   -- declared later in the file than the backdrop's own block -- drew a
   brass frame and an inner rule around the full-screen modal overlay.
   Caught before shipping; keep the `main` qualifier. */
main.wardery-world {
  border: 1px solid var(--brass);
  /* The sheet sits ON the site rather than being a border drawn on the
     window. The gutter is deliberately left as FindTheCool's own page
     colour rather than tinted warm: the cold edge is the site, the warm
     sheet is Wardery laid on it, which is exactly the "you are still
     inside FindTheCool" contrast the brief asks for. */
  margin: clamp(8px, 1.6vw, 22px);
  box-shadow: 0 1px 2px rgba(43, 32, 24, 0.10), 0 10px 26px rgba(43, 32, 24, 0.07);
}
main.wardery-world::after {
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid var(--rule);
  pointer-events: none; /* never intercepts a click meant for the page */
}

/* Corner scrollwork. One drawn motif, placed four times and mirrored
   into each corner -- the same economy the reference uses. Purely
   decorative, so aria-hidden in the markup and inert here. */
.wardery-corner {
  position: absolute;
  width: 46px; height: 46px;
  color: var(--brass);
  pointer-events: none;
}
.wardery-corner-tl { top: 0; left: 0; }
.wardery-corner-tr { top: 0; right: 0; transform: scaleX(-1); }
.wardery-corner-bl { bottom: 0; left: 0; transform: scaleY(-1); }
.wardery-corner-br { bottom: 0; right: 0; transform: scale(-1, -1); }

/* The monogram band: crown, W, pendant fleuron, flanked by rules and by
   the two label words. This is the page's own letterhead. */
.wardery-monogram-band {
  display: flex; align-items: center; gap: clamp(12px, 3vw, 24px);
  margin: 0 0 26px;
}
.wardery-monogram-band .wardery-monogram-rule {
  height: 1px; background: var(--rule); flex-grow: 1;
}
.wardery-monogram-band .wardery-monogram-word {
  font-family: "IM Fell English SC", serif;
  font-size: clamp(10px, 2.2vw, 12.5px);
  letter-spacing: 0.2em; color: var(--seal); white-space: nowrap;
}
.wardery-monogram {
  width: 84px; height: 74px; flex-shrink: 0; color: var(--brass);
  margin-bottom: -20px; /* lets the pendant fleuron hang below the rules */
}

/* Fleuron divider, between sections. The one ornament that separates. */
.wardery-fleuron-rule {
  display: flex; align-items: center; gap: 16px;
  margin: 40px 0;
}
.wardery-fleuron-rule::before,
.wardery-fleuron-rule::after {
  content: ""; height: 1px; background: var(--rule); flex-grow: 1;
}
.wardery-fleuron-rule svg { width: 132px; height: 18px; color: var(--brass); flex-shrink: 0; }

/* On a phone the frame tightens and the corner scrollwork stands down --
   at 46px a corner motif eats a real fraction of a 375px screen, and it
   is the one piece here carrying no information at all. */
@media (max-width: 600px) {
  main.wardery-world { margin: 6px; } /* a 375px screen can't spare more */
  main.wardery-world::after { inset: 5px; }
  .wardery-corner { display: none; }
  .wardery-monogram { width: 66px; height: 58px; margin-bottom: -16px; }
  .wardery-monogram-band { gap: 10px; margin-bottom: 20px; }
  .wardery-fleuron-rule { margin: 30px 0; gap: 10px; }
  .wardery-fleuron-rule svg { width: 96px; height: 14px; }
}

/* ---------- The Titles roll's engraved devices (ornate phase 2) ---------- */
/* Each Title now carries a laurel-wreathed device rather than standing as
   bare text. The wreath and the seven devices are defined once in
   wardery.html's own <defs> and referenced with <use>, so the artwork is
   markup rather than a string rebuilt in JS on every House selection.
   Everything is drawn in currentColor, so ONE rule per tier colours the
   whole device -- which is what keeps the roll's existing typographic
   hierarchy and its new heraldic one saying the same thing rather than
   two different things. */
.wardery-title-device { flex-shrink: 0; line-height: 0; }
.wardery-title-device svg { display: block; width: 100%; height: 100%; }

/* Size and colour both follow the tier the roll already established:
   tier 1 is the live-ranked capstone (Keeper, Warden), tier 2 the other
   contestable Titles, tier 3 the two permanent historical facts that can
   never change hands -- so they never need to shout. */
.wardery-house-row.wardery-tier-1 .wardery-title-device { width: 52px; height: 52px; color: var(--seal); }
.wardery-house-row.wardery-tier-2 .wardery-title-device { width: 44px; height: 44px; color: var(--brass); }
.wardery-house-row.wardery-tier-3 .wardery-title-device { width: 36px; height: 36px; color: var(--unstaked); }

/* The row was `justify-content: space-between` on two children. With a
   device in front, the name has to be free to sit NEXT to its own device
   rather than being pushed to the far edge, so the gap between device
   and name is fixed and only the holder column flexes. */
.wardery-house-row { align-items: center; }
.wardery-house-row dt { margin-right: auto; }

@media (max-width: 600px) {
  .wardery-house-row.wardery-tier-1 .wardery-title-device { width: 38px; height: 38px; }
  .wardery-house-row.wardery-tier-2 .wardery-title-device { width: 32px; height: 32px; }
  .wardery-house-row.wardery-tier-3 .wardery-title-device { width: 26px; height: 26px; }
}

/* ---------- The Muster as a formal assembly (ornate phase 3) ---------- */
/* Not a leaderboard: a ranked roll of Orders, each with its own arms.
   The row sets `color` per Order in JS, and everything inside -- crown,
   shield, charge, solid rule, hatched rule, its border -- draws in
   currentColor, so one assignment colours the whole entry. */
.wardery-order-row {
  display: grid;
  grid-template-columns: 22px 44px 34px 1fr 300px 84px;
  align-items: center; gap: 18px;
  padding: 10px 0; border-top: 1px solid var(--rule);
}
.wardery-order-row:first-of-type { border-top: none; }
.wardery-order-rank {
  font-family: "IM Fell Great Primer", serif; font-size: 22px;
  color: var(--muted); text-align: right;
}
.wardery-order-arms { display: block; }
.wardery-order-arms svg { display: block; width: 34px; height: 49px; }
.wardery-order-name {
  font-family: "IM Fell English SC", serif; font-size: 19px; color: var(--ink);
}
.wardery-order-name small {
  display: block; margin-top: 2px;
  font-family: "EB Garamond", Georgia, serif; font-size: 13px; color: var(--muted);
}
.wardery-order-standing svg { display: block; width: 100%; height: 12px; }
.wardery-order-score {
  font-family: "IM Fell Great Primer", serif; font-size: 24px;
  color: var(--ink); text-align: right;
}

/* Below 760px the standing rule and the arms are the first things to
   go: a ranked name and its score are the information, the rule is the
   comparison, and on a phone there is no room to compare across a row
   that has already wrapped. */
@media (max-width: 760px) {
  .wardery-order-row {
    grid-template-columns: 18px 34px 28px 1fr auto;
    gap: 12px; padding: 12px 0;
  }
  .wardery-order-rank { font-size: 18px; }
  .wardery-order-arms svg { width: 28px; height: 40px; }
  .wardery-order-name { font-size: 16.5px; }
  .wardery-order-name small { font-size: 12px; }
  .wardery-order-standing { display: none; }
  .wardery-order-score { font-size: 19px; }
}

/* ---------- The Realm as a ruled ledger (ornate phase 4) ---------- */
/* DEFENSIVE, per this project's most-repeated bug: both of these are
   toggled with el.hidden in wardery_refreshRealm(). Nothing below gives
   them an authored `display`, so they don't strictly need this today --
   but the next rule someone adds might, and by then the failure is a
   panel that refuses to hide with no error anywhere. Cheap insurance. */
#wardery-realm-content[hidden], #wardery-realm-locked[hidden] { display: none; }

/* The claimable-ground list under the ledger. .wardery-unclaimed is
   authored `display: block` below, and an authored display beats
   [hidden] -- this project has shipped that bug more than once -- so
   the counter-rule is not optional. */
#wardery-unclaimed[hidden] { display: none; }
.wardery-unclaimed {
  display: block;
  /* Shares .wardery-ledger own 420px column: this list is a
     continuation of the ledger above it, not a new full-width section,
     and at the parent 1080px its hairlines ran two and a half times the
     length of the ledger rules directly above them. */
  max-width: 420px;
  margin-top: 18px;
}
.wardery-unclaimed-head {
  font-family: "EB Garamond", Georgia, serif;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: 6px;
  border-bottom: 1px solid var(--rule);
}
.wardery-unclaimed-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.wardery-unclaimed-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  padding: 7px 0;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  color: var(--ink);
}
.wardery-unclaimed-row:hover .wardery-unclaimed-name { color: var(--seal); }
.wardery-unclaimed-name {
  flex: 1;
  font-family: "EB Garamond", Georgia, serif;
  font-size: 15px;
}
.wardery-unclaimed-dist {
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* Label left, figure right, hairline between, a heavier rule closing the
   column -- a ledger page, not three stat cards. */
.wardery-ledger { margin: 0 0 26px; max-width: 420px; }
.wardery-ledger-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 20px;
  padding: 13px 0 11px; border-bottom: 1px solid var(--rule);
}
.wardery-ledger-row:first-child { border-top: 2px solid var(--brass); }
.wardery-ledger-row:last-child { border-bottom: 2px solid var(--brass); }
.wardery-ledger-row dt {
  font-family: "IM Fell English SC", serif; font-size: 16px; color: var(--seal);
}
.wardery-ledger-row dd {
  margin: 0; font-family: "IM Fell Great Primer", serif; font-size: 38px;
  line-height: 1; color: var(--ink);
}

/* The medallion states what the Realm is, in the register's own voice. */
.wardery-realm-seal { display: flex; align-items: center; gap: 22px; margin: 0 0 30px; }
.wardery-medallion { width: 104px; height: 104px; flex-shrink: 0; color: var(--brass); }
.wardery-realm-note { margin: 0; font-size: 15.5px; line-height: 1.6; color: var(--ink); max-width: 52ch; }

.wardery-schedule-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding-bottom: 9px; border-bottom: 2px solid var(--brass);
  font-family: "IM Fell English SC", serif; font-size: 14px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--seal);
}
.wardery-schedule-unit { font-size: 10.5px; letter-spacing: 0.14em; color: var(--brass); }

/* The schedule rows themselves: name, ruled scale, exact figures. */
.wardery-city-row {
  display: grid; grid-template-columns: 150px 1fr 92px 54px;
  align-items: center; gap: 20px;
  padding: 12px 0 10px; border-bottom: 1px solid var(--rule);
}
.wardery-city-name { font-family: "IM Fell English SC", serif; font-size: 17px; color: var(--ink); }
.wardery-city-scale svg { display: block; width: 100%; height: 8px; }
.wardery-city-held { font-size: 14.5px; color: var(--muted); text-align: right; }
.wardery-city-pct {
  font-family: "IM Fell Great Primer", serif; font-size: 24px;
  color: var(--ink); text-align: right;
}

/* On a phone the scale is the first thing to go -- "9 of 61" and "15%"
   are the information; the ruled scale is the at-a-glance comparison,
   and there is no room to compare across a row that has wrapped. */
@media (max-width: 760px) {
  .wardery-ledger-row dd { font-size: 30px; }
  .wardery-realm-seal { gap: 16px; }
  .wardery-medallion { width: 76px; height: 76px; }
  .wardery-realm-note { font-size: 14.5px; }
  .wardery-city-row { grid-template-columns: 1fr auto auto; gap: 12px; }
  .wardery-city-scale { display: none; }
  .wardery-city-pct { font-size: 20px; }
}

/* ---------- The manicule (ornate phase 3b) ---------- */
/* The pointing hand a reader inked in the margin beside the line that
   mattered. It marks the viewer's own Order without a badge, a colour
   or a shout -- "identifiable without screaming for attention", and a
   real convention from the same records this world is modelled on.
   The mark column exists on EVERY row, empty or not, so a marked row
   never shifts the columns beside it and the roll stays a roll. */
.wardery-order-mark { display: block; }
.wardery-order-mark svg { display: block; width: 20px; height: 20px; color: var(--seal); }
.wardery-order-mine { background: rgba(122, 35, 49, 0.055); }
.wardery-order-mine .wardery-order-rank { color: var(--seal); }
.wardery-order-mine .wardery-order-name,
.wardery-order-mine .wardery-order-score { color: var(--seal-deep); font-weight: 600; }
@media (max-width: 760px) {
  .wardery-order-mark svg { width: 16px; height: 16px; }
}
