/* SkyPocket site styles.
   One stylesheet for every locale. Was duplicated inline in all fifteen
   locale pages, which let eight of them drift a design generation behind:
   ar, de, es, fr, he, it, ja and pt-br never got the card and eyebrow
   typography that English and the newer locales had. Edit here only. */

:root {
  --panel: #040609;
  --bezel: #0b1016;
  --line: rgba(255, 255, 255, 0.14);
  --green: #1ceb5c;
  --cyan: #40d9ff;
  --amber: #ffbf1a;
  --white: #ebebeb;
  --dim: rgba(235, 235, 235, 0.62);
  --faint: rgba(235, 235, 235, 0.38);
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  /* Prose is set in the reader's own system font. No webfont: it costs
     nothing, sends nothing to anyone, and is the only honest way to serve
     fifteen languages, since system-ui already resolves to a face the
     reader's OS has for Arabic, Hebrew, Japanese, Korean and both Chinese
     scripts. A Latin display font would have served eight of fifteen. */
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --raise: rgba(255, 255, 255, 0.22);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
/* Keep anchored headings clear of the sticky nav. */
html { scroll-behavior: smooth; scroll-padding-top: 84px; }
[id] { scroll-margin-top: 84px; }
body {
  background: var(--panel);
  color: var(--white);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
/* The cockpit voice, kept deliberately for the instrument details: labels,
   readouts, captions, buttons. Everything a human reads as a sentence is
   set in the body font instead, which is what stops the page reading like
   a terminal. */
.eyebrow, .wordmark, .nav-links a, .btn, .fine, .stat-box b, .stat-box span,
.card h3, .quote .stars, .quote cite, .foot,
.lang-menu summary, .strip-stats { font-family: var(--mono); }

::selection { background: var(--green); color: var(--panel); }
a { color: var(--cyan); }
:focus-visible { outline: 2px solid var(--green); outline-offset: 3px; border-radius: 2px; }
img, video { max-width: 100%; height: auto; display: block; }

.skip {
  position: absolute; inset-inline-start: -999px; top: 8px; z-index: 99;
  background: var(--green); color: var(--panel); padding: 8px 14px;
  font-weight: 700; text-decoration: none; border-radius: 4px;
}
.skip:focus { inset-inline-start: 8px; }

.wrap { max-width: 1060px; margin: 0 auto; padding: 0 22px; }

/* ---------- nav ---------- */
header.nav {
  position: sticky; top: 0; z-index: 10;
  background: rgba(4, 6, 9, 0.86);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.nav-inner { display: flex; align-items: center; gap: 26px; padding: 14px 22px; max-width: 1060px; margin: 0 auto; }
.wordmark { display: flex; align-items: center; gap: 9px; color: var(--white); text-decoration: none; font-weight: 800; letter-spacing: 3px; font-size: 15px; }
.wordmark svg { width: 18px; height: 18px; fill: var(--green); }
.nav-links { margin-inline-start: auto; display: flex; gap: 22px; align-items: center; }
.nav-links a { color: var(--dim); text-decoration: none; font-size: 12px; letter-spacing: 1.5px; text-transform: uppercase; }
.nav-links a:hover { color: var(--white); }
.nav-links a.cta {
  color: var(--panel); background: var(--green); padding: 8px 14px;
  border-radius: 5px; font-weight: 700; white-space: nowrap;
}
@media (max-width: 700px) {
  .nav-links a:not(.cta):not(.lang) { display: none; }
  .nav-inner { gap: 12px; padding: 12px 14px; }
  .nav-links { gap: 8px; }
  .wordmark { letter-spacing: 1px; }
  .lang-menu { padding: 0 6px; }
  .lang-menu summary .lang-label { display: none; }
  .strip-stats { gap: 8px; }
  .stat-box { padding: 12px 10px; }
}
@media (max-width: 420px) {
  .nav-links a.cta { font-size: 12px; padding: 8px 10px; }
}
/* The one Arabic word on the page keeps its letterforms joined. */
.nav-links a.lang { letter-spacing: 0; text-transform: none; font-size: 13px; }

/* ---------- language menu ---------- */
.lang-menu { position: relative; }
.lang-menu summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 7px;
  color: var(--dim); font-size: 13px;
}
.lang-menu summary::-webkit-details-marker { display: none; }
.lang-menu summary:hover, .lang-menu[open] summary { color: var(--white); }
.lang-menu summary svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.6; }
.lang-menu .menu {
  position: absolute; top: calc(100% + 12px); inset-inline-end: 0; z-index: 20;
  min-width: 132px; padding: 6px; display: grid; gap: 2px;
  background: var(--bezel); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.5);
}
.lang-menu .menu a { display: block; padding: 8px 12px; border-radius: 5px; }
.lang-menu .menu a:hover { background: rgba(255, 255, 255, 0.06); }
.lang-menu .menu a[aria-current] { color: var(--green); }

/* ---------- eyebrow / headings ---------- */
.eyebrow {
  color: var(--cyan); font-size: 12px; font-weight: 700;
  letter-spacing: 2.5px; text-transform: uppercase;
}
/* Bigger and tighter than before: in a proportional face the old sizes
   read as body copy in bold, not as a headline. text-wrap: balance stops
   the one-word last line, which matters most in German and Polish. */
h1, h2 { font-weight: 800; letter-spacing: -1.2px; line-height: 1.06; text-wrap: balance; }
h1 { font-size: clamp(38px, 6.2vw, 62px); }
h2 { font-size: clamp(27px, 3.9vw, 39px); }
.sub { color: var(--dim); max-width: 52ch; font-size: 17.5px; line-height: 1.6; }

/* ---------- hero ---------- */
/* A little light from somewhere, so the page opens instead of starting at
   pure black. */
.hero {
  /* The hero sets its own spacing on .hero-inner, so it opts out of the
     section rhythm below; it was getting both and opening 132px down. */
  padding-block: 0;
  position: relative; overflow: hidden; border-bottom: 1px solid var(--line);
  background:
    radial-gradient(1100px 520px at 12% -12%, rgba(28, 235, 92, 0.10), transparent 62%),
    radial-gradient(900px 460px at 92% 6%, rgba(64, 217, 255, 0.08), transparent 60%);
}
.hero-bg { position: absolute; inset: 0; pointer-events: none; opacity: 0.5; }
/* The text starts near the top rather than centring against the phone,
   which is 100px taller than it and was pushing the headline a fifth of
   the viewport down the page before anything was said. */
.hero-inner {
  position: relative; display: grid; grid-template-columns: 1.15fr 0.85fr;
  gap: 40px; align-items: start; padding-block: 38px 64px;
}
.hero-inner > .phone { align-self: center; }
@media (max-width: 860px) { .hero-inner { grid-template-columns: 1fr; padding-top: 48px; } }
.hero h1 span { color: var(--green); }
.hero .sub { margin: 18px 0 30px; }
.cta-row { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }

.btn {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--mono); font-size: 14px; font-weight: 700; letter-spacing: 1.5px;
  padding: 15px 24px; border-radius: 12px; text-decoration: none; text-transform: uppercase;
  border: 1px solid var(--line); transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.btn-green { background: var(--green); color: var(--panel); border-color: transparent; }
.btn-green:hover { transform: translateY(-1px); box-shadow: 0 6px 24px rgba(28, 235, 92, 0.25); }
.btn-ghost { color: var(--white); background: var(--bezel); }
.btn-ghost:hover { border-color: var(--dim); }
/* On a phone the two stores get equal, thumb-sized rows. Side by side they
   came out different widths, which reads as one mattering more. */
@media (max-width: 560px) {
  .cta-row { display: grid; grid-template-columns: 1fr; gap: 10px; }
  .cta-row .btn { justify-content: center; }
}
/* ---------- the promises ----------
   The whole pitch of the app, said out loud in the hero instead of hidden
   in 12px grey: one payment, and none of the things people brace for.
   Every claim here is true of the shipped app: no purchase APIs, no
   analytics SDK, and on iOS no networking code whatsoever. */
.promises {
  display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px;
}
.promises li {
  list-style: none;
  font-family: var(--mono); font-size: 12px; letter-spacing: 1px;
  text-transform: uppercase; white-space: nowrap;
  padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--dim);
}
/* The price leads, so it wears the panel's own green. */
.promises li.price {
  background: var(--green); border-color: transparent; color: var(--panel);
  font-weight: 700;
}
@media (max-width: 420px) {
  .promises { gap: 6px; }
  .promises li { font-size: 11px; padding: 6px 10px; letter-spacing: 0.5px; }
}

.fine { margin-top: 16px; color: var(--faint); font-size: 12px; letter-spacing: 0.5px; }

.phone {
  justify-self: center; width: min(292px, 76vw);
  border: 9px solid #10151c; border-radius: 46px; overflow: hidden;
  background: #000; box-shadow: 0 24px 70px rgba(0, 0, 0, 0.65), 0 0 0 1px var(--line);
}
.phone video { width: 100%; aspect-ratio: 640 / 1390; object-fit: cover; }
/* real shots */

.real-row { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 8px; }
.real-row img, .real-row video {
  height: 430px; width: auto; border-radius: 10px; flex: 0 0 auto;
  border: 1px solid var(--line); box-shadow: 0 14px 44px rgba(0, 0, 0, 0.5);
}

/* ---------- try it ----------
   A phone you can actually press. The tab bar sits inside the bezel where
   the app's own does, so switching tabs feels like switching tabs rather
   than clicking a website. Screens within a tab step round when you tap
   the screen itself. */
/* Tighter than the other sections so the whole device, tab bar included,
   lands in one screen rather than asking for a scroll mid-demo. */
#tryit {
  padding-block: 64px 72px; position: relative; overflow: hidden;
}
/* The device sits in its own pool of light rather than on flat black. */
#tryit::before {
  content: ""; position: absolute; pointer-events: none;
  inset-inline-end: -6%; top: 6%; width: 46%; height: 88%;
  background: radial-gradient(closest-side, rgba(28, 235, 92, 0.10), transparent 72%);
}
#tryit h2 { margin: 6px 0 18px; }
.try-side .eyebrow { display: block; }
/* Fills the same 1060px wrap the hero and the reviews use: sizing the two
   columns to their contents and centring them left this section visibly
   narrower than everything above it. The copy stays readable on its own
   max-width; the tile grid takes the rest of the room and gets shorter for
   it. */
.try {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 56px; align-items: center;
}
.try-cap, .try-sub, .try-points { max-width: 48ch; }
@media (max-width: 860px) { .try { grid-template-columns: 1fr; gap: 28px; justify-content: stretch; } }

.try-device {
  /* small enough that the screen AND its tab bar are visible together;
     a tab bar you have to scroll to is not a tab bar. */
  justify-self: center; width: min(224px, 64vw);
  border: 8px solid #10151c; border-radius: 36px; overflow: hidden;
  position: relative;
  background: #000; box-shadow: 0 26px 74px rgba(0, 0, 0, 0.7), 0 0 0 1px var(--line);
}
.try-stage {
  position: relative; display: block; width: 100%; background: #000;
  transition: opacity 0.16s ease;
}
/* Set while the picture is being swapped, so one fades out and the next
   fades in rather than the screen cutting between them. */
.try-stage.is-swapping { opacity: 0; }
/* The phone shows each screen whole now, its own tab bar included, since
   there is no longer a second one underneath pretending to be it. */
.try-stage img {
  width: 100%; display: block;
  aspect-ratio: 1170 / 2532; object-fit: cover; object-position: top;
}
/* An explicit display beats the browser's [hidden] rule, so a clip used to
   appear UNDER the screenshot instead of in place of it. */
.try-stage img[hidden] { display: none; }

.try-side .eyebrow { margin-bottom: 8px; }
/* Holds both a short screen name and a full sentence about a
   photograph, so it stays sentence case and is allowed to wrap. */
.try-cap {
  color: var(--green); font-family: var(--mono); font-size: 13px;
  letter-spacing: 0.6px; line-height: 1.5; max-width: 46ch; min-height: 2.6em;
  transition: opacity 0.16s ease;
}
.try-side.is-swapping .try-cap, .try-side.is-swapping .try-sub { opacity: 0.25; }
.try-sub { transition: opacity 0.16s ease; }
.try-sub { color: var(--dim); font-size: 14.5px; margin-top: 8px; max-width: 44ch; }
/* The few lines a tab brings with it: what a reel is, what a flight
   turns into after landing. Same shape as the story lists they replaced. */
.try-points { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.try-points li {
  color: var(--dim); font-size: 14px; padding-inline-start: 20px; position: relative; line-height: 1.5;
}
.try-points li::before {
  content: "\203a"; position: absolute; inset-inline-start: 0; color: var(--green); font-weight: 800;
}
[dir="rtl"] .try-points li::before { content: "\2039"; }
/* six tabs is more than a real tab bar carries{ font-size: 7.6px; letter-spacing: 0.3px; padding-inline: 1px; }

/* ---------- the rail under the phone ----------
   Everything the section holds, as thumbnails. Picking one puts it on the
   phone; the phone is the only viewer, which is what keeps it feeling like
   an app rather than a page with pictures on it. */
/* Everything the section holds, in three labelled groups: screens,
   photographs, clips. Uniform tiles on a real grid, not a flex wrap: the
   sources are phone screenshots, 3:4 photographs and video posters, and
   letting each keep its own width made every row go ragged. */
.try-rail { margin-top: 26px; }
.try-rail[hidden] { display: none; }
.try-group + .try-group { margin-top: 20px; }
/* An instrument label: the word, then a hairline running out to the edge. */
.try-group-label {
  display: flex; align-items: center; gap: 12px; margin-bottom: 9px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 2px;
  text-transform: uppercase; color: var(--cyan); white-space: nowrap;
}
.try-group-label::after {
  content: ""; flex: 1; height: 1px;
  background: linear-gradient(90deg, var(--line), transparent);
}
[dir="rtl"] .try-group-label::after {
  background: linear-gradient(270deg, var(--line), transparent);
}
.try-tiles {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr));
  gap: 7px;
}
.try-tiles button {
  padding: 0; border: 1px solid var(--line); background: none;
  border-radius: 8px; overflow: hidden; cursor: pointer; line-height: 0;
  position: relative; aspect-ratio: 3 / 4;
  transition: border-color 0.2s ease, transform 0.2s ease,
              opacity 0.2s ease, box-shadow 0.2s ease;
  opacity: 0.62;
}
.try-tiles img { width: 100%; height: 100%; object-fit: cover; display: block; }
.try-tiles button:hover { opacity: 1; transform: translateY(-3px) scale(1.04); border-color: var(--raise); z-index: 1; }
.try-tiles button[aria-current="true"] {
  opacity: 1; border-color: var(--green);
  box-shadow: 0 0 0 1px var(--green), 0 6px 20px rgba(28, 235, 92, 0.22);
}
.try-tiles button.is-clip::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: 24px; height: 24px;
  border-radius: 50%; border: 1px solid rgba(235,235,235,0.4);
  background: rgba(4,6,9,0.5) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%231ceb5c'%3E%3Cpath d='M8 5v14l11-7z'/%3E%3C/svg%3E") center/11px no-repeat;
}
/* A photograph is not phone shaped, so it sits inside the screen the way
   the app shows it, rather than being cropped to fit. */
/* Screenshots crop from the top so their own tab bar goes. A photograph
   fills the screen the way it does in the app, anchored to the bottom so
   the burned-in stats strip is never the thing that gets cropped off. */
.try-stage img.is-fit { object-fit: contain; object-position: center; background: #000; }
/* A photograph is 3:4 and the screen is nearly 1:2, so filling it edge to
   edge always crops the burned-in stats off the sides. It is fitted whole
   and centred instead, which is how the app shows one anyway. */
/* Clips are 9:16 and the screen is taller than that, so covering crops
   the burned-in stats off the sides exactly as it did with photographs.
   Contained, whole, readable. */
.try-stage video { width: 100%; display: block; aspect-ratio: 1170 / 2532; object-fit: contain; background: #000; }
@media (prefers-reduced-motion: reduce) {
  .try-tiles button, .try-stage, .try-cap, .try-sub { transition: none; }
  .try-tiles button:hover { transform: none; }
  .try-stage.is-swapping, .try-side.is-swapping .try-cap,
  .try-side.is-swapping .try-sub { opacity: 1; }
}

/* ---------- the drift ----------
   The real photographs go past like the view does: two full width rows
   moving in opposite directions, slowly. Hovering stops them so you can
   look at one, and a video only loads when you ask for it. Without
   JavaScript the rows are simply scrollable{ overflow: hidden; padding: 4px 0 8px; }
@keyframes drift-left  { from { transform: translateX(0); }    to { transform: translateX(-50%); } }
@keyframes drift-right { from { transform: translateX(-50%); } to { transform: translateX(0); } }

/* ---------- the lightbox ----------
   Anything in the drift opens full size: arrow keys or the buttons move
   along it, Escape closes. It is a <dialog>{
  border: 0; padding: 0; background: transparent; max-width: 100vw; max-height: 100vh;
  width: 100%; height: 100%; color: var(--white); overscroll-behavior: contain;
  /* the panel is a block child with a max-width, so it needs centring here */
  display: grid; place-items: center;
}
/* The panel is the app's own instrument card: bezel, hairline, and a
   status strip across the top reading what you are looking at and where
   you are in the set. Opening a picture should feel like opening a tile
   in the cockpit{
  background: var(--bezel); border: 1px solid var(--line); border-radius: 14px;
  padding: 0 0 14px; overflow: hidden; max-width: min(94vw, 940px);
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.7);
}
/* A screenshot is a phone{ border-radius: 26px; border: 7px solid #10151c; }

/* ---------- strip ---------- */

/* ---------- what people said (verbatim App Store reviews) ---------- */
/* ---------- review carousel (real App Store reviews) ---------- */
.hero-quotes { padding: 6px 0 34px; }
.quote-rail { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 6px; scroll-snap-type: x mandatory; }
.quote-rail .quote { flex: 0 0 clamp(240px, 78vw, 320px); scroll-snap-align: start; display: flex; flex-direction: column; }
.quote {
  border: 1px solid var(--line); border-radius: 14px; background: var(--bezel);
  padding: 14px 16px;
}
.quote .stars { color: var(--green); font-size: 12px; letter-spacing: 2px; }
/* A review kept verbatim from the free week says the app is free. The tag
   sits with the stars so the price is never misrepresented by omission. */
.quote .note {
  float: inline-end; letter-spacing: 0.5px; font-size: 10px;
  text-transform: uppercase; color: var(--amber); opacity: 0.85;
}
.quote blockquote { color: var(--white); font-size: 13.5px; line-height: 1.6; margin: 8px 0 10px; flex: 1; }
.quote cite { color: var(--faint); font-size: 11px; font-style: normal; }
/* Which store the review came from, in the same mark as the download button. */
.quote cite .store { display: inline-flex; margin-inline-start: 7px; vertical-align: -1px; }
.quote cite .store svg { width: 11px; height: 11px; fill: currentColor; opacity: 0.8; }
.quote .tr {
  margin-top: 10px; align-self: flex-start; background: none; cursor: pointer;
  border: 1px solid var(--line); border-radius: 4px; color: var(--cyan);
  font: inherit; font-size: 11px; padding: 4px 9px;
}
.quote .tr:hover:not([disabled]) { border-color: var(--cyan); }
.quote .tr[disabled] { color: var(--faint); cursor: default; opacity: 0.5; }
.strip { border-bottom: 1px solid var(--line); background: var(--bezel); }
.strip-inner {
  display: grid; grid-template-columns: 1.2fr 1fr; gap: 36px; align-items: center; padding-block: 46px;
}
@media (max-width: 780px) { .strip-inner { grid-template-columns: 1fr; } }
.strip p { color: var(--dim); margin-top: 10px; }
.strip-stats { display: flex; gap: 12px; }
.stat-box {
  flex: 1; border: 1px solid var(--line); border-radius: 12px; padding: 16px 14px;
  background: var(--panel); text-align: start;
}
.stat-box b { display: block; color: var(--green); font-size: 22px; letter-spacing: 0; }
.stat-box span { color: var(--cyan); font-size: 10px; letter-spacing: 1.5px; text-transform: uppercase; font-weight: 700; }

/* ---------- sections ---------- */
.section-head { margin-bottom: 40px; }
.section-head h2 { margin-top: 10px; }

/* features */
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
@media (max-width: 880px) { .grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .grid { grid-template-columns: 1fr; } }
.card {
  border: 1px solid var(--line); border-radius: 14px; background: var(--bezel);
  padding: 22px 20px;
}
.card svg { width: 26px; height: 26px; stroke: var(--green); fill: none; stroke-width: 1.6; margin-bottom: 14px; }
.card h3 { font-size: 15px; letter-spacing: 1px; text-transform: uppercase; margin-bottom: 8px; }
.card p { color: var(--dim); font-size: 13.5px; }

/* faq */
details {
  border: 1px solid var(--line); border-radius: 14px; background: var(--bezel);
  padding: 0 20px; margin-bottom: 10px;
}
summary {
  cursor: pointer; padding: 17px 0; font-weight: 700; font-size: 14.5px;
  letter-spacing: 0.3px; list-style: none; display: flex; justify-content: space-between; gap: 14px;
}
summary::-webkit-details-marker { display: none; }
summary::after { content: "+"; color: var(--green); font-weight: 800; }
/* The plus turns into a cross rather than swapping glyph. */
details p { color: var(--dim); font-size: 13.5px; padding-bottom: 18px; }

footer { border-top: 1px solid var(--line); padding: 30px 0 46px; }
.foot { display: flex; flex-wrap: wrap; gap: 10px 26px; align-items: baseline; color: var(--faint); font-size: 12px; }
.foot .wordmark { font-size: 12px; letter-spacing: 2px; }

/* hero track animation */
.track-path {
  stroke-dasharray: 6 7;
  animation: draw 3.2s ease-out forwards;
}
@keyframes draw {
  from { stroke-dashoffset: 640; }
  to { stroke-dashoffset: 0; }
}

/* ---------- motion ----------
   An app about moving through the air had a website that sat perfectly
   still: one animation and two transitions on the whole page. These are
   small on purpose. Things you can point at should answer when the cursor
   arrives, and nothing should move that the reader did not approach. */
.card, .quote, .stat-box, details, .real-row img, .real-row video {
  transition: transform 0.22s ease, border-color 0.22s ease, box-shadow 0.22s ease;
}
.card:hover, .stat-box:hover {
  transform: translateY(-3px);
  border-color: var(--raise);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.45);
}
.quote:hover { border-color: var(--raise); }
details:hover { border-color: var(--raise); } .real-row img:hover, .real-row video:hover {
  transform: translateY(-4px) scale(1.012);
  box-shadow: 0 22px 60px rgba(0, 0, 0, 0.6);
}
.card svg { transition: transform 0.22s ease; }
.card:hover svg { transform: translateY(-2px) scale(1.06); }
/* The FAQ's plus turns into its minus rather than swapping glyphs. */
summary::after { transition: transform 0.2s ease; display: inline-block; }
details[open] summary::after { transform: rotate(45deg); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .track-path { animation: none; }
  .btn, .card, .quote, .stat-box, details, .real-row img, .real-row video, .card svg, summary::after {
    transition: none;
  }
  .card:hover, .stat-box:hover,
  .real-row img:hover, .real-row video:hover, .card:hover svg {
    transform: none;
  }
}

/* ---------- the aeroplane ----------
   It flies the dashed route on an eighteen second loop, nose along the path.
   The scale goes on the inner shape, never the <g>: animateMotion drives
   the group's transform, and a CSS transform there would fight it. */
.hero-plane path {
  transform: scale(1.7);
  filter: drop-shadow(0 0 7px rgba(28, 235, 92, 0.85));
}

/* ---------- the readouts ----------
   These three numbers are the most quietly impressive thing on the page and
   they were styled like table cells. Now they read like instruments: bigger
   numerals, and each on its own channel, which is also the only place the
   amber in the palette earns its keep. */
.stat-box b { font-size: 30px; line-height: 1.1; letter-spacing: -0.5px; }
.strip-stats .stat-box:nth-child(1) b { color: var(--green); }
.strip-stats .stat-box:nth-child(2) b { color: var(--cyan); }
.strip-stats .stat-box:nth-child(3) b { color: var(--amber); }
.strip-stats .stat-box:nth-child(3) span { color: var(--amber); opacity: 0.75; }
.stat-box {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.035), transparent 60%),
    var(--panel);
}

/* The wordmark's aeroplane banks when you reach for it. */
.wordmark svg { transition: transform 0.25s ease; }
.wordmark:hover svg { transform: translateX(3px) rotate(-12deg); }
@media (prefers-reduced-motion: reduce) {
  .wordmark svg { transition: none; }
  .wordmark:hover svg { transform: none; }
}

/* ---------- rhythm ----------
   Every section used to be the same height of the same dark, which is what
   made the page read as a list. A touch more air, and the panelled sections
   get a lit top edge so they announce themselves. */
section { padding: 92px 0; }
.strip, .xpromo { position: relative; }
.strip::before, .xpromo::before {
  content: ""; position: absolute; inset-inline: 0; top: -1px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(64, 217, 255, 0.45), transparent);
}

/* ---------- cross-promo ---------- */
.xpromo { border-top: 1px solid var(--line); background: var(--bezel); padding: 38px 0; text-align: center; }
.xpromo .eyebrow { margin-bottom: 10px; }
.xpromo p:not(.eyebrow) { color: var(--dim); font-size: 13.5px; max-width: 62ch; margin: 0 auto; }
