:root {
  /* The one game cursor (bronze gauntlet). Every rule that wants pointer/default/help goes through these; keep the fallback keyword in var(--x, kw) for pages without style.css. */
  --cursor: url('ui/cursorGauntlet_bronze.png') 8 8, auto;
  --cursor-pointer: url('ui/cursorGauntlet_bronze.png') 8 8, pointer;
  /* Parchment / bronze design system. Semantic aliases below keep legacy views compatible. */
  --surface: #faf6ed;
  --surface-raised: #fffaf0;
  --surface-inset: #eee3cc;
  --surface-selected: #e8d29e;
  --decoration-glow: #dbb76344;
  --surface-disabled: #e5dfd2;
  --border: #a38a61;
  --border-soft: #c9b795;
  --focus: #245f75;
  --success-surface: #e3e9d3;
  --warning-surface: #f5e0a8;
  --rarity-common: #67583f;
  --rarity-fine: #32685c;
  --rarity-rare: #45598f;
  --rarity-legendary: #775011;
  --font-body: 'Outfit', system-ui, sans-serif, 'Koy Emoji';
  --font-display: 'Cinzel', 'Garamond', serif, 'Koy Emoji';
  --text-xs: .875rem;
  --text-sm: .9375rem;
  --text-md: 1rem;
  --text-lg: clamp(1.1rem, 1rem + .3vw, 1.25rem);
  --text-xl: clamp(1.35rem, 1.1rem + .7vw, 1.75rem);
  --text-hero: clamp(1.6rem, 1.2rem + 1vw, 2rem);
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-panel: clamp(12px, 1.5vw, 20px);
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 16px;
  --radius-pill: 999px;
  --shadow-sm: 0 2px 8px #38281120;
  --shadow-panel: 0 8px 28px #38281130;
  --shadow-modal: 0 24px 80px #16100b66;
  --duration-fast: 120ms;
  --duration-normal: 220ms;
  --duration-slow: 450ms;
  --ease-out: cubic-bezier(.2,.8,.2,1);
  --touch-target: 44px;
  --progress-height: 8px;

  --glass: rgba(250, 246, 241, 0.92);
  --glass-solid: rgba(250, 246, 241, 0.97); /* phones: same tone, no backdrop blur (see the sheet-query block below #panel) */
  --line: rgba(139, 90, 43, 0.15);
  --text: #4a4a4a;
  --ink: #2e2013;       /* dark ink text on light parchment/beige surfaces */
  --muted: #6b5033;     /* darkened for AA contrast on light surfaces */
  --accent: #d4a574;
  --even: #7a4f1a;      /* "even odds" ink tone, readable on light surfaces */
  --good: #285e1a;      /* darkened for AA contrast on light surfaces */
  --bad: #8a3322;       /* darkened for AA contrast on light surfaces */
  --blue: #56647c;
  --btn-brown: #6b4a2c; /* unused now that all buttons use the light beige style below; kept so nothing else breaks if referenced */
  --btn-beige: #d9c398;
  --btn-grey: #d8d8d8;
  --btn-danger: #7a2f22; /* unused, see --btn-danger-bg */
  --btn-danger-bg: #e8c2b8; /* light red button fill so danger buttons still get dark text, not white on dark red */
  --btn-muted: #503a22;    /* darker than --muted, for small subtext that sits on a light button */
  --lbl-bg: rgba(250, 246, 241, 0.94); /* light parchment for map labels/hover chip, replacing the old dark-navy+white style */
  --lbl-border: rgba(46, 32, 19, 0.55);
  --bar-h: 72px; /* bottom action bar height, excluding safe-area inset */
  --top-h: 0px; /* measured height of #top (resource bar); JS keeps this in sync so #quest-tracker clears it */
  --quest-h: 0px; /* measured height of #quest-tracker (0 when hidden); JS keeps this in sync so mobile #panel/#toasts clear it too */
  --alerts-h: 0px; /* measured height of #alerts (0 when empty); JS keeps this in sync so #status-pop stacks below it instead of overlapping */
  --announce-h: 0px; /* measured height (+8px gap) of the open #announce ribbon under #top, 0 when collapsed/hidden; everything else in the top area stacks below it */
  --online-h: 0px; /* offset reserved for the removed floating online chip; always 0 now (the count is a badge on the dock's online shortcut), kept so the stacks below keep their math */
  --alert-bad: #7a2f22; --alert-warn: #8a5a1f; /* dark ink tones for the top-right alert stack, on light chip backgrounds */

  /* One z-index scale for the whole HUD, low to high. Every positioned overlay below references
     one of these instead of a bare number, so the stacking order is defined once and every layer's
     relationship to every other layer is visible at a glance right here. */
  --z-local-control: 1; /* close controls within their own stacking context */
  --z-labels: 1;
  --z-hud: 2;
  --z-intro-bg: 2;
  --z-map-card: 3;
  --z-action-card: 5;   /* building/terrain selection card */
  --z-bar: 6;           /* bottom action bar */
  --z-quest: 6;         /* top-left quest tracker */
  --z-alerts: 7;        /* top-right alert stack (raid/starvation/campaign) */
  --z-coach-ring: 8;    /* tutorial coach marks */
  --z-announce: 9;      /* admin announcement ribbon (in flow under #top, never over it) */
  --z-coach-bubble: 9;
  --z-toasts: 10;       /* transient toasts */
  --z-panel: 11;        /* docked window (#panel), above toasts so a toast never covers its close button */
  --z-chrome: 12;       /* persistent floating chrome: online chip/list, chat toggle/panel — above the docked window so their own popovers still work */
  --z-panel-coach: 12;
  --z-fx: 13;           /* animation overlay (#fx-layer, animations.css): above windows/chrome, below modals */
  --z-status-pop: 14;   /* HUD-anchored "⋯ Durum"/İnşaat ustaları popover: above windows/chrome; hangs under the HUD, never over it */
  --z-bar-menu: 19;     /* open navigation menu above transient messages, below dialogs */
  --z-modal: 20;        /* full-screen dialogs: intro carousel, away report */
  --z-info: 30;         /* touch explanations */
  font-family: 'Outfit', system-ui, -apple-system, 'Segoe UI', sans-serif, 'Koy Emoji';
  font-size: clamp(13px, 12px + .16vw, 15px);
  color: var(--text);
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; background: #dfe8ec; cursor: var(--cursor); }
#app canvas { display: block; touch-action: none; cursor: var(--cursor); }
[hidden] { display: none !important; }
button { font: inherit; color: inherit; cursor: var(--cursor-pointer, pointer); }
/* The UA stylesheet gives a:any-link the OS hand; keep the gauntlet on links too. */
a:any-link { cursor: var(--cursor-pointer, pointer); }

.glass, #top, #panel, #chat, #ranking-panel, .toast, #loading, #status {
  background: var(--glass);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border: 8px solid transparent;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.3), 0 8px 24px rgba(0,0,0,0.15);
  border-image-source: url('ui/panel_brown.png');
  border-image-slice: 8;
  border-image-repeat: stretch;
}
.glass { border-image: none; border: 2px solid #8b6f47; }

/* pick / auth screens */
#pick, #auth {
  position: fixed; top: calc(max(14px, env(safe-area-inset-top)) + var(--announce-h)); left: 14px;
  width: min(360px, calc(100vw - 28px)); padding: 16px 18px; border-radius: 0;
  max-height: calc(100dvh - max(14px, env(safe-area-inset-top)) - 14px - var(--announce-h)); overflow-y: auto;
  background: var(--glass);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border: 8px solid transparent;
  border-image-source: url('ui/panel_brown.png');
  border-image-slice: 8;
  border-image-repeat: stretch;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.3), 0 8px 24px rgba(0,0,0,0.15);
}
/* Auth screen only (not #pick, which sits over the live map): on a wide desktop viewport the
   top-left-pinned card left a large empty pale-blue void filling the rest of the screen
   (playtest). Centered/framed here instead, above the 760px mobile breakpoint; unchanged below it. */
@media (min-width: 761px) {
  #auth { top: 50%; left: 50%; transform: translate(-50%, -50%); max-height: min(calc(100dvh - 48px), 640px); }
}
/* Village pick: the chat / mail / friends dock sits bottom-left at x 14-65 and the card grows taller once a spot
   is chosen (name field + submit), so on wide screens it starts to the right of the dock instead of under it (playtest 1280x800). */
@media (min-width: 761px) {
  #pick.glass { left: 80px; }
}
/* Pre-login intro video (video/ Remotion render). Sits under #auth by DOM order, so no z-index. */
#intro-bg { position: fixed; inset: 0; background: #88775e; }
#intro-bg video { width: 100%; height: 100%; object-fit: cover; }
#intro-skip { position: absolute; right: 18px; bottom: calc(18px + env(safe-area-inset-bottom, 0px)); padding: 8px 16px;
  border: 1px solid var(--lbl-border); border-radius: 8px; background: var(--lbl-bg); color: var(--ink); font: 600 13px 'Outfit', sans-serif; cursor: var(--cursor-pointer, pointer); }
#auth:not([hidden]) { animation: auth-in .5s ease-out; }
@keyframes auth-in { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { #auth:not([hidden]) { animation: none; } }
#pick h1, #auth h1 { margin: 2px 0 6px; font-size: 25px; letter-spacing: -0.5px; font-family: var(--font-display);
  color: #8b5a2b; }
.brand-lockup { display: flex; align-items: center; gap: 10px; margin: 3px 0 6px; }
.brand-lockup img { flex: none; filter: drop-shadow(0 2px 3px rgba(46, 32, 19, .22)); }
#pick .brand-lockup h1, #auth .brand-lockup h1 { margin: 0; color: var(--ink); font-size: clamp(26px, 6vw, 34px); letter-spacing: .02em; }
#pick .pick-site-links { display: flex; flex-wrap: wrap; gap: 5px 12px; margin: 0 0 10px; font-size: 12px; line-height: 1.4; }
#pick .pick-site-links a, #auth .register-consent a { color: var(--even); text-decoration: underline; text-underline-offset: 2px; }
#auth .register-consent { display: grid; grid-template-columns: 18px 1fr; gap: 3px 8px; align-items: start; margin: 3px 0 12px; font-size: 12px; line-height: 1.45; }
#auth .register-consent input { grid-row: span 3; width: 16px; height: 16px; margin: 1px 0 0; accent-color: var(--even); }
#auth .register-consent label { color: var(--text); font-size: inherit; cursor: var(--cursor-pointer, pointer); }
#auth .register-consent a { grid-column: 2; }
.settings-site-links { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; padding: 10px 0 18px; }
.settings-site-links a { display: flex; align-items: center; gap: 10px; min-width: 0; min-height: 56px; padding: 9px 12px;
  border: 1px solid var(--border-soft); border-radius: var(--radius-md); background: var(--surface-raised);
  box-shadow: var(--shadow-sm); color: var(--ink); text-decoration: none; font-size: 12px; font-weight: 700; line-height: 1.35; }
@media (hover: hover) { .settings-site-links a:hover { border-color: var(--even); background: var(--surface-selected); } }
.settings-site-links a:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.settings-site-links a:last-child:nth-child(odd) { grid-column: 1 / -1; }
.settings-site-links a > span:nth-child(2) { min-width: 0; overflow-wrap: anywhere; }
.settings-page-icon { display: grid; flex: none; place-items: center; width: 32px; height: 32px; border-radius: 7px;
  background: var(--surface-inset); color: var(--even); font-size: 17px; }
.settings-page-arrow { margin-left: auto; color: var(--even); font-size: 16px; }
@media (max-width: 380px) { .settings-site-links { grid-template-columns: 1fr; } }
.ui-section-head h4 .settings-fps { color: var(--muted); font-weight: 500; }
.settings-legal { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 18px; margin: 10px 0 6px; font-size: var(--text-sm); }
.settings-legal a { display: inline-flex; align-items: center; min-height: 40px; }
.settings-danger.ui-more { margin-top: 18px; padding-top: 6px; border-top: 1px solid var(--border-soft); }
.settings-danger.ui-more summary { box-sizing: border-box; min-height: var(--touch-target, 44px); padding-block: 11px; cursor: var(--cursor-pointer, pointer); font-weight: 700; }
/* Folded rows in Ayarlar (Tehlikeli işlemler, Harita verisi, Mobil grafik): one card row with a › chevron instead of the native marker. */
#panel details.ui-more.settings-fold { margin: 6px 0; padding: 0; background: var(--surface-inset); border: 1px solid var(--border-soft); border-radius: var(--radius-md); }
#panel details.settings-fold > summary { display: flex; align-items: center; gap: 6px; min-height: 44px; margin: 0; padding: 4px 12px; list-style: none; cursor: var(--cursor-pointer, pointer); font-weight: 700; }
#panel details.settings-fold > summary::-webkit-details-marker { display: none; }
#panel details.settings-fold > summary::after { content: '›'; margin-left: auto; padding-left: 8px; font-size: 22px; line-height: 1; }
#panel details.settings-fold[open] > summary::after { transform: rotate(90deg); }
#panel details.settings-fold > :not(summary) { margin-inline: 12px; }
#panel details.settings-fold > .settings-danger-actions { margin-bottom: 10px; }
#panel details.settings-fold > .hint { margin-block: 0 10px; }
#panel details.settings-fold > .row { margin-inline: 8px; }
#panel .settings-danger-actions .hint { margin: 0 0 6px; }
#panel #map-credits .hint a { display: inline-flex; align-items: center; min-height: 40px; padding-inline: 2px; }
.row.settings-gift input { flex: 1 1 auto; min-width: 0; }
#panel .row.settings-compact, #panel .push-settings .row, #panel .email-preferences .row { padding-block: 5px; margin-bottom: 4px; }
.settings-site-links { padding-block: 6px 8px; }
.settings-site-links a { min-height: 48px; }
.settings-legal { margin-block: 4px; }
.settings-legal a { color: var(--ink); text-decoration: underline; }
/* Short phones (360x640): account, e-mail, gift and Tehlikeli share the first screen. */
@media (max-height: 700px) {
  #panel .row.settings-tight { gap: 8px; padding: 4px 10px; min-height: 0; }
  #panel .row.settings-tight b { font-size: 14px; }
  #panel .row.settings-tight small { font-size: 12px; line-height: 1.2; }
  #panel .row.settings-tight button { min-height: 40px; padding: 4px 10px; white-space: nowrap; }
  #panel .row.settings-tight input { min-height: 40px; }
  #panel details.settings-fold > summary { min-height: 40px; }
}
.settings-danger-actions { display: flex; flex-direction: column; gap: 8px; }
.settings-danger-actions button { min-height: 44px; white-space: normal; }
.push-settings .row, .email-preferences .row { min-height: 44px; }
.settings-providers { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; padding: 10px 0 16px; }
.settings-provider-card { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px;
  min-height: 53px; padding: 9px 12px; border: 1px solid var(--border-soft); border-radius: var(--radius-md); background: var(--surface-raised); }
.settings-provider-card b { color: var(--ink); font-size: 13px; }
.settings-provider-card a { display: inline-flex; align-items: center; min-height: 32px; padding: 3px 8px;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-selected);
  color: var(--ink); font-size: 12px; font-weight: 700; text-decoration: none; }
@media (hover: hover) { .settings-provider-card a:hover { background: var(--btn-beige); } }
.settings-provider-status { color: var(--muted); font-size: 12px; }
@media (max-width: 380px) { .settings-providers { grid-template-columns: 1fr; } }
#pick p, #auth p { margin: 0 0 10px; line-height: 1.5; color: var(--text); font-size: 13px; }
#pick .kicker, #auth .kicker { color: var(--even); text-transform: uppercase; letter-spacing: 2px; font-size: 12px; font-weight: 700; margin: 0; }
#pick .hint, #auth .hint { color: var(--muted); font-size: 12px; margin: 0; }
#pick .coords { color: var(--ink); font-weight: 600; }
/* founding terrain-diversity summary/warning (§ onPickClick/sampleFoundingTerrain) */
#pick-terrain { margin: 6px 0 !important; }
#pick .hint.warn, #auth .hint.warn { color: var(--alert-warn); }
#pick .hint.bad { color: var(--bad); }
#pick-confirm { border-top: 1px solid var(--line); padding-top: 10px; margin-bottom: 10px; }
#pick label, #auth label { display: block; font-size: 12px; color: var(--muted); }
#pick input, #auth input { display: block; width: 100%; margin: 5px 0 10px; padding: 8px 10px; border-radius: 8px;
  border: 1px solid rgba(139, 90, 43, 0.35); background: rgba(255, 255, 255, 0.6); color: var(--ink); font: inherit; }
#pick input:focus, #auth input:focus { outline: 2px solid var(--focus); }
#auth .auth-tabs { margin-bottom: 10px; }
#auth .auth-verify-actions { display: flex; gap: 8px; }
#auth .auth-verify-actions button[type=submit] { flex: 1; min-width: 0; }
#auth label .hint { display: block; margin-top: 2px; }
#pick-import { margin-bottom: 12px; }
#pick-import button { width: 100%; }
.pick-settings { margin: 5px 0 12px; border: 1px solid var(--border-soft); border-radius: 8px; background: var(--surface-raised); }
.pick-heading { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.pick-heading .brand-lockup { min-width: 0; }
.pick-heading-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
.pick-heading-actions button { flex: none; min-height: 36px; padding: 5px 9px; border: 1px solid var(--border); border-radius: 7px; background: var(--surface-raised); color: var(--ink); font: 700 12px 'Outfit', sans-serif; cursor: var(--cursor-pointer, pointer); }
@media (hover: hover) { .pick-heading-actions button:hover { background: var(--surface-inset); } }
@media (pointer: coarse) { .pick-heading-actions button { min-height: 44px; } .build-slots-more summary { min-height: 44px; display: flex; align-items: center; } }
.pick-settings summary { padding: 8px 11px; color: var(--ink); font-size: 12px; font-weight: 700; cursor: var(--cursor-pointer, pointer); }
.pick-settings summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.pick-settings[open] summary { border-bottom: 1px solid var(--border-soft); }
.pick-settings-body { display: grid; gap: 9px; padding: 10px 11px 12px; }
.pick-settings-body label { font-weight: 700; }
.pick-settings-actions { display: flex; flex-wrap: wrap; gap: 7px; }
.pick-settings-actions button { min-height: 38px; padding: 7px 10px; border: 1px solid var(--border); border-radius: 7px;
  background: var(--surface-inset); color: var(--ink); font-size: 12px; font-weight: 700; }
.pick-settings-actions button.danger { color: var(--bad); }
#pick .pick-distance { margin: -3px 0 10px; }
.geo-search { position: relative; }
#geo-results { list-style: none; margin: -6px 0 10px; padding: 0; max-height: 160px; overflow-y: auto;
  border: 1px solid rgba(139, 90, 43, 0.35); border-radius: 8px; background: rgba(255, 255, 255, 0.9); }
#geo-results li { padding: 6px 10px; font-size: 12px; color: var(--ink); cursor: var(--cursor-pointer, pointer); border-bottom: 1px solid var(--line); }
#geo-results li:last-child { border-bottom: none; }
@media (hover: hover) { #geo-results li:hover { background: rgba(139, 90, 43, 0.12); } }
#geo-results li.empty { color: var(--muted); cursor: var(--cursor, default); }
@media (hover: hover) { #geo-results li.empty:hover { background: none; } }
#pick button[type=submit], #auth button[type=submit], #pick-import button {
  width: 100%; padding: 10px; border: 8px solid transparent; border-radius: 0; font-weight: 700; font-size: 14px;
  color: var(--ink); box-shadow: none;
  border-image-source: url('ui/buttonLong_beige.png');
  border-image-slice: 8;
  border-image-repeat: stretch;
  background: var(--btn-beige);
  cursor: var(--cursor-pointer, pointer);
}
#pick-suggest { margin: 0 0 10px; }
#pick-suggest .hint, #pick-found-error p { margin: 0 0 6px; overflow-wrap: anywhere; }
#pick-found-error { margin: 0 0 10px; }
#pick-suggest-btn, #pick-found-retry { box-sizing: border-box; width: 100%; max-width: 100%; min-height: 44px; padding: 8px 10px; border: 8px solid transparent; border-radius: 0;
  font: 700 14px 'Outfit', sans-serif; color: var(--ink); white-space: normal; overflow-wrap: anywhere; cursor: var(--cursor-pointer, pointer);
  border-image: url('ui/buttonLong_beige.png') 8 stretch; background: var(--btn-beige); }
#pick-suggest-btn:active, #pick-found-retry:active { border-image-source: url('ui/buttonLong_beige_pressed.png'); }
#pick button[type=submit]:active, #auth button[type=submit]:active, #pick-import button:active { border-image-source: url('ui/buttonLong_beige_pressed.png'); }
#pick button[type=submit]:disabled:not([aria-busy="true"]), #pick-import button:disabled { cursor: not-allowed; }

/* top bar */
#top {
  position: fixed; top: max(10px, env(safe-area-inset-top)); left: 10px; right: 10px;
  display: flex; align-items: center; gap: 10px; padding: 6px 10px; border-radius: 12px; flex-wrap: wrap;
}
#top-info { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; width: 100%; }
#hud-toggle { display: none; }
/* HUD movement strip (move-strip.js): one line under the resource chips, inside #top, so --top-h already counts it. A small centred card sized to its
   text (never a full-width bar, owner 2026-11-01); the text ellipsizes when the cap or the screen is narrower. */
#move-strip { position: relative; flex: 0 1 auto; width: fit-content; max-width: min(560px, 100%); min-width: 0; display: flex; align-items: center; gap: 6px; min-height: 32px; margin: 0 auto; padding: 2px 12px;
  background: var(--surface-inset); color: var(--ink); border: 1px solid var(--border-soft); border-radius: var(--radius-md);
  font: inherit; font-size: 13px; font-weight: 600; text-align: left; cursor: var(--cursor-pointer, pointer); }
#move-strip[hidden] { display: none; }
#move-strip[data-kind="incoming"] { color: var(--alert-bad); box-shadow: inset 3px 0 0 var(--alert-bad); }
#move-strip .move-strip-text { min-width: 0; flex: 0 1 auto; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
/* 🏰 Köyüme dön (move-strip.js homeCallShown): beside the strip while an attack comes and the camera is away; the pair stays centred.
   Its own row under the strip on phones (below). 44 px: a thumb target. */
#home-call { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; margin: 0 auto 0 0; padding: 0 14px;
  background: var(--surface-inset); color: var(--alert-bad); border: 1px solid var(--alert-bad); border-radius: var(--radius-md);
  font: inherit; font-size: 13px; font-weight: 700; white-space: nowrap; cursor: var(--cursor-pointer, pointer); }
#home-call[hidden] { display: none; }
#move-strip:not([hidden]):has(+ #home-call:not([hidden])) { margin-right: 0; }
#move-strip[hidden] + #home-call { margin: 0 auto; }
/* urgency: a soft ring pulses around an incoming attack only */
@keyframes move-strip-pulse { from { opacity: .55; } to { opacity: 0; } }
@media (prefers-reduced-motion: no-preference) {
  #move-strip[data-kind="incoming"]::before { content: ''; position: absolute; inset: 0; border-radius: inherit; box-shadow: 0 0 0 4px var(--strip-pulse, currentColor); pointer-events: none; animation: move-strip-pulse 1.8s ease-out infinite; }
}
#nav { position: fixed; top: calc(max(64px, calc(env(safe-area-inset-top) + 52px)) + var(--announce-h)); left: 10px; width: min(280px, calc(100vw - 20px));
  padding: 10px 12px; border-radius: 0;
  background: var(--glass);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border: 8px solid transparent;
  border-image-source: url('ui/panel_brown.png');
  border-image-slice: 8;
  border-image-repeat: stretch;
}
#nav p { margin: var(--space-2) 0; color: var(--text); font-size: var(--text-sm); line-height: 1.5; }
#nav .row2 { display: flex; gap: 6px; }
#nav .row2 button { flex: 1; }
#nav .row2.mini { align-items: center; margin-top: 0; }
#nav .row2.mini b { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--font-display); font-size: var(--text-lg); }
#nav .row2.mini button { flex: 0 0 auto; min-width: var(--touch-target); padding-inline: 0; }
#nav:has(.row2.mini:not(.head)) { width: auto; max-width: min(360px, calc(100vw - 20px)); }
/* Target-card header (navHeadHtml in ui-components.js): the title on the left, a small ✕ in the corner. It is the same row as .row2.mini
   but keeps the card's own width, and sticks to the top so the ✕ stays reachable while a long card scrolls (the mobile sticky-bottom
   .row2 rules and the open-details static rule are weaker than three classes). */
#nav .row2.mini.head { position: sticky; top: calc(-1 * var(--space-3)); bottom: auto; z-index: var(--z-local-control); margin-top: 0; padding-bottom: var(--space-1); background: var(--surface); }
/* Target-card body (navChipsHtml / navRulesHtml / navActionsHtml in ui-components.js; player, district camp, neutral point and Himaye cards):
   facts as wrapping chips, the long rules in one fold, the actions in one equal-width row with the blocking reason right above it.
   `#nav p` is stronger than a bare class, hence the #nav selectors for the paragraph margins. */
.nav-chips { display: flex; flex-wrap: wrap; gap: var(--space-1); margin: var(--space-2) 0; }
.nav-chips .ui-badge { max-width: 100%; white-space: normal; overflow-wrap: anywhere; font-weight: 600; line-height: 1.4; padding-inline: var(--space-2); }
#nav p.nav-chips { margin: var(--space-2) 0; }
#nav p.nav-line { margin: var(--space-1) 0; }
.nav-rules { margin: var(--space-2) 0; }
.nav-rules summary { cursor: var(--cursor-pointer, pointer); min-height: var(--touch-target); display: flex; align-items: center; color: var(--ink); font-size: var(--text-sm); font-weight: 600; }
.nav-rules .hint { margin: 0 0 var(--space-2); }
.nav-warn, #nav p.nav-warn { margin: var(--space-2) 0 0; color: var(--bad); font-size: var(--text-xs); line-height: 1.4; overflow-wrap: anywhere; }
.nav-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
#nav .nav-actions > button, .nav-actions > button { margin: 0; }
.nav-actions > button { flex: 1 1 auto; min-width: 7.5em; min-height: var(--touch-target); white-space: normal; overflow-wrap: normal; word-break: normal; hyphens: manual; } /* wrap whole buttons, never split a word mid-letter */
.lbl.click { pointer-events: auto; cursor: var(--cursor-pointer, pointer); }
.lbl.army { background: linear-gradient(135deg, #dde3ea, #cbd4de); border-color: rgba(50, 65, 84, 0.5); font-weight: 600; }
#nav > button, #nav .row2 { margin-top: 6px; }
#nav > button { width: 100%; }
#top .brand { font-size: 15px; white-space: nowrap; font-family: var(--font-display); font-weight: 600; }
#top .chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chip { background: transparent; border: 6px solid transparent; padding: 6px 9px; border-radius: 0; font-weight: 600; font-size: 12.5px;
  font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--ink);
  border-image-source: url('ui/panelInset_beige.png');
  border-image-slice: 6;
  border-image-repeat: stretch;
  min-height: 26px;
  display: inline-flex;
  align-items: center;
}
.chip small { color: var(--good); font-weight: 400; margin-left: 2px; }
.chip small.neg { color: var(--bad); }

/* Each status has its own dock icon above the quest button. The builder detail still opens
   under its resource-bar chip; status details open beside the dock. */
#status-pop { z-index: var(--z-status-pop); width: min(300px, calc(100vw - 16px)); }
#status-pop .status-pop-body { display: flex; flex-direction: column; gap: 5px; }
#status-pop .chip { display: flex; width: 100%; white-space: normal; text-align: left; }
/* Village status: segment tabs + one compact panel (status-hud.js). Colours from theme tokens only (light surface). */
#status-pop .status-tabs { display: flex; flex-wrap: wrap; gap: var(--space-1); }
#status-pop .status-tab { flex: 1 1 auto; min-height: 40px; min-width: 0; padding: 4px var(--space-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink); font-size: var(--text-xs); font-weight: 600; line-height: 1.2; overflow-wrap: anywhere; box-shadow: none; }
#status-pop .status-tab[aria-selected=true] { background: var(--surface-selected); border-color: var(--even); box-shadow: inset 0 0 0 1px var(--even); }
#status-pop .vs-summary { display: flex; align-items: baseline; gap: var(--space-2); padding: var(--space-1) 0; border-bottom: 1px solid var(--border-soft); }
#status-pop .vs-ico { flex: none; }
#status-pop .vs-title { flex: 1; min-width: 0; font-size: var(--text-sm); color: var(--ink); overflow-wrap: anywhere; }
#status-pop .vs-amount { flex: none; font-size: var(--text-sm); font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ink); }

.panel-close { position: absolute; top: 6px; right: 6px; width: 22px; height: 22px; min-height: 0; padding: 0;
  border: 0; border-radius: 50%; background: rgba(139, 90, 43, 0.15); color: var(--ink); font-size: 12px;
  line-height: 1; cursor: var(--cursor-pointer, pointer); z-index: var(--z-local-control); }
@media (hover: hover) { .panel-close:hover { background: rgba(139, 90, 43, 0.28); } }

/* docked window — ONE window above the bottom action bar, replacing the old right-side panel;
   toggled by the bar buttons (see #bar below), Esc closes it. */
#panel {
  position: fixed; left: 50%; transform: translateX(-50%); z-index: var(--z-panel); /* above #toasts: a stacked toast must never cover the close button */
  bottom: calc(var(--bar-h) + env(safe-area-inset-bottom, 0px) + 10px);
  width: min(400px, calc(100vw - 20px)); max-height: min(58dvh, 560px);
  border-radius: 14px; display: flex; flex-direction: column; overflow: hidden;
}
#panel .win-head { display: flex; align-items: center; gap: 8px; flex-shrink: 0; padding: 9px 34px 9px 12px; border-bottom: 1px solid var(--line);
  font-family: var(--font-display); font-weight: 700; font-size: 13px; color: var(--ink); }
#panel .win-head img { width: 20px; height: 20px; image-rendering: pixelated; }
#panel .body { flex: 1; min-height: 0; overscroll-behavior: contain; overflow-y: auto; padding: 10px; }
.rank-badge { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); margin-bottom: var(--space-2); border-radius: var(--radius-md); background: var(--surface-inset); border: 1px solid var(--border-soft); }
.rank-badge img { width: 22px; height: 22px; image-rendering: pixelated; }
.rank-badge b { font-family: var(--font-display); font-size: var(--text-md); color: var(--ink); }
.rank-badge small { color: var(--muted); margin-left: auto; }

/* bottom MMORPG action bar */
#bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-bar);
  display: flex; justify-content: center; align-items: flex-end; gap: 12px;
  padding: 4px 10px calc(4px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(to top, rgba(20, 12, 5, 0.55), rgba(20, 12, 5, 0));
}
.bar-btn {
  position: relative; min-width: 64px; width: auto; height: 64px; padding: 0 3px; box-sizing: border-box; border: 0; border-radius: 10px; /* grows with a long caption (EN/FR/DE) instead of spilling over its neighbours */
  background-image: url('ui/kibyra/slot-frame.png'); background-size: 100% 100%; image-rendering: pixelated;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0;
  min-height: 0; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.35);
}
.bar-btn.on { filter: brightness(1.25) saturate(1.2); transform: translateY(-3px); }
/* The guide's "Sıradaki adım" window glow. Set on every viewport (the mobile layout tweaks are
   separate, under #bar.mobile-guide) so a desktop player gets the same single pointer. Pulses with
   the same ring pulse as every other "recommended control" highlight in the game. The pulse is a ring pseudo-element fading its opacity
   (compositor only; animating the element's own box-shadow repainted on the main thread every frame, 2026-11-06). */
.bar-btn.guide-next { outline: 3px solid var(--even); outline-offset: 2px; transform: translateY(-4px);
  box-shadow: 0 0 0 5px var(--decoration-glow), 0 5px 14px #0006; }
.bar-btn.guide-next::before { content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  box-shadow: 0 0 0 5px var(--decoration-glow); opacity: 0; animation: next-ring 1.6s ease-in-out infinite; }
/* The 📜 Görevler dock button points while a guide step waits (quick-dock.js): the quest card opens only on a press. The bar's own guide-next glow wins, so there is one pointer. */
#quick-dock [data-quick="quest"].guide-next { outline: 3px solid var(--even); outline-offset: 2px; box-shadow: 0 0 0 5px var(--decoration-glow), 0 3px 10px #0006; }
@media (prefers-reduced-motion: no-preference) { #quick-dock [data-quick="quest"].guide-next { animation: next-pulse 1.6s ease-in-out infinite; } }
.bar-btn:active { filter: brightness(0.92); }
.bar-btn img { width: 29px; height: 29px; image-rendering: pixelated; margin-top: -5px; }
.bar-btn .key { position: absolute; top: 2px; left: 4px; font-size: 12px; font-weight: 700; color: var(--ink);
  background: var(--lbl-bg); border: 1px solid var(--lbl-border); border-radius: 5px; padding: 0 3px; line-height: 1.4; }
.bar-btn .lbl { font-size: 12px; font-weight: 700; color: var(--ink); background: var(--lbl-bg);
  border: 1px solid var(--lbl-border); border-radius: 5px; padding: 0 4px; margin-top: 1px; line-height: 1.4;
  max-width: 100%; box-sizing: border-box; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-menu-icon { color: var(--ink); font-size: 27px; font-weight: 800; line-height: 1; margin-top: -4px; }
.bar-menu-wrap { position: relative; display: flex; align-self: flex-end; }
.bar-menu-wrap > .bar-btn { flex: 1 1 auto; }
.bar-overflow {
  position: absolute; right: 0; bottom: calc(100% + 4px); /* anchored to the Menü button (.bar-menu-wrap), right edges aligned */
  width: min(276px, calc(100vw - 24px)); padding: 8px;
  display: grid; gap: 6px; border: 2px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface-raised); box-shadow: var(--shadow-panel);
}
.bar-overflow button {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 52px; padding: 6px 10px;
  border: 1px solid var(--border-soft); border-radius: var(--radius-md);
  background: var(--surface); color: var(--ink); font-size: 14px; font-weight: 700; text-align: left;
}
.bar-overflow button:focus-visible { background: var(--surface-selected); border-color: var(--border); }
@media (hover: hover) { .bar-overflow button:hover { background: var(--surface-selected); border-color: var(--border); } }
.bar-overflow img { width: 30px; height: 30px; image-rendering: pixelated; }
.bar-overflow .badge { margin-left: auto; border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--warning-surface); color: var(--ink); padding: 1px 6px; font-size: 12px; }
.bar-overflow .menu-key { margin-left: auto; color: var(--muted); font-size: 12px; }
.bar-overflow .badge + .menu-key { margin-left: 0; }
.bar-btn .badge { position: absolute; top: -5px; right: -5px; background: var(--btn-danger-bg); color: var(--bad);
  border: 1.5px solid rgba(46, 32, 19, 0.55); border-radius: 8px; font-size: 12px; font-weight: 700;
  padding: 1px 4px; line-height: 1.3; white-space: nowrap; }
.bar-btn .badge.warn { background: var(--btn-beige); color: var(--ink); } /* --even on --btn-beige was only 3.43:1, below the 4.5:1 floor */
.bar-btn .badge.good { background: var(--good); color: #fff; } /* Sefer: camps ready to hit (bar-render.js) */


/* Server admin announcement: a parchment ribbon in the top flow, directly UNDER #top (never over
   it). Everything else in the top area adds --announce-h (JS-measured) to its offset, so the quest
   card, online chip and alert stack sit below it instead of colliding. */
#announce {
  position: fixed; top: calc(max(10px, env(safe-area-inset-top)) + var(--top-h) + 8px); left: 50%; transform: translateX(-50%);
  z-index: var(--z-announce); width: min(640px, calc(100vw - 20px)); max-height: min(48vh, 380px);
  overflow-y: auto; overscroll-behavior: contain;
}
/* Server restart/deploy countdown (restart-notice.js): pinned to the very top, above the HUD and
   panels but below modals, dark ink on the warning surface so it reads on any scene. */
#restart-banner {
  position: fixed; top: max(6px, env(safe-area-inset-top)); left: 50%; transform: translateX(-50%);
  z-index: var(--z-bar-menu); max-width: calc(100vw - 20px); padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-pill); background: var(--warning-surface); color: var(--ink);
  border: 1.5px solid var(--even); box-shadow: var(--shadow-panel); font-weight: 600; text-align: center;
}
#restart-banner[hidden] { display: none; }
/* Opened from a dock button, a quick panel is a popover anchored to the right of its icon
   (JS sets left/top inline) instead of its old top-corner fixed panel. */
/* max-width: the popover sits to the right of the dock icons, so it may never be wider than the room
   left of the viewport edge (otherwise render-hud.js clamps it back over the icons / off-screen). */
#announce.anchored, #online-list.anchored, #alerts.anchored, #quest-tracker.anchored {
  left: 0; top: 0; bottom: auto; right: auto; transform: none; max-width: calc(100vw - 80px);
}
#announce.anchored { width: min(360px, calc(100vw - 80px)); }
#announce:not([hidden]) { display: grid; gap: 8px; }
.announce-card {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--space-3);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3); border-radius: var(--radius-md);
  background: var(--surface-raised); color: var(--ink); border: 1px solid var(--border);
  box-shadow: inset 0 0 0 3px var(--surface-raised), inset 0 0 0 4px var(--border-soft), inset 4px 0 0 var(--even), var(--shadow-panel);
  animation: pop .25s ease-out;
}
.announce-seal { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; font-size: 18px;
  background: var(--warning-surface); border: 1.5px solid var(--border); }
.announce-kicker { margin: 0; font: 700 var(--text-xs)/1.2 var(--font-display); letter-spacing: .06em; color: var(--even); text-transform: uppercase; }
.announce-text { margin: 2px 0 0; font-size: var(--text-sm); font-weight: 600; line-height: 1.4; overflow-wrap: anywhere; }
.announce-text a { color: inherit; text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1.5px; }
.announce-text a:focus-visible { color: var(--even); text-decoration-thickness: 2.5px; }
@media (hover: hover) { .announce-text a:hover { color: var(--even); text-decoration-thickness: 2.5px; } }
.announce-close { width: 32px; height: 32px; min-height: 0; padding: 0; border-radius: var(--radius-sm); flex: none;
  border: 1px solid var(--border-soft); background: var(--btn-beige); color: var(--ink); font-weight: 700; }

/* top-right alert stack: raid countdowns, starvation, campaigns returning.
   Same --top-h offset as #quest-tracker so it clears #top instead of sitting under it. */
#alerts {
  position: fixed; top: calc(max(10px, env(safe-area-inset-top)) + var(--top-h) + var(--announce-h) + var(--online-h) + 8px); right: 10px; z-index: var(--z-alerts);
  display: flex; flex-direction: column; gap: 6px; align-items: flex-end; max-width: min(260px, calc(100vw - 20px));
}
#alerts .alert { background: var(--lbl-bg); border: 1.5px solid var(--lbl-border); border-radius: 8px;
  padding: 5px 9px; font-size: 12px; font-weight: 600; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  animation: pop .25s ease-out; }
#alerts .alert.bad { color: var(--alert-bad); box-shadow: inset 3px 0 0 var(--alert-bad), 0 4px 12px rgba(0, 0, 0, 0.25); }
#alerts .alert.warn { color: var(--alert-warn); box-shadow: inset 3px 0 0 var(--alert-warn), 0 4px 12px rgba(0, 0, 0, 0.25); }
#alerts .alert.more { color: var(--muted); font-weight: 700; text-align: center; }
#alerts .alert.good { color: var(--good); box-shadow: inset 3px 0 0 var(--good), 0 4px 12px rgba(0, 0, 0, 0.25); }
#alerts .alert button { display: inline-block; margin-left: 6px; padding: 2px 7px; min-height: 0; border-radius: 6px;
  font-size: 12px; font-weight: 700; border: 1px solid rgba(139, 90, 43, 0.35); background: var(--btn-beige); color: var(--ink); }


/* top-left quest tracker: current tutorial step + claim button, always visible in the village view.
   top offset clears #top (the resource bar, only shown in-village) via --top-h, which JS keeps in
   sync with its live rendered height so the two never overlap regardless of how many chips wrap. */
#quest-tracker {
  position: fixed; top: calc(max(10px, env(safe-area-inset-top)) + var(--top-h) + var(--announce-h) + 8px); left: 10px; z-index: var(--z-quest);
  width: min(300px, calc(100vw - 20px)); padding: 0; background: none; border: 0; box-shadow: none;
}
#quest-tracker .ui-quest { margin: 0; box-shadow: inset 0 0 0 3px var(--surface-raised), inset 0 0 0 4px var(--border-soft), var(--shadow-panel); }
#quest-tracker .ui-quest.is-ready { box-shadow: inset 0 0 0 3px var(--surface-raised), inset 0 0 0 4px var(--even), 0 0 0 3px var(--decoration-glow), var(--shadow-panel); }
.quest-tracker-links { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 2px; margin-top: 2px; } /* help + reward + board link + skip: wrap instead of overflowing at 360 px */
.quest-tracker-links .ui-link { padding: 0 var(--space-2); border-radius: var(--radius-sm) !important; background: var(--lbl-bg) !important; }
.quest-tracker-goal .ui-quest-kicker, .quest-tracker-goal .ui-quest-title, .quest-tracker-goal .ui-quest-desc { overflow-wrap: anywhere; } /* long DE/FR words break instead of overflowing the narrow card */
.quest-tracker-goal .ui-quest-reward { display: none; }
/* Desktop "İlerleme" panel (quest-tracker-ui.js adds .progress-dock when the viewport is not a phone layout): permanent at the right edge, under the resource bar.
   The dock-popover rules further down (left:70px; bottom-anchored) are overridden here by the extra class; a docked window, the chat or a placement card hide it (.sheet-open / :has(.action-card) below). */
#quest-tracker.progress-dock { top: calc(max(10px, env(safe-area-inset-top)) + var(--top-h) + var(--announce-h) + 8px); bottom: auto; left: auto; right: 14px; transform: none;
  box-sizing: border-box; width: min(304px, calc(100vw - 28px)); max-width: none; max-height: calc(100dvh - var(--top-h) - var(--bar-h) - 72px); overflow: hidden auto; scrollbar-width: thin; }
/* The centred tab bar (480 px wide) ends before the panel starts from 1024 px on (the panel is 256 px wide up to 1179 px, 304 px above), so there the panel may run down to the window's bottom edge;
   narrower windows keep it above the bar. */
@media (min-width: 1024px) { #quest-tracker.progress-dock { max-height: calc(100dvh - max(10px, env(safe-area-inset-top)) - var(--top-h) - var(--announce-h) - 8px - 16px); } }
@media (min-width: 1024px) and (max-width: 1179.98px) { #quest-tracker.progress-dock { width: 256px; } }
.progress-head { display: flex; align-items: center; gap: var(--space-2); min-height: 36px; margin-bottom: 6px; padding: 2px 4px 2px 10px; border-radius: var(--radius-md); background: var(--lbl-bg); border: 1px solid var(--lbl-border);
  color: var(--ink); font: 700 var(--text-sm)/1.2 var(--font-body); }
.progress-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.progress-count { flex: none; min-width: 20px; padding: 2px 6px; box-sizing: border-box; text-align: center; border-radius: var(--radius-pill); border: 1px solid var(--border); background: var(--warning-surface); font: 700 12px/1.1 var(--font-body); font-variant-numeric: tabular-nums; }
.progress-count.is-danger { border-color: var(--bad); background: var(--btn-danger-bg); color: var(--bad); }
#quest-tracker .progress-fold { flex: none; width: 32px; height: 32px; min-height: 0; padding: 0; border-radius: var(--radius-sm); border: 1px solid var(--border-soft); background: var(--btn-beige); color: var(--ink); font-size: 13px; line-height: 1; }
.progress-body { display: flex; flex-direction: column; gap: 6px; }
.progress-list { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 4px; list-style: none; border-radius: var(--radius-md); background: var(--lbl-bg); border: 1px solid var(--lbl-border); box-shadow: var(--shadow-panel); }
.progress-row { margin: 0; border-radius: var(--radius-sm); color: var(--ink); }
#quest-tracker .progress-hit { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; align-items: center; gap: 6px; box-sizing: border-box; width: 100%; min-height: 32px; margin: 0; padding: 2px 8px 2px 4px;
  border: 0; border-radius: var(--radius-sm); background: transparent; color: inherit; box-shadow: none; text-align: left; font: 600 var(--text-xs)/1.25 var(--font-body); }
#quest-tracker button.progress-hit { cursor: var(--cursor-pointer, pointer); }
.progress-ico { text-align: center; font-size: 15px; line-height: 1; }
.progress-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.progress-eta { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--muted); font-weight: 700; }
.progress-row.is-danger { background: var(--btn-danger-bg); box-shadow: inset 3px 0 0 var(--alert-bad); color: var(--alert-bad); }
.progress-row.is-danger .progress-eta { color: inherit; }
.progress-more { padding: 2px 8px; color: var(--muted); font: 600 var(--text-xs)/1.4 var(--font-body); text-align: center; }
@media (hover: hover) { #quest-tracker button.progress-hit:hover { background: var(--surface-selected); } }
#quest-tracker .progress-hit:focus-visible, #quest-tracker .progress-fold:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

/* coach marks: pulsing ring + speech bubble guiding a new player through the tutorial steps.
   Both are pointer-events:none so they can never block a click on the thing they're pointing at. */
#coach-ring { position: fixed; z-index: var(--z-coach-ring); pointer-events: none; transform: translate(-50%, -50%);
  border: 3px solid #f5a524; border-radius: 50%; box-shadow: 0 0 0 3px rgba(245, 165, 36, 0.35);
  animation: coachPulse 1.4s ease-in-out infinite; }
#coach-bubble { position: fixed; z-index: var(--z-coach-bubble); pointer-events: none; transform: translate(-50%, -100%);
  max-width: min(220px, calc(100vw - 24px)); padding: 7px 10px; border-radius: 10px;
  background: var(--lbl-bg); border: 1.5px solid var(--lbl-border); color: var(--ink);
  font-size: 12px; font-weight: 600; line-height: 1.4; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28); }
#coach-bubble.below { transform: translate(-50%, 10px); }
#coach-bubble::after { content: ''; position: absolute; left: 50%; bottom: -7px; margin-left: -7px;
  border: 7px solid transparent; border-top-color: var(--lbl-bg); }
#coach-bubble.below::after { top: -7px; bottom: auto; border-top-color: transparent; border-bottom-color: var(--lbl-bg); }
#labels .coach-bubble { border-color: #f5a524; box-shadow: 0 0 0 2px rgba(245, 165, 36, 0.45), 0 4px 14px rgba(0, 0, 0, 0.3); }
@keyframes coachPulse {
  0%, 100% { transform: translate(-50%, -50%) scale(0.92); opacity: 0.75; }
  50% { transform: translate(-50%, -50%) scale(1.08); opacity: 1; }
}

/* first-run "Nasıl oynanır" carousel */
#intro, #away { position: fixed; inset: 0; z-index: var(--z-modal); display: flex; align-items: center; justify-content: center;
  background: rgba(20, 12, 5, 0.45); }
.intro-card { max-height: calc(var(--visible-h, 100dvh) - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); overflow-y: auto; overscroll-behavior: contain; position: relative; width: min(360px, calc(100vw - 32px)); padding: 52px 18px 16px; text-align: center; }
.intro-icon { font-size: 38px; margin-bottom: 8px; }
.intro-card h3 { margin: 0 0 8px; font-family: var(--font-display); color: var(--ink); font-size: 16px; }
.intro-card p { margin: 0 0 14px; color: var(--text); font-size: 13px; line-height: 1.5; }
.intro-card .dots { display: flex; justify-content: center; gap: 6px; margin-bottom: 14px; }
.intro-card .dots .dot { width: 7px; height: 7px; border-radius: 50%; background: rgba(139, 90, 43, 0.3); }
.intro-card .dots .dot.on { background: var(--accent); }
.intro-card .row2 { display: flex; gap: 8px; margin-top: 4px; }
.intro-card .row2 button, .intro-card .row2 span { flex: 1; }
.intro-card button { padding: 8px; border-radius: 0; font-weight: 600; border: 8px solid transparent; cursor: var(--cursor-pointer, pointer);
  border-image-source: url('ui/buttonLong_beige.png'); border-image-slice: 8; border-image-repeat: stretch;
  background: var(--btn-beige); color: var(--ink); }
@media (hover: hover) { .intro-card button:hover { filter: brightness(1.05); } }
/* "Sen yokken" report card: same parchment/glass card as .intro-card, left-aligned (a list reads
   better than centered) and a bit wider for the event list. */
.away-card { width: min(400px, calc(100vw - 32px)); max-height: calc(100dvh - 48px); overflow-y: auto; text-align: left; }
.away-card h3 { text-align: center; }
.away-card .away-dur { text-align: center; font-weight: 600; color: var(--ink); }
.away-events { margin: 4px 0 12px; padding: 0 0 0 18px; font-size: 12.5px; color: var(--text); line-height: 1.5; }
.away-events li { margin-bottom: 4px; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(64px, 1fr)); gap: var(--space-2); margin-block: var(--space-2) var(--space-3); }
.stats div { background: var(--surface-inset); border-radius: var(--radius-md); padding: var(--space-2) var(--space-1); text-align: center; }
.stats b { display: block; font-size: var(--text-lg); color: var(--ink); font-variant-numeric: tabular-nums; }
.stats small { color: var(--muted); font-size: var(--text-xs); }
/* Köy › Binalar: the four stat cards and the builder rows fold into two lines. */
.koy-sum, .koy-builders { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); margin: var(--space-2) 0; padding: 0 var(--space-1); font-weight: 600; color: var(--ink); }
.koy-sum span, .koy-builders span { white-space: nowrap; }
.build-cancel-rule { display: block; color: var(--muted); font-size: var(--text-xs); }
.row small { color: var(--muted); font-size: var(--text-sm); }
.row small.good { color: var(--good); font-weight: 600; }
.row { display: flex; align-items: center; gap: 8px; padding: 7px 8px; border-radius: 10px; margin-bottom: 5px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid transparent; transition: border-color .2s, background .2s; }
.row.sel { border-color: var(--focus); background: rgba(245, 165, 36, 0.1); scroll-margin-top: 8px; }
/* The folded village status: population, soldiers, guards and wall read as one row of numbers
   rather than four separate chips. The bits separate on their own so the row never wraps oddly on
   a narrow HUD. */
.chip-status { display: inline-flex; align-items: center; gap: 6px; }
.chip-status .status-bit { display: inline-flex; align-items: baseline; gap: 2px; white-space: normal; min-width: 0; }
.chip-status .status-bit small { font-size: 12px; margin: 0; }
.row.flash { animation: blink 0.5s ease-in-out 3 alternate; } /* Sur-nudge scroll-to highlight, see renderAlerts()'s open-sur handler */
.row .ico { font-size: 22px; width: 28px; text-align: center; }
.row .grow { flex: 1; min-width: 0; }
.row .grow small { display: block; }
.row em { font-style: normal; font-size: var(--text-xs); background: var(--surface-inset); color: var(--ink); border: 1px solid var(--border-soft); padding: 0 var(--space-1); border-radius: var(--radius-sm); margin-left: var(--space-1); font-weight: 700; font-variant-numeric: tabular-nums; }
.row button, .danger, .seg button {
  border: 8px solid transparent; border-radius: 0; padding: 6px 9px; font-weight: 600; font-size: 12px;
  color: var(--ink); text-align: center; transition: transform .1s, filter .2s;
  border-image-source: url('ui/buttonLong_beige.png');
  border-image-slice: 8;
  border-image-repeat: stretch;
  background: var(--btn-beige);
}
.row button small { display: block; font-weight: 500; font-size: var(--text-xs); color: var(--btn-muted); }
.row button:active:not(:disabled) { border-image-source: url('ui/buttonLong_beige_pressed.png'); }
@media (hover: hover) { .row button:hover:not(:disabled) { filter: brightness(1.05); } }
button:active:not(:disabled) { filter: brightness(0.92); }
button:disabled { opacity: 1; cursor: not-allowed; filter: none; border-image: none; background: var(--surface-disabled); color: var(--muted); }
button:focus-visible { outline: 3px solid var(--ink); outline-offset: 4px; box-shadow: 0 0 0 1px var(--accent); }
button { min-height: 34px; }
.stepper button { width: 26px; height: 26px; border: 6px solid transparent;
  border-image-source: url('ui/buttonSquare_beige.png');
  border-image-slice: 6;
  border-image-repeat: stretch;
  background: var(--btn-beige);
  color: var(--ink);
  padding: 0;
  font-weight: 700;
  font-size: 14px;
}
.stepper button:active { border-image-source: url('ui/buttonSquare_beige_pressed.png'); }
.row .col2 { display: flex; flex-direction: column; gap: 4px; }
.row .col2 button { min-height: 28px; }
.row .batch-actions { display: flex; flex: 1 0 100%; justify-content: flex-end; flex-wrap: wrap; gap: var(--space-1); }
.stepper { display: flex; align-items: center; gap: 5px; }
.stepper b { min-width: 16px; text-align: center; font-variant-numeric: tabular-nums; }
.danger { width: 100%; margin-top: 10px; background: var(--btn-danger-bg); color: var(--bad); padding: 8px; }
.seg { display: flex; align-items: center; gap: 5px; margin: 3px 0 8px; font-size: 12px; color: var(--muted); flex-wrap: wrap; }
.seg button { background: rgba(139, 90, 43, 0.1); color: var(--ink); padding: 5px 8px; }
.seg button.on { background: var(--accent); color: var(--ink); }
.seg span { margin-left: auto; color: var(--text); }
.seg .send-count { display: inline-flex; align-items: center; gap: 4px; }
.send-count input { width: 6ch; min-width: 0; padding: 4px 5px; font: inherit; }
.pow { font-weight: 700; font-variant-numeric: tabular-nums; font-size: var(--text-sm); }
.pow.weak { color: var(--good); } .pow.even { color: var(--even); } .pow.strong { color: var(--bad); }
.armies, .log { list-style: none; padding: 0; margin: 0 0 8px; }
.armies li { padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); background: var(--surface); border: 1px solid var(--border-soft); margin-bottom: var(--space-2); font-size: var(--text-sm); color: var(--ink); }
.armies li.bad { background: rgba(122, 47, 34, 0.14); color: var(--bad); animation: blink 1s infinite alternate; }
.log li { padding: var(--space-2) var(--space-1); border-bottom: 1px solid var(--border-soft); font-size: var(--text-sm); line-height: 1.45; color: var(--ink); }
.log li small { display: block; color: var(--muted); font-size: var(--text-xs); }
.hint { color: var(--text); font-size: var(--text-sm); line-height: 1.5; margin: 0 2px var(--space-3); }
.empty { color: var(--muted); text-align: center; padding: 14px 0; }
.foot { color: var(--muted); font-size: var(--text-sm); text-align: center; }

/* world labels — light parchment chips with dark ink text so they read over the 3D map/sky in any light */
#labels { position: fixed; inset: 0; pointer-events: none; overflow: hidden; }
/* Scoped to #labels (the only place these classes are ever appended, see main.js's label()/
   floatText()) so the absolute-position + light pill here can never leak into an unrelated
   ".lbl" reused elsewhere, e.g. the bottom bar's button captions (.bar-btn .lbl). */
#labels .lbl, #labels .float { position: absolute; left: 0; top: 0; white-space: nowrap; will-change: transform; }
#labels .lbl { padding: 3px 7px; border-radius: 8px; font-size: 12px; background: var(--lbl-bg); color: var(--ink);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3); border: 1.5px solid var(--lbl-border); font-weight: 600; }
.lbl.village { background: linear-gradient(135deg, #f4ecd9, #e6d9bd); border-color: rgba(46, 32, 19, 0.6); font-size: 13px; padding: 4px 10px; }
.lbl.rival, .lbl.site, .lbl.player { pointer-events: auto; cursor: var(--cursor-pointer, pointer); transition: border-color .2s; }
/* İskân Fermanı: vakıf city pins (read-only, tap = info popover) and the district pick (lit = allowed, faded = not). */
#labels .lbl.vakif { pointer-events: auto; cursor: var(--cursor, help); max-width: min(240px, 62vw); overflow: hidden; text-overflow: ellipsis; background: linear-gradient(135deg, #e9efdc, #d3dec0); border-color: rgba(52, 84, 44, 0.65); font-size: 12px; padding: 3px 8px; }
#labels .lbl.vakif [data-info] { display: block; overflow: hidden; text-overflow: ellipsis; }
#labels .lbl.iskan-ok { border-color: #2f7d3a; box-shadow: 0 0 0 2px rgba(47, 125, 58, 0.55), 0 0 14px rgba(47, 125, 58, 0.55); }
#labels .lbl.iskan-no { opacity: 0.45; filter: grayscale(0.7); }
#labels .lbl.landmark { pointer-events: auto; cursor: var(--cursor-pointer, pointer); padding: 3px 5px; min-width: 23px;
  text-align: center; border-color: #987443; background: #f5e8c7; font-size: 13px; }
#labels .lbl.landmark.locked { color: #5c5349; background: #ddd8cb; border-style: dashed; }
/* Himaye ownership tint: mine blue, someone else's orange (+ owner name), same palette as .lbl.oasis. */
#labels .lbl.landmark.mine { border-color: rgba(47, 111, 214, 0.7); background: #e1ebfa; }
#labels .lbl.landmark.taken { display: flex; gap: 6px; align-items: center; border-color: rgba(166, 87, 55, 0.7); background: #f6e3d8; }
#labels .lbl.landmark.sel { border-color: var(--focus); box-shadow: 0 0 0 2px var(--focus); }
.landmark-card { max-width: min(420px, calc(100vw - 28px)); max-height: min(80vh, 700px);
  overflow: auto; border: 1px solid #8d714b; border-radius: 12px; padding: 20px;
  background: #f7f0df; color: #352a20; box-shadow: 0 16px 45px #0008; }
.landmark-card::backdrop { background: #0008; }
.landmark-card h2 { margin: 0 60px 12px 0; font-size: 20px; }
.landmark-card p { margin: 8px 0; line-height: 1.45; }
.landmark-card figure { margin: 14px 0; }
.landmark-card img { display: block; max-width: 100%; max-height: 270px; object-fit: contain; margin: auto; }
.landmark-card figcaption { font-size: 12px; margin-top: 6px; overflow-wrap: anywhere; }
.landmark-card a { color: #70461e; }
.landmark-close { float: right; cursor: var(--cursor-pointer, pointer); }
/* Maker card (ssilistre.dev easter egg): small, centred, cream with dark ink; the body fills the dialog so a tap on the dialog itself is a backdrop tap. */
dialog.maker-card { width: min(92vw, 360px); max-width: 92vw; max-height: 90dvh; overflow: auto; margin: auto; padding: 0; border: 2px solid var(--border); border-radius: var(--radius-xl);
  background: var(--surface); color: var(--ink); box-shadow: var(--shadow-modal); }
.maker-card .maker-body { position: relative; padding: 28px 22px 22px; text-align: center; border-top: 4px solid #ff3b24; border-radius: var(--radius-xl) var(--radius-xl) 0 0; }
.maker-card img { display: block; height: 36px; width: auto; margin: 0 auto 10px; }
.maker-card .maker-label { margin: 0; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: #5a4630; }
dialog.maker-card h2 { margin: 2px 0 8px; font: 800 26px/1.2 var(--font-body); overflow-wrap: anywhere; text-transform: none; font-variant: normal; letter-spacing: 0; }
.maker-card .maker-line { margin: 0 0 18px; line-height: 1.45; overflow-wrap: anywhere; }
.maker-card .maker-close { position: absolute; top: 6px; right: 6px; padding: 0; }
dialog.maker-card a.maker-open { display: flex; align-items: center; justify-content: center; min-height: 48px; padding: 10px 16px; border-radius: var(--radius-sm);
  background: #b3200f; color: #fff; font: 700 17px/1.3 var(--font-body); text-decoration: none; text-align: center; overflow-wrap: anywhere; }
@media (hover: hover) { dialog.maker-card a.maker-open:hover { background: #8f1809; } }
/* Himaye section of the card: dark text on the parchment, wraps at 360px. */
.landmark-himaye { margin: 10px 0; padding: 4px 0; border-block: 1px solid #cdb98f; color: #352a20; overflow-wrap: anywhere; }
.landmark-himaye .seg { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 8px 0; font-size: 14px; }
.landmark-himaye .seg button { flex: 1 1 auto; min-height: 44px; }
.landmark-himaye .seg button.on { background: #ecd9a8; border-color: #70461e; }
.landmark-himaye .seg > span { flex: 1 0 100%; }
.landmark-himaye > button { display: block; width: 100%; min-height: 44px; margin-top: 6px; }
.landmark-himaye .hint { margin: 6px 0 0; color: #7a3b1d; font-size: 13px; }
.landmark-himaye h4 { margin: 12px 0 2px; font-size: 15px; }
/* Boğaz geçişleri (public/crossings-ui.js): map label (ink on light, tint = free / someone's / mine / closed) and the menu in the landmark dialog. #labels-prefixed: the shared .lbl and [role=button] rules win otherwise. */
#labels .lbl.xing { pointer-events: auto; cursor: var(--cursor-pointer, pointer); display: flex; flex-wrap: wrap; justify-content: center; gap: 2px 6px; align-items: baseline; max-width: min(260px, 70vw); border-color: rgba(52, 84, 130, 0.6); background: #e3ebf5; color: var(--ink); }
#labels .lbl.xing small { font-weight: 600; color: var(--ink); }
#labels .lbl.xing.taken { border-color: rgba(166, 87, 55, 0.7); background: #f6e3d8; }
#labels .lbl.xing.mine { border-color: rgba(47, 111, 214, 0.7); background: #e1ebfa; }
#labels .lbl.xing.closed { border-color: rgba(160, 42, 26, 0.85); background: #f5dcd6; }
#labels .lbl.xing.sel { border-color: var(--focus); box-shadow: 0 0 0 2px var(--focus); }
.crossing-menu p { margin: 6px 0; }
.crossing-menu .crossing-closed { color: #7a1d12; font-weight: 700; }
.crossing-menu .crossing-stats { font-size: 13px; }
.crossing-price-form { display: flex; flex-wrap: wrap; align-items: end; gap: 8px; margin: 6px 0; }
.crossing-price-form label { display: grid; flex: 1 1 150px; gap: 4px; font-size: 14px; }
.crossing-price-form input { box-sizing: border-box; width: 100%; min-height: 44px; font-size: 16px; }
.crossing-price-form button { flex: 0 0 auto; min-height: 44px; }
.crossing-ledger h5 { margin: 10px 0 4px; font-size: 14px; }
.crossing-ledger ul { margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.4; }
.crossing-ledger > button { display: block; width: 100%; min-height: 44px; margin-top: 6px; }
.crossing-armies { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: 13px; }
.crossing-armies th, .crossing-armies td { padding: 3px 4px; border-bottom: 1px solid #d9c9a4; text-align: left; overflow-wrap: anywhere; }
.crossing-armies th:last-child, .crossing-armies td:last-child { width: 7em; text-align: right; }
.crossing-armies th { overflow-wrap: normal; word-break: normal; }
/* Toll lines (🌉 FSM: 40 altın (yarısı Ali için)) under a trade, İmaret, Kervansaray or army card: they inherit the card's ink. */
.toll-lines { margin: 4px 0; padding-left: 18px; font-size: 13px; line-height: 1.4; overflow-wrap: anywhere; }
.vakif-work { margin: 6px 0; padding-top: 6px; border-top: 1px dashed #cdb98f; }
.vakif-work button { display: block; width: 100%; min-height: 44px; margin-top: 6px; }
.vakif-short { color: #a02a1a; font-weight: 700; text-decoration: underline; }
.lbl.rival { display: flex; gap: 6px; align-items: center; }
.lbl.rival span { font-weight: 700; }
.lbl.player { display: flex; gap: 6px; align-items: center; border-color: rgba(47, 111, 214, 0.6); }
.lbl.player b { color: var(--blue); }
.lbl.oasis { pointer-events: auto; cursor: var(--cursor-pointer, pointer); display: flex; gap: 6px; align-items: center; border-color: rgba(70, 120, 60, 0.6); background: #e8f0dc; }
.lbl.oasis.mine { border-color: rgba(47, 111, 214, 0.7); background: #e1ebfa; }
.lbl.oasis.taken { border-color: rgba(166, 87, 55, 0.7); background: #f6e3d8; }
.lbl.sel { border-color: var(--focus); box-shadow: 0 0 0 2px var(--focus); }
.weak { color: var(--good); } .even { color: var(--even); } .strong { color: var(--bad); } .cd { color: var(--muted); }
/* İlçe hakimi: lonca renginde koyu zemin, beyaz metin okunur. */
.cd.hakim { color: #fff; padding: 0 5px; border-radius: 6px; }
/* dark ink text with a light parchment halo (faux-stroke via layered text-shadow) so it stays readable over any map tile */
.float { font-weight: 700; font-size: 15px; color: var(--ink);
  text-shadow: -1.5px -1.5px 0 #faf3e6, 1.5px -1.5px 0 #faf3e6, -1.5px 1.5px 0 #faf3e6, 1.5px 1.5px 0 #faf3e6,
    0 -1.5px 0 #faf3e6, 0 1.5px 0 #faf3e6, -1.5px 0 0 #faf3e6, 1.5px 0 0 #faf3e6, 0 2px 5px rgba(0, 0, 0, 0.3); }
.float.good { color: var(--good); } .float.bad { color: var(--bad); }

#hover { position: fixed; left: 0; top: 0; pointer-events: none; padding: 4px 8px; border-radius: 8px; font-size: 12px;
  background: var(--lbl-bg); color: var(--ink); border: 1.5px solid var(--lbl-border); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25); }
#hover.water { box-shadow: inset 3px 0 0 #0284c7, 0 4px 14px rgba(0, 0, 0, 0.25); } #hover.green { box-shadow: inset 3px 0 0 #16803d, 0 4px 14px rgba(0, 0, 0, 0.25); }
#hover.building { box-shadow: inset 3px 0 0 #8b5a2b, 0 4px 14px rgba(0, 0, 0, 0.25); }

#toasts { position: fixed; left: 50%; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom, 0px) + 14px); transform: translateX(-50%); display: flex; flex-direction: column;
  gap: 6px; align-items: center; pointer-events: none; z-index: var(--z-toasts); }
.toast { padding: 8px 13px; border-radius: 10px; font-size: 13px; animation: pop .25s ease-out; transition: opacity .5s, transform .5s;
  max-width: 90vw; pointer-events: auto; display: flex; align-items: center; gap: 8px; }
.toast button { padding: 4px 9px; border-radius: 6px; font-size: 12px; font-weight: 600; border: 1px solid rgba(139, 90, 43, 0.35);
  background: var(--btn-beige); color: var(--ink); flex: none; min-height: 0; }
.toast.good { border-color: rgba(52, 211, 153, 0.5); } .toast.bad { border-color: rgba(248, 113, 113, 0.6); } .toast.warn { border-color: rgba(245, 165, 36, 0.6); }
.toast.out { opacity: 0; } /* fade in place: a slide down (translateY) landed on the toast below it in the 6px-gap stack */
.toast-more { cursor: var(--cursor-pointer, pointer); font-weight: 700; color: var(--even); border-color: rgba(139, 90, 43, 0.4); }
#loading { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); padding: 10px 16px; border-radius: 12px; display: flex; gap: 8px; align-items: center; }
.spin { width: 14px; height: 14px; border: 2px solid rgba(255, 255, 255, 0.25); border-top-color: var(--accent); border-radius: 50%; animation: spin .8s linear infinite; }
#status { position: fixed; left: 10px; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom, 0px) + 14px); padding: 6px 10px; border-radius: 10px; display: flex; gap: 6px; align-items: center; font-size: 12px; }
#attrib { position: fixed; left: 8px; bottom: 6px; font-size: 10px; line-height: 14px; color: #334155; background: rgba(255, 255, 255, 0.7); padding: 1px 5px; border-radius: 6px; display: flex; align-items: center; gap: 3px; }
#attrib a { color: inherit; }
/* ⓘ: in game it opens Ayarlar > Rehber > Harita verisi (main.js); before the game window exists it shows / hides the credit (attrib-chip.js). */
#attrib-more { display: inline-flex; align-items: center; justify-content: center; position: relative; margin: 0; padding: 0; min-width: 14px; min-height: 0; font-size: 11px; line-height: 14px; cursor: var(--cursor-pointer, pointer); }
/* Compact attribution: after the first map press / ~6 s only the ⓘ is left (the credit was shown first, public/attrib-chip.js). overflow shows the tap area; the html prefix beats the themes' padding. */
#attrib.collapsed #attrib-osm { display: none; }
html #attrib.collapsed, html.iso.ui-a #attrib.collapsed { padding: 0; width: 16px; height: 16px; box-sizing: border-box; justify-content: center; border-radius: 50%; overflow: visible; }
html #attrib.collapsed #attrib-more { min-width: 16px; line-height: 16px; }
#attrib-more:enabled { background: none; border: 0; box-shadow: none; color: inherit; }
#attrib-more::after { content: ""; position: absolute; inset: -8px -6px; } /* tap area well past the 14 px glyph */

/* action card for building selection */
.action-card { position: fixed; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom, 0px) + 14px); right: 20px;
  width: min(280px, calc(100vw - 40px)); border-radius: 0; padding: 14px;
  z-index: var(--z-action-card); animation: pop .25s ease-out;
  border: 8px solid transparent;
  border-image-source: url('ui/panel_brown.png');
  border-image-slice: 8;
  border-image-repeat: stretch;
  background: var(--glass);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
}
.action-card h3 { margin: 0 0 6px; font-size: 15px; font-weight: 600; font-family: var(--font-display); }
.action-card .desc { margin: 0 0 10px; color: var(--muted); font-size: 12.5px; line-height: 1.4; }
.action-card .row2 { display: flex; gap: 6px; margin-top: 10px; }
.action-card .choices { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; }
.action-card .choice { width: 100%; text-align: left; }
.action-card .choice small { display: block; font-weight: 400; font-size: 12px; color: var(--btn-muted); margin-top: 2px; }
.action-card button { flex: 1; padding: 8px; border-radius: 0; font-weight: 600; border: 8px solid transparent; cursor: var(--cursor-pointer, pointer);
  border-image-source: url('ui/buttonLong_beige.png');
  border-image-slice: 8;
  border-image-repeat: stretch;
  background: var(--btn-beige);
  color: var(--ink);
}
.action-card .confirm { border-image-source: url('ui/buttonLong_beige.png'); background: var(--btn-beige); color: var(--ink); }
.action-card .cancel { opacity: 0.85; }
@media (hover: hover) { .action-card .confirm:hover { filter: brightness(1.05); } }
@media (hover: hover) { .action-card .cancel:hover { filter: brightness(0.95); } }

/* hint card for empty jobs */
.hint-card { background: var(--surface-inset); border: 1px solid var(--border-soft); padding: var(--space-3); border-radius: var(--radius-md); margin: var(--space-2) 0; }
.hint-card b { display: block; margin-bottom: var(--space-1); font-size: var(--text-md); color: var(--ink); }
.hint-card p, .hint-card li { margin: var(--space-1) 0; color: var(--text); font-size: var(--text-sm); }
.hint-card ul { margin: var(--space-2) 0; padding-left: 18px; }

/* output badge */
.output { display: inline-block; font-weight: 600; font-size: var(--text-xs); padding: 0 var(--space-1); border-radius: var(--radius-sm); }
.output.producing { background: rgba(111, 168, 87, 0.2); color: var(--good); }
.output.idle { color: var(--muted); }

/* affordability styling */
.row button.affordable { background: var(--btn-beige); color: var(--ink); opacity: 1; }
.row button.unaffordable { opacity: 1; background: var(--surface-disabled); color: var(--muted); }

/* incoming raid emphasis */
li.incoming { background: rgba(168, 95, 71, 0.2) !important; border-radius: 8px !important; padding-left: 10px !important;
  font-weight: 600 !important; color: var(--bad) !important; animation: pulse 2s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.85; } }

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pop { from { opacity: 0; transform: translateY(10px) scale(.96); } }
@keyframes blink { to { background: rgba(122, 47, 34, 0.3); } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }






/* --- online chip/list + chat: independent of #top (visible any time a session is live, not
   just in the 3D village view) ------------------------------------------------------------- */

/* Same top-offset formula as #alerts/#quest-tracker/#status-pop (max(10px,safe) + --top-h + 8px):
   clears #top (the resource bar) once it's showing in the village view instead of sitting on top
   of its rightmost chips — the reported bug. --top-h is 0 outside the village view (pick/auth/
   city), so the chip still sits near the top there, same as before. */
#online-list { position: fixed; top: calc(max(10px, env(safe-area-inset-top)) + var(--top-h) + var(--announce-h) + 8px + 44px); right: 14px; z-index: var(--z-chrome);
  width: min(280px, calc(100vw - 28px)); max-height: 50dvh; overflow-y: auto; padding: 6px;
  background: var(--glass); border: 1.5px solid var(--lbl-border); border-radius: 10px; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2); }
.online-row { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-radius: 8px; cursor: var(--cursor-pointer, pointer); color: var(--ink); font-size: 12.5px; }
@media (hover: hover) { .online-row:hover { background: rgba(139, 90, 43, 0.12); } }
.online-row .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex: none; }
.online-row .dot.on { background: var(--good); }
.online-row small { color: var(--muted); }
.online-row .hint { margin-left: auto; }
.online-row { padding: 3px; }
.online-visit { display: flex; align-items: center; flex: 1; min-width: 0; gap: 8px; padding: 4px;
  border: 0; background: transparent; color: var(--ink); text-align: left; }
.online-player-name { display: grid; min-width: 0; line-height: 1.3; }
.online-player-name b, .online-player-name small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.online-message { margin-left: auto; min-width: 32px; min-height: 32px; border: 1px solid var(--border-soft);
  border-radius: var(--radius-md); background: var(--surface-raised); color: var(--ink); }

#quick-dock { position: fixed; left: 14px; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 14px);
  z-index: var(--z-chrome); display: flex; flex-direction: column; gap: 6px;
  max-height: calc(100dvh - var(--top-h) - var(--bar-h) - 88px); overflow: hidden auto;
  padding: 2px 5px 2px 2px; scrollbar-width: thin; pointer-events: none; } /* the box can be wider than its buttons (event pill) and must not eat taps meant for the map card beside it */
#quick-dock > * { pointer-events: auto; }
#quick-dock button { position: relative; flex: none; width: 44px; height: 44px; padding: 0;
  border-radius: 50%; border: 1.5px solid var(--lbl-border); background: var(--glass); color: var(--ink);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .2); font-size: 19px; line-height: 1; }
/* The rail (2026-11-04, owner: grouped like the phone's, desktop included): a fixed set of at most six keys (event, quest, alerts, chat, 🗺️ layers (only on the zoomed-out map)
   or 👣 walk (only near the own village), ☷; İstanbul/Köy is the bar's); everything else (mail, announcements, status, ranking, online) is a cell of the "Diğer" grid (#dock-more).
   quick-dock.js syncQuickDockOrder keeps the same list in order: change both together (test/dock-layout.test.mjs compares them). */
#quick-dock > :not(.village-event-launcher, [data-quick="quest"], [data-quick="alerts"], #chat-toggle, #layers-btn, #walk-btn, #quick-dock-toggle) { display: none; }
#quick-dock button.is-open { border-color: var(--even); background: var(--warning-surface);
  box-shadow: 0 0 0 2px var(--surface-raised), 0 0 0 4px var(--even); }
#quick-dock .quick-badge { position: absolute; right: 1px; top: 1px; min-width: 17px; padding: 2px 3px;
  border-radius: 10px; border: 1px solid var(--bad); background: var(--btn-danger-bg); color: var(--bad);
  font: 700 12px/1 var(--font-body); }
body:has(#nav:not([hidden])) #nav { left: 70px; }
#quest-tracker, #alerts, #announce, #online-list {
  top: auto; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 64px);
  left: 70px; right: auto; max-height: min(54dvh, calc(100dvh - var(--top-h) - var(--bar-h) - 88px));
  overflow-y: auto; transform: none; }
#quest-tracker { width: min(340px, calc(100vw - 86px)); }
#alerts { width: min(300px, calc(100vw - 86px)); max-width: none; align-items: stretch; }
#announce { width: min(640px, calc(100vw - 86px)); }
#online-list { width: min(280px, calc(100vw - 86px)); }
/* "Diğer" grid: opened by the ☷ toggle on phones; status items, mail, announcements and online as 3-column cells. Light raised surface, dark ink. */
#dock-more { position: fixed; z-index: var(--z-chrome); left: 70px; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 14px); box-sizing: border-box;
  width: min(300px, calc(100vw - 86px)); max-height: min(54dvh, calc(100dvh - var(--top-h) - var(--bar-h) - 88px)); overflow-y: auto; overscroll-behavior: contain;
  padding: var(--space-2); border-radius: var(--radius-lg); background: var(--surface-raised); color: var(--ink); border: 1px solid var(--border); box-shadow: var(--shadow-panel); }
#dock-more:not([hidden]), .dock-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
#dock-more.anchored { left: 0; top: 0; bottom: auto; right: auto; max-width: calc(100vw - 80px); }
.dock-cell { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-width: 0; min-height: 52px; padding: 4px 2px;
  border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface-raised); color: var(--ink); box-shadow: none; }
.dock-cell-ico { font-size: 20px; line-height: 1; }
.dock-cell-label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 600 11px/1.2 var(--font-body); }
.dock-cell[aria-pressed=true] { background: var(--surface-selected); border-color: var(--even); box-shadow: inset 0 0 0 1px var(--even); }
.dock-cell .quick-badge { position: absolute; right: 2px; top: 2px; min-width: 17px; padding: 2px 3px; box-sizing: border-box; text-align: center;
  border-radius: 10px; border: 1px solid var(--bad); background: var(--btn-danger-bg); color: var(--bad); font: 700 12px/1 var(--font-body); }
#status-pop .dock-grid { flex: none; margin-bottom: var(--space-1); }
#quest-tracker:not(.quick-open), #alerts:not(.quick-open), #announce:not(.quick-open), #online-list:not(.quick-open), #dock-more:not(.quick-open),
.sheet-open #quick-dock, .sheet-open #quest-tracker, .sheet-open #alerts, .sheet-open #announce, .sheet-open #online-list, .sheet-open #dock-more,
body:has(.action-card) #quest-tracker.progress-dock {
  visibility: hidden; pointer-events: none; }
/* Open card (2026-11-03, owner): on desktop it sits at the right and the dock at the left, so the dock stays; only the right-edge "İlerleme" panel (above) collides
   with it. Phone layouts (their own block further down) keep hiding the dock: there the card is a bottom sheet over it. Between 761 and 1023 px the card (280 px
   at right:20px) can reach the wide left popovers (#announce 640 px and #ranking-panel 580 px end at x=710 / 650): they hide, the buttons stay. */
@media (min-width: 761px) and (max-width: 1023.98px) and (pointer: fine) {
  body:has(.action-card) #alerts, body:has(.action-card) #announce, body:has(.action-card) #online-list,
  body:has(.action-card) #dock-more, body:has(.action-card) #ranking-panel { visibility: hidden; pointer-events: none; }
}
#announce .announce-card { max-height: inherit; overflow-y: auto; }
body:has(#quick-dock .is-open) #toasts { top: calc(max(6px, env(safe-area-inset-top)) + var(--top-h) + 8px); bottom: auto; }
/* Open placement/selection card: toasts move up under the HUD and sit one layer below the card, so on a short phone a tall stack
   slides under it instead of covering its title and buttons. */
body:has(.action-card) #toasts { top: calc(max(6px, env(safe-area-inset-top)) + var(--top-h) + 8px); bottom: auto; z-index: calc(var(--z-action-card) - 1); }
/* Phones: only the newest toast shows while a card is open (the full list stays in Kayıtlar), so it ends before the card starts. */
@media (max-width: 480px) {
  body:has(.action-card) #toasts { left: 8px; right: 8px; transform: none; } /* full width: shrink-to-fit under left:50% gave the text only half the screen */
  /* newest real toast only: the "+N bildirim daha" badge can be appended last during a burst, so it never counts as newest */
  body:has(.action-card) #toasts .toast:has(~ .toast:not(.toast-more)), body:has(.action-card) #toasts .toast-more { display: none; }
  body:has(.action-card) #toasts .toast { padding-block: 3px; } /* a 3-line DE toast with a button still ends above a 640px-tall card */
}
#chat-toggle { position: fixed; left: 14px; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom, 0px) + 14px); z-index: var(--z-chrome);
  width: 44px; height: 44px; border-radius: 50%; font-size: 18px; color: var(--ink);
  background: var(--glass); border: 1.5px solid var(--lbl-border); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2); }
#quick-dock #chat-toggle { position: relative; left: auto; right: auto; top: auto; bottom: auto; z-index: auto; flex: none; }
#chat-toggle .badge, #chat-badge { position: absolute; top: -4px; right: -4px; background: var(--btn-danger-bg); color: var(--bad);
  border-radius: 10px; font-size: 12px; font-weight: 700; padding: 1px 5px; min-width: 14px; }

/* Same docked-window skin as #panel/#nav (panel_brown.png wood frame, via the shared
   .glass/#top/#panel/#chat/... rule above) instead of a plain thin-border card — chat is a real
   toggleable window, same family as the Köy/İşler/Sefer/Kayıtlar/Ayarlar windows, not a HUD chip. */
#chat { position: fixed; left: 14px; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom, 0px) + 66px); z-index: var(--z-chrome);
  width: min(320px, calc(100vw - 28px)); max-height: 46dvh; display: flex; flex-direction: column;
  padding: 0; border-radius: 12px; overflow: hidden; }
/* Desktop: the panel opens beside the dock's icon column (x = 70, like #nav and the quick panels), not over the icons. */
@media (min-width: 761px) and (pointer: fine) { #chat { left: 70px; width: min(320px, calc(100vw - 86px)); } }

/* Lonca tag next to a nick/village name on maps, chat rows and player cards. */
.clan-tag { color: var(--muted); font-weight: 600; }
#lonca-name, #lonca-tag, #lonca-search { display: block; width: 100%; padding: 7px 9px; border-radius: 8px;
  border: 1px solid rgba(139, 90, 43, 0.35); background: rgba(255, 255, 255, 0.6); color: var(--ink); font: inherit; }
#lonca-name { margin-bottom: 4px; }
.row-wrap { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 2px 10px; }
.badge-pin { background: var(--btn-beige); color: var(--ink); border-radius: 20px; padding: 4px 10px; font-size: 12px; font-weight: 700; }
#chat-messages { flex: 1; min-height: 60px; overscroll-behavior: contain; overflow-y: auto; padding: 8px 10px; display: flex; flex-direction: column; gap: 4px; }
.chat-msg { font-size: 12.5px; color: var(--ink); line-height: 1.4; word-break: break-word; }
.chat-msg b { color: var(--muted); }
.chat-msg small { color: var(--muted); margin-left: 4px; font-size: 12px; }
.chat-msg.chat-npc { font-style: italic; }
.chat-msg.chat-npc b { color: var(--even); }
#chat-form { display: flex; gap: 6px; padding: 8px; border-top: 1px solid var(--line); position: relative; }
#chat-mention-options { position: absolute; left: 8px; right: 8px; bottom: 100%; max-height: 180px;
  overflow-y: auto; background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: var(--shadow-panel); z-index: 1; }
#chat-form #chat-mention-options button { display: block; width: 100%; min-height: 36px; padding: 6px 10px;
  text-align: left; border: 0; border-image: none; border-radius: 0; background: transparent; color: var(--ink); }
#chat-form #chat-mention-options button[aria-selected="true"] { background: var(--btn-beige); }
@media (hover: hover) { #chat-form #chat-mention-options button:hover { background: var(--btn-beige); } }
#chat-form input { flex: 1; min-width: 0; padding: 8px 10px; border-radius: 8px; border: 1px solid rgba(139, 90, 43, 0.35);
  background: rgba(255, 255, 255, 0.6); color: var(--ink); font: inherit; }
/* Same pixel-art beige button skin as every other actionable button in the game (.row button,
   .action-card button, #pick/#auth submits, …) — plain <button> has no skin of its own (see the
   bare `button { font: inherit; color: inherit; cursor: var(--cursor-pointer, pointer); }` base rule), so without this
   the send button fell back to the browser's default chrome instead of matching the HUD. */
#chat-form button { padding: 8px 12px; border: 8px solid transparent; border-radius: 0; font-weight: 700;
  border-image-source: url('ui/buttonLong_beige.png'); border-image-slice: 8; border-image-repeat: stretch;
  background: var(--btn-beige); color: var(--ink); }
#chat-form button:active { border-image-source: url('ui/buttonLong_beige_pressed.png'); }

/* One strip: channel hint on the left, channel-specific text links on the right. */
#chat-subbar { display: flex; align-items: center; justify-content: space-between; gap: 4px 8px; padding: 2px 12px 4px;
  border-bottom: 1px solid var(--line); }
#chat-blocked-list { padding: 4px 10px; display: flex; flex-wrap: wrap; gap: 6px; }
#chat-blocked-list button { border: 1px solid var(--border-soft); border-radius: var(--radius-md);
  background: var(--surface-raised); padding: 5px 8px; }
#chat-messages { gap: 7px; padding: 10px; background: var(--surface); }
.chat-msg { align-self: flex-start; max-width: 94%; padding: 7px 9px; border: 1px solid var(--border-soft);
  border-radius: 10px 10px 10px 3px; background: var(--surface-raised); line-height: 1.45; }
.chat-msg.chat-own { align-self: flex-end; background: var(--success-surface); border-color: #a5b994;
  border-radius: 10px 10px 3px 10px; }
.chat-msg.chat-mentioned { background: var(--surface-selected); border-color: var(--even); }
.chat-msg b { display: block; margin-bottom: 2px; font-size: 12px; color: var(--even); }
.chat-msg small { display: block; margin: 3px 0 0; text-align: right; font-size: 12px; }
.chat-msg .chat-actions { display: flex; gap: 8px; margin-top: 3px; }
.chat-msg .chat-actions button { border: 0; background: none; color: var(--muted); font-size: 12px; padding: 3px; text-decoration: underline; }
.chat-msg.chat-supporter, .chat-msg.chat-supporter b, .chat-msg.chat-supporter > span { color: #775011; }
.chat-supporter-badge { display: inline-block; margin-left: 4px; font-size: 12px; font-weight: 700; }
#chat-messages .empty { align-self: center; text-align: center; padding: 14px; }



/* One pointer surface for the canvas and map labels; HUD sheets remain scrollable siblings. */
#app { position: fixed; inset: 0; height: 100dvh; touch-action: none; }
#labels { z-index: var(--z-labels); }
#top { z-index: var(--z-hud); }
#pick, #auth, #nav { z-index: var(--z-map-card); }
#intro-bg { z-index: var(--z-intro-bg); }
#geo-results li { padding: 0; }
#geo-results button { width: 100%; min-height: 44px; padding: 8px 10px; text-align: left; border: 0; background: transparent; }
#geo-results .empty { padding: 10px; }
/* ---- Anchored info popover: one parchment card for HUD chip details (#touch-info, rich or plain)
   and the "⋯ Durum"/İnşaat ustaları popover (#status-pop). JS (placePopover in info-card.js)
   sets left/top/max-height and --arrow-x; HUD cards always hang BELOW the whole resource bar. */
.info-pop { position: fixed; left: 0; top: 0; box-sizing: border-box; display: flex; flex-direction: column;
  padding: var(--space-3); border-radius: var(--radius-md); color: var(--ink);
  background: var(--surface-raised); border: 1px solid var(--border);
  box-shadow: inset 0 0 0 3px var(--surface-raised), inset 0 0 0 4px var(--border-soft), var(--shadow-panel);
  animation: info-pop-in var(--duration-fast) var(--ease-out); }
.info-pop > .info-body, .info-pop > .status-pop-body { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
@keyframes info-pop-in { from { opacity: 0; translate: 0 -4px; } }
@media (prefers-reduced-motion: reduce) { .info-pop, .announce-card { animation: none; } }
/* Arrow toward the chip; the card itself never scrolls (its body does), so it is never clipped. */
.info-pop[data-arrow=on]::before { content: ''; position: absolute; left: calc(var(--arrow-x, 50%) - 7px); width: 13px; height: 13px;
  background: var(--surface-raised); border: 1px solid var(--border); transform: rotate(45deg); pointer-events: none; }
.info-pop[data-side=below][data-arrow=on]::before { top: -8px; border-right: 0; border-bottom: 0; }
.info-pop[data-side=above][data-arrow=on]::before { bottom: -8px; border-left: 0; border-top: 0; }
#touch-info { z-index: var(--z-info); width: min(340px, calc(100vw - 16px)); }
#touch-info .info-close { position: absolute; top: 6px; right: 6px; width: 44px; height: 44px; padding: 0; border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm); background: var(--btn-beige); color: var(--ink); font-weight: 700; z-index: 2; }
#touch-info .info-body { padding-right: 46px; }
#touch-info.is-rich .info-body { padding-right: 0; }
#touch-info.is-rich .info-head { padding-right: 48px; }
.info-text { white-space: pre-line; overflow-wrap: anywhere; margin: 4px 0; line-height: 1.55; font-size: var(--text-sm); }
.info-head { display: flex; align-items: center; gap: var(--space-2); padding-bottom: var(--space-2); margin-bottom: var(--space-1); border-bottom: 1px solid var(--border-soft); min-height: 44px; }
.info-head-ico { display: grid; place-items: center; flex: none; width: 34px; height: 34px; border-radius: 50%; font-size: 18px; background: var(--surface-inset); border: 1.5px solid var(--border-soft); }
.info-head-main { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.info-title { font: 700 var(--text-md)/1.2 var(--font-display); color: var(--ink); }
.info-amount { font-size: var(--text-sm); font-weight: 700; font-variant-numeric: tabular-nums; color: var(--muted); }
.info-rate { flex: none; font-size: var(--text-sm); font-variant-numeric: tabular-nums; padding: 2px 8px; border-radius: var(--radius-pill); background: var(--surface-inset); }
.info-rate.good, .info-val.good { color: var(--good); } .info-rate.bad, .info-val.bad { color: var(--bad); }
.info-group { margin-top: var(--space-2); }
.info-group h6 { margin: 0 0 2px; font: 700 12px/1.3 var(--font-body); letter-spacing: .08em; text-transform: uppercase; color: var(--even); }
.info-group ul { list-style: none; margin: 0; padding: 0; }
.info-group li { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; align-items: baseline; gap: var(--space-2); padding: 3px 0; font-size: var(--text-sm); border-bottom: 1px dotted var(--border-soft); }
.info-group li:last-child { border-bottom: 0; }
.info-ico { text-align: center; }
.info-label { overflow-wrap: anywhere; }
.info-val { font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.info-note { margin: var(--space-2) 0 0; font-size: var(--text-xs); color: var(--muted); line-height: 1.4; }
.info-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.info-actions .info-action { flex: 1 1 140px; min-height: 40px; padding: 6px 10px; border: 1px solid var(--border-soft); border-radius: var(--radius-md); background: transparent; color: var(--ink); font-weight: 700; }
.info-actions .info-action.primary { background: var(--focus); border-color: var(--focus); color: #fff; }
#top .chip { text-align: left; }
#chat-bar, #chat-form { flex-shrink: 0; }
#panel, #nav, .action-card, #status-pop, #online-list { overflow-wrap: anywhere; }
#nav { max-height: calc(100dvh - 160px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); overflow-y: auto; overscroll-behavior: contain; }
.action-card { max-height: calc(100dvh - var(--bar-h) - 40px - env(safe-area-inset-bottom)); overflow-y: auto; overscroll-behavior: contain; }

/* Touch laptops and tablets also need large targets, even when they retain the desktop layout. */
@media (pointer: coarse), (max-width: 760px), (max-height: 500px) and (max-width: 1100px) {
  body button, body input, body select, body [role="button"], .online-row {
    min-width: 44px; min-height: 44px;
  }
  .panel-close { width: 44px; height: 44px; min-height: 44px; }
  #panel .win-head { min-height: 56px; padding-right: 52px; }
  .chip, .bar-btn, .lbl, #app { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
  body input, body textarea, body select, #auth input, #pick input,
  #chat-form input, #lonca-name, #lonca-tag, #lonca-search { font-size: 16px; }
  button, [role="button"] { touch-action: manipulation; }
  #app [role="button"] { touch-action: none; display: flex; align-items: center; justify-content: center; }
  .stepper button { width: 44px; height: 44px; flex: 0 0 44px; }
  .bar-btn .key { display: none; }
  #alerts .alert button, #announce button { min-height: 44px; min-width: 44px; }
}

/* Keep this query in sync with SHEET_QUERY in mobile-ui.js. */
@media (max-width: 760px), (pointer: coarse) and (max-width: 1100px), (max-height: 500px) and (max-width: 1100px) {
  :root { --bar-h: 72px; --edge-left: max(8px, env(safe-area-inset-left)); --edge-right: max(8px, env(safe-area-inset-right)); }
  #top { left: var(--edge-left); right: var(--edge-right); top: max(6px, env(safe-area-inset-top));
    padding: 2px; border-width: 6px; border-radius: 0; }
  #top-info { display: block; }
  #top .brand { display: none; }
  #top .chips { display: grid; width: 100%; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 2px; }
  #top .chip { min-width: 0; min-height: 44px; font-size: 12px; padding: 2px; border-width: 3px; white-space: normal; overflow-wrap: anywhere; /* a longer FR/DE label wraps inside its cell instead of spilling into the next one */
    justify-content: center; flex-wrap: wrap; align-content: center; line-height: 1.3; gap: 0 2px; }
  #top .chip small { font-size: 12px; margin: 0; }
  #top .chip:nth-child(-n+4) small { flex-basis: 100%; text-align: center; }
  #bar { gap: 4px; padding: 6px var(--edge-right) calc(6px + env(safe-area-inset-bottom)) var(--edge-left); }
  .bar-btn { flex: 1 1 0; max-width: 70px; width: auto; height: 60px; min-width: 40px; padding: 0 1px; }
  .bar-menu-wrap { flex: 1 1 0; max-width: 70px; min-width: 40px; }
  .bar-menu-wrap > .bar-btn { flex: 1 1 auto; max-width: none; min-width: 0; }
  .bar-btn img { width: 28px; height: 28px; margin-top: 0; }
  .bar-btn .lbl { display: block; padding: 1px 1px; font-size: clamp(9px, 2.45vw, 12px); letter-spacing: -0.02em; } /* seven captions share the width: shrink with it, never spill */
  .bar-btn .badge { font-size: 12px; right: -2px; }
  #panel, #chat, #ranking-panel { left: var(--edge-left); right: var(--edge-right); transform: none; width: auto; max-width: 560px; margin-inline: auto;
    bottom: calc(var(--bar-h) + env(safe-area-inset-bottom)); border-radius: 14px 14px 0 0;
    max-height: calc(var(--visible-h, 100dvh) - var(--bar-h) - 16px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
  #panel { height: auto; max-height: min(68dvh, 640px, calc(var(--visible-h, 100dvh) - var(--bar-h) - 16px - env(safe-area-inset-top) - env(safe-area-inset-bottom))); }
  #panel .body { padding: 8px; }
  #chat, #ranking-panel { height: min(58dvh, 560px); }
  .sheet-open #chat-toggle, .sheet-open #online-list,
  .sheet-open #coach-ring, .sheet-open #coach-bubble { visibility: hidden; }
  #chat-toggle { left: var(--edge-left); bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 10px); }
  #online-list { right: var(--edge-right); max-height: calc(100dvh - var(--top-h) - var(--announce-h) - 150px); }
  #announce { left: var(--edge-left); right: var(--edge-right); width: auto; transform: none; }
  .announce-card { gap: var(--space-2); padding-left: var(--space-2); }
  .announce-seal { width: 30px; height: 30px; font-size: 16px; }
  #quest-tracker { left: var(--edge-left); width: calc(100% - 144px - var(--edge-left) - var(--edge-right));
    max-height: 34dvh; overflow-y: auto; overscroll-behavior: contain; }
  #alerts { right: var(--edge-right); max-width: 132px; max-height: 28dvh; overflow-y: auto; }
  #alerts .alert { padding: 5px; font-size: 12px; }
  #toasts, #status { top: auto; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 12px); }
  #pick, #auth { left: var(--edge-left); right: var(--edge-right); width: auto; transform: none;
    top: calc(var(--visible-top, 0px) + max(8px, env(safe-area-inset-top)));
    max-height: calc(var(--visible-h, 100dvh) - 16px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
    padding: 12px; overscroll-behavior: contain; }
  #auth { width: min(440px, calc(100% - var(--edge-left) - var(--edge-right))); margin: auto; }
  #pick { top: auto; bottom: calc(8px + env(safe-area-inset-bottom)); max-height: 48dvh; }
  #pick .kicker { display: none; }
  #pick .pick-explain { font-size: 12px; line-height: 1.35; }
  #pick:has(#pick-confirm:not([hidden])) .pick-explain { display: none; }
  #pick h1 { font-size: 18px; }
  #pick .hint { font-size: 12px; }
  /* The suggested site and its "📍 Buraya kur" sit right under the heading, not below the fold of this 48dvh sheet (2026-11-10: the primary button was the last
     thing in the card and half cut on a 390x844 phone). `:not([hidden])` keeps the UA `display: none` of the closed card; children never shrink, the sheet scrolls. */
  #pick:not([hidden]) { display: flex; flex-direction: column; }
  #pick:not([hidden]) > * { flex-shrink: 0; }
  #pick:not([hidden]) > .pick-heading { order: -2; }
  #pick:not([hidden]) > #pick-suggest { order: -1; margin: 8px 0 10px; }
  #nav { position: fixed; top: auto; margin: 0; left: var(--edge-left); right: var(--edge-right);
    bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 8px); width: auto;
    max-height: 48dvh; padding: 8px; z-index: var(--z-action-card); }
  /* Istanbul idle card: keep the map visible on phones; the bar's İstanbul button already returns to the village. */
  #nav > button[data-go=home] { display: none; }
  .action-card { top: auto; left: var(--edge-left); right: var(--edge-right); transform: none; width: auto;
    bottom: calc(var(--bar-h) + env(safe-area-inset-bottom)); max-height: calc(100dvh - var(--bar-h) - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
  body:has(.action-card) #chat-toggle, body:has(.action-card) #online-list { visibility: hidden; }
  .row { gap: 6px; flex-wrap: wrap; padding: 7px 2px; }
  .row .grow { flex-basis: 100px; overflow-wrap: anywhere; }
  .row .col2 { max-width: 100%; }
  .row .col2 button { min-height: 44px; }
  .row .ico { flex-shrink: 0; }
  #attrib { left: auto; right: var(--edge-right); bottom: calc(var(--bar-h) + env(safe-area-inset-bottom)); font-size: 11px; padding: 1px 4px; pointer-events: none; }
  body:has(#pick:not([hidden])) #attrib { top: 60px; bottom: auto; }
  /* Only the link takes touches (OSM licence needs it clickable); `body` outranks the later global min-height. */
  body #attrib a { display: inline-flex; min-height: 0; align-items: center; pointer-events: auto; }
  body #attrib-more { pointer-events: auto; }
  /* Istanbul map: the stamp is a small corner label; only the link itself takes touches, so panning works under it. */
  body:has(#nav:not([hidden])) #attrib { left: var(--edge-left); right: auto; top: max(4px, env(safe-area-inset-top)); bottom: auto;
    font-size: 10px; padding: 1px 4px; max-width: calc(100vw - 16px); pointer-events: none; z-index: var(--z-chrome); }
  body:has(#nav:not([hidden])) #attrib a { min-height: 0; pointer-events: auto; }
  .sheet-open #attrib, body:has(.action-card) #attrib { visibility: hidden; }
  .keyboard-open #chat, .keyboard-open #ranking-panel, .keyboard-open #panel { bottom: calc(var(--keyboard-inset, 0px) + env(safe-area-inset-bottom));
    max-height: calc(var(--visible-h, 100dvh) - 12px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
  .keyboard-open #bar { visibility: hidden; }
  .keyboard-open #auth, .keyboard-open #pick { top: calc(var(--visible-top, 0px) + 6px); bottom: auto;
    max-height: calc(var(--visible-h, 100dvh) - 12px); }
}

@media (max-height: 500px) and (max-width: 1100px) {
  #pick .pick-explain { display: none; }
  :root { --bar-h: 64px; }
  .bar-btn { height: 52px; }
  #top .chips { grid-template-columns: repeat(8, minmax(0, 1fr)); }
  #panel, #chat, #ranking-panel { max-height: calc(var(--visible-h, 100dvh) - var(--top-h) - var(--bar-h) - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
  .keyboard-open #panel, .keyboard-open #chat, .keyboard-open #ranking-panel { max-height: calc(var(--visible-h, 100dvh) - 12px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
  #panel .body { padding: 6px 10px; }
  #quest-tracker { width: 220px; max-height: calc(100dvh - var(--top-h) - var(--announce-h) - var(--bar-h) - 30px); }
  #pick { width: min(340px, 44vw); right: auto; top: max(8px, env(safe-area-inset-top)); bottom: auto;
    max-height: calc(100dvh - 16px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
  #nav { left: auto; width: min(360px, 46vw); max-height: calc(100dvh - var(--bar-h) - 24px - env(safe-area-inset-top)); }
  body:has(#nav:not([hidden])) #online-list { right: auto; left: var(--edge-left); }
  body:has(#nav:not([hidden])) #alerts { right: auto; left: var(--edge-left); }
}
/* Four compact shortcuts share the chat edge on small screens. Each button opens one card,
   while the other cards stay out of the map and out of the resource HUD. */
@media (max-width: 760px), (pointer: coarse) and (max-width: 1100px), (max-height: 500px) and (max-width: 1100px) {
  #quick-dock { position: fixed; left: var(--edge-left); bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 10px);
    z-index: var(--z-chrome); display: flex; flex-direction: column; gap: 6px;
    max-height: calc(var(--visible-h, 100dvh) - var(--top-h) - var(--bar-h) - 88px); overflow: hidden auto;
    padding: 2px 5px 2px 2px; scrollbar-width: thin; }
  #quick-dock button { position: relative; flex: none; width: 44px; height: 44px; padding: 0;
    border-radius: 50%; border: 1.5px solid var(--lbl-border); background: var(--glass); color: var(--ink);
    box-shadow: 0 4px 14px rgba(0, 0, 0, .2); font-size: 19px; line-height: 1; }
  #quick-dock button.is-open { border-color: var(--even); background: var(--warning-surface); box-shadow: 0 0 0 2px var(--surface-raised), 0 0 0 4px var(--even); }
  #quick-dock .quick-badge { position: absolute; right: 1px; top: 1px; min-width: 17px; padding: 2px 3px;
    border-radius: 10px; border: 1px solid var(--bad); background: var(--btn-danger-bg); color: var(--bad);
    font: 700 12px/1 var(--font-body); }
  .sheet-open #quick-dock { visibility: hidden; }
  body:has(#nav:not([hidden])) #nav, body:has(#pick:not([hidden])) #pick { left: calc(var(--edge-left) + 56px); }
  body:has(.action-card) #quick-dock { visibility: hidden; }
  body:has(#nav:not([hidden])) #quick-dock, body:has(#nav:not([hidden])) #dock-more { visibility: hidden; }
  #quest-tracker, #alerts, #announce, #online-list {
    top: auto; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 64px);
    left: calc(var(--edge-left) + 56px); right: var(--edge-right); width: auto; max-width: none;
    max-height: min(54dvh, calc(var(--visible-h, 100dvh) - var(--top-h) - var(--bar-h) - 88px));
    overflow-y: auto; transform: none; }
  #quest-tracker:not(.quick-open), #alerts:not(.quick-open), #announce:not(.quick-open), #online-list:not(.quick-open), #dock-more:not(.quick-open) {
    visibility: hidden; pointer-events: none; }
  #alerts.has-urgent:not(.quick-open) {
    visibility: visible; pointer-events: auto; top: calc(max(8px, env(safe-area-inset-top)) + var(--top-h) + var(--announce-h) + var(--online-h) + 8px);
    bottom: auto; left: auto; right: var(--edge-right); width: min(260px, 65vw);
    max-height: min(24dvh, calc(var(--visible-h, 100dvh) - var(--top-h) - 24px)); }
  #alerts.has-urgent:not(.quick-open) .alert:not(.urgent) { display: none; }
  #alerts { align-items: stretch; }
  #announce .announce-card { max-height: inherit; overflow-y: auto; }
  .sheet-open #quest-tracker, .sheet-open #alerts, .sheet-open #announce, .sheet-open #online-list, .sheet-open #dock-more,
  body:has(.action-card) #quest-tracker, body:has(.action-card) #alerts, body:has(.action-card) #announce, body:has(.action-card) #dock-more,
  body:has(.action-card) #online-list { visibility: hidden; }
  .sheet-open #alerts.has-urgent:not(.quick-open),
  body:has(.action-card) #alerts.has-urgent:not(.quick-open) { visibility: visible; pointer-events: auto; }
  body:has(#quick-dock .is-open) #toasts { top: calc(max(6px, env(safe-area-inset-top)) + var(--top-h) + 8px); bottom: auto; }
}
@media (max-height: 500px) and (max-width: 1100px) {
  #dock-more { bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 70px); left: var(--edge-left); max-height: calc(var(--visible-h, 100dvh) - var(--top-h) - var(--bar-h) - 134px); }
  #quick-dock { flex-direction: row; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 10px);
    max-height: 52px; max-width: calc(100vw - var(--edge-left) - var(--edge-right)); overflow-x: auto; }
  #quest-tracker, #alerts, #announce, #online-list {
    bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 120px);
    left: var(--edge-left); max-height: calc(var(--visible-h, 100dvh) - var(--top-h) - var(--bar-h) - 134px); }
}
/* "?" beside the title: opens the help centre on this window's card. 44px like the close button; with 💬 (phones) the pair sits together on the right. */
#panel .win-help { flex: 0 0 var(--touch-target); width: var(--touch-target); height: var(--touch-target); min-height: 0; margin-left: auto; padding: 0; border: 0; border-radius: 50%;
  box-shadow: none; background: var(--surface-inset); color: var(--ink); font: 700 20px/1 var(--font-body); }
#panel .win-help ~ .win-chat { margin-left: 0; }
/* the panel's 💬 on every screen size (desktop: the compact chat steps aside while a window is open, community.css) */
.win-chat { display: block; margin-left: auto; border: 0; border-radius: 8px; background: var(--btn-beige); }
/* same 44px square, surface and no bevel as the close button beside it (header action row stays aligned) */
#panel .win-chat { flex: 0 0 var(--touch-target); width: var(--touch-target); height: var(--touch-target); min-height: 0; padding: 0; border: 0; box-shadow: none; background: var(--surface-inset); line-height: 1; }
@media (max-width: 760px), (pointer: coarse) and (max-width: 1100px), (max-height: 500px) and (max-width: 1100px) {
  #panel .win-head { padding-top: 2px; padding-bottom: 2px; }
}
}

/* During the mobile tutorial the dock keeps the same layout as after it (no "Diğer" fold); only the guide-next emphasis differs. */
@media (max-width: 760px), (pointer: coarse) and (max-width: 1100px), (max-height: 500px) and (max-width: 1100px) {
  #bar.mobile-guide .bar-btn:not(.guide-next):not(.on) { filter: saturate(.6); box-shadow: 0 2px 5px #0004; }
  #bar.mobile-guide .bar-btn.guide-next { outline: 3px solid var(--even); outline-offset: 2px; transform: translateY(-4px); box-shadow: 0 0 0 5px var(--decoration-glow), 0 5px 14px #0006; }
  body:has(#bar.mobile-guide) #online-list,
  body:has(#bar.mobile-guide) #quick-dock [data-quick="online"] { display: none; }
}
.away-card { max-height: calc(var(--visible-h, 100dvh) - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
@media (pointer: coarse), (max-width: 760px) {
  /* "Sen yokken" stays above the bottom bar: the overlay leaves the bar strip free and the card's height budget loses it (same budget as mobile-sheet.css) */
  #away { padding-bottom: calc(var(--bar-h) + env(safe-area-inset-bottom, 0px)); }
  .away-card { max-height: calc(var(--visible-h, 100dvh) - var(--bar-h) - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
  .chip[title], .badge-pin[title] { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }
  #nav .row2, .action-card .row2 { position: sticky; bottom: -8px; padding-block: 4px; background: var(--glass); }
}

/* Shared component contracts. Feature files contain domain layout, never a second skin. */
:where(button, input, select, textarea, summary, [role=button]) { font-family: var(--font-body); }
#panel :is(button, input, select, summary, [role=button]), :where(dialog, #auth, #pick, #intro, #away, #touch-info) :is(button, input, select, summary, [role=button]) { min-height: var(--touch-target); min-width: var(--touch-target); }
body :is(button, summary, a, input, select, textarea, [tabindex]):focus-visible {
  outline: 3px solid var(--focus); outline-offset: 2px;
}
body button { transition: background var(--duration-fast), box-shadow var(--duration-fast); }
body button:active:not(:disabled) { filter: brightness(.94); }
#panel button, dialog button, .ui-button, #nav button, #quest-tracker .ui-quest button {
  border: 3px double var(--border); border-image: none; border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3); background: var(--btn-beige); color: var(--ink);
  font: 600 var(--text-sm)/1.4 var(--font-body); white-space: normal; overflow-wrap: anywhere;
  box-shadow: var(--shadow-sm); cursor: var(--cursor-pointer, pointer);
}
@media (hover: hover) { #panel button:hover:enabled:not(.on):not([aria-pressed=true]), dialog button:hover:enabled { background: var(--surface-selected); } }
/* Secondary: every non-recommended action, choice option and row action. One primary per view
   is marked with .primary (or .is-next for the recommended next step). */
#panel :is(.seg button, .ui-choice button, .ghost, .secondary), #panel :where(.row) button:not(.primary, .is-next, .danger), .ui-button.secondary, #nav :is(.secondary, .seg button), #layers-panel .seg button, dialog .secondary {
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); box-shadow: none;
}
#panel :is(.seg button, .ui-choice button):is(.on, [aria-pressed=true]), #nav .seg button:is(.on, [aria-pressed=true]), #layers-panel .seg button:is(.on, [aria-pressed=true]), #panel .ui-choice button[aria-pressed=true] {
  background: var(--surface-selected); border-color: var(--even); box-shadow: inset 0 0 0 1px var(--even); color: var(--ink);
}
#panel :is(button.is-next, .primary.is-next) { box-shadow: 0 0 0 3px var(--decoration-glow), var(--shadow-sm); }
#panel button.danger, .ui-button.danger, #nav button.danger, dialog button.danger { color: var(--bad); background: var(--btn-danger-bg); border: 1px solid var(--bad); box-shadow: none; }
#panel button:disabled, dialog button:disabled, #panel button.unaffordable, #nav button:disabled {
  opacity: 1; color: var(--muted); background: var(--surface-disabled); border-color: var(--border-soft);
  box-shadow: none; cursor: not-allowed; filter: none;
}
#panel button small { color: inherit; font-size: var(--text-xs); }
#panel .panel-close { width: var(--touch-target); height: var(--touch-target); padding: 0; border: 0; box-shadow: none; background: var(--surface-inset); }
#panel .win-head { min-height: 56px; padding: var(--space-2) 56px var(--space-2) var(--space-4); font-size: var(--text-lg); }
#panel .body { padding: var(--space-panel); scrollbar-gutter: stable; }
#panel { width: min(560px, calc(100vw - 32px)); max-height: min(70dvh, 760px, calc(var(--visible-h, 100dvh) - var(--top-h) - var(--bar-h) - 28px)); box-shadow: var(--shadow-panel); }
.ui-badge { display: inline-block; padding: 0 var(--space-1); border-radius: var(--radius-sm); background: var(--surface-inset); border: 1px solid var(--border-soft); color: var(--ink); font-size: var(--text-xs); font-weight: 700; line-height: 1.5; font-variant-numeric: tabular-nums; white-space: nowrap; }
#panel :where(.row, .research-summary, .research-queue, .research-node, .ledger-card, .difficulty-card, .artifact-card, .museum-dig, .museum-goods, .museum-recent, .artifact-profile, .hint-card), .ui-card {
  background: var(--surface); border: 1px solid var(--border-soft); border-radius: var(--radius-md);
  padding: var(--space-3); margin-block: var(--space-2); color: var(--ink);
}
#panel .row { gap: var(--space-2); flex-wrap: wrap; }
#panel .row .grow { min-width: 0; flex: 1 1 130px; }
#panel .row .col2 { max-width: 100%; }
#panel .row .ico { flex: 0 0 auto; }
#panel :is(.research-summary, .research-queue, .difficulty-card, .museum-dig) { background: var(--surface-inset); }
#panel .row.sel { background: var(--surface); border-color: var(--even); border-left: 3px solid var(--even); }
#panel :is(h3, h4) { font-family: var(--font-display); line-height: 1.4; }
#panel h3 { font-size: var(--text-lg); }
#panel h3 { color: var(--ink); margin: var(--space-2) 0; }
#panel h4 { font-size: var(--text-sm); margin: var(--space-4) 0 var(--space-2); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
#panel h4 small { text-transform: none; letter-spacing: 0; font-family: var(--font-body); }
#panel h5 { font: 700 var(--text-md)/1.35 var(--font-body); color: var(--ink); }
#panel :is(p, small, .hint, .empty) { line-height: 1.55; }
#panel .empty, .ui-empty, .ui-empty-state { padding: var(--space-4); border: 1px dashed var(--border); border-radius: var(--radius-md); background: var(--surface); color: var(--muted); text-align: center; font-size: var(--text-sm); }
#panel :is(input, select) { max-width: 100%; font-size: max(16px, 1rem); }
.ui-progress { display: block; min-width: 0; margin-block: var(--space-2); font-variant-numeric: tabular-nums; }
.ui-progress-label { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-1) var(--space-2); font-size: var(--text-xs); color: var(--muted); }
.ui-progress-track, #panel progress, .weekly-ledger progress, .era-progress {
  display: block; appearance: none; width: 100%; height: var(--progress-height); border: 0;
  border-radius: var(--radius-pill); overflow: hidden; background: var(--border-soft); margin-block: var(--space-1);
}
.ui-progress-fill { display: block; height: 100%; background: var(--good); border-radius: inherit; transition: width var(--duration-normal) linear; }
progress::-webkit-progress-bar { background: var(--border-soft); }
progress::-webkit-progress-value { background: var(--good); border-radius: var(--radius-pill); }
progress::-moz-progress-bar { background: var(--good); border-radius: var(--radius-pill); }
/* One dialog skin: native event, era ceremony and every future <dialog>. */
dialog.village-event-dialog, dialog.era-ceremony { background: var(--surface); color: var(--ink); border: 2px solid var(--border); border-radius: var(--radius-xl); box-shadow: var(--shadow-modal); z-index: var(--z-modal); }
dialog::backdrop { background: #241d16a6; backdrop-filter: blur(3px); }
#account-delete-dialog, #chat-report-dialog { width: min(420px, calc(100vw - 24px)); padding: 22px; background: var(--surface); color: var(--ink);
  border: 2px solid var(--border); border-radius: var(--radius-xl); box-shadow: var(--shadow-modal); }
#account-delete-dialog h2, #chat-report-dialog h2 { margin: 0 0 12px; font-family: var(--font-display); }
#account-delete-dialog p, #chat-report-dialog p { line-height: 1.5; }
#account-delete-dialog label, #chat-report-dialog label { display: block; margin: 16px 0; font-weight: 600; }
#account-delete-dialog input, #chat-report-dialog select { display: block; width: 100%; margin-top: 6px; padding: 10px;
  border: 1px solid var(--border); border-radius: var(--radius-md); font: inherit; }
#account-delete-dialog .row, #chat-report-dialog .row { display: flex; gap: 8px; }
#account-delete-dialog .row button, #chat-report-dialog .row button { flex: 1; margin: 0; }
.village-event-dialog .village-event-close { padding: 0; box-shadow: none; background: var(--surface-inset); }
.toast, #touch-info, #status-pop, #online-list { background-color: var(--surface); box-shadow: var(--shadow-panel); border-radius: var(--radius-lg); }
#chat { width: min(380px, calc(100vw - 24px)); }
#attrib a { display: inline-flex; align-items: center; min-height: 20px; }
#panel:not([hidden]), #chat:not([hidden]), #ranking-panel:not([hidden]) { animation: panel-enter var(--duration-normal) var(--ease-out); }
@keyframes panel-enter { from { opacity: 0; translate: 0 8px; } }
@keyframes resource-gain { 50% { color: var(--good); scale: 1.1; } }
.resource-gain { display: inline-block; animation: resource-gain var(--duration-slow) var(--ease-out); }
/* Sheets always clear the measured HUD; short screens keep scrolling within the body. */
@media (max-width: 760px), (pointer: coarse) and (max-width: 1100px), (max-height: 500px) and (max-width: 1100px) {
  #panel, #panel.research-wide, #panel.artifacts-wide, #chat, #ranking-panel { width: auto; max-width: 640px;
    max-height: min(72dvh, 700px, calc(var(--visible-h, 100dvh) - var(--top-h) - var(--bar-h) - 18px - env(safe-area-inset-top) - env(safe-area-inset-bottom))); }
  .sheet-open #quest-tracker, .sheet-open #alerts { visibility: hidden; }
  #panel .body { padding: var(--space-2); }
  #panel .win-head { min-height: 52px; }
  .keyboard-open #panel, .keyboard-open #chat, .keyboard-open #ranking-panel { max-height: calc(var(--visible-h, 100dvh) - 16px); }
}
/* Phones/tablets: backdrop-filter over the live WebGL canvas is re-blurred every frame (fps-probe TRACE=1, mobile: GPU swap time
   ~88 -> ~9 ms/s with it off); the 0.92 glass already hid the map, so use a near-solid fill of the same tone. Desktop keeps the blur. */
@media (max-width: 760px), (pointer: coarse) and (max-width: 1100px), (max-height: 500px) and (max-width: 1100px) {
  .glass, #top, #panel, #chat, #ranking-panel, .toast, #status, #nav, .action-card { backdrop-filter: none; -webkit-backdrop-filter: none; }
  #top, #panel, #chat, #ranking-panel, #nav, .action-card { background: var(--glass-solid); }
}
@media (max-width: 360px) {
  #top .chip small { font-size: 12px; }
}
/* 320 px: seven bar buttons at 4 px gaps left 40 px cells and 'Ekonomi'/'Economy' clipped; 2 px gaps and no side padding give 44 px cells. */
@media (max-width: 340px) {
  #bar { gap: 2px; padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }
  .bar-btn { padding: 0; }
  .bar-btn .lbl { padding: 1px 0; letter-spacing: -0.04em; }
}
@media (max-height: 500px) {
  #panel .body { scroll-padding-block: var(--space-2); }
  #panel .row { padding: var(--space-2); }
}
/* Passive status text must never intercept map or attribution links. */
.toast:not(.toast-more), #status, #loading { pointer-events: none; }
.toast button, .toast-more { pointer-events: auto; }
/* Wide research retains its desktop width; presence stays in the HUD lane above it. */
@media (min-width: 761px) and (pointer: fine) and (min-height: 501px) {
  #top .chip { white-space: normal; }
  #panel { max-width: calc(100vw - 32px); }
  #panel.research-wide, #panel.market-wide { width: min(940px, calc(100vw - 32px)); max-height: min(70dvh, 760px, calc(var(--visible-h, 100dvh) - var(--top-h) - var(--bar-h) - 80px)); }
  #panel.market-wide { width: min(1040px, calc(100vw - 32px)); }
}
/* Every dialog uses the same readable text and backdrop, including native event sheets. */
#intro .panel-close { width: var(--touch-target); height: var(--touch-target); }
/* A compact visual checkbox inside a 44px keyboard/touch control. */
#panel input[type=checkbox] {
  appearance: none; display: grid; place-items: center; margin: 0; cursor: var(--cursor-pointer, pointer);
  background: transparent; border: 0; border-radius: var(--radius-md);
}
#panel input[type=checkbox]::before {
  content: ''; width: 22px; height: 22px; border: 2px solid var(--border);
  border-radius: var(--radius-sm); background: var(--surface);
}
#panel input[type=checkbox]:checked::before {
  content: '✓'; display: grid; place-items: center; color: var(--ink);
  background: var(--surface-selected); font-weight: 700;
}
/* Badges belong to their action's bounds; empty dock space does not cover map credits. */
#bar { pointer-events: none; }
#bar .bar-btn { pointer-events: auto; }
#bar .bar-overflow, #bar .bar-overflow button { pointer-events: auto; }
body:has(#bar-overflow:not([hidden])) #bar { z-index: var(--z-bar-menu); }
#bar .bar-btn .badge { top: 0; right: 0; max-width: 100%; }
/* A resized visual viewport also occurs on large touch screens. */
.keyboard-open :is(#chat, #ranking-panel) {
  bottom: calc(var(--keyboard-inset, 0px) + env(safe-area-inset-bottom));
  max-height: calc(var(--visible-h, 100dvh) - 16px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
}
.keyboard-open #panel {
  bottom: calc(var(--keyboard-inset, 0px) + env(safe-area-inset-bottom));
  max-height: calc(var(--visible-h, 100dvh) - var(--top-h) - 24px - env(safe-area-inset-top));
}
.keyboard-open #bar { visibility: hidden; }
dialog.village-event-dialog, dialog.era-ceremony {
  inset-inline: env(safe-area-inset-left) env(safe-area-inset-right);
  max-width: calc(100vw - 24px - env(safe-area-inset-left) - env(safe-area-inset-right));
  max-height: calc(var(--visible-h, 100dvh) - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
}
/* An action in flight (public/act-gate.js): the pressed button stays disabled and shows a small spinner until the server answers. */
button[aria-busy="true"] { cursor: progress; }
button[aria-busy="true"]::before {
  content: ''; display: inline-block; width: .8em; height: .8em; margin-inline-end: .35em; vertical-align: -.1em;
  border: 2px solid currentColor; border-top-color: transparent; border-radius: 50%; animation: spin var(--duration-slow) linear infinite;
}
#panel[aria-busy=true] .win-head::after {
  content: ''; flex: 0 0 14px; height: 14px; border: 2px solid var(--border-soft);
  border-top-color: var(--good); border-radius: 50%; animation: spin var(--duration-slow) linear infinite;
}
@media (max-height: 500px) {
  .keyboard-open #panel { max-height: calc(var(--visible-h, 100dvh) - 16px); }
  .keyboard-open #top { visibility: hidden; }
}
@media (max-height: 500px) {
  #panel .win-head { min-height: 52px; } /* 44px close target plus its top inset */
}

/* Shared forms/actions for panels and map sheets. */
.ui-form { display: grid; gap: var(--space-2); margin-block: var(--space-3); }
.ui-form label { display: grid; min-width: 0; gap: var(--space-1); }
.ui-form :is(input, select) { width: 100%; min-width: 0; max-width: 100%; min-height: var(--touch-target); font: inherit; color: var(--ink); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: var(--space-2); }
.ui-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.ui-actions > * { flex: 1 1 120px; }
.ui-button { min-height: var(--touch-target); min-width: var(--touch-target); white-space: normal; }
.ui-card { min-width: 0; overflow-wrap: anywhere; }
.ui-card summary { min-height: var(--touch-target); padding-block: var(--space-3); cursor: var(--cursor-pointer, pointer); font-weight: 700; }
/* Expanded sheet forms must not scroll underneath the footer controls. */
#nav:has(details[open]) .row2 { position: static; }

/* ---------------------------------------------------------------------------------------------
   Tab consistency pass (ux/tab-consistency). One tab strip, one section header, one cost row,
   one status badge vocabulary and one empty/locked state for every window and nested view.
   --------------------------------------------------------------------------------------------- */
#panel .body { container: panel-body / inline-size; }
/* Tabs never scroll sideways and never leave a lone orphan row: an even grid from --tab-count. */
.ui-tabs {
  --tab-cols: var(--tab-count, 3);
  display: grid; grid-template-columns: repeat(var(--tab-cols), minmax(0, 1fr)); gap: var(--space-1);
  margin: 0 0 var(--space-4); padding: var(--space-1);
  background: var(--surface-inset); border: 1px solid var(--border-soft); border-radius: var(--radius-md);
}
.ui-tabs[data-count="6"] { --tab-cols: 3; }
/* Seven Kayıtlar tabs: 4 + 3, with no orphaned last tab on a phone. */
.ui-tabs[data-count="7"] { --tab-cols: 12; }
.ui-tabs[data-count="7"] > .ui-tab { grid-column: span 3; }
.ui-tabs[data-count="7"] > .ui-tab:nth-child(n+5) { grid-column: span 4; }
@container panel-body (max-width: 320px) {
  .ui-tabs[data-count="7"] { --tab-cols: 6; }
  .ui-tabs[data-count="7"] > .ui-tab { grid-column: span 2; }
  .ui-tabs[data-count="7"] > .ui-tab:nth-child(n+4) { grid-column: span 3; }
}
/* Five tabs on a narrow window: 3 + 2 on a six-column grid, so both rows are full (no empty cell). */
.ui-tabs[data-count="5"] { --tab-cols: 6; }
.ui-tabs[data-count="5"] > .ui-tab { grid-column: span 2; }
.ui-tabs[data-count="5"] > .ui-tab:nth-child(n+4) { grid-column: span 3; }
/* Nine Kayıtlar tabs: 5 + 4 on a 20-column grid (no cramped single row), 3 x 3 when very narrow, one row when wide. */
.ui-tabs[data-count="9"] { --tab-cols: 20; }
.ui-tabs[data-count="9"] > .ui-tab { grid-column: span 4; }
.ui-tabs[data-count="9"] > .ui-tab:nth-child(n+6) { grid-column: span 5; }
@container panel-body (max-width: 360px) { .ui-tabs[data-count="9"] { --tab-cols: 3; } .ui-tabs[data-count="9"] > .ui-tab:nth-child(n) { grid-column: auto; } }
@container panel-body (min-width: 820px) { .ui-tabs[data-count="9"] { --tab-cols: 9; } .ui-tabs[data-count="9"] > .ui-tab:nth-child(n) { grid-column: auto; } }
@container panel-body (max-width: 299px) { .ui-tabs[data-count="4"] { --tab-cols: 2; } }
@container panel-body (min-width: 460px) { .ui-tabs[data-count="5"] { --tab-cols: 5; } .ui-tabs[data-count="5"] > .ui-tab:nth-child(n) { grid-column: auto; } }
@container panel-body (min-width: 720px) { .ui-tabs[data-count="6"] { --tab-cols: 6; } }
@container panel-body (min-width: 720px) { .ui-tabs[data-count="7"] { --tab-cols: 7; } .ui-tabs[data-count="7"] > .ui-tab:nth-child(n) { grid-column: auto; } }
#panel .ui-tabs .ui-tab {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-width: 0; min-height: 66px; margin: 0; padding: var(--space-1) var(--space-1);
  border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent; box-shadow: none;
  color: var(--muted); font: 600 var(--text-xs)/1.15 var(--font-body); text-align: center;
  white-space: normal; overflow-wrap: normal; hyphens: none;
}
.ui-tab-icon { font-size: 20px; line-height: 1; }
.ui-tab-label { max-width: 100%; }
/* 5+ tabs (Sefer, Bey, Kayıtlar, Mağaza...): ONE row that scrolls sideways instead of wrapping into 2-3 rows, so the window body keeps its height.
   Tabs share the width while they fit and keep a 76px minimum when they do not; edge fades (background-attachment trick) show there is more. */
.ui-tabs.ui-tabs--scroll {
  display: flex; flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scrollbar-width: none;
  background:
    linear-gradient(to right, var(--surface-inset) 30%, transparent) left center / 22px 100% no-repeat local,
    linear-gradient(to left, var(--surface-inset) 30%, transparent) right center / 22px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, #3b2a1a44, transparent) left center / 9px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, #3b2a1a44, transparent) right center / 9px 100% no-repeat scroll,
    var(--surface-inset);
}
.ui-tabs.ui-tabs--scroll::-webkit-scrollbar { display: none; }
#panel .ui-tabs.ui-tabs--scroll .ui-tab { flex: 1 0 auto; min-width: 76px; min-height: 56px; padding-inline: var(--space-2); white-space: nowrap; scroll-snap-align: center; }
/* Sefer sub-tabs (Ordu / Kamplar / Oyuncular / Seferler / Geçmiş): all five on ONE row at every width, icon over a short label, no sideways scroll (consensus S1; ui-modern-a.css repeats it for the grid theme). */
#panel .ui-tabs:has(> [data-act="sef-sub"]) { display: flex; flex-wrap: nowrap; overflow: hidden; gap: 2px; padding: 3px; }
#panel .ui-tabs:has(> [data-act="sef-sub"]) > .ui-tab { flex: 1 1 0; min-width: 0; min-height: 0; padding: 5px 2px; white-space: normal; }
#panel .ui-tabs:has(> [data-act="sef-sub"]) .ui-tab-label { font-size: 12px; line-height: 1.1; text-align: center; overflow-wrap: anywhere; } /* a long caption ("Armee / Überfall") wraps to 2 lines instead of truncating */
@container panel-body (max-width: 480px) {
  #panel .ui-tabs:has(> [data-act="sef-sub"]) .ui-tab-label { font-size: 10.5px; }
  #panel .ui-tabs:has(> [data-act="sef-sub"]) .ui-tab-icon { font-size: 15px; }
}
.nw { white-space: nowrap; } /* a number and its unit ("174 m", "Sv 2") never split across lines */
@media (hover: hover) { #panel .ui-tabs .ui-tab:hover:enabled:not(.on) { background: transparent; } }
@media (hover: hover) { #panel .ui-tabs .ui-tab:hover:enabled:not(.on) { background: var(--surface); color: var(--ink); } }
#panel .ui-tabs .ui-tab.on {
  background: var(--surface-raised); border-color: var(--border); color: var(--ink);
  box-shadow: inset 0 -3px var(--even), var(--shadow-sm);
}
.ui-tab-badge {
  position: absolute; top: 2px; right: 2px; min-width: 20px; padding: 0 5px;
  border: 1px solid var(--border); border-radius: var(--radius-pill); background: var(--warning-surface);
  color: var(--ink); font: 700 12px/16px var(--font-body); font-variant-numeric: tabular-nums;
}
#panel .ui-tabs .ui-tab.is-locked:not(.on) { color: var(--muted); background: transparent; }
.ui-tab.is-locked .ui-tab-icon { font-size: 16px; }
.ui-tab.is-next::before {
  content: ''; position: absolute; top: 6px; left: 6px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--even); box-shadow: 0 0 0 2px var(--surface-raised);
}
/* The tab dot's glow ring is the tab's ::after (ui-modern-a.css), pulsing opacity only. next-pulse (box-shadow) is left for the Görevler dock button below. */
@keyframes next-pulse { 50% { box-shadow: 0 0 0 5px var(--decoration-glow); } }
@keyframes next-ring { 50% { opacity: 1; } }

/* Choice groups (amount, resource, formation, graphics…): radio-like options, not navigation. */
#panel :is(.seg, .ui-choice), #nav .seg, #layers-panel .seg { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: var(--space-2) 0 var(--space-3); padding: 0; font-size: var(--text-sm); color: var(--muted); }
#panel :is(.seg, .ui-choice) button, #nav .seg button, #layers-panel .seg button { flex: 1 1 auto; }
#panel .seg > span { flex: 1 0 100%; margin: 0; text-align: right; }

/* Section header: title, one-line explanation, optional right action. */
.ui-section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-2); margin: var(--space-4) 0 var(--space-2); }
.ui-section-head > div { flex: 1; min-width: 0; }
.ui-term:last-child { margin-right: 0; }
#panel .ui-section-head h4 { margin: 0; }
.ui-section-head p { margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--text); line-height: 1.5; }
.ui-section-head > button { flex: 0 0 auto; }
.site-group { margin: var(--space-3) 0 var(--space-1); font-size: var(--text-sm); color: var(--ink); }
.site-group small { color: var(--text); font-weight: normal; }
/* Ekonomi window (public/tabs/economy-tabs.js): hourly summary strip, storehouse line, free slots, auto-assign toggle, one-line site rows. */
.eco-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin: 4px 0 6px; }
.eco-cell { display: flex; flex-direction: column; min-width: 0; background: var(--surface-inset); border-radius: var(--radius-md); }
#panel .eco-cell > button { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; width: 100%; min-width: 0; min-height: 44px; padding: 6px 8px; border: 0; background: transparent; text-align: left; white-space: nowrap; }
.eco-cell b { font-size: .85rem; }
.eco-cell .u { font-size: .75rem; color: var(--muted); line-height: 1.2; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.eco-cell.is-neg b { color: var(--bad); }
#panel .eco-cell > button.eco-link { min-height: 0; padding: 0 8px 6px; color: var(--focus); font-weight: 700; font-size: .75rem; text-decoration: underline; white-space: normal; }
#panel .eco-cell.is-zero > button:first-child { min-height: 0; padding-bottom: 0; }
/* Takas offer card on phones: the sticky bottom card is one row (offer left, "Takas et" right) and drops the static explanation, so the pickers
   above it stay visible (a blocked reason is not the static note and still shows). Stronger than trade.css's `.trade-quote button { width: 100% }`. */
@media (max-width: 760px), (pointer: coarse) and (max-width: 1100px) {
  html #panel .body .row.trade-quote-takas { flex-wrap: nowrap; align-items: center; }
  html #panel .body .row.trade-quote-takas .grow { flex: 1 1 0; min-width: 0; }
  html #panel .body .row.trade-quote-takas > button { width: auto; flex: 0 0 auto; }
  html #panel .body .row.trade-quote-takas .trade-quote-note { display: none; }
}
/* Narrow panels (360 px phones, long DE/FR labels): 2x2 so "Nahrung / Std." and "Steinbruch bauen" fit; the cells of a row share one height. */
@container panel-body (max-width: 340px) { .eco-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.eco-depo { margin: 0 0 8px; color: var(--muted); font-size: var(--text-sm); overflow-wrap: anywhere; }
.eco-area, .eco-auto { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin: 0 0 8px; }
.eco-area b, .eco-auto span { flex: 1 1 55%; min-width: 0; font-size: var(--text-sm); }
.eco-area button, .eco-auto button { flex: 0 0 auto; }
.eco-auto button.on { font-weight: 700; }
.site-row { position: relative; flex-wrap: nowrap; }
.site-row .grow { min-width: 0; } /* one line when it fits; a long name (DE) wraps the meta under it instead of cutting the output */
.site-row .grow b, .site-row .grow small { display: inline; }
.site-row .grow small.site-extra { display: block; white-space: normal; }
.site-row .site-name-short { display: none; }
.site-row .site-fill { flex: 0 0 auto; }
#panel .site-row button.site-x { position: absolute; top: -9px; right: -6px; width: 26px; min-width: 0; height: 26px; min-height: 0; padding: 0; font-size: .75rem; line-height: 1; background: var(--surface-inset); }
#panel .site-row button.site-x.is-armed { width: auto; padding: 0 8px; border-color: var(--bad); font-weight: 700; z-index: 1; }
@media (max-width: 720px) {
  .site-row { gap: 6px; padding: 6px 8px; font-size: .8rem; }
  .site-row .site-name-full { display: none; }
  .site-row .site-name-short { display: inline; }
  .site-row .grow b { font-size: .8rem; }
  .site-row .grow small { font-size: .72rem; }
  .site-row .stepper { flex: none; gap: 3px; }
  .site-row .stepper button { width: 36px; flex: 0 0 36px; }
  .site-row .stepper b { min-width: 0; }
  .site-row .site-fill { margin-left: auto; }
}
.ui-term {
  display: inline-grid; place-items: center; vertical-align: middle; margin: -8px 0 -8px -6px;
  padding: 0; border: 0 !important; background: transparent !important; box-shadow: none !important;
  color: var(--focus) !important; font: 700 16px/1 var(--font-body) !important; letter-spacing: 0; text-transform: none;
}
#panel .ui-term, #nav .ui-term, dialog .ui-term { min-width: 44px; min-height: 44px; }

/* Cost row: icon + tr-TR number; unaffordable items are coloured and spelled out for readers. */
.ui-cost { display: inline-flex; flex-wrap: wrap; justify-content: center; gap: 2px var(--space-2); font-variant-numeric: tabular-nums; }
.ui-cost-item { display: inline-flex; align-items: center; gap: 2px; white-space: nowrap; }
.ui-cost-item.is-short { color: var(--bad); font-weight: 700; text-decoration: underline dotted; text-underline-offset: 3px; }
#panel .ui-shortfall { display: block; flex: 1 0 100%; margin: 0; color: var(--bad); font-size: var(--text-sm); font-weight: 600; }

/* Status badges: one vocabulary for research, quests, achievements, buildings and diplomacy. */
.ui-badge--done { background: var(--success-surface); border-color: var(--good); color: var(--good); }
.ui-badge--active { background: var(--warning-surface); border-color: var(--even); }
.ui-badge--queued { background: var(--surface); border-color: var(--even); }
.ui-badge--open { background: var(--surface); border-color: var(--good); color: var(--good); }
.ui-badge--locked { background: var(--surface-disabled); color: var(--muted); }
.ui-badge--danger { background: var(--btn-danger-bg); border-color: var(--bad); color: var(--bad); }
.ui-badge--next { background: var(--surface-selected); border-color: var(--even); }
.row .grow > .ui-badge { margin-left: var(--space-1); vertical-align: 1px; }

/* Empty and locked states say what is missing, why and the one step that fixes it. */
.ui-empty-state { display: grid; justify-items: center; gap: var(--space-1); margin: var(--space-3) 0; padding: var(--space-4); }
.ui-empty-state b { color: var(--ink); font-size: var(--text-md); }
.ui-empty-state p { margin: 0; color: var(--text); line-height: 1.5; }
.ui-empty-icon { font-size: 30px; line-height: 1.2; }
.ui-empty-state button { margin-top: var(--space-2); min-width: min(100%, 220px); }

/* Recommended next step: one per view, next to the primary control. */
.ui-next-note { display: flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-3); padding: var(--space-2) var(--space-3);
  border: 1px solid var(--even); border-left-width: 4px; border-radius: var(--radius-md); background: var(--surface-raised); color: var(--ink); font-size: var(--text-sm); }
.ui-next-note b { font-weight: 700; }
#panel .row.is-next-row { border-color: var(--even); box-shadow: inset 3px 0 var(--even); }

/* City and visit cards use the same parchment card as every window. */
#nav { border: 1px solid var(--border); border-image: none; border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow-panel); padding: var(--space-3); color: var(--ink); }
#nav > b { font-family: var(--font-display); font-size: var(--text-lg); }
#nav button { min-height: var(--touch-target); }

/* Mobile body copy stays at or above 15 px inside windows, cards and dialogs. */
@media (max-width: 760px), (pointer: coarse) and (max-width: 1100px) {
  #panel, #nav, dialog, #intro, #away, .action-card, #touch-info { --text-xs: 14px; --text-sm: 15px; --text-md: 16px; }
  #panel .ui-quest-kicker { font-size: var(--text-sm); }
  #panel .ui-quest.kq .kq-kicker { font-size: var(--text-sm); } /* Görevler: "⭐ Günün görevi · 2× ödül · ⏳ …" is information, not a label: body size on a phone (base rule below stays 12 px for desktop) */
  #panel .row.kq-link .grow > small { font-size: var(--text-sm); } /* the Haftalık Defter link: "125 yol puanı · ⏳ 4 gün 7 sa" is information too */
  .intro-card p, .away-events, .action-card .desc, #touch-info p { font-size: 15px; }
  .action-card .choice small { font-size: 14px; }
  body:has(#nav:not([hidden])) #toasts { top: calc(max(8px, env(safe-area-inset-top)) + 56px); bottom: auto; }
}
#panel .wide, #nav .wide { display: block; width: 100%; margin-block: var(--space-2); }
.ui-more { margin-block: var(--space-2); }
.ui-more summary { color: var(--ink); font-size: var(--text-sm); }
.ui-more[open] summary { margin-bottom: var(--space-2); }
.lonca-tag-input { text-transform: uppercase; margin-top: var(--space-1); }
.pow small { display: block; font-size: var(--text-xs); font-weight: 600; }
#panel .row.is-done { background: var(--surface-inset); }
#panel .row .grow > b + em, #panel .row .grow > b + .ui-badge { margin-left: var(--space-1); }
.ui-next-note { flex-wrap: wrap; } /* narrow windows: the button drops under the text instead of squeezing it to one word per line */
.ui-next-note > span:nth-child(2) { flex: 1 1 11rem; min-width: 0; }
.ui-next-note button { flex: 0 0 auto; white-space: nowrap; overflow-wrap: normal; }
/* After the tutorial the note is a hint, not a card: one line (text clipped with an ellipsis) + the Git button, so it never pushes the window body down. */
.ui-next-note.is-compact { flex-wrap: nowrap; margin-bottom: var(--space-2); padding-block: var(--space-1); }
.ui-next-note.is-compact > span:nth-child(2) { flex: 1 1 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-next-note.is-compact button { min-height: 36px; }
.ui-list { margin: 0; padding-left: var(--space-4); font-size: var(--text-sm); color: var(--ink); }
.ui-list li { margin: var(--space-1) 0; }
#panel .row > button { flex: 0 0 auto; max-width: 100%; }
.row .war-acts { display: flex; flex-direction: column; gap: 4px; flex: 0 0 auto; max-width: 45%; } /* Sefer › Oyuncular: Haritada göster + Saldır, 360 px'te taşmasın */
.standing-card dl { margin: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px; font-size: var(--text-sm); }
.standing-card dt { font-weight: 700; margin-top: 6px; }
.standing-card dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }
.atk-filter { margin: 4px 0 8px; max-width: 100%; text-align: left; }
/* Sefer summary line (war-tabs.js summaryHtml): "⚔ 40 asker · 640 güç · 🛡 650 · 🧱 180" + the Akın clock link; the link turns into a red pill at 10 min or less. */
.war-sum { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 8px; margin: 4px 0 2px; padding: 3px 10px; border-radius: var(--radius-md); background: var(--surface); border: 1px solid var(--border-soft); font-size: var(--text-sm); line-height: 1.3; }
#panel .war-sum .war-sum-link { flex: 0 0 auto; width: auto; min-height: 0; padding: 0; line-height: 1.3; background: none; border: 0; box-shadow: none; color: var(--focus); font-size: var(--text-xs); white-space: nowrap; }
#panel .war-sum ~ .ui-choice { margin: 2px 0 0; flex-wrap: nowrap; gap: 4px; } /* one row at 360 px, also in DE ("Genug / 50% / Alle / Anzahl [ ]") */
#panel .war-sum ~ .ui-choice > button { flex: 1 1 0; min-width: 0; padding-inline: 4px; }
#panel .war-sum ~ .ui-choice > .send-count { flex: 0 0 auto; margin-left: 0; }
#panel .ui-tabs.section-nav:has(> [data-act="sef-sub"]) { margin: 0 0 2px; }
#panel .war-sum ~ .ui-choice :is(button, input) { min-height: 36px; } /* Kamplar first screen: every px above the camp rows counts on a 640 px phone */
#panel .war-sum ~ .ui-section-head + .row.camp-row { margin-top: 2px; }
#panel .war-sum ~ .ui-section-head { margin: 4px 0 0; }
#panel .war-sum ~ .ui-section-head h4 { margin: 0; } /* a generic #panel h4 top margin put 18px above "Komşu kamplar" */
#panel .war-sum .war-sum-link.urgent { padding: 2px 9px; border-radius: 99px; background: var(--btn-danger-bg); color: var(--bad); font-weight: 700; }
/* Kamplar rows: name + power/odds tag on line 1, decision numbers on a small line 2, Yağmala / Yak with their consequence as sub text. `.row` is a flex row and `#panel .row .col2` (above) forces
   flex rows: the selectors below carry .row.camp-row to stay heavier than those and than style.css's late button rules. */
#panel .row.camp-row { flex-wrap: wrap; gap: 6px 8px; padding: 6px 8px; }
#panel .row.camp-row .grow { flex: 1 1 0; min-width: 0; }
.camp-l1 { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.camp-tag { padding: 1px 7px; border: 1px solid currentColor; border-radius: 99px; font-size: 11px; white-space: nowrap; }
.camp-meta { display: block; margin-top: 2px; line-height: 1.35; font-size: 11.5px; }
#panel .row.camp-row .camp-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; flex: 0 0 250px; max-width: 100%; }
#panel .row.camp-row .camp-acts > button { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 42px; padding: 3px 4px; line-height: 1.15; font-size: 13px; white-space: nowrap; }
#panel .row.camp-row .camp-acts > button small { font-size: 10.5px; font-weight: 500; opacity: .8; }
#panel .row.camp-row .camp-acts > button.armed:enabled { background: #a32a1f; color: #fff; border-color: #d4574a; }
@media (max-width: 760px), (pointer: coarse) and (max-width: 1100px) {
  #panel .row.camp-row .camp-acts { flex: 1 0 100%; }
  #panel .row.camp-row .camp-acts > button { font-size: 12px; min-height: 44px; }
  #panel .row.camp-row .camp-acts > button small { font-size: 9.5px; }
  .camp-meta { font-size: 11px; }
}
/* Sefer › Oyuncular: the revenge row pinned on top and the "🎯 Pay %X · Bugün a/2 hak" appetite line under each player. */
#panel .row.camp-revenge { background: rgba(224, 130, 40, 0.16); border-color: rgba(224, 130, 40, 0.6); }
.revenge-title { color: var(--even); }
.appetite { display: block; font-size: 11px; }
.appetite.dim { opacity: .55; }
.empty-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 8px; }
#panel .row .col2 { flex-direction: row; flex-wrap: wrap; }
#panel .row .col2 > button { flex: 1 1 auto; }
#panel .body { font-size: var(--text-sm); color: var(--ink); }
#panel .row .grow > b, #panel .row label.grow > b { font-size: var(--text-md); }
/* The map coach bubble wraps instead of growing wider than a phone screen (it would be hidden). */
#labels .lbl.coach-bubble { white-space: normal; width: max-content; max-width: min(240px, 72vw); text-align: center; line-height: 1.35; }
.ui-res-icon { width: 18px; height: 18px; image-rendering: pixelated; vertical-align: -3px; flex: none; }

/* ---- Quest card (tracker + Görevler): parchment scroll, ornamental rule, wax seal ---- */
.ui-quest {
  position: relative; display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: var(--space-2) var(--space-3); align-items: start;
  margin-block: var(--space-2); padding: var(--space-3);
  background: linear-gradient(180deg, var(--surface-raised), var(--surface) 55%, var(--surface-inset));
  border: 1px solid var(--border); border-radius: var(--radius-md);
  box-shadow: inset 0 0 0 3px var(--surface-raised), inset 0 0 0 4px var(--border-soft), var(--shadow-sm);
  color: var(--ink);
}
.ui-quest-seal {
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, var(--surface-raised), var(--surface-selected));
  border: 2px solid var(--border); font-size: 22px; line-height: 1;
}
.ui-quest-seal img { image-rendering: pixelated; }
.ui-quest.is-ready { border-color: var(--even); box-shadow: inset 0 0 0 3px var(--surface-raised), inset 0 0 0 4px var(--even), 0 0 0 3px var(--decoration-glow), var(--shadow-sm); }
.ui-quest.is-ready .ui-quest-seal { background: radial-gradient(circle at 35% 30%, #b0503a, var(--alert-bad)); border-color: #5a1f15; box-shadow: 0 2px 0 #5a1f15; }
.ui-quest.is-done { background: var(--surface-inset); box-shadow: none; }
.ui-quest.is-done .ui-quest-seal { background: var(--success-surface); border-color: var(--good); }
.ui-quest-body { min-width: 0; }
.ui-quest-kicker { display: flex; align-items: center; gap: var(--space-2); margin: 0 0 2px; color: var(--muted); font: 700 var(--text-xs)/1.3 var(--font-display); letter-spacing: .08em; text-transform: uppercase; }
.ui-quest-kicker::after { content: '❖'; flex: 1; text-align: right; color: var(--border); letter-spacing: 0;
  background: linear-gradient(var(--border-soft), var(--border-soft)) left center / calc(100% - 1.4em) 1px no-repeat; }
#panel .ui-quest-title, .ui-quest-title { margin: 0; font: 700 var(--text-md)/1.35 var(--font-body); color: var(--ink); }
.ui-quest-desc { margin: 2px 0 0; font-size: var(--text-sm); line-height: 1.45; color: var(--text); }
.ui-quest-progress { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-2); }
.ui-quest-progress .ui-progress-track { flex: 1; height: 10px; margin: 0; background: var(--surface-disabled); box-shadow: inset 0 1px 2px #38281133; border: 1px solid var(--border-soft); }
.ui-quest-progress .ui-progress-fill { background: linear-gradient(180deg, #5d8c3a, var(--good)); }
.ui-quest-progress b { font-size: var(--text-sm); font-variant-numeric: tabular-nums; color: var(--ink); white-space: nowrap; }
.ui-quest-reward { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); margin: var(--space-2) 0 0; font-size: var(--text-sm); }
.ui-quest-reward:empty { display: none; }
.ui-quest-reward-label { color: var(--muted); font-weight: 600; }
.ui-quest-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ui-quest-actions > button { flex: 1 1 140px; }
.ui-quest-actions > button.primary { font-weight: 700; }
.ui-quest.is-compact { margin: 0; padding: var(--space-2) var(--space-3); grid-template-columns: 36px minmax(0, 1fr); }
.ui-quest.is-compact .ui-quest-seal { width: 36px; height: 36px; font-size: 18px; }
/* Kayıtlar › Görevler (2026-11-09): the compact login card is ONE row (seal, text, button) and every task a title + one meta line, so three tasks fit the first phone screen. */
#panel .ui-quest.is-compact { grid-template-columns: minmax(0, 1fr) auto; align-items: center; margin: var(--space-1) 0; padding: 6px 10px; }
#panel .ui-quest.is-compact .ui-quest-seal { display: none; } /* the card is already the ringed "ready" one; the seal only cost a column */
#panel .ui-quest.is-compact .ui-quest-actions { grid-column: auto; }
#panel .ui-quest.is-compact .ui-quest-actions > button { flex: none; min-height: 40px; padding: 2px 12px; }
#panel .ui-quest.is-compact .ui-quest-body { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--space-2); }
#panel .ui-quest.is-compact .ui-quest-kicker { margin: 0; font-size: var(--text-xs); }
#panel .ui-quest.is-compact .ui-quest-kicker::after { content: none; }
#panel .ui-quest.is-compact .ui-quest-title { font-size: 15px; line-height: 1.3; }
#panel .ui-quest.is-compact .ui-quest-reward { flex-basis: 100%; margin-top: 2px; }
#panel .ui-quest.is-compact .ui-quest-reward-label { display: none; }
#panel .ui-quest.is-compact .ui-quest-reward .ui-badge--next { display: none; }
#panel .ui-quest.kq { display: flex; flex-direction: column; align-items: stretch; gap: 2px; margin-block: 3px; padding: 5px 10px; }
#panel .ui-quest.kq .ui-quest-title { font: 700 14px/1.3 var(--font-body); }
#panel .kq-kicker { margin: 0; color: var(--ink); font: 700 12px/1.3 var(--font-body); }
#panel .kq-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 13px; }
#panel .kq-meta .ui-progress-track { flex: 0 0 44px; height: 8px; margin: 0; }
#panel .kq-meta b { color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
#panel .kq-meta .ui-cost-item { font-size: 13px; }
#panel .kq-sp { flex: 1 1 0; min-width: 0; }
#panel .kq-meta button { flex: none; min-height: 40px; padding: 2px 10px; font-size: 13px; white-space: nowrap; }
#panel .kq-meta button .ui-cost-item { font-size: 13px; }
#panel .row.kq-link { width: 100%; min-height: 44px; text-align: left; }
#panel .row.kq-link small { display: block; }
.ui-link { display: inline-flex; align-items: center; gap: 4px; min-height: 44px; padding: 0 var(--space-1); border: 0 !important; background: transparent !important; box-shadow: none !important;
  color: var(--focus) !important; font: 600 var(--text-sm)/1.2 var(--font-body) !important; text-decoration: underline; text-underline-offset: 3px; cursor: var(--cursor-pointer, pointer); }
#panel .stats .ui-stat { display: block; min-width: 0; margin: 0; padding: var(--space-2) var(--space-1); border: 1px solid var(--border-soft); border-radius: var(--radius-md);
  background: var(--surface-inset); box-shadow: none; text-align: center; color: var(--ink); cursor: var(--cursor, help); }
#panel .stats .ui-stat b { display: block; font-size: var(--text-lg); }
#panel .stats .ui-stat small { color: var(--muted); font-size: var(--text-xs); font-weight: 600; overflow-wrap: break-word; hyphens: manual; }
/* Four stat cards share two rows on phones: long German/French labels no longer break mid-word. */
@media (max-width: 480px) { #panel .stats:has(> :nth-child(4)) { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.ui-stat-info { position: relative; color: var(--focus); font-weight: 700; }
@media (pointer: coarse) { .ui-stat-info::after { content: ''; position: absolute; top: 50%; left: 50%; width: 44px; height: 44px; transform: translate(-50%, -50%); } }
#panel .stats .ui-stat small { text-wrap: balance; }

#top .brand small.ui-badge { margin-left: var(--space-1); font-family: var(--font-body); vertical-align: 2px; }
/* Very wide screens: the resource bar is a centred strip instead of chips crammed to the left. */
@media (min-width: 1680px) and (pointer: fine) {
  #top { left: 50%; right: auto; width: min(1560px, calc(100vw - 20px)); transform: translateX(-50%); }
  #top-info { justify-content: center; }
}

/* ---- Attention badge: one component for unread chat, idle villagers, raids, rewards, offers ---- */
.ui-count, #chat-toggle .ui-count {
  display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 5px; box-sizing: border-box;
  border: 1.5px solid var(--border); border-radius: var(--radius-pill); background: var(--warning-surface); color: var(--ink);
  font: 700 12px/1 var(--font-body); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.ui-count--alert, #chat-toggle .ui-count, .bar-btn .badge:not(.warn) { background: var(--btn-danger-bg); border-color: var(--bad); color: var(--bad); animation: count-pulse 1.8s var(--ease-out) infinite; }
#chat-toggle .ui-count { position: absolute; top: -6px; right: -6px; }
.ui-count--alert { position: relative; } /* the ring pseudo needs it; #chat-toggle .ui-count / .bar-btn .badge are already absolute and win */
/* The expanding ring is a pseudo-element (opacity + scale only, compositor); the badge itself only scales. 2026-11-06 */
.ui-count--alert::after, #chat-toggle .ui-count::after, .bar-btn .badge:not(.warn)::after {
  content: ''; position: absolute; inset: -2px; border-radius: inherit;
  box-shadow: 0 0 0 4px #8a3322; opacity: 0; animation: count-ring 1.8s var(--ease-out) infinite; }
@keyframes count-pulse { 50% { transform: scale(1.08); } }
@keyframes count-ring { 0%, 100% { opacity: .33; transform: scale(.92); } 50% { opacity: 0; transform: scale(1.3); } }
@media (prefers-reduced-motion: reduce) { .ui-count--alert, #chat-toggle .ui-count, .bar-btn .badge:not(.warn) { animation: none; box-shadow: 0 0 0 3px var(--decoration-glow); } }
/* Landscape phones: a single compact tab row keeps most of the short sheet for content. */
@media (max-height: 500px) and (max-width: 1100px) {
  #panel .ui-tabs .ui-tab { flex-direction: row; gap: var(--space-1); min-height: 46px; white-space: nowrap; }
  .ui-tab-icon { font-size: 16px; }
  .ui-tabs { margin-bottom: var(--space-2); }
  @container panel-body (min-width: 460px) { .ui-tabs[data-count="4"] { --tab-cols: 4; } .ui-tabs[data-count="5"], .ui-tabs[data-count="6"] { --tab-cols: var(--tab-count); } .ui-tabs[data-count="5"] > .ui-tab:nth-child(n) { grid-column: auto; } }
}
/* Bar badges stay compact (they share the attention colours and pulse above). */
.bar-btn .badge { border: 1.5px solid var(--border); border-radius: var(--radius-pill); background: var(--warning-surface); color: var(--ink); overflow: hidden; text-overflow: clip; }
.bar-btn .badge:not(.warn) { overflow: visible; } /* the pulse ring pseudo would be clipped; counts are short (white-space: nowrap, max-width 100%) */
body:has(#bar-overflow:not([hidden])) #quick-dock,
body:has(#bar-overflow:not([hidden])) #chat-toggle { visibility: hidden; }
/* Dock captions: a short visible word under every icon (quick-dock.js dockShort / status-hud.js statusShort write data-short).
   Dark ink on the light raised surface, never white on light; 48px keeps it inside the dock box (which clips) and left of the cards at 70px. */
/* 2026-11-04: the rail is at most six keys on every screen, so the captions fit at any desktop height too (they used to need a window >= 820 px tall for ten keys). */
#quick-dock { gap: 17px; padding-bottom: 16px; } /* the padding keeps the last caption inside the (scrolling) dock box */
#quick-dock > button::after { content: attr(data-short); position: absolute; top: calc(100% + 2px); left: 50%; transform: translateX(-50%);
  box-sizing: border-box; width: max-content; max-width: 48px; padding: 0 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  border-radius: 6px; background: var(--surface-raised); color: var(--ink); font: 600 9.5px/13px var(--font-body); pointer-events: none; }
#quick-dock .village-event-launcher::after { content: none; } /* wide screens: the pill already spells its label */
@media (max-height: 500px), (max-width: 760px) { #quick-dock .village-event-launcher::after { content: attr(data-short); } }
body:has(#quick-dock .is-open) #quick-dock .village-event-launcher::after { content: attr(data-short); }
@media (max-height: 500px) and (max-width: 1100px) { /* landscape phone: the dock is one short row, no room for captions */
  #quick-dock { gap: 6px; padding-bottom: 2px; }
  #quick-dock > button::after, #quick-dock .village-event-launcher::after { content: none; }
}
/* Small phones: the floating quest card drops its seal and clamps long instructions so the map
   (and its labels) stay visible; the full text is one tap away in Kayıtlar → Görevler. */
@media (max-width: 420px) {
  #quest-tracker .ui-quest.is-compact { grid-template-columns: minmax(0, 1fr); gap: var(--space-1); padding: var(--space-2); }
  #quest-tracker .ui-quest-seal { display: none; }
  #quest-tracker .ui-quest-desc { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  #quest-tracker .ui-quest-title { font-size: var(--text-sm); }
  #quest-tracker .ui-quest-kicker::after { display: none; }
  #quest-tracker .ui-quest-progress, #quest-tracker .ui-quest-reward { margin-top: var(--space-1); }
  /* The floating board card keeps the action and progress. Full reward details stay in Görevler. */
  #quest-tracker .quest-tracker-board .ui-quest-reward { display: none; }
  #quest-tracker .quest-tracker-board .ui-quest-kicker { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  #quest-tracker .quest-tracker-board .ui-quest-title { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  #quest-tracker .quest-tracker-board .quest-tracker-links { justify-content: space-between; gap: 2px; }
  #quest-tracker .quest-tracker-board .quest-help { flex: 0 0 44px; justify-content: center; padding: 0; }
  #quest-tracker .quest-tracker-board .quest-help-label { display: none; }
}

/* Mobile map first: four spendable resources stay visible; secondary HUD values expand on demand. */
@media (max-width: 760px), (pointer: coarse) and (max-width: 1100px), (max-height: 500px) and (max-width: 1100px) {
  :root { --bar-h: 60px; }
  #top { display: grid; grid-template-columns: minmax(0, 1fr) 44px; gap: 2px; align-items: start; }
  #move-strip { grid-column: 1 / -1; justify-self: center; }
  #home-call { grid-column: 1 / -1; justify-self: center; margin: 2px 0 0; }
  #move-strip:not([hidden]):has(+ #home-call:not([hidden])) { margin-right: auto; } /* own rows here: the strip stays centred */
  #top-info { min-width: 0; }
  #top .chips { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  #top:not(.hud-expanded) .chips > .chip:nth-child(n+5) { display: none; }
  #top:not(.hud-expanded) #era-hud { display: none; }
  #hud-toggle { display: grid; place-items: center; width: 44px; height: 44px; min-width: 44px; padding: 0;
    color: var(--ink); background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-md);
    font-size: 22px; font-weight: 700; }
  /* Collapsed ▾: a small "+" badge says more status cells are folded behind it; an idle builder chip stays visible (mobile-hud.css). */
  #top:not(.hud-expanded) #hud-toggle { position: relative; }
  #top:not(.hud-expanded) #hud-toggle::after { content: '+'; position: absolute; top: 2px; right: 2px; min-width: 15px; height: 15px; border-radius: var(--radius-pill);
    background: var(--surface-selected); border: 1px solid var(--border); color: var(--ink); font-size: 12px; font-weight: 800; line-height: 13px; text-align: center; }
  #bar { padding-top: 2px; padding-bottom: calc(2px + env(safe-area-inset-bottom, 0px)); }
  .bar-btn { height: 52px; }
  .bar-btn img { width: 24px; height: 24px; }
  .keyboard-open #chat-messages { min-height: 0; }
}
@media (max-height: 500px) and (max-width: 1100px) {
  :root { --bar-h: 56px; }
  .bar-btn { height: 48px; }
  body:has(#pick:not([hidden])) #quick-dock { top: 64px; bottom: auto; left: auto; right: var(--edge-right); }
  body:has(#nav:not([hidden])) :is(#quest-tracker, #alerts, #announce, #online-list) {
    top: calc(max(8px, env(safe-area-inset-top)) + 56px); bottom: auto;
    max-height: calc(var(--visible-h, 100dvh) - var(--bar-h) - 80px);
  }
}

.mcp-settings, .mcp-lapsed { margin-top: 16px; }
.mcp-settings label { display: block; margin: 10px 0 4px; font-weight: 600; }
.mcp-controls { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.mcp-controls input { flex: 1; min-width: 120px; }
.mcp-settings input, .mcp-settings textarea { max-width: 100%; box-sizing: border-box; }
.mcp-settings textarea, #mcp-endpoint { width: 100%; }
.mcp-settings pre { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 12px; }
.mcp-settings button, .mcp-settings summary, .mcp-lapsed button { min-height: 44px; }
.mcp-issued { padding: 12px; border: 1px solid var(--bronze); }

/* Sefer › Geçmiş: saldırı geçmişi satırları (tema değişkenleri; açık zeminde koyu metin). */
.raid-history { list-style: none; margin: 0; padding: 0; }
.raid-row summary { cursor: var(--cursor-pointer, pointer); }
.raid-row summary small { display: block; color: var(--muted); }
.raid-detail { display: grid; grid-template-columns: max-content 1fr; gap: 2px var(--space-3); margin: 0; font-size: var(--text-sm); color: var(--ink); }
.raid-detail dt { color: var(--muted); }
.raid-detail dd { margin: 0; }

/* #panel sits above #toasts so a toast never covers its close button, which left every toast raised
   while a window was open (a rejected trade, a failed build) hidden behind it. While the window is
   open, toasts move to the top, under the HUD and announcement ribbon, clear of the bottom-docked
   window, and stack above it in case a tall window reaches that high. */
body:has(#panel:not([hidden])) #toasts { top: calc(max(6px, env(safe-area-inset-top)) + var(--top-h) + var(--announce-h) + 8px); bottom: auto; z-index: var(--z-chrome);
  /* Only the strip between the HUD and the window's top edge (window max-height = min(58dvh, 560px)) is toast space: the clip keeps a
     stack from reaching the window title, and it is drawn above the window (a toast behind it was invisible at 1280x720), so it must never reach the title. */
  max-height: max(56px, calc(100dvh - max(6px, env(safe-area-inset-top)) - var(--top-h) - var(--announce-h) - 8px - var(--bar-h) - env(safe-area-inset-bottom, 0px) - 10px - min(58dvh, 560px) - 8px)); overflow: hidden; }
/* With a window open only the newest toast (+ the "+N" badge) shows; older ones are in Kayıtlar. */
body:has(#panel:not([hidden])) #toasts .toast:has(~ .toast:not(.toast-more)) { display: none; }
/* Desktop with the plain 400px window: toasts take the free strip to its right (outside the window, no clipping, full stack). Wide windows
   (shop/artifacts/research) leave no such strip and keep the clamped band above them. */
@media (min-width: 1000px) and (pointer: fine) {
  body:has(#panel:not([hidden]):not([class*="-wide"])) #toasts { left: auto; right: 14px; transform: none; align-items: flex-end;
    width: min(340px, calc(50vw - 200px - 28px)); max-height: none; overflow: visible; }
  body:has(#panel:not([hidden]):not([class*="-wide"])) #toasts .toast:has(~ .toast:not(.toast-more)) { display: flex; }
}
/* Phones: a full-width toast column. Under left:50% the box shrank to half the screen, so wrapped text spilled past its own card
   (the "ghost" strip at the right edge) — same fix as the action-card case above, now for every phone state. */
@media (max-width: 760px) {
  #toasts { left: calc(var(--edge-left, 8px) + 56px); right: var(--edge-right, 8px); transform: none; } /* 56px: the quick dock's icon column stays uncovered */
  #toasts .toast { max-width: 100%; box-sizing: border-box; overflow-wrap: anywhere; }
}
/* Phones, one alert (K4): the most urgent alert runs full width with a "🔔 N" button (alert-bell.js) opening the list; the truncated "+N bildirim daha" pill is gone. */
.alert-bell { display: none; }
@media (max-width: 720px) {
  #alerts.has-urgent:not(.quick-open) { left: var(--edge-left, 8px); right: calc(var(--edge-right, 8px) + 60px); width: auto; max-width: none; }
  body:has(#alerts.has-urgent:not(.quick-open)) .alert-bell { display: flex; align-items: center; justify-content: center; }
  .alert-bell { position: fixed; z-index: var(--z-chrome); right: var(--edge-right, 8px); min-width: 52px; min-height: 44px; box-sizing: border-box; padding: 0 10px;
    top: calc(max(8px, env(safe-area-inset-top)) + var(--top-h) + var(--announce-h, 0px) + var(--online-h, 0px) + 8px);
    border-radius: 8px; border: 1.5px solid var(--lbl-border); background: var(--surface); color: var(--ink); font: 700 14px var(--font-body); cursor: var(--cursor-pointer, pointer); }
  body:has(#alerts.has-urgent:not(.quick-open)) #toasts#toasts .toast.toast-more { display: none; } /* the 🔔 N counts them; doubled id: beats ui-modern-a.css `html.iso.ui-a #toasts .toast:not(:has(> *)) { display: block }`, which showed the pill over the alert */
}
/* #chat (z-chrome) is drawn over the default-layer toasts, so a chat action's confirmation (message report sent) was hidden. */
body:has(#chat:not([hidden])):not(:has(.action-card)) #toasts { z-index: var(--z-chrome); } /* an open action card keeps toasts under it */
/* Hesap: hediye kodu girişi (yalnız görsel büyük harf; sunucu kodu kendisi normalize eder) */
#gift-code-input { text-transform: uppercase; letter-spacing: .06em; min-width: 0; width: 9em; }

/* Hesap: davet paneli (settings-tabs.js) */
.referral-link { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; margin: 8px 0; }
.referral-link input { width: 100%; min-width: 0; box-sizing: border-box; }
.referral-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; margin: 8px 0; }
.referral-stat { min-width: 0; padding: 7px 10px; border: 1px solid var(--border-soft); border-radius: var(--radius-md); background: var(--surface-raised); }
.referral-stat dt { color: var(--muted); font-size: var(--text-sm); overflow-wrap: anywhere; }
.referral-stat dd { margin: 0; color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }

/* Language switch (language-switch.js): 2x2 grid with flag, code and native name; compact 4-up row on login and village pick. */
.lang-switch { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; width: 100%; }
.lang-switch .lang-btn { display: flex; align-items: center; gap: 8px; min-width: 0; min-height: 44px; padding: 6px 10px; border: 1px solid rgba(172, 121, 65, .48); border-radius: 8px;
  background: linear-gradient(180deg, rgba(255, 251, 241, .96), rgba(237, 222, 192, .96)); color: var(--ink, #392714); font: 600 13px 'Outfit', sans-serif; cursor: var(--cursor-pointer, pointer); touch-action: manipulation; }
.lang-switch .lang-btn svg { flex: none; width: 24px; height: 16px; border-radius: 2px; box-shadow: 0 0 0 1px rgba(57, 39, 20, .35); }
.lang-switch .lang-code { font-weight: 700; }
.lang-switch .lang-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; font-size: 12px; }
.lang-switch .lang-btn[aria-pressed="true"] { border-color: #7a4f1d; background: #e3c27d; box-shadow: inset 0 0 0 2px #7a4f1d; }
.lang-switch .lang-btn:focus-visible { outline: 2px solid #b17a3f; outline-offset: 2px; }
.lang-compact .lang-switch { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; }
.lang-compact .lang-btn { justify-content: center; gap: 5px; padding: 6px 4px; }
.lang-compact .lang-name { display: none; }
#auth #auth-language-switch { margin: 12px 0 0; }
.pick-language { display: grid; gap: 5px; font-weight: 700; }

/* Istanbul idle card: title, then the map filters as labelled chips in two columns. On = filled tick box + bold
   dark text; off = empty box + muted text. Names wrap (DE/FR are long), nothing is icon-only. */
#nav .nav-head > b { display: block; margin-bottom: var(--space-2); white-space: nowrap; }
:is(#nav .nav-head, #layers-panel) .seg.layers { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; margin: 0; }
:is(#nav .nav-head, #layers-panel) .layer-chip { display: flex; align-items: center; justify-content: flex-start; gap: 6px; min-width: 0; min-height: var(--touch-target); padding: 4px 8px;
  text-align: left; font-size: var(--text-xs); font-weight: 500; line-height: 1.15; color: var(--muted); background: rgba(139, 90, 43, 0.06); }
:is(#nav .nav-head, #layers-panel) .layer-chip[aria-pressed=true] { font-weight: 700; color: var(--ink); }
:is(#nav .nav-head, #layers-panel) .lc-box { flex: 0 0 18px; display: grid; place-items: center; width: 18px; height: 18px; border: 2px solid var(--muted); border-radius: 4px; background: var(--surface);
  font-size: 12px; font-weight: 900; line-height: 1; color: #fff8e8; }
:is(#nav .nav-head, #layers-panel) .layer-chip[aria-pressed=true] .lc-box { border-color: var(--ink); background: var(--ink); }
:is(#nav .nav-head, #layers-panel) .lc-ico { flex: 0 0 auto; font-size: 16px; line-height: 1; }
:is(#nav .nav-head, #layers-panel) :is(.lc-box, .lc-ico, .lc-txt) { margin: 0; } /* beat the generic `.seg span { margin-left: auto }` */
:is(#nav .nav-head, #layers-panel) .lc-txt { flex: 1 1 auto; min-width: 0; overflow-wrap: normal; hyphens: manual; color: inherit; }
:is(#nav .nav-head, #layers-panel) .lc-txt small { display: block; font-size: 12px; font-weight: 600; color: var(--btn-muted); }
@media (max-width: 400px) { :is(#nav .nav-head, #layers-panel) .lc-ico { display: none; } } /* narrow phones: the text is enough, and a long word must not split */
@media (min-width: 761px) { #nav:has(.nav-head) { width: min(340px, calc(100vw - 20px)); } }

/* Unified map, zoomed out: the map filters are a 🗺️ key in the left icon rail (#quick-dock, same look as its other keys; .is-open while the panel is up)
   and a two-column panel that opens to the right of the rail, its bottom edge on the key (main.js renderLayersPanel anchors it; left/bottom here is the fallback).
   Same .layer-chip look as the #nav card (rules above also match #layers-panel); windows and cards take priority. */
#layers-panel { position: fixed; left: 70px; bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + 14px); z-index: var(--z-action-card);
  box-sizing: border-box; width: min(320px, calc(100vw - 86px)); max-height: calc(100dvh - var(--top-h) - var(--announce-h) - var(--bar-h) - 88px); overflow-y: auto; padding: 8px; border-radius: 12px; }
#layers-btn[hidden], #layers-panel[hidden] { display: none; }
#layers-panel .seg.layers { margin: 0; }
/* "İlçeye git…" picker: native select, full width of its card, never wider than it (long DE/FR names truncate). */
.goto-district { display: block; box-sizing: border-box; width: 100%; max-width: 100%; min-height: var(--touch-target); margin: 8px 0 0; padding: 4px 8px;
  font: 600 var(--text-sm)/1.2 var(--font-body); color: var(--ink); background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-md); text-overflow: ellipsis; }
#nav .goto-district { margin: 8px 0; }
body:has(#nav:not([hidden])) :is(#layers-btn, #layers-panel), body:has(.action-card) :is(#layers-btn, #layers-panel), .sheet-open :is(#layers-btn, #layers-panel) { visibility: hidden; pointer-events: none; }

/* Touch hit areas >= 40px without growing the visuals (the 32px controls get an invisible ring around them). */
@media (pointer: coarse), (max-width: 760px) {
  .announce-close, .online-message, #move-strip { position: relative; }
  .announce-close::after, .online-message::after { content: ''; position: absolute; inset: -4px; }
  #move-strip::after { content: ''; position: absolute; inset: -4px 0; }
}

/* A disabled button must never look pressable (2026-11-03: "Fermanı mühürle" and the era "başlat" button looked live, the player pressed and nothing happened).
   Last word of this file, heavy on purpose: the button rules above weigh up to #panel :is(.seg button):is(.on) = (1,2,1), so a plain `button:disabled` (0,1,1)
   lost to them. `:not(#_)` adds an ID (always true) and `:not(.community-rank-row button)` a class + element: (1,2,2), and it comes later than all of them.
   The ranking rows (community-ranking.css) disable the player's own name button on purpose and keep it a plain link, so they are the one exception.
   No opacity and no cursor here: #auth's submit dims itself and shows "wait" while it signs in (auth.css); the cursor is set in the two lighter rules above. */
button:disabled:not(#_):not(.community-rank-row button) { background: var(--surface-disabled); color: var(--muted); border-image: none; box-shadow: none; filter: none; }
/* an action in flight (act-gate.js) is disabled too: it keeps the progress cursor the not-allowed ones above would take away */
button[aria-busy="true"]:disabled, #panel button[aria-busy="true"]:disabled, dialog button[aria-busy="true"]:disabled, #nav button[aria-busy="true"]:disabled { cursor: progress; }
