:root {
      --void: #0a0908;
      --void-2: #100d0b;
      --amber: #e8a33d;
      --amber-soft: rgba(232, 163, 61, 0.68);
      --rust: #8a3324;
      --bone: #d8d0c0;
      --muted: #9a8a76;
      --cold: #89a4bd;
      --seal: #b21818;
      --panel: rgba(14, 11, 9, 0.84);
      --line: rgba(232, 163, 61, 0.34);
      --shadow: rgba(0, 0, 0, 0.62);
      --display: "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
      --prose: "Palatino Linotype", "Book Antiqua", Palatino, Georgia, serif;
      --mono: "IBM Plex Mono", "JetBrains Mono", ui-monospace, monospace;
      font-family: var(--mono);
      color: var(--bone);
      background: var(--void);
    }

    * {
      box-sizing: border-box;
    }

    html,
    body {
      width: 100%;
      height: 100%;
      margin: 0;
      overflow: hidden;
      background: radial-gradient(circle at 50% 50%, #14100d 0%, var(--void) 62%);
    }

    body {
      letter-spacing: 0;
      user-select: none;
    }

    .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;
    }

    button,
    input,
    select {
      font: inherit;
    }

    #app {
      position: fixed;
      inset: 0;
      min-width: 320px;
      background:
        linear-gradient(rgba(232, 163, 61, 0.028) 50%, rgba(0, 0, 0, 0) 50%) 0 0 / 100% 4px,
        radial-gradient(circle at center, rgba(232, 163, 61, 0.08), transparent 55%);
    }

    #glCanvas,
    #labelCanvas {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      display: block;
      /* Hand touch gestures on the map to the app (one-finger pan, two-finger pinch)
         instead of letting the browser scroll/zoom the page. Touch-only; no mouse effect. */
      touch-action: none;
    }

    #labelCanvas {
      pointer-events: none;
    }

    .scanlines {
      position: fixed;
      inset: 0;
      pointer-events: none;
      z-index: 30;
      opacity: 0.035;
      background:
        repeating-linear-gradient(0deg, rgba(255, 214, 134, 0.7), rgba(255, 214, 134, 0.7) 1px, transparent 1px, transparent 4px);
      mix-blend-mode: screen;
    }

    .topbar,
    .bottombar,
    .panel,
    .debug {
      position: fixed;
      z-index: 20;
      background: var(--panel);
      border: 1px solid var(--line);
      box-shadow: 0 18px 42px var(--shadow), inset 0 0 28px rgba(232, 163, 61, 0.035);
      backdrop-filter: blur(8px);
      clip-path: polygon(12px 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%, 0 12px);
    }

    /* While the boot overlay is up, drop the chrome's backdrop-filter. On some GPUs the
       filtered layer composites ABOVE the opaque boot screen and ghosts the chrome through
       as faint grey shapes (the topbar/bottombar silhouettes read as a bar + bevel triangle).
       The chrome is fully hidden behind the boot screen here, so this has no visual cost;
       initBootSequence removes .booting once the boot screen is gone and the blur returns. */
    body.booting .topbar,
    body.booting .bottombar,
    body.booting .panel,
    body.booting .debug {
      -webkit-backdrop-filter: none;
      backdrop-filter: none;
    }

    .topbar {
      top: 12px;
      left: 12px;
      right: 12px;
      min-height: 54px;
      display: flex;
      align-items: center;
      gap: 14px;
      padding: 9px 12px;
    }

    .brand {
      display: flex;
      align-items: baseline;
      gap: 10px;
      min-width: 250px;
      flex: 1 1 auto;
      color: var(--amber);
      text-transform: uppercase;
      text-shadow: 0 0 18px rgba(232, 163, 61, 0.38);
      animation: headerFlicker 7s infinite steps(1);
    }

    .brand h1 {
      margin: 0;
      font-family: var(--display);
      font-weight: 700;
      font-size: clamp(16px, 2vw, 24px);
      letter-spacing: 2.5px;
      white-space: nowrap;
    }

    .brand span {
      color: var(--muted);
      font-size: 11px;
    }

    @keyframes headerFlicker {
      0%, 94%, 100% { opacity: 1; }
      95% { opacity: 0.76; }
      96% { opacity: 1; }
      97% { opacity: 0.84; }
    }

    .controls {
      display: flex;
      align-items: center;
      justify-content: flex-end;
      flex: 1 1 auto;
      gap: 8px;
      min-width: 0;
      flex-wrap: wrap;
    }

    /* Ko-fi support link, centered in the gap between the brand and the controls. Keeps
       the original discreet rust pill: low opacity, small, brightening on hover. */
    .kofi-link {
      flex: 0 0 auto;
      align-self: center;
      white-space: nowrap;
      font-size: 13px;
      letter-spacing: 0.12em;
      text-transform: uppercase;
      color: #d97e57;
      text-decoration: none;
      opacity: 0.9;
      border: 1px solid rgba(217, 126, 87, 0.5);
      padding: 8px 30px;
      border-radius: 2px;
      background: rgba(10, 9, 8, 0.8);
      transition: opacity 0.25s ease, background 0.25s ease, color 0.25s ease;
    }

    .kofi-link:hover {
      opacity: 1;
      color: #eaa06a;
      background: rgba(138, 51, 36, 0.22);
    }

    .kofi-skull {
      font-size: 1.15em;
      line-height: 1;
      opacity: 0.85;
    }

    .kofi-skull:first-child { margin-right: 0.55em; }
    .kofi-skull:last-child { margin-left: 0.55em; }

    /* Both banner buttons live in a centre overlay: an absolutely-positioned layer that
       spans the (page-symmetric) topbar so its horizontal middle IS the page middle. Two
       equal 1fr columns meet at that middle, and the column-gap straddles it — so the space
       BETWEEN the two pills is centred on the page regardless of their differing widths.
       pointer-events pass through the empty layer; only the pills themselves catch clicks. */
    .banner-actions {
      position: absolute;
      inset: 0;
      display: grid;
      grid-template-columns: 1fr 1fr;
      align-items: center;
      column-gap: 22px;
      pointer-events: none;
      z-index: 1;
    }
    .banner-actions > .kofi-link { pointer-events: auto; }
    .banner-actions > .kofi-link:first-child { justify-self: end; }
    .banner-actions > .kofi-link:last-child { justify-self: start; }

    /* "Contact the Mechanicus" pill: click crossfades the label out and a mailto rune in.
       Both faces share one grid cell so the pill sizes to the wider of the two and never
       jumps when it flips. */
    .contact-link {
      display: inline-grid;
      align-items: center;
      justify-items: center;
      cursor: pointer;
      -webkit-user-select: none;
      user-select: none;
    }
    .contact-link .contact-face {
      grid-area: 1 / 1;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      white-space: nowrap;
      transition: opacity 0.4s ease;
    }
    .contact-link .contact-email {
      opacity: 0;
      pointer-events: none;
      color: inherit;
      text-decoration: none;
      text-transform: none;
    }
    .contact-link.revealed .contact-label {
      opacity: 0;
      pointer-events: none;
    }
    .contact-link.revealed .contact-email {
      opacity: 1;
      pointer-events: auto;
    }
    .contact-link .contact-email:hover { text-decoration: underline; }

    .field,
    .icon-button,
    .toggle,
    .range-field {
      border: 1px solid rgba(232, 163, 61, 0.28);
      background: rgba(10, 9, 8, 0.75);
      color: var(--bone);
      height: 32px;
      border-radius: 0;
      outline: none;
    }

    .field {
      padding: 0 9px;
    }

    /* Magnifier affordance for the archive search (kept off the <select> fields). */
    #searchInput {
      padding-left: 30px;
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239a8a76' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M20 20l-4.6-4.6'/%3E%3C/svg%3E");
      background-repeat: no-repeat;
      background-position: 9px center;
      background-size: 14px 14px;
    }

    .icon-button,
    .toggle {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 6px;
      padding: 0 9px;
      cursor: pointer;
      text-transform: uppercase;
      font-size: 12px;
    }

    /* Layer toggles default to OFF-reading (muted, recessed border) so an inactive
       layer is not mistaken for the RESET action; the pressed rule below makes ON
       unmistakable. Placed before :hover so hovering an off toggle still brightens. */
    .toggle:not([aria-pressed="true"]) {
      color: var(--muted);
      border-color: rgba(232, 163, 61, 0.15);
    }

    .icon-button:hover,
    .toggle:hover,
    .field:focus,
    .range-field:focus {
      border-color: var(--amber);
      color: var(--amber);
      box-shadow: 0 0 14px rgba(232, 163, 61, 0.15);
    }

    .range-field {
      width: 92px;
      padding: 0 6px;
      accent-color: var(--amber);
    }

    .toggle[aria-pressed="true"] {
      color: var(--amber);
      border-color: rgba(232, 163, 61, 0.55);
      background: rgba(232, 163, 61, 0.15);
      box-shadow: inset 0 0 12px rgba(232, 163, 61, 0.14);
    }

    /* RESET is a rare, non-toggle action: keep it quiet (muted until hover) so it no
       longer out-shouts the era switch and layer toggles. */
    #resetCamera {
      color: var(--muted);
      border-color: rgba(232, 163, 61, 0.16);
    }

    /* Thin separators split the toolbar into its three groups: era | layers | reset. */
    .ctrl-divider {
      align-self: center;
      width: 1px;
      height: 20px;
      margin: 0 2px;
      background: rgba(232, 163, 61, 0.22);
    }

    /* Keyboard focus ring (on-theme). The blanket `outline: none` above stripped the
       focus indicator from the toolbar controls; restore a clear ring for keyboard
       navigation only (:focus-visible), so mouse clicks stay ring-free. */
    .icon-button:focus-visible,
    .toggle:focus-visible,
    .era-option:focus-visible,
    .field:focus-visible,
    .range-field:focus-visible,
    .tab:focus-visible,
    .section-title:focus-visible,
    .lore-link:focus-visible {
      outline: 2px solid var(--amber);
      outline-offset: 2px;
    }

    /* Archive rows carry a clip-path notch that would clip an outset ring, so inset it. */
    .archive-row:focus-visible {
      outline: 2px solid var(--amber);
      outline-offset: -2px;
    }

    .era-switch {
      display: inline-flex;
      height: 32px;
      border: 1px solid rgba(232, 163, 61, 0.28);
      background: rgba(10, 9, 8, 0.75);
    }

    .era-option {
      border: 0;
      background: transparent;
      color: var(--muted);
      padding: 0 10px;
      cursor: pointer;
      text-transform: uppercase;
      font-size: 12px;
    }

    .era-option:hover {
      color: var(--bone);
    }

    .era-option.active {
      color: var(--amber);
      background: rgba(232, 163, 61, 0.1);
    }

    .era-option[data-era="m42"].active {
      color: #e8737f;
      background: rgba(216, 53, 74, 0.14);
      text-shadow: 0 0 10px rgba(216, 53, 74, 0.45);
    }

    .dev-only {
      display: none !important;
    }

    .debug-visible .dev-only {
      display: inline-flex !important;
    }

    #app::after {
      content: "";
      position: absolute;
      inset: 0;
      pointer-events: none;
      z-index: 15;
      background: radial-gradient(ellipse at 50% 45%, transparent 58%, rgba(5, 4, 3, 0.5) 100%);
    }

    .panel {
      top: 78px;
      bottom: 44px;
      width: min(360px, calc(100vw - 32px));
      transition: transform 220ms ease, opacity 220ms ease;
    }

    .left-panel {
      left: 12px;
    }

    .right-panel {
      right: 12px;
      width: min(390px, calc(100vw - 32px));
    }

    .panel.collapsed.left-panel {
      transform: translateX(calc(-100% + 42px));
    }

    .panel.collapsed.right-panel {
      transform: translateX(calc(100% - 42px));
    }

    .panel.collapsed .panel-body,
    .panel.collapsed .purity-seal {
      opacity: 0;
      pointer-events: none;
    }

    .panel.collapsed .panel-head span {
      display: none;
    }

    .right-panel.collapsed .panel-head {
      justify-content: flex-start;
    }

    .panel-head {
      height: 44px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 0 12px 0 16px;
      color: var(--amber);
      border-bottom: 1px solid rgba(232, 163, 61, 0.22);
      text-transform: uppercase;
      font-size: 13px;
    }

    .panel-body {
      height: calc(100% - 44px);
      overflow: hidden;
      padding: 12px;
    }

    .collapse {
      width: 26px;
      height: 26px;
      padding: 0;
    }

    .index-tools {
      display: grid;
      grid-template-columns: 1fr;
      gap: 8px;
      margin-bottom: 10px;
    }

    .index-tools .field {
      width: 100%;
    }

    .index-note {
      color: var(--muted);
      font-size: 10px;
      text-transform: uppercase;
      letter-spacing: 1px;
      border-left: 2px solid rgba(232, 163, 61, 0.34);
      padding-left: 7px;
      margin-bottom: 10px;
    }

    .left-panel .panel-body {
      display: flex;
      flex-direction: column;
    }

    .row-list {
      flex: 1;
      min-height: 0;
      overflow: auto;
      padding-right: 4px;
    }

    .archive-row {
      width: 100%;
      display: flex;
      align-items: center;
      gap: 9px;
      border: 1px solid rgba(232, 163, 61, 0.18);
      background: rgba(10, 9, 8, 0.55);
      color: var(--bone);
      font: inherit;
      text-decoration: none;
      text-align: left;
      margin-bottom: 7px;
      padding: 8px 9px;
      cursor: pointer;
      clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
    }

    .row-glyph {
      flex: 0 0 26px;
      width: 26px;
      height: 26px;
      background-repeat: no-repeat;
      opacity: 0.92;
    }

    .row-text {
      flex: 1;
      min-width: 0;
    }

    .row-name,
    .row-meta {
      display: block;
    }

    .archive-row:hover,
    .archive-row.active {
      border-color: rgba(232, 163, 61, 0.62);
      background: rgba(232, 163, 61, 0.08);
    }

    .row-name {
      color: var(--bone);
      text-transform: uppercase;
      font-size: 13px;
      margin-bottom: 5px;
    }

    /* Amber is reserved for the row you are hovering or have selected, so the archive
       reads as a hierarchy instead of a uniform wall of gold. */
    .archive-row:hover .row-name,
    .archive-row.active .row-name {
      color: var(--amber);
    }

    .row-meta {
      color: var(--muted);
      font-size: 11px;
      line-height: 1.35;
    }

    .badge {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      color: var(--amber);
      border: 1px solid rgba(232, 163, 61, 0.34);
      background: rgba(232, 163, 61, 0.08);
      padding: 2px 5px;
      font-size: 10px;
      text-transform: uppercase;
      margin-left: 5px;
    }

    .dossier-empty {
      height: 100%;
      display: grid;
      place-items: center;
      color: var(--muted);
      text-align: center;
      line-height: 1.55;
      padding: 18px;
    }

    .empty-glyph {
      font-family: var(--display);
      font-size: 42px;
      color: var(--rust);
      margin-bottom: 10px;
      text-shadow: 0 0 18px rgba(138, 51, 36, 0.5);
    }

    .empty-sub {
      color: var(--muted);
      font-size: 10px;
      letter-spacing: 2px;
      text-transform: uppercase;
      margin: 10px 0 0;
      opacity: 0.8;
    }

    .right-panel .panel-body {
      position: relative;
    }

    .doc-mini {
      position: sticky;
      top: 0;
      z-index: 5;
      display: flex;
      align-items: center;
      gap: 9px;
      max-height: 0;
      opacity: 0;
      overflow: hidden;
      background: rgba(14, 11, 9, 0.96);
      border-bottom: 1px solid rgba(232, 163, 61, 0.3);
      transition: max-height 200ms ease, opacity 200ms ease;
    }

    .dossier.scrolled .doc-mini {
      max-height: 36px;
      opacity: 1;
      padding: 4px 2px;
    }

    .doc-mini strong {
      color: var(--amber);
      font-family: var(--display);
      font-size: 15px;
      letter-spacing: 1px;
      text-transform: uppercase;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .dossier {
      height: 100%;
      overflow: auto;
      padding-right: 4px;
      user-select: text;
      cursor: auto;
    }

    .dossier h1 {
      margin: 0 0 8px;
      color: var(--amber);
      font-family: var(--display);
      font-weight: 700;
      letter-spacing: 1.5px;
      font-size: clamp(24px, 4.2vw, 42px);
      line-height: 0.95;
      text-transform: uppercase;
      overflow-wrap: anywhere;
    }

    .doc-bar {
      font-size: 9px;
      letter-spacing: 1.4px;
      text-transform: uppercase;
      color: var(--muted);
      border: 1px solid rgba(232, 163, 61, 0.2);
      border-left: 3px solid var(--rust);
      padding: 4px 46px 4px 8px;
      margin-bottom: 8px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .doc-banner {
      position: relative;
      height: 150px;
      margin-bottom: 10px;
      border: 1px solid rgba(232, 163, 61, 0.28);
      overflow: hidden;
      clip-path: polygon(10px 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 10px);
    }

    .doc-banner canvas {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
    }

    .doc-banner::after {
      content: "";
      position: absolute;
      inset: 0;
      background: linear-gradient(180deg, rgba(10, 8, 6, 0.2), rgba(10, 8, 6, 0.04) 42%, rgba(10, 8, 6, 0.8));
    }

    .dossier .doc-banner h2 {
      position: absolute;
      left: 12px;
      right: 12px;
      bottom: 8px;
      z-index: 2;
      margin: 0;
      font-size: clamp(20px, 3vw, 30px);
      text-shadow: 0 2px 9px rgba(0, 0, 0, 0.95);
    }

    .doc-stamp {
      position: absolute;
      right: 10px;
      top: 15px;
      z-index: 2;
      transform: rotate(-11deg);
      font-size: 11px;
      letter-spacing: 2px;
      text-transform: uppercase;
      padding: 4px 9px;
      border: 2px solid;
      box-shadow: inset 0 0 0 1px rgba(10, 8, 6, 0.6);
      opacity: 0.85;
      background: rgba(10, 8, 6, 0.25);
    }

    .stamp-amber { color: var(--amber); border-color: rgba(232, 163, 61, 0.7); }
    .stamp-crimson { color: #e8566a; border-color: rgba(216, 53, 74, 0.75); }
    .stamp-cold { color: var(--cold); border-color: rgba(137, 164, 189, 0.7); }

    .doc-ref {
      display: flex;
      align-items: center;
      gap: 8px;
      color: var(--muted);
      font-size: 10px;
      letter-spacing: 1px;
      margin-bottom: 10px;
    }

    #relationChart {
      width: 100%;
      display: block;
      margin-bottom: 10px;
      border: 1px solid rgba(232, 163, 61, 0.22);
      background: rgba(8, 6, 4, 0.6);
      cursor: pointer;
      clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
    }

    .lore-link,
    .dossier-page-link {
      color: var(--amber);
      cursor: pointer;
      text-decoration: underline dotted rgba(232, 163, 61, 0.55);
      text-underline-offset: 3px;
    }

    .lore-link:hover,
    .dossier-page-link:hover {
      color: #ffd98c;
      text-shadow: 0 0 8px rgba(232, 163, 61, 0.4);
    }

    @keyframes transcribe {
      from {
        opacity: 0;
        transform: translateY(5px);
      }
    }

    .timeline2 {
      position: relative;
      padding-left: 18px;
    }

    .timeline2::before {
      content: "";
      position: absolute;
      left: 5px;
      top: 2px;
      bottom: 2px;
      width: 2px;
      background: linear-gradient(rgba(232, 163, 61, 0.5), rgba(232, 163, 61, 0.14));
    }

    .tl-event {
      position: relative;
      margin-bottom: 12px;
    }

    .tl-node {
      position: absolute;
      left: -17px;
      top: 4px;
      width: 7px;
      height: 7px;
      border: 1px solid var(--amber);
      background: #1a120a;
      transform: rotate(45deg);
    }

    .tl-event strong {
      display: block;
      color: var(--amber);
      font-size: 11px;
      margin-bottom: 2px;
    }

    .tl-event p {
      margin: 0;
      font-family: var(--prose);
      font-size: 13px;
      line-height: 1.5;
      color: var(--bone);
    }

    .tl-nihilus strong { color: var(--cold); }
    .tl-nihilus .tl-node { border-color: var(--cold); }

    .rift-break {
      position: relative;
      margin: 15px 0 15px -18px;
      padding: 7px 0 7px 20px;
      color: #e8737f;
      font-size: 10px;
      letter-spacing: 3px;
      text-transform: uppercase;
      background: linear-gradient(90deg, rgba(216, 53, 74, 0.2), rgba(216, 53, 74, 0.03) 85%);
      border-top: 1px solid rgba(216, 53, 74, 0.55);
      border-bottom: 1px solid rgba(216, 53, 74, 0.55);
      clip-path: polygon(0 0, 10% 22%, 24% 0, 38% 26%, 54% 0, 70% 24%, 86% 0, 100% 20%, 100% 80%, 88% 100%, 72% 76%, 56% 100%, 40% 78%, 24% 100%, 10% 76%, 0 100%);
    }

    .section-copy p:first-child:not(:has(.era-note))::first-letter,
    .tab-content > p.copy:first-child::first-letter {
      font-family: var(--display);
      float: left;
      font-size: 33px;
      line-height: 0.82;
      padding: 3px 7px 0 0;
      color: var(--amber);
    }

    .dossier-meta {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 8px;
      margin-bottom: 12px;
    }

    .kv {
      display: flex;
      flex-direction: column;
      justify-content: center;
      border: 1px solid rgba(232, 163, 61, 0.2);
      padding: 7px;
      background: rgba(10, 9, 8, 0.5);
      min-width: 0;
    }

    .kv span {
      display: block;
      color: var(--muted);
      font-size: 10px;
      text-transform: uppercase;
      margin-bottom: 4px;
    }

    .kv strong {
      color: var(--bone);
      font-size: 12px;
      overflow-wrap: anywhere;
    }

    .chips {
      display: flex;
      flex-wrap: wrap;
      gap: 6px;
      margin: 10px 0 12px;
    }

    .chip {
      border: 1px solid rgba(216, 208, 192, 0.24);
      color: var(--bone);
      background: rgba(216, 208, 192, 0.05);
      padding: 3px 6px;
      font-size: 11px;
    }

    .tabs {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 6px;
      margin-bottom: 12px;
    }

    .tab {
      height: 30px;
      border: 1px solid rgba(232, 163, 61, 0.24);
      background: rgba(10, 9, 8, 0.7);
      color: var(--muted);
      cursor: pointer;
      text-transform: uppercase;
      font-size: 11px;
    }

    .tab.active {
      color: var(--amber);
      border-color: rgba(232, 163, 61, 0.56);
      background: rgba(232, 163, 61, 0.08);
    }

    .copy {
      color: var(--bone);
      font-family: var(--prose);
      font-size: 14px;
      line-height: 1.62;
      margin: 0;
    }

    .copy + .copy {
      margin-top: 10px;
    }

    .section-block {
      border: 1px solid rgba(232, 163, 61, 0.22);
      background: rgba(10, 9, 8, 0.46);
      margin-bottom: 8px;
      clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
    }

    .section-block[open] {
      border-color: rgba(232, 163, 61, 0.42);
      background: rgba(232, 163, 61, 0.055);
    }

    .section-title {
      cursor: pointer;
      color: var(--amber);
      text-transform: uppercase;
      font-size: 12px;
      padding: 8px 10px;
      border-bottom: 1px solid rgba(232, 163, 61, 0.14);
    }

    .section-title::marker {
      color: var(--rust);
    }

    .section-copy {
      padding: 9px 10px 11px;
    }

    /* Overview lead prose sits flush (no bordered block) since the tab already labels it. */
    .section-copy.section-lead {
      padding: 2px 0 8px;
    }

    .section-copy p {
      color: var(--bone);
      font-family: var(--prose);
      font-size: 14px;
      line-height: 1.62;
      margin: 0 0 10px;
    }

    .section-copy p:last-child {
      margin-bottom: 0;
    }

    .era-note {
      color: var(--amber);
      font-family: var(--mono);
      font-size: 11px;
      text-transform: uppercase;
      margin-right: 6px;
    }

    .timeline {
      display: grid;
      gap: 9px;
    }

    .event {
      border-left: 2px solid var(--rust);
      padding-left: 9px;
      color: var(--bone);
      font-size: 12px;
      line-height: 1.45;
    }

    .event strong {
      display: block;
      color: var(--amber);
      margin-bottom: 3px;
    }

    .relation {
      width: 100%;
      min-height: 34px;
      margin-bottom: 7px;
      text-align: left;
      border: 1px solid rgba(232, 163, 61, 0.22);
      background: rgba(10, 9, 8, 0.62);
      color: var(--bone);
      cursor: pointer;
      padding: 7px;
    }

    .relation:hover {
      color: var(--amber);
      border-color: var(--amber);
    }

    .bottombar {
      left: 12px;
      right: 12px;
      bottom: 10px;
      min-height: 28px;
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 5px 10px;
      color: var(--muted);
      font-size: 11px;
    }

    .footer-copy {
      color: var(--muted);
      opacity: 0.72;
      min-width: 0;
    }

    .footer-guides {
      color: var(--amber);
      text-decoration: none;
      white-space: nowrap;
    }

    .footer-guides:hover,
    .footer-guides:focus-visible {
      color: var(--bone);
      text-decoration: underline;
    }

    /* The thought is centred on the PAGE, not merely within the slack between the disclaimer
       and the readouts (the disclaimer is wider, so an in-flow flex:1 box would sit right of
       centre). The bottombar is page-symmetric (left:12/right:12), so left:50% == page centre.
       max-width reserves symmetric room for the ~520px disclaimer + right readouts so the
       centred text never runs under them; on narrower viewports it simply ellipses to nothing. */
    .thought {
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
      max-width: calc(100vw - 1120px);
      min-width: 0;
      text-align: center;
      color: var(--bone);
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      transition: opacity 400ms ease;
    }

    #bootScreen {
      position: fixed;
      inset: 0;
      z-index: 60;
      background:
        repeating-linear-gradient(0deg, rgba(255, 214, 134, 0.03), rgba(255, 214, 134, 0.03) 1px, transparent 1px, transparent 4px),
        #050403;
      display: grid;
      place-items: center;
      transition: opacity 650ms ease;
      cursor: pointer;
    }

    #bootScreen.done {
      opacity: 0;
      pointer-events: none;
    }

    #bootLines {
      width: min(640px, 90vw);
      font-size: 13px;
      line-height: 2.1;
      color: var(--amber-soft);
      text-shadow: 0 0 12px rgba(232, 163, 61, 0.3);
    }

    #bootLines div:last-child::after {
      content: "\2588";
      margin-left: 6px;
      animation: bootBlink 0.7s steps(1) infinite;
    }

    @keyframes bootBlink {
      50% { opacity: 0; }
    }

    .coord-readout,
    .fps-readout {
      white-space: nowrap;
      color: var(--amber-soft);
    }

    /* Thought is out of flow (absolutely centred), so pin the readouts to the right edge. */
    .coord-readout {
      margin-left: auto;
    }

    .fps-readout {
      display: none;
    }

    .debug-visible .fps-readout {
      display: inline;
    }

    .debug {
      right: 16px;
      bottom: 56px;
      width: 230px;
      padding: 10px;
      color: var(--amber);
      font-size: 11px;
      line-height: 1.55;
      display: none;
    }

    .debug-visible .debug {
      display: block;
    }

    .purity-seal {
      position: absolute;
      right: 14px;
      top: 50px;
      width: 37px;
      height: 37px;
      border-radius: 50%;
      background: radial-gradient(circle at 34% 28%, #e05a48, #b21f18 48%, #711310 92%);
      border: 1px solid rgba(255, 206, 143, 0.35);
      box-shadow:
        inset 0 2px 5px rgba(255, 230, 200, 0.22),
        inset 0 -4px 7px rgba(0, 0, 0, 0.5),
        inset 0 0 0 4px rgba(120, 20, 15, 0.55),
        0 0 20px rgba(178, 24, 24, 0.3);
      opacity: 0.92;
      transform: rotate(-6deg);
    }

    .purity-seal::before {
      content: "\2720";
      position: absolute;
      inset: 0;
      display: grid;
      place-items: center;
      color: #7c120e;
      font-size: 17px;
      text-shadow: 0 1px 0 rgba(255, 220, 190, 0.22);
    }

    .purity-seal::after {
      content: "";
      position: absolute;
      left: 14px;
      top: 33px;
      width: 10px;
      height: 64px;
      background: linear-gradient(90deg, #4e100e, #7c1a14 45%, #4e100e), linear-gradient(#6d1714, rgba(109, 23, 20, 0.12));
      background-blend-mode: overlay;
      clip-path: polygon(0 0, 100% 0, 82% 100%, 50% 86%, 18% 100%);
      transform: rotate(4deg);
      box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
    }

    ::-webkit-scrollbar {
      width: 8px;
      height: 8px;
    }

    ::-webkit-scrollbar-track {
      background: rgba(10, 9, 8, 0.7);
    }

    ::-webkit-scrollbar-thumb {
      background: rgba(232, 163, 61, 0.32);
    }

    @media (max-width: 920px) {
      .topbar {
        align-items: flex-start;
        flex-direction: column;
      }

      .brand {
        min-width: 0;
        flex: 0 0 auto;
      }

      .controls {
        width: 100%;
        justify-content: flex-start;
      }

      /* Column banner: drop the centre overlay. order:1 sinks the pills BELOW the controls
         (brand + controls stay at order 0), and flex:1 1 0 halves shrink both pills so they
         sit compact, side by side across a single row. */
      .banner-actions {
        order: 1;
        position: static;
        display: flex;
        flex-wrap: nowrap;
        width: 100%;
        gap: 6px;
        align-items: stretch;
      }
      .banner-actions > .kofi-link {
        flex: 1 1 0;
        min-width: 0;
        justify-self: auto;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 6px 6px;
        font-size: 10px;
        letter-spacing: 0.04em;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
      /* Skulls cost width the narrow row can't spare. */
      .banner-actions .kofi-skull { display: none; }
      /* Keep the reveal overlay stacked, but let the shrunk column ellipsize instead of overflow. */
      .banner-actions .contact-link {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
      }
      .banner-actions .contact-link .contact-face {
        display: block;
        max-width: 100%;
        text-align: center;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }

      .panel {
        top: 118px;
        bottom: 44px;
      }

      .right-panel:not(.collapsed) {
        left: 12px;
        right: auto;
      }
    }

    @media (max-width: 620px) {
      /* ===== Mobile bottom-sheet layout (phones <=620px only; desktop & tablet untouched).
         Panels dock to the bottom as ~half-height sheets so the map stays visible and
         touch-pannable/zoomable above them. ===== */
      .panel {
        left: 0;
        right: 0;
        width: 100%;
        top: auto;
        bottom: calc(26px + env(safe-area-inset-bottom, 0px));
        height: min(46vh, 400px);
        border-radius: 16px 16px 0 0;
        clip-path: none;
        overflow: hidden;
        box-shadow: 0 -16px 36px var(--shadow), inset 0 0 26px rgba(232, 163, 61, 0.035);
      }

      /* Dossier sheet stacks above the archive sheet when a world is open. */
      .right-panel {
        z-index: 21;
      }
      .right-panel:not(.collapsed) {
        left: 0;
        right: 0;
      }

      /* Grab handle at the top of each sheet. */
      .panel::before {
        content: "";
        position: absolute;
        top: 6px;
        left: 50%;
        transform: translateX(-50%);
        width: 40px;
        height: 4px;
        border-radius: 2px;
        background: rgba(232, 163, 61, 0.45);
        z-index: 6;
      }
      .panel-head {
        padding-top: 8px;
      }

      /* Archive collapses to a peeking header handle (its persistent tap-to-open access). */
      .panel.collapsed.left-panel {
        transform: translateY(calc(100% - 48px));
      }
      /* Dossier is a full overlay: collapsing it slides fully off (past the disclaimer
         strip) to reveal the archive underneath — avoids two stacked peek handles. */
      .panel.collapsed.right-panel {
        transform: translateY(calc(100% + 34px + env(safe-area-inset-bottom, 0px)));
      }
      .panel.collapsed .panel-head span {
        display: inline;
      }

      .controls { gap: 6px; }
      .icon-button, .toggle, .era-option { padding: 0 6px; font-size: 11px; }
      .doc-stamp { right: 18px; font-size: 10px; }
      .thought { display: none; }

      /* Clear the notch / Dynamic Island, and drop the subtitle to save vertical space. */
      .topbar {
        top: calc(10px + env(safe-area-inset-top, 0px));
      }
      .brand span {
        display: none;
      }

      /* Thin disclaimer strip pinned to the very bottom, beneath the sheets. */
      .bottombar {
        flex-direction: row;
        align-items: center;
        gap: 8px;
        left: 0;
        right: 0;
        bottom: 0;
        min-height: 0;
        padding: 3px 12px calc(3px + env(safe-area-inset-bottom, 0px));
        border: 0;
        border-top: 1px solid rgba(232, 163, 61, 0.16);
        border-radius: 0;
        background: rgba(10, 8, 6, 0.92);
        clip-path: none;
        z-index: 22;
      }
      .footer-copy { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 9px; }
      .footer-guides { font-size: 9px; }
      .coord-readout, .fps-readout { display: none; }
    }
