@font-face {
  font-family: 'Geist';
  src: url('fonts/Geist-Variable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Light-or-dark page, one dark-or-vivid stage, one lime accent, one radius family.
   Two independent axes: --mode (light/dark, the whole page — data-mode on <html>, defaults to
   light for every visitor regardless of OS setting, overridable via the toggle) and the stage's
   own look (data-theme="wallpaper" default | "green" | "orange" on <body>, or ?theme= in the URL). */
:root {
  --bg: #f3f4f4;
  --card: #e6e8e8;
  --card-on: #dcdfdf;
  --ink: #111314;
  --ink2: #5d6366;
  --ink3: #8d9497;
  --line: rgba(17, 19, 20, 0.1);
  --lime: #bdea3f;
  --r: 34px;
  --notch: 26px;
  --tile: 20px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  /* A handful of small elements (the "Get the app" pill, the vertical name tag, the tray card's
     name label) are always a bright chip with dark text/icons, in both page modes — that's a
     deliberate constant, not "page text", so it reads from this fixed color rather than --ink,
     which flips in dark mode. */
  --chip-ink: #111314;
}

:root[data-mode='dark'] {
  --bg: #121314;
  --card: #1d1f20;
  --card-on: #282a2b;
  --ink: #f2f3f1;
  --ink2: #a2a8a6;
  --ink3: #717674;
  --line: rgba(255, 255, 255, 0.1);
}

body[data-theme='green'] {
  --wall-a: #14413a;
  --wall-b: #0a221e;
  --glow: rgba(120, 190, 160, 0.4);
  --floor: rgba(0, 0, 0, 0.26);
  --string: #c99b58;
}

body[data-theme='orange'] {
  --wall-a: #cb4a32;
  --wall-b: #b23824;
  --glow: rgba(255, 196, 160, 0.46);
  --floor: rgba(70, 10, 0, 0.24);
  --string: #f4dfb8;
}

/* Wallpaper stage: a Mac desktop. Swap website/assets/wallpapers/dusk.webp for your own photo.
   The pets walk along 66% of the stage height, so keep a "ground" there if you can. */
body[data-theme='wallpaper'] {
  --wall-a: #16284a;
  --wall-b: #0b2129;
  --string: #f4dfb8;
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Geist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

.ic {
  display: inline-block;
  width: 1em;
  height: 1em;
  background: currentColor;
  -webkit-mask: var(--i) center / contain no-repeat;
  mask: var(--i) center / contain no-repeat;
}

a:focus-visible, button:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* ───────── Hero ───────── */
.hero { height: 100dvh; min-height: 680px; }

.frame {
  height: 100%;
  padding: 18px;
  display: grid;
  grid-template-columns: minmax(470px, 35%) 1fr;
}

.left {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 4px 30px 26px 14px;
}

/* Top row: logo, then one white bar holding the category pills with the light/dark toggle at its
   right end. On a column too narrow for both on one line, the bar wraps below the logo and takes
   the full width instead of squeezing. */
.toprow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
}
.navbar {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 5px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

/* Logo slot: ~36px tall, left of the wordmark. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  height: 36px;
  text-decoration: none;
}
.brand-mark {
  position: relative;
  width: 36px;
  height: 36px;
  border-radius: 11px;
  /* A ring (a bead with a hole), not a solid dot — the inner ink circle punches the hole back
     out of the lime ring. */
  background: var(--ink) radial-gradient(circle at 50% 50%, var(--ink) 0 2.3px, var(--lime) 2.3px 6.5px, transparent 6.5px);
}
/* The charm-on-a-string motif at logo scale: a short lime line from the top edge down to the
   ring's own top edge (50% - 6.5px), so it never runs under/past the ring itself. */
.brand-mark::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  width: 1px;
  height: calc(50% - 6.5px);
  background: var(--lime);
  transform: translateX(-50%);
}
/* Same typeface as the headline, bold, with the headline's tight tracking. */
.brand-name { font-size: 18px; font-weight: 700; letter-spacing: -0.03em; }

/* In dark mode the square itself is var(--ink), which is near-black on the page's own near-black
   background — the mark all but disappears, only the lime ring stays visible. Dark mode instead
   swaps which part is which: a lime square with a fixed dark ring/string on top (not var(--ink),
   which is light in dark mode — this needs to stay dark regardless of mode). */
:root[data-mode-resolved='dark'] .brand-mark {
  background: var(--lime) radial-gradient(circle at 50% 50%, var(--lime) 0 2.3px, #111314 2.3px 6.5px, transparent 6.5px);
}
:root[data-mode-resolved='dark'] .brand-mark::before {
  background: #111314;
}

/* Always a white pill, in both page modes — the same "bright chip" language as .get/.vert/.chip
   below, so its own text/selected colors are fixed (--chip-ink), not the page's var(--ink), which
   would turn near-white in dark mode and vanish against this pill's always-white surface. */
.pillnav {
  display: inline-flex;
  min-width: 0;
}
.pillnav button {
  padding: 9px clamp(11px, 1.05vw, 17px);
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 500;
  color: #5d6366;
  transition: background-color 0.25s var(--ease), color 0.25s var(--ease);
}
.pillnav button:hover { background: rgba(17, 19, 20, 0.05); color: var(--chip-ink); }
.pillnav button[aria-current='true'] { background: var(--chip-ink); color: #fff; }

/* Light/dark toggle — a small circle at the right end of the white bar, so it gets a hairline
   edge to stay visible on the bar's own white. Both icons are always in the DOM; only one is
   shown, decided by data-mode-resolved (see site.js), which is set before first paint so there's
   no flash of the wrong icon. */
.mode-toggle {
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 1px rgba(17, 19, 20, 0.06), 0 1px 3px rgba(0, 0, 0, 0.06);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #5d6366;
  font-size: 17px;
}
.mode-toggle:hover { color: var(--chip-ink); }
.mode-toggle .ic-moon { display: none; }
:root[data-mode-resolved='dark'] .mode-toggle .ic-sun { display: none; }
:root[data-mode-resolved='dark'] .mode-toggle .ic-moon { display: block; }

h1 {
  margin: clamp(32px, 9vh, 84px) 0 0;
  font-weight: 600;
  /* The 3-line "luck on your [faces]" headline is wider than the old one, so it runs a touch
     smaller than the original 4.6rem cap to feel the same size. */
  font-size: clamp(2.3rem, 4.3vw, 4.1rem);
  line-height: 1;
  letter-spacing: -0.045em;
}

.faces {
  display: inline-flex;
  vertical-align: middle;
  margin-left: 12px;
  position: relative;
  top: -4px;
}
.faces i {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 3px solid var(--bg);
  background: var(--card);
  margin-left: -14px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.faces i:first-child { margin-left: 0; }
.faces img { height: 82%; object-fit: contain; }

/* Download + demo buttons, straight under the headline: the platform downloads sit side by
   side, with "Watch demo" on its own row underneath rather than crowding the same line. */
.hero-ctas {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 18px;
  margin: 28px 0 28px;
}
.hero-cta-downloads {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}
.hero-cta-primary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 5.5px 21.5px 5.5px 5.5px;
  border-radius: 999px;
  /* Outlined: a white pill with a thin dark stroke, a dark circle badge and dark text, fixed
     (not mode-dependent) so it reads the same on both the light and the dark page. */
  background: #fff;
  border: 1.5px solid var(--chip-ink);
  color: var(--chip-ink);
  font-size: 14.5px;
  font-weight: 500;
  text-decoration: none;
  transition: transform 0.15s var(--ease), box-shadow 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}
/* On hover it flips to solid black: white text, white badge with a dark icon, white arrow. */
.hero-cta-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 20px rgba(17, 19, 20, 0.16);
  background: var(--chip-ink);
  color: #fff;
}
.hero-cta-primary:hover i { background: #fff; color: var(--chip-ink); }
.hero-cta-primary:hover .hero-cta-arrow { background: #fff; }
.hero-cta-primary i {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--chip-ink);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.hero-cta-arrow { width: 15px; height: 15px; background: var(--chip-ink); margin-left: 2px; transition: background-color 0.2s ease; }
.hero-cta-secondary {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--ink);
  font-size: 14.5px;
  font-weight: 600;
  text-decoration: none;
}
.hero-cta-secondary i {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.2s ease;
}
.hero-cta-secondary .ic { width: 12px; height: 12px; }
.hero-cta-secondary:hover i { border-color: var(--ink); }

/* Scroll hint, pinned to the bottom-left of the hero column (.left is a flex column, so the auto
   margin takes up the free space above it). Dashed edge uses --ink3 so it shows in dark mode too. */
.scroll {
  align-self: flex-start;
  margin-top: auto;
  text-decoration: none;
}
.scroll span {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 18px;
  border: 1.5px dashed var(--ink3);
  border-radius: 999px;
  font-size: 13px;
  color: var(--ink2);
  transition: color 0.2s ease, border-color 0.2s ease;
}
.scroll:hover span { color: var(--ink); border-color: var(--ink2); }
.scroll .ic { font-size: 15px; }

/* ───────── Stage ───────── */
.right { position: relative; min-width: 0; }

.stage {
  position: absolute;
  inset: 0;
  border-radius: var(--r);
  overflow: hidden;
  background:
    radial-gradient(46% 58% at 52% 16%, var(--glow), transparent 70%),
    linear-gradient(180deg, var(--wall-a) 0%, var(--wall-b) 100%);
  transition: background 0.5s ease;
}
.floor {
  position: absolute;
  left: 0;
  right: 0;
  top: 60%;
  bottom: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.06) 0, var(--floor) 3%, var(--floor) 100%);
}

/* The engine's overlay fills the stage; only the charm, pet and ritual item take the mouse. */
.overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}
#charmStringLine { stroke: var(--string); }

.chip {
  position: absolute;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 15px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.96);
  /* Fixed, not inherited from var(--ink): always-white surface on the stage image, so its text
     needs to stay dark in both page modes rather than following the page's own ink color. */
  color: var(--chip-ink);
  font-size: 12.5px;
  font-weight: 500;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.14);
  pointer-events: none;
  animation: fade 0.4s ease both;
}
.chip .ic { font-size: 16px; }
.chip small { font-size: 12px; color: var(--ink2); font-weight: 400; }

/* Base positions (moved here from inline styles so the mobile override below can actually win
   without !important). Tuned for the tall desktop stage, where the hanging charm's resting swing
   never reaches this height. */
#chipHint { left: 9%; top: 42%; }
#chipOrigin { right: 8%; top: 54%; }

.vert {
  position: absolute;
  z-index: 3;
  left: 22px;
  top: 22px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 16px 8px 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.96);
  color: var(--chip-ink); /* see the comment on .chip above */
  text-decoration: none;
  transition: transform 0.2s var(--ease);
}
.vert:hover { transform: translateY(2px); }
.vert span {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  max-height: 190px;
  overflow: hidden;
  white-space: nowrap;
}
.vert i, .get i {
  border-radius: 50%;
  /* Fixed, not var(--ink): .vert and the default .get are always a white pill (they sit on the
     stage image, not the page), so their icon circle needs to stay dark regardless of page mode. */
  background: var(--chip-ink);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.vert i { width: 26px; height: 26px; font-size: 14px; }

.tags {
  position: absolute;
  z-index: 3;
  right: 26px;
  bottom: 26px;
  width: min(360px, 60%);
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}
.tags button {
  padding: 10px 20px;
  border-radius: 999px;
  color: #fff;
  font-size: 13px;
  font-weight: 500;
  background: rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.5);
  transition: background-color 0.2s ease, color 0.2s ease, transform 0.12s ease;
}
.tags button:hover { background: rgba(255, 255, 255, 0.3); }
.tags button:active { transform: scale(0.97); }
.tags button[aria-pressed='true'] { background: #fff; color: var(--chip-ink); border-color: #fff; }
.tags button:focus-visible { outline-color: #fff; }

/* Wallpaper theme */
body[data-theme='wallpaper'] .stage {
  background: #16284a url('assets/wallpapers/dusk.webp') center / cover no-repeat;
}
body[data-theme='wallpaper'] .floor { display: none; }
body[data-theme='wallpaper'] .vert { top: 46px; }

/* Notches: page-coloured shapes cut into the stage's corners, with concave fillets. */
.notch { position: absolute; z-index: 4; background: var(--bg); }

.n-tr {
  top: 0;
  right: 0;
  padding: 10px 0 12px 20px;
  border-bottom-left-radius: var(--notch);
  display: flex;
  align-items: center;
}
.n-tr::before, .n-tr::after {
  content: '';
  position: absolute;
  width: var(--notch);
  height: var(--notch);
  background: radial-gradient(circle at 0 100%, transparent calc(var(--notch) - 0.5px), var(--bg) var(--notch));
}
.n-tr::before { right: 100%; top: 0; }
.n-tr::after { right: 0; top: 100%; }

.get {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 20px 6px 6px;
  border-radius: 999px;
  background: #fff;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  color: var(--chip-ink); /* see the comment on .chip above */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
  transition: transform 0.15s var(--ease), box-shadow 0.2s ease;
}
.get:hover { box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12); }
.get:active { transform: scale(0.98); }
.get i { width: 34px; height: 34px; font-size: 16px; }
.get-dark { background: var(--chip-ink); color: #fff; }
.get-dark i { background: #fff; color: var(--chip-ink); }

.n-bl {
  left: 0;
  bottom: 0;
  padding: 18px 20px 16px 0;
  border-top-right-radius: var(--notch);
}
.n-bl::before, .n-bl::after {
  content: '';
  position: absolute;
  width: var(--notch);
  height: var(--notch);
  background: radial-gradient(circle at 100% 0, transparent calc(var(--notch) - 0.5px), var(--bg) var(--notch));
}
.n-bl::before { left: 0; bottom: 100%; }
.n-bl::after { left: 100%; bottom: 0; }

.cards { display: flex; gap: 10px; }
.tray-card {
  position: relative;
  width: 128px;
  height: 150px;
  border-radius: var(--tile);
  background: var(--card);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 14px 12px 44px;
  transition: transform 0.2s var(--ease), background-color 0.2s ease;
}
.tray-card:hover { transform: translateY(-2px); }
.tray-card:active { transform: scale(0.98); }
.tray-card[aria-pressed='true'] { outline: 2px solid var(--ink); outline-offset: -2px; background: var(--card-on); }
.tray-card .art { height: 100%; width: 100%; }
/* A glyph (an emoji stand-in — Atmosphere art, or a Rage Room item like Fire that has no photo
   of its own) has a fixed 104px font-size regardless of its container, which just overflows a
   card this small — unlike a real photo, which already scales via max-width/max-height:100%.
   Scoped to .glyph generally (not just Atmosphere's .art-mini) so any glyph-based item is
   caught; charm/ritual photos in the same tray are untouched since they're never glyphs. */
.tray-card .art .glyph { font-size: 40px; }
/* Atmosphere specifically (a leaf photo cropped tight with no built-in breathing room) also
   needs its actual photo capped, unlike other charm/ritual photos which already fit at this
   card size. */
.tray-card .art-mini img { max-width: 48px; max-height: 48px; }
.tray-card em {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  height: 32px;
  padding: 0 8px;
  border-radius: 999px;
  background: #fff;
  color: var(--chip-ink); /* see the comment on .chip above */
  font-style: normal;
  font-size: 12.5px;
  font-weight: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pager { display: flex; align-items: center; justify-content: space-between; margin-top: 14px; padding: 0 4px; }
.pager b { font-size: 22px; font-weight: 500; letter-spacing: -0.02em; }
.pager sup { font-size: 11px; font-weight: 400; color: var(--ink2); margin-left: 1px; }
.pager span { display: flex; gap: 6px; font-size: 18px; }
.pager button { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; transition: background-color 0.2s ease; }
.pager button:hover:not(:disabled) { background: rgba(17, 19, 20, 0.07); }
.pager button:disabled { opacity: 0.3; cursor: default; }

/* Artwork used by tray cards and gallery cards */
.art { display: flex; align-items: center; justify-content: center; min-height: 0; }
.art img { max-width: 100%; max-height: 100%; object-fit: contain; filter: drop-shadow(0 8px 10px rgba(17, 19, 20, 0.22)); pointer-events: none; }
.art .glyph { font-size: 104px; line-height: 1; }
.art .icon { width: 56px; height: 56px; color: var(--ink); }
.art .stack { display: flex; flex-direction: column; align-items: center; }
.art .stack img { max-width: none; max-height: none; filter: drop-shadow(0 2px 3px rgba(17, 19, 20, 0.25)); }

/* ───────── Everything, below the fold ───────── */
.all { padding: 72px 32px 40px; max-width: 1520px; margin: 0 auto; }

.sec { margin-bottom: 112px; }
.sec h2 { margin: 0; font-size: clamp(2rem, 3.6vw, 3.4rem); font-weight: 600; line-height: 1; letter-spacing: -0.045em; }
.sec > p { margin: 14px 0 32px; max-width: 46ch; font-size: 16px; line-height: 1.55; color: var(--ink2); }

.grid { display: grid; gap: 12px; }
.grid.charms { grid-template-columns: repeat(4, 1fr); }
.grid.wide { grid-template-columns: repeat(2, 1fr); }
.grid.mood { grid-template-columns: repeat(3, 1fr); }

.card {
  position: relative;
  text-align: left;
  border-radius: var(--tile);
  background: var(--card);
  padding: 18px 18px 20px;
  transition: transform 0.35s var(--ease), background-color 0.2s ease;
}
.card:hover { transform: translateY(-3px); background: var(--card-on); }
.card:active { transform: scale(0.985); transition-duration: 0.1s; }
.card[aria-pressed='true'] { background: var(--card-on); outline: 2px solid var(--ink); outline-offset: -2px; }
.card h3 { margin: 0; font-size: 16px; font-weight: 600; letter-spacing: -0.015em; }
.card p { margin: 3px 0 0; font-size: 13px; color: var(--ink3); }
.card .num { font-size: 12px; color: var(--ink3); }
.card .now {
  position: absolute;
  top: 16px;
  right: 18px;
  display: none;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 500;
}
.card .now::before { content: ''; width: 7px; height: 7px; background: var(--lime); border: 1px solid var(--ink); border-radius: 50%; }
.card[aria-pressed='true'] .now { display: flex; }

.card.tall { height: 350px; display: flex; flex-direction: column; }
.card.tall .art { flex: 1; padding: 14px 0; }
/* Every charm is fitted into the same box, so tall, wide and small pieces read at one size. */
.card.tall .art img { max-width: 150px; max-height: 158px; }

.card.side { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; height: 300px; padding: 0; overflow: hidden; }
.card.side .art { padding: 22px; }
.card.side .art img { max-width: 80%; max-height: 82%; }
.card.side .txt { display: flex; flex-direction: column; justify-content: center; padding: 28px 28px 28px 4px; }
.card.side .txt .desc { margin-top: 12px; font-size: 14px; line-height: 1.5; color: var(--ink2); max-width: 30ch; }
.card.side .now { top: 18px; right: 20px; }

.card.mood { height: 250px; display: flex; flex-direction: column; justify-content: flex-start; gap: 66px; }
.card.mood .art { justify-content: flex-start; }
.card.mood .art .icon { width: 44px; height: 44px; }
/* A real photo or emoji illustration reads richer than the flat line icon above, but at the
   icon's own 44px it would look like a thumbnail crop — a little bigger reads as art on
   purpose, not a fallback that didn't fit. */
.card.mood .art img { max-width: 64px; max-height: 64px; }
.card.mood .art .glyph { font-size: 56px; }
.card.mood .desc { margin-top: 8px; font-size: 14px; line-height: 1.5; color: var(--ink2); max-width: 32ch; }

.reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.8s var(--ease), transform 0.8s var(--ease); }
.reveal.in { opacity: 1; transform: none; }

/* ───────── Benefits strip ───────── */
.why { max-width: 1520px; margin: 0 auto; padding: 22px 32px 0; }
.why-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding: 30px 6px;
  border-radius: var(--r);
  /* Follows the page like every other content surface (.card, the FAQ's .q) — a hardcoded white
     here would go near-white-text-on-white in dark mode, since its own h3/p read from var(--ink). */
  background: var(--card);
}
.why-item { padding: 2px 30px; border-left: 1px solid var(--line); }
.why-item:first-child { border-left: 0; }
.why-item .ic {
  width: 44px;
  height: 44px;
  padding: 11px;
  border-radius: 50%;
  /* A step up from .why-grid's own now-var(--card) background, so the icon tile still reads as
     a distinct circle instead of blending into the panel. */
  background: var(--card-on);
  color: var(--ink);
  -webkit-mask: none;
  mask: none;
  position: relative;
}
/* the icon glyph sits inside the tile: mask lives on a pseudo-element so the tile keeps its fill */
.why-item .ic::before {
  content: '';
  position: absolute;
  inset: 11px;
  background: currentColor;
  -webkit-mask: var(--i) center / contain no-repeat;
  mask: var(--i) center / contain no-repeat;
}
.why-item h3 { margin: 18px 0 6px; font-size: 16px; font-weight: 600; letter-spacing: -0.015em; }
.why-item p { margin: 0; max-width: 30ch; font-size: 14px; line-height: 1.55; color: var(--ink2); }

/* ───────── FAQ ───────── */
.faq { max-width: 1520px; margin: 0 auto; padding: 96px 32px 0; }
.faq .sec { margin-bottom: 96px; }
/* Two independent columns: an open answer only pushes down its own column. */
.faq-grid { columns: 2; column-gap: 12px; }
.q { margin-bottom: 12px; break-inside: avoid; border-radius: var(--tile); background: var(--card); transition: background-color 0.25s ease, box-shadow 0.25s ease; }
.q:hover { background: var(--card-on); }
/* var(--card-on), not a hardcoded white — same bug as .why-grid above: the open answer's text
   reads from var(--ink)/var(--ink2), which is near-white in dark mode. */
.q[open] { background: var(--card-on); box-shadow: 0 0 0 1px var(--line); }
.q summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 20px 22px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.015em;
  cursor: pointer;
  list-style: none;
}
.q summary::-webkit-details-marker { display: none; }
.q summary .ic { flex: none; font-size: 20px; transition: transform 0.35s var(--ease); }
.q[open] summary .ic { transform: rotate(45deg); }
.q p { margin: 0; padding: 0 22px 22px; max-width: 58ch; font-size: 15px; line-height: 1.6; color: var(--ink2); animation: fade 0.35s ease both; }

/* ───────── Replay (the second live demo) ───────── */
/* Centered, unlike every other section header on the page — a deliberate one-off for the single
   "come play again" moment near the end, not a pattern reused elsewhere. */
.replay { max-width: 900px; margin: 0 auto; padding: 8px 32px 0; text-align: center; }
.replay h2 { margin: 0; font-size: clamp(2.1rem, 4.6vw, 3.4rem); font-weight: 600; line-height: 1.05; letter-spacing: -0.03em; }
.replay h2 span { display: block; color: var(--ink3); }
.replay > p { margin: 14px auto 0; max-width: 38ch; font-size: 15px; color: var(--ink2); }

.replay-frame {
  margin: 32px auto 0;
  border-radius: var(--r);
  overflow: hidden;
  background: #101211;
  box-shadow: 0 30px 70px rgba(17, 19, 20, 0.16);
}
.replay-frame iframe { display: block; width: 100%; height: 560px; border: 0; }

@media (max-width: 900px) {
  .replay-frame iframe { height: 480px; }
}
@media (max-width: 560px) {
  .replay { padding-inline: 16px; }
  .replay-frame iframe { height: 420px; }
}

/* ───────── Footer ───────── */
/* Fixed near-black + the brand's lime, not the page's own mode-dependent tokens or the stage's
   wallpaper gradient — this band is meant to read as "the brand," the same two colors as the
   logo mark, in both light and dark page mode alike. */
.foot {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin: 0 32px 32px;
  padding: 76px 56px;
  border-radius: var(--r);
  /* Explicit background-color, not the trailing color slot in the `background` shorthand — a
     bare var() there doesn't reliably parse as a color across engines and silently drops the
     whole background-color, leaving this transparent (and the white heading invisible on the
     light page behind it). */
  background-color: var(--chip-ink);
  background-image: radial-gradient(120% 160% at 88% 8%, rgba(189, 234, 63, 0.26), transparent 55%);
  color: #fff;
  max-width: 1456px;
}
@media (min-width: 1584px) { .foot { margin-left: auto; margin-right: auto; } }
.foot > div, .foot-ctas { position: relative; z-index: 1; }
.foot h2 { margin: 0; font-size: clamp(2.1rem, 3.6vw, 3.4rem); font-weight: 600; letter-spacing: -0.04em; line-height: 1.05; }
.foot p { margin: 12px 0 0; color: rgba(255, 255, 255, 0.78); font-size: 16px; }
.foot .get-dark { background: var(--lime); color: var(--chip-ink); flex: none; }
.foot .get-dark i { background: var(--chip-ink); color: var(--lime); }

/* A big, mostly-hidden echo of the logo mark itself (same rounded-square-plus-dot shape,
   scaled way up and faded into the corner) — a quiet brand flourish rather than another loud
   element, clipped by .foot's own overflow:hidden so it never pokes past the rounded corner. */
.foot-mark {
  position: absolute;
  top: -70px;
  right: -70px;
  width: 300px;
  height: 300px;
  border-radius: 86px;
  background: rgba(255, 255, 255, 0.04) radial-gradient(circle at 70% 30%, rgba(189, 234, 63, 0.4) 0 100px, transparent 102px);
  transform: rotate(-14deg);
  pointer-events: none;
  z-index: 0;
}

.foot-ctas { display: flex; flex-wrap: wrap; gap: 12px; flex: none; }
/* The trailing arrow (kept alongside the new platform icon, per request) — bare, not in its
   own circle badge, so the button reads as "[platform icon] Download for macOS →" rather than
   two competing icon badges. */
.get-arrow { width: 15px; height: 15px; margin-left: 2px; }

/* Windows isn't out yet — same shape and platform-icon language as the macOS button so the two
   read as a pair, but visibly inert: dimmed, no hover lift, not an actual link (a <span>, not
   an <a>, since there's nowhere for it to go yet). */
.get-soon { background: rgba(255, 255, 255, 0.14); color: rgba(255, 255, 255, 0.78); cursor: default; }
.get-soon i { background: rgba(255, 255, 255, 0.16); color: #fff; }
.get-soon:hover { box-shadow: none; }
.get-soon:active { transform: none; }

/* A quiet closing bar under the dark CTA band — follows the page's own light/dark mode (unlike
   the CTA band above it, which is always dark), since it's ordinary page chrome, not a moment. */
.site-foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 18px 28px;
  max-width: 1520px;
  margin: 0 auto;
  padding: 26px 32px 40px;
  border-top: 1px solid var(--line);
}
.sf-brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; flex: none; }
.sf-brand .brand-mark { width: 26px; height: 26px; border-radius: 8px; }
.sf-brand .brand-name { font-size: 14px; font-weight: 700; letter-spacing: -0.02em; }
.sf-tagline { margin: 0; font-size: 13px; color: var(--ink3); }
.sf-links { display: flex; gap: 20px; font-size: 13px; }
.sf-links a { color: var(--ink2); text-decoration: none; }
.sf-links a:hover { color: var(--ink); }
.sf-meta { display: flex; align-items: center; gap: 20px; margin-left: auto; font-size: 13px; color: var(--ink3); }
.sf-meta a { color: var(--ink3); text-decoration: none; }
.sf-meta a:hover { color: var(--ink); }

@media (max-width: 700px) {
  .site-foot { padding-inline: 16px; }
  .sf-meta { margin-left: 0; }
  .sf-tagline { flex-basis: 100%; order: 3; }
}

@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .chip { animation: none; }
  .card, .tray-card, .vert, .get, .q, .q summary .ic { transition: none; }
  .q p { animation: none; }
}

@media (max-width: 1100px) {
  .grid.charms { grid-template-columns: repeat(3, 1fr); }
}

/* Narrow screens: readable stack. The preview physics is mouse-driven, so this is a fallback,
   not a touch experience. */
@media (max-width: 900px) {
  .hero { height: auto; min-height: 0; }
  .frame { grid-template-columns: 1fr; height: auto; }
  .left { padding: 4px 14px 24px; }
  .right { height: 620px; }

  /* Below the width where macOS and Windows fit on one line, they wrap onto their own — each
     sized to its own text ("Windows" is longer than "macOS"), so stacked they visibly don't
     match. Stretching both to the row's full width (align-items overrides the default "center",
     which only sizes to content) makes them equal, with their contents centered rather than
     left-hugging the now-wider pill. */
  .hero-cta-downloads { flex-direction: column; align-items: stretch; }
  .hero-cta-downloads .hero-cta-primary { justify-content: center; }
  .grid.charms, .grid.wide, .grid.mood { grid-template-columns: repeat(2, 1fr); }
  .why-grid { grid-template-columns: repeat(2, 1fr); row-gap: 26px; }
  .why-item:nth-child(3) { border-left: 0; }
  .faq-grid { columns: 1; }
  .card.side { grid-template-columns: 1fr; height: auto; }
  .card.side .art { height: 200px; }
  .card.side .txt { padding: 4px 22px 22px; }
  .foot { flex-direction: column; align-items: flex-start; }

  /* The quick-pick tags (bottom-right) and the thumbnail tray (bottom-left) are sized for the
     wide desktop stage, where there's room for both. Below 900px the stage is narrower than the
     two put together, so they overlap — the tray's opaque panel was drawing over the left edge
     of whichever tag pills sat behind it. Every item here is already reachable from the pill nav
     up top and the full grid below, so hiding this shortcut row on the narrow stage is a clean
     way to drop the collision rather than trying to squeeze both into too little width. */
  .tags { display: none; }

  /* On the shorter 620px mobile stage (vs. the tall desktop hero), a hanging charm's resting
     swing reaches down into the same band as the hint chip at its desktop top:42%, so the coin/
     charm art was rendering over the chip's own text. Moving it down near the floor line clears
     the swing entirely. */
  #chipHint { top: 66%; }
}
@media (max-width: 560px) {
  .grid.charms, .grid.wide, .grid.mood { grid-template-columns: 1fr; }
  .why-grid { grid-template-columns: 1fr; }
  .why-item { border-left: 0; }
  .all, .why, .faq { padding-inline: 16px; }

  /* The thumbnail tray (3 cards + pager) is sized for the desktop stage; at phone widths the
     stage itself is only ~300-340px wide, and .stage clips overflow-x, so without this the
     "next" arrow and part of a card render entirely outside the visible/clickable area. */
  /* Smaller charm faces so "luck on your" + the faces fit on one line at phone width. */
  .faces { margin-left: 8px; }
  .faces i { width: 36px; height: 36px; margin-left: -11px; border-width: 2px; }
  .n-bl { padding: 12px 14px 12px 0; }
  .cards { gap: 6px; }
  .tray-card { width: 78px; height: 108px; padding: 8px 6px 28px; }
  .tray-card em { height: 24px; left: 5px; right: 5px; bottom: 5px; padding: 0 4px; font-size: 10px; }
  .pager { margin-top: 8px; }
  .pager b { font-size: 18px; }
  .pager button { width: 28px; height: 28px; }
}
