/* WordsApp — the site wears what the app wears.
   Every colour here is lifted from src/WordsApp.Android/Resources/values/colors.xml,
   and both faces are the app's own, self-hosted: a German privacy page that
   fetches fonts from Google would hand every visitor's address to Google on the
   very page that promises it does not. */

@font-face {
  font-family: "Baloo 2";
  src: url("fonts/Baloo2-Bold.ttf") format("truetype");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("fonts/Poppins-Medium.ttf") format("truetype");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("fonts/Poppins-SemiBold.ttf") format("truetype");
  font-weight: 600;
  font-display: swap;
}

:root {
  /* Three hues, and no more: the felt, the tile, the brass. */
  --felt: #2e3b2e;
  --felt-deep: #253022;
  --tile: #f5ebd0;
  --tile-edge: #c9b98f;
  --tile-text: #3a2c1a;
  --brass: #c9a24b;
  --text: #f2ead8;
  --muted: #bfb49a;

  --display: "Baloo 2", system-ui, sans-serif;
  --body: "Poppins", system-ui, -apple-system, sans-serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  background: var(--felt);
  color: var(--text);
  font-family: var(--body);
  font-weight: 500;
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* The felt, given depth. A radial lift above the middle reads as a lamp over
   the table; the grain keeps the flat colour from looking like a CSS swatch. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background: radial-gradient(ellipse 70% 55% at 50% 32%, rgba(255, 255, 255, 0.05) 0%, transparent 70%);
  pointer-events: none;
  z-index: 1;
}
body::after {
  content: "";
  position: fixed;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
  pointer-events: none;
  z-index: 50;
}

/* ── Chrome ─────────────────────────────────────────────────────────── */

.shell { position: relative; z-index: 10; }

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.75rem clamp(1.25rem, 5vw, 4rem);
  /* Lifted above the hero on purpose. The hero is pulled up under this bar so
     its content reads as centred, and being positioned it would otherwise paint
     over the bar and swallow every click on these links — which is exactly what
     it did, on the front page only, because no other page pulls anything up. */
  position: relative;
  z-index: 20;
}

.nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.9rem;
  transition: color 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.nav a:hover { color: var(--text); }

.nav__mark {
  font-family: var(--display);
  font-size: 1.15rem;
  color: var(--text);
  letter-spacing: -0.01em;
}
.nav__links { display: flex; gap: clamp(1rem, 3vw, 2rem); }

/* ── Hero: the wordmark is the picture ──────────────────────────────── */

.hero {
  position: relative;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: clamp(1rem, 4vh, 3rem) clamp(1.25rem, 5vw, 4rem) clamp(3rem, 8vh, 6rem);
  margin-top: -4.5rem;
}

/* The board, suggested rather than drawn: the 15×15 grid the game is played on,
   faint enough to read as texture in the felt and not as a diagram. It fades out
   before the edges so nothing about it has a border. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    repeating-linear-gradient(to right, rgba(242, 234, 216, 0.055) 0 1px, transparent 1px calc(100% / 15)),
    repeating-linear-gradient(to bottom, rgba(242, 234, 216, 0.055) 0 1px, transparent 1px calc(100% / 15));
  background-size: min(78vmin, 46rem) min(78vmin, 46rem);
  background-position: center;
  background-repeat: no-repeat;
  -webkit-mask-image: radial-gradient(ellipse 52% 46% at 50% 50%, #000 30%, transparent 78%);
          mask-image: radial-gradient(ellipse 52% 46% at 50% 50%, #000 30%, transparent 78%);
  pointer-events: none;
}

.hero > * { position: relative; }

.hero__eyebrow {
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: clamp(1.5rem, 4vh, 2.5rem);
}

/* The tiles are the heading. Semantically it stays an h1 with a plain-text
   fallback for anything that does not read CSS. */
.wordmark {
  --tile-size: clamp(2.6rem, 10.4vw, 10.5rem);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0;
  margin-bottom: clamp(2rem, 5vh, 3.5rem);
}

/* Hidden from the eye, kept for screen readers and crawlers. A class and not an
   inline style: the Content-Security-Policy forbids inline styles, so the one
   that used to sit here was dropped by the browser and the word appeared in the
   open beside the tiles. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  white-space: nowrap;
  clip-path: inset(50%);
}

.tile {
  --lift: 0deg;
  position: relative;
  display: grid;
  place-items: center;
  /* The wordmark is the picture, so it takes the room a picture would: eight
     tiles run to roughly three quarters of the viewport on a desktop. They
     overlap by six percent, exactly as WordTiles.Render lays them out in the
     app — a wordmark with gaps between the tiles reads as a spelling exercise,
     one where they touch reads as a word somebody put down. */
  width: var(--tile-size);
  height: var(--tile-size);
  margin-right: calc(var(--tile-size) * -0.06);
  background: linear-gradient(168deg, #fdf6e4 0%, var(--tile) 55%, #ece0c0 100%);
  border-radius: clamp(0.35rem, 1vw, 0.9rem);
  box-shadow:
    inset 0 -2px 0 rgba(0, 0, 0, 0.13),
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    0 clamp(3px, 0.7vw, 9px) clamp(8px, 1.6vw, 22px) rgba(0, 0, 0, 0.34);
  transform: rotate(var(--lift)) translateY(var(--drop, 0));
  font-family: var(--display);
  font-size: clamp(1.5rem, 6.4vw, 6.4rem);
  line-height: 1;
  color: var(--tile-text);
  user-select: none;
}

.tile:last-child { margin-right: 0; }

/* Hand-placed, not printed. The ranges are the app's own: WordTiles.Render
   tilts each tile by up to 4.5 degrees and lifts or drops it by up to 8% of its
   size. The app draws from a hash, which cannot be reproduced here and does not
   need to be — what carries is the amount, not the particular angles. */
.tile:nth-child(1) { --lift: -3.6deg; --drop:  2%; }
.tile:nth-child(2) { --lift:  2.9deg; --drop: -5%; }
.tile:nth-child(3) { --lift: -1.4deg; --drop:  6%; }
.tile:nth-child(4) { --lift:  4.1deg; --drop: -2%; }
.tile:nth-child(5) { --lift: -2.7deg; --drop: -7%; }
.tile:nth-child(6) { --lift:  1.8deg; --drop:  4%; }
.tile:nth-child(7) { --lift: -4.3deg; --drop: -3%; }
.tile:nth-child(8) { --lift:  2.2deg; --drop:  5%; }

.hero__line {
  font-family: var(--display);
  font-size: clamp(1.6rem, 3.6vw, 3.1rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  max-width: 20ch;
  text-wrap: balance;
  margin-bottom: clamp(1.25rem, 3vh, 2rem);
}
.hero__line em {
  font-style: normal;
  color: var(--brass);
}

.hero__sub {
  font-size: clamp(1rem, 1.15vw, 1.15rem);
  color: var(--muted);
  max-width: 42ch;
  margin-bottom: clamp(2rem, 5vh, 3rem);
}

/* ── The one button ─────────────────────────────────────────────────── */

.cta {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 44px;
  padding: 0.95rem 2.1rem;
  border-radius: 999px;
  background: var(--brass);
  color: #241f19;
  font-family: var(--body);
  font-weight: 600;
  font-size: 0.875rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-decoration: none;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1),
              box-shadow 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.cta:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.34);
}
.cta:active { transform: translateY(0) scale(0.98); }
.cta svg { width: 1.05rem; height: 1.05rem; }

/* Google's own badge, when it is on disk. It is a trademarked asset with its
   own clear-space rules, so it is used as delivered and never redrawn — the
   link is the button, and nothing is painted behind it. */
.badge {
  display: inline-block;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.badge img {
  display: block;
  height: clamp(3.1rem, 4.6vw, 3.9rem);
  width: auto;
}
.badge:hover { transform: translateY(-2px); }
.badge:active { transform: translateY(0) scale(0.98); }

/* ── Entry: the tiles are laid down, one after another ──────────────── */

@keyframes lay {
  from { opacity: 0; transform: translateY(24px) rotate(0deg) scale(0.94); }
  to   { opacity: 1; transform: rotate(var(--lift)) translateY(var(--drop, 0)) scale(1); }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(22px); filter: blur(7px); }
  to   { opacity: 1; transform: translateY(0); filter: blur(0); }
}

.tile,
.hero__eyebrow,
.hero__line,
.hero__sub,
.hero__cta { opacity: 0; }

.tile { animation: lay 0.62s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
.tile:nth-child(1) { animation-delay: 0.10s; }
.tile:nth-child(2) { animation-delay: 0.16s; }
.tile:nth-child(3) { animation-delay: 0.22s; }
.tile:nth-child(4) { animation-delay: 0.28s; }
.tile:nth-child(5) { animation-delay: 0.34s; }
.tile:nth-child(6) { animation-delay: 0.40s; }
.tile:nth-child(7) { animation-delay: 0.46s; }
.tile:nth-child(8) { animation-delay: 0.52s; }

.hero__eyebrow { animation: rise 0.6s cubic-bezier(0.16, 1, 0.3, 1) 0.02s forwards; }
.hero__line    { animation: rise 0.7s cubic-bezier(0.16, 1, 0.3, 1) 0.44s forwards; }
.hero__sub     { animation: rise 0.7s cubic-bezier(0.16, 1, 0.3, 1) 0.54s forwards; }
.hero__cta     { animation: rise 0.7s cubic-bezier(0.16, 1, 0.3, 1) 0.62s forwards; }

@media (prefers-reduced-motion: reduce) {
  .tile, .hero__eyebrow, .hero__line, .hero__sub, .hero__cta {
    animation: none;
    opacity: 1;
    transform: rotate(var(--lift)) translateY(var(--drop, 0));
  }
}

/* ── Prose: the legal pages and anything else that is mostly words ──── */

.page { padding: clamp(2rem, 6vh, 4rem) clamp(1.25rem, 5vw, 4rem) 6rem; }
.prose { max-width: 44rem; margin: 0 auto; }

.prose h1 {
  font-family: var(--display);
  font-size: clamp(2rem, 4.5vw, 3rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-bottom: 0.4rem;
}
.prose h2 {
  font-family: var(--display);
  font-size: 1.3rem;
  color: var(--brass);
  margin: 2.6rem 0 0.7rem;
}
.prose h3 { font-size: 1.05rem; margin: 1.6rem 0 0.5rem; }
.prose p, .prose ul, .prose ol { margin-bottom: 1rem; }
.prose ul, .prose ol { padding-left: 1.35rem; }
.prose li { margin-bottom: 0.4rem; }
.prose a { color: var(--brass); }
.prose strong { font-weight: 600; color: #fff; }
.prose .lede { color: var(--muted); margin-bottom: 2.2rem; }

.prose .box {
  background: rgba(0, 0, 0, 0.17);
  border: 1px solid rgba(201, 185, 143, 0.22);
  border-radius: 0.7rem;
  padding: 1.1rem 1.25rem;
  margin-bottom: 1.3rem;
}

.prose .table-wrap { overflow-x: auto; margin-bottom: 1.3rem; }
.prose table { border-collapse: collapse; width: 100%; min-width: 34rem; font-size: 0.95rem; }
.prose th, .prose td {
  text-align: left;
  vertical-align: top;
  padding: 0.6rem 0.75rem;
  border-bottom: 1px solid rgba(201, 185, 143, 0.2);
}
.prose th { color: var(--muted); font-weight: 600; }

/* ── Foot ───────────────────────────────────────────────────────────── */

/* No rule above it: a line across the felt reads as a frame around the page,
   and the whole point of the felt is that it has no edge. */
.foot {
  padding: 2rem clamp(1.25rem, 5vw, 4rem) 3rem;
  color: var(--muted);
  font-size: 0.875rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.6rem;
  align-items: center;
}
.foot a { color: var(--muted); text-decoration: none; }
.foot a:hover { color: var(--text); text-decoration: underline; }
.foot__spacer { margin-left: auto; }

@media (max-width: 640px) {
  .foot__spacer { margin-left: 0; }
  .nav__links { gap: 1rem; font-size: 0.85rem; }
}

/* ── Numbers ────────────────────────────────────────────────────────── */

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: 0.85rem;
  margin-bottom: 2.5rem;
}

/* A counter should read like a tile on the table, not like a table cell. */
.tile-stat {
  background: linear-gradient(168deg, #fdf6e4 0%, var(--tile) 55%, #ece0c0 100%);
  border-radius: 0.7rem;
  padding: 1.1rem 1rem 0.9rem;
  text-align: center;
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.13),
              inset 0 1px 0 rgba(255, 255, 255, 0.7),
              0 4px 14px rgba(0, 0, 0, 0.24);
}
.tile-stat__value {
  display: block;
  font-family: var(--display);
  font-size: clamp(1.7rem, 3.4vw, 2.4rem);
  line-height: 1;
  color: var(--tile-text);
}
.tile-stat__label {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: rgba(58, 44, 26, 0.66);
}

.player {
  border-top: 1px solid rgba(201, 185, 143, 0.18);
  padding-top: 1.2rem;
  margin-bottom: 1.6rem;
}
.player__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.6rem; }
.player__head strong { font-family: var(--display); font-size: 1.15rem; color: #fff; }
.player__meta { color: var(--muted); font-size: 0.86rem; }
.player__devices { display: flex; flex-wrap: wrap; gap: 0.45rem; margin: 0.6rem 0 0.9rem; }

/* The build a device last spoke from. Amber when it never said — that is a
   client from before the version header, and the one you cannot steer. */
.chip {
  font-size: 0.78rem;
  padding: 0.28rem 0.65rem;
  border-radius: 999px;
  background: rgba(201, 162, 75, 0.16);
  border: 1px solid rgba(201, 162, 75, 0.42);
  color: var(--text);
}
.chip--warn { background: rgba(214, 84, 48, 0.16); border-color: rgba(214, 84, 48, 0.5); }
.chip--muted { background: rgba(191, 180, 154, 0.12); border-color: rgba(191, 180, 154, 0.3); color: var(--muted); }
