/* Packtray — landing page styles.
   Written to be edited: one section per heading, no minification, no utility soup.
   Sections, in order:
     1  Tokens          6  Stage (the interactive demo)
     2  Reset + base    7  Feature tiles
     3  Layout + type   8  Privacy
     4  Nav + buttons   9  Download + footer
     5  Hero           10  Reveal + responsive                                        */

/* ─────────────────────────────────────────────────────────── 1. Tokens ───── */

:root {
  --bg: #070707;
  --bg-lift: #0d0d0d;
  --panel: rgba(255, 255, 255, 0.032);
  --panel-solid: #111111;
  --line: rgba(255, 255, 255, 0.085);
  --line-soft: rgba(255, 255, 255, 0.05);

  --ink: #f4f4f4;
  --ink-2: #b4b4b4;
  --ink-3: #7a7a7a;

  /* No hue on the page at all. Emphasis is carried by brightness and weight, which is
     why --accent and --good are both plain white: what used to be "the green one" is
     now "the bright one". Keep it that way — a single colour creeping back in is what
     made the old build look generated. */
  --accent: #ffffff;
  --accent-soft: #8b86ff;
  --good: #ffffff;
  --warn: #9a9a9a;

  --radius: 16px;
  --radius-lg: 22px;

  /* One knob for the page's vertical rhythm. The old build used 130px top *and*
     bottom on every section, which is where all the dead air came from. */
  --section: clamp(54px, 6.5vw, 88px);
  --wrap: 1120px;

  --shadow: 0 24px 60px -28px rgba(0, 0, 0, 0.9);
  --shadow-lift: 0 30px 70px -26px rgba(0, 0, 0, 0.95);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ──────────────────────────────────────────────────── 2. Reset + base ───── */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 16px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Any [hidden] element must stay hidden even when a class gives it a display.
   Without this, `.out-live[hidden]` loses to `.out-live { display: grid }`. */
[hidden] { display: none !important; }

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
code, .mono { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace; }

/* Two soft lights, fixed so they don't scroll with the content. */
.ambient {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(760px 420px at 78% -6%, rgba(123, 123, 255, 0.14), transparent 70%),
    radial-gradient(620px 420px at 6% 34%, rgba(52, 211, 153, 0.05), transparent 72%);
}

main, nav, footer { position: relative; z-index: 1; }

/* ─────────────────────────────────────────────────── 3. Layout + type ───── */

.wrap {
  width: min(var(--wrap), calc(100% - 44px));
  margin-inline: auto;
}

/* Top-level only: nested <section>s (the shortcut groups) must not inherit this. */
main > section { padding: var(--section) 0; }

h1, h2, h3 { margin: 0; letter-spacing: -0.028em; line-height: 1.06; font-weight: 700; }
h1 { font-size: clamp(38px, 5.6vw, 66px); }
h2 { font-size: clamp(28px, 3.7vw, 43px); line-height: 1.1; }
h3 { font-size: 19px; line-height: 1.25; letter-spacing: -0.018em; }
p  { margin: 0; }

.eyebrow {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 15px;
  font-size: 11.5px;
  font-weight: 650;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--accent-soft);
}
.eyebrow span {
  width: 20px;
  height: 1px;
  background: currentColor;
  opacity: 0.55;
}

.head { max-width: 640px; margin-bottom: 34px; }
.head p.sub { margin-top: 13px; color: var(--ink-2); font-size: 16.5px; }
.head.center { margin-inline: auto; text-align: center; }
.head.center .eyebrow { justify-content: center; }

.g {
  background: linear-gradient(96deg, var(--accent-soft), #e6e6e6 55%, var(--good));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ──────────────────────────────────────────────────── 4. Nav + buttons ───── */

.nav {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(7, 7, 11, 0.76);
  backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid var(--line-soft);
}
.nav-inner {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 62px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 640;
  letter-spacing: -0.015em;
}
/* The app icon, drawn inline so it stays sharp at 26px. */
.mark {
  display: block;
  width: 26px;
  height: 26px;
  flex: none;
}
.mark svg { display: block; width: 100%; height: 100%; }

.status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 99px;
  border-radius: 99px;
  font-size: 10.5px;
  font-weight: 620;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.status i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--good);
  box-shadow: 0 0 9px var(--good);
}

.nav-links { margin-left: auto; display: flex; gap: 26px; font-size: 14.5px; color: var(--ink-2); }
.nav-links a:hover { color: var(--ink); }

.nav-cta {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 15px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  font-size: 14px;
  font-weight: 560;
  transition: border-color 0.2s, background 0.2s;
}
.nav-cta:hover { border-color: rgba(255, 255, 255, 0.3); background: rgba(255, 255, 255, 0.09); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 13px 22px;
  border-radius: 12px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  transition: transform 0.18s var(--ease), box-shadow 0.18s, background 0.2s;
}
/* Matches .btn.solid in the hero: one button treatment across the page. */
.btn.primary {
  background: var(--ink);
  color: #080808;
}
.btn.primary:hover { background: #fff; transform: translateY(-1px); }
.btn.quiet { border: 1px solid var(--line); color: var(--ink-2); }
.btn.quiet:hover { border-color: rgba(255, 255, 255, 0.2); color: var(--ink); }
.btn.big { padding: 15px 26px; font-size: 16px; }

/* ──────────────────────────────────────────────────────────── 5. Hero ───── */

/* One screen, everything centred: the mark, the line, what it does and two ways in, with
   the tools it works with along the bottom edge. The numbered cards (.hero-bits) float in
   the side gutters, and only when the window is wide enough for them to stay clear of the
   headline. The launch film lives behind "Watch the film", not on the page. */
.hero {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - 62px);
  min-height: calc(100svh - 62px);
  overflow: hidden;
}
/* The one lift on the page: a soft light over the mark, fading well before the edges. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(620px 420px at 50% 24%, rgba(139, 134, 255, 0.13), transparent 70%),
    radial-gradient(1200px 640px at 50% -8%, rgba(255, 255, 255, 0.05), transparent 70%);
  pointer-events: none;
}

.hero-center {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 56px 0 64px;
  text-align: center;
}

/* The mark. The outer box carries the rings and the light on the floor, which stay put;
   the inner one tilts under the pointer (hero.js). */
.hero-mark {
  position: relative;
  width: 104px;
  height: 104px;
  animation: hero-rise 0.9s var(--ease) both;
}
.hero-mark::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  top: 50%;
  width: 1160px;
  height: 1160px;
  transform: translate(-50%, -50%);
  background: repeating-radial-gradient(circle, transparent 0 129px, rgba(255, 255, 255, 0.05) 129px 130px);
  -webkit-mask: radial-gradient(circle, #000 16%, transparent 58%);
  mask: radial-gradient(circle, #000 16%, transparent 58%);
  pointer-events: none;
}
.hero-mark::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 16%;
  right: 16%;
  bottom: -18px;
  height: 22px;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(139, 134, 255, 0.5), transparent);
  filter: blur(8px);
}
.hero-mark-tilt {
  --rx: 0deg;
  --ry: 0deg;
  width: 100%;
  height: 100%;
  transform: perspective(600px) rotateX(var(--rx)) rotateY(var(--ry));
  transition: transform 0.18s ease-out;
}
.hero-mark svg {
  width: 100%;
  height: 100%;
  filter: drop-shadow(0 18px 28px rgba(0, 0, 0, 0.6));
}
/* The three bars drop into the tray, bottom one first: collecting, in one second. */
.mk-bar { animation: mk-drop 0.8s cubic-bezier(0.34, 1.3, 0.64, 1) both; }
.mk-3 { animation-delay: 0.3s; }
.mk-2 { animation-delay: 0.46s; }
.mk-1 { animation-delay: 0.62s; }

.hero h1 {
  margin-top: 34px;
  padding-bottom: 0.08em;
  font-size: clamp(42px, 6.4vw, 92px);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.045em;
  text-wrap: balance;
  background: linear-gradient(180deg, #ffffff 42%, #b8b8c2);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: hero-rise 0.9s var(--ease) 0.08s both;
}
.hero-lede {
  max-width: 600px;
  margin-top: 24px;
  font-size: clamp(16.5px, 1.3vw, 19px);
  line-height: 1.55;
  color: var(--ink-2);
  text-wrap: pretty;
  animation: hero-rise 0.9s var(--ease) 0.16s both;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 12px;
  margin-top: 36px;
  animation: hero-rise 0.9s var(--ease) 0.24s both;
}
.hero-actions .btn { height: 58px; padding: 0 28px; border-radius: 14px; }
.hero-actions .arr { display: inline-block; transition: transform 0.25s var(--ease); }
.hero-actions .btn:hover .arr { transform: translateY(2px); }
.hero-actions a:focus-visible { outline: 2px solid var(--accent-soft); outline-offset: 3px; }

/* "Watch the film": the film itself plays, small and muted, inside the button. */
.film-btn {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  height: 58px;
  padding: 6px 22px 6px 6px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.035);
  text-align: left;
  transition: border-color 0.2s, background 0.2s, transform 0.18s var(--ease);
}
.film-btn:hover {
  border-color: rgba(255, 255, 255, 0.24);
  background: rgba(255, 255, 255, 0.065);
  transform: translateY(-1px);
}
.film-thumb {
  position: relative;
  flex: none;
  width: 80px;
  height: 45px;
  overflow: hidden;
  border-radius: 9px;
  background: #050505 url("packtray-film-thumb.jpg") center / cover;
}
.film-thumb::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12);
  pointer-events: none;
}
.film-thumb video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.8;
  transition: transform 0.6s var(--ease), opacity 0.3s;
}
.film-btn:hover .film-thumb video { transform: scale(1.08); opacity: 1; }
.film-play { position: absolute; inset: 0; display: grid; place-items: center; }
.film-play svg {
  width: 24px;
  height: 24px;
  padding: 6px 5px 6px 7px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.94);
  fill: #080808;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.45);
  transition: transform 0.25s var(--ease);
}
.film-btn:hover .film-play svg { transform: scale(1.1); }
.film-text b { display: block; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; line-height: 1.25; }
.film-text em { display: block; font-size: 12.5px; font-style: normal; line-height: 1.3; color: var(--ink-3); }

.hero-note {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 6px 10px;
  margin-top: 22px;
  font-size: 13px;
  color: var(--ink-3);
  animation: hero-rise 0.9s var(--ease) 0.3s both;
}
.hero-note > span { display: inline-flex; align-items: center; gap: 8px; }
.hero-note i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent-soft);
  box-shadow: 0 0 10px var(--accent-soft);
}
.hero-note .sep { opacity: 0.45; }

.hero-works {
  position: relative;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 10px 28px;
  padding: 22px 0 26px;
  border-top: 1px solid var(--line-soft);
}

/* The numbered cards: the four things the demo collects, as the pack numbers them. Three
   layers so the motions don't fight: .bit follows the pointer, .bit-float bobs, and
   .bit-card holds the tilt and the entrance. */
.hero-bits { position: absolute; inset: 0; z-index: 1; display: none; pointer-events: none; }
@media (min-width: 1240px) and (min-height: 660px) {
  .hero-bits { display: block; }
}
.bit {
  position: absolute;
  transform: translate3d(calc(var(--px, 0) * var(--d) * -26px), calc(var(--py, 0) * var(--d) * -18px), 0);
  transition: transform 1s var(--ease);
}
.b1 { --d: 1.1; --r: -5deg; left: max(28px, calc(50% - 650px)); top: 14%; }
.b2 { --d: 0.7; --r: 3deg; left: max(52px, calc(50% - 600px)); top: 57%; }
.b3 { --d: 0.85; --r: 4deg; right: max(44px, calc(50% - 620px)); top: 19%; }
.b4 { --d: 1.25; --r: -3deg; right: max(28px, calc(50% - 650px)); top: 56%; }
.bit-float { animation: bit-float 9s ease-in-out infinite; }
.b2 .bit-float { animation-duration: 11s; animation-delay: -4s; }
.b3 .bit-float { animation-duration: 10s; animation-delay: -7s; }
.b4 .bit-float { animation-duration: 12s; animation-delay: -2s; }
.bit-card {
  position: relative;
  padding: 10px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 16px;
  background: linear-gradient(180deg, rgba(30, 30, 36, 0.92), rgba(16, 16, 19, 0.92));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 26px 60px -20px rgba(0, 0, 0, 0.9),
    0 10px 22px -12px rgba(0, 0, 0, 0.7);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  transform: rotate(var(--r));
  animation: bit-in 1.1s var(--ease) both;
}
.b1 .bit-card { animation-delay: 0.55s; }
.b3 .bit-card { animation-delay: 0.7s; }
.b2 .bit-card { animation-delay: 0.85s; }
.b4 .bit-card { animation-delay: 1s; }
.bit-n {
  position: absolute;
  top: -10px;
  left: -10px;
  z-index: 2;
  display: grid;
  place-items: center;
  min-width: 26px;
  height: 26px;
  padding: 0 8px;
  border-radius: 13px;
  background: #f4f4f4;
  color: #09090b;
  font-size: 12.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.55);
}
.bit-cap { display: block; padding: 0 4px 2px; text-align: left; }
.bit-cap b { display: block; font-size: 12.5px; font-weight: 600; letter-spacing: -0.005em; color: var(--ink); }
.bit-cap em { display: block; font-size: 11.5px; font-style: normal; color: var(--ink-3); }

.shot-mini {
  display: block;
  width: 188px;
  height: 108px;
  margin-bottom: 10px;
  overflow: hidden;
  border-radius: 9px;
  background: linear-gradient(155deg, #efeff2, #bcbcc4);
}
.sm-bar { display: flex; gap: 4px; padding: 7px 8px; background: rgba(0, 0, 0, 0.07); }
.sm-bar i { width: 6px; height: 6px; border-radius: 50%; background: rgba(0, 0, 0, 0.2); }
.sm-body { display: grid; gap: 7px; padding: 11px 12px; }
.sm-body > i { height: 5px; border-radius: 3px; background: rgba(0, 0, 0, 0.18); }
.sm-body .w70 { width: 70%; }
.sm-body .w45 { width: 45%; }
.sm-body .w60 { width: 60%; }
.sm-err {
  position: relative;
  display: flex;
  align-items: center;
  height: 17px;
  padding: 0 7px;
  border-radius: 5px;
  background: rgba(0, 0, 0, 0.78);
}
.sm-err i { width: 62%; height: 4px; border-radius: 2px; background: rgba(255, 255, 255, 0.55); }
/* A markup pin on the error, as the editor draws one. */
.sm-err b {
  position: absolute;
  right: -6px;
  top: -7px;
  display: grid;
  place-items: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  box-shadow: 0 0 0 2px #e4e4e8;
}

.bit-code {
  display: block;
  margin-bottom: 10px;
  padding: 11px 13px;
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 9px;
  background: rgba(0, 0, 0, 0.38);
  font-size: 11.5px;
  line-height: 1.6;
  color: #c4c4cc;
  text-align: left;
  white-space: nowrap;
}
.bit-code span { color: var(--accent-soft); }

.bit-row { display: flex; align-items: center; gap: 12px; padding: 13px 18px 13px 13px; }
.bit-row .bit-cap { padding: 0; }
.bit-file { width: 34px; height: 42px; flex: none; }
.bit-file .pg { fill: rgba(255, 255, 255, 0.07); stroke: rgba(255, 255, 255, 0.38); stroke-width: 1.3; }
.bit-file .fold { fill: rgba(255, 255, 255, 0.2); }
.bit-file .code { fill: none; stroke: var(--accent-soft); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.bit-note {
  max-width: 196px;
  margin: 4px 4px 10px;
  padding-left: 11px;
  border-left: 2px solid var(--accent-soft);
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--ink);
  text-align: left;
  text-wrap: pretty;
}

@keyframes hero-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes mk-drop { from { transform: translateY(-620px); } to { transform: none; } }
@keyframes bit-in {
  from { opacity: 0; transform: rotate(var(--r)) translateY(22px) scale(0.94); }
  to { opacity: 1; transform: rotate(var(--r)); }
}
@keyframes bit-float { 50% { transform: translateY(-10px); } }

/* The film, over everything. The dialog is as wide as the window allows while the video,
   its close button and caption still fit its height. */
.film {
  width: min(1120px, calc(100vw - 40px), calc((100vh - 150px) * 16 / 9));
  max-width: none;
  max-height: none;
  margin: auto;
  padding: 0;
  border: 0;
  overflow: visible;
  background: transparent;
  color: var(--ink);
}
.film::backdrop {
  background: rgba(4, 4, 6, 0.8);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.film[open] { animation: film-in 0.4s var(--ease); }
.film[open]::backdrop { animation: film-fade 0.3s ease; }
.film-frame {
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 18px;
  background: #000;
  box-shadow: 0 50px 120px -30px rgba(0, 0, 0, 0.95);
}
.film-frame video { display: block; width: 100%; height: 100%; }
.film-close {
  position: absolute;
  top: -50px;
  right: -6px;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
  color: var(--ink);
  transition: background 0.2s;
}
.film-close:hover { background: rgba(255, 255, 255, 0.2); }
.film-close:focus-visible { outline: 2px solid var(--accent-soft); outline-offset: 2px; }
.film-close svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.film-cap {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin-top: 14px;
  padding: 0 4px;
  font-size: 13px;
  color: var(--ink-3);
}
@media (pointer: coarse) { .film-esc { display: none; } }
html:has(.film[open]) { overflow: hidden; }
@keyframes film-in { from { opacity: 0; transform: translateY(10px) scale(0.98); } to { opacity: 1; transform: none; } }
@keyframes film-fade { from { opacity: 0; } to { opacity: 1; } }

/* White on black. A coloured gradient with a matching glow is the house style of every
   generated landing page; a flat inverted button is louder and cheaper. */
.btn.solid {
  padding: 13px 24px;
  border-radius: 10px;
  background: var(--ink);
  color: #080808;
  font-size: 15px;
  font-weight: 620;
  transition: background 0.18s, transform 0.16s var(--ease);
}
.btn.solid:hover { background: #fff; transform: translateY(-1px); }
.plain {
  font-size: 14.5px;
  color: var(--ink-3);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-color: rgba(255, 255, 255, 0.22);
}
.plain:hover { color: var(--ink-2); text-decoration-color: rgba(255, 255, 255, 0.45); }

.fine { font-size: 13px; color: var(--ink-3); }

.muted-label {
  font-size: 10.5px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.logos { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 25px; }
.logos b {
  font-size: 14.5px;
  font-weight: 560;
  color: var(--ink-3);
  transition: color 0.2s;
}
.logos b:hover { color: var(--ink-2); }

/* ─────────────────────────────────────────────────────────── 6. Stage ───── */

/* The two side columns are the same width and every column is stretched to the same
   height, so the three panels start and end on the same lines. Each column carries a
   label for the same reason: one missing label is what made the row look crooked. */
.stage {
  --demo-stage-height: 460px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.95fr) minmax(0, 1fr);
  gap: 18px;
  align-items: stretch;
  height: var(--demo-stage-height);
}
.col { display: flex; flex-direction: column; min-width: 0; min-height: 0; }

/* The window in the middle is the real UI, so it uses the app's own dark-theme tokens
   straight out of App.css rather than the page's greyscale. Same reasoning as the drop
   spot: it isn't an illustration of the app, it's a picture of it. Change it only
   alongside App.css. */
.col-app,
.shots {
  --surface: #1d1d23;
  --surface-2: #23232a;
  --app-bg: #141418;
  --app-border: rgb(255 255 255 / 8%);
  --app-border-strong: rgb(255 255 255 / 15%);
  --app-text: #ededf2;
  --app-text-2: #a3a3ae;
  --app-text-3: #7c7c88;
  --app-accent-solid: #6262ee;
  --app-ok: #34d399;
}

.col-label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 11px;
  font-size: 10.5px;
  font-weight: 640;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.dotline { width: 16px; height: 1px; background: currentColor; opacity: 0.6; }

.sources {
  flex: 1;
  display: grid;
  grid-template-rows: repeat(4, minmax(0, 1fr));
  gap: 9px;
  min-height: 0;
}
.src {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-radius: 13px;
  background: var(--panel);
  text-align: left;
  transition: border-color 0.18s, background 0.18s, transform 0.18s var(--ease);
}
.src:hover {
  border-color: rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.07);
  transform: translateX(3px);
}
.src:active { transform: translateX(3px) scale(0.985); }
.src-t b { display: block; font-size: 14px; font-weight: 560; }
.src-t i { font-style: normal; font-size: 11.5px; color: var(--ink-3); }
.src .add {
  margin-left: auto;
  display: grid;
  place-items: center;
  width: 21px;
  height: 21px;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.06);
  font-size: 14px;
  color: var(--ink-3);
}
.src:hover .add { background: rgba(255, 255, 255, 0.2); color: #fff; }

/* Icons are alpha masks, so one rule colours them all. demo.js copies the `--i`
   value onto the flying ghost, which is why it lives on the element itself. */
.src-ic,
.ghost span {
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.09);
  position: relative;
}
.src-ic::after,
.ghost span::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--accent-soft);
  -webkit-mask: var(--i) center / 55% no-repeat;
  mask: var(--i) center / 55% no-repeat;
}
.i-shot { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='2'/%3E%3Ccircle cx='8.5' cy='10' r='1.4'/%3E%3Cpath d='m21 15-5-5L5 19'/%3E%3C/svg%3E"); }
.i-text { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round'%3E%3Cpath d='M4 6h16M4 10.5h10M4 15h13M4 19.5h7'/%3E%3C/svg%3E"); }
.i-file { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 3v5h5'/%3E%3Cpath d='M19 8.5V19a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7z'/%3E%3C/svg%3E"); }
.i-note { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 20h9'/%3E%3Cpath d='M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z'/%3E%3C/svg%3E"); }

/* The app in the middle */
.app {
  flex: 1;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--app-border);
  border-radius: 14px;
  background: var(--app-bg);
  box-shadow: 0 2px 8px rgb(0 0 0 / 35%), 0 18px 44px rgb(0 0 0 / 45%);
  overflow: hidden;
}
.app-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--app-border);
  color: var(--app-text);
  font-size: 12.5px;
}
.lights { display: flex; gap: 5px; }
.lights i { width: 11px; height: 11px; border-radius: 50%; }
.lights i:first-child { background: #ff5f57; }
.lights i:nth-child(2) { background: #febc2e; }
.lights i:nth-child(3) { background: #28c840; }
.app-name { font-weight: 560; }
.app-count { margin-left: auto; font-size: 11.5px; color: var(--app-text-3); }
.app-count b { color: var(--app-text); font-weight: 620; }

.app-body {
  position: relative;
  flex: 1;
  min-height: 0;
  padding: 13px;
  overflow-y: auto;
  scrollbar-gutter: stable;
}
.app-grid { align-content: start; }
.app-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }
.app-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 13px;
  color: var(--app-text-3);
  transition: opacity 0.3s;
  pointer-events: none;
}

.tile {
  position: relative;
  padding: 8px;
  border: 1px solid var(--app-border);
  border-radius: 12px;
  background: var(--surface);
  box-shadow: 0 1px 2px rgb(0 0 0 / 30%);
  opacity: 0;
  transform: scale(0.9);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.tile.in { opacity: 1; transform: none; }
.tile .n {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 2;
  display: grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 10px;
  background: rgb(20 20 28 / 62%);
  backdrop-filter: blur(8px);
  color: #fff;
  font-size: 11px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.tile .th {
  display: grid;
  gap: 4px;
  align-content: center;
  height: 44px;
  padding: 8px;
  border-radius: 7px;
  margin-bottom: 7px;
}
.th.pale { background: linear-gradient(150deg, #e6e6e6, #b8b8b8); }
.th.dark { background: rgba(255, 255, 255, 0.06); }
.th.amber { background: rgba(255, 255, 255, 0.075); }
.th .b { height: 3px; border-radius: 2px; background: rgba(255, 255, 255, 0.22); }
.th.pale .b { background: rgba(0, 0, 0, 0.3); }
.th .b.red { background: #6f6f6f; }
.th .b.acc { background: var(--accent-soft); }
.tile .cap { display: block; padding: 0 1px; }
.tile .cap b { display: block; color: var(--app-text); font-size: 11.5px; font-weight: 560; line-height: 1.25; }
.tile .cap span { font-size: 11px; color: var(--app-text-2); white-space: nowrap; }

.app-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 13px;
  border-top: 1px solid var(--app-border);
  background: var(--surface-2);
}
.secrets { font-size: 11.5px; color: var(--app-ok); }
.pack-btn {
  margin-left: auto;
  height: 30px;
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: var(--app-accent-solid);
  color: #fff;
  font-size: 12.5px;
  font-weight: 550;
  box-shadow: 0 1px 2px rgb(40 40 160 / 25%), inset 0 1px 0 rgb(255 255 255 / 14%);
  transition: opacity 0.2s, transform 0.18s var(--ease);
}
.pack-btn:disabled { opacity: 0.32; cursor: not-allowed; }
.pack-btn:not(:disabled) { animation: armed 2.4s ease-in-out infinite; }
.pack-btn:not(:disabled):hover { background: #5757dd; }
.pack-btn:not(:disabled):hover { transform: translateY(-1px); }

@keyframes armed {
  0%, 100% { box-shadow: 0 0 0 0 rgb(123 123 255 / 45%), inset 0 1px 0 rgb(255 255 255 / 14%); }
  50%      { box-shadow: 0 0 0 7px rgb(123 123 255 / 0), inset 0 1px 0 rgb(255 255 255 / 14%); }
}


/* The pack on the right */
.out {
  flex: 1;
  display: flex;
  flex-direction: column;
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  padding: 14px;
  background: var(--panel);
  transition: border-style 0.3s, border-color 0.3s, background 0.3s;
}
.out[data-state="live"] {
  border-style: solid;
  border-color: rgba(255, 255, 255, 0.24);
  background: rgba(255, 255, 255, 0.035);
}
.out-idle {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 10px;
  flex: 1;
  text-align: center;
  font-size: 12.5px;
  color: var(--ink-3);
}
.out-ghost {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border: 1px dashed var(--line);
  border-radius: 11px;
  font-size: 15px;
}
.out-live {
  flex: 1;
  display: grid;
  align-content: start;
  gap: 11px;
  min-height: 0;
  overflow-y: auto;
  scrollbar-gutter: stable;
}

.tree {
  padding: 11px;
  border-radius: 11px;
  background: rgba(0, 0, 0, 0.35);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  line-height: 1.75;
  color: var(--ink-2);
  white-space: nowrap;
  overflow-x: auto;
}
.tree .root { color: var(--ink); font-weight: 620; }
.tree .md { color: var(--good); }

.msg { padding: 11px; border: 1px solid var(--line-soft); border-radius: 11px; background: rgba(255, 255, 255, 0.028); }
.msg-h {
  display: block;
  margin-bottom: 6px;
  font-size: 10px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.msg p { font-size: 12.5px; line-height: 1.55; color: var(--ink-2); min-height: 3.1em; }
.msg p::after {
  content: "";
  display: inline-block;
  width: 6px;
  height: 13px;
  margin-left: 2px;
  vertical-align: -2px;
  background: var(--accent-soft);
  animation: caret 1s steps(2) infinite;
}
.msg p.done::after { display: none; }

@keyframes caret { 50% { opacity: 0; } }

.targets { display: flex; flex-wrap: wrap; gap: 6px; }
.target {
  padding: 5px 10px;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.03);
  font-size: 11.5px;
  color: var(--ink-2);
}

.stage-foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  flex-wrap: wrap;
  margin-top: 20px;
}
.ghost-btn {
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 9px;
  font-size: 12.5px;
  color: var(--ink-2);
  transition: border-color 0.2s, color 0.2s;
}
.ghost-btn:hover { border-color: rgba(255, 255, 255, 0.22); color: var(--ink); }
.stage-note { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--ink-3); }
.stage-note i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--good);
  box-shadow: 0 0 8px var(--good);
}

/* The item flying from a source button into its new tile. */
.ghost {
  position: fixed;
  z-index: 80;
  display: grid;
  place-items: center;
  pointer-events: none;
  transition: transform 0.55s var(--ease), opacity 0.55s var(--ease);
}

/* ─────────────────────────────────────── 6a. Many screenshots at once ───── */

.shots-scene {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center;
  gap: clamp(16px, 3vw, 34px);
  padding: clamp(22px, 3.5vw, 40px);
  border: 1px solid var(--line);
  border-radius: 22px;
  background: #0a0a0a;
}

/* The key */
.shot-key {
  display: grid;
  justify-items: center;
  gap: 10px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.03);
  transition: background 0.18s, border-color 0.18s, transform 0.1s var(--ease);
}
.shot-key:hover { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.2); }
.shot-key.pressed { transform: scale(0.96); }

.shot-keys { display: flex; gap: 5px; }
.shot-keys kbd {
  display: grid;
  place-items: center;
  min-width: 34px;
  height: 38px;
  padding: 0 8px;
  border: 1px solid var(--line-soft);
  border-bottom-color: rgba(0, 0, 0, 0.55);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px;
  color: var(--ink-2);
  transition: background 0.12s, color 0.12s;
}
.shot-key.pressed .shot-keys kbd { background: var(--ink); color: #080808; }
.shot-hint { font-size: 11.5px; color: var(--ink-3); }

/* Three dots travelling toward the window. */
.shots-flow { display: flex; gap: 7px; }
.shots-flow i {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.3);
  animation: flow 1.6s ease-in-out infinite;
}
.shots-flow i:nth-child(2) { animation-delay: 0.18s; }
.shots-flow i:nth-child(3) { animation-delay: 0.36s; }

@keyframes flow {
  0%, 100% { opacity: 0.2; transform: translateX(-3px); }
  50%      { opacity: 1; transform: translateX(3px); }
}

/* The window they land in, in the app's own colours. */
.shots-app {
  border: 1px solid var(--app-border);
  border-radius: 14px;
  background: var(--app-bg);
  box-shadow: 0 2px 8px rgb(0 0 0 / 35%), 0 18px 44px rgb(0 0 0 / 45%);
  overflow: hidden;
}
.shots-body { position: relative; min-height: 168px; padding: 13px; }
.shots-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-content: start;
  gap: 9px;
}
.shots-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 12.5px;
  color: var(--app-text-3);
  transition: opacity 0.3s;
  pointer-events: none;
}
.shots-empty.gone { opacity: 0; }

.shot-tile {
  position: relative;
  display: block;
  padding: 7px;
  border: 1px solid var(--app-border);
  border-radius: 12px;
  background: var(--surface);
  box-shadow: 0 1px 2px rgb(0 0 0 / 30%);
  opacity: 0;
  transform: scale(0.88);
  transition: opacity 0.26s var(--ease), transform 0.26s var(--ease);
}
.shot-tile.in { opacity: 1; transform: none; }
.shot-tile .n {
  position: absolute;
  top: 5px;
  left: 5px;
  z-index: 2;
  display: grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: rgb(20 20 28 / 62%);
  backdrop-filter: blur(8px);
  color: #fff;
  font-size: 10px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.shot-tile .sh {
  display: grid;
  gap: 5px;
  align-content: center;
  height: 44px;
  padding: 9px;
  border-radius: 7px;
  background: linear-gradient(150deg, #e4e4e9, #b6b6bf);
}
.shot-tile .sh i { height: 3px; border-radius: 2px; background: rgba(0, 0, 0, 0.32); }

/* A capture in flight. */
.shot-ghost {
  position: fixed;
  z-index: 60;
  width: 52px;
  height: 36px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 6px;
  background: linear-gradient(150deg, #e4e4e9, #b6b6bf);
  box-shadow: 0 10px 24px -8px rgba(0, 0, 0, 0.9);
  pointer-events: none;
  transition: transform 0.42s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.42s ease;
}

.shots-note { margin-top: 16px; text-align: center; font-size: 13px; color: var(--ink-3); }
.shots-note b { color: var(--ink-2); font-weight: 560; }

/* ───────────────────────────────────────────── 6b. Keyboard shortcuts ───── */

.shortcuts { background: linear-gradient(180deg, transparent, rgba(255, 255, 255, 0.015), transparent); }

.kb-layout { display: grid; justify-items: center; }

/* macOS / Windows. The bindings really differ, so this isn't decoration. */
.kb-os {
  display: inline-flex;
  gap: 4px;
  margin-bottom: 22px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
}
.kb-os-btn {
  padding: 7px 17px;
  border-radius: 9px;
  font-size: 13px;
  font-weight: 560;
  color: var(--ink-3);
  transition: background 0.18s, color 0.18s;
}
.kb-os-btn:hover { color: var(--ink-2); }
.kb-os-btn.on { background: var(--ink); color: #080808; }

/* The board. Capped rather than full-bleed, so the keys keep something like real key
   proportions instead of stretching into letterboxes on a wide screen. */
.kb {
  display: grid;
  gap: 7px;
  width: 100%;
  max-width: 800px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: #0a0a0a;
}
.kb-row { display: flex; gap: 7px; }

.kb-key {
  flex-basis: 0;
  display: grid;
  place-items: center;
  height: 48px;
  border: 1px solid var(--line-soft);
  border-bottom-color: rgba(0, 0, 0, 0.55);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.035);
  font-size: 13px;
  font-weight: 540;
  color: var(--ink-3);
  transition: background 0.22s, color 0.22s, border-color 0.22s, transform 0.12s var(--ease);
}

/* While a shortcut is showing the rest of the board recedes, so the combination reads
   at a glance instead of having to be picked out. */
.kb.dimmed .kb-key { color: rgba(255, 255, 255, 0.2); border-color: rgba(255, 255, 255, 0.035); }

/* Must out-specify `.kb.dimmed .kb-key` above (0,3,0), or the lit key inherits the
   dimmed near-white text and its glyph disappears into the white cap. */
.kb .kb-key.lit,
.kb.dimmed .kb-key.lit {
  background: var(--ink);
  border-color: var(--ink);
  color: #080808;
  font-weight: 650;
  transform: translateY(1px);
}

/* Reads out whichever row is showing, so the board makes sense on its own. */
.kb-now {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 22px 0 34px;
}
.kb-now b {
  flex: none;
  padding: 8px 14px;
  border-radius: 9px;
  background: var(--ink);
  color: #080808;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px;
  font-weight: 650;
}
.kb-now span { font-size: 17px; color: var(--ink); letter-spacing: -0.015em; }

/* The three groups */
.kb-groups {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 26px 22px;
  align-items: start;
  width: 100%;
}
.kb-group h3 {
  margin-bottom: 9px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--line-soft);
  font-size: 10.5px;
  font-weight: 620;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.kb-group ul { list-style: none; margin: 0; padding: 0; }

.kb-groups button {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: 9px;
  text-align: left;
  transition: background 0.18s, border-color 0.18s;
}
.kb-groups li.on button { background: rgba(255, 255, 255, 0.06); border-color: var(--line); }
.kb-groups button:hover { background: rgba(255, 255, 255, 0.06); }

.kb-groups kbd {
  flex: none;
  min-width: 68px;
  padding: 4px 7px;
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.05);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  text-align: center;
  color: var(--ink-2);
}
.kb-groups li.on kbd { background: var(--ink); border-color: var(--ink); color: #080808; }
.kb-groups button span { font-size: 13.5px; color: var(--ink-2); }
.kb-groups li.on button span { color: var(--ink); }

.kb-more { margin-top: 24px; font-size: 13px; color: var(--ink-3); }

/* ──────────────────────────────────────────────── 6c. The drop spot ───── */

/* The section is a Mac desktop: wallpaper, menu bar, a window in front, and the spot
   pinned to the bottom-right corner of the screen. That arrangement is the feature —
   it sits above whatever you're working in — so showing it beats describing it. */

.mac {
  position: relative;
  aspect-ratio: 16 / 9.4;
  min-height: 330px;
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  /* A wallpaper, kept greyscale like the rest of the page so the spot stays the only
     coloured thing on screen. */
  /* A wallpaper, in the app's own accent family so the spot sits on it naturally. */
  background:
    radial-gradient(88% 70% at 18% -12%, rgba(123, 123, 255, 0.34), transparent 62%),
    radial-gradient(76% 62% at 90% 110%, rgba(52, 211, 153, 0.2), transparent 60%),
    radial-gradient(60% 55% at 62% 42%, rgba(178, 120, 255, 0.13), transparent 72%),
    linear-gradient(158deg, #1b1934 0%, #101019 56%, #15152252 100%),
    #0f0f16;
}

/* Menu bar */
.mac-bar {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 15px;
  height: 25px;
  padding: 0 14px;
  background: rgba(255, 255, 255, 0.07);
  backdrop-filter: blur(14px) saturate(140%);
  font-size: 11px;
  color: rgba(255, 255, 255, 0.62);
}
.mac-logo {
  width: 11px;
  height: 13px;
  background: rgba(255, 255, 255, 0.72);
  /* An apple-ish silhouette, drawn rather than traced: a round body with a bite. */
  -webkit-mask: radial-gradient(circle at 50% 62%, #000 52%, transparent 53%);
  mask: radial-gradient(circle at 50% 62%, #000 52%, transparent 53%);
}
.mac-menu.strong { color: rgba(255, 255, 255, 0.9); font-weight: 620; }
.mac-tray { margin-left: auto; color: rgba(255, 255, 255, 0.9); flex: none; }
.mac-clock { font-variant-numeric: tabular-nums; }

/* The window you're working in */
.ds-win {
  position: absolute;
  left: 7%;
  top: 19%;
  width: min(68%, 520px);
  z-index: 1;
  border: 1px solid rgba(255, 255, 255, 0.11);
  border-radius: 11px;
  background: #121215;
  box-shadow: 0 26px 60px -22px rgba(0, 0, 0, 1);
  overflow: hidden;
}
/* The window chrome: toolbar, then a sidebar beside the list, the way Finder is laid
   out. It is macOS furniture rather than our app, so it carries macOS's own blue and
   nothing of the product's palette. */
.ds-win-bar {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 11px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  background: rgba(255, 255, 255, 0.045);
}
.ds-arrows { display: flex; gap: 2px; }
.ds-arrows svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: rgba(255, 255, 255, 0.32);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ds-win-name {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 560;
  color: var(--ink-2);
}
.ic-folder { width: 14px; height: 12px; fill: #56a8ff; opacity: 0.9; }

/* The four view buttons; the list view is the one that's on. */
.ds-views { margin-left: auto; display: flex; gap: 3px; }
.ds-views i {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.09);
}
.ds-views i.on { background: rgba(255, 255, 255, 0.24); }

.ds-win-main { display: flex; align-items: stretch; }

/* Favourites */
.ds-side {
  flex: none;
  width: 108px;
  padding: 8px 7px 10px;
  border-right: 1px solid rgba(255, 255, 255, 0.06);
  background: rgba(255, 255, 255, 0.022);
}
.ds-side p {
  margin: 0 0 4px 7px;
  font-size: 9px;
  font-weight: 620;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.3);
}
.ds-side ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; }
.ds-side li {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3.5px 7px;
  border-radius: 5px;
  font-size: 10.5px;
  color: rgba(255, 255, 255, 0.58);
}
.ds-side li.on { background: rgba(255, 255, 255, 0.1); color: var(--ink); }
.ds-side svg {
  flex: none;
  width: 12px;
  height: 12px;
  fill: none;
  stroke: #56a8ff;
  stroke-width: 1.35;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The list, with its column headings */
.ds-list { flex: 1; min-width: 0; padding: 5px 6px 7px; }
.ds-cols,
.ds-file {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) 52px 88px;
  align-items: center;
  gap: 9px;
}
.ds-cols {
  padding: 0 9px 5px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  font-size: 9.5px;
  letter-spacing: 0.03em;
  color: rgba(255, 255, 255, 0.34);
}
.ds-cols span:first-child { grid-column: 2; }
.ds-cols span:nth-child(2) { text-align: right; }

.ds-win-body { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 1px; }

.ds-file {
  padding: 5px 9px;
  border: 1px solid transparent;
  border-radius: 6px;
  font-size: 12px;
  color: var(--ink-2);
  cursor: grab;
  user-select: none;
  transition: background 0.16s, border-color 0.16s, opacity 0.16s;
}
/* Finder's own row stripes. */
.ds-file:nth-child(even) { background: rgba(255, 255, 255, 0.028); }
.ds-file:hover,
.ds-file.picked { background: rgba(86, 168, 255, 0.24); border-color: rgba(86, 168, 255, 0.34); color: var(--ink); }
.ds-file:active { cursor: grabbing; }
.ds-file.lifting { opacity: 0.35; }
.ds-file b {
  min-width: 0;
  font-weight: 500;
  font-size: 11px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ds-file em { font-style: normal; font-size: 10.5px; text-align: right; color: var(--ink-3); }
.ds-kind { font-size: 10.5px; white-space: nowrap; color: var(--ink-3); }

/* One document icon per kind, drawn the way macOS draws them: a white page with a
   folded corner, and a preview instead of a page for the picture. */
.ds-ic { flex: none; width: 17px; height: 21px; }
.ds-ic .pg { fill: #fafafc; stroke: rgba(0, 0, 0, 0.22); stroke-width: 0.7; }
.ds-ic .fold { fill: #d3d3dc; }
.ds-ic .ln { fill: #b6b6c2; }
.ds-ic .shot { fill: #2a2a33; }
.ds-ic .acc { fill: #ff5f57; }
.ds-ic .tag { fill: #f4453c; }
.ds-ic .code {
  fill: none;
  stroke: #3178c6;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The spot, in the screen's bottom-right corner and above the window. */
.ds-float {
  position: absolute;
  right: 12px;
  bottom: 10px;
  z-index: 2;
  /* The real card casts no shadow on purpose (its own window is transparent), so the
     elevation that sells "above everything" lives out here instead. */
  filter: drop-shadow(0 16px 26px rgba(0, 0, 0, 0.8));
}

/* The pointer, and the file it carries. Both are moved by dropspot.js in pixels
   measured from the live layout, so they land correctly at any width. */
.mac-cursor {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 6;
  width: 21px;
  height: 21px;
  fill: #fff;
  stroke: rgba(0, 0, 0, 0.55);
  stroke-width: 1.1;
  stroke-linejoin: round;
  opacity: 0;
  pointer-events: none;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.5));
  transition: transform 0.9s cubic-bezier(0.45, 0, 0.25, 1), opacity 0.3s ease;
}
.mac-cursor.grabbing { transform-origin: 4px 3px; }

.mac-drag {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 9px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 7px;
  background: rgba(24, 24, 28, 0.95);
  box-shadow: 0 10px 22px -8px rgba(0, 0, 0, 0.9);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px;
  color: var(--ink-2);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: transform 0.9s cubic-bezier(0.45, 0, 0.25, 1), opacity 0.25s ease;
}

.ds-note { margin-top: 16px; text-align: center; font-size: 13px; color: var(--ink-3); }
.ds-note b { color: var(--ink-2); font-weight: 560; }

/* ── From here down: DropSpot.css, kept as close to the original as the page allows ── */

.dropspot {
  --spot-bg: rgb(26 26 33 / 88%);
  --spot-line: rgb(255 255 255 / 11%);
  --spot-text: rgb(238 238 245 / 92%);
  --spot-text-2: rgb(238 238 245 / 55%);
  --spot-accent: #8b83ff;
  --spot-accent-soft: rgb(123 115 255 / 18%);
  --spot-ok: #34d399;
  --spot-warn: #fbbf24;
}

.spot {
  position: relative;
  display: grid;
  place-items: center;
  width: 116px;
  height: 116px;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.spot-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: 88px;
  height: 88px;
  border: 1px solid var(--spot-line);
  border-radius: 22px;
  background: var(--spot-bg);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 7%);
  backdrop-filter: blur(22px) saturate(140%);
  transition:
    transform 0.18s cubic-bezier(0.2, 0.8, 0.2, 1),
    border-color 0.18s ease,
    background 0.18s ease;
}

/* The dashed well is what says "drop here" before any word is read. */
.spot-well {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border: 1.5px dashed rgb(255 255 255 / 22%);
  border-radius: 14px;
  color: var(--spot-text-2);
  transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
}

.spot-label {
  color: var(--spot-text-2);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  transition: color 0.18s ease;
}

/* How much is waiting in the session: the spot doubles as a quiet status light. */
.spot-count {
  position: absolute;
  top: -6px;
  right: -6px;
  display: grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border: 1px solid rgb(0 0 0 / 25%);
  border-radius: 10px;
  background: #6262ee;
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.spot:hover .spot-card { border-color: rgb(255 255 255 / 18%); transform: translateY(-1px); }
.spot:hover .spot-well,
.spot:hover .spot-label { color: var(--spot-text); }
.spot:active .spot-card { transform: translateY(0) scale(0.98); }

/* Something is being dragged over it. */
.spot.drag .spot-card {
  border-color: rgb(139 131 255 / 55%);
  background: rgb(31 29 48 / 92%);
  transform: scale(1.04);
}
.spot.drag .spot-well {
  border-style: solid;
  border-color: var(--spot-accent);
  background: var(--spot-accent-soft);
  color: var(--spot-accent);
}
.spot.drag .spot-label { color: var(--spot-accent); }

.spot.ok .spot-well {
  border-style: solid;
  border-color: var(--spot-ok);
  background: rgb(52 211 153 / 14%);
  color: var(--spot-ok);
}
.spot.ok .spot-label { color: var(--spot-ok); }

.spot.error .spot-well {
  border-style: solid;
  border-color: var(--spot-warn);
  background: rgb(251 191 36 / 14%);
  color: var(--spot-warn);
}
.spot.error .spot-label { color: var(--spot-warn); }

@media (prefers-reduced-motion: no-preference) {
  /* The arrow dips into the tray while a drag hovers: the only movement here. */
  .spot.drag .tray-arrow { animation: drop-in 1.1s ease-in-out infinite; }

  @keyframes drop-in {
    0%, 100% { transform: translateY(-1px); opacity: 0.75; }
    45%      { transform: translateY(2px); opacity: 1; }
  }
}

/* ────────────────────────────────────────────────── 7. Feature tiles ───── */

/* The tiles show the app's own surfaces, so they carry its palette: the dark-theme
   tokens from App.css, plus the markup editor's real shape colours from markup.ts
   (MARK #ff3b30, HIGHLIGHT rgb(255 214 10 / 42%), COVER #1c1c20). */
.tiles {
  --app-surface: #1d1d23;
  --app-border: rgb(255 255 255 / 8%);
  --app-text: #ededf2;
  --app-text-2: #a3a3ae;
  --app-accent: #7b7bff;
  --app-accent-soft: rgb(123 123 255 / 14%);
  --app-ok: #34d399;
  --app-ok-soft: rgb(52 211 153 / 13%);
  --app-danger: #f87171;
  --app-danger-soft: rgb(248 113 113 / 12%);
  --mark: #ff3b30;
  --highlight: rgb(255 214 10 / 42%);
  --cover: #1c1c20;
}

.tiles-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  /* start, not stretch: each tile takes the height its content needs, so the grid reads
     as a bento of different-sized cards rather than a table of equal boxes. */
  align-items: start;
  gap: 14px;
}

.fcard {
  grid-column: span 6;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: linear-gradient(168deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012));
  transition: border-color 0.25s, transform 0.25s var(--ease);
}
.fcard:hover { border-color: rgba(255, 255, 255, 0.16); transform: translateY(-3px); }
.fcard.span7 { grid-column: span 7; }
.fcard.span5 { grid-column: span 5; }
.fcard.span4 { grid-column: span 4; }

.chip {
  align-self: flex-start;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.04);
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.fcard h3 { margin-bottom: 7px; }
.fcard p { font-size: 13.5px; line-height: 1.55; color: var(--ink-3); }
/* Only a trailing copy block absorbs the slack, so cards whose text sits above
   the visual don't get a gap pushed into their middle. */
.fcard .tc-copy:last-child { margin-top: auto; }

.viz {
  border: 1px solid var(--line-soft);
  border-radius: 14px;
  background: rgba(0, 0, 0, 0.26);
  padding: 16px;
}

/* 7a. Everything queues — many things in, one thing out. */
.viz-queue { display: grid; gap: 15px; }
.q-stack { display: flex; align-items: center; padding-left: 4px; }
.q-shot {
  position: relative;
  overflow: hidden;
  display: grid;
  gap: 4px;
  align-content: center;
  width: 58px;
  height: 42px;
  padding: 8px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 6px;
  background: linear-gradient(150deg, #e4e4e9, #b6b6bf);
  box-shadow: 0 6px 16px -8px rgba(0, 0, 0, 0.9);
}
.q-shot i { height: 3px; border-radius: 2px; background: rgba(0, 0, 0, 0.32); }
.q-shot i:nth-child(1) { width: 78%; }
.q-shot i:nth-child(2) { width: 46%; }
.q-shot i:nth-child(3) { width: 64%; }
.q-shot.a { transform: rotate(-6deg); }
.q-shot.b { margin-left: -14px; transform: rotate(-1deg); }
.q-shot.c { margin-left: -14px; transform: rotate(4deg); }
.q-shot.d { margin-left: -14px; transform: rotate(9deg); }

.q-flow { display: flex; align-items: center; gap: 14px; }
.q-tally, .q-out {
  display: flex;
  align-items: baseline;
  gap: 7px;
  padding: 8px 13px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.035);
}
.q-tally b, .q-out b { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }
.q-tally em, .q-out em { font-style: normal; font-size: 11.5px; color: var(--ink-3); }
.q-out { border-color: rgba(52, 211, 153, 0.34); background: rgba(52, 211, 153, 0.08); }
.q-out b { color: var(--app-ok); }
.q-wire {
  flex: 1;
  position: relative;
  height: 1px;
  background: rgba(255, 255, 255, 0.14);
}

/* 7b. Image prep — a before/after pair, the bars in proportion to the pixel counts. */
.viz-size { display: grid; gap: 10px; }
.sz-row { display: flex; align-items: center; gap: 11px; }
.sz-label { width: 46px; flex: none; font-size: 11.5px; color: var(--ink-3); }
.sz-track {
  flex: 1;
  height: 12px;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.06);
  overflow: hidden;
}
.sz-fill { position: relative; display: block; height: 100%; border-radius: 99px; overflow: hidden; }
/* Widths are the real ratio: 2048×1152 is 16% of 5120×2880's pixels. */
.sz-fill.before { width: 100%; background: rgba(255, 255, 255, 0.3); }
.sz-fill.after  { width: 16%; background: var(--app-ok); }
.sz-val {
  width: 86px;
  flex: none;
  text-align: right;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px;
  color: var(--ink-3);
}
.sz-val.ok { color: var(--app-ok); }
.sz-note { margin-top: 3px; font-size: 12.5px; color: var(--ink-3); }
.sz-note b { font-size: 21px; font-weight: 700; letter-spacing: -0.02em; color: var(--app-ok); margin-right: 6px; }

/* 7c. OCR */
.viz-ocr { position: relative; overflow: hidden; }
.ocr-shot {
  display: grid;
  gap: 7px;
  align-content: center;
  height: 96px;
  padding: 14px;
  border-radius: 9px;
  background: linear-gradient(150deg, #e9e9e9, #c4c4c4);
}
.ocr-shot i { height: 5px; border-radius: 3px; background: rgba(0, 0, 0, 0.32); }
.ocr-shot i:nth-child(1) { width: 78%; }
.ocr-shot i:nth-child(2) { width: 52%; background: rgba(0, 0, 0, 0.6); }
.ocr-shot i:nth-child(3) { width: 66%; }
.scan-line {
  position: absolute;
  left: 16px;
  right: 16px;
  top: 16px;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--app-accent), transparent);
  box-shadow: 0 0 14px var(--app-accent);
  animation: scan 2.8s ease-in-out infinite;
}
@keyframes scan {
  0%, 100% { transform: translateY(2px); }
  50%      { transform: translateY(90px); }
}
.ocr-found {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 11px;
  padding: 5px 10px;
  border-radius: 7px;
  background: var(--app-ok-soft);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px;
  color: var(--app-ok);
}

/* 7d. Annotation — the marks sit on the shot and a pen keeps working over them. */
.viz-markup { position: relative; }
.markup-shot {
  position: relative;
  height: 130px;
  padding: 16px;
  border-radius: 9px;
  background: linear-gradient(150deg, #e9e9e9, #c4c4c4);
  color: #161616;
  overflow: hidden;
}
.markup-shot .mk-title { font-size: 13.5px; font-weight: 640; }

.mk-highlight {
  position: absolute;
  left: 16px;
  top: 46px;
  width: 124px;
  height: 13px;
  border-radius: 2px;
  background: var(--highlight);
  overflow: hidden;
}
.mk-box {
  position: absolute;
  left: 156px;
  top: 38px;
  width: 96px;
  height: 34px;
  border: 2px solid var(--mark);
  border-radius: 4px;
}
.mk-redact {
  position: absolute;
  left: 16px;
  bottom: 20px;
  width: 104px;
  height: 13px;
  border-radius: 2px;
  background: var(--cover);
}
.mk-arrow {
  position: absolute;
  right: 22px;
  bottom: 18px;
  width: 46px;
  height: 46px;
  fill: none;
  stroke: var(--mark);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mk-arrow .head { fill: var(--mark); stroke: none; }
.mk-pin {
  position: absolute;
  right: 18px;
  top: 16px;
  display: grid;
  place-items: center;
  width: 23px;
  height: 23px;
  border-radius: 50%;
  background: var(--mark);
  color: #fff;
  font-size: 11px;
  font-weight: 650;
  box-shadow: 0 5px 14px -4px rgba(0, 0, 0, 0.5);
}

/* The pen that keeps circling the marks. */
.mk-pen {
  position: absolute;
  width: 13px;
  height: 13px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  background: #161616;
  box-shadow: 0 0 0 3px rgba(22, 22, 22, 0.18), 0 3px 8px rgba(0, 0, 0, 0.35);
}

.keys { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 12px; }
.key {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 9px;
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.05);
  font-size: 11px;
  color: var(--ink-2);
}
.key b { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 620; color: var(--ink); }

/* 7e. Secrets */
.viz-mask { display: grid; gap: 8px; justify-items: start; }
.viz-mask code {
  width: 100%;
  padding: 9px 11px;
  border-radius: 8px;
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.code-before { background: var(--app-danger-soft); color: var(--app-danger); }
.code-after { background: var(--app-ok-soft); color: var(--app-text-2); }
/* The placeholder is the real one the exporter writes; see secrets.rs. */
.code-after b {
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--app-ok);
  color: #0c2a1e;
  font-weight: 620;
}
.mask-arrow { font-size: 13px; color: var(--ink-3); padding-left: 10px; }

/* 7f. Order */
.viz-order { display: grid; gap: 7px; }
.viz-order span {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 11px;
  border: 1px solid var(--line-soft);
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.03);
  font-size: 12px;
}
.viz-order b {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px;
  color: var(--app-accent);
}
.viz-order .ctx {
  border-color: var(--app-ok-soft);
  background: var(--app-ok-soft);
  color: var(--app-ok);
}

/* Product examples, simplified from the actual app surfaces. Each card shows a useful
   before/after action instead of a decorative diagram. No screenshot/video request or JS timer. */
.tiles .head .sub { max-width: 590px; margin-top: 17px; }
.viz-product-session, .viz-product-clipboard, .viz-product-ocr, .viz-product-markup {
  position: relative;
  overflow: hidden;
  color: var(--app-text);
  background: #141419;
  border-color: rgba(255,255,255,.1);
}
.viz-product-session { padding: 0; min-height: 280px; }
.product-titlebar { display: flex; align-items: center; gap: 10px; height: 37px; padding: 0 14px; border-bottom: 1px solid var(--app-border); font-size: 12px; }
.product-titlebar strong { font-weight: 650; }
.product-titlebar small { margin-left: auto; color: var(--app-text-2); }
.window-dots { display: flex; gap: 4px; }
.window-dots i { width: 7px; height: 7px; border-radius: 50%; background: #ff5f57; }
.window-dots i:nth-child(2) { background: #febc2e; }
.window-dots i:nth-child(3) { background: #28c840; }
.product-items { display: grid; gap: 5px; padding: 12px 14px; }
.product-items > span { display: flex; align-items: center; gap: 10px; min-height: 38px; padding: 6px 10px; border: 1px solid var(--app-border); border-radius: 8px; background: #1e1e25; white-space: nowrap; overflow: hidden; }
.product-items b { font: 600 10px ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--app-accent); }
.product-items i { flex: none; display: grid; place-items: center; width: 21px; height: 21px; border-radius: 5px; font-size: 10px; font-style: normal; color: #9995ff; background: #2c2b40; }
.product-items .mini-image::after { content: "▧"; }
.product-items strong { overflow: hidden; text-overflow: ellipsis; font-size: 11.5px; font-weight: 580; }
.product-items em { margin-left: auto; color: var(--app-text-2); font-size: 10px; font-style: normal; }
.product-footer { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 8px 14px; border-top: 1px solid var(--app-border); background: #202028; font-size: 11px; color: var(--app-text-2); }
.product-footer b { padding: 7px 11px; border-radius: 7px; background: #615af1; color: #fff; font-size: 10px; font-weight: 650; }
.product-footer b span { margin-left: 7px; }
.demo-pointer { position: absolute; z-index: 5; width: 15px; height: 20px; pointer-events: none; filter: drop-shadow(0 2px 2px #000); }
.demo-pointer::before { content: ""; display: block; width: 0; height: 0; border-top: 17px solid #fff; border-right: 11px solid transparent; transform: rotate(-18deg); filter: drop-shadow(1px 1px #111); }
.session-pointer { left: 68%; top: 64%; animation: pointer-pack 6s ease-in-out infinite; }
@keyframes pointer-pack { 0%, 12% { left: 64%; top: 61%; opacity: 0; } 20% { opacity: 1; } 43%, 60% { left: 85%; top: 89%; opacity: 1; } 66% { transform: scale(.8); } 76%, 100% { left: 85%; top: 89%; opacity: 0; } }

.viz-product-clipboard { min-height: 280px; padding: 13px; }
.clip-demo-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 6px 3px 11px; color: #9898a4; font-size: 10px; letter-spacing: .08em; }
.clip-demo-toolbar b { padding: 2px 5px; border-radius: 99px; background: #30303a; color: #dedee5; letter-spacing: 0; }
.clip-demo-pill { padding: 6px 10px; border: 1px solid #67618d; border-radius: 99px; background: #302d40; color: #e5dfff; font-size: 11px; letter-spacing: 0; }
.clip-demo-pill i { font-style: normal; color: #a9a6ba; }
.clip-demo-menu { display: grid; gap: 0; width: min(100%, 330px); margin-left: auto; border: 1px solid #373741; border-radius: 10px; background: #23232b; box-shadow: 0 10px 24px #0007; overflow: hidden; }
.clip-demo-now, .clip-demo-entry { display: flex; flex-direction: column; gap: 3px; padding: 9px 11px; border-bottom: 1px solid #373741; font-size: 10.5px; }
.clip-demo-now { display: flex; flex-direction: row; align-items: center; color: #dfdcff; }
.clip-demo-now kbd { margin-left: auto; color: #aaa8b5; font: 10px ui-monospace, SFMono-Regular, Menlo, monospace; }
.clip-demo-menu small { padding: 7px 11px; font-size: 9px; color: #9999a5; text-transform: uppercase; letter-spacing: .08em; }
.clip-demo-entry strong { font-size: 10.5px; font-weight: 560; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.clip-demo-entry em { color: #9999a5; font-size: 9px; font-style: normal; }
.clip-demo-entry:first-of-type { background: #343147; }
.clip-demo-menu .clip-demo-foot { padding: 8px 11px; color: #8e8e9b; font-size: 9px; text-transform: none; letter-spacing: 0; }
.clipboard-pointer { left: 76%; top: 17%; animation: pointer-clip 6.5s ease-in-out infinite; }
@keyframes pointer-clip { 0%, 12% { left: 70%; top: 7%; opacity: 0; } 22%, 34% { left: 78%; top: 17%; opacity: 1; } 38% { transform: scale(.8); } 55%, 72% { left: 42%; top: 55%; opacity: 1; transform: scale(1); } 77% { transform: scale(.8); } 90%, 100% { opacity: 0; left: 42%; top: 55%; } }

.viz-product-ocr { display: grid; gap: 10px; min-height: 233px; padding: 13px; }
.ocr-demo-shot { position: relative; display: grid; align-content: center; gap: 6px; min-height: 110px; padding: 13px 15px; border-radius: 8px; background: #e9e9ed; color: #202027; overflow: hidden; }
.ocr-demo-app { font-size: 9px; color: #6b6a75; text-transform: uppercase; letter-spacing: .08em; }
.ocr-demo-shot strong { font-size: 13px; font-weight: 650; }
.ocr-demo-shot code { font-size: 10px; color: #b52c3a; white-space: normal; }
.ocr-demo-line { position: absolute; inset: 0 auto 0 0; width: 2px; background: #7b7bff; box-shadow: 0 0 12px #7b7bff; animation: ocr-pass 5.5s ease-in-out infinite; }
@keyframes ocr-pass { 0%, 12% { left: 0; opacity: 0; } 19% { opacity: 1; } 49% { left: 100%; opacity: 1; } 58%, 100% { left: 100%; opacity: 0; } }
.ocr-demo-result { display: grid; gap: 5px; padding: 9px 11px; border: 1px solid #363642; border-radius: 7px; background: #202028; }
.ocr-demo-result small { color: #9c9ba8; font-size: 9px; letter-spacing: .1em; }
.ocr-demo-result code { font-size: 10px; color: #d8d7e6; white-space: normal; }
.ocr-demo-result > span { justify-self: start; font-size: 9px; color: #a5a1ff; }
.ocr-demo-result > span b { margin-left: 3px; }

.viz-product-markup { display: grid; grid-template-columns: minmax(0, 1fr) 164px; gap: 10px; min-height: 233px; padding: 13px; }
.markup-demo-shot { position: relative; display: grid; align-content: center; gap: 13px; padding: 16px; border-radius: 8px; background: #e9e9ed; color: #202027; font-size: 11px; overflow: hidden; }
.markup-demo-shot > span:not(.markup-demo-box):not(.markup-demo-pin):not(.markup-demo-cursor) { display: flex; justify-content: space-between; gap: 10px; }
.markup-demo-shot .markup-demo-top { justify-content: start !important; color: #76747d; font-size: 9px; letter-spacing: .08em; }
.markup-demo-shot b { font-weight: 670; }
.markup-demo-total { padding-top: 10px; border-top: 1px solid #b9b9c2; font-size: 13px; }
.markup-demo-box { position: absolute; right: 10px; bottom: 20px; width: 90px; height: 32px; border: 2px solid #ff3b30; border-radius: 4px; animation: mark-in 6.8s ease-in-out infinite; }
.markup-demo-pin { position: absolute; right: 1px; bottom: 43px; display: grid; place-items: center; width: 19px; height: 19px; border-radius: 50%; background: #ff3b30; color: #fff; font-size: 10px; font-weight: 700; animation: mark-in 6.8s ease-in-out .4s infinite; }
.markup-demo-note { align-self: end; display: grid; gap: 6px; padding: 10px; border: 1px solid #52403d; border-radius: 8px; background: #2c2223; font-size: 10px; }
.markup-demo-note b { color: #ff736e; font-size: 9px; }
.markup-demo-note span { color: #e9d9d8; line-height: 1.4; }
.markup-demo-cursor { left: 32%; top: 27%; animation: pointer-mark 6.8s ease-in-out infinite; }
@keyframes pointer-mark { 0%, 10% { left: 55%; top: 32%; opacity: 0; } 20% { opacity: 1; } 43% { left: 77%; top: 76%; opacity: 1; } 55% { left: 82%; top: 81%; opacity: 1; transform: scale(.8); } 70%, 100% { opacity: 0; transform: scale(1); } }
@keyframes mark-in { 0%, 25% { opacity: .35; } 45%, 85% { opacity: 1; } 100% { opacity: .35; } }

/* ─────────────────────────────────── 7g. Tiles: always live ───── */

/* Every tile keeps moving. The rule throughout is that nothing disappears and comes
   back — an element that vanishes on a loop reads as flicker, not life — so each tile
   animates a travelling light, a pulse or a pen over content that stays put. Cycles are
   long and out of phase with each other, so the grid breathes instead of ticking. */

/* One shared sheen, long-cycled so it passes and then leaves the element alone. */
@keyframes sheen {
  0%        { transform: translateX(-130%); }
  38%, 100% { transform: translateX(130%); }
}

/* 7g-1. Queue — each capture registers in turn, the tally answers, the handoff lands. */
.q-shot::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 22%, rgba(255, 255, 255, 0.85) 50%, transparent 78%);
  animation: sheen 5s ease-in-out infinite;
}
.q-shot.b::after { animation-delay: 0.16s; }
.q-shot.c::after { animation-delay: 0.32s; }
.q-shot.d::after { animation-delay: 0.48s; }
.q-tally b { display: inline-block; animation: tally 5s ease-in-out 0.7s infinite; }
@keyframes tally {
  0%, 10%   { transform: scale(1); }
  16%       { transform: scale(1.18); }
  24%, 100% { transform: scale(1); }
}
/* A pulse crosses the wire from the tally to the handoff. */
.q-wire::after {
  content: "";
  position: absolute;
  top: -2px;
  left: 0;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--app-ok);
  box-shadow: 0 0 9px var(--app-ok);
  opacity: 0;
  animation: q-run 5s ease-in-out 1s infinite;
}
@keyframes q-run {
  0%        { opacity: 0; left: 0; }
  8%        { opacity: 1; }
  30%       { opacity: 1; left: 100%; }
  38%, 100% { opacity: 0; left: 100%; }
}
.q-out { animation: q-land 5s ease-in-out 1.5s infinite; }
@keyframes q-land {
  0%, 8%    { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.45); }
  20%, 100% { box-shadow: 0 0 0 10px rgba(52, 211, 153, 0); }
}

/* 7g-2. Image prep — the after bar keeps shrinking down to its real share. */
.sz-fill.after { animation: sz-shrink 5.2s cubic-bezier(0.4, 0, 0.2, 1) infinite; }
@keyframes sz-shrink {
  0%, 6%    { width: 100%; }
  30%       { width: 16%; }
  92%       { width: 16%; }
  100%      { width: 100%; }
}
.sz-fill::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 22%, rgba(255, 255, 255, 0.5) 50%, transparent 78%);
  animation: sheen 5.2s ease-in-out infinite;
}

/* 7g-3. Text recognition — the scan sweeps; the chip answers it. */
.ocr-found { animation: found-pulse 2.8s ease-in-out infinite; }
@keyframes found-pulse {
  0%, 100% { opacity: 0.62; }
  45%      { opacity: 1; }
}

/* 7g-4. Annotation — a pen works its way around the marks, and each one answers as the
   pen arrives. Every mark stays on screen the whole time; only the pen travels. */
.mk-pen { animation: pen-path 7.2s cubic-bezier(0.55, 0, 0.45, 1) infinite; }
/* left/top rather than transform: the arrow and pin are anchored to the shot's right
   edge, and a translate in pixels can't follow a width that changes with the tile.
   Percentages in `left` resolve against the shot; in `translate` they'd resolve against
   the 13px pen itself. */
@keyframes pen-path {
  0%        { left: calc(100% - 150px); top: 108px; opacity: 0; }
  5%        { left: calc(100% - 150px); top: 108px; opacity: 1; }
  /* along the highlight */
  14%       { left: 22px;  top: 53px; }
  22%       { left: 136px; top: 53px; }
  /* around the box */
  32%       { left: 162px; top: 44px; }
  40%       { left: 246px; top: 66px; }
  /* down the arrow, tail to head */
  52%       { left: calc(100% - 28px); top: 106px; }
  60%       { left: calc(100% - 56px); top: 82px; }
  /* up to the pin */
  72%       { left: calc(100% - 30px); top: 28px; }
  80%       { left: calc(100% - 30px); top: 28px; }
  /* and back to rest */
  94%, 100% { left: calc(100% - 150px); top: 108px; opacity: 1; }
}
}

/* Each mark answers on the beat the pen reaches it. */
.mk-highlight::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, 0.75) 50%, transparent 80%);
  animation: sheen 7.2s ease-in-out 1s infinite;
}
.mk-box { animation: box-flash 7.2s ease-in-out infinite; }
@keyframes box-flash {
  0%, 30%   { box-shadow: 0 0 0 0 rgba(255, 59, 48, 0); }
  36%       { box-shadow: 0 0 0 4px rgba(255, 59, 48, 0.25); }
  48%, 100% { box-shadow: 0 0 0 0 rgba(255, 59, 48, 0); }
}
/* The arrow stays drawn; a brighter segment runs along it as the pen passes, so the
   mark never vanishes the way a redraw-from-nothing would. */
.mk-arrow .chase {
  stroke: #fff;
  stroke-width: 3.2;
  stroke-dasharray: 9 60;
  stroke-dashoffset: 69;
  opacity: 0;
  animation: chase-run 7.2s ease-in-out infinite;
}
@keyframes chase-run {
  0%, 50%   { stroke-dashoffset: 69; opacity: 0; }
  54%       { opacity: 0.9; }
  64%       { stroke-dashoffset: 0; opacity: 0.9; }
  70%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
.mk-arrow .head { transform-origin: 9px 13px; animation: head-tap 7.2s ease-in-out infinite; }
@keyframes head-tap {
  0%, 60%   { transform: scale(1); }
  66%       { transform: scale(1.35); }
  74%, 100% { transform: scale(1); }
}
.mk-pin { animation: beacon 7.2s ease-out 5.2s infinite; }
@keyframes beacon {
  0%       { box-shadow: 0 5px 14px -4px rgba(0, 0, 0, 0.5), 0 0 0 0 rgba(255, 59, 48, 0.55); }
  12%, 100% { box-shadow: 0 5px 14px -4px rgba(0, 0, 0, 0.5), 0 0 0 12px rgba(255, 59, 48, 0); }
}

/* 7g-5. Secret masking — the arrow keeps making the same point. */
.mask-arrow { animation: drip 2.4s ease-in-out infinite; }
@keyframes drip {
  0%, 100% { opacity: 0.4; transform: translateY(-3px); }
  45%      { opacity: 1; transform: translateY(3px); }
}
.code-after b { position: relative; overflow: hidden; display: inline-block; }
.code-after b::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 25%, rgba(255, 255, 255, 0.5) 50%, transparent 75%);
  animation: sheen 5.6s ease-in-out infinite;
}

/* 7g-6. Local — a pulse runs each wire in turn, then the pair rests. */
.wire { position: relative; overflow: visible; }
.wire::after {
  content: "";
  position: absolute;
  top: -2px;
  left: 0;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--app-accent);
  box-shadow: 0 0 9px var(--app-accent);
  opacity: 0;
}
.hops i:nth-of-type(1)::after { animation: wire-run 4.2s ease-in-out infinite; }
.hops i:nth-of-type(2)::after { animation: wire-run 4.2s ease-in-out 0.55s infinite; }
@keyframes wire-run {
  0%        { opacity: 0; transform: translateX(-2px); }
  8%        { opacity: 1; }
  26%       { opacity: 1; transform: translateX(16px); }
  34%, 100% { opacity: 0; transform: translateX(18px); }
}
.hops > span { animation: hop-lit 4.2s ease-in-out infinite; }
.hops > span:nth-of-type(2) { animation-delay: 0.55s; }
.hops > span:nth-of-type(3) { animation-delay: 1.1s; }
@keyframes hop-lit {
  0%, 4%    { border-color: var(--line); color: var(--ink-2); }
  12%       { border-color: rgba(123, 123, 255, 0.55); color: var(--ink); }
  30%, 100% { border-color: var(--line); color: var(--ink-2); }
}

/* 7g-7. The pack — a read-through runs down the list, index first. */
.viz-order span { animation: row-read 5s ease-in-out infinite; }
.viz-order span:nth-child(2) { animation-delay: 0.3s; }
.viz-order span:nth-child(3) { animation-delay: 0.6s; }
.viz-order span:nth-child(4) { animation-delay: 0.9s; }
@keyframes row-read {
  0%, 6%    { border-color: var(--line-soft); }
  14%       { border-color: rgba(255, 255, 255, 0.22); }
  30%, 100% { border-color: var(--line-soft); }
}

/* ── Hover: the card's edge lights up ── */

.fcard { position: relative; }
.fcard:hover {
  border-color: rgba(255, 255, 255, 0.24);
  box-shadow: 0 0 34px -10px rgba(255, 255, 255, 0.1);
}

/* A brighter arc travels the border. Guarded: without mask compositing the ring would
   paint as a filled panel over the card, so it simply never renders and the plain
   border brighten above carries the hover on its own. */
@property --edge {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

@supports ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .fcard::before {
    content: "";
    position: absolute;
    inset: -1px;
    z-index: 1;
    padding: 1px;
    border-radius: inherit;
    background: conic-gradient(
      from var(--edge),
      transparent 0deg 250deg,
      rgba(255, 255, 255, 0.85) 310deg,
      transparent 360deg
    );
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
  }
  .fcard:hover::before {
    opacity: 1;
    animation: edge-run 2.6s linear infinite;
  }
  @keyframes edge-run {
    to { --edge: 360deg; }
  }
}

/* ── Chips: every small pill on the page reacts to the pointer ── */

.chip, .key, .target, .hop, .viz-order span {
  transition:
    transform 0.2s var(--ease),
    background 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease;
}

/* A light passes over the label rather than the whole thing just brightening. */
.chip { position: relative; overflow: hidden; z-index: 2; }
.chip::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 32%, rgba(255, 255, 255, 0.22) 50%, transparent 68%);
  transform: translateX(-130%);
}
.chip:hover {
  transform: translateY(-2px);
  border-color: rgba(255, 255, 255, 0.26);
  background: rgba(255, 255, 255, 0.09);
  color: var(--ink);
}
.chip:hover::after { animation: t-shine 0.75s ease both; }
@keyframes t-shine { from { transform: translateX(-130%); } to { transform: translateX(130%); } }

/* The shortcut pills behave like keys: they go down, not up. */
.key:hover {
  transform: translateY(1px);
  border-bottom-width: 1px;
  background: rgba(255, 255, 255, 0.11);
  color: var(--ink);
}

.target:hover,
.hop:hover {
  transform: translateY(-2px);
  border-color: rgba(255, 255, 255, 0.24);
  background: rgba(255, 255, 255, 0.07);
  color: var(--ink);
}

.viz-order span:hover {
  transform: translateX(3px);
  border-color: rgba(255, 255, 255, 0.18);
}

/* The tile's own contents sit above the border ring. */
.fcard > * { position: relative; z-index: 2; }

@media (prefers-reduced-motion: reduce) {
  /* Nothing loops, and hover responds without travelling. */
  .q-shot::after, .q-tally b, .q-wire::after, .q-out, .sz-fill.after, .sz-fill::after,
  .scan-line, .ocr-found, .mk-pen, .mk-highlight::after, .mk-box, .mk-arrow .shaft,
  .mk-arrow .head, .mk-pin, .mask-arrow, .code-after b::after, .wire::after,
  .hops > span, .viz-order span, .fcard:hover::before { animation: none; }
  .mk-pen { opacity: 0; }
  .mk-arrow .chase { opacity: 0; }
  .ocr-found { opacity: 1; }
  .chip:hover, .key:hover, .target:hover, .hop:hover, .viz-order span:hover { transform: none; }
  .chip:hover::after { animation: none; }
  .session-pointer, .clipboard-pointer, .markup-demo-cursor, .ocr-demo-line,
  .markup-demo-box, .markup-demo-pin { animation: none; }
  .session-pointer, .clipboard-pointer, .markup-demo-cursor, .ocr-demo-line { opacity: 0; }
  .markup-demo-box, .markup-demo-pin { opacity: 1; }
}

/* ──────────────────────────────────────────────────────── 8. Privacy ───── */

.privacy-shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  gap: clamp(24px, 4vw, 54px);
  align-items: center;
  padding: clamp(24px, 3.4vw, 40px);
  border: 1px solid var(--line);
  border-radius: 26px;
  background:
    radial-gradient(520px 260px at 82% 12%, rgba(255, 255, 255, 0.05), transparent 70%),
    linear-gradient(168deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.01));
}
.privacy-copy p.sub { margin-top: 13px; color: var(--ink-2); font-size: 15.5px; }
.local-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
  padding: 8px 14px;
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.05);
  font-size: 12.5px;
  color: var(--good);
}
.local-badge i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 9px currentColor;
}

.zeros { display: grid; grid-template-columns: repeat(2, 1fr); gap: 11px; }
.zero {
  padding: 16px;
  border: 1px solid var(--line-soft);
  border-radius: 14px;
  background: rgba(0, 0, 0, 0.26);
}
.zero b {
  display: block;
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1;
  margin-bottom: 5px;
}
.zero span { font-size: 12px; color: var(--ink-3); }

.detail-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  margin-top: 22px;
  font-size: 12.5px;
  color: var(--ink-3);
}

/* ────────────────────────────────────────────── 9. Download + footer ───── */

.download-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(22px, 4vw, 50px);
  align-items: center;
  padding: clamp(26px, 3.6vw, 44px);
  border: 1px solid var(--line);
  border-radius: 26px;
  background:
    radial-gradient(560px 300px at 14% 0%, rgba(255, 255, 255, 0.05), transparent 70%),
    linear-gradient(168deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.012));
}
.download-card h2 { margin-bottom: 11px; }
.download-card p { color: var(--ink-2); font-size: 15px; }
.download-actions { display: grid; justify-items: center; gap: 9px; }
.download-actions small { font-size: 11.5px; color: var(--ink-3); }
.windows {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  font-size: 13.5px;
  color: var(--ink-2);
  transition: border-color 0.2s, color 0.2s;
}
.windows:hover { border-color: rgba(255, 255, 255, 0.22); color: var(--ink); }
/* Before the first release: the same shapes, visibly not buttons yet. */
.btn.soon {
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.05);
  color: var(--ink-2);
  cursor: default;
}
.btn.soon:hover { background: rgba(255, 255, 255, 0.05); transform: none; }
.windows.soon { cursor: default; }
.windows.soon:hover { border-color: var(--line); color: var(--ink-2); }

footer { border-top: 1px solid var(--line-soft); padding: 26px 0 36px; }
footer .wrap {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px 22px;
  font-size: 13px;
  color: var(--ink-3);
}
footer .sp { flex: 1; }
footer a:hover { color: var(--ink); }

/* ──────────────────────────────────────────── 10. Reveal + responsive ───── */

/* Gated on html.js so the page is fully readable when the script never runs. */
html.js .rise {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
html.js .rise.in { opacity: 1; transform: none; }

@media (max-width: 980px) {
  /* Six section links stop fitting beside the brand and the button below this width, and
     wrapped links make a tall, broken bar. The page scrolls to every section anyway. */
  .nav-links { display: none; }
  .nav-cta { margin-left: auto; }
  .status, .nav-cta { white-space: nowrap; }
  /* A tall, narrow screen would leave a gap under the buttons; let the hero end there. */
  .hero { min-height: auto; }
  .hero-center { padding: 76px 0 72px; }
  /* minmax(0, ...) not 1fr: a bare 1fr is minmax(auto, 1fr), so the monospace block
     below sets the column's width and pushes the whole page sideways. */
  .lede { max-width: 52ch; }
  .stage {
    grid-template-columns: minmax(0, 1fr);
    height: auto;
  }
  .app-body { min-height: 0; }
  .out { min-height: 0; }
  .out-idle { min-height: 130px; }
  .privacy-shell, .download-card { grid-template-columns: minmax(0, 1fr); }
  .kb-groups { grid-template-columns: minmax(0, 1fr); gap: 6px 0; }
  .shots-scene { grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 20px; }
  .shots-flow { transform: rotate(90deg); }
  .shots-app { width: 100%; }
  /* The scene stacks: the window on top, the spot centred under it rather than over it. */
  .mac { aspect-ratio: auto; min-height: 0; padding-bottom: 142px; }
  .ds-win { position: relative; left: 0; top: 0; width: auto; margin: 36px 12px 0; }
  .ds-float { right: 10px; bottom: 10px; }
  .mac-menu { display: none; }
  .mac-menu.strong { display: inline; }
  .fcard, .fcard.span5, .fcard.span7, .fcard.span4 { grid-column: span 12; }
}

@media (max-width: 640px) {
  .wrap { width: calc(100% - 32px); }
  /* The bar has room for the brand and one button, and nothing else. */
  .nav-links, .status { display: none; }
  .brand { white-space: nowrap; }
  .nav-cta { margin-left: auto; }
  /* The hero stops filling the screen, lets the headline wrap where it balances, and
     stacks the two buttons at full width. */
  .hero-center { padding: 46px 0 44px; }
  .hero-mark { width: 84px; height: 84px; }
  .hero-br { display: none; }
  .hero h1 { margin-top: 28px; }
  .hero-lede { margin-top: 18px; }
  .hero-actions { flex-direction: column; align-items: stretch; width: 100%; max-width: 380px; margin-top: 30px; }
  .hero-actions .btn, .film-btn { width: 100%; justify-content: center; }
  /* The line wraps here, and a dot left hanging at the end of a line reads as a typo. */
  .hero-note { margin-top: 18px; gap: 6px 16px; font-size: 12.5px; }
  .hero-note .sep { display: none; }
  .hero-works { gap: 8px 18px; padding: 18px 0 22px; }
  .app-grid { grid-template-columns: repeat(2, 1fr); }
  .kb { padding: 8px; gap: 4px; border-radius: 12px; }
  .kb-row { gap: 4px; }
  .kb-key { height: 26px; font-size: 9px; border-radius: 5px; }
  .kb-now { margin: 16px 0 24px; gap: 10px; }
  .kb-now span { font-size: 14.5px; }
  .kb-groups kbd { min-width: 60px; }
  /* Finder's own order of sacrifice on a narrow window: the Kind column first, then
     the sidebar shrinks. Both headings and cells have to change together. */
  .ds-cols, .ds-file { grid-template-columns: 18px minmax(0, 1fr) 52px; gap: 8px; }
  .ds-cols span:last-child, .ds-kind { display: none; }
  .ds-side { width: 92px; }
  .ds-side li { font-size: 10px; padding: 3px 6px; }
  .viz-product-markup { grid-template-columns: minmax(0, 1fr); }
  .markup-demo-shot { min-height: 170px; }
  .markup-demo-note { align-self: auto; }
  .product-items em { display: none; }
  .zeros { grid-template-columns: 1fr 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  html.js .rise { opacity: 1; transform: none; }
}

/* ───────────────────────────────────────────────────────────── 404 ───── */

.notfound { display: grid; place-items: center; min-height: calc(100vh - 62px); min-height: calc(100svh - 62px); padding: 40px 0 80px; text-align: center; }
.notfound .eyebrow { justify-content: center; }
.notfound h1 { font-size: clamp(34px, 4.6vw, 54px); }
.notfound p.sub { margin: 14px 0 28px; color: var(--ink-2); font-size: 16px; }
