/* app-rankings
 *
 * The one design problem here: in a ranking, a SMALLER number is BETTER. That inversion
 * is what a non-technical reader gets wrong, and every choice below exists to remove it
 * from the page rather than explain it.
 *
 *   - Sparklines are drawn with the rank axis flipped, so a line going UP always means
 *     doing better. On a log scale, because the top ten is where the business is.
 *   - Direction is carried by GREEN (up) and RED (down), and NEVER by colour alone.
 *     Every green or red thing here sits beside an ARROW saying the same thing and a
 *     CLAUSE saying it a third time, because red/green is unreadable for about 8% of
 *     men. This replaced a dawn-blue/dusk-amber pair on 13 Sep 2026: the pair was
 *     honest, and Imran could not read it at a glance, which is the only test that
 *     matters on a page built for him. Dawn blue survives as the focus ring, dusk
 *     amber as the login warning - hence --up/--down are their OWN variables.
 *   - Every number is followed by a clause in words: "#12 - up 4 places". The number
 *     alone is never the whole message.
 *
 * Paper is cool rather than cream, deliberately away from the warm-cream-and-clay look.
 * Fraunces carries the voice and the rank figures; IBM Plex Sans does the work and keeps
 * kinship with the rest of the desk. Arabic and Bengali keywords appear on these pages,
 * so both are in the stack and keyword text sets its own direction.
 */

:root {
  --paper:   #F6F7F9;
  --card:    #FFFFFF;
  --ink:     #14161D;
  --ink-2:   #4A5160;
  --quiet:   #7E8798;
  --rule:    #E3E6EB;
  --rule-2:  #CDD4DE;
  --rise:    #1F5FA8;
  --rise-bg: rgba(31, 95, 168, .10);
  --slip:    #A8620F;
  --slip-bg: rgba(168, 98, 15, .12);
  --star:    #B8860B;
  /* DIRECTION. Green up, red down - Imran asked for exactly that on 13 Sep 2026, and
     he is the only reader of this page.

     These are NEW variables, not a redefinition of --rise/--slip, and that matters:
     --rise is also the focus ring in three places below, and --slip is also the login
     warning box and .pill.slip. Redefining them would turn keyboard focus green, which
     is not a colour decision about rankings at all. --rise and --slip stay, now meaning
     "the accent" and "the warning".

     Red/green is unreadable for about 8% of men, so COLOUR IS NEVER ALONE here. Every
     green or red thing on this site sits beside an arrow that says the same thing, and
     a clause that says it a third time ("up 3"). Take all the colour away and the page
     still reads correctly. */
  --up:      #0B7A3B;
  --up-bg:   rgba(11, 122, 59, .10);
  --down:    #B3261E;
  --down-bg: rgba(179, 38, 30, .10);

  --display: "Fraunces", Georgia, "Times New Roman", serif;
  --ui: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
        "Noto Sans Arabic", "Noto Sans Bengali", sans-serif;
  --measure: 66ch;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:   #0E1117;
    --card:    #161B23;
    --ink:     #E9EDF3;
    --ink-2:   #A6B0C0;
    --quiet:   #737F91;
    --rule:    #232B36;
    --rule-2:  #313B4A;
    --rise:    #74AEEE;
    --rise-bg: rgba(116, 174, 238, .14);
    --slip:    #DDA45C;
    --slip-bg: rgba(221, 164, 92, .14);
    --star:    #D9A93A;
    --up:      #56C98A;
    --up-bg:   rgba(86, 201, 138, .16);
    --down:    #F2857D;
    --down-bg: rgba(242, 133, 125, .16);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--ui);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }
a:focus-visible, button:focus-visible, summary:focus-visible {
  outline: 2px solid var(--rise);
  outline-offset: 3px;
  border-radius: 2px;
}

.wrap { max-width: 940px; margin: 0 auto; padding: 0 24px 96px; }
@media (max-width: 620px) { .wrap { padding: 0 16px 64px; } }

/* ---------- masthead ---------- */

.top {
  display: flex; align-items: baseline; gap: 24px; flex-wrap: wrap;
  padding: 22px 0 18px; border-bottom: 1px solid var(--rule);
}
.top .home {
  font-family: var(--display);
  font-variation-settings: "SOFT" 30, "WONK" 1, "opsz" 24;
  font-size: 21px; font-weight: 600; text-decoration: none; letter-spacing: -.01em;
}
.top nav { display: flex; gap: 18px; margin-left: auto; flex-wrap: wrap; }
.top nav a { color: var(--ink-2); text-decoration: none; font-size: 14.5px; }
.top nav a:hover, .top nav a[aria-current] { color: var(--ink); text-decoration: underline; }
.top nav a[aria-current] { font-weight: 600; }

.head { padding: 44px 0 26px; }
h1 {
  font-family: var(--display);
  font-variation-settings: "SOFT" 40, "WONK" 1, "opsz" 96;
  font-weight: 400; font-size: clamp(34px, 5.6vw, 54px); line-height: 1.06;
  letter-spacing: -.02em; margin: 0 0 10px; text-wrap: balance;
}
.head p { margin: 0; color: var(--ink-2); max-width: var(--measure); font-size: 17px; }
.stamp { color: var(--quiet); font-size: 13.5px; margin-top: 14px; }
.stamp b { font-weight: 600; color: var(--ink-2); }

.head + h2, .head + p + h2 { margin-top: 26px; }
h2 {
  font-family: var(--display);
  font-variation-settings: "SOFT" 30, "WONK" 0, "opsz" 40;
  font-weight: 400; font-size: 26px; letter-spacing: -.015em;
  margin: 44px 0 4px;
}
h2 + .note { margin: 0 0 20px; color: var(--ink-2); font-size: 15px; }

/* ---------- the app list ----------
 * A list with rules, not a deck of identical rounded cards. These are thirteen of the
 * same kind of thing; a grid of boxes would imply they are separate places to go.
 */

.list { border-top: 1px solid var(--rule); }
/* Two store lines per app, so the row STACKS: the app name, then its stores hanging
   under it. They are facts ABOUT that app, not a second column of apps. */
.row { padding: 16px 4px; border-bottom: 1px solid var(--rule); }
.row:hover { background: var(--card); }

.who { min-width: 0; display: flex; gap: 2px; align-items: center; }
.who-text { min-width: 0; }
.stores { margin: 5px 0 0 34px; }

/* A GRID, not a flex row, so the store name, the strip and the number line up down the
   whole list. That alignment IS the feature: it is what lets thirteen apps be read in
   one sweep instead of as thirteen separate sentences. */
.sline {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr) auto auto;
  align-items: center; gap: 2px 16px; padding: 4px 0; font-size: 14.5px;
}
.sline .st { color: var(--quiet); font-size: 12.5px; font-weight: 600;
             letter-spacing: .02em; white-space: nowrap; }
.sline .at { color: var(--ink-2); min-width: 0; overflow-wrap: anywhere; }
.sline .at .kw { color: var(--ink); }
.sline .at .sep { color: var(--rule-2); margin: 0 2px; }
/* Grey and italic, spanning the space the numbers would have used. NOT red: "you have
   not starred it" and "this app has no Play page" are SETTINGS, and "we could not read
   the page" is a GAP. None of the three is a decline, and the whole project exists to
   keep those apart. Same rule as .cell .noread. */
.sline .why { grid-column: 2 / -1; color: var(--quiet); font-size: 13.5px;
              font-style: italic; }
.sline .spark { width: 108px; height: 26px; }

.dir { display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap;
       justify-content: flex-end; min-width: 132px; }
/* The RANK stays ink. Thirteen rows of big green and red numerals is a Christmas tree,
   and he asked for this not to be overwhelming. Only the arrow and the phrase - the two
   things that are actually ABOUT direction - take the colour. */
.dir .n {
  font-family: var(--display);
  /* opsz IS THE OPTICAL SIZE AXIS, and it must roughly match the size actually drawn.
     This was copied from .place .n, which uses opsz 60 at 34px - and two numbers per
     row meant shrinking it to 23px while leaving the axis behind. A face cut for 60pt
     display use has hairlines to match, so at 23px they thin out to grey, and on the
     dark theme light-on-dark thins them further. Imran's dark-mode screenshot is where
     that showed. Matching the axis to the size restores the weight without shouting. */
  font-variation-settings: "SOFT" 20, "WONK" 0, "opsz" 24;
  font-size: 24px; line-height: 1; font-weight: 500; color: var(--ink);
  font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}
.dir .n .hash { font-size: 14px; color: var(--quiet); }
.dir .short { font-size: 12.5px; font-variant-numeric: tabular-nums; min-width: 56px; }
.dir.rise .short { color: var(--up); }
.dir.slip .short { color: var(--down); }
.dir.flat .short { color: var(--quiet); }
/* Said in words for a screen reader, which cannot see an arrow or a colour. */
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden;
      clip: rect(0 0 0 0); white-space: nowrap; }
.who .name {
  font-size: 17px; font-weight: 600; letter-spacing: -.006em;
  text-decoration: none; display: inline-block; vertical-align: middle;
}
/* The star and the bell sit SIDE BY SIDE on the app-name line. Stacked was tried first
   and read wrong: the lower glyph lined up with the "best in India for ..." sentence and
   looked like it belonged to that, not to the app. Both switches answer a question about
   the APP, so both sit on the app's own line. 26px keeps two real tap targets inside the
   width a phone can spare. */
.swpair { flex: 0 0 auto; margin: -2px 3px 0 -5px; display: flex;
          align-items: center; }
.swform { display: block; }
.who .name:hover { text-decoration: underline; }
.who .where {
  color: var(--ink-2); font-size: 14.5px; margin-top: 2px;
  overflow-wrap: anywhere;
}
.who .where .kw { color: var(--ink); }

.spark { width: 148px; height: 34px; display: block; }
.spark path { fill: none; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.spark .rise { stroke: var(--up); }
.spark .slip { stroke: var(--down); }
.spark .flat { stroke: var(--quiet); }
/* Where position ten sits. Above this line is the top ten - which is the question
   people are actually asking, and a line with no reference cannot answer it. */
.spark .ten { stroke: var(--rule-2); stroke-width: 1; stroke-dasharray: 2 3; }
.spark circle.rise { fill: var(--up); stroke: none; }
.spark circle.slip { fill: var(--down); stroke: none; }
.spark circle.flat { fill: var(--quiet); stroke: none; }
/* On a phone the strip goes and the sentence shortens. Three lines per app turns a
   thirteen-item list into a scroll, and the second clause is a nice-to-know, not the
   answer to "where am I". */
/* On a phone the strip goes and the store line folds to two rows: the store name and
   the number on one, the country and search underneath. Measured at 390px. */
@media (max-width: 620px) {
  .spark { display: none; }
  .wide { display: none; }
  .row { padding: 14px 2px; }
  .place { min-width: 78px; }
  .place .n { font-size: 30px; }
  .stores { margin-left: 0; margin-top: 6px; }
  .sline { grid-template-columns: minmax(0, 1fr) auto; gap: 0 10px; padding: 6px 0;
           align-items: start; }
  .sline .st  { grid-column: 1; grid-row: 1; }
  .sline .at  { grid-column: 1; grid-row: 2; font-size: 13.5px; }
  .sline .why { grid-column: 1; grid-row: 2; }
  .sline .dir { grid-column: 2; grid-row: 1 / span 2; align-self: center;
                min-width: 0; }
  .dir .n { font-size: 21px; }
  .dir .short { min-width: 0; }
}

.place { text-align: right; min-width: 92px; }
.place .n {
  font-family: var(--display);
  font-variation-settings: "SOFT" 20, "WONK" 0, "opsz" 60;
  font-size: 34px; line-height: 1; font-weight: 400;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
  display: block;
}
.place .n .hash { font-size: 20px; color: var(--quiet); }
.place .move { font-size: 13px; margin-top: 3px; display: block; }
/* The shape that carries the meaning when the colour cannot. Scoped loosely on purpose:
   the grid has its own .cell .arrow sizing, and everywhere else wants this one. */
.arrow { font-size: 11px; line-height: 1; }
.arrow.rise { color: var(--up); }
.arrow.slip { color: var(--down); }
.arrow.flat { color: var(--quiet); }
td.nowrap { white-space: nowrap; }
/* A chart we read and were not in. Quiet, never red: not being in a top forty is not a
   fall, and most of these rows will say exactly that for a long time. */
tr.quietrow td { color: var(--quiet); }
.quiet { color: var(--quiet); font-weight: 400; }
b.up { color: var(--up); }
b.down { color: var(--down); }
.move.rise { color: var(--up); }
.move.slip { color: var(--down); }
.move.flat { color: var(--quiet); }
.place .none { font-size: 15px; color: var(--quiet); font-family: var(--ui); }

/* ---------- switches ---------- */

.switches { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 20px; }
.toggle {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: 14.5px; cursor: pointer;
  padding: 7px 14px; border-radius: 999px;
  border: 1px solid var(--rule-2); background: none; color: var(--quiet);
}
.toggle span { font-size: 13px; filter: grayscale(1); opacity: .55; }
.toggle.on { border-color: var(--star); color: var(--ink); }
.toggle.on span { filter: none; opacity: 1; }
.toggle:hover { border-color: var(--ink-2); color: var(--ink); }
.switch-note { margin: 10px 0 0; color: var(--quiet); font-size: 14px; max-width: var(--measure); }
.sw { border: 0; background: none; padding: 0; cursor: pointer; line-height: 1;
      font-size: 15px; color: var(--rule-2);
      width: 26px; height: 26px; display: flex; align-items: center;
      justify-content: center; border-radius: 7px; }
.sw.on { color: var(--star); }
.sw:hover { color: var(--star); background: var(--card); }
.sw:focus-visible { outline: 2px solid var(--star); outline-offset: 1px; }
/* The bell is an emoji, so `color` cannot touch it - grey it out the way the worded
   toggles on the app page already do, and keep the struck-through glyph as the real
   signal. Same trick as `.toggle span`. */
.sw.bell { font-size: 13px; filter: grayscale(1); opacity: .4; }
.sw.bell.on { filter: none; opacity: 1; }
.sw.bell:hover { opacity: .9; }

/* ---------- tables ---------- */

table { width: 100%; border-collapse: collapse; font-size: 15px; }
th {
  text-align: left; font-weight: 600; font-size: 13.5px; color: var(--quiet);
  padding: 0 12px 8px 0; border-bottom: 1px solid var(--rule-2);
}
td { padding: 11px 12px 11px 0; border-bottom: 1px solid var(--rule); vertical-align: middle; }
td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.scroll { overflow-x: auto; }

.kw { overflow-wrap: anywhere; }
[dir="rtl"] { text-align: right; }

/* ---------- small parts ---------- */

.pill {
  display: inline-block; padding: 1px 8px; border-radius: 999px;
  font-size: 12.5px; background: var(--rise-bg); color: var(--rise);
}
.pill.slip { background: var(--slip-bg); color: var(--slip); }
.pill.quiet { background: none; color: var(--quiet); border: 1px solid var(--rule-2); }

.empty {
  padding: 34px 0; color: var(--ink-2); max-width: var(--measure);
  border-top: 1px solid var(--rule);
}
.empty b { color: var(--ink); }

.more { display: inline-block; margin-top: 22px; font-size: 15px; color: var(--ink-2); }

.legend {
  margin-top: 30px; padding-top: 18px; border-top: 1px solid var(--rule);
  color: var(--quiet); font-size: 13.5px; max-width: var(--measure);
}

.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 0 32px; }

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

/* ---------- signing in ----------
 * A single card on the paper, not a full-width page: a login screen is one small
 * decision and giving it 940px of chrome makes it look like a form to fill in rather
 * than a door to open. Replaced the browser's own grey box on 2026-09-08.
 *
 * 16px on the two inputs is not a style choice - iOS Safari zooms the whole page in on
 * any focused field smaller than that, and the zoom does not come back out.
 */

body.signin {
  display: flex; align-items: center; justify-content: center;
  min-height: 100dvh; padding: 24px;
}
.card-in {
  width: 100%; max-width: 380px;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 14px;
  padding: 34px 30px 28px;
}
.card-in h1 { font-size: 30px; margin: 0 0 6px; }
.card-in .sub { color: var(--ink-2); font-size: 15px; margin: 0 0 22px; }
.card-in label {
  display: block; font-size: 13px; font-weight: 600;
  color: var(--ink-2); margin: 0 0 6px; letter-spacing: .01em;
}
.card-in input {
  width: 100%; font: inherit; font-size: 16px;
  padding: 11px 12px; margin: 0 0 18px;
  color: var(--ink); background: var(--paper);
  border: 1px solid var(--rule-2); border-radius: 8px;
}
.card-in input:focus-visible { outline: 2px solid var(--rise); outline-offset: 1px; }
.card-in button {
  width: 100%; font: inherit; font-weight: 600; font-size: 15.5px;
  padding: 12px; margin-top: 4px; cursor: pointer;
  color: var(--card); background: var(--ink);
  border: 1px solid var(--ink); border-radius: 8px;
}
.card-in button:hover { background: var(--ink-2); border-color: var(--ink-2); }
.card-in .warn {
  background: var(--slip-bg); color: var(--slip);
  border: 1px solid var(--slip); border-radius: 8px;
  padding: 10px 12px; margin: 0 0 20px; font-size: 14.5px;
}
.card-in .fine { color: var(--quiet); font-size: 12.5px; margin: 18px 0 0; }

/* Sign out sits in the masthead and must not look like a fourth page to visit. */
.top nav .signout { display: inline; margin: 0; }
.top nav .signout button {
  font: inherit; font-size: 14.5px; color: var(--quiet);
  background: none; border: 0; padding: 0; cursor: pointer;
}
.top nav .signout button:hover { color: var(--ink); text-decoration: underline; }

/* ---------- the keyword x country grid ----------
 *
 * Countries scroll sideways and the search column stays put. That is the whole trick,
 * and it is done with position:sticky and overflow-x - still no script. The one script
 * this site carries flips a star or a bell and touches nothing else.
 *
 * FOUR STATES THAT MUST NOT LOOK ALIKE. "#12" is a rank. "not in top 200" means we
 * looked that far and the app was not there. "no reading" means we could not read the
 * page at all - never a drop. A faint dot means we do not run that search in that
 * country. A dashboard that drew any two of those the same way would turn a bad night
 * for Google's servers into what looks like a collapse.
 *
 * The arrow carries DIRECTION and reuses the dawn-blue/dusk-amber pair from the top of
 * this file, so it means the same thing here as it does in a sparkline.
 */

.storetabs { display: flex; gap: 8px; margin: 0 0 18px; }
.storetabs .tab {
  font-size: 14px; padding: 6px 14px; border-radius: 999px; text-decoration: none;
  color: var(--ink-2); border: 1px solid var(--rule-2); background: var(--card);
}
.storetabs .tab:hover { color: var(--ink); border-color: var(--quiet); }
.storetabs .tab.on {
  color: var(--card); background: var(--ink); border-color: var(--ink); font-weight: 600;
}

.gridwrap {
  position: relative;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--card);
  /* Nothing else on this site told a reader there was more to the right. An inset
     shadow, not a background gradient: a gradient painted a hard vertical LINE through
     the last column, which read as a border rather than as "keep going". */
  box-shadow: inset -15px 0 13px -13px var(--rule-2);
}
.gridwrap:focus-visible { outline: 2px solid var(--rise); outline-offset: 2px; }

table.grid { border-collapse: separate; border-spacing: 0; font-size: 14px; width: auto; }
table.grid th, table.grid td { border-bottom: 1px solid var(--rule); }

/* The frozen column. Without an opaque background the keyword scrolls under itself. */
table.grid .kwcol {
  position: sticky; left: 0; z-index: 2;
  background: var(--card);
  text-align: left; font-weight: 500; color: var(--ink);
  padding: 9px 14px 9px 12px;
  min-width: 148px; max-width: 210px;
  border-right: 1px solid var(--rule-2);
}
table.grid thead .kwcol { z-index: 3; }
table.grid thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--card); color: var(--quiet);
  font-size: 12px; font-weight: 600; letter-spacing: .02em;
  padding: 8px 10px; text-align: center; white-space: nowrap;
  border-bottom: 1px solid var(--rule-2);
}
table.grid th.cc .code { display: block; font-size: 11px; }
table.grid tbody tr:hover .cell { background: var(--paper); }

.cell {
  text-align: center; padding: 8px 10px; min-width: 74px; white-space: nowrap;
  vertical-align: middle;
}
.cell .n {
  font-family: var(--display); font-size: 19px;
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.cell .arrow {
  display: inline-block; margin-left: 3px; font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.cell .arrow.rise { color: var(--up); }
.cell .arrow.slip { color: var(--down); }
.cell .arrow.flat { color: var(--quiet); }
/* Muted and small on purpose: these are facts, not failures, and must not shout louder
   than the ranks they sit beside. */
.cell .deep { font-size: 11.5px; color: var(--quiet); white-space: normal;
              display: inline-block; max-width: 76px; line-height: 1.25; }
/* NOT amber. Amber means "slipping" everywhere else on this site, and a page we could
   not read is not a decline - treating it as one is the exact confusion the whole
   project exists to prevent. Quiet text plus a hatch: clearly "nothing here", with no
   direction implied and nothing that depends on telling two colours apart. */
.cell .noread { font-size: 11.5px; color: var(--quiet); font-style: italic; }
.cell.noread {
  background: repeating-linear-gradient(135deg, transparent, transparent 5px,
              var(--rule) 5px, var(--rule) 6px);
}
.cell .untracked { color: var(--rule-2); }

/* Read by a screen reader, never drawn. The whole sentence lives here and in title=,
   because a box is too small for "up 4 places" and the words are not optional. */
.sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

@media (max-width: 620px) {
  table.grid { font-size: 13px; }
  table.grid .kwcol { min-width: 116px; max-width: 132px; padding: 8px 10px 8px 9px;
                      white-space: normal; }
  .cell { min-width: 62px; padding: 7px 7px; }
  .cell .n { font-size: 17px; }
  .cell .deep { max-width: 62px; font-size: 10.5px; }
  .storetabs .tab { padding: 6px 12px; }
}
