/* Fonts are self-hosted (SIL Open Font License, see assets/fonts), so visitors' browsers never
   contact Google: loading Google Fonts remotely hands every visitor's IP address to Google. */

/* Google Sans Code, latin-ext */
@font-face {
  font-family: "Google Sans Code";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("assets/fonts/google-sans-code-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Google Sans Code, latin */
@font-face {
  font-family: "Google Sans Code";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("assets/fonts/google-sans-code-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Google Sans Flex, latin-ext */
@font-face {
  font-family: "Google Sans Flex";
  font-style: normal;
  font-weight: 1 1000;
  font-stretch: 100%;
  font-display: swap;
  src: url("assets/fonts/google-sans-flex-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Google Sans Flex, latin */
@font-face {
  font-family: "Google Sans Flex";
  font-style: normal;
  font-weight: 1 1000;
  font-stretch: 100%;
  font-display: swap;
  src: url("assets/fonts/google-sans-flex-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Tokens follow the client's Material 3 baseline scheme (MaterialTokens.java). */
:root {
  color-scheme: light dark;
  --page: light-dark(#fdf8ff, #0f0d13);
  --surface: light-dark(#fef7ff, #141218);
  --surface-container: light-dark(#f3edf7, #211f26);
  --surface-high: light-dark(#ece6f0, #2b2930);
  --on-surface: light-dark(#1d1b20, #e6e0e9);
  --on-surface-variant: light-dark(#49454f, #cac4d0);
  --text-muted: light-dark(#5d5966, #938f99);
  --primary: light-dark(#6750a4, #d0bcff);
  --on-primary: light-dark(#ffffff, #381e72);
  --secondary-container: light-dark(#e8def8, #4a4458);
  --on-secondary-container: light-dark(#1d192b, #e8def8);
  --primary-container: light-dark(#eaddff, #4f378b);
  --on-primary-container: light-dark(#21005d, #eaddff);
  --tertiary: light-dark(#7d5260, #efb8c8);
  --on-tertiary: light-dark(#ffffff, #492532);
  --tertiary-container: light-dark(#ffd8e4, #633b48);
  --on-tertiary-container: light-dark(#31111d, #ffd8e4);
  --surface-highest: light-dark(#ffffff, #36343b);
  --outline-variant: light-dark(#cac4d0, #49454f);

  /* Backdrop shader inks: valley, lit fold, warm sheen. */
  --silk-deep: light-dark(#e2d4fb, #4f378b);
  --silk-glow: light-dark(#f7f1ff, #d0bcff);
  --silk-warm: light-dark(#f6d2dd, #efb8c8);

  /* The footer's giant lockup: deep end, lit fold and warm sheen, plus the pool beneath it. */
  --wordmark-a: light-dark(#7d65cf, #4f378b);
  --wordmark-b: light-dark(#c3aefa, #d0bcff);
  --wordmark-c: light-dark(#e49ab6, #efb8c8);
  --wordmark-shadow: light-dark(rgb(103 80 164 / 0.16), rgb(0 0 0 / 0.45));

  --glass: light-dark(rgb(255 255 255 / 0.5), rgb(255 255 255 / 0.045));
  --glass-edge: light-dark(rgb(0 0 0 / 0.06), rgb(255 255 255 / 0.09));
  --shadow: light-dark(rgb(56 30 114 / 0.18), rgb(0 0 0 / 0.55));
  --hairline: light-dark(rgb(0 0 0 / 0.1), rgb(255 255 255 / 0.1));
  --key-edge: light-dark(rgb(0 0 0 / 0.1), rgb(0 0 0 / 0.32));

  /* Changelog entry types: the client's hues (EntryType.java), readable in both schemes. */
  --type-added: light-dark(#1b7a43, #86efac);
  --type-improved: light-dark(#0b6aa2, #7dd3fc);
  --type-changed: light-dark(#6750a4, #c4b5fd);
  --type-fixed: light-dark(#9a5b00, #fcd34d);
  --type-removed: light-dark(#b3264a, #fda4af);

  /* Code: the client's accent family, one hue per token kind. */
  --code-keyword: light-dark(#6750a4, #d0bcff);
  --code-string: light-dark(#8c4a60, #efb8c8);
  --code-number: light-dark(#2f6b52, #b8dccb);
  --code-call: light-dark(#4a4458, #e8def8);

  /* Material 3 Expressive motion. */
  --ease-spatial: cubic-bezier(0.38, 1.21, 0.22, 1);
  --ease-spatial-slow: cubic-bezier(0.39, 1.29, 0.35, 0.98);
  --ease-effects: cubic-bezier(0.34, 0.8, 0.34, 1);

  --font: "Google Sans Flex", "Google Sans", "Roboto Flex", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* The scheme follows the system unless the footer's theme switch pins one (data-theme on
   <html>, set before first paint by the inline script in index.html). */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

/* Theme changes reveal as a circle from the switch (hero.js), not the default crossfade. */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

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

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

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

body {
  margin: 0;
  background: var(--page);
  color: var(--on-surface);
  font-family: var(--font);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

svg { display: block; fill: currentColor; }

button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

/* ---------------------------------------------------------------- hero */

.hero {
  --silk-base: var(--page);
  position: relative;
  isolation: isolate;
  overflow: clip;
  padding-bottom: clamp(64px, 10vw, 128px);
}

.backdrop {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 1.4s var(--ease-effects);
}

.backdrop.is-live { opacity: 1; }

/* Without WebGL the silk is approximated by one quiet glow behind the window. */
.no-webgl {
  background:
    radial-gradient(60% 40% at 50% 52%, color-mix(in srgb, var(--silk-deep) 45%, transparent), transparent 70%),
    var(--page);
}

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

.bar {
  position: relative;
  z-index: 3;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  max-width: 1280px;
  margin: 0 auto;
  padding: 20px 28px;
}

.brand {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--on-surface);
  text-decoration: none;
  border-radius: 12px;
}

.brand-mark {
  width: 28px;
  height: 28px;
  fill: var(--primary);
  transition: transform 0.6s var(--ease-spatial);
}

.brand:hover .brand-mark { transform: rotate(45deg); }

.brand-name {
  font-size: 1.4375rem;
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
  padding-bottom: 0.06em;
}

.links {
  position: relative;
  display: flex;
}

.links a {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 18px;
  border-radius: 999px;
  color: var(--on-surface-variant);
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  transition: color 0.2s var(--ease-effects);
}

.links a:hover,
.links a:focus-visible,
.links a[aria-current="page"] { color: var(--on-surface); }

.links .pill { top: 0; height: 40px; background: color-mix(in srgb, var(--on-surface) 8%, transparent); }

.bar-cta { justify-self: end; }

/* Selection capsule shared by the links and the screen tabs; hero.js springs its edges. */
.pill {
  position: absolute;
  left: 0;
  width: 0;
  border-radius: 999px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s var(--ease-effects);
}

.pill.is-visible { opacity: 1; }

/* --------------------------------------------------------------- intro */

.intro {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(56px, 10vh, 120px) 24px 0;
  text-align: center;
}

.headline {
  margin: 0;
  font-size: clamp(3rem, 1.1rem + 5.6vw, 6.5rem);
  font-weight: 500;
  line-height: 0.96;
  letter-spacing: -0.035em;
  font-variation-settings: "ROND" 40;
}

/* What ellice is, in the words people search for; part of the heading, set small above it. */
.kicker {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: clamp(20px, 3vw, 28px);
  padding: 7px 15px 7px 11px;
  border-radius: 999px;
  background: var(--glass);
  box-shadow: inset 0 0 0 1px var(--glass-edge);
  color: var(--on-surface-variant);
  font-size: clamp(0.8125rem, 0.77rem + 0.2vw, 0.9375rem);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: 0;
  font-variation-settings: normal;
}

.kicker::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--primary);
}

/* Each line masks its own rise; the padding keeps the comma's descender inside the mask. */
.line {
  display: block;
  overflow: hidden;
  padding: 0 0.04em 0.1em;
  margin-bottom: -0.1em;
}

.line > span { display: block; }

.morph {
  display: inline-block;
  width: 0.92em;
  height: 0.92em;
  margin: 0 0.04em 0 -0.1em;
  vertical-align: -0.1em;
  fill: var(--primary);
  overflow: visible;
}

.lede {
  max-width: 33em;
  margin: 28px 0 0;
  color: var(--on-surface-variant);
  font-size: clamp(1.0625rem, 0.98rem + 0.3vw, 1.25rem);
  line-height: 1.5;
  text-wrap: balance;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 36px;
}

.meta {
  margin: 22px 0 0;
  color: var(--text-muted);
  font-size: 0.875rem;
  letter-spacing: 0.01em;
}

.meta span { margin: 0 0.35em; }

/* ------------------------------------------------------------- buttons */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 56px;
  padding: 0 28px;
  overflow: hidden;
  border-radius: 28px;
  font: 500 1.0625rem/1 var(--font);
  letter-spacing: 0.005em;
  text-decoration: none;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
  transition: border-radius 0.45s var(--ease-spatial);
}

.btn svg { width: 22px; height: 22px; flex: none; }

/* State layer, as in Material: tinted by the button's own ink. */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: currentColor;
  opacity: 0;
  transition: opacity 0.2s var(--ease-effects);
}

.btn:hover::before { opacity: 0.08; }
.btn:active::before { opacity: 0.12; }

/* Expressive shape morph: pressed buttons square off, then spring back. */
.btn:active { border-radius: 14px; transition-duration: 0.2s; }

.btn-filled { background: var(--primary); color: var(--on-primary); }
.btn-filled:has(svg) { padding-left: 24px; }
.btn-tonal {
  background: var(--secondary-container);
  color: var(--on-secondary-container);
}

.btn-small {
  height: 40px;
  padding: 0 20px;
  border-radius: 20px;
  font-size: 0.9375rem;
}

.btn-small:active { border-radius: 12px; }

:is(.btn, .brand, .links a, .tabs button):focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 3px;
}

/* ------------------------------------------------------------- product */

.product {
  position: relative;
  z-index: 1;
  width: min(1200px, calc(100% - 48px));
  margin: clamp(72px, 10vh, 112px) auto 0;
}

/* Glass bezel around the real, headless-rendered client screens. */
.window {
  padding: 10px;
  border-radius: 32px;
  background: var(--glass);
  box-shadow:
    inset 0 0 0 1px var(--glass-edge),
    inset 0 1px 0 0 var(--glass-edge),
    0 50px 120px -30px var(--shadow),
    0 30px 60px -40px var(--shadow);
  transform-origin: 50% 0;
  will-change: transform;
  transform:
    perspective(2400px)
    rotateX(calc(var(--tilt, 0) * 14deg))
    scale(calc(1 - var(--tilt, 0) * 0.06));
}

.screens {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-radius: 22px;
  background: var(--surface);
}

.screen {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transform: scale(1.025);
  transition:
    opacity 0.45s var(--ease-effects),
    transform 0.9s var(--ease-spatial),
    visibility 0s linear 0.45s;
}

.screen.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

.screen img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Floats on the bezel's top edge, like the navigation capsule in the client's menu. */
.tabs {
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 2;
  display: flex;
  padding: 5px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--surface-container) 94%, transparent);
  box-shadow: inset 0 0 0 1px var(--glass-edge), 0 12px 32px -12px var(--shadow);
  transform: translate(-50%, -50%);
}

.tabs button {
  position: relative;
  z-index: 1;
  height: 40px;
  padding: 0 20px;
  border-radius: 999px;
  color: var(--on-surface-variant);
  font-size: 0.9375rem;
  font-weight: 500;
  transition: color 0.2s var(--ease-effects);
}

.tabs button:hover { color: var(--on-surface); }
.tabs button[aria-selected="true"] { color: var(--on-secondary-container); }
.tabs .pill { top: 5px; height: 40px; background: var(--secondary-container); }

/* ------------------------------------------------------------ features */

.features {
  display: grid;
  /* An explicit track, so the code's longest line scrolls instead of widening the page. */
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(112px, 13vw, 184px);
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px clamp(112px, 13vw, 184px);
}

.feature {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: center;
  gap: clamp(40px, 6vw, 104px);
}

.feature.is-flipped { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.feature.is-flipped .feature-copy { order: 2; }

.feature h2,
.section-head h2 {
  margin: 0;
  font-size: clamp(2.25rem, 1.3rem + 2.5vw, 3.5rem);
  font-weight: 500;
  line-height: 1.04;
  letter-spacing: -0.03em;
  font-variation-settings: "ROND" 40;
  text-wrap: balance;
}

.feature p,
.section-head p {
  max-width: 30em;
  margin: 24px 0 0;
  color: var(--on-surface-variant);
  font-size: 1.125rem;
  line-height: 1.6;
  text-wrap: pretty;
}

.points {
  margin: 36px 0 0;
  padding: 0;
  list-style: none;
  border-bottom: 1px solid var(--hairline);
}

.points li {
  position: relative;
  padding: 15px 0 15px 34px;
  border-top: 1px solid var(--hairline);
  font-size: 1rem;
  line-height: 1.4;
}

.points li::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 20px;
  height: 20px;
  transform: translateY(-50%);
  background: var(--primary);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath d='M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath d='M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Tonal stage for each visual; the same silk inks as the hero, at rest. */
.feature-visual {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 6 / 5;
  padding: clamp(24px, 6%, 64px);
  overflow: hidden;
  border-radius: 36px;
  background:
    radial-gradient(110% 90% at 0% 0%, color-mix(in srgb, var(--silk-deep) 55%, transparent), transparent 62%),
    radial-gradient(80% 70% at 100% 100%, color-mix(in srgb, var(--silk-warm) 16%, transparent), transparent 65%),
    var(--surface-container);
  box-shadow: inset 0 0 0 1px var(--glass-edge);
}

.shot { display: block; width: 100%; }

.shot img {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 28px 48px var(--shadow)) drop-shadow(0 2px 6px var(--shadow));
}

/* A game scene rather than a client window: square pixels need a frame of their own. */
.shot-scene img { border-radius: clamp(14px, 2vw, 24px); }

/* Whole client windows are landscape: a wider stage with a slimmer margin keeps them readable. */
.feature-visual-wide {
  aspect-ratio: 3 / 2;
  padding: clamp(16px, 4%, 40px);
}

/* The settings dialog runs off the stage at a legible scale. The offsets place both cuts in
   its own gutters: right of the preset grid, and between the second and third preset rows. */
.feature-visual-bleed { place-items: start; padding: 0; aspect-ratio: 6 / 5; }
.feature-visual-bleed .shot {
  position: absolute;
  top: 16.5%;
  left: 9%;
  width: 149%;
}

/* Rows rise into place once, as they scroll in (hero.js adds .reveal and .is-in). */
@media (prefers-reduced-motion: no-preference) {
  .reveal .feature-copy,
  .reveal .feature-visual {
    transition:
      opacity 0.9s var(--ease-effects),
      transform 1.1s var(--ease-spatial);
  }

  .reveal .feature-visual { transition-delay: 0.08s; }

  .reveal .feature:not(.is-in) .feature-copy,
  .reveal .feature:not(.is-in) .feature-visual {
    opacity: 0;
    transform: translateY(40px);
  }
}

/* --------------------------------------------------------------- facts */

/* What a player checks first, right under the hero: price, modules, versions, setup. */
.facts {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px clamp(104px, 12vw, 168px);
}

.facts dl {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0;
}

.facts div {
  padding: 4px clamp(16px, 2.5vw, 32px);
  border-left: 1px solid var(--hairline);
}

.facts div:first-child { padding-left: 0; border-left: 0; }

.facts dt {
  font-size: clamp(2.25rem, 1.4rem + 2.4vw, 3.5rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.035em;
  font-variation-settings: "ROND" 40;
}

.facts dd {
  margin: 14px 0 0;
  color: var(--on-surface-variant);
  font-size: 1rem;
  line-height: 1.5;
}

/* --------------------------------------------------------------- watch */

.watch {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px clamp(112px, 13vw, 184px);
}

.watch-more {
  display: flex;
  justify-content: center;
  margin: 40px 0 0;
}

/* ----------------------------------------------------------------- faq */

.faq {
  max-width: 880px;
  margin: 0 auto;
  padding: 0 24px clamp(112px, 13vw, 184px);
}

.faq-list { border-top: 1px solid var(--hairline); }
.faq details { border-bottom: 1px solid var(--hairline); }

.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 24px 4px;
  font-size: clamp(1.0625rem, 0.98rem + 0.3vw, 1.25rem);
  font-weight: 500;
  line-height: 1.35;
  list-style: none;
  cursor: pointer;
  border-radius: 12px;
}

.faq summary::-webkit-details-marker { display: none; }

/* A plus that turns into a cross when the answer is open. */
.faq summary::after {
  content: "";
  flex: none;
  width: 24px;
  height: 24px;
  background: var(--primary);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath d='M440-440H200v-80h240v-240h80v240h240v80H520v240h-80v-240Z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath d='M440-440H200v-80h240v-240h80v240h240v80H520v240h-80v-240Z'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform 0.45s var(--ease-spatial);
}

.faq details[open] summary::after { transform: rotate(135deg); }

.faq summary:hover { color: var(--primary); }

.faq summary:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
}

.faq details p {
  max-width: 44em;
  margin: 0 0 28px;
  padding: 0 4px;
  color: var(--on-surface-variant);
  font-size: 1.0625rem;
  line-height: 1.65;
}

.faq details a {
  color: var(--primary);
  text-underline-offset: 3px;
}

.faq code {
  font-family: "Google Sans Code", ui-monospace, monospace;
  font-size: 0.92em;
}

/* ------------------------------------------------------------- modules */

.modules {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px clamp(112px, 13vw, 184px);
}

.section-head {
  max-width: 720px;
  margin: 0 auto clamp(48px, 6vw, 72px);
  text-align: center;
}

.section-head p { margin-left: auto; margin-right: auto; }

.bento {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-areas:
    "visuals visuals combat   combat"
    "visuals visuals movement player"
    "hud     tools   keys     keys";
  gap: 12px;
}

.tile-visuals { grid-area: visuals; }
.tile-combat { grid-area: combat; }
.tile-movement { grid-area: movement; }
.tile-player { grid-area: player; }
.tile-hud { grid-area: hud; }
.tile-tools { grid-area: tools; }
.tile-keys { grid-area: keys; }

/* Each tile is a Material container; accent tiles swap the whole ink set at once. */
.tile {
  --tile-bg: var(--surface-container);
  --tile-ink: var(--on-surface);
  --tile-muted: var(--on-surface-variant);
  --tile-edge: var(--outline-variant);
  --shape: var(--primary);
  --shape-ink: var(--on-primary);
  display: flex;
  flex-direction: column;
  min-height: 248px;
  padding: 28px;
  border-radius: 32px;
  background: var(--tile-bg);
  color: var(--tile-ink);
  box-shadow: inset 0 0 0 1px var(--glass-edge);
}

.tile-accent {
  --tile-bg: var(--primary-container);
  --tile-ink: var(--on-primary-container);
  --tile-muted: color-mix(in srgb, var(--on-primary-container) 80%, transparent);
  --tile-edge: color-mix(in srgb, var(--on-primary-container) 28%, transparent);
}

.tile-warm {
  --tile-bg: var(--tertiary-container);
  --tile-ink: var(--on-tertiary-container);
  --tile-muted: color-mix(in srgb, var(--on-tertiary-container) 80%, transparent);
  --tile-edge: color-mix(in srgb, var(--on-tertiary-container) 28%, transparent);
  --shape: var(--tertiary);
  --shape-ink: var(--on-tertiary);
}

.tile-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.tile h3 {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.02em;
  font-variation-settings: "ROND" 40;
}

.tile p {
  max-width: 26em;
  margin: 8px 0 0;
  color: var(--tile-muted);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.tile-visuals h3 { font-size: clamp(1.75rem, 1.3rem + 1vw, 2.25rem); }
.tile-visuals p { font-size: 1.0625rem; }

/* Module counts sit inside the client's Material shapes and turn a notch on hover. */
.count {
  position: relative;
  display: grid;
  flex: none;
  place-items: center;
  width: 64px;
  height: 64px;
  color: var(--shape-ink);
  font-size: 1.375rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.count svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  fill: var(--shape);
  transition: transform 0.7s var(--ease-spatial);
}

.count span { position: relative; }

.tile:hover .count svg { transform: rotate(45deg) scale(1.04); }

.tile-visuals .count { width: 104px; height: 104px; font-size: 2.25rem; }

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: auto 0 0;
  padding: 28px 0 0;
  list-style: none;
}

.chips li {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--tile-edge);
  border-radius: 8px;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
}

/* The large tile gets larger chips, so its twenty modules fill it instead of floating. */
.tile-visuals .chips { gap: 10px; }
.tile-visuals .chips li {
  height: 42px;
  padding: 0 16px;
  border-radius: 12px;
  font-size: 1rem;
}

.chips .more {
  border-color: transparent;
  background: color-mix(in srgb, currentColor 10%, transparent);
}

.chips .is-new { gap: 8px; }

.chips .new {
  padding: 3px 6px;
  border-radius: 6px;
  background: color-mix(in srgb, currentColor 12%, transparent);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

:is(.feature, .tile) code {
  font-family: "Google Sans Code", ui-monospace, monospace;
  font-size: 0.92em;
}

.tile-keys {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 24px 32px;
}

.keys {
  display: grid;
  gap: 12px;
  margin: 0;
}

.keys div {
  display: flex;
  align-items: center;
  gap: 16px;
}

.keys dt { margin: 0; }
.keys dd { margin: 0; color: var(--tile-muted); font-size: 0.9375rem; }

/* Keycaps; pressing the real key presses these too (hero.js). */
.keys kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 132px;
  height: 52px;
  padding: 0 18px;
  border-radius: 14px;
  background: var(--surface-highest);
  color: var(--on-surface);
  font: 500 1rem/1 var(--font);
  box-shadow:
    inset 0 -3px 0 var(--key-edge),
    inset 0 0 0 1px var(--glass-edge),
    0 10px 20px -10px var(--shadow);
  transition: transform 0.12s var(--ease-effects), box-shadow 0.12s var(--ease-effects);
}

.keys kbd.is-pressed {
  transform: translateY(2px);
  box-shadow:
    inset 0 -1px 0 var(--key-edge),
    inset 0 0 0 1px var(--glass-edge),
    0 4px 10px -8px var(--shadow);
}

@media (prefers-reduced-motion: no-preference) {
  .reveal .tile {
    transition:
      opacity 0.8s var(--ease-effects),
      transform 1s var(--ease-spatial);
    transition-delay: calc(var(--i, 0) * 70ms);
  }

  .reveal .bento:not(.is-in) .tile {
    opacity: 0;
    transform: translateY(32px) scale(0.97);
  }
}

/* ------------------------------------------------------------ download */

.download {
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 12px 12px;
}

/* The bookend to the hero: the same silk, glowing up from the stage's floor. */
.stage {
  --silk-base: var(--surface);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(72px, 9vw, 120px) clamp(16px, 5vw, 72px) clamp(16px, 5vw, 72px);
  border-radius: 40px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--glass-edge);
}

.stage-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 720px;
  margin: 0 auto;
  text-align: center;
}

.stage-head .stage-mark {
  width: 88px;
  height: 88px;
  margin: 0 0 28px;
  vertical-align: 0;
}

.stage-head h2 {
  margin: 0;
  font-size: clamp(2.75rem, 1.4rem + 4vw, 5rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.035em;
  font-variation-settings: "ROND" 40;
}

.stage-head p {
  margin: 20px 0 0;
  color: var(--on-surface-variant);
  font-size: clamp(1.0625rem, 0.98rem + 0.3vw, 1.25rem);
  line-height: 1.5;
}

.versions {
  position: relative;
  display: flex;
  width: fit-content;
  max-width: 100%;
  margin: 44px auto 0;
  padding: 5px;
  overflow-x: auto;
  border-radius: 999px;
  background: color-mix(in srgb, var(--surface-container) 92%, transparent);
  box-shadow: inset 0 0 0 1px var(--glass-edge);
  scrollbar-width: none;
}

.versions button {
  position: relative;
  z-index: 1;
  flex: none;
  height: 44px;
  padding: 0 22px;
  border-radius: 999px;
  color: var(--on-surface-variant);
  font-size: 1rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  transition: color 0.2s var(--ease-effects);
}

.versions button:hover { color: var(--on-surface); }
.versions button[aria-checked="true"] { color: var(--on-primary); }
.versions .pill { top: 5px; height: 44px; background: var(--primary); }

.versions button:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: -3px;
}

.version-note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 28px;
  margin: 18px 0 0;
  color: var(--on-surface-variant);
  font-size: 0.9375rem;
  text-align: center;
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 26px;
  padding: 0 11px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tone) 16%, transparent);
  color: var(--tone);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.status::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.status[data-tone="latest"] { --tone: var(--primary); }
.status[data-tone="stable"] { --tone: var(--code-number); }
.status[data-tone="experimental"] { --tone: var(--tertiary); }
.status[data-tone="legacy"] { --tone: var(--text-muted); }

.options {
  display: grid;
  max-width: 640px;
  margin: clamp(48px, 6vw, 72px) auto 0;
}

/* Tinted glass over the glowing floor (no backdrop blur: the silk moves every frame, and
   re-blurring it would cost more than it shows). */
.option {
  display: flex;
  flex-direction: column;
  padding: clamp(24px, 3vw, 36px);
  border-radius: 32px;
  background: color-mix(in srgb, var(--surface) 76%, transparent);
  box-shadow:
    inset 0 0 0 1px var(--glass-edge),
    inset 0 1px 0 0 var(--glass-edge),
    0 30px 60px -30px var(--shadow);
}

.option-launcher {
  background:
    linear-gradient(160deg, color-mix(in srgb, var(--primary-container) 55%, transparent), transparent 70%),
    color-mix(in srgb, var(--surface) 76%, transparent);
}

.app-icon {
  display: grid;
  place-items: center;
  width: 60px;
  height: 60px;
  margin-bottom: 24px;
  border-radius: 18px;
  background: linear-gradient(145deg, var(--primary), color-mix(in srgb, var(--primary) 55%, var(--tertiary)));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.35), 0 12px 24px -12px var(--shadow);
}

.app-icon svg { width: 32px; height: 32px; fill: var(--on-primary); }

.option h3 {
  margin: 0;
  font-size: clamp(1.5rem, 1.2rem + 0.8vw, 1.875rem);
  font-weight: 500;
  letter-spacing: -0.025em;
  font-variation-settings: "ROND" 40;
}

.option > p {
  margin: 10px 0 0;
  color: var(--on-surface-variant);
  font-size: 1rem;
  line-height: 1.55;
}

.option .points { margin-top: 24px; }

.option-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  margin-top: auto;
  padding-top: 32px;
}

.option-alt {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.875rem;
  line-height: 1.5;
}

.option-alt a {
  color: var(--on-surface);
  text-decoration: underline;
  text-decoration-color: var(--hairline);
  text-underline-offset: 3px;
  transition: text-decoration-color 0.2s var(--ease-effects);
}

.option-alt a:hover { text-decoration-color: currentColor; }

@media (prefers-reduced-motion: no-preference) {
  .reveal .option {
    transition:
      opacity 0.9s var(--ease-effects),
      transform 1.1s var(--ease-spatial);
  }

  .reveal .options:not(.is-in) .option {
    opacity: 0;
    transform: translateY(40px);
  }
}

/* -------------------------------------------------------------- footer */

/* An inverted sheet rising from the page's edge: it always takes the other colour scheme,
   and every light-dark() token inside follows. */
.footer {
  color-scheme: light;
  width: calc(100% - 24px);
  max-width: 1296px;
  margin: 0 auto;
  padding-top: clamp(64px, 8vw, 104px);
  overflow: hidden;
  border-radius: 40px 40px 0 0;
  background: var(--surface);
  color: var(--on-surface);
  box-shadow: inset 0 1px 0 var(--glass-edge);
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .footer { color-scheme: dark; }
}

:root[data-theme="light"] .footer { color-scheme: dark; }

.footer-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px;
}

.footer-top {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 2fr);
  gap: 48px;
  padding-bottom: 56px;
}

.footer-brand > p {
  margin: 14px 0 0;
  color: var(--on-surface-variant);
  font-size: 1rem;
}

.footer-label {
  margin: 0 0 14px;
  color: var(--text-muted);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.01em;
}

.theme-block { margin-top: 40px; }
html:not(.js) .theme-block { display: none; }

/* The same segmented capsule as the version picker; each option carries its shape. */
.theme {
  position: relative;
  display: inline-flex;
  padding: 4px;
  border-radius: 999px;
  background: var(--surface-container);
  box-shadow: inset 0 0 0 1px var(--glass-edge);
}

.theme button {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px 0 12px;
  border-radius: 999px;
  color: var(--on-surface-variant);
  font-size: 0.9375rem;
  font-weight: 500;
  transition: color 0.2s var(--ease-effects);
}

.theme button svg {
  width: 16px;
  height: 16px;
  transition: transform 0.6s var(--ease-spatial);
}

.theme button:hover { color: var(--on-surface); }
.theme button:hover svg { transform: rotate(45deg); }
.theme button[aria-checked="true"] { color: var(--on-secondary-container); }
.theme .pill { top: 4px; height: 40px; background: var(--secondary-container); }

.theme button:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: -3px;
}

.footer-links {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 32px;
}

.footer-links ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.footer-links a {
  display: inline-block;
  padding: 5px 0;
  color: var(--on-surface);
  font-size: 0.9375rem;
  text-decoration: none;
  transition: color 0.2s var(--ease-effects);
}

.footer-links a:hover,
.footer-links a[aria-current="page"] { color: var(--primary); }

:is(.footer-links a, .footer-brand .brand):focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 3px;
  border-radius: 6px;
}

.footer-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 32px;
  padding: 20px 0;
  border-top: 1px solid var(--hairline);
  color: var(--text-muted);
  font-size: 0.8125rem;
  line-height: 1.5;
}

.footer-bar p { margin: 0; }
.footer-bar span { margin: 0 0.45em; opacity: 0.6; }

/* The lockup at monumental size. Glyphs rise out of the sheet's edge, lean towards the
   pointer and share one gradient across the word (hero.js sets the geometry variables).
   Everything here is static paint and the glyphs only move by transform: no filters, masks,
   looping animations or per-frame backgrounds, so hovering stays cheap. */
.wordmark {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Headroom for lifted glyphs. */
  margin: calc(clamp(32px, 5vw, 72px) - 0.22em) 0 -0.17em;
  padding-top: 0.22em;
  font-size: min(24vw, 360px);
  font-weight: 500;
  line-height: 0.9;
  letter-spacing: -0.055em;
  user-select: none;
  /* Keeps the glyphs' per-frame changes from reflowing or repainting the rest of the page. */
  contain: layout paint style;
}

/* A soft coloured pool under the letters, painted once. */
.wordmark::before {
  content: "";
  position: absolute;
  inset: 20% 8% -10%;
  z-index: -1;
  background: radial-gradient(closest-side, var(--wordmark-shadow), transparent);
}

.wordmark-mark {
  flex: none;
  width: 0.9em;
  height: 0.9em;
  margin-right: -0.02em;
  overflow: visible;
}

/* Rise, lift and tilt are one transform per part, driven by variables (hero.js) and animated
   by transitions, which the browser runs on the compositor. The overshooting curve gives the
   Material spring feel without script running every frame. */
.wordmark-mark,
.glyph {
  --rise: 0;
  --lift: 0;
  --tilt: 0;
  transform:
    translateY(calc(var(--rise) * 112%))
    translateY(calc(var(--lift) * -0.07em))
    rotate(calc(var(--tilt) * 1deg));
  transition:
    transform 0.7s var(--ease-spatial),
    font-variation-settings 0.35s var(--ease-effects);
  will-change: transform;
}

.wordmark.is-waiting :is(.wordmark-mark, .glyph) { --rise: 1; }

.wordmark.is-entering :is(.wordmark-mark, .glyph) {
  transition-duration: 1.1s;
  transition-delay: calc(var(--i, 0) * 75ms);
}

.glyph.is-round { font-variation-settings: "ROND" 100; }

.wordmark-type {
  --word-w: 2.4em;
  --word-h: 0.9em;
  position: relative;
  display: inline-flex;
}

.glyph {
  --x: 0px;
  display: inline-block;
  /* The tight tracking lets ink overhang each glyph's box, and background-clip: text only
     paints inside it; this bleed widens the box without moving the letters. */
  padding: 0.14em 0.08em 0.06em;
  margin: -0.14em -0.08em -0.06em;
  /* The fade into the sheet's colour is part of each glyph's own paint, so it costs nothing
     when the glyph moves. */
  background-image:
    linear-gradient(to bottom, transparent 42%, var(--surface) 96%),
    url("assets/grain.png"),
    linear-gradient(100deg, var(--wordmark-a) 0%, var(--wordmark-b) 38%, var(--wordmark-c) 62%, var(--wordmark-a) 100%);
  /* The gradient overshoots the word by 0.2em on each side: with this tracking the outer
     glyphs' ink reaches past the word's box, and past the gradient it would turn transparent. */
  background-size: 100% 100%, 64px 64px, calc(var(--word-w) + 0.4em) var(--word-h);
  background-position: 0 0, 0 0, calc(-0.2em - var(--x)) 0;
  background-repeat: no-repeat, repeat, no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-variation-settings: "ROND" 40;
}

/* ----------------------------------------------------------- changelog */

.page-top { padding: 0 12px; }

.page-stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 32px;
  max-width: 1296px;
  margin: 8px auto 0;
  padding-top: clamp(88px, 10vw, 136px);
  padding-bottom: clamp(40px, 5vw, 64px);
}

.log-head h1 {
  margin: 0;
  font-size: clamp(3rem, 1.2rem + 5.4vw, 7rem);
  font-weight: 500;
  line-height: 0.95;
  letter-spacing: -0.04em;
  font-variation-settings: "ROND" 40;
}

.log-head p {
  margin: 20px 0 0;
  color: var(--on-surface-variant);
  font-size: clamp(1.0625rem, 0.98rem + 0.3vw, 1.25rem);
}

/* Version odometer: each digit is a 0-9 strip in a one-digit window, moved by transform
   (hero.js sets --d), so it rolls on the compositor. The overshooting curve lets a
   neighbouring digit peek past the window's edge, like a real counter settling. */
.odometer {
  display: inline-flex;
  margin: 0;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.odo-digit {
  display: inline-block;
  height: 1em;
  overflow: hidden;
}

.odo-strip {
  display: flex;
  flex-direction: column;
  transform: translateY(calc(var(--d, 0) * -1em));
  transition: transform 1s var(--ease-spatial) calc(var(--p, 0) * 70ms);
  will-change: transform;
}

.odo-strip span { height: 1em; }
.odo-dot { color: var(--primary); }

.odometer-hero {
  font-size: clamp(4.5rem, 1.5rem + 9vw, 11rem);
  margin-bottom: -0.06em;
}

.log {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  align-items: start;
  gap: clamp(40px, 6vw, 104px);
  max-width: 1200px;
  margin: 0 auto;
  padding: clamp(56px, 7vw, 96px) 24px clamp(112px, 13vw, 184px);
}

.rail {
  position: sticky;
  top: 32px;
}

/* Takes over from the stage's odometer once that scrolls away (site.js toggles .is-shown).
   Until then it is folded to nothing, so the rail starts with the version list. */
.rail-now {
  display: grid;
  grid-template-rows: 1fr;
  transition:
    grid-template-rows 0.6s var(--ease-effects),
    opacity 0.5s var(--ease-effects),
    transform 0.7s var(--ease-spatial);
}

.rail-now > div {
  min-height: 0;
  overflow: hidden;
  padding-bottom: 28px;
}

.rail-now:not(.is-shown) {
  grid-template-rows: 0fr;
  opacity: 0;
  transform: translateY(12px);
}

.odometer-rail { font-size: 4rem; }

.rail-title {
  min-height: 2.9em;
  margin: 12px 0 0;
  color: var(--on-surface-variant);
  font-size: 0.9375rem;
  line-height: 1.45;
}

.rail-versions { position: relative; }

.rail-versions ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

.rail-versions a {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 44px;
  padding: 0 16px;
  border-radius: 999px;
  color: var(--on-surface-variant);
  font-size: 1rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  transition: color 0.2s var(--ease-effects), opacity 0.3s var(--ease-effects);
}

.rail-versions a:hover { color: var(--on-surface); }
.rail-versions a[aria-current="true"] { color: var(--on-secondary-container); }
.rail-versions a.is-empty { opacity: 0.38; }
.rail-versions time { color: var(--text-muted); font-size: 0.875rem; font-weight: 400; }

.rail-versions .pill {
  top: 0;
  width: 100%;
  height: 0;
  background: var(--secondary-container);
}

.rail-label {
  margin: 32px 0 12px;
  color: var(--text-muted);
  font-size: 0.8125rem;
  font-weight: 500;
}

/* Material filter chips; the pressed one is filled. */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.filter {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 14px;
  border: 1px solid var(--outline-variant);
  border-radius: 10px;
  color: var(--on-surface-variant);
  font-size: 0.875rem;
  font-weight: 500;
  transition: background-color 0.2s var(--ease-effects), border-color 0.2s var(--ease-effects), color 0.2s var(--ease-effects);
}

.filter:hover { color: var(--on-surface); }
.filter span { color: var(--text-muted); font-variant-numeric: tabular-nums; }

.filter i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--tone);
}

.filter[aria-pressed="true"] {
  border-color: transparent;
  background: var(--secondary-container);
  color: var(--on-secondary-container);
}

.filter[aria-pressed="true"] span { color: inherit; opacity: 0.7; }

:is(.rail-versions a, .filter):focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
}

/* Entry types keep the client's hues (EntryType.java), tuned for both schemes. */
[data-type="added"] { --tone: var(--type-added); }
[data-type="improved"] { --tone: var(--type-improved); }
[data-type="changed"] { --tone: var(--type-changed); }
[data-type="fixed"] { --tone: var(--type-fixed); }
[data-type="removed"] { --tone: var(--type-removed); }

.releases {
  display: grid;
  gap: clamp(104px, 12vw, 168px);
}

.release { scroll-margin-top: 32px; }

.release-head h2 {
  margin: 0;
  font-size: clamp(2rem, 1.2rem + 2.3vw, 3.25rem);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.03em;
  font-variation-settings: "ROND" 40;
  text-wrap: balance;
}

.release-meta {
  margin: 16px 0 0;
  color: var(--text-muted);
  font-size: 1rem;
}

.release-meta span { margin: 0 0.4em; }

/* Highlights as a small bento; each tile wears one of the client's Material shapes. */
.highlights {
  --shape-1: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 9.81C50.48 9.44 50.97 9.07 51.45 8.7 62.76 0 78.77 1.04 88.87 11.13 98.96 21.23 100 37.24 91.3 48.55 90.93 49.03 90.56 49.52 90.19 50 90.56 50.48 90.93 50.97 91.3 51.45 100 62.76 98.96 78.77 88.87 88.87 78.77 98.96 62.76 100 51.45 91.3 50.97 90.93 50.48 90.56 50 90.19 49.52 90.56 49.03 90.93 48.55 91.3 37.24 100 21.23 98.96 11.13 88.87 1.04 78.77 0 62.76 8.7 51.45 9.07 50.97 9.44 50.48 9.81 50 9.44 49.52 9.07 49.03 8.7 48.55 0 37.24 1.04 21.23 11.13 11.13 21.23 1.04 37.24 0 48.55 8.7 49.03 9.07 49.52 9.44 50 9.81Z'/%3E%3C/svg%3E");
  --shape-2: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 1.42C53.65 1.42 57.3 2.73 60.19 5.35 63.13 8.01 67 9.42 70.96 9.27 78.76 8.97 85.51 14.63 86.57 22.37 87.11 26.3 89.16 29.86 92.3 32.29 98.47 37.08 100 45.76 95.84 52.36 93.72 55.72 93.01 59.77 93.85 63.65 95.5 71.28 91.09 78.91 83.66 81.3 79.88 82.51 76.73 85.15 74.88 88.67 71.24 95.57 62.96 98.58 55.73 95.63 52.06 94.13 47.94 94.13 44.27 95.63 37.04 98.58 28.76 95.57 25.12 88.67 23.27 85.15 20.12 82.51 16.34 81.3 8.91 78.91 4.5 71.28 6.15 63.65 6.99 59.77 6.28 55.72 4.16 52.36 0 45.76 1.53 37.08 7.7 32.29 10.84 29.86 12.89 26.3 13.43 22.37 14.49 14.63 21.24 8.97 29.04 9.27 33 9.42 36.87 8.01 39.81 5.35 42.7 2.73 46.35 1.42 50 1.42Z'/%3E%3C/svg%3E");
  --shape-3: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M18.66 27.24C19.36 26.28 19.73 25.07 19.63 23.81 19.4 20.81 19.17 17.82 18.94 14.83 18.65 10.99 22.5 8.18 26.07 9.63 28.87 10.77 31.66 11.91 34.46 13.04 36.81 14 39.5 13.12 40.83 10.96 42.4 8.4 43.98 5.85 45.55 3.29 47.57.01 52.34 0 54.37 3.27 55.96 5.84 57.56 8.4 59.15 10.97 60.49 13.12 63.18 13.99 65.53 13.02 68.3 11.88 71.08 10.74 73.86 9.6 77.42 8.13 81.28 10.92 81 14.76 80.78 17.78 80.56 20.79 80.35 23.8 80.16 26.33 81.83 28.62 84.3 29.21 87.21 29.92 90.13 30.63 93.05 31.33 96.79 32.24 98.27 36.77 95.79 39.72 93.84 42.02 91.9 44.33 89.95 46.64 88.32 48.58 88.32 51.41 89.96 53.34 91.91 55.63 93.85 57.92 95.8 60.2 98.29 63.14 96.83 67.67 93.09 68.6 90.16 69.32 87.23 70.04 84.3 70.76 81.84 71.37 80.17 73.67 80.37 76.19 80.6 79.19 80.83 82.18 81.06 85.17 81.35 89.02 77.5 91.82 73.93 90.37 71.13 89.23 68.34 88.09 65.54 86.96 63.19 86 60.5 86.88 59.17 89.04 57.6 91.6 56.02 94.15 54.45 96.71 52.43 99.99 47.66 100 45.63 96.73 44.04 94.16 42.44 91.6 40.85 89.03 39.51 86.88 36.82 86.01 34.47 86.98 31.7 88.12 28.92 89.26 26.14 90.4 22.58 91.87 18.72 89.08 19 85.24 19.22 82.22 19.44 79.21 19.65 76.2 19.84 73.67 18.17 71.38 15.7 70.79 12.79 70.08 9.87 69.37 6.95 68.67 3.21 67.76 1.73 63.23 4.21 60.28 6.16 57.98 8.1 55.67 10.05 53.36 11.68 51.42 11.68 48.59 10.04 46.66 8.09 44.37 6.15 42.08 4.2 39.8 1.71 36.86 3.17 32.33 6.91 31.4 9.84 30.68 12.77 29.96 15.7 29.24 16.93 28.93 17.96 28.21 18.66 27.24Z'/%3E%3C/svg%3E");
  --shape-4: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M91.21 91.21C85.78 96.64 78.28 100 70 100 56.67 100 43.33 100 30 100 13.43 100 0 86.57 0 70 0 56.67 0 43.33 0 30 0 13.43 13.43 0 30 0 43.33 0 56.67 0 70 0 86.57 0 100 13.43 100 30 100 43.33 100 56.67 100 70 100 78.28 96.64 85.78 91.21 91.21Z'/%3E%3C/svg%3E");
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
  margin: 40px 0 0;
  padding: 0;
  list-style: none;
}

.highlights li {
  position: relative;
  min-height: 176px;
  padding: 80px 24px 24px;
  border-radius: 28px;
  background: var(--surface-container);
  box-shadow: inset 0 0 0 1px var(--glass-edge);
  font-size: 1.0625rem;
  line-height: 1.45;
}

.highlights li::before {
  content: "";
  position: absolute;
  top: 24px;
  left: 24px;
  width: 36px;
  height: 36px;
  background: var(--primary);
  -webkit-mask: var(--shape-1) center / contain no-repeat;
  mask: var(--shape-1) center / contain no-repeat;
  transition: transform 0.7s var(--ease-spatial);
}

.highlights li:nth-child(4n + 2)::before { -webkit-mask-image: var(--shape-2); mask-image: var(--shape-2); }
.highlights li:nth-child(4n + 3)::before { -webkit-mask-image: var(--shape-3); mask-image: var(--shape-3); }
.highlights li:nth-child(4n + 4)::before { -webkit-mask-image: var(--shape-4); mask-image: var(--shape-4); }
.highlights li:hover::before { transform: rotate(45deg); }

/* Four highlights sit as a square; a last tile left alone on its row takes the whole row. */
.highlights:has(> li:nth-child(4):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.highlights li:last-child:nth-child(3n + 1):not(:nth-child(4)) { grid-column: 1 / -1; min-height: 0; }

.highlights li:first-child {
  background: var(--primary-container);
  color: var(--on-primary-container);
}

.highlights li:first-child::before { background: var(--on-primary-container); }

.entries {
  margin: 40px 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--hairline);
}

.entries li {
  display: grid;
  grid-template-columns: 116px minmax(0, 1fr);
  align-items: baseline;
  gap: 20px;
  padding: 18px 0;
  border-bottom: 1px solid var(--hairline);
}

.entries p {
  margin: 0;
  font-size: 1rem;
  line-height: 1.6;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  width: fit-content;
  height: 26px;
  padding: 0 11px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tone) 14%, transparent);
  color: var(--tone);
  font-size: 0.8125rem;
  font-weight: 600;
}

.badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

/* Filtering: highlights are untyped, so they step aside while one type is shown. */
.releases:not([data-filter="all"]) .highlights { display: none; }
.releases[data-filter="added"] .entries li:not([data-type="added"]),
.releases[data-filter="improved"] .entries li:not([data-type="improved"]),
.releases[data-filter="changed"] .entries li:not([data-type="changed"]),
.releases[data-filter="fixed"] .entries li:not([data-type="fixed"]),
.releases[data-filter="removed"] .entries li:not([data-type="removed"]) { display: none; }

@media (prefers-reduced-motion: no-preference) {
  .reveal .release {
    transition:
      opacity 0.9s var(--ease-effects),
      transform 1.1s var(--ease-spatial);
  }

  .reveal .release:not(.is-in) {
    opacity: 0;
    transform: translateY(40px);
  }
}

/* --------------------------------------------------------------- legal */

/* Imprint and privacy: one readable column, section names on the same 250px rail as the
   changelog, so every secondary page shares the grid. */
.legal {
  max-width: 1200px;
  margin: 0 auto;
  padding: clamp(64px, 9vw, 128px) 24px clamp(112px, 13vw, 184px);
}

.legal-head h1 {
  margin: 0;
  font-size: clamp(3rem, 1.2rem + 5.4vw, 7rem);
  font-weight: 500;
  line-height: 0.95;
  letter-spacing: -0.04em;
  font-variation-settings: "ROND" 40;
}

.legal-head p {
  max-width: 36em;
  margin: 24px 0 0;
  color: var(--on-surface-variant);
  font-size: clamp(1.0625rem, 0.98rem + 0.3vw, 1.25rem);
  line-height: 1.5;
}

.legal-body {
  margin-top: clamp(56px, 7vw, 96px);
  border-top: 1px solid var(--hairline);
}

.legal-section {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: 16px clamp(40px, 6vw, 104px);
  padding: 36px 0;
  border-bottom: 1px solid var(--hairline);
}

.legal-section h2 {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 500;
  line-height: 1.6;
}

.legal-section p {
  max-width: 44em;
  margin: 0 0 1em;
  color: var(--on-surface-variant);
  font-size: 1.0625rem;
  line-height: 1.7;
}

.legal-section p:last-child { margin-bottom: 0; }

.legal-section address {
  margin-bottom: 1em;
  font-size: 1.375rem;
  font-style: normal;
  line-height: 1.45;
  letter-spacing: -0.01em;
}

.legal-section address:last-child { margin-bottom: 0; }

.legal-section a {
  color: var(--primary);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
  text-underline-offset: 3px;
  transition: text-decoration-color 0.2s var(--ease-effects);
}

.legal-section a:hover { text-decoration-color: currentColor; }

.legal-updated {
  margin: 32px 0 0;
  color: var(--text-muted);
  font-size: 0.875rem;
}

/* -------------------------------------------------------------- videos */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.videos {
  max-width: 1200px;
  margin: 0 auto;
  padding: clamp(48px, 6vw, 80px) 24px clamp(112px, 13vw, 184px);
}

/* Two-click privacy: posters are drawn locally; YouTube loads on play, or everywhere once
   the visitor allows it (site.js). */
.yt-consent {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 20px 24px;
  margin-bottom: clamp(40px, 5vw, 64px);
  padding: 22px 24px;
  border-radius: 28px;
  background: var(--surface-container);
  box-shadow: inset 0 0 0 1px var(--glass-edge);
}

.yt-consent-icon { width: 28px; height: 28px; fill: var(--primary); }

.yt-consent h2 {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 500;
}

.yt-consent p {
  margin: 4px 0 0;
  color: var(--on-surface-variant);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.yt-consent a {
  color: var(--primary);
  text-underline-offset: 3px;
}

/* Material 3 switch. */
.switch {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  user-select: none;
}

.switch input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.switch-track {
  position: relative;
  flex: none;
  width: 52px;
  height: 32px;
  border: 2px solid var(--text-muted);
  border-radius: 999px;
  background: var(--surface-highest);
  transition: background-color 0.2s var(--ease-effects), border-color 0.2s var(--ease-effects);
}

.switch-thumb {
  position: absolute;
  top: 50%;
  left: 6px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--text-muted);
  transform: translateY(-50%);
  transition: transform 0.35s var(--ease-spatial), width 0.2s var(--ease-effects), height 0.2s var(--ease-effects), background-color 0.2s var(--ease-effects);
}

.switch input:checked + .switch-track { border-color: var(--primary); background: var(--primary); }

.switch input:checked + .switch-track .switch-thumb {
  width: 24px;
  height: 24px;
  background: var(--on-primary);
  transform: translate(18px, -50%);
}

.switch input:focus-visible + .switch-track {
  outline: 3px solid var(--primary);
  outline-offset: 3px;
}

.switch-label {
  font-size: 0.9375rem;
  font-weight: 500;
  white-space: nowrap;
}

.video-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(32px, 4vw, 48px) 16px;
  margin-top: clamp(56px, 7vw, 88px);
}

/* A local poster in the silk colours, so nothing has to come from YouTube before play. */
.poster {
  --gx: 18%;
  --gy: 12%;
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 28px;
  background:
    radial-gradient(80% 95% at var(--gx) var(--gy), color-mix(in srgb, var(--silk-glow) 42%, transparent), transparent 62%),
    radial-gradient(70% 85% at 92% 100%, color-mix(in srgb, var(--silk-warm) 38%, transparent), transparent 66%),
    linear-gradient(160deg, var(--primary-container), var(--surface-container));
  box-shadow: inset 0 0 0 1px var(--glass-edge);
  isolation: isolate;
}

.video-grid .video:nth-child(3n + 1) .poster { --gx: 82%; --gy: 8%; }
.video-grid .video:nth-child(3n + 2) .poster { --gx: 40%; --gy: 100%; }
.video-grid .video:nth-child(3n + 3) .poster { --gx: 8%; --gy: 70%; }

.poster img,
.poster iframe {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
}

.poster iframe { z-index: 2; }

.play {
  width: clamp(64px, 7vw, 88px);
  height: clamp(64px, 7vw, 88px);
}

.video-featured .play { width: clamp(80px, 9vw, 120px); height: clamp(80px, 9vw, 120px); }

.play svg {
  width: 100%;
  height: 100%;
  filter: drop-shadow(0 10px 24px rgb(0 0 0 / 0.28));
  transition: transform 0.6s var(--ease-spatial);
}

.play-shape { fill: var(--primary); }
.play-icon { fill: var(--on-primary); }

.poster:hover .play svg,
.poster:focus-visible .play svg { transform: rotate(45deg) scale(1.06); }

.poster:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 4px;
}

.duration {
  position: absolute;
  right: 16px;
  bottom: 16px;
  padding: 4px 9px;
  border-radius: 8px;
  background: rgb(0 0 0 / 0.62);
  color: #fff;
  font-size: 0.8125rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.video h2,
.video h3 {
  margin: 20px 0 0;
  font-size: 1.1875rem;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.01em;
}

.video-featured h2 {
  margin-top: 28px;
  font-size: clamp(1.5rem, 1.1rem + 1.2vw, 2.25rem);
  line-height: 1.15;
  letter-spacing: -0.025em;
  font-variation-settings: "ROND" 40;
}

.video-featured .poster { border-radius: 36px; }

.video-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  margin: 10px 0 0;
  color: var(--text-muted);
  font-size: 0.9375rem;
}

.source {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 10px;
  border-radius: 999px;
  background: var(--surface-high);
  color: var(--on-surface-variant);
  font-size: 0.75rem;
  font-weight: 600;
}

.source.is-official {
  background: var(--secondary-container);
  color: var(--on-secondary-container);
}

/* Once playing, the poster's own chrome steps aside for the player. */
.poster.is-playing .play,
.poster.is-playing .duration { visibility: hidden; }

/* ------------------------------------------------------------ entrance */

@media (prefers-reduced-motion: no-preference) {
  .js .bar { animation: fade 1s var(--ease-effects) 0.1s both; }
  .js .kicker { animation: lift 1s var(--ease-spatial) 0.02s both; }
  .js .line > span { animation: rise 1.1s var(--ease-spatial-slow) both; }
  .js .line + .line > span { animation-delay: 0.07s; }
  .js .lede { animation: lift 1s var(--ease-spatial) 0.2s both; }
  .js .actions { animation: lift 1s var(--ease-spatial) 0.28s both; }
  .js .meta { animation: lift 1s var(--ease-spatial) 0.34s both; }
  .js .product { animation: lift-far 1.3s var(--ease-spatial) 0.42s both; }

  .js:not(.ready) :is(.bar, .kicker, .line > span, .lede, .actions, .meta, .product) {
    animation-play-state: paused;
  }
}

@keyframes rise { from { transform: translateY(108%); } }
@keyframes lift { from { opacity: 0; transform: translateY(18px); } }
@keyframes lift-far { from { opacity: 0; transform: translateY(56px); } }
@keyframes fade { from { opacity: 0; } }

/* ---------------------------------------------------------- responsive */

@media (max-width: 859px) {
  .bar { grid-template-columns: 1fr auto; padding: 16px 20px; }
  .links { display: none; }

  .feature,
  .feature.is-flipped { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .feature.is-flipped .feature-copy { order: 0; }

  .bento {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas:
      "visuals  visuals"
      "combat   combat"
      "movement player"
      "hud      tools"
      "keys     keys";
  }

  .facts dl { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 0; }
  .facts div:nth-child(3) { padding-left: 0; border-left: 0; }

  .footer-top { grid-template-columns: minmax(0, 1fr); }

  .page-stage { grid-template-columns: minmax(0, 1fr); }
  .log { grid-template-columns: minmax(0, 1fr); }
  .rail { position: static; }
  .rail-now, .rail-versions { display: none; }
  .rail-label { margin-top: 0; }

  .legal-section { grid-template-columns: minmax(0, 1fr); padding: 28px 0; }

  .yt-consent { grid-template-columns: auto minmax(0, 1fr); }
  .yt-consent .switch { grid-column: 1 / -1; }
  .video-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 599px) {
  .intro { padding-top: 48px; }
  .lede { margin-top: 20px; }
  .actions { margin-top: 28px; width: 100%; }
  .actions .btn { flex: 1 1 auto; }

  .product { width: calc(100% - 24px); margin-top: 72px; }
  .window { padding: 6px; border-radius: 22px; }
  .screens { border-radius: 16px; }
  .tabs { padding: 4px; }
  .tabs button { height: 36px; padding: 0 12px; font-size: 0.8125rem; }
  .tabs .pill { top: 4px; height: 36px; }

  .features { padding-left: 16px; padding-right: 16px; }
  .feature-copy { padding: 0 6px; }
  .feature-visual { aspect-ratio: 1; border-radius: 28px; }
  .feature-visual-bleed { aspect-ratio: 6 / 5; }
  .feature-visual-wide { aspect-ratio: 3 / 2; padding: 12px; }

  .modules { padding-left: 16px; padding-right: 16px; }
  .bento {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "visuals" "combat" "movement" "player" "hud" "tools" "keys";
  }
  .tile { min-height: 0; padding: 24px; border-radius: 28px; }
  .tile-visuals .count { width: 84px; height: 84px; font-size: 1.875rem; }
  .tile-visuals .chips li { height: 34px; padding: 0 12px; border-radius: 8px; font-size: 0.875rem; }
  .tile-keys { grid-template-columns: minmax(0, 1fr); }

  .download { padding: 0 8px 8px; }
  .stage { border-radius: 28px; }
  .stage-head .stage-mark { width: 64px; height: 64px; margin-bottom: 20px; }
  .versions { margin-top: 32px; }
  .versions button { height: 40px; padding: 0 14px; font-size: 0.9375rem; }
  .versions .pill { height: 40px; }
  .option { border-radius: 26px; }
  .option-actions .btn { align-self: stretch; }

  .footer { width: calc(100% - 16px); border-radius: 28px 28px 0 0; }

  .page-top { padding: 0 8px; }
  .legal { padding-left: 20px; padding-right: 20px; }
  .videos { padding-left: 16px; padding-right: 16px; }
  .video-grid { grid-template-columns: minmax(0, 1fr); }
  .poster, .video-featured .poster { border-radius: 22px; }
  .legal-section address { font-size: 1.1875rem; }
  .log { padding-left: 20px; padding-right: 20px; }
  .filters { flex-wrap: nowrap; overflow-x: auto; margin: 0 -20px; padding: 0 20px; scrollbar-width: none; }
  .filter { flex: none; }
  .entries li { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .highlights,
  .highlights:has(> li:nth-child(4):last-child) { grid-template-columns: minmax(0, 1fr); }
  .highlights li { min-height: 0; padding-top: 76px; }
  .footer-inner { padding: 0 20px; }
  .footer-links { gap: 16px; }
  .theme button { padding: 0 14px 0 10px; }
}
