/* Ellie's Games — mobile-first. Base styles target 320px; breakpoints add upward.
   The brand blue is the page itself and content rides on white cards, so body copy
   never sits on the blue. Every text pair below is WCAG AA verified (ratio noted). */

:root {
  --brand: #54b8eb;          /* the page — decorative, never behind body copy */
  --brand-dark: #2f9ad4;     /* deeper blue for the footer band */
  --ink-on-brand: #0d2b3a;   /* text directly on blue — 6.63:1 PASS */
  --ink: #1d2b33;            /* body copy on white — 14.1:1 PASS */
  --ink-soft: #566973;       /* secondary text on white — 5.9:1 PASS */
  --heading: #1b4d66;        /* headings on white — 9.13:1 PASS */
  --link: #25698c;           /* links on white — 6.04:1 PASS */
  --accent: #d93b25;         /* primary CTA, white text — 4.56:1 PASS */
  --accent-dark: #b32e1c;
  --card: #ffffff;
  --tint: #f2f9fd;
  --rule: #dce9f0;
  --free: #0f6b3f;           /* on --free-bg — 5.9:1 PASS */
  --free-bg: #e3f5ea;
  --star: #a86400;           /* on white — 5.1:1 PASS */

  --col: 58rem;              /* content column — narrow enough to feel deliberate */
  --measure: 66ch;
  --tap: 44px;
  --r-card: 28px;
  --r-btn: 999px;
  --pad: clamp(1.15rem, 4vw, 2.25rem);
  --shadow: 0 2px 4px rgba(10, 45, 62, .07), 0 12px 32px rgba(10, 45, 62, .13);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
          Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
  --display: "ArcherPro", Georgia, "Iowan Old Style", serif;
}

/* The brand's own typeface, used on this site since 2011. One weight, subset to
   the characters this site actually uses (11KB), self-hosted so no request ever
   leaves for a font CDN — which matters on a site whose whole pitch is privacy. */
@font-face {
  font-family: "ArcherPro";
  src: url("/assets/fonts/archer-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.62;
  color: var(--ink);
  overflow-x: hidden;
  /* Dots, because nearly every app in the catalog is one. Two offset grids of
     faint circles give the blue some depth without adding a single byte. */
  background-color: var(--brand);
  background-image: radial-gradient(rgba(255,255,255,.16) 2px, transparent 2.1px);
  background-size: 46px 46px;
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.12;
  color: var(--heading);
  text-wrap: balance;
  margin: 0 0 .5em;
}
h1 { font-size: clamp(1.8rem, 1.3rem + 2.6vw, 3.25rem); letter-spacing: -.012em; }
h2 { font-size: clamp(1.3rem, 1.1rem + 1vw, 1.95rem); margin-top: 1.7em; }
h3 { font-size: 1.15rem; }

p, li { max-width: var(--measure); }
p { margin: 0 0 1em; }

a { color: var(--link); text-underline-offset: .15em; }
a:hover { color: var(--heading); }
a:focus-visible, button:focus-visible {
  outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 6px;
}

.wrap { width: 100%; max-width: var(--col); margin-inline: auto; padding-inline: clamp(.85rem, 3vw, 1.5rem); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip { position: absolute; left: -9999px; top: 0; z-index: 100;
        background: var(--card); color: var(--heading); padding: .75rem 1rem; font-weight: 700; }
.skip:focus { left: .5rem; top: .5rem; }

/* ---------- The card: the one repeated surface ---------- */
.card {
  background: var(--card);
  border-radius: var(--r-card);
  box-shadow: var(--shadow);
  padding: var(--pad);
  margin-block: .8rem;
  /* Hard guarantee: nothing can ever render outside a card, in any engine. */
  overflow: hidden;
}

/* ---------- Header ---------- */
.site-header { padding-block: .6rem .25rem; padding-top: max(.6rem, env(safe-area-inset-top)); }
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; gap: .5rem .75rem; }
.logo { display: inline-flex; align-items: center; min-height: var(--tap); flex: none; }
.logo img { width: 108px; height: auto; }

.site-nav ul { list-style: none; display: flex; gap: .1rem .7rem; margin: 0; padding: 0; }
.site-nav a {
  display: inline-flex; align-items: center; min-height: var(--tap); padding-inline: .2rem;
  color: var(--ink-on-brand); font-weight: 700; text-decoration: none; font-size: .98rem;
  white-space: nowrap;
}
.site-nav a:hover, .site-nav a[aria-current="page"] { text-decoration: underline; text-decoration-thickness: 2px; }

/* ---------- Breadcrumbs (sit on the blue) ---------- */
.crumbs { font-size: .92rem; padding-block: .5rem .25rem; color: var(--ink-on-brand); }
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: .4rem; margin: 0; padding: 0; }
.crumbs li::after { content: "›"; margin-left: .4rem; opacity: .65; }
.crumbs li:last-child::after { content: ""; }
.crumbs a { color: var(--ink-on-brand); font-weight: 600; }

/* ---------- Hub hero (on blue, no card) ---------- */
.page-intro { padding-block: .5rem .9rem; color: var(--ink-on-brand); }
.page-intro h1 { color: var(--ink-on-brand); max-width: 20ch; margin-bottom: .35em; }
.page-intro p {
  color: var(--ink-on-brand); font-weight: 500; max-width: 58ch; margin-bottom: 0;
  font-size: clamp(1rem, .95rem + .35vw, 1.2rem);
  line-height: 1.5;
}

/* ---------- App hero card ---------- */
.app-hero { display: grid; gap: .9rem; align-items: start; }
.app-hero__icon { width: 84px; height: 84px; border-radius: 24%; box-shadow: 0 3px 10px rgba(10,45,62,.18); }
.app-hero h1 { margin-bottom: .2rem; }
.app-hero .lede {
  font-size: clamp(1.05rem, 1rem + .35vw, 1.2rem);
  color: var(--ink); max-width: 40ch; margin-bottom: .9rem; line-height: 1.45;
}

/* ---------- Facts ---------- */
.facts {
  margin: 0 0 .15rem; max-width: none;
  font-size: 1rem; color: var(--ink);
  display: flex; flex-wrap: wrap; align-items: baseline;
  column-gap: .9rem; row-gap: .1rem;   /* spacing, not middots, so wraps stay clean */
}
.facts b { font-weight: 700; }
.facts b.is-free { color: var(--free); }
.facts--spec { font-size: .88rem; color: var(--ink-soft); margin-bottom: 1.1rem; column-gap: .8rem; }
.facts .rc { color: var(--ink-soft); }
.rating-star { color: var(--star); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 48px; min-width: var(--tap); padding: .7rem 1rem;
  border-radius: var(--r-btn); border: 2px solid transparent;
  font-size: 1rem; font-weight: 700; text-decoration: none; text-align: center;
  transition: background-color .15s ease, transform .15s ease;
}
.btn--primary { background: var(--accent); color: #fff; box-shadow: 0 4px 12px rgba(217,59,37,.3); }
.btn--primary:hover { background: var(--accent-dark); color: #fff; transform: translateY(-1px); }
.btn--ghost { background: var(--card); color: var(--heading); border-color: var(--rule); }
.btn--ghost:hover { background: var(--tint); color: var(--heading); }

/* Side by side on a phone rather than stacked — two full-width pills is a lot
   of vertical spend for one card. */
.actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.actions .btn { flex: 1 1 auto; }

/* ---------- Screenshot gallery ---------- */
.shots {
  display: grid; grid-auto-flow: column; grid-auto-columns: min(58vw, 210px);
  gap: .75rem; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  /* Stays inside the card's padding. A negative-margin bleed escapes the card's
     rounded corner — the page never scrolls, so it looks broken rather than
     failing any overflow check. */
  padding-block: .25rem .75rem;
  scrollbar-width: thin;
}
.shots--wide { grid-auto-columns: min(84vw, 400px); }
.shots img { width: 100%; height: auto; scroll-snap-align: center;
             border-radius: 14px; border: 1px solid var(--rule); background: var(--tint); }
.shots::-webkit-scrollbar { height: 8px; }
.shots::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 4px; }
.shots-hint { font-size: .9rem; color: var(--ink-soft); margin-top: -.4rem; }

/* Screenshot row inside a hub spotlight card. These are App Store marketing
   shots with real text on them, so three-across on a phone is illegible —
   it scrolls instead, at a size you can actually read. */
/* Hidden on phones. The hub's job on a small screen is to route you to an app,
   and these are duplicated in full on each app page anyway. */
.mini-shots { display: none; }
.mini-shots::-webkit-scrollbar { display: none; }
.mini-shots img {
  flex: none; width: 38vw; max-width: 150px;
  /* Capped and top-cropped: full height costs ~365px of a phone screen for one
     card, and the part worth seeing is the top of the shot. */
  height: 190px; object-fit: cover; object-position: top center;
  scroll-snap-align: start;
  border-radius: 12px; border: 1px solid var(--rule); background: var(--tint);
}

/* ---------- App list ---------- */
.app-grid { list-style: none; margin: 0; padding: 0; display: grid; gap: .85rem; grid-template-columns: 1fr; }
.app-card {
  position: relative; display: flex; gap: .85rem; align-items: center;
  padding: .7rem .8rem; background: var(--card); border-radius: 16px;
  box-shadow: 0 1px 2px rgba(10,45,62,.06), 0 4px 12px rgba(10,45,62,.09);
  max-width: none; transition: transform .15s ease;
}
.app-card:hover { transform: translateY(-2px); }
.app-card img { width: 56px; height: 56px; border-radius: 24%; flex: none; }
.app-card h3 { margin: 0 0 .05rem; font-size: 1rem; line-height: 1.25; }
.app-card h3 a { text-decoration: none; color: var(--heading); }
.app-card h3 a::after { content: ""; position: absolute; inset: 0; }
.app-card > div { min-width: 0; }
.app-card p {
  margin: 0; font-size: .88rem; color: var(--ink-soft); max-width: none; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.app-card__meta {
  margin-top: .2rem; font-size: .8rem; color: var(--ink-soft); font-weight: 600;
  -webkit-line-clamp: 1;
}

/* Spotlight = the two heroes, given a full card each.
   Icon sits beside the name even on a phone; stacking it wastes a whole row. */
.spotlight { display: grid; gap: 1rem; }
.spotlight__item {
  display: grid; grid-template-columns: auto 1fr;
  column-gap: .9rem; row-gap: .85rem; align-items: center;
}
.spotlight__item img.icon { width: 66px; height: 66px; border-radius: 24%; box-shadow: 0 3px 10px rgba(10,45,62,.18); }
.spotlight__item h3 { font-size: 1.25rem; margin: 0 0 .15rem; }
.spotlight__item p { margin: 0; font-size: .98rem; }
.spotlight__body { grid-column: 1 / -1; }

/* ---------- Prose bits ---------- */
.prose ul, .prose ol { padding-left: 1.2rem; }
.prose li { margin-bottom: .4rem; }
.prose .no-list { list-style: none; padding-left: 0; }
.prose .no-list li { padding-left: 1.7rem; position: relative; }
.prose .no-list li::before { content: "✓"; position: absolute; left: 0; color: var(--free); font-weight: 700; }
.prose > h2:first-child { margin-top: 0; }

.callout { border-left: 5px solid var(--accent); background: var(--tint);
           padding: 1rem 1.2rem; border-radius: 0 16px 16px 0; margin-block: 1.6rem; }
.callout p:last-child { margin-bottom: 0; }

.lede-note { font-size: 1.15rem; color: var(--ink-soft); }
.updated { font-size: .9rem; color: var(--ink-soft); border-top: 1px solid var(--rule); padding-top: 1rem; }

.table-scroll { overflow-x: auto; margin-block: 1.25rem; }
table { border-collapse: collapse; width: 100%; min-width: 28rem; font-size: .95rem; }
caption { text-align: left; color: var(--ink-soft); font-size: .9rem; padding-bottom: .6rem; }
th, td { text-align: left; padding: .65rem .75rem; border-bottom: 1px solid var(--rule); vertical-align: top; }
thead th { background: var(--tint); color: var(--heading); }
tbody th { font-weight: 700; }

.about-photo { width: 100%; border-radius: 20px; margin-bottom: 1.25rem; }

/* ---------- Install bar ---------- */
.install-bar {
  position: fixed; inset: auto 0 0 0; z-index: 20;
  display: flex; align-items: center; gap: .7rem;
  padding: .55rem clamp(.85rem, 3vw, 1.5rem);
  padding-bottom: max(.55rem, env(safe-area-inset-bottom));
  background: var(--card); border-top: 1px solid var(--rule);
  box-shadow: 0 -2px 16px rgba(10,45,62,.14);
}
.install-bar img.icon { width: 38px; height: 38px; border-radius: 24%; flex: none; }
.install-bar__name { font-weight: 700; font-size: .95rem; line-height: 1.2; }
.install-bar__price { font-size: .85rem; color: var(--ink-soft); }
.install-bar > div { min-width: 0; }
.install-bar__name, .install-bar__price { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.install-bar .btn { margin-left: auto; padding: .55rem 1.1rem; min-height: 44px; flex: none; }
body.has-install-bar { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }

/* ---------- Footer ---------- */
.site-footer {
  margin-top: 2rem; padding-block: 2rem;
  padding-bottom: max(2rem, env(safe-area-inset-bottom));
  background: var(--brand-dark); color: var(--ink-on-brand); font-size: .95rem;
}
.site-footer ul { list-style: none; margin: 0 0 .5rem; padding: 0; display: flex; flex-wrap: wrap; gap: .1rem 1.25rem; }
.site-footer a { display: inline-flex; align-items: center; min-height: var(--tap); color: var(--ink-on-brand); font-weight: 600; }
.site-footer p { max-width: var(--measure); margin: 0; }

/* ============ Breakpoints — mobile-first, additive upward ============ */

@media (min-width: 34rem) {
  .app-grid { grid-template-columns: repeat(2, 1fr); }
  .shots { grid-auto-columns: 190px; }
  .shots--wide { grid-auto-columns: 340px; }
}

@media (min-width: 48rem) {
  body { font-size: 1.125rem; }
  .btn { min-height: 52px; padding: .8rem 1.6rem; font-size: 1.0625rem; }
  .actions .btn { flex: 0 0 auto; }
  .logo img { width: 150px; }
  .site-nav a { font-size: 1.05rem; padding-inline: .3rem; }
  .site-header { padding-block: 1.1rem .25rem; }
  .app-hero { grid-template-columns: auto 1fr; column-gap: 1.75rem; }
  .app-hero__icon { width: 132px; height: 132px; }
  .spotlight__item { column-gap: 1.4rem; }
  .spotlight__item img.icon { width: 92px; height: 92px; }
  .spotlight__item h3 { font-size: 1.5rem; }
  .mini-shots {
    display: flex; gap: .6rem; margin: 0 0 1.15rem; overflow: visible;
  }
  .mini-shots img { width: 150px; height: 190px; object-fit: cover; object-position: top center; }
  .shots { grid-auto-columns: 218px; }
  .shots--wide { grid-auto-columns: 400px; }
  .install-bar { display: none; }
  body.has-install-bar { padding-bottom: 0; }
}

@media (min-width: 64rem) {
  .app-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (prefers-contrast: more) {
  :root { --ink-soft: #33424a; --rule: #9fb8c5; }
}

/* Section heading that sits on the blue, above a group of cards. */
.section-head { color: var(--ink-on-brand); margin: 1.4rem 0 .1rem; }
