/* ================================================================
   KINGDOM 685 — SITE ACCENT
   The one place the accent colour is defined. Every page loads this
   file plus /theme.js, which sets data-accent (the Profile choice) and
   data-theme="light" on <html> before paint. Page stylesheets only
   read the tokens below — none of them define accent colours.

   Per accent:
     --ks-accent-rgb         dark-mode accent (also used for tints and
                             for areas pinned dark in light mode)
     --ks-accent-bright-rgb  its brighter hover/emphasis step
     --ks-accent-ink         light-mode text accent, AAA on --bg-soft
     --ks-accent-ink-bright  light-mode emphasis text
     --ks-accent-line-rgb    light-mode border tint
   ================================================================ */
:root,
[data-accent="default"] {
  --ks-accent-rgb: 201,166,107;
  --ks-accent-bright-rgb: 227,191,126;
  --ks-accent-ink: #63491c;
  --ks-accent-ink-bright: #5c4620;
  --ks-accent-line-rgb: 154,116,58;
}
[data-accent="crimson"] {
  --ks-accent-rgb: 201,107,107;
  --ks-accent-bright-rgb: 227,138,138;
  --ks-accent-ink: #6e3b3b;
  --ks-accent-ink-bright: #5b3737;
  --ks-accent-line-rgb: 139,79,79;
}
[data-accent="sapphire"] {
  --ks-accent-rgb: 107,142,201;
  --ks-accent-bright-rgb: 138,176,227;
  --ks-accent-ink: #3b4e6f;
  --ks-accent-ink-bright: #37465b;
  --ks-accent-line-rgb: 75,100,143;
}
[data-accent="emerald"] {
  --ks-accent-rgb: 107,201,142;
  --ks-accent-bright-rgb: 126,227,168;
  --ks-accent-ink: #3b6f4e;
  --ks-accent-ink-bright: #325b43;
  --ks-accent-line-rgb: 75,143,100;
}
[data-accent="violet"] {
  --ks-accent-rgb: 155,107,201;
  --ks-accent-bright-rgb: 185,126,227;
  --ks-accent-ink: #553b6f;
  --ks-accent-ink-bright: #4a325b;
  --ks-accent-line-rgb: 107,79,143;
}
[data-accent="rose"] {
  --ks-accent-rgb: 201,107,142;
  --ks-accent-bright-rgb: 227,126,168;
  --ks-accent-ink: #6f3b4e;
  --ks-accent-ink-bright: #5b3243;
  --ks-accent-line-rgb: 143,79,107;
}

/* Living background (OPS-128, built by theme.js). The page backdrop
   (styles.css .ambient) gets a few rising embers (its glows are blurred, so
   they only move with the mouse/scroll, never on a loop);
   theme.js leans each layer with the mouse and scroll through `translate`,
   leaving `transform` to the animations here. Pages without .ambient get
   .ks-ambient: a fixed layer under everything (body is isolated so it
   paints above the page's own background). Neither ever takes clicks. */
.ks-alive .ambient-grid { inset: -40px; }
.ks-alive .ambient-glow, .ks-amb-glow, .ks-amb-embers { will-change: translate, transform; }
.ks-own-ambient body { isolation: isolate; }
.ks-ambient {
  position: fixed; inset: 0; z-index: -1;
  pointer-events: none; overflow: hidden;
}
.ks-amb-glow {
  position: absolute; inset: -60px;
  background:
    radial-gradient(38vmax 30vmax at 18% 20%, rgba(var(--ks-accent-rgb), 0.1), rgba(var(--ks-accent-rgb), 0.05) 30%, rgba(var(--ks-accent-rgb), 0.015) 55%, transparent 78%),
    radial-gradient(34vmax 28vmax at 84% 74%, rgba(58, 90, 99, 0.16), rgba(58, 90, 99, 0.08) 30%, rgba(58, 90, 99, 0.024) 55%, transparent 78%);
  animation: ks-amb-breathe 38s ease-in-out infinite alternate;
}
:root[data-theme="light"] .ks-amb-glow {
  background:
    radial-gradient(38vmax 30vmax at 18% 20%, rgba(var(--ks-accent-line-rgb), 0.11), rgba(var(--ks-accent-line-rgb), 0.055) 30%, rgba(var(--ks-accent-line-rgb), 0.017) 55%, transparent 78%),
    radial-gradient(34vmax 28vmax at 84% 74%, rgba(58, 90, 99, 0.08), rgba(58, 90, 99, 0.04) 30%, rgba(58, 90, 99, 0.012) 55%, transparent 78%);
}
.ks-amb-embers { position: absolute; inset: -60px; pointer-events: none; }
.ks-amb-embers i {
  position: absolute; top: 100%; border-radius: 50%;
  background: rgb(var(--ks-accent-bright-rgb));
  box-shadow: 0 0 6px 1px rgba(var(--ks-accent-bright-rgb), 0.55);
  opacity: 0;
  animation: ks-amb-rise var(--d, 20s) linear infinite;
}
:root[data-theme="light"] .ks-amb-embers i {
  background: rgb(var(--ks-accent-line-rgb));
  box-shadow: 0 0 5px rgba(var(--ks-accent-line-rgb), 0.4);
}
@keyframes ks-amb-breathe {
  from { transform: translate3d(-3%, -2%, 0) scale(1); }
  to   { transform: translate3d(3%, 2.5%, 0) scale(1.12); }
}
@keyframes ks-amb-rise {
  0%   { transform: translate3d(0, 0, 0); opacity: 0; }
  12%  { opacity: 0.5; }
  50%  { transform: translate3d(var(--w, 0px), calc(-50vh - 60px), 0); }
  80%  { opacity: 0.35; }
  100% { transform: translate3d(0, calc(-100vh - 120px), 0); opacity: 0; }
}
.ks-ambient-paused .ambient *,
.ks-ambient-paused .ks-ambient * { animation-play-state: paused !important; }
@media (prefers-reduced-motion: reduce) {
  .ks-amb-glow { animation: none; }
  .ks-amb-embers { display: none; }
}
@media print { .ks-ambient, .ks-amb-embers { display: none; } }

/* Mode-independent accent — for surfaces that stay dark in light mode
   (modals, photo scrims, the tools nav) and for hard-coded tints. */
:root {
  --ks-accent: rgb(var(--ks-accent-rgb));
  --ks-accent-bright: rgb(var(--ks-accent-bright-rgb));
  --ks-accent-dim: color-mix(in srgb, var(--ks-accent) 70%, #000);
}

/* The names page stylesheets read. The aliases are older names for the
   same two colours, kept so markup and per-section CSS need no changes. */
:root {
  --gold: var(--ks-accent);
  --gold-bright: var(--ks-accent-bright);
  --line: rgba(var(--ks-accent-rgb), 0.16);
  --line-strong: rgba(var(--ks-accent-rgb), 0.30);
  --ks-on-accent: #06090c;   /* text on a solid --gold fill */
}
:root[data-theme="light"] {
  --gold: var(--ks-accent-ink);
  --gold-bright: var(--ks-accent-ink-bright);
  --line: rgba(var(--ks-accent-line-rgb), 0.28);
  --line-strong: rgba(var(--ks-accent-line-rgb), 0.42);
  --ks-on-accent: #ffffff;
}
/* Native controls and scrollbars match the page instead of defaulting to
   light grey — most visible in the Tool widgets embedded on the Hub. */
:root { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }
:root {
  scrollbar-color: rgba(var(--ks-accent-rgb), 0.35) transparent;
}
:root[data-theme="light"] {
  scrollbar-color: rgba(var(--ks-accent-line-rgb), 0.45) transparent;
}
* { scrollbar-width: thin; }

:root,
:root[data-theme="light"] {
  --sage: var(--gold);
  --sage2: var(--gold-bright);
  --brass: var(--gold);
  --brass-dim: var(--gold-bright);
}

/* Page zoom control (theme.js). Sits flush on the right edge, dim until
   hovered or in use, so it never competes with page content. */
.ks-zoom {
  position: fixed; right: 0; bottom: 96px; z-index: 900;
  display: flex; flex-direction: column;
  background: rgba(10,13,17,0.82); border: 1px solid rgba(var(--ks-accent-rgb),0.28); border-right: 0;
  border-radius: 8px 0 0 8px; overflow: hidden; opacity: .55; transition: opacity .15s;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.ks-zoom:hover, .ks-zoom:focus-within, .ks-zoom.is-zoomed { opacity: 1; }
.ks-zoom button {
  width: 34px; height: 30px; padding: 0; border: 0; background: none; cursor: pointer;
  color: rgb(var(--ks-accent-bright-rgb)); font: 600 16px/1 Inter, system-ui, sans-serif;
}
.ks-zoom button[data-z="reset"] { height: 22px; font-size: 9px; letter-spacing: .02em; color: #9aa3ad;
  border-top: 1px solid rgba(var(--ks-accent-rgb),0.16); border-bottom: 1px solid rgba(var(--ks-accent-rgb),0.16); }
.ks-zoom button:hover { background: rgba(var(--ks-accent-rgb),0.14); }
@media print { .ks-zoom { display: none; } }

/* Kingdom 685's four alliances, one colour each, everywhere a tag is shown:
   <span class="ks-ally" data-tag="AAA">AAA</span>. Tags are case-sensitive
   in game ("XXX" and "XxX" are different alliances), and so is this match. */
.ks-ally { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; }
.ks-ally::before { content: ''; width: 9px; height: 9px; border-radius: 2px; flex: none; background: var(--ally, rgba(154,164,166,0.5)); }
[data-tag="AAA"] { --ally: #e0b84f; }
[data-tag="SHR"] { --ally: #9b6bd6; }
[data-tag="XXX"] { --ally: #d9534f; }
[data-tag="ASN"] { --ally: #4f8fdc; }
.ks-ally[data-tag="AAA"], .ks-ally[data-tag="SHR"], .ks-ally[data-tag="XXX"], .ks-ally[data-tag="ASN"] { color: var(--ally); }
/* Their in-game banners (cropped from the game, transparent PNGs). A tag chip
   shows its banner in place of the colour swatch; <i class="ks-banner"
   data-tag="AAA"></i> draws the banner on its own, and stays empty for any
   other alliance. */
[data-tag="AAA"] { --ally-banner: url("/assets/alliances/aaa.png"); }
[data-tag="SHR"] { --ally-banner: url("/assets/alliances/shr.png"); }
[data-tag="XXX"] { --ally-banner: url("/assets/alliances/xxx.png"); }
[data-tag="ASN"] { --ally-banner: url("/assets/alliances/asn.png"); }
.ks-ally[data-tag="AAA"]::before, .ks-ally[data-tag="SHR"]::before, .ks-ally[data-tag="XXX"]::before, .ks-ally[data-tag="ASN"]::before {
  width: 13px; height: 16px; border-radius: 0; background: var(--ally-banner) center / contain no-repeat;
}
.ks-banner { display: inline-block; flex: none; width: 1.1em; height: 1.35em; vertical-align: -0.3em;
  background: var(--ally-banner, none) center / contain no-repeat; }
.ks-banner:not([data-tag="AAA"]):not([data-tag="SHR"]):not([data-tag="XXX"]):not([data-tag="ASN"]) { display: none; }

/* ---- Tab transitions (OPS-58, softened in OPS-97) ----
   Page to page: a cross-document view transition. Every page gets this
   file (functions/_middleware.js), so the Tools and Forms pages animate
   too, not just the ones on styles.css. The app bar — .header on the main
   pages, the .ksb bar site-bar.js draws on Tools/Forms pages — shares one
   view-transition-name and is swapped in place without animating, so it
   stays still while the content under it crossfades. Old and new use the
   same duration and curve, so with the browser's default plus-lighter
   blending their opacities always add up to 1: the page never dips to
   the background in between. The new page is live from the first frame,
   so nothing waits on the fade. Browsers without view transitions
   (Firefox, older Safari) ignore all of this and navigate normally. */
@view-transition { navigation: auto; }
.header, .ksb { view-transition-name: app-header; }
html:has(.ksb) .header { view-transition-name: none; }
::view-transition-group(app-header) { animation: none; }
::view-transition-old(app-header) { display: none; }
::view-transition-new(app-header) { animation: none; }
::view-transition-old(root), ::view-transition-new(root) {
  animation-duration: 220ms;
  animation-timing-function: cubic-bezier(.4,0,.2,1);
  animation-fill-mode: both;
}
::view-transition-old(root) { animation-name: ks-vt-out; }
::view-transition-new(root) { animation-name: ks-vt-in; }
@keyframes ks-vt-out { to { opacity: 0; } }
@keyframes ks-vt-in { from { opacity: 0; } }

/* A fresh load (typed URL, reload, a link from outside, a browser without
   view transitions) fades the page in instead of it popping in. theme.js
   adds .ks-load-in only when no view transition is running, so a
   page-to-page hop doesn't fade twice. The fade starts on the first paint
   and holds nothing back. */
@keyframes ks-load-in { from { opacity: 0; } }
.ks-load-in body { animation: ks-load-in 360ms cubic-bezier(.3,0,.2,1) backwards; }

/* In-page tabs: a panel with .ks-tab-in fades in each time it is shown
   (display:none -> shown restarts a CSS animation), and
   KS685Theme.tabIn(el) replays it on content a tab re-renders in place.
   Off until the visitor first clicks or presses a key (theme.js adds
   .ks-interacted), so a page's first paint doesn't animate. */
@keyframes ks-tab-in { from { opacity: 0; transform: translateY(3px); } }
.ks-interacted .ks-tab-in { animation: ks-tab-in 300ms cubic-bezier(.3,0,.2,1) backwards; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  .ks-interacted .ks-tab-in, .ks-load-in body { animation: none; }
}

/* OPS-117: inside the installed home-screen app, pwa.js lets the page run
   edge to edge (viewport-fit=cover). Keep content clear of the notch in
   landscape and of the home indicator at the bottom. No effect in a normal
   browser tab, where the insets are 0. */
html.ks-standalone {
  padding-left: env(safe-area-inset-left, 0px);
  padding-right: env(safe-area-inset-right, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

/* ---- Mailbox (notifications.js) ----
   Here rather than injected by notifications.js so the icon is styled from
   the first frame: site-bar.js and the early draw in notifications.js put
   it in the app bar before that script's own setup runs (OPS-147). */
.ks-mailbox { position: relative; display: inline-flex; align-items: center; }
.ks-mailbox-btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0;
  background: none; border: 0;
  color: var(--ks-accent-bright); cursor: pointer; line-height: 1;
  transition: color 0.15s, transform 0.15s;
}
.ks-mailbox-btn svg { width: 24px; height: 24px; display: block; }
.ks-mailbox-btn:hover, .ks-mailbox-btn[aria-expanded="true"] { color: #eef1ec; }
.ks-mailbox-btn:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; border-radius: 4px; }
.ks-mailbox.is-on-light .ks-mailbox-btn { color: var(--ks-accent-ink); }
.ks-mailbox.is-on-light .ks-mailbox-btn:hover, .ks-mailbox.is-on-light .ks-mailbox-btn[aria-expanded="true"] { color: var(--ks-accent-ink-bright); }
.ks-mailbox.is-on-light .ks-mailbox-dot { border-color: #f5f2ec; }
.ks-mailbox-dot {
  position: absolute; top: 1px; right: -1px;
  width: 9px; height: 9px; border-radius: 50%;
  background: #c85a34; border: 2px solid #06090c;
  display: none;
}
.ks-mailbox-dot.is-visible { display: block; }
.ks-mailbox-fixed {
  position: fixed; top: 14px; right: 14px; z-index: 10000;
}
.ks-mailbox-panel {
  position: absolute; top: calc(100% + 10px); right: 0;
  width: 340px; max-width: calc(100vw - 24px);
  max-height: 420px; overflow-y: auto;
  background: #0d1319; border: 1px solid rgba(var(--ks-accent-rgb),0.28);
  border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,0.5);
  z-index: 10001; display: none;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
}
.ks-mailbox-panel.is-open { display: block; }
.ks-mailbox-panel.is-docked { position: fixed; left: 10px; right: 10px; width: auto; max-width: none; max-height: 70vh; }
.ks-mailbox-head {
  position: sticky; top: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px; border-bottom: 1px solid rgba(255,255,255,0.08);
  background: #0d1319;
}
.ks-mailbox-head strong { color: #eef1ec; font-size: 13px; letter-spacing: 0.02em; }
.ks-mailbox-markall {
  background: none; border: none; color: var(--ks-accent-bright); font-size: 11px;
  cursor: pointer; text-transform: uppercase; letter-spacing: 0.06em;
}
.ks-mailbox-markall:hover { color: #fff; }
.ks-mailbox-markall:disabled { opacity: 0.35; cursor: default; }
.ks-mailbox-empty { padding: 28px 16px; text-align: center; color: #9aa6a8; font-size: 12.5px; }
.ks-mailbox-item {
  display: flex; gap: 10px; padding: 11px 14px;
  border-bottom: 1px solid rgba(255,255,255,0.05);
  cursor: pointer; text-align: left; width: 100%; background: none; border-left: none; border-right: none; border-top: none;
}
.ks-mailbox-item:hover { background: rgba(var(--ks-accent-rgb),0.06); }
.ks-mailbox-item.is-unread { background: rgba(var(--ks-accent-rgb),0.04); }
.ks-mailbox-icon { font-size: 16px; flex-shrink: 0; margin-top: 1px; }
.ks-mailbox-body { flex: 1; min-width: 0; }
.ks-mailbox-title { color: #eef1ec; font-size: 12.5px; font-weight: 600; margin: 0 0 2px; display: flex; align-items: center; gap: 6px; min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
.ks-mailbox-title .ks-mailbox-unread-dot { width: 6px; height: 6px; border-radius: 50%; background: #c85a34; flex-shrink: 0; }
.ks-mailbox-text { color: #9aa6a8; font-size: 11.5px; line-height: 1.4; margin: 0; overflow-wrap: anywhere; word-break: break-word; white-space: normal; }
.ks-mailbox-time { color: #5c6668; font-size: 10px; margin-top: 4px; text-transform: uppercase; letter-spacing: 0.05em; }

/* ---- App bar tabs as real tabs (OPS-148) ----
   The current tab's highlight is a child element (theme.js markTab) with
   its own view-transition-name, so a tab change slides it from the old tab
   to the new one while the rest of the bar stays still (see "Tab
   transitions" above). It takes over from the underline / pill the two
   bars used to draw on the link itself; currentColor keeps each bar's
   colour. Only one may carry the name, so a page with both bars leaves
   the hidden main header's out. */
.ks-tab-ink {
  position: absolute; left: 0; right: 0; bottom: -2px; height: 2px;
  background: currentColor; pointer-events: none;
  view-transition-name: ks-tab-ink;
}
html:has(.ksb) .header .ks-tab-ink { view-transition-name: none; }
nav a[aria-current="page"]:has(> .ks-tab-ink), .ksb-tabs a[aria-current="page"]:has(> .ks-tab-ink) { box-shadow: none; }
/* The old underline padded the current tab 2px taller, which nudged its
   text up a pixel against its neighbours; the highlight hangs below it
   instead, so every tab's text sits on one line as it slides. */
@media (min-width: 561px) {
  nav a[aria-current="page"]:has(> .ks-tab-ink), .ksb-tabs a[aria-current="page"]:has(> .ks-tab-ink) { padding-bottom: 0; }
}
/* Alliance Mgmt sits after a divider; underline the text only. */
nav .nav-eo-link[aria-current="page"]:has(> .ks-tab-ink)::after { display: none; }
nav .nav-eo-link > .ks-tab-ink { left: var(--eo-pad, 0); }
.ksb-tabs a.ksb-lead > .ks-tab-ink { left: 20px; }
::view-transition-group(ks-tab-ink) {
  animation-duration: 320ms;
  animation-timing-function: cubic-bezier(.4,0,.2,1);
}
/* Phones: the tabs are pills, so the highlight is the filled pill. */
@media (max-width: 560px) {
  .ks-tab-ink, nav .nav-eo-link > .ks-tab-ink, .ksb-tabs a.ksb-lead > .ks-tab-ink {
    top: -1px; right: -1px; bottom: -1px; left: -1px; height: auto;
    border: 1px solid currentColor; border-radius: 999px;
    background: color-mix(in srgb, currentColor 16%, transparent);
  }
  nav a[aria-current="page"]:has(> .ks-tab-ink) {
    border-color: var(--line2); background: color-mix(in srgb, var(--text) 2%, transparent);
  }
  .ksb-tabs a[aria-current="page"]:has(> .ks-tab-ink) { border-color: rgba(255,255,255,.08); }
}

/* Tab shell (shell.js, OPS-153): while the next tab is on its way there is
   no browser loading bar, so the pointer says it instead. */
html.ks-shell-busy, html.ks-shell-busy a { cursor: progress; }
/* OPS-157: a tab with its own bar (Forms hub, site-bar.js) shows that bar
   in place of the main one while it is the tab showing. */
html.ks-shell-own-bar body > header.header, html.ks-shell-own-bar body > .ambient { display: none; }
