/* ==========================================================================================
   Readable numbers, supplied icon art, the Knightro map pin, camera flip, and the phone layouts.
   Loaded last. Desktop layout is unchanged except for icons and number styling.
   ========================================================================================== */
:root {
  /* Digits only. The pixel fonts make 5/8/S and 6/b look alike; Space Mono keeps the retro feel with clear,
     equal-width digits so columns and timers line up. */
  --f-num: 'Space Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
}

/* ------------------------------------------------------------------ numbers */
.num {
  font-family: var(--f-num); font-weight: 700; font-style: normal;
  font-variant-numeric: tabular-nums lining-nums; letter-spacing: 0; text-shadow: none;
}
/* Small pixel-font contexts: give digits a touch more size so they hold up on phones. */
.mission-bar .num { font-size: 1.3em; line-height: 1; }
.status .num, .fresh-note .num, .label .num, .ticker .num, .px-btn .num, .report-btn .num { font-size: 1.15em; line-height: 1; }
input[type="number"], #account-code { font-family: var(--f-num); font-weight: 700; }
.badge, .stack-count {
  font: 700 12px/1 var(--f-num); letter-spacing: 0; padding: 4px 5px 3px; min-width: 24px; text-shadow: none;
}
.kt-pin .age, .asset-pin .age { font: 700 10px/1.25 var(--f-num); letter-spacing: 0; padding: 1px 4px; }
.bounty-clock { font: 700 15px var(--f-num); letter-spacing: 0; }
.stat {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 10px 12px;
  background: var(--ink); box-shadow: inset 0 0 0 2px var(--line);
}
.stat-value { font-size: 26px; line-height: 1; color: var(--gold); }

/* Leaderboard: rank badge grows for 2-3 digit ranks; names truncate; points stay right-aligned in one column. */
.leaderboard li { grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; }
.leaderboard .rank {
  min-width: 30px; width: auto; height: 30px; padding: 0 6px;
  font: 700 15px/1 var(--f-num); letter-spacing: 0;
}
.lb-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.leaderboard li .lb-score { white-space: nowrap; text-align: right; color: var(--gold); font-size: 17px; line-height: 1; }
.lb-score small { font: 10px var(--f-display); letter-spacing: 0.06em; color: var(--dim); }
.leaderboard li.top .lb-score { color: var(--gold-hi); }

/* ------------------------------------------------------------------ bottom dock + ticker */
/* REPORT and RECENT share one height, outline, and drop, so they sit on the same baseline and press the same way.
   The ticker always reserves two lines, and the dock sits a clear gap above it plus the buttons' drop shadow,
   so a long message never grows into the buttons. */
:root {
  --dock-h: 60px; --dock-ring: 3px; --dock-drop: 7px; /* the RECENT tile's original stroke */
  --ticker-h: 58px;
  --ticker-gap: 12px; /* clear space between the ticker and the bottom frame */
  --dock-bottom: calc(var(--frame) + var(--ticker-gap) + var(--ticker-h) + var(--dock-drop) + 12px);
}
.ticker { bottom: calc(var(--frame) + var(--ticker-gap)); height: var(--ticker-h); min-height: 0; }
/* REPORT + RECENT are centred together as one group (landscape phones re-enable the grid below). */
.dock { display: flex; justify-content: center; align-items: end; gap: 18px; }
.dock > span:first-child { display: none; }
.dock .report-btn, .dock .recent-btn {
  height: var(--dock-h); margin: 0; align-self: end;
  box-shadow: 0 calc(-1 * var(--dock-ring)) 0 var(--ink), 0 var(--dock-ring) 0 var(--ink), calc(-1 * var(--dock-ring)) 0 0 var(--ink), var(--dock-ring) 0 0 var(--ink),
    inset 3px 3px 0 var(--bevel-hi), inset -3px -3px 0 var(--bevel-lo), 0 var(--dock-drop) 0 var(--bevel-lo);
}
.dock .report-btn:hover, .dock .recent-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 calc(-1 * var(--dock-ring)) 0 var(--ink), 0 var(--dock-ring) 0 var(--ink), calc(-1 * var(--dock-ring)) 0 0 var(--ink), var(--dock-ring) 0 0 var(--ink),
    inset 3px 3px 0 var(--bevel-hi), inset -3px -3px 0 var(--bevel-lo), 0 calc(var(--dock-drop) + 2px) 0 var(--bevel-lo);
}
.dock .report-btn:active, .dock .recent-btn:active {
  transform: translateY(calc(var(--dock-drop) - 4px));
  box-shadow: 0 calc(-1 * var(--dock-ring)) 0 var(--ink), 0 var(--dock-ring) 0 var(--ink), calc(-1 * var(--dock-ring)) 0 0 var(--ink), var(--dock-ring) 0 0 var(--ink),
    inset 3px 3px 0 var(--bevel-lo), inset -3px -3px 0 var(--bevel-hi), 0 4px 0 var(--bevel-lo);
}

/* ------------------------------------------------------------------ supplied icon art */
.icon-art { display: block; object-fit: contain; image-rendering: auto; pointer-events: none; flex: none; }
/* The art files are framed on their visible artwork (tight viewBox), so plain centring is optical centring. */
/* Winking Knightro in the menu's KNIGHTRO HQ badge (the toggle keeps its three bars). */
.nav-badge { width: 44px; height: 44px; background: var(--tile); box-shadow: inset 2px 2px 0 #fff, inset -2px -2px 0 var(--tile-sh), 0 0 0 2px var(--ink); }
.nav-badge #nav-helm { width: 36px; height: 36px; image-rendering: auto; }
.recent-btn .icon-art { width: 32px; height: 32px; }
.report-btn .icon-art { width: 34px; height: 34px; }
/* The pin art is taller than wide: keep its proportions at whatever height a layout gives the icon. */
.report-btn .icon-art.pin-art-icon { width: auto; aspect-ratio: 228.8 / 290.4; }
.nav-ico { width: 38px; height: 38px; }
.nav-item { grid-template-columns: 38px minmax(0, 1fr) auto; }
.nav-ico.art { background: var(--tile); box-shadow: inset 2px 2px 0 #fff, inset -2px -2px 0 var(--tile-sh), 0 0 0 2px var(--ink); }
.nav-ico.art img { width: 30px; height: 30px; object-fit: contain; image-rendering: auto; }
.nav-ico.art img.wide-art { transform: scale(1.12); } /* flat podium art: same perceived size as the others */
.nav-item:hover .nav-ico.art img { transform: translateY(-1px) scale(1.06); }
.nav-item:hover .nav-ico.art img.wide-art { transform: translateY(-1px) scale(1.18); }
.nav-ico.art img { transition: transform 180ms var(--ease-ui); }

/* ------------------------------------------------------------------ Knightro map pin */
/* Leaflet positions .kt-pin; only inner wrappers animate, so the tip stays on its coordinate. */
.leaflet-container .asset-pin .pin-art img { width: 100%; height: 100%; }
.sighting-pin .kt-pin-body { filter: drop-shadow(0 3px 0 rgba(0, 0, 0, 0.55)); transform-origin: 50% 100%; } /* straight-down shadow keeps the pin visually centred */
/* Age label centred under the tip by layout (no translate maths that can drift while fonts load). */
.sighting-pin .age { left: 0; right: 0; width: max-content; margin: 1px auto 0; transform: none; }
.sighting-pin .pin-art { transform-origin: 50% 100%; }
.asset-pin.sel .pin-art img { filter: drop-shadow(0 0 0 #fff) drop-shadow(0 0 4px rgba(255, 255, 255, 0.9)); }
.pending-pin .pin-art img { filter: saturate(0.35) brightness(0.9); }
.pending-pin .age { background: var(--warn); color: var(--ink); }
.asset-pin.spotlight .kt-pin-body::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -5px; width: 18px; height: 9px; margin: 0 auto;
  border: 3px solid var(--gold); border-radius: 50%; pointer-events: none;
  opacity: 0; animation: spotRing 0.9s ease-out 3 both; /* invisible except while pulsing: never left behind */
}
@keyframes spotRing { from { transform: scale(0.6); opacity: 1; } to { transform: scale(4); opacity: 0; } }
.kt-drop .drop-art { display: block; width: 100%; height: 100%; }
.leaflet-container .kt-drop img { width: 100%; height: 100%; object-fit: contain; image-rendering: auto; }

/* ------------------------------------------------------------------ camera flip */
.camera-viewport.mirror video { transform: scaleX(-1); } /* live selfie preview only; captured photos are never mirrored */
.camera-flip {
  position: absolute; right: 8px; bottom: 8px; z-index: 1; min-width: 64px; min-height: 40px; padding: 7px 10px 5px;
  border: 0; cursor: pointer; background: rgba(12, 12, 14, 0.82); color: var(--gold);
  font: 11px var(--f-display); letter-spacing: 0.06em; box-shadow: 0 0 0 2px var(--gold);
  transition: transform 140ms var(--ease-ui), background 120ms ease;
}
.camera-flip:hover:not(:disabled) { background: var(--gold); color: var(--ink); }
.camera-flip:active:not(:disabled) { transform: translateY(2px); }
.camera-flip:disabled { opacity: 0.45; cursor: progress; }

/* ==========================================================================================
   Phones, portrait. Three compact rows on top, map in the middle, report + recent + ticker at the bottom.
   Panels are bottom sheets that never exceed the visible height; only one sheet or the menu shows at a time.
   ========================================================================================== */
@media (max-width: 720px) {
  :root {
    --frame: 10px;
    --row1: calc(var(--frame) + var(--safe-t) + 8px);        /* menu · title · sound, clear of the frame */
    --row2: calc(var(--row1) + 48px);                         /* live status */
    --row3: calc(var(--row2) + 26px);                         /* mission chips */
    --chrome-bottom: calc(var(--row3) + 36px);
    --ticker-h: 40px;
    --dock-h: 50px; --dock-ring: 3px; --dock-drop: 7px;
    --ticker-gap: 8px;
    --dock-bottom: calc(var(--frame) + var(--safe-b) + var(--ticker-gap) + var(--ticker-h) + var(--dock-drop) + 10px);
  }
  .frame-corner { width: 18px; height: 18px; }
  .corner { top: var(--row1); width: 44px; height: 44px; }
  .corner.l { left: calc(var(--frame) + 4px); }
  .corner.r { right: calc(var(--frame) + 4px); }
  .corner img { width: 24px; }
  .plaque { top: var(--row1); max-width: calc(100vw - 2 * (var(--frame) + 54px)); padding: 4px 8px; }
  .status { top: var(--row2); padding: 3px 9px 2px; font-size: 10px; }
  .mission-bar { top: var(--row3); width: calc(100vw - 2 * var(--frame) - 12px); gap: 8px; }
  .mission-bar button { flex: 1 1 0; min-width: 0; height: 30px; margin-bottom: 4px; padding: 6px 6px 4px; font-size: 9px; }

  /* Map controls: one vertical group on the right, just above the dock (thumb reach), clear of the title rows. */
  .leaflet-bottom.leaflet-left {
    top: auto; left: auto; right: calc(var(--frame) + 4px);
    bottom: calc(var(--dock-bottom) + 66px);
  }
  .leaflet-control-zoom { display: block; }
  .leaflet-bar a, .leaflet-bar a:hover, .leaflet-touch .leaflet-bar a { width: 40px; height: 40px; line-height: 38px; }
  .leaflet-bar a, .leaflet-bar a:hover { border-right: 0 !important; border-bottom: 2px solid var(--ink) !important; }
  .leaflet-bar a:last-child { border-bottom: 0 !important; }
  .leaflet-bottom.leaflet-right { top: auto; right: auto; left: calc(var(--frame) + 2px); bottom: calc(var(--dock-bottom) + 58px); }
  .leaflet-control-attribution { font-size: 9px; line-height: 1.3; padding: 0 4px; }

  /* Dock: report fills the row, recent beside it. One line of text, never wraps. */
  .dock { display: flex; align-items: end; gap: 10px; padding: 0 calc(var(--frame) + 6px); bottom: var(--dock-bottom); }
  .dock > span:first-child { display: none; }
  .report-btn {
    flex: 1 1 auto; width: auto; min-width: 0; padding: 0 12px; gap: 8px;
    font-size: clamp(12px, 3.7vw, 15px); white-space: nowrap;
  }
  .report-btn > span { overflow: hidden; text-overflow: ellipsis; }
  .report-btn .icon-art { width: 28px; height: 28px; }
  .recent-btn { flex: none; width: 58px; padding-top: 3px; }
  .recent-btn .icon-art { width: 28px; height: 28px; }
  .recent-btn span { font-size: 9px; }
  .ticker {
    bottom: calc(var(--frame) + var(--safe-b) + var(--ticker-gap)); width: calc(100vw - 2 * var(--frame) - 8px);
    padding: 5px 10px 3px; font-size: 10px; border-width: 2px;
  }

  /* Bottom sheet: from the bottom frame up to at most the top rows; content scrolls inside. */
  .panel-shell {
    left: calc(var(--frame) - 4px); right: calc(var(--frame) - 4px); width: auto; top: auto;
    bottom: calc(var(--frame) + var(--safe-b));
    height: min(62dvh, calc(var(--vvh, 100dvh) - var(--chrome-bottom) - var(--frame) - var(--safe-b)));
    min-height: 0;
  }
  .panel-head { padding: 7px 8px 6px 12px; }
  .panel-head h2 { font-size: 13px; }
  .panel-head .x { min-width: 44px; min-height: 40px; font-size: 14px; }
  #panel-close { background: var(--gold); color: var(--ink); box-shadow: inset 2px 2px 0 var(--bevel-hi), inset -2px -2px 0 var(--bevel-lo); }
  .panel-body { padding: 12px 12px calc(14px + var(--safe-b)); gap: 10px; }
  .camera-viewport { max-height: min(240px, 34dvh); }

  /* Menu: one panel at a time. While it is open, any sheet steps aside (kept, so a report in progress survives). */
  .navigation {
    top: calc(var(--row1) + 52px); left: calc(var(--frame) + 4px);
    width: min(320px, calc(100vw - 2 * var(--frame) - 8px));
    max-height: calc(var(--vvh, 100dvh) - var(--row1) - 52px - var(--frame) - var(--safe-b));
  }
  .nav-item { min-height: 50px; }
  body.menu-open .panel-shell.open { transform: translateY(calc(100% + 60px)); visibility: hidden; transition: transform 0.2s ease-in, visibility 0s linear 0.2s; }

  .toasts { top: var(--chrome-bottom); left: 50%; right: auto; transform: translateX(-50%); width: min(340px, calc(100vw - 24px)); }
}

/* Short portrait screens (e.g. 320×568 or a keyboard on Android, where the layout itself shrinks): the sheet may rise
   over the top rows instead of becoming a sliver. */
@media (max-width: 389px) {
  #mission-sense .m-long { display: none; } /* the gold chip already signals a new hint */
}
@media (max-width: 374px) {
  .mission-bar .m-long { display: none; } /* keep the numbers, drop the filler words */
  .mission-bar button { font-size: 8.5px; padding-inline: 4px; }
}
@media (max-width: 720px) and (max-height: 600px) {
  .panel-shell { height: auto; top: calc(var(--row1) + 50px); }
}
/* iOS keyboard (the layout does not shrink): sit the sheet on top of the keyboard and use all visible height. */
@media (max-width: 720px) {
  body.keyboard-open .panel-shell { top: calc(var(--safe-t) + 6px); height: auto; bottom: calc(var(--kb) + 4px); }
}

/* ==========================================================================================
   Phones, landscape (short screens). Status and missions share one row; panels become a right-hand column.
   ========================================================================================== */
@media (orientation: landscape) and (max-height: 500px) {
  :root {
    --frame: 8px;
    --row1: calc(var(--frame) + 6px);
    --row2: calc(var(--row1) + 46px);
    --chrome-bottom: calc(var(--row2) + 34px);
    --dock-h: 44px; --dock-ring: 3px; --dock-drop: 6px;
    --dock-bottom: calc(var(--frame) + var(--safe-b) + var(--dock-drop) + 8px);
  }
  .frame-corner { width: 16px; height: 16px; }
  .corner { top: var(--row1); width: 42px; height: 42px; }
  .corner.l { left: calc(var(--frame) + 4px + env(safe-area-inset-left, 0px)); }
  .corner.r { right: calc(var(--frame) + 4px + env(safe-area-inset-right, 0px)); }
  .plaque { top: var(--row1); padding: 4px 10px; }
  .plaque h1 { font-size: 13px; gap: 6px; }
  .knightro-window { width: 32px; height: 32px; margin-block: -5px; }
  .knightro-anim { width: 25px; }
  .status { top: var(--row2); left: calc(var(--frame) + 56px + env(safe-area-inset-left, 0px)); transform: none; font-size: 10px; padding: 4px 9px 3px; animation: none; }
  .mission-bar { top: var(--row2); left: auto; right: calc(var(--frame) + 56px + env(safe-area-inset-right, 0px)); transform: none; gap: 8px; width: auto; max-width: calc(100vw - 2 * var(--frame) - 260px); }
  .mission-bar button { flex: 0 1 auto; height: 28px; padding: 6px 8px 4px; font-size: 9px; margin-bottom: 0; }

  /* Bottom band: ticker on the left, report in the middle, recent on its right. */
  /* Bottom band: ticker on the left; REPORT + RECENT centred together as one group. */
  :root { --report-w: clamp(200px, 34vw, 300px); }
  .dock { display: flex; justify-content: center; bottom: var(--dock-bottom); gap: 10px; padding: 0; }
  .dock > span:first-child { display: none; }
  .report-btn { flex: none; min-width: 0; width: var(--report-w); font-size: 13px; padding: 0 12px; gap: 8px; white-space: nowrap; }
  .report-btn .icon-art { width: 26px; height: 26px; }
  .recent-btn { width: 56px; }
  .recent-btn .icon-art { width: 24px; height: 24px; }
  .recent-btn span { font-size: 8px; }
  .ticker {
    left: calc(var(--frame) + 4px + env(safe-area-inset-left, 0px)); transform: none; animation: none;
    bottom: var(--dock-bottom); height: var(--dock-h); width: calc(50vw - (var(--report-w) + 66px) / 2 - var(--frame) - 18px - env(safe-area-inset-left, 0px));
    padding: 4px 8px 3px; font-size: 9px; border-width: 2px;
  }
  .ticker.glitch { animation: none; }
  .leaflet-bottom.leaflet-left { top: calc(var(--chrome-bottom) + 6px); bottom: auto; left: auto; right: calc(var(--frame) + 4px + env(safe-area-inset-right, 0px)); }
  .leaflet-control-zoom { display: block; }
  .leaflet-bar a, .leaflet-bar a:hover, .leaflet-touch .leaflet-bar a { width: 34px; height: 34px; line-height: 32px; font-size: 18px; }
  .leaflet-bottom.leaflet-right { top: auto; bottom: calc(var(--dock-bottom) + 52px); right: calc(var(--frame) + 4px); }
  .leaflet-control-attribution { font-size: 9px; }

  .panel-shell {
    left: auto; right: calc(var(--frame) + 4px + env(safe-area-inset-right, 0px)); width: min(380px, 48vw);
    top: calc(var(--chrome-bottom) + 2px); bottom: calc(var(--frame) + var(--safe-b)); height: auto;
    transform: translateX(calc(100% + 50px));
  }
  .panel-shell.open { transform: none; }
  .panel-head .x { min-width: 40px; min-height: 36px; }
  .panel-body { padding: 10px; gap: 10px; }
  .camera-viewport { max-height: 46dvh; }
  .navigation { top: calc(var(--row1) + 48px); max-height: calc(var(--vvh, 100dvh) - var(--row1) - 48px - var(--frame)); width: min(300px, 46vw); }
  body.menu-open .panel-shell.open { transform: translateX(calc(100% + 50px)); visibility: hidden; transition: transform 0.2s ease-in, visibility 0s linear 0.2s; }
  .toasts { top: var(--chrome-bottom); right: auto; left: 50%; transform: translateX(-50%); width: min(340px, 60vw); }
  body.keyboard-open .panel-shell { top: calc(var(--frame) + 2px); bottom: calc(var(--kb) + 4px); }
}
/* Small landscape phones (e.g. 568×320): drop filler words and tighten the report label so numbers never clip. */
@media (orientation: landscape) and (max-height: 500px) and (max-width: 700px) {
  .mission-bar .m-long { display: none; }
  .mission-bar { max-width: calc(100vw - 2 * var(--frame) - 240px); }
  :root { --report-w: clamp(180px, 38vw, 230px); }
  .report-btn { font-size: 11px; letter-spacing: 0.05em; gap: 6px; }
  .report-btn .icon-art { width: 22px; height: 22px; }
  .ticker { font-size: 8px; }
}
/* Pixel icons inside the mission chips (2× bounty bolt, Knight-Sense radar). Inline so the chip text can still truncate. */
.mission-bar .chip-ico { display: inline-block; width: 16px; height: 16px; margin-right: 6px; vertical-align: -4px; image-rendering: auto; }
@media (max-width: 720px) { .mission-bar .chip-ico { width: 15px; height: 15px; margin-right: 4px; vertical-align: -4px; } }

/* ------------------------------------------------------------------ spinning Knightro in the title */
/* Plain black window (no dot grid). Each frame has ~9% transparent margin around the figure, so the frame box is
   sized so the figure itself fills the window's inner area (inside the 3px bevel); only empty margin is clipped. */
.knightro-window { --kw: 56px; width: var(--kw); height: var(--kw); background: var(--ink); overflow: hidden; }
.knightro-anim {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: auto; height: calc((var(--kw) - 6px) / 0.86); aspect-ratio: 800.41 / 858.63;
}
@media (max-width: 720px) { .knightro-window { --kw: 36px; margin-block: -6px; } }
@media (max-width: 360px) { .knightro-window { --kw: 31px; margin-block: -5px; } }
@media (orientation: landscape) and (max-height: 500px) { .knightro-window { --kw: 34px; margin-block: -6px; } }

/* ------------------------------------------------------------------ pins keep their proportion to the map */
/* app.js sets --pin-scale from the zoom (1 at street level, down to 0.55 zoomed out). Only the inner art scales,
   from the anchor point, so pins stay on their coordinates; the clickable area shrinks with the art. */
.kt-pin .kt-pin-body, .kt-drop .drop-art { scale: var(--pin-scale, 1); }
.kt-drop .drop-art { transform-origin: 50% 100%; }
.leaflet-marker-icon.kt-pin { pointer-events: none !important; }
.leaflet-marker-icon.kt-pin .kt-pin-body { pointer-events: auto; }
.map-root.far-out .kt-pin .age { display: none; } /* labels would only add clutter when zoomed far out */

/* ------------------------------------------------------------------ title plaque inside the frame */
/* Desktop: the plaque sits inside the gold frame, level with the corner buttons, with equal padding above and
   below; the status chip and missions move down to keep their spacing. */
.plaque { top: calc(var(--frame) + 8px); padding: 6px 16px; }
.knightro-window { --kw: 44px; margin-block: -4px; }
.status { top: calc(var(--frame) + 68px); }
.mission-bar { top: calc(var(--frame) + 98px); }
.panel-shell { top: calc(var(--frame) + 150px); }
@media (max-width: 720px) {
  .plaque { top: var(--row1); padding: 4px 8px; }
  .knightro-window { --kw: 36px; margin-block: -4px; }
  .status { top: var(--row2); }
  .mission-bar { top: var(--row3); }
}
@media (max-width: 360px) { .knightro-window { --kw: 31px; margin-block: -3px; } }
@media (orientation: landscape) and (max-height: 500px) {
  .plaque { top: var(--row1); padding: 4px 10px; }
  .knightro-window { --kw: 34px; margin-block: -5px; }
  .status, .mission-bar { top: var(--row2); }
}
/* Knight-Sense chip: the radar icon takes room, so "· NEW HINT" drops a little earlier (the gold chip still signals it). */
@media (max-width: 479px) { #mission-sense .m-long { display: none; } }

/* "No active sightings": the RECENT button's Knightro art on a plain black tile (no dot grid). */
.empty img.empty-art {
  width: 56px; height: 56px; padding: 5px; box-sizing: border-box; object-fit: contain; image-rendering: auto;
  background: var(--ink); box-shadow: inset 2px 2px 0 var(--bevel-lo), inset -2px -2px 0 var(--bevel-hi);
}
/* Private moderation photos are loaded only in the authorized admin panel. */
.admin-review-photo { display:block; width:160px; max-width:100%; height:120px; object-fit:contain; background:var(--ink, #111); margin:8px 0; }

/* Report result + error icons: pixel checkmark on success, pixel warning when something failed or was not posted. */
.victory img.result-art { width: 56px; height: 56px; object-fit: contain; image-rendering: auto; flex: none; }
.victory.not-posted h3 { color: var(--warn); }
.msg.err.error-box .msg-ico { width: 26px; height: 26px; flex: none; object-fit: contain; image-rendering: auto; }
.msg.err.error-box > span { flex: 1 1 150px; }

/* ------------------------------------------------------------------ Knightro medallion map pins */
/* Round pins centred on their point: scale, hover lift, tap pulse and the highlight ring all work from the centre.
   Normal and hover art are stacked in the same box and cross-fade. */
.sighting-pin .kt-pin-body, .sighting-pin .pin-art, .kt-drop .drop-art { transform-origin: 50% 50%; }
.sighting-pin .pin-art img, .kt-drop .drop-art img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; image-rendering: auto; transition: opacity 140ms ease; }
.kt-drop .drop-art { position: relative; }
.kt-drop .drop-art img { transform-origin: 50% 50%; }
.pin-hover { opacity: 0; }
.asset-pin:hover .pin-hover, .asset-pin:focus-visible .pin-hover, .kt-drop.lifted .pin-hover { opacity: 1; }
.asset-pin:hover .pin-normal, .asset-pin:focus-visible .pin-normal, .kt-drop.lifted .pin-normal { opacity: 0; }
.asset-pin.sighting-pin:hover .kt-pin-body, .asset-pin.sighting-pin:focus-visible .kt-pin-body { transform: scale(1.12); }
.asset-pin.sighting-pin.sel .kt-pin-body { transform: scale(1.08); }
.kt-drop.lifted .drop-art img { transform: none; }
.kt-drop.lifted .drop-art { transform: translateY(-10px) scale(1.15); filter: drop-shadow(3px 10px 0 rgba(0, 0, 0, 0.35)); }
.kt-drop .drop-art { transition: transform 0.15s var(--pop), filter 0.15s; }
.sighting-pin .age { margin-top: 3px; }
.asset-pin.sighting-pin.spotlight .kt-pin-body::after {
  top: 0; bottom: 0; left: 0; right: 0; width: auto; height: auto; margin: 0; border-radius: 50%;
}
.asset-pin.sighting-pin.spotlight .kt-pin-body::after { animation-name: spotRingRound; }
@keyframes spotRingRound { from { transform: scale(0.95); opacity: 1; } to { transform: scale(1.8); opacity: 0; } }

/* ==========================================================================================
   Report flow: photo → current location & submit
   ========================================================================================== */
.report-photo { margin: 0; display: grid; gap: 8px; justify-items: start; }
.report-photo img { width: 100%; max-height: 220px; object-fit: contain; background: var(--ink); border: 3px solid var(--ink); box-shadow: 0 0 0 2px var(--line); }
.report-photo.review img { max-height: 160px; }
.loc-summary {
  display: grid; gap: 4px; justify-items: start; padding: 10px 12px; background: var(--ink);
  border-left: 4px solid var(--gold); box-shadow: inset 0 0 0 2px var(--line);
}
.loc-summary strong { color: var(--gold-hi); }
.loc-problem { display: grid; gap: 10px; justify-items: start; }
/* The current step's main action stays reachable at the bottom of the report panel while its content scrolls. */
body.report-open .panel-body > .panel-foot {
  position: sticky; bottom: 0; z-index: 2; margin: 4px -14px -14px; padding: 10px 14px calc(10px + var(--safe-b));
  background: var(--screen); box-shadow: 0 -3px 0 var(--line);
}
@media (max-width: 720px) {
  /* The report panel is nearly full screen: from just under the top row to the bottom frame. */
  body.report-open .panel-shell { top: calc(var(--row1) + 50px); height: auto; bottom: calc(var(--frame) + var(--safe-b)); }
}
/* A keyboard-open sheet rises over the top row; keep it above the corner buttons so nothing overlaps its header. */
body.keyboard-open .panel-shell { z-index: 840; }
.report-pin .drop-art { transform-origin: 50% 100%; }

/* ==========================================================================================
   Event medallions, raised Report/bounty art, and the orange accent
   ========================================================================================== */
/* ---------- event pins: three frames, swapped discretely (no cross-fade, no float) ---------- */
.event-pin .kt-pin-body { animation: none; transform-origin: 50% 50%; }
.event-pin .event-frame { animation: none; opacity: 1; visibility: hidden; object-fit: contain; image-rendering: auto; }
.event-pin [data-frame="1"] .frame-0, .event-pin [data-frame="2"] .frame-1, .event-pin [data-frame="3"] .frame-2 { visibility: visible; }
.event-pin .frame-1, .event-pin .frame-2 { transform: translateX(1.4%); } /* frames 2–3 sit 1.4% left in their files */
.event-pin:hover .kt-pin-body, .event-pin.sel .kt-pin-body { transform: scale(1.08); }

/* ---------- shared orange accent: the mute button's cross-out ---------- */
:root { --accent: var(--bad); }
#btn-sound.muted::after { background: var(--accent); }
.badge, .stack-count { background: var(--accent); color: var(--ink); box-shadow: 0 0 0 2px var(--ink); }
.badge { top: -11px; right: -11px; padding: 4px 6px 3px; }
.stack-count { border: 0; right: -10px; top: -6px; }
/* Restrained extra uses: the current menu item's edge and the ticker's typing cursor. */
.nav-item[aria-current] { box-shadow: var(--raise), inset 4px 0 0 var(--accent); }
.ticker .cursor { background: var(--accent); }

/* ---------- Report Sighting: raised, lit from the top-left ---------- */
/* Dithered highlight along the top, shade along the bottom and right; the middle (where the label sits) stays clean. */
.dock .report-btn {
  background:
    var(--drs-hi-down) 0 0 / 8px 16px repeat-x,
    var(--drs-lo-up) 0 100% / 8px 16px repeat-x,
    var(--drs-lo-left) 100% 0 / 16px 8px repeat-y,
    var(--gold);
  text-shadow: none; font-weight: 700;
}
.dock .report-btn:hover { background-color: var(--gold-hi); }
.dock .report-btn:active { /* pressed: light and shade swap, like a key pushed in */
  background-image: var(--drs-lo-down), var(--drs-hi-up), var(--drs-hi-right);
  background-position: 0 0, 0 100%, 0 0;
}
.dock .report-btn.active { background: var(--screen); }
.report-btn::after { background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.4), transparent); } /* softer shine over the label */

/* ---------- 2× bounty tile: same light direction, clear numerals ---------- */
.bounty-art {
  font: 700 25px/1 var(--f-num); letter-spacing: -0.02em; padding-top: 1px;
  background:
    var(--drs-hi-down) 0 0 / 8px 16px repeat-x,
    var(--drs-hi-right) 0 0 / 16px 8px repeat-y,
    var(--drs-lo-up) 0 100% / 8px 16px repeat-x,
    var(--drs-lo-left) 100% 0 / 16px 8px repeat-y,
    var(--gold);
}
.asset-pin:hover .bounty-art { background-color: var(--gold-hi); }
.bounty-multiplier { font: 700 20px var(--f-num); letter-spacing: -0.02em; }

/* ------------------------------------------------------------------ title Knightro: no square behind the head */
/* The window stays as an invisible, fixed-size box (so nothing around it shifts); only its fill and bevel go. */
.knightro-window { background: none; box-shadow: none; }

/* ==========================================================================================
   Grey controls: the Report button's depth recipe in the grey family
   Light from the top-left: dithered highlight along the top, dithered shade along the bottom and right, two-tone
   bevel; pressed swaps them. Full-height buttons get the gradual ramps; small buttons and rows get thin 4 px strips,
   so labels always sit on a clean middle.
   ========================================================================================== */
:root {
  --grey-hi: #4a4f5c; --grey-lo: #0d0e11;
  --grey-ramps: var(--drs-steel-down) 0 0 / 8px 16px repeat-x, var(--drs-ink-up) 0 100% / 8px 16px repeat-x, var(--drs-ink-left) 100% 0 / 16px 8px repeat-y;
  --grey-ramps-pressed: var(--drs-ink-down) 0 0 / 8px 16px repeat-x, var(--drs-steel-up) 0 100% / 8px 16px repeat-x, var(--drs-steel-right) 0 0 / 16px 8px repeat-y;
  --grey-strips: var(--dt-steel-50) 0 0 / 8px 4px repeat-x, var(--dt-ink-75) 0 100% / 8px 4px repeat-x;
  --grey-strips-pressed: var(--dt-ink-75) 0 0 / 8px 4px repeat-x, var(--dt-steel-50) 0 100% / 8px 4px repeat-x;
  --grey-raise: inset 2px 2px 0 var(--grey-hi), inset -2px -2px 0 var(--grey-lo);
  --grey-sunk: inset 2px 2px 0 var(--grey-lo), inset -2px -2px 0 var(--grey-hi);
}
/* Secondary buttons (BACK, RETRY, REFRESH, CANCEL, RETAKE …) */
.px-btn.alt { background: var(--grey-ramps), var(--screen-2); box-shadow: 0 0 0 2px var(--ink), var(--grey-raise); }
.px-btn.alt:hover:not(:disabled) { background: var(--grey-ramps), #2b2f38; }
.px-btn.alt:active:not(:disabled) { background: var(--grey-ramps-pressed), var(--screen-2); box-shadow: 0 0 0 2px var(--ink), var(--grey-sunk); }
.px-btn.alt.sm { background: var(--grey-strips), var(--screen-2); }
.px-btn.alt.sm:hover:not(:disabled) { background: var(--grey-strips), #2b2f38; }
.px-btn.alt.sm:active:not(:disabled) { background: var(--grey-strips-pressed), var(--screen-2); }
.px-btn.alt[aria-pressed="true"], .px-btn.alt.on { box-shadow: 0 0 0 2px var(--ink), var(--grey-sunk), inset 0 -3px 0 var(--accent); } /* selected */
.px-btn.alt:disabled { background: var(--screen-2); box-shadow: 0 0 0 2px var(--line); opacity: 0.5; }
/* Panel header buttons (BACK / close on desktop; the phone close stays gold) */
.x { background: var(--grey-strips), var(--screen-2); box-shadow: var(--grey-raise); }
.x:hover { background: var(--grey-strips), #2b2f38; }
.x:active { background: var(--grey-strips-pressed), var(--screen-2); box-shadow: var(--grey-sunk); }
/* Menu rows and switch rows (the current menu item keeps its gold face and orange edge) */
.nav-item:not([aria-current]), .switch-row { background: var(--grey-strips), var(--screen-2); box-shadow: var(--grey-raise); }
.nav-item:not([aria-current]):hover, .nav-item:not([aria-current]):focus-visible, .switch-row:hover { background: var(--grey-strips), #262a33; }
.nav-item:not([aria-current]):active, .switch-row:active { background: var(--grey-strips-pressed), var(--screen-2); box-shadow: var(--grey-sunk); }

/* Event details popup: one static image (frame 3); no float, no cross-fade. Map event pins are unaffected. */
.event-hero { animation: none; }
.event-hero .event-hero-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; image-rendering: auto; }

/* ==========================================================================================
   The same lit-from-top-left texture on the remaining flat controls (shared ramps, palettes unchanged)
   ========================================================================================== */
:root {
  /* cream family (tiles, map zoom): white light along the top, cream shade along the bottom and right */
  --cream-ramps: var(--drs-paper-down) 0 0 / 8px 16px repeat-x, var(--drs-cream-up) 0 100% / 8px 16px repeat-x, var(--drs-cream-left) 100% 0 / 16px 8px repeat-y;
  --cream-ramps-pressed: var(--drs-cream-down) 0 0 / 8px 16px repeat-x, var(--drs-paper-up) 0 100% / 8px 16px repeat-x, var(--drs-cream-right) 0 0 / 16px 8px repeat-y;
  /* gold family, small controls */
  --gold-strips: var(--dt-hi-50) 0 0 / 8px 4px repeat-x, var(--dt-lo-75) 0 100% / 8px 4px repeat-x;
  --gold-strips-pressed: var(--dt-lo-75) 0 0 / 8px 4px repeat-x, var(--dt-hi-50) 0 100% / 8px 4px repeat-x;
}
/* cream tiles: Recent, menu, sound */
.tile, .dock .recent-btn { background: var(--cream-ramps), var(--tile); }
.tile:hover, .dock .recent-btn:hover { background: var(--cream-ramps), #fff; }
.tile:active, .dock .recent-btn:active { background: var(--cream-ramps-pressed), var(--tile); }
.tile:disabled { background: var(--tile); opacity: 0.5; cursor: default; }
/* map zoom buttons */
.leaflet-bar a, .leaflet-touch .leaflet-bar a { background: var(--dt-paper-75) 0 0 / 8px 4px repeat-x, var(--dt-cream-75) 0 100% / 8px 4px repeat-x, var(--tile); }
.leaflet-bar a:hover { background: var(--dt-paper-75) 0 0 / 8px 4px repeat-x, var(--dt-cream-75) 0 100% / 8px 4px repeat-x, #fff; }
.leaflet-bar a:active { background: var(--dt-cream-75) 0 0 / 8px 4px repeat-x, var(--dt-paper-75) 0 100% / 8px 4px repeat-x, var(--tile); }
.leaflet-bar a.leaflet-disabled { background: var(--tile); color: #8a8578; opacity: 0.6; cursor: default; }
/* mission chips (ink, gold text) take the grey ramps; the alert chip takes the gold strips */
.mission-bar button { background: var(--grey-strips), var(--ink); }
.mission-bar button:hover, .mission-bar button:focus-visible { background: var(--gold-strips), var(--gold); }
.mission-bar button:active { background: var(--grey-strips-pressed), var(--ink); }
.mission-bar .has-alert, .mission-bar .has-alert:active { background: var(--gold-strips), var(--gold); }
.mission-bar button:disabled { background: var(--ink); opacity: 0.5; }
/* retry chip */
.retry-chip { background: var(--gold-strips), var(--gold); }
.retry-chip:hover { background: var(--gold-strips), var(--gold-hi); }
.retry-chip:active { background: var(--gold-strips-pressed), var(--gold); }
.retry-chip:disabled { background: var(--gold); opacity: 0.5; }
/* clickable cards keep their gold edge stripe and gain a lit top and shaded bottom; pressed swaps them */
.feed-item, .event-row, .bounty-card, .admin-pick {
  background: var(--dt-gold-50) 0 0 / 6px 8px repeat-y, var(--dt-steel-50) 0 0 / 8px 4px repeat-x, var(--dt-ink-75) 0 100% / 8px 4px repeat-x, var(--screen-2);
}
.feed-item:hover, .event-row:hover, .bounty-card:hover, .admin-pick:hover { background-color: #262a33; }
.feed-item:active, .event-row:active, .bounty-card:active, .admin-pick:active {
  background: var(--dt-gold-50) 0 0 / 6px 8px repeat-y, var(--dt-ink-75) 0 0 / 8px 4px repeat-x, var(--dt-steel-50) 0 100% / 8px 4px repeat-x, var(--screen-2);
  box-shadow: inset 0 0 0 2px var(--gold);
}
.admin-pick.on, .admin-pick[aria-pressed="true"] { background-color: #2a2614; }
/* switch rows: disabled while saving */
.switch-row:disabled { background: var(--screen-2); box-shadow: none; opacity: 0.55; cursor: progress; }

/* ---------- admin test events: visibility tag ---------- */
.vis-tag { display: inline-block; padding: 1px 5px; font: 9px var(--f-display); letter-spacing: 0.08em; color: var(--dim); box-shadow: inset 0 0 0 2px var(--line); }
.vis-tag.on { color: var(--ink); background: var(--ok); box-shadow: none; }
.dock .recent-btn.active, .dock .recent-btn.active:hover { background: var(--gold-strips), var(--gold-hi); } /* selected (list open) */

/* ==========================================================================================
   One raised-gold system: report-flow buttons, title, top box, frame/panel edges, close buttons
   Reference: .dock .report-btn and .bounty-art (light from the top-left, dithered highlight on top,
   dithered shade along the bottom and right, clean middle for the label).
   ========================================================================================== */
:root {
  /* Short ramps (--drq-*, 8px deep, same 2px dots) for buttons too short for the Report button's 16px ramps. */
  --gold-ramps: var(--drq-hi-down) 0 0 / 8px 8px repeat-x, var(--drq-lo-up) 0 100% / 8px 8px repeat-x, var(--drq-lo-left) 100% 0 / 8px 8px repeat-y;
  --gold-ramps-pressed: var(--drq-lo-down) 0 0 / 8px 8px repeat-x, var(--drq-hi-up) 0 100% / 8px 8px repeat-x, var(--drq-hi-right) 0 0 / 8px 8px repeat-y;
  --gold-raise: inset 2px 2px 0 var(--gold-hi), inset -2px -2px 0 var(--gold-lo);
  --gold-sunk: inset 2px 2px 0 var(--gold-lo), inset -2px -2px 0 var(--gold-hi);
  --charcoal: #2b2b2b; /* top box: lifts the artwork's near-black (#070808–#1b1913) off the background */
  /* Two-tone edge for 4px boxes: a solid outer step plus a dithered inner step over gold, like the frame. */
  --edge-layers:
    linear-gradient(var(--bevel-hi), var(--bevel-hi)) 0 0 / 100% 2px no-repeat border-box,
    linear-gradient(var(--bevel-hi), var(--bevel-hi)) 0 0 / 2px 100% no-repeat border-box,
    linear-gradient(var(--bevel-lo), var(--bevel-lo)) 0 100% / 100% 2px no-repeat border-box,
    linear-gradient(var(--bevel-lo), var(--bevel-lo)) 100% 0 / 2px 100% no-repeat border-box;
  --edge-under:
    var(--dt-lo-50) 0 100% / 8px 8px repeat-x border-box,
    var(--dt-lo-50) 100% 0 / 8px 8px repeat-y border-box,
    var(--dt-hi-50) 0 0 / 8px 8px border-box,
    linear-gradient(var(--gold), var(--gold)) border-box;
}

/* ---------- 1. yellow buttons (report steps, camera, sign-in, See Sighting…) ---------- */
.px-btn:not(.alt):not(.danger) {
  background: var(--gold-ramps), var(--gold);
  box-shadow: var(--px-border), var(--gold-raise);
  transition: transform 150ms var(--ease-ui), background-color 100ms, box-shadow 150ms;
}
.px-btn:not(.alt):not(.danger):hover:not(:disabled) { background: var(--gold-ramps), var(--gold-hi); transform: translateY(-2px); }
.px-btn:not(.alt):not(.danger):focus-visible:not(:disabled) { transform: translateY(-2px); }
.px-btn:not(.alt):not(.danger):active:not(:disabled) {
  background: var(--gold-ramps-pressed), var(--gold); box-shadow: var(--px-border), var(--gold-sunk); transform: translateY(2px);
}
.px-btn:not(.alt):not(.danger)[aria-pressed="true"], .px-btn:not(.alt):not(.danger).on {
  background: var(--gold-ramps-pressed), var(--gold-hi); box-shadow: var(--px-border), var(--gold-sunk), inset 0 -3px 0 var(--accent); /* selected */
}
.px-btn:not(.alt):not(.danger):disabled { background: var(--gold); box-shadow: var(--px-border); opacity: 0.45; transform: none; }
/* Busy (submitting): keep the moving stripes on top of the texture. */
.px-btn:not(.alt):not(.danger).loading {
  opacity: 1; background: repeating-linear-gradient(45deg, rgba(0, 0, 0, 0.15) 0 8px, transparent 8px 16px) 0 0 / 23px 23px, var(--gold-ramps), var(--gold);
  animation: stripes 0.5s linear infinite;
}
@keyframes stripes { to { background-position: 23px 0, 0 0, 0 100%, 100% 0, 0 0; } }
@media (prefers-reduced-motion: reduce) {
  .px-btn:not(.alt):not(.danger), .px-btn:not(.alt):not(.danger):hover:not(:disabled), .px-btn:not(.alt):not(.danger):active:not(:disabled) { transform: none; transition: none; }
}

/* ---------- 2. title: lit top, gold face, shaded base, dithered steps between ---------- */
.plaque h1 { text-shadow: none; }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .plaque h1 > span:not(.knightro-window) {
    color: transparent; -webkit-text-fill-color: transparent;
    background:
      var(--dt-hi-50) 0 38% / 8px 4px repeat-x,
      var(--dt-lo-50) 0 72% / 8px 4px repeat-x,
      linear-gradient(var(--gold-hi) 0 40%, var(--gold) 40% 70%, var(--gold-lo) 70%);
    -webkit-background-clip: text; background-clip: text;
    /* Two crisp shade steps down-right (no blur, no outline), so letter shapes stay clean. */
    filter: drop-shadow(1px 1px 0 #6e5300) drop-shadow(1px 1px 0 #141414);
    padding: 0 2px 2px 0; /* room for the shade so it is never clipped */
  }
}

/* ---------- 3 + 4. charcoal top box; frame, panels and menu share one edge ---------- */
.plaque, .panel-shell, .navigation { border-color: transparent; }
.plaque { background: var(--edge-layers), linear-gradient(var(--charcoal), var(--charcoal)) padding-box, var(--edge-under); }
.panel-shell, .navigation { background: var(--edge-layers), linear-gradient(var(--screen), var(--screen)) padding-box, var(--edge-under); }
/* Outer frame face: dithered light on the top/left faces, dithered shade on the bottom/right (face only, map untouched). */
.frame::before {
  --fw: calc(var(--frame) - 8px);
  border-color: transparent;
  background:
    var(--dt-hi-50) 0 0 / 8px var(--fw) repeat-x border-box,
    var(--dt-hi-50) 0 0 / var(--fw) 8px repeat-y border-box,
    var(--dt-lo-50) 0 100% / 8px var(--fw) repeat-x border-box,
    var(--dt-lo-50) 100% 0 / var(--fw) 8px repeat-y border-box,
    linear-gradient(var(--gold), var(--gold)) 0 0 / 100% var(--fw) no-repeat border-box,
    linear-gradient(var(--gold), var(--gold)) 0 100% / 100% var(--fw) no-repeat border-box,
    linear-gradient(var(--gold), var(--gold)) 0 0 / var(--fw) 100% no-repeat border-box,
    linear-gradient(var(--gold), var(--gold)) 100% 0 / var(--fw) 100% no-repeat border-box;
}

/* ---------- 5. close / back buttons: lift and press, never rotate ---------- */
.x, #panel-close { transform: none; transition: transform 150ms var(--ease-ui), box-shadow 150ms var(--ease-ui), background-color 100ms; }
.x { box-shadow: var(--grey-raise), 0 2px 0 var(--ink); }
.x:hover, .x:focus-visible, #panel-close:hover, #panel-close:focus-visible { transform: translateY(-2px); box-shadow: var(--grey-raise), 0 4px 0 var(--ink); }
.x:active, #panel-close:active { transform: translateY(1px); box-shadow: var(--grey-sunk); }
@media (max-width: 720px) {
  #panel-close { background: var(--gold-ramps), var(--gold); box-shadow: var(--gold-raise), 0 2px 0 var(--ink); }
  #panel-close:hover, #panel-close:focus-visible { background: var(--gold-ramps), var(--gold-hi); box-shadow: var(--gold-raise), 0 4px 0 var(--ink); }
  #panel-close:active { background: var(--gold-ramps-pressed), var(--gold); box-shadow: var(--gold-sunk); }
}
@media (prefers-reduced-motion: reduce) {
  .x, #panel-close { transition: none; }
  .x:hover, .x:focus-visible, .x:active, #panel-close:hover, #panel-close:focus-visible, #panel-close:active { transform: none; } /* shading still shows the press */
}

/* ==========================================================================================
   Pixel typography, charcoal icon surfaces, retro count badges, demo-data controls
   ========================================================================================== */
/* ---------- type: every interface face is a pixel font ---------- */
/* Display: Silkscreen. Body: Pixelify Sans. Numbers: VT323, a monospaced pixel face whose 0/8, 1/7, 5/S and 6/b
   stay distinct (the reason Space Mono was used before), with equal-width digits so timers and columns line up. */
:root { --f-num: 'VT323', 'Silkscreen', ui-monospace, monospace; }
button, input, select, textarea { font-family: inherit; } /* form controls otherwise fall back to the system font */
.num { font-weight: 400; font-size: 1.35em; line-height: 0.85; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; }
.mission-bar .num { font-size: 1.6em; }
.status .num, .fresh-note .num, .label .num, .ticker .num, .px-btn .num, .report-btn .num { font-size: 1.45em; line-height: 0.8; }
input[type="number"], #account-code { font-weight: 400; font-size: 22px; letter-spacing: 0.04em; }
.kt-pin .age, .asset-pin .age { font: 400 14px/1 var(--f-num); letter-spacing: 0.03em; padding: 2px 4px 1px; }
.bounty-clock { font: 400 20px var(--f-num); letter-spacing: 0.02em; }
.leaderboard .rank { font: 400 20px/1 var(--f-num); }
.bounty-art { font: 400 32px/1 var(--f-num); letter-spacing: 0; padding-top: 0; }
.bounty-multiplier { font: 400 26px var(--f-num); letter-spacing: 0; }
.stat-value { font-size: 36px; }

/* ---------- charcoal: icon and button containers match the title box (artwork untouched) ---------- */
.mission-bar button { background: var(--grey-strips), var(--charcoal); }
.mission-bar button:active { background: var(--grey-strips-pressed), var(--charcoal); }
.mission-bar button:disabled { background: var(--charcoal); }
.status { background: rgba(43, 43, 43, 0.94); }
.nav-ico { background-color: var(--charcoal); }
.empty-state img, .empty img { background: var(--dt-lo-25) 0 0 / var(--ds), var(--charcoal); }
.empty img.empty-art { background: var(--charcoal); }
.leaderboard .rank { background-color: var(--charcoal); }
.camera-flip { background: rgba(43, 43, 43, 0.9); }
.kt-pin .age, .asset-pin .age { background: var(--charcoal); }
.panel-head { background: var(--charcoal); }

/* ---------- count badges (Recent, map stacks): one shared retro block ---------- */
.badge, .stack-count {
  display: grid; place-items: center; box-sizing: border-box; min-width: 24px; height: 24px; padding: 1px 6px 0;
  border: 0; border-radius: 0; text-align: center; white-space: nowrap;
  font: 400 19px/1 var(--f-num); letter-spacing: 0; font-variant-numeric: tabular-nums; color: var(--ink); text-shadow: none;
  /* Orange accent face, light edge up-left, ember edge down-right, a dithered step only along the bottom (under the digits). */
  background: var(--dt-ember-50) 0 100% / 8px 4px repeat-x, var(--accent);
  box-shadow: 0 0 0 2px var(--ink), inset 2px 2px 0 #ffb3a8, inset -2px -2px 0 #a8392c;
}
.badge { top: -12px; right: -12px; }
.stack-count { top: -8px; right: -12px; }
.badge.pop { animation: badgeNudge 240ms steps(2, end); } /* small lift when the count changes */
@keyframes badgeNudge { 50% { transform: translateY(-3px); } }
@media (prefers-reduced-motion: reduce) { .badge.pop { animation: none; } }

/* ---------- admin demo data ---------- */
.demo-card { display: grid; gap: 8px; }
.demo-vis { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.demo-vis .label { flex-basis: 100%; }
.demo-tag { background: var(--accent); }
.badge[hidden], .stack-count[hidden] { display: none; } /* zero count: keep the badge hidden */
/* Digits everywhere: a digits-only alias of VT323 placed first in the display and body stacks, so every 0-9 in the
   app (including plain sentences) uses the clear pixel numerals, while letters keep Silkscreen / Pixelify Sans.
   size-adjust brings VT323's small digits up to the letter height. Same file the Google Fonts link already loads. */
@font-face {
  font-family: 'KT Digits'; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(https://fonts.gstatic.com/s/vt323/v18/pxiKyp0ihIEF2isfFJU.woff2) format('woff2');
  unicode-range: U+0030-0039; size-adjust: 135%;
}
:root {
  --f-display: 'KT Digits', 'Silkscreen', 'Courier New', monospace;
  --f-body: 'KT Digits', 'Pixelify Sans', 'Trebuchet MS', system-ui, sans-serif;
}
@media (max-width: 720px) { .badge { top: -10px; right: -6px; } } /* phones: keep the Recent badge clear of the 8-10px frame */
