/* 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 ───── */

.hero { min-height: calc(100vh - 62px); min-height: calc(100svh - 62px); padding: 18px 0 0; }
.hero-stack { display:flex; min-height:calc(100vh - 80px); min-height:calc(100svh - 80px); flex-direction:column; align-items:center; }
.hero-video-shell { position:relative; width:min(760px,74vw); aspect-ratio:16/9; overflow:hidden; border:1px solid rgba(255,255,255,.12); border-radius:13px; background:#0a0a0a; box-shadow:0 18px 50px rgba(0,0,0,.42); }
.hero-video-shell::after { content:""; position:absolute; inset:0; pointer-events:none; border-radius:inherit; box-shadow:inset 0 0 0 1px rgba(255,255,255,.025); }
.hero-video-shell video { display:block; width:100%; height:100%; object-fit:cover; }
.video-cue { position:absolute; right:10px; top:10px; padding:5px 8px; border-radius:5px; background:rgba(5,5,5,.72); color:rgba(255,255,255,.58); font:540 9px/1 ui-monospace,SFMono-Regular,Menlo,monospace; letter-spacing:.06em; text-transform:uppercase; transition:opacity .18s; pointer-events:none; }
.hero-video-shell:hover .video-cue { opacity:0; }

.hero-lockup { display:flex; flex-direction:column; align-items:center; margin-top:18px; text-align:center; }
.hero-app-icon { --icon-rx:0deg; --icon-ry:0deg; position:relative; width:66px; height:66px; padding:5px; border:1px solid rgba(255,255,255,.13); border-radius:16px; background:#111114; box-shadow:0 12px 25px rgba(0,0,0,.34),inset 0 1px rgba(255,255,255,.06); transform:perspective(500px) rotateX(var(--icon-rx)) rotateY(var(--icon-ry)); transform-style:preserve-3d; transition:transform .14s ease-out,border-color .2s,box-shadow .2s; }
.hero-app-icon::before { content:""; position:absolute; inset:7px; border:1px solid rgba(255,255,255,.055); border-radius:11px; transform:translateZ(7px); pointer-events:none; }
.hero-app-icon img { width:100%; height:100%; border-radius:12px; transform:translateZ(14px); }
.hero-app-icon>span { position:absolute; left:50%; bottom:-8px; width:30px; height:5px; transform:translateX(-50%) translateZ(-4px); border-radius:50%; background:rgba(0,0,0,.7); filter:blur(4px); transition:width .2s,opacity .2s; }
.hero-app-icon:hover { border-color:rgba(255,255,255,.25); box-shadow:0 18px 34px rgba(0,0,0,.45),inset 0 1px rgba(255,255,255,.09); }
.hero-app-icon:hover>span { width:38px; opacity:.7; }

.hero h1 { margin-top:13px; font-size:clamp(40px,5vw,64px); line-height:1; letter-spacing:-.045em; font-weight:690; }
.hero .lede { margin-top:10px; color:var(--ink-3); font-size:14.5px; }

/* 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); }

.hero-workflow { width:100%; margin-top:auto; display:flex; align-items:center; gap:14px 30px; flex-wrap:wrap; min-height:65px; border-top:1px solid var(--line-soft); }
.muted-label {
  font-size: 10.5px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.logos { display:flex; flex-wrap:wrap; gap:10px 25px; margin-left:auto; }
.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);
}

/* ─────────────────────────────────── 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; }
}

/* ──────────────────────────────────────────────────────── 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) {
  /* 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; }
  .hero { padding-top:14px; min-height:auto; }
  .hero-stack { min-height:auto; }
  .hero-video-shell { width:100%; border-radius:10px; }
  .video-cue { display:none; }
  .hero-lockup { margin-top:16px; }
  .hero-app-icon { width:58px; height:58px; border-radius:14px; }
  .hero h1 { font-size:clamp(38px,12vw,52px); }
  .hero .lede { font-size:13.5px; }
  .hero-workflow { margin-top:28px; padding:17px 0 20px; min-height:0; align-content:center; }
  .hero-workflow .logos { margin-left:0; gap:8px 18px; }
  .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; }
  .zeros { grid-template-columns: 1fr 1fr; }
  .logos { margin-left: 0; }
  .hero-actions .btn { flex: 1; }
}

@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; }
