
/* ===== Muletto =====

   Light ground throughout. No dark sections, no glass, no pills, no gradient
   words, no centred hero. Corners stay between 4 and 12px: the giveaway of a
   page assembled rather than designed is that everything is a soft rounded
   card, so the radius scale deliberately stops short of that.

   Colour, type and spacing values come from the reference set rather than from
   taste - accent, inks and the 112px section rhythm are measured, not chosen. */
:root {
  --bg: #f5f6fa;
  --surface: #ffffff;
  --surface-2: #fafafa;
  --ink: #222326;
  --ink-2: #131316;
  --body: #444448;
  --muted: #636467;
  --line: #e4e6ee;
  --line-2: #eef0f4;
  --accent: #3b0bd9;
  --accent-strong: #2f08ad;
  --accent-soft: #eeeafd;
  --accent-ink: #ffffff;
  --ok: #15925f;
  --ok-soft: #e7f6ee;

  /* 2px for hairline chips, 12px is the ceiling. Nothing rounder. */
  --radius-sm: 4px;
  --radius: 6px;
  --radius-lg: 10px;
  --radius-xl: 12px;

  /* Flat and close to the surface. The reference shadows are barely there;
     a deep soft drop shadow reads as a template. */
  --shadow-sm: 0 1px 2px rgba(19,19,22,.05);
  --shadow: 0 1px 2px rgba(19,19,22,.05), 0 4px 12px rgba(19,19,22,.05);
  --shadow-lg: 0 10px 19px 4px rgba(19,19,22,.08), 0 2px 5px rgba(19,19,22,.06);

  --font: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SFMono-Regular", "GeistMono", Menlo, Consolas, monospace;

  /* The dot grid the reference sections sit on. Subtle enough to read as
     paper texture rather than decoration. */
  --dots: radial-gradient(#e1e8fa 1px, transparent 1px);
  /* The one accented-panel fill. Flat, not a gradient. */
  --tint: #f7f5fe;

  --wrap: 1200px;
  /* Two rhythms, on purpose. Marketing sections get the reference's 112px;
     a policy or pricing page is dense prose and reads better tighter. */
  --section: 112px;
  --section-tight: 64px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--body);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 { color: var(--ink); line-height: 1.08; letter-spacing: -.02em; margin: 0; font-weight: 680; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--accent-soft); color: var(--accent-strong); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* scrollbar */
* { scrollbar-width: thin; scrollbar-color: #cdd0da transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: #c9ccd6; border-radius: 4px; border: 3px solid var(--bg); }
*::-webkit-scrollbar-thumb:hover { background: #b7bbc8; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding-left: 32px; padding-right: 32px; }
.row { display: flex; align-items: center; gap: 16px; }
.between { justify-content: space-between; }
.muted { color: var(--muted); }

/* ===== wordmark ===== */
.wordmark {
  display: inline-block; vertical-align: middle;
  aspect-ratio: 430 / 117; height: 26px; width: auto;
  background-color: var(--ink);
  -webkit-mask: url(wordmark.png) left center / contain no-repeat;
  mask: url(wordmark.png) left center / contain no-repeat;
  text-indent: -9999px; overflow: hidden; white-space: nowrap;
}

/* ===== nav ===== */
.nav {
  position: sticky; top: 0; z-index: 40;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
.nav .wrap { display: flex; align-items: center; justify-content: space-between; height: 64px; }
.nav-left { display: flex; align-items: center; gap: 32px; }
.nav .wordmark { height: 27px; }
.nav-links { display: flex; gap: 26px; }
.nav-links a { color: var(--muted); font-size: 15px; font-weight: 500; transition: color .12s; }
.nav-links a:hover, .nav-links a.active { color: var(--ink); }
.nav-right { display: flex; align-items: center; gap: 14px; }

/* ===== buttons ===== */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px; border-radius: var(--radius);
  font-size: 15px; font-weight: 560; cursor: pointer;
  border: 1px solid transparent; transition: background .12s, border-color .12s, color .12s, transform .04s;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--accent); color: var(--accent-ink); box-shadow: var(--shadow-sm); }
.btn.primary:hover { background: var(--accent-strong); }
.btn.secondary { background: var(--surface); color: var(--ink); border-color: var(--line); box-shadow: var(--shadow-sm); }
.btn.secondary:hover { border-color: #d6d8e2; background: var(--surface-2); }
.btn.ghost { color: var(--muted); }
.btn.ghost:hover { color: var(--ink); }
.btn.lg { padding: 13px 22px; font-size: 16px; }
.btn.block { display: flex; width: 100%; justify-content: center; }
.btn .arrow { transition: transform .12s; }
.btn:hover .arrow { transform: translateX(2px); }

/* ===== sections ===== */
section { padding-top: 112px; padding-bottom: 112px; }
.eyebrow-none {}
.h-sub { color: var(--muted); font-size: 18px; max-width: 60ch; margin-top: 20px; }
.section-head { max-width: 660px; margin-bottom: 64px; }
.section-head h2 { font-size: clamp(28px, 4vw, 40px); }
.section-head p { color: var(--muted); font-size: 17px; margin-top: 16px; }

/* ===== hero ===== */
.hero { padding-top: 104px; padding-bottom: 96px; }
.hero-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 80px; align-items: center; }
@media (max-width: 980px) { .hero-grid { grid-template-columns: 1fr; gap: 48px; } }
.hero h1 { font-size: clamp(40px, 6vw, 64px); letter-spacing: -.035em; }
.hero .h-sub { font-size: 19px; }
.hero-cta { display: flex; gap: 12px; margin-top: 32px; flex-wrap: wrap; }
.hero-note { margin-top: 18px; color: var(--muted); font-size: 14px; }

/* ===== screenshots =====

   One component, used by the home page and by every guide step. It was two,
   and they collided on the class name: the guide caption ended up inside a
   frame with overflow:hidden and no padding, so it read as part of the
   screenshot rather than as a note about it.

   No fake browser chrome. A drawn window bar with an invented URL and three
   traffic-light dots is decoration that claims to be evidence, and it is
   instantly recognisable as neither. The screenshot is the evidence. */
.figshot { margin: 0; }
.figshot-frame {
  display: block; overflow: hidden; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
}
.figshot-frame img { display: block; width: 100%; height: auto; }

/* Outside the frame, and spaced like a caption rather than crammed under the
   bottom edge of the image. */
.figshot figcaption {
  margin-top: 14px; font-size: 13.5px; line-height: 1.6; color: var(--muted);
  max-width: 62ch;
}

/* Waiting for a real screenshot, and saying so. Deliberately flat: a
   placeholder that looks finished gets shipped as finished. */
.figshot-ph {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; aspect-ratio: 16 / 10; padding: 28px; text-align: center;
  background-color: var(--surface-2);
  background-image: var(--dots); background-size: 22px 22px;
}
.figshot-ph b {
  font-family: var(--mono); font-size: 11px; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.figshot-ph span { font-size: 13px; color: var(--muted); max-width: 34ch; line-height: 1.55; }

.shot-row { display: grid; gap: 32px 24px; grid-template-columns: repeat(2, 1fr); }
@media (max-width: 860px) { .shot-row { grid-template-columns: 1fr; } }

/* ===== logo strip ===== */
.logos { padding-top: 44px; padding-bottom: 44px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.logos p { text-align: center; color: var(--muted); font-family: var(--mono); font-size: 11.5px;
  letter-spacing: .1em; text-transform: uppercase; margin-bottom: 22px; }
.logos-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 34px; align-items: center; }
.logos-row svg { width: 26px; height: 26px; color: #9aa0ad; }

/* ===== steps (how it works) =====

   Three panels joined by a drawn curve rather than butted against hard 1px
   dividers, and no 01/02/03. Numbering a three-item sequence that already
   reads left to right adds a label without adding information, and the
   monospace ordinal is its own small cliche. The curve does the same job by
   suggesting the order instead of announcing it. */
.steps { display: flex; align-items: stretch; gap: 0; }
.step {
  flex: 1 1 0; min-width: 0; padding: 30px 28px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}
.step h3 { font-size: 18px; margin: 0 0 10px; }
.step p { color: var(--muted); font-size: 14.5px; line-height: 1.62; }

.step-link {
  flex: 0 0 56px; align-self: center; height: 40px;
  color: #c9cddd; overflow: visible;
}
.step-link path { fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-dasharray: 4 5; }

@media (max-width: 900px) {
  .steps { flex-direction: column; }
  .step-link { flex: 0 0 32px; height: 32px; width: 40px; transform: rotate(90deg); }
}

/* ===== feature split ===== */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 80px; align-items: center; }
.split.alt { direction: rtl; } .split.alt > * { direction: ltr; }
.feat-list { list-style: none; padding: 0; margin: 20px 0 0; }
.feat-list li { position: relative; padding-left: 30px; margin: 18px 0; color: var(--body); }
.feat-list li svg { position: absolute; left: 0; top: 3px; width: 18px; height: 18px; color: var(--accent); }
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-xl); box-shadow: var(--shadow-sm); padding: 28px; }

/* ===== cards / guides ===== */
.grid { display: grid; gap: 16px; }
.grid.cards { grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); }
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 20px; cursor: pointer; transition: border-color .12s, box-shadow .12s, transform .12s;
  box-shadow: var(--shadow-sm);
}
.card:hover { border-color: #d7d9e4; box-shadow: var(--shadow); transform: translateY(-2px); }
.card .glyph { width: 40px; height: 40px; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; color: var(--ink); }
.card .glyph svg { width: 22px; height: 22px; }
.card h3 { font-size: 17px; margin: 14px 0 6px; }
.card .meta { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; color: var(--muted); font-size: 13px; }

.badge { font-family: var(--mono); font-size: 11px; padding: 3px 7px; border-radius: 3px;
  border: 1px solid var(--line); color: var(--muted); background: var(--surface-2);
  font-weight: 500; letter-spacing: .04em; text-transform: uppercase; }
.badge.easy { color: var(--ok); background: var(--ok-soft); border-color: #cdeadb; }
.badge.medium { color: #9a6a11; background: #fdf4e3; border-color: #f0e0bd; }
.badge.hard { color: #b23b3b; background: #fdecec; border-color: #f4cccc; }
.badge.verified { color: var(--ok); background: var(--ok-soft); border-color: #cdeadb; }

/* ===== dropzone / opener ===== */
.drop {
  border: 1.5px dashed #cdd0dc; border-radius: var(--radius-lg); background: var(--surface);
  padding: 52px 22px; text-align: center; color: var(--muted); cursor: pointer;
  transition: border-color .12s, background .12s;
}
.drop:hover { border-color: var(--accent); }
.drop.hot { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-strong); }
.drop strong { color: var(--ink); }
.import-result { margin-top: 20px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: 20px; }
.import-result .proof { color: var(--ok); font-size: 14px; margin: 0 0 14px; display: flex; align-items: center; gap: 8px; }
.import-result .proof svg { width: 16px; height: 16px; }
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.tile { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.tile.accent { border-color: var(--accent); background: var(--accent-soft); }
.tile-n { font-size: 23px; font-weight: 680; color: var(--ink); }
.tile.accent .tile-n { color: var(--accent-strong); }
.tile-l { font-size: 13px; margin-top: 2px; color: var(--body); }
.tile-s { font-size: 12px; color: var(--muted); margin-top: 4px; }
.filewrap { margin-top: 14px; }
.filewrap summary { cursor: pointer; color: var(--muted); font-size: 14px; padding: 6px 0; }
.filewrap summary:hover { color: var(--ink); }
.filelist { max-height: 320px; overflow: auto; font-family: var(--mono); font-size: 12.5px; margin-top: 8px; }
.filelist div { display: flex; justify-content: space-between; padding: 5px 0; border-bottom: 1px solid var(--line-2); gap: 12px; }
.filelist .sz { color: var(--muted); white-space: nowrap; }

/* ===== pricing ===== */
.plans { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 820px; }
.plan { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 34px; box-shadow: var(--shadow-sm); }
.plan.featured { border-color: var(--accent); box-shadow: var(--shadow); position: relative; }
.plan .flag { position: absolute; top: -11px; left: 28px; background: var(--accent); color: #fff; font-size: 12px; font-weight: 600; padding: 3px 11px; border-radius: 999px; }
.plan h3 { font-size: 18px; }
.plan .price { font-size: 30px; font-weight: 700; color: var(--ink); margin: 12px 0 2px; letter-spacing: -.02em; }
.plan .price small { display: block; font-size: 14px; font-weight: 400; color: var(--muted); margin-top: 4px; }
.plan ul { list-style: none; padding: 0; margin: 20px 0; }
.plan li { position: relative; padding-left: 28px; margin: 11px 0; color: var(--body); font-size: 15px; }
.plan li svg { position: absolute; left: 0; top: 3px; width: 18px; height: 18px; color: var(--accent); }
.plan .fine { color: var(--muted); font-size: 13px; margin-top: 14px; }

/* ===== page header (guides/app) ===== */
.page-head { padding-top: 88px; padding-bottom: 0; }
.page-head h1 { font-size: clamp(32px, 5vw, 46px); }
.page-head p { color: var(--muted); font-size: 18px; margin-top: 14px; max-width: 60ch; }

/* ===== callout ===== */
.cta-band { background: var(--ink-2); border-radius: var(--radius-xl); padding: 56px 56px; color: #fff; display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.cta-band h2 { color: #fff; font-size: 30px; }
.cta-band p { color: #b7b9c4; margin-top: 8px; }

/* ===== footer ===== */
main { flex: 1 0 auto; }
footer.site { border-top: 1px solid var(--line); padding: 44px 0; margin-top: 48px; }
footer.site .wrap { display: flex; justify-content: space-between; align-items: center; gap: 20px; flex-wrap: wrap; }
footer.site .wordmark { height: 22px; }
footer.site .fine { color: var(--muted); font-size: 14px; }
.foot-links { display: flex; gap: 22px; }
.foot-links a { color: var(--muted); font-size: 14px; }
.foot-links a:hover { color: var(--ink); }

/* ===== modal ===== */
.modal { position: fixed; inset: 0; background: rgba(16,18,27,.42); backdrop-filter: blur(2px); display: flex; align-items: center; justify-content: center; padding: 20px; z-index: 60; }
.modal[hidden] { display: none; }
.modal-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); max-width: 620px; width: 100%; max-height: 86vh; overflow: auto; padding: 30px; position: relative; box-shadow: var(--shadow-lg); }
.modal-close { position: absolute; top: 16px; right: 18px; width: 30px; height: 30px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--surface); color: var(--muted); font-size: 16px; cursor: pointer; line-height: 1; }
.modal-close:hover { color: var(--ink); background: var(--surface-2); }
.g-head { display: flex; align-items: center; gap: 14px; margin-bottom: 6px; }
.g-head .glyph { width: 44px; height: 44px; border-radius: 11px; background: var(--surface-2); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; }
.g-head .glyph svg { width: 24px; height: 24px; color: var(--ink); }
.step-row { padding: 14px 0; border-bottom: 1px solid var(--line-2); }
.step-row .n { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 6px; background: var(--accent-soft); color: var(--accent-strong); font-size: 12px; font-weight: 700; margin-right: 10px; }
.step-row .detail { color: var(--muted); font-size: 14px; margin: 6px 0 0 32px; }
.note { color: var(--body); font-size: 14px; background: var(--surface-2); border: 1px solid var(--line); border-left: 3px solid var(--accent); padding: 10px 14px; margin: 10px 0; border-radius: 0 var(--radius) var(--radius) 0; }
.loading { color: var(--muted); }

@media (max-width: 860px) {
  .hero-grid, .split, .plans { grid-template-columns: 1fr; }
  .split.alt { direction: ltr; }
  .steps { grid-template-columns: 1fr; }
  .nav-links { display: none; }
  section { padding-top: 72px; padding-bottom: 72px; }
}

/* ---------- Detected-provider banner ---------- */
.detected { display: flex; align-items: center; gap: 10px; padding: 12px 16px; margin-bottom: 14px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--accent-soft); color: var(--ink); font-size: 15px; }
.detected strong { font-weight: 640; }
.detected .d-ic { width: 22px; height: 22px; display: inline-flex; color: var(--ink); }
.detected .d-ic svg { width: 22px; height: 22px; }
.detected.unknown { background: var(--surface-2); color: var(--muted); }

/* ===== What you get (home switcher) ===== */
.switcher { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.sw-btn { display: inline-flex; align-items: center; gap: 9px; padding: 9px 16px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  font-size: 14.5px; font-weight: 550; cursor: pointer; transition: all .12s; font-family: inherit; }
.sw-btn:hover { color: var(--ink); border-color: #d6d8e2; }
.sw-btn.on { background: var(--ink-2); color: #fff; border-color: var(--ink-2); }
.sw-ic { width: 17px; height: 17px; display: inline-flex; }
.sw-ic svg { width: 17px; height: 17px; }
.sw-panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm); padding: 32px; }
.sw-meta { display: flex; flex-wrap: wrap; gap: 40px; padding-bottom: 26px; margin-bottom: 26px; border-bottom: 1px solid var(--line-2); }
.sw-meta .k { display: block; font-size: 12.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; margin-bottom: 5px; }
.sw-meta b { font-size: 17px; color: var(--ink); font-weight: 620; }
.sw-rows { display: flex; flex-direction: column; gap: 18px; margin-bottom: 28px; }
.sw-row { display: grid; grid-template-columns: 220px 1fr 200px; gap: 20px; align-items: center; }
.sw-label { font-size: 15px; color: var(--ink); font-weight: 520; }
.sw-track { height: 9px; background: var(--line-2); border-radius: 999px; overflow: hidden; }
.sw-track i { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.sw-note { font-size: 13.5px; color: var(--muted); }

/* ===== Library viewer ===== */
.tabs { display: flex; flex-wrap: wrap; gap: 4px; margin: 22px 0 18px; border-bottom: 1px solid var(--line); }
.tab { padding: 10px 16px; border: 0; background: none; color: var(--muted); font-size: 14.5px;
  font-weight: 550; cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; font-family: inherit; }
.tab:hover { color: var(--ink); }
.tab.on { color: var(--accent); border-bottom-color: var(--accent); }
.tabpanel { min-height: 120px; }
.small { font-size: 13.5px; }

.thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 12px; margin-top: 14px; }
.thumb { margin: 0; }
.thumb .ph { aspect-ratio: 1; border-radius: var(--radius); background: var(--surface-2) center/cover no-repeat;
  border: 1px solid var(--line); display: flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: 11px; font-family: var(--mono); }
.thumb .ph.has-img { border-color: var(--line-2); }
.thumb figcaption { font-size: 11.5px; color: var(--muted); margin-top: 6px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }

.chatwrap { display: grid; grid-template-columns: 260px 1fr; gap: 18px; margin-top: 14px; }
.convlist { max-height: 460px; overflow: auto; border: 1px solid var(--line); border-radius: var(--radius); padding: 6px; }
.conv { display: flex; justify-content: space-between; gap: 10px; width: 100%; text-align: left;
  padding: 9px 11px; border: 0; background: none; border-radius: var(--radius-sm); cursor: pointer;
  font-size: 14px; color: var(--body); font-family: inherit; }
.conv:hover { background: var(--surface-2); }
.conv.on { background: var(--accent-soft); color: var(--accent-strong); font-weight: 560; }
.conv .cn { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.conv .cc { color: var(--muted); font-size: 12.5px; font-family: var(--mono); flex: none; }
.msgs { max-height: 460px; overflow: auto; display: flex; flex-direction: column; gap: 10px; padding-right: 4px; }
.msg { max-width: 78%; }
.msg.out { align-self: flex-end; text-align: right; }
.msg .mh { font-size: 11.5px; color: var(--muted); margin-bottom: 3px; }
.msg .mb { display: inline-block; padding: 9px 13px; border-radius: 12px; background: var(--surface-2);
  border: 1px solid var(--line); font-size: 14.5px; text-align: left; white-space: pre-wrap; word-break: break-word; }
.msg.out .mb { background: var(--accent-soft); border-color: #dcdcfa; }

.chart { display: flex; align-items: flex-end; gap: 6px; height: 150px; margin: 18px 0 24px;
  padding: 12px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-2); }
.chart .bar { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; gap: 6px; }
.chart .bar i { display: block; width: 100%; max-width: 42px; background: var(--accent); border-radius: 4px 4px 0 0; }
.chart .bar span { font-size: 11px; color: var(--muted); font-family: var(--mono); }
.evlist { max-height: 300px; overflow: auto; }
.ev { display: flex; gap: 16px; padding: 7px 0; border-bottom: 1px solid var(--line-2); font-size: 14px; }
.ev .when { color: var(--muted); font-family: var(--mono); font-size: 12.5px; flex: none; width: 108px; }
.ev .what { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.scatter { width: 100%; height: auto; border: 1px solid var(--line); border-radius: var(--radius); margin-top: 14px; }
.sc-bg { fill: var(--surface-2); }
.sc-grid { stroke: var(--line); stroke-width: 1; }
.sc-dots circle { fill: var(--accent); fill-opacity: .55; }

.pills { display: flex; flex-wrap: wrap; gap: 7px; margin: 14px 0 16px; }
.pill { padding: 6px 13px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface);
  color: var(--muted); font-size: 13px; cursor: pointer; font-family: inherit; }
.pill:hover { color: var(--ink); }
.pill.on { background: var(--accent-soft); color: var(--accent-strong); border-color: #dcdcfa; font-weight: 560; }
.tablewrap { overflow: auto; max-height: 460px; border: 1px solid var(--line); border-radius: var(--radius); }
.tablewrap table { border-collapse: collapse; width: 100%; font-size: 13px; }
.tablewrap th, .tablewrap td { text-align: left; padding: 8px 12px; border-bottom: 1px solid var(--line-2); white-space: nowrap; }
.tablewrap th { position: sticky; top: 0; background: var(--surface-2); color: var(--ink); font-weight: 600; z-index: 1; }
.tablewrap td { color: var(--body); max-width: 320px; overflow: hidden; text-overflow: ellipsis; }

@media (max-width: 860px) {
  .sw-row { grid-template-columns: 1fr; gap: 6px; }
  .chatwrap { grid-template-columns: 1fr; }
  .sw-panel { padding: 22px; }
}

/* ===== Guide article pages ===== */
.article { padding-top: 40px; padding-bottom: 96px; }
.crumbs { display: flex; gap: 9px; align-items: center; font-size: 13.5px; color: var(--muted); margin-bottom: 26px; }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--ink); }
.art-head { max-width: 760px; margin-bottom: 44px; }
.art-head h1 { font-size: clamp(30px, 4.4vw, 44px); }
.art-meta { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 18px 0; font-size: 14px; }
.art-intro { color: var(--muted); font-size: 18px; }
.art-grid { display: grid; grid-template-columns: minmax(0, 1fr) 296px; gap: 64px; align-items: start; }
.art-main h2 { font-size: 25px; margin: 44px 0 18px; }
.art-main > p { margin-bottom: 16px; }
.steps-ol { list-style: none; counter-reset: s; padding: 0; margin: 0; }
.steps-ol li { counter-increment: s; position: relative; padding-left: 52px; padding-bottom: 28px; }
.steps-ol li::before {
  content: counter(s); position: absolute; left: 0; top: 0;
  width: 32px; height: 32px; border-radius: 9px; background: var(--accent-soft);
  color: var(--accent-strong); font-weight: 680; font-size: 14px;
  display: flex; align-items: center; justify-content: center;
}
.steps-ol li:not(:last-child)::after {
  content: ""; position: absolute; left: 15.5px; top: 38px; bottom: 6px; width: 1px; background: var(--line);
}
.steps-ol h3 { font-size: 17.5px; margin-bottom: 6px; padding-top: 5px; }
.steps-ol p { color: var(--muted); font-size: 15.5px; }
.art-side { position: sticky; top: 88px; display: flex; flex-direction: column; gap: 16px; }
.side-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 22px; box-shadow: var(--shadow-sm); }
.side-card h4 { font-size: 13px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin-bottom: 14px; font-weight: 620; }
.side-card dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 8px 16px; font-size: 14px; }
.side-card dt { color: var(--muted); }
.side-card dd { margin: 0; color: var(--ink); text-align: right; }
.side-links { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 2px; }
.side-links a { display: block; padding: 7px 0; font-size: 14.5px; color: var(--body); border-bottom: 1px solid var(--line-2); }
.side-links li:last-child a { border-bottom: 0; }
.side-links a:hover { color: var(--accent); }
a.card { color: inherit; }

@media (max-width: 900px) {
  .art-grid { grid-template-columns: 1fr; gap: 40px; }
  .art-side { position: static; }
}

/* ===== Library toolbar (search + save) ===== */
.toolbar { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin: 22px 0 6px; }
.search {
  flex: 1 1 260px; min-width: 220px; padding: 10px 14px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); color: var(--ink); font-family: inherit; font-size: 14.5px;
}
.search::placeholder { color: var(--muted); }
.search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.search::-webkit-search-cancel-button { cursor: pointer; }
.tool-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.tool-actions .btn { font-size: 14px; padding: 9px 15px; }
.save-status { margin: 8px 0 0; min-height: 18px; }

/* ===== Save option row ===== */
.opt { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-top: 12px; font-size: 14.5px; color: var(--body); cursor: pointer; }
.opt input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.tag-plus { font-size: 11.5px; font-weight: 650; letter-spacing: .02em; color: var(--accent-strong); background: var(--accent-soft); border: 1px solid #dcdcfa; padding: 2px 8px; border-radius: 999px; }
.opt-note { color: var(--muted); font-size: 13.5px; }

/* ===== Similar-photo groups ===== */
.dupe-group { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 16px; margin-bottom: 14px; background: var(--surface-2); }
.dupe-head { font-size: 13.5px; color: var(--muted); margin-bottom: 12px; }
.dupe-group .thumbs { margin-top: 0; }
.thumb .keep { font-size: 10.5px; font-weight: 650; color: var(--ok); background: var(--ok-soft); border: 1px solid #cdeadb; padding: 1px 6px; border-radius: 999px; }
.src-chip { display: inline-flex; align-items: center; gap: 6px; margin-right: 10px; }
.src-chip .d-ic, .src-chip .d-ic svg { width: 16px; height: 16px; }
.btn:disabled { opacity: .55; cursor: default; }

/* ===== Resume an interrupted save ===== */
.resume-card { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap;
  border: 1px solid var(--accent); background: var(--accent-soft); border-radius: var(--radius-lg);
  padding: 18px 22px; margin-bottom: 18px; }
.resume-card strong { color: var(--ink); }

/* ===== Structure report + video posters ===== */
.report { margin: 0; padding: 16px; font-family: var(--mono); font-size: 12px;
  line-height: 1.5; color: var(--body); white-space: pre-wrap; word-break: break-word; }
.thumb .ph.is-video { position: relative; }
.thumb .ph.is-video::after { content: ""; position: absolute; right: 6px; bottom: 6px;
  border-style: solid; border-width: 5px 0 5px 8px; border-color: transparent transparent transparent #fff;
  filter: drop-shadow(0 0 2px rgba(0,0,0,.6)); }

/* Inline text button (reads as a link, behaves as a button) */
.linklike { background: none; border: 0; padding: 0; font: inherit; color: var(--accent);
  font-weight: 560; cursor: pointer; text-decoration: none; }
.linklike:hover { text-decoration: underline; }
.linklike:disabled { color: var(--muted); cursor: default; text-decoration: none; }

/* Guide screenshots use .figshot, defined above. */
.figshot { margin: 22px 0 6px; }

/* How recently a guide's flow was walked by hand */
.confirmed-line { margin: -4px 0 26px; font-size: 14px; color: var(--muted); line-height: 1.6; }

/* Steps still written from documentation rather than experience */
.unconfirmed { margin: 14px 0 0; padding: 14px 16px; border-radius: 10px;
  background: #fdf4e3; border: 1px solid #f0e0bd; color: #7a5510;
  font-size: 14px; line-height: 1.6; }
.unconfirmed strong { color: #6a4708; }

/* Brand marks beside the sidebar links */
.side-links a { display: flex; align-items: center; gap: 9px; }
.side-ic { display: inline-flex; width: 17px; height: 17px; flex: 0 0 17px; color: var(--muted); }
.side-ic svg { width: 100%; height: 100%; }
.side-links a:hover .side-ic { color: var(--ink); }

/* Expand a screenshot to full size */
.shot img { cursor: zoom-in; }
.shot img:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
body.no-scroll { overflow: hidden; }
.lightbox { position: fixed; inset: 0; z-index: 200; display: flex;
  align-items: center; justify-content: center; padding: 40px;
  background: rgba(16, 18, 22, 0.82); overflow: auto; }
.lightbox[hidden] { display: none; }
.lb-figure { margin: auto; max-width: 100%; }
.lb-figure img { display: block; max-width: 100%; width: auto; height: auto;
  border-radius: 8px; background: #fff;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45); cursor: default; }
.lb-figure figcaption { margin: 16px auto 0; max-width: 720px; text-align: center;
  color: rgba(255, 255, 255, 0.82); font-size: 14px; line-height: 1.55; }
.lb-close { position: fixed; top: 20px; right: 24px; width: 40px; height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; border: 1px solid rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.1); color: #fff; cursor: pointer; }
.lb-close:hover { background: rgba(255, 255, 255, 0.2); }
.lb-close:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

@media (max-width: 640px) {
  /* Fitting a 1300px UI screenshot to a phone gives the same unreadable size
     it already had inline. Show it at full size and let the reader pan. */
  .lightbox { padding: 56px 16px 16px; justify-content: flex-start; }
  .lb-figure { margin: auto; }
  .lb-figure img { max-width: none; }
  .lb-figure figcaption { max-width: 90vw; position: sticky; left: 0; }
  .lb-close { top: 10px; right: 12px; }
}

/* ---------- View switcher ---------- */
.views { display: flex; flex-wrap: wrap; gap: 4px; margin: 26px 0 0;
  padding: 4px; border-radius: 12px; background: var(--surface-2);
  border: 1px solid var(--line); }
.views .view { display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 15px; border: 0; border-radius: 9px; background: none;
  font: inherit; font-size: 14px; font-weight: 520; color: var(--muted);
  cursor: pointer; }
.views .view:hover { color: var(--ink); }
.views .view.on { background: var(--surface); color: var(--ink);
  box-shadow: 0 1px 2px rgba(16, 18, 22, 0.08); }
.view-ic { display: inline-flex; width: 16px; height: 16px; flex: 0 0 16px; }
.view-ic svg { width: 100%; height: 100%; }

/* ---------- Timeline ---------- */
.tl-head { margin: 22px 0 6px; }
.tl-legend { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.tl-chip { display: inline-flex; align-items: center; gap: 7px; padding: 4px 11px;
  border-radius: 999px; border: 1px solid var(--line); background: var(--surface);
  font-size: 12.5px; color: var(--muted); }
.tl-chip i { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }
.tl-chip.t-photo i { background: #3b82f6; }
.tl-chip.t-video i { background: #8b5cf6; }
.tl-chip.t-chat i { background: #10b981; }
.tl-chip.t-place i { background: #f59e0b; }
.tl-chip.t-event i { background: #64748b; }

.tl { margin-top: 24px; }
.tl-day { margin-bottom: 34px; }
.tl-date { position: sticky; top: 0; z-index: 2; padding: 10px 0 12px;
  background: linear-gradient(var(--bg) 72%, rgba(255, 255, 255, 0)); }
.tl-date h3 { margin: 0; font-size: 15.5px; font-weight: 620; letter-spacing: -0.01em; }
.tl-date span { display: block; margin-top: 2px; }

.tl-items { position: relative; padding-left: 108px; }
.tl-items::before { content: ""; position: absolute; left: 92px; top: 4px; bottom: 4px;
  width: 1px; background: var(--line); }

.tl-item { position: relative; display: flex; align-items: flex-start; gap: 12px;
  padding: 11px 14px 11px 0; cursor: pointer; border-radius: 10px; }
.tl-item:hover { background: var(--surface-2); }
.tl-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.tl-item.is-open { background: var(--surface-2); }
.tl-time { position: absolute; left: -108px; width: 66px; text-align: right;
  font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums;
  padding-top: 1px; }
.tl-dot { position: absolute; left: -20px; top: 16px; width: 9px; height: 9px;
  border-radius: 50%; background: var(--muted); box-shadow: 0 0 0 3px var(--bg); }
.t-photo .tl-dot { background: #3b82f6; }
.t-video .tl-dot { background: #8b5cf6; }
.t-chat .tl-dot { background: #10b981; }
.t-place .tl-dot { background: #f59e0b; }
.t-event .tl-dot { background: #64748b; }

.tl-body { flex: 1; min-width: 0; }
.tl-title { font-size: 14.5px; font-weight: 500; line-height: 1.45;
  overflow-wrap: anywhere; }
.tl-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
  margin-top: 3px; font-size: 12.5px; color: var(--muted); }
.tl-src { display: inline-flex; align-items: center; gap: 5px; }
.tl-ic { display: inline-flex; width: 13px; height: 13px; flex: 0 0 13px; }
.tl-ic svg { width: 100%; height: 100%; }
.tl-chev { flex: 0 0 auto; width: 22px; height: 22px; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 6px;
  color: var(--muted); font-size: 15px; line-height: 1; }
.tl-item:hover .tl-chev { background: var(--surface); color: var(--ink); }

.tl-detail { margin: 2px 0 10px; padding: 16px 18px; border-radius: 11px;
  background: var(--surface); border: 1px solid var(--line); }
.tl-preview { margin-bottom: 14px; }
.tl-preview img { display: block; max-width: 100%; max-height: 420px; width: auto;
  border-radius: 8px; border: 1px solid var(--line); }
.tl-msgs { max-height: 460px; overflow-y: auto; padding-right: 4px; }
.tl-more { padding: 8px 0 40px; text-align: center; }

/* ---------- Data tree ---------- */
.tv { font-size: 13.5px; line-height: 1.65; }
.tv-node > summary { cursor: pointer; color: var(--muted); font-size: 12.5px;
  padding: 1px 0; list-style: none; }
.tv-node > summary::-webkit-details-marker { display: none; }
.tv-node > summary::before { content: "+ "; font-family: ui-monospace, monospace; }
.tv-node[open] > summary::before { content: "- "; }
.tv-kids { margin-left: 14px; padding-left: 12px; border-left: 1px solid var(--line); }
.tv-row { display: flex; gap: 12px; align-items: baseline; padding: 2px 0; }
.tv-k { flex: 0 0 auto; min-width: 150px; color: var(--muted); font-size: 12.5px; }
.tv-s { overflow-wrap: anywhere; }
.tv-num, .tv-date { font-variant-numeric: tabular-nums; }
.tv-date { color: var(--accent); }
.tv-null { color: var(--muted); font-style: italic; }

/* ---------- Chat viewer ---------- */
.chatapp { display: grid; grid-template-columns: 290px 1fr; gap: 0;
  margin-top: 18px; border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden; background: var(--surface); height: 620px; }
.ca-list { overflow-y: auto; border-right: 1px solid var(--line);
  background: var(--surface-2); }
.ca-person { display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 12px 14px; border: 0; border-bottom: 1px solid var(--line);
  background: none; font: inherit; text-align: left; cursor: pointer; }
.ca-person:hover { background: var(--surface); }
.ca-person.on { background: var(--surface); box-shadow: inset 3px 0 0 var(--accent); }
.ca-av { flex: 0 0 36px; width: 36px; height: 36px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent); font-weight: 620; font-size: 15px; }
.ca-meta { min-width: 0; flex: 1; }
.ca-name { display: block; font-size: 14px; font-weight: 520;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ca-sub { display: flex; align-items: center; gap: 5px; margin-top: 2px;
  font-size: 12px; color: var(--muted); }
.ca-ic { display: inline-flex; width: 12px; height: 12px; flex: 0 0 12px; }
.ca-ic svg { width: 100%; height: 100%; }

.ca-thread { display: flex; flex-direction: column; min-width: 0; }
.ca-head { display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; padding: 16px 20px; border-bottom: 1px solid var(--line); }
.ca-head h3 { margin: 0 0 2px; font-size: 15.5px; font-weight: 600; }
.ca-plats { display: flex; flex-wrap: wrap; gap: 6px; }
.ca-plat { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px;
  border-radius: 999px; background: var(--surface-2); border: 1px solid var(--line);
  font-size: 12px; color: var(--muted); }
.ca-plat i { display: inline-flex; width: 12px; height: 12px; }
.ca-plat svg { width: 100%; height: 100%; }
.ca-msgs { flex: 1; overflow-y: auto; padding: 18px 20px; }
.ca-daysep { margin: 18px 0 12px; text-align: center; font-size: 12px;
  color: var(--muted); }
.ca-daysep::before, .ca-daysep::after { content: ""; display: inline-block;
  width: 46px; height: 1px; background: var(--line); vertical-align: middle;
  margin: 0 10px; }
.ca-msgs .msg .mh { display: flex; align-items: center; gap: 6px; }

/* ---------- Map ---------- */
.map-head { display: flex; align-items: flex-start; justify-content: space-between;
  gap: 20px; margin: 20px 0 12px; }
.map-years { font-size: 13px; color: var(--muted); white-space: nowrap; }
.map-years select { margin-left: 8px; padding: 5px 9px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--surface); font: inherit;
  font-size: 13px; color: var(--ink); }
.mapwrap { position: relative; }
.map-tip { position: absolute; transform: translate(-50%, -140%);
  padding: 5px 10px; border-radius: 7px; background: var(--ink); color: #fff;
  font-size: 12px; white-space: nowrap; pointer-events: none; z-index: 3; }
.map-tip[hidden] { display: none; }
.sc-eq { stroke: var(--line); stroke-width: 1; stroke-dasharray: 4 4; }
.map-foot { margin-top: 10px; }

@media (max-width: 860px) {
  .chatapp { grid-template-columns: 1fr; height: auto; }
  .ca-list { max-height: 230px; border-right: 0; border-bottom: 1px solid var(--line); }
  .ca-msgs { max-height: 460px; }
  .tl-items { padding-left: 20px; }
  .tl-items::before { left: 4px; }
  .tl-time { position: static; width: auto; text-align: left; display: block;
    margin-bottom: 2px; }
  .tl-dot { left: -20px; top: 18px; }
  .tl-item { flex-wrap: wrap; }
  .map-head { flex-direction: column; gap: 10px; }
}

/* Joining one person's threads across platforms, by hand */
.ca-link { display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--muted); }
.ca-link select { padding: 3px 8px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); font: inherit; font-size: 12px; color: var(--ink);
  max-width: 160px; }
.ca-unlink { padding: 3px 11px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); font: inherit; font-size: 12px; color: var(--muted);
  cursor: pointer; }
.ca-unlink:hover { color: var(--ink); border-color: var(--muted); }
.ca-known { margin: 0; padding: 10px 20px; border-bottom: 1px solid var(--line);
  background: var(--surface-2); }

/* ---------- Data explorer ---------- */

/* The explorer reuses semantic elements the marketing pages already style, so
   it has to opt out of those first. section carries 112px of vertical padding
   for the landing page, which turned every one-item day in the timeline into a
   quarter of a screen of nothing. */
#explorer section { padding: 0; }
#explorer h1, #explorer h2, #explorer h3, #explorer h4 { line-height: 1.3; }
#explorer main { flex: initial; }


/* Sidebar */
.ex-side { display: flex; flex-direction: column; gap: 22px; min-height: 0;
  padding: 20px 16px; overflow-y: auto;
  border-right: 1px solid var(--line); background: var(--surface-2); }
.ex-brand { display: flex; align-items: center; gap: 11px; padding: 0 6px; }
.ex-logo { display: inline-flex; width: 34px; height: 34px; flex: 0 0 34px;
  align-items: center; justify-content: center; border-radius: 9px;
  background: var(--accent); color: #fff; }
.ex-logo svg { width: 20px; height: 20px; }
.ex-brand strong { display: block; font-size: 14.5px; font-weight: 620; }
.ex-brand em { display: block; font-size: 12px; color: var(--muted); font-style: normal; }

.ex-nav { display: flex; flex-direction: column; gap: 2px; }
.ex-navi { display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 9px 11px; border: 0; border-radius: 9px; background: none;
  font: inherit; font-size: 13.5px; color: var(--muted); cursor: pointer;
  text-align: left; }
.ex-navi i { display: inline-flex; width: 17px; height: 17px; flex: 0 0 17px; }
.ex-navi i svg { width: 100%; height: 100%; }
.ex-navi span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.ex-navi em { font-style: normal; font-size: 11.5px; font-variant-numeric: tabular-nums;
  color: var(--muted); }
.ex-navi:hover { background: var(--surface); color: var(--ink); }
.ex-navi.on { background: var(--accent-soft); color: var(--accent); font-weight: 560; }
.ex-navi.on em { color: var(--accent); }

.ex-sources h4 { margin: 0 0 8px; padding: 0 11px; font-size: 11.5px;
  font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--muted); }
.ex-source { display: flex; align-items: center; gap: 11px; padding: 7px 11px;
  font-size: 13px; }
.ex-source i { display: inline-flex; width: 16px; height: 16px; flex: 0 0 16px;
  color: var(--muted); }
.ex-source i svg { width: 100%; height: 100%; }
.ex-source span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.ex-source em { font-style: normal; font-size: 11.5px; color: var(--muted);
  font-variant-numeric: tabular-nums; }
.ex-add { width: 100%; margin-top: 8px; padding: 9px; border-radius: 9px;
  border: 1px dashed var(--line); background: none; font: inherit; font-size: 13px;
  color: var(--muted); cursor: pointer; }
.ex-add:hover { border-color: var(--accent); color: var(--accent); }

.ex-privacy { margin-top: auto; padding: 13px 14px; border-radius: 11px;
  background: var(--ok-soft); border: 1px solid #cdeadb; }
.ex-privacy strong { display: block; font-size: 12.5px; color: var(--ok); }
.ex-privacy p { margin: 5px 0 0; font-size: 11.5px; line-height: 1.55; color: #3f6b53; }

/* Main column */
.ex-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.ex-top { display: flex; align-items: center; gap: 16px; flex-shrink: 0;
  padding: 13px 26px; border-bottom: 1px solid var(--line); background: var(--surface); }
.ex-search { position: relative; flex: 1; max-width: 540px; }
.ex-search i { position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; color: var(--muted); display: inline-flex; }
.ex-search i svg { width: 100%; height: 100%; }
.ex-search input { width: 100%; padding: 9px 14px 9px 38px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface-2); font: inherit;
  font-size: 13.5px; color: var(--ink); }
.ex-search input:focus { outline: 2px solid var(--accent); outline-offset: -1px;
  background: var(--surface); }
.ex-topact { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.btn.sm { padding: 7px 13px; font-size: 13px; }

.ex-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 26px 26px 60px; }
.ex-headline h1 { margin: 0; font-size: 25px; font-weight: 640; letter-spacing: -0.02em; }
.ex-headline p { margin: 4px 0 0; font-size: 14px; }

.ex-stats { display: grid; gap: 12px; margin: 22px 0 8px;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); }
.ex-stat { position: relative; padding: 15px 17px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--surface); }
.ex-stat.wide { grid-column: span 2; }
.ex-stat-l { display: block; font-size: 12px; color: var(--muted); }
.ex-stat-v { display: block; margin-top: 5px; font-size: 19px; font-weight: 620;
  letter-spacing: -0.01em; }
.ex-stat i { position: absolute; top: 15px; right: 16px; width: 17px; height: 17px;
  color: var(--muted); display: inline-flex; opacity: 0.7; }
.ex-stat i svg { width: 100%; height: 100%; }
.ex-status:empty { display: none; }
.ex-count { margin: 20px 0 6px; }

/* Timeline rows */
.ex-day { margin-bottom: 10px; }
.ex-dayh { position: sticky; top: -26px; z-index: 2; display: flex;
  align-items: baseline; justify-content: space-between; gap: 14px;
  margin: 22px 0 4px; padding: 9px 2px; font-size: 13.5px; font-weight: 620;
  background: var(--bg); border-bottom: 1px solid var(--line); }
.ex-dayh span { font-size: 12px; font-weight: 400; color: var(--muted); }

.ex-rows { display: flex; flex-direction: column; }
.ex-row { display: grid; align-items: center; gap: 14px;
  grid-template-columns: 62px 34px 132px minmax(0, 1fr) 66px;
  padding: 9px 10px; border-radius: 10px; cursor: pointer; }
.ex-row:hover { background: var(--surface-2); }
.ex-row.on { background: var(--accent-soft); }
.ex-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ex-time { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.ex-ic { display: inline-flex; width: 34px; height: 34px; align-items: center;
  justify-content: center; border-radius: 9px; }
.ex-ic svg { width: 17px; height: 17px; }
.ex-ic.sm { width: 24px; height: 24px; border-radius: 7px; }
.ex-ic.sm svg { width: 13px; height: 13px; }
.ex-ic.lg { width: 40px; height: 40px; border-radius: 11px; }
.ex-ic.lg svg { width: 20px; height: 20px; }
.c-blue { background: #e8f0fe; color: #1a5fd0; }
.c-violet { background: #f0e9fd; color: #6d3fc4; }
.c-green { background: #e3f6ec; color: #12805a; }
.c-amber { background: #fdf1dc; color: #9a6a11; }
.c-slate { background: #eceef2; color: #4b5563; }

.ex-what { min-width: 0; }
.ex-what b { display: block; font-size: 13.5px; font-weight: 540;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ex-what em { display: block; font-style: normal; font-size: 12px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ex-desc { min-width: 0; }
.ex-desc1 { display: block; font-size: 13.5px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.ex-desc2 { display: block; font-size: 12px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ex-thumb { width: 66px; height: 42px; border-radius: 7px; overflow: hidden;
  background: transparent; }
.ex-thumb img { width: 100%; height: 100%; object-fit: cover; display: block;
  border-radius: 7px; }
.ex-more { padding: 18px 0 10px; text-align: center; }

/* Detail panel */
.ex-detail { display: flex; flex-direction: column; min-width: 0; min-height: 0;
  border-left: 1px solid var(--line); background: var(--surface); overflow: hidden; }
.ex-detail[hidden] { display: none; }
.ex-dh { display: flex; align-items: center; gap: 12px; flex-shrink: 0;
  padding: 16px 20px; border-bottom: 1px solid var(--line); }
.ex-dh-t { flex: 1; min-width: 0; }
.ex-dh-t b { display: block; font-size: 14.5px; font-weight: 600; }
.ex-dh-t em { display: block; font-style: normal; font-size: 12px; color: var(--muted); }
.ex-dh-a { display: flex; gap: 5px; }
.ex-nav-btn { width: 30px; height: 30px; display: inline-flex; align-items: center;
  justify-content: center; border-radius: 8px; border: 1px solid var(--line);
  background: var(--surface); font-size: 15px; line-height: 1; color: var(--muted);
  cursor: pointer; }
.ex-nav-btn:hover:not(:disabled) { color: var(--ink); border-color: var(--muted); }
.ex-nav-btn:disabled { opacity: 0.4; cursor: default; }

.ex-dbody { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 20px 40px; }
.ex-when { margin: 0 0 14px; font-size: 13.5px; font-weight: 520; }
.ex-dh4 { margin: 22px 0 10px; font-size: 11.5px; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.ex-dpreview img { display: block; width: 100%; height: auto; border-radius: 10px;
  border: 1px solid var(--line); }
.ex-dmsgs { max-height: 300px; overflow-y: auto; padding-right: 4px; }
.ex-dl { display: grid; grid-template-columns: auto 1fr; gap: 6px 16px;
  margin: 14px 0 0; font-size: 13px; }
.ex-dl dt { color: var(--muted); }
.ex-dl dd { margin: 0; font-variant-numeric: tabular-nums; }
.ex-dfoot { margin: 26px 0 0; padding-top: 14px; border-top: 1px solid var(--line); }

.ex-minimap { border-radius: 10px; overflow: hidden; border: 1px solid var(--line); }
.ex-minimap svg { display: block; width: 100%; height: 200px; }
.mm-sea { fill: #eaf1f8; }
.mm-land { fill: #dfe5ec; stroke: #c6ced9; stroke-width: 0.4; }
.mm-dots circle { fill: var(--accent); fill-opacity: 0.55; }
.mm-here { fill: #e5484d; stroke: #fff; stroke-width: 0.8; }

.ex-near { display: flex; flex-direction: column; gap: 2px; }
.ex-nearrow { display: grid; align-items: center; gap: 10px;
  grid-template-columns: 46px 24px 108px minmax(0, 1fr); padding: 6px 4px;
  border-radius: 8px; }
.ex-nearrow:hover { background: var(--surface-2); }
.ex-nearw { min-width: 0; }
.ex-nearw b { display: block; font-size: 12.5px; font-weight: 520;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ex-nearw em { display: block; font-style: normal; font-size: 11px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ex-neard { font-size: 12.5px; color: var(--muted); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }

.reopen { display: flex; align-items: center; justify-content: space-between;
  gap: 20px; padding: 20px 22px; border-radius: 12px; border: 1px solid var(--line);
  background: var(--surface); }
.reopen p { margin: 0; font-size: 14px; }
.reopen strong { display: block; }

@media (max-width: 1180px) {
  .ex:has(.ex-detail:not([hidden])) { grid-template-columns: 278px minmax(0, 1fr) 360px; }
  .ex-row { grid-template-columns: 56px 34px minmax(0, 1fr) 60px; }
  .ex-row .ex-what { display: none; }
}
@media (max-width: 900px) {
  .ex, .ex:has(.ex-detail:not([hidden])) { grid-template-columns: 1fr; }
  .ex-side { display: none; }
  .ex-detail { position: fixed; inset: 0; z-index: 70; border-left: 0; }
  .ex-stat.wide { grid-column: span 1; }
}

/* ---------- Chat bubble alignment ----------
   The sender line has to sit over its own bubble, and anything the account
   owner sent belongs on the right. Aligning the row rather than the text keeps
   the name, the time and the bubble travelling together. */
.msg { display: flex; flex-direction: column; max-width: 76%; margin-bottom: 14px; }
.msg.in { align-items: flex-start; margin-right: auto; }
.msg.out { align-items: flex-end; margin-left: auto; }
.msg .mh { display: flex; align-items: center; gap: 6px; margin-bottom: 4px;
  padding: 0 4px; font-size: 11.5px; color: var(--muted); }
.msg.out .mh { flex-direction: row-reverse; }
.msg .mb { display: inline-block; padding: 9px 13px; border-radius: 14px;
  font-size: 13.5px; line-height: 1.5; overflow-wrap: anywhere; }
.msg.in .mb { background: var(--surface-2); border: 1px solid var(--line);
  border-bottom-left-radius: 5px; }
.msg.out .mb { background: var(--accent-soft); border: 1px solid transparent;
  color: var(--ink); border-bottom-right-radius: 5px; }

/* Chat header: name and the link control on one line, platforms beneath */
.ca-head { display: block; }
.ca-htop { display: flex; align-items: center; justify-content: space-between;
  gap: 16px; }
.ca-htop h3 { margin: 0; }
.ca-hbot { display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-top: 8px; }
.ca-hbot p { margin: 0; text-align: right; }
.ca-link { flex-shrink: 0; margin-left: auto; }

/* ---------- Date rail ----------
   The scrollbar for time. --w is how close a mark is to what is on screen
   (0..1) and --s is the matching scale; both are set per mark on every scroll
   frame, which is what makes the magnification move as one piece. */
.ex-main { position: relative; }
.rail { position: absolute; top: 64px; right: 6px; bottom: 12px; z-index: 5;
  display: flex; flex-direction: column; justify-content: space-between;
  align-items: flex-end; width: 62px; padding: 4px 0;
  pointer-events: none; touch-action: none; }
.rail > * { pointer-events: auto; }

.rail-m { --w: 0; --s: 1; position: relative; display: flex; align-items: center;
  justify-content: flex-end; gap: 6px; min-height: 0; padding: 0; border: 0;
  background: none; cursor: pointer; font: inherit; line-height: 1;
  transform-origin: right center; }
.rail-t { font-size: 9.5px; font-variant-numeric: tabular-nums; white-space: nowrap;
  color: var(--muted);
  opacity: calc(0.16 + 0.84 * var(--w));
  transform: scale(var(--s));
  transform-origin: right center;
  transition: color 0.12s linear; }
.rail-b { width: calc(5px + 9px * var(--w)); height: 1.5px; border-radius: 1px;
  background: var(--line);
  opacity: calc(0.35 + 0.65 * var(--w)); }

.rail-m.y .rail-t { font-weight: 640; color: var(--ink);
  opacity: calc(0.3 + 0.7 * var(--w)); }
.rail-m.empty .rail-t { opacity: calc(0.08 + 0.4 * var(--w)); }
.rail-m.near .rail-t { color: var(--accent); }
.rail-m.near .rail-b { background: var(--accent); }
.rail-m:hover .rail-t { color: var(--accent); }
.rail-m:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Leave room so long rows do not run under the rail. */
.ex-scroll { padding-right: 78px; }

/* ---------- Image library ---------- */
.ex-lib { margin-top: 4px; }
.lib-month { margin-bottom: 26px; }
.lib-grid { display: grid; gap: 10px; margin-top: 12px;
  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); }
.lib-cell { margin: 0; cursor: pointer; border-radius: 11px; }
.lib-cell:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.lib-img { display: block; aspect-ratio: 1 / 1; border-radius: 11px;
  background: var(--surface-2) center/cover no-repeat;
  border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600; color: var(--muted); letter-spacing: .04em;
  transition: transform 0.14s ease, box-shadow 0.14s ease; }
.lib-cell:hover .lib-img { transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(16, 18, 22, 0.14); }
.lib-cell.on .lib-img { outline: 3px solid var(--accent); outline-offset: 2px; }
.lib-img.vid::after { content: ""; position: absolute; }
.lib-cell figcaption { margin-top: 6px; font-size: 11.5px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Row previews in the timeline, big enough to recognise the picture */
.ex-row { grid-template-columns: 62px 34px 132px minmax(0, 1fr) 92px; }
.ex-thumb { width: 92px; height: 62px; border-radius: 8px; overflow: hidden; }
.ex-thumb.has { background: var(--surface-2); border: 1px solid var(--line); }
.ex-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ex-thumb.nodecode { background: var(--surface-2); }

/* Tighter days: a one-item day should be one item tall */
.ex-dayh { margin: 14px 0 2px; }
.ex-day { margin-bottom: 4px; }

/* ==========================================================================
   Motion
   One place for easing and duration, so everything moves the same way.
   Everything here is subtle on purpose: the point is that the interface feels
   settled, not that it performs.
   ========================================================================== */
:root {
  --ease: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --t-fast: 0.14s;
  --t: 0.22s;
  --t-slow: 0.36s;
}

/* Someone who has asked their system to stop animations means it. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

@keyframes m-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes m-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes m-slide-in { from { transform: translateX(100%); } to { transform: none; } }
@keyframes m-pop { from { opacity: 0; transform: scale(0.97); } to { opacity: 1; transform: none; } }

/* Site chrome */
.btn, .linklike, .tab, .view, .card, .pill, .sw-btn, .conv, .nav-links a,
.foot-links a, .side-links a, .ex-navi, .ex-add, .ex-nav-btn, .ca-person,
.rail-m, .lib-cell, .ex-row, .thumb {
  transition: background-color var(--t) var(--ease), color var(--t) var(--ease),
    border-color var(--t) var(--ease), box-shadow var(--t) var(--ease),
    transform var(--t) var(--ease), opacity var(--t) var(--ease);
}
.btn:active { transform: translateY(1px); }
.card:hover { transform: translateY(-3px); }
.nav-links a { position: relative; }
.nav-links a::after { content: ""; position: absolute; left: 0; right: 0; bottom: -6px;
  height: 2px; border-radius: 2px; background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--t) var(--ease); }
.nav-links a:hover::after, .nav-links a.active::after { transform: scaleX(1); }

/* Pages settle in rather than appearing */
main > section, .article > *, .page-head { animation: m-rise var(--t-slow) var(--ease-out) both; }
main > section:nth-child(2) { animation-delay: 0.04s; }
main > section:nth-child(3) { animation-delay: 0.08s; }

/* "Your data" in the nav, once an export is open in this tab */
.nav-explore { display: inline-flex; align-items: center; gap: 7px; }
.nav-explore .dot { width: 6px; height: 6px; border-radius: 50%;
  background: var(--ok); box-shadow: 0 0 0 0 rgba(18, 128, 90, 0.5);
  animation: m-pulse 2.4s var(--ease) infinite; }
@keyframes m-pulse {
  0% { box-shadow: 0 0 0 0 rgba(18, 128, 90, 0.45); }
  70% { box-shadow: 0 0 0 7px rgba(18, 128, 90, 0); }
  100% { box-shadow: 0 0 0 0 rgba(18, 128, 90, 0); }
}

/* ==========================================================================
   Explorer motion and layout corrections
   ========================================================================== */

.ex-main { position: relative; }

/* The explorer owns its own scrolling, and the rail is its scrollbar. A native
   thumb would measure only what has been rendered so far and claim the bottom
   was near while years were still unrendered. */
/* No scroll-behavior here. It applies to the wheel as well as to
   scrollIntoView, which puts a smoothing delay on every ordinary scroll and
   makes the rail look like it is lagging behind. Programmatic jumps ask for
   smooth explicitly instead. */
.ex-scroll { scrollbar-width: none; }
.ex-scroll::-webkit-scrollbar { width: 0; height: 0; }

/* Views that manage their own panes fill the height instead of scrolling the
   page, otherwise their inner lists sit below the fold out of reach. */
.ex-scroll.fills { overflow: hidden; display: flex; flex-direction: column;
  padding-bottom: 20px; }
.ex-scroll.fills #ex-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.ex-scroll.fills .chatapp { height: auto; flex: 1; min-height: 0; }
.ex-scroll.fills .mapwrap { flex: 1; min-height: 0; }
.ex-scroll.fills .scatter { height: 100%; }

/* Flex children need this before a descendant's overflow can work at all. */
.ca-thread, .ca-msgs, .ex-main, .ex-detail, .ex-dbody { min-height: 0; }

.ex-row, .lib-cell, .ex-day, .lib-month { animation: m-rise var(--t) var(--ease-out) both; }
.ex-row:hover { transform: translateX(2px); }
.ex-navi.on { animation: m-pop var(--t) var(--ease-out); }
.ex-thumb img, .lib-img { animation: m-fade var(--t-slow) var(--ease-out) both; }
#ex-body { animation: m-fade var(--t) var(--ease-out); }

/* Rail thumb: where you are, measured in months rather than rendered pixels */
.rail { --p: 0; }
.rail-thumb { position: absolute; right: 1px; top: 0; width: 3px; height: 34px;
  border-radius: 2px; background: var(--accent); opacity: 0.28;
  transform: translateY(calc(var(--p) * (100cqh - 34px)));
  transition: transform var(--t) var(--ease), opacity var(--t) var(--ease);
  pointer-events: none; }
.rail { container-type: size; }
.rail:hover .rail-thumb, .rail.dragging .rail-thumb { opacity: 0.75; }
.rail.dragging { cursor: grabbing; }
.rail.dragging .rail-t { transition: none; }
.rail-m { cursor: pointer; }
.rail::before { content: attr(data-label); position: absolute; right: 100%; top: 50%;
  margin-right: 10px; padding: 5px 10px; border-radius: 8px;
  background: var(--ink); color: #fff; font-size: 12px; white-space: nowrap;
  opacity: 0; transform: translateY(-50%) translateX(6px);
  transition: opacity var(--t) var(--ease), transform var(--t) var(--ease);
  pointer-events: none; }
.rail.dragging::before { opacity: 1; transform: translateY(-50%); }

/* Site identity and links inside the explorer sidebar */
.ex-brand { display: block; padding: 2px 6px 0; }
.ex-brand .wordmark { font-size: 21px; }
.ex-sitenav { display: flex; gap: 14px; margin-top: 8px; }
.ex-sitenav a { font-size: 12.5px; color: var(--muted); text-decoration: none; }
.ex-sitenav a:hover { color: var(--accent); }

/* ==========================================================================
   Explorer layout, second pass
   ========================================================================== */

/* One nav across the whole site, this page included. The explorer sits under
   it rather than replacing it, so the wordmark and links never move. */
body.exploring { overflow: hidden; }
body.exploring > main, body.exploring > footer.site { display: none; }
body.exploring > nav.nav { display: block; position: relative; z-index: 70; }

#explorer { position: fixed; left: 0; right: 0; bottom: 0;
  top: var(--navh, 61px); z-index: 60; background: var(--bg); }

/* The detail panel is a real column again.

   Sliding it over the top meant it covered the rail and blocked every control
   under it, which is worse than the reflow it avoided. It takes space now, and
   the reflow is bearable because every row is a fixed grid with ellipsis
   truncation: the columns narrow, the text clips, nothing re-wraps or changes
   height. */
.ex { display: grid; grid-template-columns: 278px minmax(0, 1fr) 0px;
  height: 100%;
  transition: grid-template-columns var(--t-slow) var(--ease); }
.ex.detail-open { grid-template-columns: 278px minmax(0, 1fr) clamp(340px, 30vw, 460px); }

.ex-detail { position: relative; inset: auto; width: auto; z-index: 1;
  border-left: 1px solid var(--line); box-shadow: none;
  animation: none; overflow: hidden; }
.ex-detail[hidden] { display: none; }
/* Fade the contents in rather than sliding the panel, so nothing is in motion
   while the column is still resizing. */
.ex-dbody, .ex-dh { animation: m-fade var(--t-slow) var(--ease-out) both; }

/* Rows keep their shape while the column narrows */
.ex-row, .ex-nearrow { contain: layout style; }

/* ==========================================================================
   Rail, second pass: legible, and cheap to move
   ========================================================================== */
.rail { width: 86px; top: 60px; right: 4px; }
.ex-scroll { padding-right: 100px; }

.rail-t { font-size: 12px; font-weight: 500; }
.rail-m.y .rail-t { font-size: 13.5px; font-weight: 660; }
/* The magnified end of the scale has to be worth reading, which is the whole
   point of the rail. */
.rail-m.near .rail-t { font-weight: 620; }
.rail-b { width: calc(6px + 12px * var(--w)); height: 2px; }

/* Only the newest page animates in. Several hundred rows each running their
   own entry animation is a large part of what made scrolling stutter. */
.ex-row, .lib-cell { animation: none; }
.ex-day.fresh .ex-row, .lib-month.fresh .lib-cell {
  animation: m-rise var(--t) var(--ease-out) both; }
.ex-row:hover { transform: none; background: var(--surface-2); }

@media (max-width: 1180px) {
  .ex.detail-open { grid-template-columns: 278px minmax(0, 1fr) 340px; }
}
@media (max-width: 900px) {
  .ex, .ex.detail-open { grid-template-columns: 1fr; }
  .ex-side { display: none; }
  .ex-detail { position: fixed; inset: var(--navh, 61px) 0 0 0; z-index: 70; }
}

/* The card behind the explorer, shown when it is closed */
.reopen { display: flex; align-items: center; justify-content: space-between;
  gap: 24px; padding: 18px 22px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--surface); }
.reopen p { margin: 3px 0 0; }
.reopen strong { font-size: 14.5px; }

/* ---------- Source filter ---------- */
.ex-source { display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 7px 11px; border: 0; border-radius: 8px; background: none;
  font: inherit; font-size: 13px; text-align: left; color: var(--ink);
  cursor: pointer; }
.ex-source:hover { background: var(--surface); }
.ex-source.on { background: var(--accent-soft); color: var(--accent); font-weight: 560; }
.ex-source.on i, .ex-source.on em { color: var(--accent); }
.ex-source.off { opacity: 0.42; }
.ex-clearsrc { width: 100%; margin-top: 6px; padding: 7px; border-radius: 8px;
  border: 0; background: none; font: inherit; font-size: 12.5px;
  color: var(--accent); cursor: pointer; text-align: left; }
.ex-clearsrc:hover { text-decoration: underline; }
.ex-clearsrc[hidden] { display: none; }

/* ==========================================================================
   Rail, third pass: room to grow
   The labels scale up, so the space they need is the magnified size, not the
   resting one. Sizing the rail for the resting text is what clipped them.
   ========================================================================== */
.rail { width: 118px; padding: 4px 10px 4px 0; overflow: visible; }
.ex-scroll { padding-right: 132px; }
.ex-main { overflow: visible; }

/* Each mark reserves height in proportion to how magnified it is, so the ones
   either side move out of the way instead of being overlapped. */
.rail-m { min-height: calc(11px + 13px * var(--w)); padding-right: 2px; }
.rail-t { transform-origin: right center; will-change: transform, opacity; }

/* Big enough to actually read at the focused end. */
.rail-t { font-size: 11.5px; }
.rail-m.y .rail-t { font-size: 12.5px; }
.rail-m.near .rail-t { letter-spacing: -0.01em; }

/* ==========================================================================
   Stop the library jumping while the detail panel opens
   auto-fill recomputes the column count continuously as the column narrows,
   so pictures hop between rows for the whole animation. A fixed count, set
   once when the width settles, just narrows them.
   ========================================================================== */
.lib-grid { grid-template-columns: repeat(var(--cols, 5), minmax(0, 1fr)); }
.lib-img { transition: none; }
.lib-cell:hover .lib-img { transform: translateY(-2px); }

/* Rows and pictures should not re-render mid-transition either. */
.ex-scroll { contain: paint; }
.ex-detail { contain: paint; }

.ex-forget { margin-top: 10px; padding: 0; border: 0; background: none;
  font: inherit; font-size: 11.5px; color: #3f6b53; text-decoration: underline;
  cursor: pointer; opacity: 0.75; }
.ex-forget:hover { opacity: 1; }
.ex-forget[data-sure="1"] { color: #b23b3b; font-weight: 600; opacity: 1; }

.ex-source.superseded { opacity: 0.7; }
.ex-source .tagline { font-style: normal; font-size: 10px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
  padding: 1px 5px; margin-left: 6px; border-radius: 4px;
  background: var(--surface-2); border: 1px solid var(--line); }

.ex-work { display: flex; flex-direction: column; gap: 4px; margin-top: 10px;
  padding-top: 10px; border-top: 1px solid #cdeadb; }
.ex-worklink { padding: 0; border: 0; background: none; font: inherit;
  font-size: 11.5px; color: #2f7a58; text-align: left; cursor: pointer; }
.ex-worklink:hover { text-decoration: underline; }

/* A picture that has not been decoded yet still holds its place, so the page
   is its true height from the first frame and nothing shifts as they arrive. */
.lib-img.skeleton { background-color: var(--surface-2); position: relative;
  overflow: hidden; }
.lib-img.skeleton::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  transform: translateX(-100%); animation: m-shimmer 1.4s infinite; }
@keyframes m-shimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .lib-img.skeleton::after { animation: none; } }

/* ==========================================================================
   Explorer chrome, second pass
   ========================================================================== */

/* The explorer is its own place, not a page of the site with a site nav on
   top. The mark stays top left and goes home; everything else is the app. */
body.exploring > nav.nav { display: none; }
#explorer { top: 0; }

.ex-home { display: block; padding: 2px 8px 4px; text-decoration: none; }
.ex-home .wordmark { font-size: 22px; }

/* Even rhythm between sections on the content pages.

   The gap between two sections comes from exactly one rule, rather than from
   each section's own padding plus whatever its contents happen to add. A
   heading with cards under it and a heading with only a paragraph produced
   different gaps otherwise, because .section-head carries a margin only when
   something follows it. */
section.wrap.tight { padding-top: 0; padding-bottom: 0; }
section.wrap.tight + section.wrap.tight { padding-top: var(--section-tight); }
section.wrap.tight:last-of-type { padding-bottom: 96px; }
.page-head + section.wrap.tight { padding-top: var(--section-tight); }
section.wrap.tight .section-head { margin-bottom: 0; }
section.wrap.tight .section-head:not(:last-child) { margin-bottom: 22px; }

/* ---------- Opening curtain ---------- */
#curtain { position: fixed; inset: 0; z-index: 200; display: flex;
  align-items: center; justify-content: center; background: var(--bg);
  opacity: 0; pointer-events: none; transition: opacity var(--t-slow) var(--ease); }
body.curtained #curtain { opacity: 1; pointer-events: auto; }
.curtain-in { text-align: center; max-width: 420px; padding: 0 24px; }
.curtain-in .wordmark { font-size: 30px; }
.curtain-bar { width: 220px; height: 3px; margin: 26px auto 20px; border-radius: 2px;
  background: var(--surface-2); overflow: hidden; }
.curtain-bar i { display: block; width: 40%; height: 100%; border-radius: 2px;
  background: var(--accent); animation: m-slide 1.15s var(--ease) infinite; }
@keyframes m-slide {
  0% { transform: translateX(-110%); }
  100% { transform: translateX(360%); }
}
.curtain-msg { font-size: 14.5px; min-height: 1.4em; }
.curtain-fine { margin-top: 8px; font-size: 12.5px; color: var(--muted); }
@media (prefers-reduced-motion: reduce) { .curtain-bar i { animation: none; width: 100%; } }

/* ==========================================================================
   Notification centre
   Everything the app says appears in one corner and stays in a list, instead
   of a line of text next to whichever button started the work.
   ========================================================================== */
#notify { position: fixed; top: 12px; right: 16px; z-index: 300;
  display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }

.nt-bell { position: relative; width: 38px; height: 38px; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  cursor: pointer; box-shadow: var(--shadow-sm);
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease); }
.nt-bell:hover { color: var(--ink); border-color: var(--muted); }
.nt-bell svg { width: 19px; height: 19px; }
.nt-dot { position: absolute; top: 7px; right: 8px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--accent); border: 2px solid var(--surface); }
.nt-dot[hidden] { display: none; }

.nt-toasts { display: flex; flex-direction: column; gap: 8px; align-items: flex-end; }
.nt-toast { display: flex; align-items: flex-start; gap: 10px; width: min(370px, calc(100vw - 40px));
  padding: 12px 13px; border-radius: 12px; border: 1px solid var(--line);
  background: var(--surface); box-shadow: 0 12px 32px rgba(16, 18, 22, .13);
  animation: m-rise var(--t) var(--ease-out) both; }
.nt-toast.out { animation: m-fade var(--t) var(--ease) reverse both; }
.nt-toast.go { cursor: pointer; }
.nt-toast.go:hover { border-color: var(--accent); }
.nt-toast b { display: block; font-size: 13.5px; font-weight: 560; line-height: 1.4; }
.nt-toast em { display: block; margin-top: 3px; font-style: normal; font-size: 12.5px;
  color: var(--muted); line-height: 1.5; }
.nt-toast > span:nth-child(2) { flex: 1; min-width: 0; }
.nt-x { flex: 0 0 auto; width: 20px; height: 20px; border: 0; background: none;
  color: var(--muted); font-size: 16px; line-height: 1; cursor: pointer; border-radius: 5px; }
.nt-x:hover { color: var(--ink); background: var(--surface-2); }

.nt-ic { flex: 0 0 26px; width: 26px; height: 26px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center; }
.nt-ic svg { width: 15px; height: 15px; }
.nt-ic.k-info { background: var(--surface-2); color: var(--muted); }
.nt-ic.k-work { background: var(--accent-soft); color: var(--accent); }
.nt-ic.k-done { background: var(--ok-soft); color: var(--ok); }
.nt-ic.k-warn { background: #fdf4e3; color: #9a6a11; }
.nt-toast.k-work .nt-ic svg { animation: m-spin 1.6s linear infinite; }
@keyframes m-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .nt-toast.k-work .nt-ic svg { animation: none; } }

.nt-panel { width: min(380px, calc(100vw - 40px)); max-height: 66vh; display: flex;
  flex-direction: column; border-radius: var(--radius-xl); border: 1px solid var(--line);
  background: var(--surface); box-shadow: 0 20px 48px rgba(16, 18, 22, .18);
  overflow: hidden; animation: m-rise var(--t) var(--ease-out) both; }
.nt-panel[hidden] { display: none; }
.nt-panel header { display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px; border-bottom: 1px solid var(--line); font-size: 13.5px; }
.nt-clear { border: 0; background: none; font: inherit; font-size: 12.5px;
  color: var(--muted); cursor: pointer; }
.nt-clear:hover { color: var(--accent); }
.nt-list { overflow-y: auto; padding: 6px; }
.nt-empty { padding: 22px 14px; text-align: center; font-size: 13px; color: var(--muted); }
.nt-item { display: flex; gap: 10px; width: 100%; padding: 10px; border: 0; border-radius: 9px;
  background: none; font: inherit; text-align: left; }
.nt-item.go { cursor: pointer; }
.nt-item.go:hover { background: var(--surface-2); }
.nt-item b { display: block; font-size: 13px; font-weight: 540; line-height: 1.4; }
.nt-item em { display: block; margin-top: 2px; font-style: normal; font-size: 12px;
  color: var(--muted); line-height: 1.5; }
.nt-item time { display: block; margin-top: 4px; font-size: 11px; color: var(--muted); }
.nt-item > span:nth-child(2) { flex: 1; min-width: 0; }

/* The explorer's own buttons sit under the bell, so give them room. */
.ex-topact { padding-right: 46px; }

/* ==========================================================================
   Clean up
   ========================================================================== */
.cl-summary { display: flex; flex-wrap: wrap; align-items: center; gap: 26px;
  margin: 18px 0 8px; padding: 16px 20px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--surface); }
.cl-stat span { display: block; font-size: 21px; font-weight: 640; letter-spacing: -.01em; }
.cl-stat em { font-style: normal; font-size: 12px; color: var(--muted); }
.cl-stat.out span { color: #b23b3b; }
.cl-explain { flex: 1 1 260px; margin: 0; font-size: 12.5px; color: var(--muted); line-height: 1.55; }

.cl-h { margin: 30px 0 4px; font-size: 15.5px; font-weight: 620; }
.cl-note { margin-bottom: 14px; }
.cl-groups { display: flex; flex-direction: column; gap: 14px; }
.cl-group { padding: 14px 16px; border-radius: 12px; border: 1px solid var(--line);
  background: var(--surface); }
.cl-group header { display: flex; align-items: center; justify-content: space-between;
  gap: 14px; margin-bottom: 11px; font-size: 12.5px; color: var(--muted); }
.cl-keepall { border: 1px solid var(--line); background: var(--surface-2); font: inherit;
  font-size: 12px; padding: 4px 11px; border-radius: 999px; color: var(--ink); cursor: pointer; }
.cl-keepall:hover { border-color: var(--accent); color: var(--accent); }
.cl-row { display: flex; flex-wrap: wrap; gap: 12px; }
.cl-cell { position: relative; width: 138px; margin: 0; cursor: pointer; }
.cl-cell .lib-img { aspect-ratio: 1 / 1; }
.cl-cell figcaption { margin-top: 6px; font-size: 11.5px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cl-mark { position: absolute; top: 8px; right: 8px; width: 22px; height: 22px;
  border-radius: 50%; border: 2px solid #fff; background: var(--ok);
  box-shadow: 0 1px 4px rgba(0,0,0,.3);
  transition: background var(--t) var(--ease); }
.cl-mark::after { content: ""; position: absolute; inset: 0;
  background: no-repeat center/11px url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' \
stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'><path d='m5 12 5 5L20 7'/></svg>"); }
.cl-cell.dropped .lib-img { opacity: .38; filter: grayscale(1); }
.cl-cell.dropped figcaption { text-decoration: line-through; }
.cl-cell.dropped .cl-mark { background: #b23b3b; }
.cl-cell.dropped .cl-mark::after { background-image: url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' \
stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'><path d='M6 6l12 12M18 6L6 18'/></svg>"); }
.cl-cell:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Save-your-work: a button, not a whisper */
.ex-savework { display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; margin-top: 12px; padding: 9px 12px; border-radius: 9px;
  border: 1px solid #bfe2d0; background: var(--surface); font: inherit;
  font-size: 12.5px; font-weight: 540; color: #1d6b4b; cursor: pointer; }
.ex-savework:hover { background: var(--ok-soft); border-color: var(--ok); }
.ex-savework svg { width: 15px; height: 15px; }

/* ==========================================================================
   Clean up, second pass: breathing room and the rule controls
   ========================================================================== */
.cl-group { padding: 18px 20px 20px; }
.cl-group header { margin-bottom: 14px; gap: 18px; flex-wrap: wrap; }
.cl-row { gap: 16px; padding: 2px; }
.cl-cell { width: 146px; }
.cl-cell figcaption { margin-top: 8px; }
.cl-groups { gap: 16px; }
.cl-h { margin-top: 36px; }

.cl-rules { display: flex; flex-wrap: wrap; align-items: center; gap: 20px;
  margin: 14px 0 4px; padding: 14px 20px; border-radius: 12px;
  background: var(--surface-2); border: 1px solid var(--line); }
.cl-rules label { display: inline-flex; align-items: center; gap: 9px;
  font-size: 13px; color: var(--muted); }
.cl-rules select, .cl-grule { padding: 6px 10px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--surface); font: inherit;
  font-size: 12.5px; color: var(--ink); }

.cl-gtools { display: inline-flex; align-items: center; gap: 12px; }
.cl-keepn { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; }
.cl-keepn.off { opacity: .4; pointer-events: none; }
.cl-keepn b { font-weight: 540; color: var(--ink); min-width: 54px; text-align: center; }
.cl-step { width: 24px; height: 24px; border-radius: 7px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); font: inherit; line-height: 1; cursor: pointer; }
.cl-step:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.cl-step:disabled { opacity: .35; cursor: default; }

/* ==========================================================================
   Export wizard
   ========================================================================== */
body.exporting { overflow: hidden; }
#exportx, #captionx { position: fixed; inset: 0; z-index: 400; display: flex;
  align-items: center; justify-content: center; padding: 28px; }
.xw-scrim { position: absolute; inset: 0; background: rgba(16, 18, 22, .5);
  animation: m-fade var(--t) var(--ease) both; }
.xw { position: relative; width: min(680px, 100%); max-height: calc(100vh - 56px);
  display: flex; flex-direction: column; border-radius: 16px; background: var(--surface);
  box-shadow: 0 30px 80px rgba(16, 18, 22, .3);
  animation: m-rise var(--t-slow) var(--ease-out) both; overflow: hidden; }

.xw-head { display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; padding: 22px 24px 14px; }
.xw-head h2 { margin: 0 0 3px; font-size: 20px; font-weight: 640; }
.xw-x { width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--surface); color: var(--muted); font-size: 17px; line-height: 1; cursor: pointer; }
.xw-x:hover { color: var(--ink); }

.xw-steps { display: flex; gap: 6px; margin: 0; padding: 0 24px 16px; list-style: none; }
.xw-steps li { flex: 1; padding-top: 9px; border-top: 2px solid var(--line);
  font-size: 11.5px; color: var(--muted); }
.xw-steps li.on { border-color: var(--accent); color: var(--accent); font-weight: 560; }
.xw-steps li.done { border-color: var(--ok); color: var(--ok); }

.xw-body { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 24px 20px; }
.xw-opt, .xw-radio { display: flex; gap: 12px; padding: 13px 14px; margin-bottom: 8px;
  border-radius: 11px; border: 1px solid var(--line); background: var(--surface);
  cursor: pointer; transition: border-color var(--t) var(--ease), background var(--t) var(--ease); }
.xw-opt:hover, .xw-radio:hover { border-color: var(--muted); }
.xw-opt input, .xw-radio input { margin-top: 2px; accent-color: var(--accent); flex: 0 0 auto; }
.xw-opt b, .xw-radio b { display: block; font-size: 13.5px; font-weight: 540; }
.xw-opt em, .xw-radio em { display: block; margin-top: 3px; font-style: normal;
  font-size: 12.5px; color: var(--muted); line-height: 1.55; }
.xw-opt:has(input:checked), .xw-radio:has(input:checked) {
  border-color: var(--accent); background: var(--accent-soft); }
.xw-radio.disabled { opacity: .55; cursor: default; }

.xw-group { margin: 0 0 16px; padding: 0; border: 0; }
.xw-group legend { padding: 0 0 8px; font-size: 11.5px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.xw-fine { margin-top: 6px; font-size: 12.5px; color: var(--muted); }

.xw-foot { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 16px 24px; border-top: 1px solid var(--line);
  background: var(--surface-2); }

.xw-tiles { display: grid; gap: 10px; margin-bottom: 18px;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
.xw-tiles div { padding: 14px 16px; border-radius: 11px; border: 1px solid var(--line);
  background: var(--surface-2); }
.xw-tiles b { display: block; font-size: 20px; font-weight: 640; letter-spacing: -.01em; }
.xw-tiles span { font-size: 12px; color: var(--muted); }
.xw-tiles .bad b { color: #b23b3b; }
.xw-did { margin: 0 0 4px; padding-left: 20px; font-size: 13.5px; line-height: 1.75; }
.xw-h3 { margin: 24px 0 10px; font-size: 13px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.xw-guides { display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.xw-guide { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 14px; border-radius: 10px; border: 1px solid var(--line);
  background: var(--surface); font-size: 13.5px; text-decoration: none; color: var(--ink); }
.xw-guide:hover { border-color: var(--accent); color: var(--accent); }

@media (max-width: 620px) {
  #exportx, #captionx { padding: 0; align-items: stretch; }
  .xw { width: 100%; max-height: none; border-radius: 0; }
  .xw-steps li { font-size: 0; }
  .xw-steps li.on { font-size: 11.5px; }
}

/* ==========================================================================
   Clean up and library, third pass: spacing and controls that match the rest
   ========================================================================== */

/* Selects were the browser's own: square, grey, and with the arrow jammed
   against the text. One shared look, with room for the chevron drawn in. */
.cl-rules select, .cl-grule {
  appearance: none; -webkit-appearance: none;
  padding: 7px 34px 7px 13px; border-radius: 999px;
  border: 1px solid var(--line); background-color: var(--surface);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' \
viewBox='0 0 24 24' fill='none' stroke='%236b6c73' stroke-width='2.2' stroke-linecap='round' \
stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
  background-repeat: no-repeat; background-position: right 11px center; background-size: 14px;
  font: inherit; font-size: 12.5px; color: var(--ink); cursor: pointer;
  transition: border-color var(--t) var(--ease), background-color var(--t) var(--ease); }
.cl-rules select:hover, .cl-grule:hover { border-color: var(--accent); }
.cl-rules select:focus-visible, .cl-grule:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; }
.cl-grule { max-width: 210px; }

/* The group header had its controls hard against the corner. */
.cl-group { padding: 16px 18px 20px; }
.cl-group header { padding: 2px 2px 0; margin-bottom: 16px; row-gap: 10px; }
.cl-gtools { gap: 14px; flex-wrap: wrap; }

/* The stepper reads as one control rather than three loose pieces. */
.cl-keepn { gap: 0; padding: 2px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface); }
.cl-keepn b { padding: 0 12px; font-size: 12.5px; }
.cl-step { width: 26px; height: 26px; border: 0; border-radius: 999px;
  background: transparent; font-size: 15px; color: var(--muted); }
.cl-step:hover:not(:disabled) { background: var(--accent-soft); color: var(--accent); }

.cl-rules { padding: 16px 20px; row-gap: 14px; }
.cl-rules label { gap: 11px; }

/* ---------- Comparison controls on the image library ---------- */
.lib-bar { display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 16px; margin: 18px 0 6px;
  padding: 14px 18px; border-radius: 12px; background: var(--surface);
  border: 1px solid var(--line); }
.lib-bar > p { margin: 0; }
.lib-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.lib-found { font-size: 12.5px; color: var(--muted); }

/* ---------- A notice that leads somewhere ---------- */
.nt-go { display: inline-flex; align-items: center; gap: 6px; margin-top: 9px;
  padding: 6px 12px; border-radius: 999px; border: 1px solid var(--accent);
  background: var(--accent); color: var(--accent-ink); font: inherit;
  font-size: 12.5px; font-weight: 540; cursor: pointer; }
.nt-go:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
.nt-golink { display: block; margin-top: 4px; font-size: 11.5px; font-weight: 560;
  color: var(--accent); }

/* The `#explorer section { padding: 0 }` reset outranks any class selector, so
   a section that does want padding has to say so at the same specificity. */
#explorer .cl-group { padding: 16px 18px 20px; }
#explorer .cl-rules { padding: 16px 20px; }
#explorer .lib-bar { padding: 14px 18px; }

/* ---------- Structure report ---------- */
.rp-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  margin: 16px 0 14px; }
#explorer pre.report { max-height: 60vh; overflow: auto; margin: 0;
  padding: 16px 18px; border-radius: 12px; border: 1px solid var(--line);
  background: var(--surface); font-size: 12px; line-height: 1.65;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  white-space: pre; color: var(--ink); }

/* ---------- What is in here ---------- */
.rp-lead { max-width: 68ch; margin: 18px 0 6px; font-size: 14px; line-height: 1.65; }
.rp-src { margin-top: 30px; padding-bottom: 8px; }
#explorer .rp-src { padding: 0; }
.rp-head h3 { margin: 0 0 2px; font-size: 17px; font-weight: 640; }
.rp-cards { display: grid; gap: 10px; margin: 16px 0 6px;
  grid-template-columns: repeat(auto-fit, minmax(136px, 1fr)); }
.rp-card { padding: 13px 15px; border-radius: 11px; border: 1px solid var(--line);
  background: var(--surface); }
.rp-card b { display: block; font-size: 19px; font-weight: 640; letter-spacing: -.01em; }
.rp-card span { font-size: 12px; color: var(--muted); }
.rp-card.quiet { background: var(--surface-2); }

.rp-h { margin: 26px 0 8px; font-size: 11.5px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted); }
.rp-note { max-width: 70ch; margin-top: 8px; }
.rp-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.rp-table th { text-align: left; font-weight: 560; font-size: 11.5px; color: var(--muted);
  padding: 8px 12px; border-bottom: 1px solid var(--line); }
.rp-table td { padding: 9px 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
.rp-table code { font-size: 12px; overflow-wrap: anywhere; }

.rp-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.rp-chip { display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px;
  border-radius: 999px; border: 1px solid var(--line); background: var(--surface);
  font-size: 12.5px; color: var(--muted); }
.rp-chip b { color: var(--ink); font-weight: 560; }
.rp-chip.odd { border-color: #f0e0bd; background: #fdf4e3; color: #8a6210; }
.rp-chip.odd b { color: #6a4708; }

.rp-more { margin-top: 10px; padding: 0; border: 0; background: none; font: inherit;
  font-size: 12.5px; color: var(--accent); cursor: pointer; }
.rp-more:hover { text-decoration: underline; }
.rp-hidden { margin-top: 10px; }

.rp-shapes { display: flex; flex-direction: column; gap: 6px; }
.rp-shape { border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.rp-shape summary { padding: 10px 14px; cursor: pointer; font-size: 13px; }
.rp-shape pre { margin: 0; padding: 0 14px 14px; font-size: 11.5px; line-height: 1.6;
  overflow-x: auto; color: var(--muted); }

.rp-foot { margin: 40px 0 20px; padding: 20px 22px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--surface-2); }
.rp-foot h4 { margin: 0 0 6px; font-size: 14px; font-weight: 620; }
.rp-foot p { max-width: 70ch; }

/* ---------- Sources as toggles ---------- */
.ex-source.off { opacity: .4; }
.ex-source.off span { text-decoration: line-through; }
.ex-source.on { background: none; color: var(--ink); font-weight: 400; }

/* ---------- Empty sections ---------- */
.ex-empty { max-width: 58ch; margin: 40px 0; padding: 26px 28px; border-radius: 13px;
  border: 1px dashed var(--line); background: var(--surface); }
.ex-empty h3 { margin: 0 0 8px; font-size: 16px; font-weight: 620; }
.ex-empty p { margin: 0; font-size: 13.5px; line-height: 1.65; }
.ex-empty .btn { margin-top: 16px; }

/* ---------- Date range ---------- */
button.ex-stat { display: block; width: 100%; text-align: left; cursor: pointer;
  font: inherit; }
button.ex-stat:hover { border-color: var(--accent); }
.ex-stat.set { border-color: var(--accent); background: var(--accent-soft); }
.ex-stat.set .ex-stat-v { color: var(--accent); }

.cal { position: absolute; z-index: 120; width: 316px; padding: 12px;
  border-radius: 14px; border: 1px solid var(--line); background: var(--surface);
  box-shadow: 0 22px 54px rgba(16, 18, 22, .2);
  animation: m-rise var(--t) var(--ease-out) both; }
.cal-presets { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;
  padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.cal-preset { padding: 5px 11px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); font: inherit; font-size: 12px; color: var(--muted);
  cursor: pointer; }
.cal-preset:hover { border-color: var(--accent); color: var(--accent); }
.cal-head { display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px; font-size: 13.5px; font-weight: 560; }
.cal-nav { width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--surface); font-size: 16px; line-height: 1; color: var(--muted);
  cursor: pointer; }
.cal-nav:hover { color: var(--accent); border-color: var(--accent); }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-dow { display: flex; align-items: center; justify-content: center; height: 24px;
  font-size: 11px; color: var(--muted); }
.cal-day { height: 34px; border: 0; border-radius: 8px; background: none;
  font: inherit; font-size: 12.5px; color: var(--muted); cursor: default; }
.cal-day.empty { visibility: hidden; }
/* A day with nothing in it is not worth picking, and saying so up front beats
   an empty result afterwards. */
.cal-day:disabled { opacity: .3; }
.cal-day.has { color: var(--ink); cursor: pointer; font-weight: 520; }
.cal-day.has:hover { background: var(--surface-2); }
.cal-day.in { background: var(--accent-soft); border-radius: 0; }
.cal-day.edge { background: var(--accent); color: var(--accent-ink); border-radius: 8px; }
.cal-foot { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line);
  font-size: 12.5px; color: var(--muted); }

/* ---------- Workflow guides ---------- */
.flow-card p { margin: 8px 0 0; font-size: 13.5px; line-height: 1.6; }
.flow-why { max-width: 68ch; margin: 26px 0 8px; padding: 18px 22px; border-radius: 12px;
  background: var(--surface-2); border: 1px solid var(--line); }
.flow-why h3 { margin: 0 0 6px; font-size: 13px; font-weight: 620; }
.flow-why p { margin: 0; font-size: 14px; line-height: 1.65; }
.flow-warn { max-width: 68ch; margin: 14px 0 26px; }

.flow-step { display: flex; gap: 20px; padding: 28px 0; border-top: 1px solid var(--line); }
.flow-step:first-of-type { border-top: 0; }
.flow-n { flex: 0 0 38px; width: 38px; height: 38px; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent); font-weight: 640; font-size: 15px; }
.flow-body { min-width: 0; max-width: 68ch; }
.flow-body h2 { margin: 4px 0 10px; font-size: 19px; font-weight: 640; }
.flow-body p { margin: 0 0 12px; font-size: 14.5px; line-height: 1.7; }
.flow-list { margin: 0 0 12px; padding-left: 20px; font-size: 14.5px; line-height: 1.7; }
.flow-list li { margin-bottom: 8px; }
.flow-end { max-width: 68ch; margin: 10px 0 40px; padding: 22px 24px; border-radius: 12px;
  border: 1px solid #cdeadb; background: var(--ok-soft); }
.flow-end h3 { margin: 0 0 8px; font-size: 15px; font-weight: 620; color: var(--ok); }
.flow-end p { margin: 0 0 8px; font-size: 14px; line-height: 1.65; }

@media (max-width: 640px) {
  .flow-step { gap: 14px; padding: 22px 0; }
  .flow-n { flex-basis: 32px; width: 32px; height: 32px; font-size: 14px; }
}

/* ---------- describing pictures ----------

   Built on the export wizard's shell (.xw) rather than a second panel style,
   because they are the same kind of thing: a short sequence of decisions
   ending in something being written. Only the parts that do not exist there
   are new. */
.cx-field { display: grid; grid-template-columns: 92px 1fr; align-items: center;
  gap: 10px; margin-bottom: 8px; font-size: 13px; }
.cx-field span { color: var(--muted); }
.cx-field input { width: 100%; padding: 9px 11px; border-radius: 9px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  font: inherit; font-size: 13px; }
.cx-field input:focus { outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent); }

.cx-note { margin: 12px 0 0; padding: 10px 12px; border-radius: 9px; font-size: 13px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--ink); }
.cx-note.ok { border-color: color-mix(in srgb, var(--ok) 45%, var(--line)); }
.cx-note.warn { border-color: color-mix(in srgb, #b23b3b 40%, var(--line)); }

.cx-where { margin: 4px 0 12px; font-size: 13.5px; line-height: 1.6; color: var(--ink); }
.cx-where b { font-weight: 600; }

.cx-bar { height: 8px; border-radius: 999px; background: var(--surface-2);
  overflow: hidden; margin: 6px 0 10px; }
.cx-bar i { display: block; height: 100%; background: var(--accent);
  transition: width .25s ease; }
.cx-count { margin: 0 0 14px; font-size: 13px; color: var(--muted); }

/* The last description, so a run that is going wrong is visible while it runs
   rather than at the end of it. Fixed height so the panel does not jump as
   sentences of different lengths arrive. */
.cx-last { margin: 0 0 14px; padding: 12px 14px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface-2); min-height: 62px;
  display: flex; align-items: center; }
.cx-last figcaption { font-size: 13.5px; line-height: 1.55; color: var(--ink); }

/* ---------- tooltips ----------

   One bubble on <body>, position:fixed. Fixed means no ancestor can clip it
   and no panel can stack above it, which is the entire reason it is not
   rendered inside the thing it explains. See tips.js. */
.tip-dot { display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; margin-left: 5px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--muted);
  font-size: 10px; font-weight: 700; line-height: 1; cursor: help;
  vertical-align: middle; user-select: none; flex: 0 0 auto;
  transition: color .12s ease, border-color .12s ease, background .12s ease; }
.tip-dot:hover, .tip-dot:focus-visible { color: var(--surface); background: var(--accent);
  border-color: var(--accent); outline: none; }

.tip-bubble { position: fixed; z-index: 9999; pointer-events: none;
  padding: 9px 12px; border-radius: 9px; font-size: 12.5px; line-height: 1.5;
  background: #1b1e26; color: #f2f3f6; box-shadow: var(--shadow-lg);
  opacity: 0; transform: translateY(-3px); transition: opacity .13s ease, transform .13s ease; }
.tip-bubble.above { transform: translateY(3px); }
.tip-bubble.on { opacity: 1; transform: translateY(0); }
.tip-bubble::after { content: ""; position: absolute; left: var(--tip-ax, 50%);
  margin-left: -5px; border: 5px solid transparent; }
.tip-bubble:not(.above)::after { bottom: 100%; border-bottom-color: #1b1e26; }
.tip-bubble.above::after { top: 100%; border-top-color: #1b1e26; }

/* A label with its own explanation beside it, used in the panels. */
.tip-label { display: inline-flex; align-items: center; }

/* The paragraph that says what a panel is for, before it asks for anything. */
.cx-lede { margin: 0 0 14px; font-size: 13.5px; line-height: 1.65; color: var(--muted); }
.cx-lede b { color: var(--ink); font-weight: 560; }

/* ---------- AI tagging ----------

   The one feature here that changes what a photo library can do was a ghost
   button, which in this palette is muted text on nothing - indistinguishable
   from a disabled control. It gets a filled button and, until it has been
   used, a block that says what it is for. */
/* Solid, not a gradient. A gradient button is the same tell as a gradient
   headline word - it reads as decoration applied to make something feel
   premium. The icon already carries the meaning. */
.btn.ai { background: var(--accent); color: var(--accent-ink); border-color: transparent;
  box-shadow: var(--shadow-sm); display: inline-flex; align-items: center; gap: 7px; }
.btn.ai:hover { background: var(--accent-strong); }
.ai-spark { width: 15px; height: 15px; flex: 0 0 auto; }

.ai-promo { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 26px;
  align-items: center; margin: 0 0 16px; padding: 18px 22px;
  border-radius: var(--radius-lg); border: 1px solid var(--line);
  background: var(--tint); }
.ai-promo h3 { margin: 0 0 6px; font-size: 16.5px; font-weight: 640; letter-spacing: -.01em; }
.ai-promo p { margin: 0 0 6px; font-size: 13px; line-height: 1.55; color: var(--muted); }
.ai-promo p:last-child { margin-bottom: 0; }
.ai-promo b { color: var(--ink); font-weight: 560; }
.ai-promo-cta { display: flex; flex-direction: column; align-items: stretch; gap: 9px; }
.ai-promo-cta .btn { justify-content: center; }
.ai-fine { font-size: 12px; line-height: 1.5; color: var(--muted); text-align: center; }

.ai-strip { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  margin: 0 0 16px; padding: 11px 14px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--surface); font-size: 13px; }
.ai-strip span { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); }
.ai-strip .ai-spark { color: var(--accent); }
.ai-strip.done { background: var(--surface-2); }

@media (max-width: 780px) {
  .ai-promo { grid-template-columns: 1fr; gap: 18px; }
  .ai-strip { flex-direction: column; align-items: stretch; }
}

/* ---------- tabs inside the pictures view ----------

   Clean up is not a separate place in the app, it is the second thing you do
   to the pictures you are already looking at. */
.ph-tabs { display: flex; gap: 4px; margin: 0 0 18px; border-bottom: 1px solid var(--line); }
.ph-tab { display: inline-flex; align-items: center; gap: 7px; padding: 9px 14px;
  border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px;
  background: none; color: var(--muted); font: inherit; font-size: 13.5px;
  font-weight: 520; cursor: pointer; transition: color .12s ease, border-color .12s ease; }
.ph-tab:hover { color: var(--ink); }
.ph-tab.on { color: var(--accent); border-bottom-color: var(--accent); }
.ph-tab em { font-style: normal; font-size: 11.5px; padding: 1px 6px; border-radius: 999px;
  background: var(--surface-2); color: var(--muted); }
.ph-tab.on em { background: var(--accent-soft);
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }

/* ---------- choosing a route, and buying credits ---------- */
.cx-route { padding: 18px 20px; margin-bottom: 12px; border-radius: var(--radius-lg);
  border: 1px solid var(--line); background: var(--surface); }
.cx-route.pick { border-color: color-mix(in srgb, var(--accent) 40%, var(--line));
  background: var(--tint); }
.cx-route-head { display: flex; align-items: center; gap: 10px; margin-bottom: 7px; }
.cx-route h3 { margin: 0; font-size: 15.5px; font-weight: 620; }
.cx-route p { margin: 0 0 10px; font-size: 13px; line-height: 1.58; color: var(--muted); }
.cx-route b { color: var(--ink); font-weight: 560; }
.cx-badge { font-size: 11px; font-weight: 600; letter-spacing: .02em; padding: 3px 8px;
  border-radius: 999px; background: var(--accent-soft);
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  color: var(--accent); }
.cx-badge.quiet { background: var(--surface-2); color: var(--muted); }
.cx-pledge-h { margin-bottom: 6px !important; }

/* The promises about what happens to a picture that leaves the machine. Set
   as a list rather than a paragraph because each line is a separate
   commitment and a wall of prose hides that. */
.cx-pledge { margin: 0 0 12px; padding: 0; list-style: none; }
.cx-pledge li { position: relative; padding-left: 21px; margin-bottom: 5px;
  font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.cx-pledge li::before { content: ""; position: absolute; left: 2px; top: 6px;
  width: 9px; height: 5px; border-left: 2px solid var(--ok);
  border-bottom: 2px solid var(--ok); transform: rotate(-45deg); }

/* The exact price for this library, itemised. Laid out as a receipt rather
   than a set of tiles, because there is nothing to choose between - there is
   one price, and the only line worth explaining is the floor. */
.cx-quote { margin: 0 0 16px; padding: 14px 16px; border-radius: var(--radius);
  border: 1px solid var(--line);
  border-color: color-mix(in srgb, var(--accent) 32%, var(--line));
  background: var(--tint); }
.cx-quote-line { display: flex; justify-content: space-between; gap: 12px;
  font-size: 13px; color: var(--muted); padding: 2px 0; }
.cx-quote-line.floor { color: var(--ink); }
.cx-quote-total { display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px; margin-top: 8px; padding-top: 9px; border-top: 1px solid var(--line);
  font-size: 13px; color: var(--muted); }
.cx-quote-total b { font-size: 21px; font-weight: 660; letter-spacing: -.01em; color: var(--ink); }
.cx-quote .btn { margin-top: 12px; }
.cx-quote-note { margin: 9px 0 0; font-size: 12px; line-height: 1.55; color: var(--muted); }

.cx-other { margin: 0 0 12px; font-size: 13px; }
.cx-other summary { cursor: pointer; color: var(--muted); padding: 6px 0; }
.cx-other summary:hover { color: var(--ink); }
.cx-other .cx-field { margin-top: 8px; }
.cx-other .btn { margin-top: 4px; }

.cx-redeem { margin: 0 0 4px; font-size: 13px; }
.cx-redeem summary { cursor: pointer; color: var(--muted); padding: 6px 0; }
.cx-redeem summary:hover { color: var(--ink); }
.cx-redeem .cx-field { margin-top: 8px; }

.xw-footl { display: flex; gap: 6px; }

/* ---------- the ask ----------

   Last thing in the export summary, after the destination guides, so it is
   never in the way of anything. Quiet on purpose: a loud panel here would be
   the one moment in the product that felt like it wanted something. */
.dn { margin: 26px 0 0; padding: 18px 20px; border-radius: var(--radius-lg);
  border: 1px solid var(--line); background: var(--surface-2); }
.dn h3 { margin: 0 0 6px; font-size: 15.5px; font-weight: 620; }
.dn p { margin: 0 0 12px; font-size: 13px; line-height: 1.6; color: var(--muted); }
.dn-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.dn-amt { min-width: 62px; justify-content: center; }
.dn-no { margin-left: auto; }
.dn-fine { margin: 10px 0 0 !important; font-size: 11.5px; }
@media (max-width: 520px) { .dn-no { margin-left: 0; } }

/* ---------- earning the benefit of the doubt ----------

   Nobody arrives believing "nothing is uploaded". They have been told that by
   sites that then uploaded everything, so the sentence carries no weight - it
   is exactly what a site that did upload would also say.

   Two things do carry weight. First, not having to trust us at all on the first
   run: the sample exports show the whole product working on invented people.
   Second, a test the reader performs themselves - turning the network off and
   watching everything keep working is proof they generate rather than proof we
   assert. So those get real space here, not a footnote. */
.trust { display: grid; gap: 14px; margin-top: 22px; }
.trust-try { padding: 20px 22px; border-radius: var(--radius-lg);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, var(--line));
  background: var(--tint); }
.trust-try h2 { margin: 0 0 7px; font-size: 17px; font-weight: 640; letter-spacing: -.01em; }
.trust-try p { margin: 0 0 14px; font-size: 13.5px; line-height: 1.6; color: var(--muted); }

.trust-check { padding: 20px 22px; border-radius: var(--radius-lg);
  border: 1px solid var(--line); background: var(--surface); }
.trust-check h3 { margin: 0 0 6px; font-size: 15px; font-weight: 620; }
.trust-check > p { margin: 0 0 12px; font-size: 13.5px; line-height: 1.6; color: var(--muted); }
.trust-check ol { margin: 0 0 14px; padding-left: 20px; }
.trust-check li { margin-bottom: 10px; font-size: 13.5px; line-height: 1.62; color: var(--muted); }
.trust-check li strong { color: var(--ink); font-weight: 560; }
.trust-check .fine { margin: 0; }

/* Section rhythm from the reference set: 112px, which is roughly double what
   this page had. The single biggest difference between a designed page and an
   assembled one is how much air it is willing to leave. */
main > section.wrap { padding-top: var(--section); padding-bottom: 0; }
main > section.wrap:last-child { padding-bottom: var(--section); }
.hero.wrap { padding-top: 96px; padding-bottom: 96px; }
.section-head { max-width: 62ch; margin-bottom: 40px; }
.section-head h2 { font-size: clamp(28px, 3.4vw, 40px); letter-spacing: -.03em; }
.section-head p { margin-top: 14px; font-size: 17px; color: var(--muted); line-height: 1.6; }

@media (max-width: 720px) {
  :root { --section: 72px; --section-tight: 48px; }
  .hero.wrap { padding-top: 64px; padding-bottom: 64px; }
}

/* ---------- sorting by instruction ----------

   The strip lives in Clean up because that tab is already where keep-or-drop
   decisions happen. It does not replace the duplicate groups: a rule is good at
   "all screenshots" and useless at "which of these four near-identical shots is
   sharpest", so the two answer different questions and sit next to each other. */
.pl-strip { display: flex; align-items: center; justify-content: space-between; gap: 18px;
  margin: 0 0 18px; padding: 16px 18px; border-radius: var(--radius-lg);
  border: 1px solid var(--line); background: var(--tint); }
.pl-strip b { display: block; font-size: 14px; font-weight: 600; color: var(--ink); }
.pl-strip p { margin: 4px 0 0; font-size: 13px; line-height: 1.55; color: var(--muted); }
.pl-strip .btn { flex: 0 0 auto; }

.pl-text { width: 100%; padding: 12px 14px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  font: inherit; font-size: 14px; line-height: 1.55; resize: vertical; }
.pl-text:focus { outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft); }

.pl-egs { display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  margin: 12px 0 14px; font-size: 12.5px; }
.pl-egs > span { color: var(--muted); }
.pl-eg { text-align: left; font-size: 12.5px; line-height: 1.5; }

/* One entry per bucket: what it is called, where it goes, how many matched, the
   rule in words, and six actual pictures. The samples are the point - a count
   alone cannot show that "notes" also caught every photo of a whiteboard. */
.pl-buckets { list-style: none; margin: 0 0 14px; padding: 0; counter-reset: none; }
.pl-bucket { padding: 14px 16px; margin-bottom: 10px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--surface); }
.pl-bucket.out { border-color: color-mix(in srgb, #b23b3b 30%, var(--line));
  background: #fdf8f8; }
.pl-bhead { display: flex; align-items: center; gap: 9px; }
.pl-bhead b { font-size: 14px; font-weight: 600; color: var(--ink); }
.pl-bhead em { margin-left: auto; font-style: normal; font-size: 12.5px; color: var(--muted); }
.pl-rule { margin: 7px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.pl-samples { display: flex; gap: 6px; margin-top: 11px; align-items: center; }
.pl-thumb { width: 46px; height: 46px; flex: 0 0 auto; border-radius: var(--radius-sm);
  background: var(--surface-2) center / cover no-repeat; border: 1px solid var(--line); }
.pl-thumb.nodecode { background: var(--line-2); }
.pl-more { font-size: 12px; color: var(--muted); font-family: var(--mono); }
.pl-empty { margin: 9px 0 0; font-size: 12.5px; color: var(--muted); }

@media (max-width: 620px) {
  .pl-strip { flex-direction: column; align-items: stretch; }
}
