html {
  scroll-behavior: smooth;
}
body {
  margin: 0;
  overflow-x: hidden;
  background: #f4ede3;
  color: #2f211b;
  font-family: "DM Sans", sans-serif;
  -webkit-font-smoothing: antialiased;
}
* {
  box-sizing: border-box;
}
a {
  color: inherit;
  text-decoration: none;
}
a:hover {
  color: #557789;
}
::selection {
  background: rgba(120, 155, 173, 0.28);
}
:focus-visible {
  outline: 2px solid #557789;
  outline-offset: 3px;
}
@keyframes kv-up {
  from {
    opacity: 0;
    transform: translateY(26px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes kv-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes kv-rise {
  from {
    opacity: 0;
    transform: translateY(40px) rotate(var(--r, 0deg));
  }
  to {
    opacity: 1;
    transform: translateY(0) rotate(var(--r, 0deg));
  }
}
@keyframes kv-spin {
  to {
    transform: rotate(360deg);
  }
}
/* The marquee track holds four identical groups, so shifting by a quarter of it
   lands exactly one group along and the loop restarts invisibly. Three groups
   stay on screen at the reset point, which keeps wide viewports covered. */
@keyframes kv-marquee {
  to {
    transform: translateX(-25%);
  }
}
@keyframes kv-floatA {
  0%,
  100% {
    transform: translate(-108px, 6px) rotate(-7deg) scale(0.86);
  }
  50% {
    transform: translate(-108px, -10px) rotate(-6deg) scale(0.86);
  }
}
@keyframes kv-floatB {
  0%,
  100% {
    transform: translate(90px, -6px) rotate(5deg);
  }
  50% {
    transform: translate(90px, 12px) rotate(4deg);
  }
}
@keyframes kv-grow {
  from {
    width: 0;
  }
  to {
    width: 32%;
  }
}
@keyframes kv-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* hover + focus states */
.x1:hover {
  opacity: 1;
}
.x2:hover {
  opacity: 1;
}
.x3:hover {
  opacity: 1;
}
.x4:hover {
  opacity: 1;
}
.x5:hover {
  background: #2f211b;
  border-color: #2f211b;
  color: #f4ede3;
}
.x6:hover {
  transform: translateY(-3px);
  box-shadow: 0 16px 30px rgba(47, 33, 27, 0.22);
}
.x7:hover {
  background: rgba(47, 33, 27, 0.05);
  border-color: rgba(47, 33, 27, 0.45);
}
.x8:hover {
  background: rgba(47, 33, 27, 0.035);
}
.x9:hover {
  background: rgba(47, 33, 27, 0.035);
}
.x10:hover {
  background: rgba(47, 33, 27, 0.035);
}
.x11:hover {
  border-color: rgba(169, 192, 204, 0.4);
}
.x12:hover {
  border-color: rgba(169, 192, 204, 0.4);
}
/* The app mockup cards carry their resting tilt as an inline transform, which
   outranks these rules on specificity. !important lets the hover state win. */
.x13:hover {
  transform: rotate(0deg) translateY(-10px) scale(1.03) !important;
  box-shadow: 0 32px 46px rgba(0, 0, 0, 0.24) !important;
}
.x14:hover {
  border-color: rgba(169, 192, 204, 0.4);
}
.x15:hover {
  transform: rotate(0deg) translateY(-10px) scale(1.03) !important;
  box-shadow: 0 34px 52px rgba(18, 13, 10, 0.3) !important;
}
.x16:hover {
  background: #789bad;
  color: #1c2b32;
}
.x17:hover {
  border-color: rgba(169, 192, 204, 0.4);
}
.x18:hover {
  transform: rotate(0deg) translateY(-10px) scale(1.03) !important;
  box-shadow: 0 34px 50px rgba(18, 13, 10, 0.3) !important;
}
.x19:focus {
  border-color: #f4ede3;
  background: rgba(255, 255, 255, 0.16);
}
.x20:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 26px rgba(20, 30, 36, 0.28);
}

/* FAQ accordion */
.faq-list {
  border-top: 1px solid rgba(47, 33, 27, 0.16);
}
.faq-item {
  border-bottom: 1px solid rgba(47, 33, 27, 0.16);
}
.faq-item summary {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 82px;
  padding: 20px 62px 20px 0;
  font-family: "Instrument Serif", serif;
  font-size: clamp(1.45rem, 2.6vw, 2rem);
  line-height: 1.2;
  cursor: pointer;
  list-style: none;
  transition:
    color 0.2s,
    padding-left 0.2s;
}
.faq-item summary::-webkit-details-marker {
  display: none;
}
.faq-item summary::before,
.faq-item summary::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 10px;
  width: 20px;
  height: 1px;
  background: #557789;
  transition: transform 0.25s ease;
}
.faq-item summary::after {
  transform: rotate(90deg);
}
.faq-item summary:hover {
  color: #557789;
  padding-left: 8px;
}
.faq-item[open] summary {
  color: #557789;
}
.faq-item[open] summary::after {
  transform: rotate(0deg);
}
.faq-answer {
  animation: faq-reveal 0.3s ease both;
}
.faq-answer p {
  max-width: 760px;
  margin: 0;
  padding: 0 62px 28px 0;
  color: #6b564a;
  font-size: 0.88rem;
  line-height: 1.8;
}
.faq-answer a {
  color: #557789;
  border-bottom: 1px solid rgba(85, 119, 137, 0.4);
}
@keyframes faq-reveal {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* Support page */
.support-page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.support-wrap {
  width: min(1180px, calc(100% - 48px));
  margin-inline: auto;
}
.page-nav {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(244, 237, 227, 0.9);
  border-bottom: 1px solid rgba(47, 33, 27, 0.12);
  backdrop-filter: blur(14px);
}
.page-nav-inner {
  width: min(1180px, calc(100% - 48px));
  margin-inline: auto;
  height: 78px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}
.page-nav-brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  flex: none;
}
.page-nav-brand img {
  width: 40px;
  height: 40px;
  object-fit: contain;
}
.page-nav-brand span {
  color: #40566a;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.34em;
}
.page-nav-tabs {
  display: flex;
  align-items: center;
  gap: 25px;
  font-size: 0.8rem;
  font-weight: 500;
}
.page-nav-tabs > a:not(.page-nav-cta) {
  position: relative;
  padding-block: 8px;
  opacity: 0.78;
  white-space: nowrap;
}
.page-nav-tabs > a:not(.page-nav-cta)::after {
  content: "";
  position: absolute;
  right: 100%;
  bottom: 2px;
  left: 0;
  height: 1px;
  background: #557789;
  transition: right 0.2s;
}
.page-nav-tabs > a:hover,
.page-nav-tabs > a[aria-current="page"] {
  color: #2f211b;
  opacity: 1;
}
.page-nav-tabs > a:hover::after,
.page-nav-tabs > a[aria-current="page"]::after {
  right: 0;
}
.page-nav-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border: 1px solid rgba(47, 33, 27, 0.28);
  border-radius: 100px;
  font-weight: 600;
  white-space: nowrap;
  transition:
    background 0.22s,
    border-color 0.22s,
    color 0.22s;
}
.page-nav-cta i {
  width: 6px;
  height: 6px;
  background: #557789;
  border-radius: 50%;
  animation: kv-pulse 2.4s ease-in-out infinite;
}
.page-nav-cta:hover {
  color: #f4ede3;
  background: #2f211b;
  border-color: #2f211b;
}
.support-main {
  flex: 1;
  display: grid;
  place-items: center;
  padding-block: 72px 110px;
}
.support-card {
  width: min(720px, 100%);
  position: relative;
  overflow: hidden;
  padding: clamp(42px, 7vw, 78px);
  background: #e8d9c4;
  border: 1px solid rgba(47, 33, 27, 0.14);
  border-radius: 18px;
  box-shadow: 0 28px 70px rgba(47, 33, 27, 0.1);
  animation: kv-up 0.8s ease both;
}
.support-card::after {
  content: "";
  position: absolute;
  width: 300px;
  height: 300px;
  right: -170px;
  bottom: -190px;
  border: 1px solid rgba(85, 119, 137, 0.25);
  border-radius: 50%;
  box-shadow:
    0 0 0 48px rgba(85, 119, 137, 0.045),
    0 0 0 96px rgba(85, 119, 137, 0.025);
}
.support-kicker {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 28px;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.support-kicker::before {
  content: "";
  width: 28px;
  height: 1px;
  background: currentColor;
}
.support-card h1 {
  margin: 0 0 24px;
  font-family: "Instrument Serif", serif;
  font-size: clamp(3.8rem, 9vw, 6.8rem);
  font-weight: 400;
  letter-spacing: -0.05em;
  line-height: 0.9;
}
.support-card h1 em {
  color: #557789;
  font-weight: 400;
}
.support-copy {
  max-width: 510px;
  margin: 0 0 35px;
  color: #51382c;
  font-size: clamp(1rem, 2vw, 1.18rem);
  line-height: 1.65;
}
.support-email {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 20px;
  min-height: 54px;
  padding: 0 22px;
  color: #f4ede3;
  background: #2f211b;
  border-radius: 100px;
  font-size: 0.82rem;
  font-weight: 600;
  transition:
    transform 0.2s,
    box-shadow 0.2s;
}
.support-email:hover {
  color: #f4ede3;
  transform: translateY(-2px);
  box-shadow: 0 12px 24px rgba(47, 33, 27, 0.15);
}
.support-footer {
  min-height: 100px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  border-top: 1px solid rgba(47, 33, 27, 0.14);
  color: #8d7665;
  font-size: 0.66rem;
}
.support-footer p {
  margin: 0;
}
.footer-privacy-link {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 0 13px;
  color: #51382c;
  border: 1px solid rgba(47, 33, 27, 0.2);
  border-radius: 100px;
  font-weight: 600;
  transition:
    color 0.2s,
    background 0.2s,
    border-color 0.2s;
}
.footer-privacy-link:hover,
.footer-privacy-link[aria-current="page"] {
  color: #f4ede3;
  background: #2f211b;
  border-color: #2f211b;
}

/* Privacy page */
.privacy-page {
  min-height: 100vh;
}
.privacy-main {
  width: min(900px, calc(100% - 48px));
  margin-inline: auto;
  padding-block: 92px 120px;
}
.privacy-header {
  padding-bottom: 48px;
  border-bottom: 1px solid rgba(47, 33, 27, 0.16);
  animation: kv-up 0.8s ease both;
}
.privacy-kicker {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 22px;
  color: #557789;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.privacy-kicker::before {
  content: "";
  width: 28px;
  height: 1px;
  background: currentColor;
}
.privacy-header h1 {
  margin: 0;
  font-family: "Instrument Serif", serif;
  font-size: clamp(4rem, 8vw, 6.6rem);
  font-weight: 400;
  letter-spacing: -0.05em;
  line-height: 0.92;
}
.privacy-header h1 em {
  color: #557789;
  font-weight: 400;
}
.privacy-effective {
  margin: 28px 0 0;
  color: #6b564a;
  font-size: 0.85rem;
}
.privacy-policy {
  padding-top: 25px;
  color: #51382c;
  font-size: 0.94rem;
  line-height: 1.8;
}
.privacy-policy h2 {
  margin: 52px 0 13px;
  color: #2f211b;
  font-family: "Instrument Serif", serif;
  font-size: clamp(2rem, 4vw, 2.7rem);
  font-weight: 400;
  line-height: 1.1;
}
.privacy-policy h3 {
  margin: 30px 0 10px;
  color: #2f211b;
  font-family: "Instrument Serif", serif;
  font-size: 1.55rem;
  font-weight: 400;
}
.privacy-policy p {
  margin: 0 0 17px;
}
.privacy-policy ul {
  display: grid;
  gap: 8px;
  margin: 14px 0 22px;
  padding-left: 22px;
}
.privacy-policy li::marker {
  color: #789bad;
}
.privacy-policy a {
  color: #557789;
  border-bottom: 1px solid rgba(85, 119, 137, 0.4);
}
.privacy-policy address {
  margin-top: 22px;
  padding: 24px;
  background: #e8d9c4;
  border: 1px solid rgba(47, 33, 27, 0.13);
  border-radius: 14px;
  font-style: normal;
  line-height: 1.8;
}

/* Updates page */
.updates-page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.updates-main {
  flex: 1;
  width: min(1180px, calc(100% - 48px));
  margin-inline: auto;
  display: grid;
  place-items: center;
  /* The hero alone should sit centred in the viewport, but once the feed loads the
     content outgrows it. Safe centring keeps the top edge reachable either way. */
  align-content: safe center;
  gap: 44px;
  padding-block: 80px 110px;
}
.updates-hero {
  width: min(780px, 100%);
  position: relative;
  overflow: hidden;
  padding: clamp(46px, 8vw, 82px);
  background: #e8d9c4;
  border: 1px solid rgba(47, 33, 27, 0.14);
  border-radius: 18px;
  box-shadow: 0 28px 70px rgba(47, 33, 27, 0.1);
  animation: kv-up 0.8s ease both;
}
.updates-hero::after {
  content: "";
  position: absolute;
  width: 320px;
  height: 320px;
  right: -190px;
  bottom: -200px;
  border: 1px solid rgba(85, 119, 137, 0.25);
  border-radius: 50%;
  box-shadow:
    0 0 0 50px rgba(85, 119, 137, 0.045),
    0 0 0 100px rgba(85, 119, 137, 0.025);
}
.updates-kicker {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 22px;
  color: #557789;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.updates-kicker::before {
  content: "";
  width: 28px;
  height: 1px;
  background: currentColor;
}
.updates-hero h1 {
  margin: 0;
  font-family: "Instrument Serif", serif;
  font-size: clamp(4rem, 8vw, 6.6rem);
  font-weight: 400;
  letter-spacing: -0.05em;
  line-height: 0.92;
}
.updates-hero h1 em {
  color: #557789;
  font-weight: 400;
}
.updates-intro {
  max-width: 620px;
  margin: 30px 0 0;
  color: #6f5b4d;
  font-size: clamp(1rem, 2vw, 1.18rem);
  line-height: 1.7;
}
.updates-status {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 9px;
  width: fit-content;
  margin-top: 34px;
  padding: 9px 14px;
  color: #40566a;
  background: rgba(120, 155, 173, 0.13);
  border: 1px solid rgba(85, 119, 137, 0.22);
  border-radius: 100px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.updates-status i {
  width: 7px;
  height: 7px;
  background: #557789;
  border-radius: 50%;
  animation: kv-pulse 2.4s ease-in-out infinite;
}

/* Release feed, drawn as a timeline.

   --gutter is the space the rail lives in and --rail is the rail's centre inside
   it. The dots and the filter position themselves from both, so the timeline
   stays aligned from one breakpoint override rather than hand-tuned offsets.

   The wrapper holds the filter, the list and the empty note together, so
   .updates-main's wide gap falls between the hero and the feed rather than
   between these three. */
.updates-feed {
  --gutter: 46px;
  --rail: 16px;
  /* Even, so half of it is a whole pixel. At 13px the node's edges landed on
     x.5 and the browser rounded them one way and the 2px rail the other, which
     read as the line sitting off-centre in the circle. */
  --dot: 14px;
  width: min(780px, 100%);
  display: grid;
  gap: 20px;
}
/* Before CI publishes anything there is no feed and nothing to filter, and an
   empty grid item would still collect the gap under the hero. */
.updates-feed:has(.updates-list:empty) {
  display: none;
}
.updates-list {
  position: relative;
  width: 100%;
  margin: 0;
  padding: 0 0 0 var(--gutter);
  display: grid;
  gap: 14px;
  list-style: none;
}
/* Both rails span the full list and fade out at the ends, which lets the card
   padding change with the viewport without leaving the line short or overhanging. */
.updates-list::before,
.updates-list::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--rail) - 1px);
  width: 2px;
  /* Fades short of the first and last node, so the rail reads as running between
     them rather than stopping dead above the top card. */
  mask-image: linear-gradient(
    transparent 0,
    #000 26px,
    #000 calc(100% - 26px),
    transparent 100%
  );
}
.updates-list::before {
  background: rgba(47, 33, 27, 0.16);
}
/* The accent rail draws itself as the list scrolls past. Browsers without
   scroll-driven animations ignore animation-timeline and run this on load with
   the initial duration, so the rail simply arrives already drawn. */
.updates-list::after {
  background: linear-gradient(#557789, rgba(85, 119, 137, 0.4));
  transform: scaleY(0);
  transform-origin: top;
  animation: kv-rail linear both;
  animation-timeline: view();
  /* Ends before the list can leave the viewport. A short list never scrolls far
     enough to reach a later range, which would strand the rail part-drawn. */
  animation-range: entry 20% cover 55%;
}
@keyframes kv-rail {
  to {
    transform: scaleY(1);
  }
}
.update-entry {
  position: relative;
  padding: clamp(20px, 2.6vw, 26px) clamp(22px, 3vw, 30px);
  background: #efe6d7;
  border: 1px solid rgba(47, 33, 27, 0.14);
  border-radius: 18px;
  box-shadow: 0 14px 34px rgba(47, 33, 27, 0.06);
  /* Entries are linkable by slug and the nav is sticky, so leave it room. */
  scroll-margin-top: 96px;
  animation: kv-up linear both;
  animation-timeline: view();
  animation-range: entry 5% cover 30%;
}
/* The node on the rail. The ring is the page colour rather than transparent so
   it punches a hole in the rail instead of letting it run through the dot. */
.update-entry::before {
  content: "";
  position: absolute;
  /* Card padding, then half the 30px pill, then back up by half the node, which
     puts the node on the pill's centre line rather than near its top. */
  top: calc(clamp(20px, 2.6vw, 26px) + 15px - var(--dot) / 2);
  left: calc(var(--rail) - var(--dot) / 2 - var(--gutter));
  /* The global box-sizing rule covers elements, not pseudo-elements, so without
     this the 2px border sits outside --dot and the node hangs off the rail. */
  box-sizing: border-box;
  width: var(--dot);
  height: var(--dot);
  background: #f4ede3;
  border: 2px solid #557789;
  border-radius: 50%;
  box-shadow: 0 0 0 5px #f4ede3;
}
/* Give the node the same colour as the entry's pill so the rail reads at a glance. */
.update-entry:has(.update-pill-improved)::before {
  border-color: #607c52;
}
.update-entry:has(.update-pill-fixed)::before {
  border-color: #966533;
}
.update-meta {
  display: flex;
  align-items: center;
  gap: 12px;
}
.update-meta time {
  color: #6f5b4d;
  font-size: 0.8rem;
}
.update-pill {
  padding: 6px 12px;
  border-radius: 100px;
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.update-pill-new {
  color: #40566a;
  background: rgba(120, 155, 173, 0.16);
  border: 1px solid rgba(85, 119, 137, 0.24);
}
.update-pill-improved {
  color: #4c6042;
  background: rgba(122, 148, 106, 0.16);
  border: 1px solid rgba(96, 124, 82, 0.24);
}
.update-pill-fixed {
  color: #7d5330;
  background: rgba(176, 122, 66, 0.16);
  border: 1px solid rgba(150, 101, 51, 0.24);
}
.update-entry h2 {
  margin: 10px 0 0;
  font-family: "Instrument Serif", serif;
  font-size: clamp(1.3rem, 2.2vw, 1.6rem);
  font-weight: 400;
  letter-spacing: -0.03em;
  line-height: 1.2;
}
.update-entry p {
  margin: 8px 0 0;
  color: #6f5b4d;
  font-size: 0.94rem;
  line-height: 1.6;
}
/* Filter. The three kinds are fixed by the feed's contract, so the controls can
   be plain markup and the filtering plain selectors — no state to keep in step
   with the list. Indented by --gutter to line up with the cards, not the rail. */
.updates-controls {
  margin: 0;
  padding: 0 0 0 var(--gutter);
  border: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* The group still needs a name for screen readers; it just does not need one on
   screen, where four labelled buttons under a feed explain themselves. */
.updates-controls legend {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* The radios carry the state and the labels are what you see. Hidden this way
   rather than with display:none, which would take them out of the tab order. */
.updates-controls input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}
.updates-controls label {
  padding: 7px 15px;
  color: #6f5b4d;
  border: 1px solid rgba(47, 33, 27, 0.18);
  border-radius: 100px;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    color 0.2s ease,
    background 0.2s ease,
    border-color 0.2s ease;
}
.updates-controls label:hover {
  border-color: rgba(47, 33, 27, 0.4);
}
.updates-controls input:checked + label {
  color: #f4ede3;
  background: #2f211b;
  border-color: #2f211b;
}
/* Focus lands on the hidden radio, so the ring has to be drawn on its label. */
.updates-controls input:focus-visible + label {
  outline: 2px solid #557789;
  outline-offset: 2px;
}
.updates-controls:has(#kind-new:checked)
  + .updates-list
  .update-entry:not(:has(.update-pill-new)),
.updates-controls:has(#kind-improved:checked)
  + .updates-list
  .update-entry:not(:has(.update-pill-improved)),
.updates-controls:has(#kind-fixed:checked)
  + .updates-list
  .update-entry:not(:has(.update-pill-fixed)) {
  display: none;
}
/* A feed can hold none of a given kind — nothing fixed yet, say — and the list
   would then filter down to blank space with no explanation. */
.updates-empty {
  display: none;
  margin: 0;
  padding-left: var(--gutter);
  color: #6f5b4d;
  font-size: 0.94rem;
}
.updates-controls:has(#kind-new:checked)
  + .updates-list:not(:has(.update-pill-new))
  + .updates-empty,
.updates-controls:has(#kind-improved:checked)
  + .updates-list:not(:has(.update-pill-improved))
  + .updates-empty,
.updates-controls:has(#kind-fixed:checked)
  + .updates-list:not(:has(.update-pill-fixed))
  + .updates-empty {
  display: block;
}

/* The blanket reduced-motion rule above only shortens animation-duration, which a
   scroll-driven animation ignores — its progress comes from the scroll position.
   These have to be switched off by hand, at their finished state. */
@media (prefers-reduced-motion: reduce) {
  .updates-list::after {
    animation: none;
    transform: scaleY(1);
  }
  .update-entry {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* Phones.
   The hero decoration and its two mockups are sized and offset in fixed pixels,
   which spreads them roughly 600px wide. On a phone that runs off both edges and
   body's overflow-x:hidden crops them rather than letting the page scroll, so the
   mockups arrive already cut in half. Pull the offsets in and scale them down.
   These override inline styles, hence !important. */
@media (max-width: 640px) {
  @keyframes kv-floatA-sm {
    0%,
    100% {
      transform: translate(-52px, 6px) rotate(-7deg) scale(0.62);
    }
    50% {
      transform: translate(-52px, -8px) rotate(-6deg) scale(0.62);
    }
  }
  @keyframes kv-floatB-sm {
    0%,
    100% {
      transform: translate(46px, -6px) rotate(5deg) scale(0.72);
    }
    50% {
      transform: translate(46px, 10px) rotate(4deg) scale(0.72);
    }
  }
  figure[style*="kv-floatA"] {
    animation-name: kv-floatA-sm !important;
  }
  figure[style*="kv-floatB"] {
    animation-name: kv-floatB-sm !important;
  }
  div[style*="width: 560px"] {
    width: 320px !important;
    height: 320px !important;
  }
  div[style*="width: 430px"][style*="border-radius: 50%"] {
    width: 240px !important;
    height: 240px !important;
  }

  /* The four section links plus the call to action run off the side of the bar
     beside the logo, taking "iOS soon" with them. Drop the section links, which
     only jump down the same page, and keep the logo and the call to action. */
  nav a.x1,
  nav a.x2,
  nav a.x3,
  nav a.x4 {
    display: none !important;
  }

  .support-wrap {
    width: min(100% - 32px, 1180px);
  }
  .support-main {
    padding-block: 48px 76px;
    text-align: left;
  }
  .support-card {
    padding: 42px 28px;
  }
  .support-footer {
    min-height: 120px;
    flex-direction: column;
    justify-content: center;
  }

  .page-nav-inner {
    width: min(100% - 32px, 1180px);
    height: auto;
    min-height: 78px;
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    padding-top: 12px;
  }
  .page-nav-brand {
    align-self: flex-start;
  }
  .page-nav-tabs {
    width: calc(100% + 32px);
    margin-left: -16px;
    overflow-x: auto;
    gap: 20px;
    padding: 4px 16px 12px;
    scrollbar-width: none;
  }
  .page-nav-tabs::-webkit-scrollbar {
    display: none;
  }
  .page-nav-tabs > a:not(.page-nav-cta) {
    display: block !important;
  }
  .updates-main {
    width: min(100% - 32px, 1180px);
    padding-block: 48px 76px;
  }
  .updates-hero {
    padding: 42px 28px;
    text-align: left;
  }
  .updates-hero h1 {
    font-size: clamp(3.6rem, 18vw, 5rem);
  }
  /* A phone cannot spare 46px of gutter, so pull the rail in. The dots follow,
     since they are positioned from these two values. */
  .updates-feed {
    --gutter: 30px;
    --rail: 10px;
  }
  /* 30px is a fine click target and a poor thumb target. Pad to 44. */
  .updates-controls label {
    padding: 14px 16px;
  }
  .faq-item summary {
    min-height: 72px;
    padding-right: 48px;
    text-align: left;
  }
  .faq-answer p {
    padding-right: 35px;
    text-align: left;
  }
  .privacy-main {
    width: min(100% - 32px, 900px);
    padding-block: 62px 90px;
  }
  .privacy-header h1 {
    font-size: clamp(3.6rem, 17vw, 5rem);
  }
  .privacy-policy {
    font-size: 0.9rem;
  }

  /* Three hardcoded columns leave about 130px each, too narrow for the step
     cards, so they spill past the edge. Stack them instead. */
  div[style*="repeat(3, 1fr)"] {
    grid-template-columns: 1fr !important;
  }

  /* Centred copy reads better in a narrow column. The rows of buttons and
     labels are flex, so they need their own centring. */
  #top > section,
  section[id] {
    text-align: center;
  }
  #top > section [style*="display: flex"],
  section[id] [style*="display: flex"] {
    justify-content: center;
  }
  nav [style*="display: flex"] {
    justify-content: space-between;
  }

  /* Stacked, the step cards keep a 280px floor meant for a three column row,
     which leaves a large empty gap under each one, and their icon stays pinned
     to the right where it looks detached from the centred text. Let each card
     size to its content, centre the icon, and turn the column dividers into a
     rule between the stacked cards. */
  .x8,
  .x9,
  .x10 {
    min-height: 0 !important;
    padding: 24px 20px 32px !important;
    border-left: 0 !important;
    border-right: 0 !important;
  }
  .x8:not(:last-of-type),
  .x9:not(:last-of-type),
  .x10:not(:last-of-type) {
    border-bottom: 1px solid rgba(47, 33, 27, 0.14) !important;
  }
  /* No height here: the third icon is a rotated grid taller than the other
     two SVGs, and a fixed box would crop it. */
  .x8 [style*="justify-content: flex-end"],
  .x9 [style*="justify-content: flex-end"],
  .x10 [style*="justify-content: flex-end"] {
    justify-content: center !important;
    margin-top: 14px !important;
  }
  .x8 p,
  .x9 p,
  .x10 p {
    margin-inline: auto !important;
  }
  .x8 h3,
  .x9 h3,
  .x10 h3 {
    margin-top: 18px !important;
  }
}
