/* App Tick dark theme
   Chart ink follows the validated dark palette: series blue #3987e5 on the
   panel surface, status green/red only for rank deltas, always paired with an
   arrow glyph and a signed number so direction never rests on hue alone. */

:root {
  --bg: #08090c;
  --bg-elev: #0d0f14;
  --panel: #101318;
  --panel-2: #151922;
  --panel-3: #1b202a;
  --line: #222835;
  --line-soft: #1a1f29;
  --ink: #f4f6fa;
  --ink-2: #c2c9d6;
  --muted: #8b94a6;
  --faint: #626c7e;
  --accent: #3987e5;
  --accent-2: #6aa8f0;
  --accent-soft: rgba(57, 135, 229, 0.14);
  --good: #0ca30c;
  --good-soft: rgba(12, 163, 12, 0.13);
  --bad: #d03b3b;
  --bad-soft: rgba(208, 59, 59, 0.13);
  --warn: #fab219;
  --radius: 14px;
  --radius-sm: 10px;
  --shadow: 0 1px 0 rgba(255, 255, 255, 0.03) inset, 0 12px 32px rgba(0, 0, 0, 0.45);
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Inter,
    system-ui, Roboto, "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  color-scheme: dark;
}

body {
  margin: 0;
  background:
    radial-gradient(1200px 600px at 78% -10%, rgba(57, 135, 229, 0.10), transparent 60%),
    radial-gradient(900px 500px at 8% 0%, rgba(106, 168, 240, 0.06), transparent 55%),
    var(--bg);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  min-height: 100vh;
  min-height: 100dvh;
  padding-bottom: env(safe-area-inset-bottom);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent-2); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { margin: 0; font-weight: 650; letter-spacing: -0.015em; }
h1 { font-size: 1.55rem; }
h2 { font-size: 1.05rem; }
h3 { font-size: 0.95rem; }

/* ------------------------------------------------------------ top bar */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(8, 9, 12, 0.86);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--line-soft);
  padding-top: env(safe-area-inset-top);
}

.topbar-inner {
  max-width: 1360px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px max(16px, env(safe-area-inset-left)) 10px max(16px, env(safe-area-inset-right));
  min-height: 56px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 680;
  letter-spacing: -0.02em;
  color: var(--ink);
  font-size: 1.02rem;
}
.brand:hover { text-decoration: none; }
.brand .mark {
  width: 26px;
  height: 26px;
  border-radius: 8px;
  background: linear-gradient(150deg, var(--accent-2), var(--accent) 55%, #1c5cab);
  display: grid;
  place-items: center;
  box-shadow: 0 2px 10px rgba(57, 135, 229, 0.35);
}
.brand .mark svg { width: 15px; height: 15px; display: block; }

.nav { display: flex; gap: 2px; margin-left: 8px; }
.nav a {
  color: var(--ink-2);
  padding: 7px 12px;
  border-radius: 9px;
  font-size: 0.9rem;
  font-weight: 520;
}
.nav a:hover { background: var(--panel-2); text-decoration: none; color: var(--ink); }
.nav a.active { background: var(--panel-3); color: var(--ink); }

.spacer { flex: 1; }

.userchip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 6px 5px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  font-size: 0.84rem;
  color: var(--ink-2);
}
.userchip .avatar {
  width: 24px; height: 24px; border-radius: 50%;
  background: linear-gradient(150deg, #2f3a4d, #1b2230);
  display: grid; place-items: center;
  font-size: 0.72rem; font-weight: 700; color: var(--ink);
  border: 1px solid var(--line);
}

.navtoggle {
  display: none;
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--ink);
  width: 40px; height: 40px;
  border-radius: 10px;
  align-items: center; justify-content: center;
  cursor: pointer;
}

/* ------------------------------------------------------------ layout */

.page {
  max-width: 1360px;
  margin: 0 auto;
  padding: 22px max(16px, env(safe-area-inset-left)) 60px max(16px, env(safe-area-inset-right));
}

.pagehead {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 14px;
  margin-bottom: 18px;
}
.pagehead .titles { min-width: 0; }
.pagehead .sub {
  color: var(--muted);
  font-size: 0.87rem;
  margin-top: 5px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}
.pagehead .actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

.panel {
  background: linear-gradient(180deg, var(--panel), var(--bg-elev));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.panel + .panel { margin-top: 18px; }
.panel-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line-soft);
}
.panel-head .hint { color: var(--muted); font-size: 0.82rem; }
.panel-body { padding: 16px; }

/* ------------------------------------------------------------ controls */

.filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px;
  padding: 14px;
}

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field.compact .btn { width: auto; justify-self: start; }
.field label {
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 640;
}

select, input[type="text"], input[type="password"], input[type="number"], input[type="search"] {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  font-size: 16px; /* keeps iOS from zooming the page on focus */
  font-family: inherit;
  color: var(--ink);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  appearance: none;
  -webkit-appearance: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
select {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%238b94a6' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px;
  padding-right: 34px;
}
select:focus, input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
::placeholder { color: var(--faint); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 44px;
  padding: 0 15px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--ink);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 560;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.08s ease;
}
.btn:hover { background: var(--panel-3); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  border-color: #2a6fc4;
  color: #fff;
  box-shadow: 0 6px 18px rgba(57, 135, 229, 0.25);
}
.btn-primary:hover { filter: brightness(1.06); background: linear-gradient(180deg, var(--accent-2), var(--accent)); }
.btn-danger { color: #ff9a9a; border-color: #3a2027; background: #1c1317; }
.btn-danger:hover { background: #24171c; }
.btn-sm { min-height: 36px; padding: 0 11px; font-size: 0.82rem; }
.btn svg { width: 15px; height: 15px; }
.btn-block { width: 100%; }

.star {
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  width: 38px; height: 38px;
  border-radius: 9px;
  display: inline-grid; place-items: center;
  cursor: pointer;
}
.star:hover { background: var(--panel-2); color: var(--ink-2); }
.star.on { color: var(--warn); }
.star svg { width: 17px; height: 17px; }

/* Row level shortcut to the App Store listing: a compact square button that
   leads the app cell, so it lines up in its own column left of every icon. */
.storebtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: none;
  border: 1px solid rgba(57, 135, 229, 0.3);
  border-radius: 9px;
  background: var(--accent-soft);
  color: var(--accent-2);
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.storebtn:hover, .storebtn:focus-visible {
  text-decoration: none;
  color: #fff;
  border-color: #2a6fc4;
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
}
.storebtn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }
.storebtn svg { width: 15px; height: 15px; flex: none; }
/* Keeps the icons aligned when a row has no store link. */
.storebtn-blank { width: 32px; height: 32px; flex: none; }

/* ------------------------------------------------- searchable country picker */

.combo { position: relative; }
/* The native select still submits the value; JavaScript hides it visually. */
.combo .combo-native {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  overflow: hidden;
}

.combo-button {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  padding: 10px 34px 10px 12px;
  font: inherit;
  font-size: 16px;
  text-align: left;
  color: var(--ink);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%238b94a6' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.combo-button:hover { border-color: #2c3342; }
.combo-button:focus-visible,
.combo.is-open .combo-button {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.combo-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.combo-panel {
  position: absolute;
  z-index: 60;
  top: calc(100% + 6px);
  left: 0;
  min-width: 100%;
  width: max-content;
  max-width: 340px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
  overflow: hidden;
}
.combo-search { padding: 10px; border-bottom: 1px solid var(--line-soft); }
.combo-input { min-height: 40px; }

.combo-list {
  list-style: none;
  margin: 0;
  padding: 6px;
  max-height: 320px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* a flex column so the closest matches can be ordered to the top */
  display: flex;
  flex-direction: column;
}
/* .combo-option sets display, which would otherwise beat the [hidden] rule */
.combo [hidden] { display: none !important; }
.combo-group {
  padding: 9px 10px 5px;
  font-size: 0.68rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 680;
}
.combo-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px;
  min-height: 42px;
  border-radius: 9px;
  color: var(--ink-2);
  font-size: 0.92rem;
  cursor: pointer;
  white-space: nowrap;
}
.combo-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combo-option .combo-code {
  margin-left: auto;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}
.combo-option:hover, .combo-option.is-active { background: var(--panel-2); color: var(--ink); }
.combo-option.is-selected { background: var(--accent-soft); color: var(--accent-2); }
.combo-option.is-selected .combo-code { color: var(--accent-2); }
.combo-empty { margin: 0; padding: 16px 12px; color: var(--muted); font-size: 0.86rem; }

.combo-backdrop { display: none; }

@media (max-width: 700px) {
  /* A half width dropdown cannot hold a country name, so the picker opens as
     a sheet across the viewport instead. */
  /* Hangs from the top of the visible area so the on screen keyboard can
     never cover the results; app.js keeps it inside the visual viewport. */
  .combo-panel {
    position: fixed;
    top: calc(env(safe-area-inset-top) + 8px);
    bottom: auto;
    left: 8px;
    right: 8px;
    width: auto;
    min-width: 0;
    max-width: none;
    border-radius: 16px;
  }
  .combo-list { max-height: 60vh; overscroll-behavior: contain; }
  .combo-option { min-height: 46px; font-size: 0.98rem; }
  .combo-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 55;
    background: rgba(4, 5, 7, 0.6);
  }
  .combo-panel { z-index: 56; }
}

/* ------------------------------------------------------------ chips, flash */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--ink-2);
  font-size: 0.76rem;
  font-weight: 540;
  white-space: nowrap;
}
.chip.accent { background: var(--accent-soft); border-color: rgba(57,135,229,0.3); color: var(--accent-2); }
.chip.good { background: var(--good-soft); border-color: rgba(12,163,12,0.32); color: #5ed25e; }
.chip.warn { background: rgba(250,178,25,0.12); border-color: rgba(250,178,25,0.3); color: #f5c451; }
.chip.bad { background: var(--bad-soft); border-color: rgba(208,59,59,0.32); color: #ef8080; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

.flash {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid rgba(12, 163, 12, 0.3);
  background: var(--good-soft);
  color: #9ae79a;
  margin-bottom: 16px;
  font-size: 0.9rem;
}
.flash.error { border-color: rgba(208, 59, 59, 0.35); background: var(--bad-soft); color: #f0a3a3; }
.flash.info { border-color: rgba(57,135,229,0.3); background: var(--accent-soft); color: var(--accent-2); }

/* ------------------------------------------------------------ stat tiles */

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  gap: 12px;
  margin: 16px 0 18px;
}
.tile {
  background: linear-gradient(180deg, var(--panel), var(--bg-elev));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 15px;
}
.tile .label {
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 640;
}
.tile .value {
  font-size: 1.7rem;
  font-weight: 660;
  letter-spacing: -0.02em;
  margin-top: 6px;
  line-height: 1.1;
}
.tile .value.up { color: #5ed25e; }
.tile .value.down { color: #ef8080; }
.tile .foot { color: var(--muted); font-size: 0.78rem; margin-top: 4px; }

/* ------------------------------------------------------------ movers */

.movers { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 18px; }
.movercol { background: linear-gradient(180deg, var(--panel), var(--bg-elev)); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.movercol h3 { padding: 12px 14px; border-bottom: 1px solid var(--line-soft); font-size: 0.8rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); display: flex; align-items: center; gap: 7px; }
.moverrow { display: flex; align-items: center; gap: 10px; padding: 9px 14px; border-bottom: 1px solid var(--line-soft); }
.moverrow:last-child { border-bottom: none; }
.moverrow img { width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--line); flex: none; }
.moverrow .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.87rem; color: var(--ink); }
.moverrow .mv { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 620; font-size: 0.84rem; white-space: nowrap; }
.moverrow .mv.up { color: #5ed25e; }
.moverrow .mv.down { color: #ef8080; }
.moverrow .to { color: var(--faint); font-size: 0.78rem; font-variant-numeric: tabular-nums; }

@media (max-width: 700px) { .movers { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------ chart table */

.tablewrap { overflow-x: auto; }
/* The rankings table must NOT sit in a scroll container: that would make the
   sticky header stick to the wrapper instead of the viewport. */
.chartwrap { overflow: visible; }

table.chart {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}
table.chart thead th {
  position: sticky;
  top: 56px;
  z-index: 5;
  background: var(--panel-2);
  text-align: left;
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 680;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
table.chart tbody td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}
table.chart tbody tr:hover td { background: rgba(255, 255, 255, 0.022); }
table.chart tbody tr:last-child td { border-bottom: none; }

.rank {
  font-variant-numeric: tabular-nums;
  font-weight: 660;
  color: var(--ink);
  width: 64px;
  white-space: nowrap;
}
.rank .hash { color: var(--faint); font-weight: 500; letter-spacing: -0.04em; }
.rank.top3 { color: var(--accent-2); }

.delta {
  font-variant-numeric: tabular-nums;
  font-size: 0.82rem;
  font-weight: 620;
  white-space: nowrap;
  width: 74px;
  color: var(--faint);
}
.delta.up { color: #5ed25e; }
.delta.down { color: #ef8080; }
.delta.new { color: var(--warn); }

.appcell { display: flex; align-items: center; gap: 11px; min-width: 0; }
.icon {
  width: 40px; height: 40px;
  border-radius: 10px;
  object-fit: cover;
  background: var(--panel-3);
  border: 1px solid var(--line);
  flex: none;
}
.icon.lg { width: 76px; height: 76px; border-radius: 18px; }
.appcell .meta { min-width: 0; }
.appcell .name {
  font-weight: 580;
  color: var(--ink);
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 44ch;
}
.appcell .name:hover { color: var(--accent-2); text-decoration: none; }
.appcell .dev {
  /* block, because overflow and max-width do nothing on an inline element:
     a long developer name used to run straight past the card */
  display: block;
  color: var(--muted);
  font-size: 0.79rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 40ch;
}
.mutedcell { color: var(--ink-2); white-space: nowrap; }
.cellactions { display: flex; align-items: center; gap: 6px; justify-content: flex-end; }

.empty {
  padding: 46px 20px;
  text-align: center;
  color: var(--muted);
}
.empty .big { font-size: 1.05rem; color: var(--ink-2); margin-bottom: 6px; font-weight: 560; }

/* ------------------------------------------------------------ app detail */

.apphero { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.apphero .meta { min-width: 0; flex: 1; }
.apphero h1 { font-size: 1.35rem; }
.badges { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px; }

.sparkbox { position: relative; }
.spark { width: 100%; height: 190px; display: block; }
.spark .line { vector-effect: non-scaling-stroke; }
.sparkaxis {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 2px 0;
  pointer-events: none;
  font-size: 0.72rem;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}
.spark .grid { stroke: #2c2c2a; stroke-width: 1; }
.spark .line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.spark .area { fill: url(#sparkfill); }
.spark .now { fill: var(--accent); }
.spark .pt { fill: var(--accent); stroke: var(--panel); stroke-width: 2; }

.ranklist { display: grid; gap: 8px; }
.rankrow {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  font-size: 0.88rem;
}
.rankrow .pos {
  font-variant-numeric: tabular-nums;
  font-weight: 660;
  margin-left: auto;
  color: var(--ink);
}
.rankrow .where { color: var(--ink-2); }
.rankrow .when { color: var(--faint); font-size: 0.76rem; }

.desc { color: var(--ink-2); font-size: 0.9rem; white-space: pre-wrap; line-height: 1.6; }

/* ------------------------------------------------------------ auth pages */

.authwrap {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 28px max(18px, env(safe-area-inset-left)) 40px max(18px, env(safe-area-inset-right));
}
.authcard {
  width: 100%;
  max-width: 400px;
  background: linear-gradient(180deg, var(--panel), var(--bg-elev));
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 26px 22px;
  box-shadow: var(--shadow);
}
.authcard .brand { font-size: 1.15rem; margin-bottom: 18px; }
.authcard h1 { font-size: 1.2rem; }
.authcard p.lede { color: var(--muted); font-size: 0.88rem; margin: 6px 0 18px; }
.authcard .field { margin-bottom: 13px; }
.authfoot { color: var(--faint); font-size: 0.82rem; text-align: center; margin-top: 16px; }

/* ------------------------------------------------------------ admin */

.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; }
.stack { display: grid; gap: 13px; }
.stack > .btn { justify-self: start; }

.keyrow {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
}
.keyrow code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9rem;
  color: var(--ink);
  letter-spacing: 0.06em;
}

table.data { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
table.data th {
  text-align: left;
  font-size: 0.68rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 680;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
table.data td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--line-soft);
  color: var(--ink-2);
  vertical-align: middle;
}
table.data tr:last-child td { border-bottom: none; }
table.data .inline { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.switch { display: flex; align-items: center; gap: 9px; font-size: 0.88rem; color: var(--ink-2); }
.switch input { width: 18px; height: 18px; accent-color: var(--accent); }

.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.8rem; }
.nowrap { white-space: nowrap; }
.muted { color: var(--muted); }
.tiny { font-size: 0.78rem; }

/* ------------------------------------------------------------ mobile */

@media (max-width: 900px) {
  .nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 2px;
    background: var(--bg-elev);
    border-bottom: 1px solid var(--line);
    padding: 8px max(12px, env(safe-area-inset-left));
    margin: 0;
    display: none;
    box-shadow: 0 18px 30px rgba(0, 0, 0, 0.5);
  }
  .nav.open { display: flex; }
  .nav a { padding: 12px 14px; font-size: 0.98rem; }
  .navtoggle { display: inline-flex; }
  .userchip .uname { display: none; }
  h1 { font-size: 1.3rem; }
  .pagehead .actions { margin-left: 0; width: 100%; }
  .pagehead .actions form { flex: 1; margin: 0; }
  .pagehead .actions form .btn { width: 100%; }
  .pagehead .sep { display: none; }
  .apphero .actions { width: 100%; }
  .apphero .actions form, .apphero .actions .btn { flex: 1; width: 100%; }
  .pagehead .actions .btn { flex: 1; }
}

@media (max-width: 860px) {
  /* The rankings table becomes a card list: same markup, different geometry. */
  table.chart, table.chart tbody, table.chart tr, table.chart td { display: block; width: 100%; }
  table.chart thead { display: none; }
  table.chart tbody tr {
    position: relative;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm);
    background: var(--panel-2);
    margin-bottom: 9px;
    /* right padding keeps the title clear of the watchlist star */
    padding: 11px 56px 11px 60px;
    min-height: 62px;
  }
  table.chart tbody tr:hover td { background: transparent; }
  table.chart tbody td { border: none; padding: 0; }
  table.chart td.rank {
    position: absolute;
    left: 12px;
    top: 12px;
    width: 40px;
    font-size: 0.95rem;
    text-align: left;
  }
  table.chart td.delta {
    position: absolute;
    left: 12px;
    top: 36px;
    width: 44px;
    font-size: 0.72rem;
  }
  table.chart td.c-cat, table.chart td.c-price { display: inline-block; width: auto; margin-top: 7px; }
  table.chart td.c-cat::after { content: "·"; color: var(--faint); margin: 0 7px; }
  table.chart td.c-cat, table.chart td.c-price { font-size: 0.8rem; color: var(--muted); }
  table.chart td.cellwrap-actions {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    width: auto;
  }
  /* Truncate against the real column width. A 100vw based max-width feeds
     back on itself: an overflow widens the layout viewport, which widens the
     max-width, and the phone ends up rendering the whole page zoomed out. */
  table.chart td.c-app { min-width: 0; }
  .appcell { min-width: 0; }
  .appcell .meta { flex: 1 1 auto; min-width: 0; }
  .appcell .name, .appcell .dev { max-width: 100%; }
  .icon { width: 36px; height: 36px; border-radius: 9px; }
  .appcell { gap: 9px; }
  .storebtn, .storebtn-blank { width: 36px; height: 36px; }
  .storebtn svg { width: 16px; height: 16px; }
  .star { width: 40px; height: 40px; }
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
  .tiles > .tile:last-child:nth-child(odd) { grid-column: span 2; }
  .tile { padding: 12px; }
  .tile .value { font-size: 1.4rem; }
  .panel-body { padding: 13px; }
  .filters { grid-template-columns: 1fr 1fr; gap: 10px; padding: 12px; }
  .filters .field.wide { grid-column: 1 / -1; }
  .chartwrap { overflow: visible; }
}

@media (max-width: 380px) {
  .filters { grid-template-columns: 1fr; }
  .appcell .name { font-size: 0.92rem; }
  .spark { height: 150px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ------------------------------------------------------------ idea finder */

.btn[disabled] { opacity: 0.55; cursor: not-allowed; filter: none; }

.scanpanel { margin-bottom: 16px; }
.scanline { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.progress { height: 6px; border-radius: 999px; background: var(--panel-3); overflow: hidden; }
.progress span {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width 0.4s ease;
}

/* Footprint: one labelled cell per scanned market, so the gaps (where an app
   has not spread yet) read as plainly as the hits. One blue hue stepped by
   rank, lighter means stronger on this dark surface. */
.fp {
  display: inline-flex; align-items: center; justify-content: center;
  width: 12px; height: 12px; border-radius: 3px;
  background: #161a22; box-shadow: inset 0 0 0 1px #2a3140;
}
.fp.r1 { background: #86b6ef; box-shadow: none; }
.fp.r2 { background: #3987e5; box-shadow: none; }
.fp.r3 { background: #1c5cab; box-shadow: none; }
.footprint .fp {
  width: 27px; height: 20px; border-radius: 5px;
  font-size: 0.6rem; font-weight: 680; letter-spacing: 0.04em; font-style: normal;
  color: #4b5465;
}
.footprint .fp.r1 { color: #0b1a2e; }
.footprint .fp.r2 { color: #fff; }
.footprint .fp.r3 { color: #d6e6fb; }

.legend { display: flex; flex-wrap: wrap; gap: 12px; font-size: 0.76rem; color: var(--muted); }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend .fp { width: 10px; height: 10px; }

.ideas { list-style: none; margin: 0; padding: 0; }
.idea {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 18px;
  align-items: center;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line-soft);
}
.idea:last-child { border-bottom: none; }
.idea:hover { background: rgba(255, 255, 255, 0.018); }
.idea .badges { margin-top: 8px; padding-left: 43px; }
.idea-label {
  font-size: 0.68rem; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--faint); font-weight: 680; margin-bottom: 7px;
}
.wherechips { display: flex; flex-wrap: wrap; gap: 6px; }
.where-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 9px; border-radius: 9px;
  background: var(--accent-soft); border: 1px solid rgba(57, 135, 229, 0.28);
  font-size: 0.8rem; color: var(--ink-2); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
a.where-chip { transition: border-color 0.15s ease, background 0.15s ease; }
a.where-chip:hover { text-decoration: none; border-color: var(--accent); background: rgba(57, 135, 229, 0.22); }
.where-chip strong { color: var(--ink); font-weight: 680; }
.where-chip .mv { font-style: normal; font-size: 0.72rem; font-weight: 650; }
.where-chip .mv.up { color: #5ed25e; }
.where-chip .mv.down { color: #ef8080; }
.where-chip .mv.new { color: var(--warn); }
.footprint { display: flex; flex-wrap: wrap; gap: 4px; max-width: 340px; }

details.scanlist { margin-top: 18px; }
details.scanlist > summary { cursor: pointer; list-style: none; }
details.scanlist > summary::-webkit-details-marker { display: none; }
details.scanlist > summary::after { content: "Edit"; margin-left: auto; font-size: 0.8rem; color: var(--accent-2); }
details.scanlist[open] > summary::after { content: "Close"; }

@media (max-width: 900px) {
  .idea { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .idea .badges { padding-left: 0; }
  .legend { order: 3; width: 100%; }
}
@media (max-width: 860px) {
  .idea .appcell .name, .idea .appcell .dev { max-width: 100%; }
}
.scanline:has(+ .progress[hidden]) { margin-bottom: 0; }

/* Arriving from an Idea finder chip: land on the app's row, clear of the
   sticky header, and mark it. */
table.chart tbody tr[id] { scroll-margin-top: 110px; }
table.chart tbody tr:target td { background: rgba(57, 135, 229, 0.12); }
table.chart tbody tr:target td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
@media (max-width: 860px) {
  table.chart tbody tr:target { border-color: var(--accent); background: rgba(57, 135, 229, 0.12); }
  table.chart tbody tr:target td { background: transparent; box-shadow: none; }
}
