/* KeywordScope — site styles.
   Colours are the app's own tokens (docs/design/design-spec.md), so the site
   and the product are visibly one thing. Dark ground, because the app is. */

:root {
  /* Light ground. The app ships light and dark; the site shows the light face,
     because a marketing page read in daylight should not be a dark room. */
  --bg:        #ffffff;   /* raised bands, cards */
  --desk:      #f6f3ff;   /* page ground, faintly violet */
  --surface:   #ffffff;
  --raise:     #f3efff;
  --text:      #16152b;
  --t2:        #4d4b6a;
  --t3:        #6c6889;   /* 4.8:1 on the tinted band — AA at small sizes */
  --line:      #eae5fa;
  --line-2:    #ddd5f5;

  /* Brand violet, darkened from the app token so it clears 4.5:1 on white. */
  --accent:    #6144e8;
  --accent-hi: #8a71ff;
  --accent-dim:#efeaff;

  /* ---- LOGO INK ----------------------------------------------------------
     The site draws the mark a shade darker than the app icon, because the icon
     violet was picked against a dark Dock and reads pale on white (3.2:1).
     The .icon document is NOT affected — it keeps #9184d9 / #b5abfc.

     TO REVERT to the exact app-icon colours, set these two back to
     #9184d9 and #b5abfc. That is the whole change; nothing else references
     the mark's colour.                                                      */
  --logo-frame: #7a6ad0;   /* app icon: #9184d9 */
  --logo-arrow: #9d8ef2;   /* app icon: #b5abfc */

  /* Supporting hues. Each one MEANS something and is used only for that:
     green = present/included, amber = a caveat, pink = emphasis,
     blue = the editor/MCP story, teal = the local-first story. */
  --good:      #0f9f6e;
  --warn:      #c9741a;
  --pink:      #e8467f;
  --blue:      #1f8ff0;
  --teal:      #0fa8a8;

  --measure:   68ch;
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--desk);
  color: var(--text);
  font: 400 17px/1.65 -apple-system, BlinkMacSystemFont, "SF Pro Text",
        "Helvetica Neue", Arial, sans-serif;
  font-feature-settings: "kern" 1;
}

a { color: var(--accent-hi); text-decoration: none; }
a:hover { text-decoration: underline; }

.wrap { max-width: 1040px; margin: 0 auto; padding: 0 28px; }
.narrow { max-width: var(--measure); }

/* ---- header ---- */

header.site {
  border-bottom: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.86);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  position: sticky;
  top: 0;
  z-index: 10;
}
header.site .wrap {
  display: flex;
  align-items: center;
  gap: 28px;
  height: 72px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  font-size: 17px;
  color: var(--text);
  letter-spacing: -0.01em;
}
.brand:hover { text-decoration: none; }
.brand .mark { width: 40px; height: 40px; display: block; }

/* The hero mark is the app icon at the size it is seen in the Dock. */
.hero .mark { width: 76px; height: 76px; display: block; margin: 0 0 26px; }
header.site nav { margin-left: auto; display: flex; gap: 24px; font-size: 15px; }
header.site nav a { color: var(--t2); }
header.site nav a:hover { color: var(--text); text-decoration: none; }

/* ---- hero ---- */

.hero {
  padding: 96px 0 72px;
  background:
    radial-gradient(1100px 520px at 12% -10%, #e4dcff 0%, rgba(228,220,255,0) 60%),
    radial-gradient(900px 480px at 88% 0%, #ffe3f0 0%, rgba(255,227,240,0) 62%),
    linear-gradient(180deg, #ffffff 0%, #efe9ff 100%);
}
.hero h1 span.grad {
  background: linear-gradient(120deg, var(--accent), var(--pink));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero h1 {
  font-size: 52px;
  line-height: 1.12;
  letter-spacing: -0.025em;
  font-weight: 600;
  margin: 0 0 22px;
  max-width: 16ch;
}
.hero .lede {
  font-size: 21px;
  line-height: 1.55;
  color: var(--t2);
  max-width: 56ch;
  margin: 0 0 34px;
}

.cta-row { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }

.btn {
  display: inline-block;
  padding: 12px 22px;
  border-radius: 9px;
  font-size: 16px;
  font-weight: 500;
  border: 1px solid transparent;
}
.btn:hover { text-decoration: none; }
.btn-primary {
  background: linear-gradient(135deg, var(--accent), #8a4de8 55%, var(--pink));
  color: #fff;
  box-shadow: 0 6px 18px -6px rgba(97, 68, 232, 0.55);
}
.btn-primary:hover { filter: brightness(1.08); box-shadow: 0 8px 22px -6px rgba(97, 68, 232, 0.62); }
.btn-secondary { border-color: var(--line-2); color: var(--text); background: #fff; }
.btn-secondary:hover { border-color: var(--accent); color: var(--accent); }

.cta-note { font-size: 14px; color: var(--t3); margin-top: 14px; }

/* ---- shot ---- */

.shot {
  background: linear-gradient(180deg, #efe9ff 0%, var(--desk) 100%);
  padding-bottom: 84px;
}
.shot img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--line-2);
  border-radius: 14px;
  box-shadow: 0 24px 60px -24px rgba(40, 24, 110, 0.30);
}
.shot figcaption {
  font-size: 14px;
  color: var(--t3);
  margin-top: 14px;
  text-align: center;
}

/* ---- gallery ----
   Two columns of real screens. Captions state what the screen is FOR, not
   what is in it — the picture already carries the second. */

.gallery {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 40px 32px;
  margin-top: 44px;
}
.gallery figure { margin: 0; }
.gallery a {
  display: block;
  border-radius: 12px;
  border: 1px solid var(--line-2);
  overflow: hidden;
  background: #fff;
  box-shadow: 0 10px 30px -18px rgba(40, 24, 110, 0.35);
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.gallery a:hover {
  border-color: var(--accent);
  box-shadow: 0 16px 38px -18px rgba(97, 68, 232, 0.45);
  transform: translateY(-2px);
  text-decoration: none;
}
.gallery img { width: 100%; height: auto; display: block; }
.gallery figcaption { margin-top: 14px; }
.gallery h3 { font-size: 17px; margin: 0 0 6px; }
.gallery p { font-size: 15px; color: var(--t2); margin: 0; line-height: 1.55; }

@media (max-width: 720px) {
  .gallery { grid-template-columns: 1fr; gap: 32px; }
}

/* ---- lightbox ----
   Progressive enhancement: the gallery links work as plain links with no
   script. The script intercepts them and shows the full-size file in place. */

.lb {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 56px 24px;
  background: rgba(22, 21, 43, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.lb[open], .lb.is-open { display: flex; }

.lb figure {
  margin: 0;
  max-width: 1400px;
  width: 100%;
  text-align: center;
}
.lb img {
  max-width: 100%;
  max-height: calc(100vh - 168px);
  width: auto;
  height: auto;
  display: block;
  margin: 0 auto;
  border: 1px solid var(--line-2);
  border-radius: 10px;
  background: var(--desk);
}
.lb figcaption {
  margin-top: 16px;
  font-size: 15px;
  color: rgba(255,255,255,0.78);
}
.lb figcaption b { color: #fff; font-weight: 600; }
.lb figcaption .count { color: rgba(255,255,255,0.55); margin-left: 10px; font-size: 14px; }

.lb button {
  position: absolute;
  border: 1px solid var(--line-2);
  background: rgba(255, 255, 255, 0.94);
  color: var(--text);
  border-radius: 8px;
  cursor: pointer;
  font: inherit;
  line-height: 1;
  padding: 0;
  display: grid;
  place-items: center;
  transition: border-color .15s ease, background .15s ease;
}
.lb button:hover { border-color: var(--accent); background: #fff; color: var(--accent); }
.lb button:focus-visible { outline: 2px solid var(--accent-hi); outline-offset: 2px; }

.lb .lb-close { top: 16px; right: 20px; width: 40px; height: 40px; font-size: 20px; }
.lb .lb-prev, .lb .lb-next {
  top: 50%; transform: translateY(-50%);
  width: 44px; height: 60px; font-size: 20px;
}
.lb .lb-prev { left: 16px; }
.lb .lb-next { right: 16px; }

@media (max-width: 720px) {
  .lb { padding: 64px 12px; }
  .lb .lb-prev, .lb .lb-next { top: auto; bottom: 16px; transform: none; height: 44px; }
}

body.lb-lock { overflow: hidden; }

/* ---- sections ---- */

section { padding: 84px 0; border-top: 1px solid var(--line); background: var(--bg); }
section.plain { background: var(--desk); }

h2 {
  font-size: 32px;
  line-height: 1.2;
  letter-spacing: -0.02em;
  font-weight: 600;
  margin: 0 0 18px;
}
h3 {
  font-size: 19px;
  font-weight: 600;
  margin: 0 0 8px;
  letter-spacing: -0.01em;
}
p { margin: 0 0 18px; }
.sub { color: var(--t2); max-width: var(--measure); }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 34px 40px;
  margin-top: 44px;
}
.grid p { color: var(--t2); font-size: 16px; margin: 0; }

/* ---- pricing ---- */

.plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 22px;
  margin: 46px 0 0;
  align-items: start;
}
.plan {
  border: 1px solid var(--line-2);
  border-radius: 14px;
  padding: 30px;
  background: var(--surface);
}
.plan {
  box-shadow: 0 8px 26px -20px rgba(40, 24, 110, 0.35);
}
.plan.featured {
  border-color: transparent;
  background:
    linear-gradient(#fff, #fff) padding-box,
    linear-gradient(135deg, var(--accent), var(--pink)) border-box;
  border: 2px solid transparent;
  box-shadow: 0 18px 44px -22px rgba(97, 68, 232, 0.55);
}
.plan.featured h3 { color: var(--accent); font-weight: 600; }
.plan h3 { font-size: 16px; color: var(--t2); font-weight: 500; margin-bottom: 14px; }
.price { font-size: 42px; font-weight: 600; letter-spacing: -0.03em; line-height: 1; }
.price span { font-size: 16px; font-weight: 400; color: var(--t3); letter-spacing: 0; }
.plan .alt { font-size: 15px; color: var(--t3); margin: 10px 0 0; }
.plan ul { list-style: none; padding: 0; margin: 26px 0 0; }
.plan li {
  font-size: 15px;
  color: var(--t2);
  padding: 7px 0 7px 26px;
  position: relative;
}
.plan li::before {
  content: "";
  position: absolute;
  left: 4px; top: 14px;
  width: 8px; height: 8px;
  border-radius: 2px;
  background: var(--good);
}
.plan li.off { color: var(--t3); }
.plan li.off::before { background: var(--line-2); }
.plan .btn { margin-top: 28px; width: 100%; text-align: center; }

.note {
  border-left: 3px solid var(--warn);
  background: #fff8ef;
  border-radius: 0 10px 10px 0;
  padding: 16px 18px;
  margin: 40px 0 0;
  color: var(--t2);
  font-size: 15px;
  max-width: var(--measure);
}
.note strong { color: #8a4d05; }

/* ---- prose pages (legal) ---- */

.prose { padding: 70px 0 100px; max-width: var(--measure); }
.prose h1 { font-size: 38px; letter-spacing: -0.02em; margin: 0 0 6px; font-weight: 600; }
.prose .updated { color: var(--t3); font-size: 15px; margin: 0 0 44px; }
.prose h2 { font-size: 21px; margin: 40px 0 12px; }
.prose p, .prose li { color: var(--t2); font-size: 16.5px; }
.prose ul { padding-left: 22px; }
.prose li { margin-bottom: 8px; }
.prose strong { color: var(--text); font-weight: 600; }
.prose h3 { font-size: 17px; margin: 26px 0 8px; color: var(--text); }

/* Wider than the reading measure, because a five-column table cannot be
   squeezed into 68ch without becoming unreadable. */
.prose .wide {
  margin: 22px 0 26px;
  width: calc(100vw - 56px);
  max-width: 900px;
  margin-left: calc(50% - min(450px, 50vw - 28px));
  overflow-x: auto;
}
.prose table {
  border-collapse: collapse;
  width: 100%;
  font-size: 14.5px;
  color: var(--t2);
}
.prose th, .prose td {
  text-align: left;
  vertical-align: top;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line);
}
.prose th {
  color: var(--text);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  border-bottom-color: var(--line-2);
  white-space: nowrap;
}
.prose tbody tr:last-child td { border-bottom: none; }

.prose .legal-id {
  border: 1px solid var(--line-2);
  background: var(--accent-dim);
  border-radius: 10px;
  padding: 20px 22px;
  margin: 22px 0;
  font-size: 15.5px;
  line-height: 1.75;
  color: var(--t2);
}
.prose .legal-id b { color: var(--text); font-weight: 600; }

@media (max-width: 980px) {
  .prose .wide { width: 100%; max-width: none; margin-left: 0; }
}

/* ---- footer ---- */

footer.site {
  border-top: 1px solid var(--line);
  background: var(--desk);
  padding: 44px 0 60px;
  font-size: 14.5px;
  color: var(--t3);
}
footer.site nav { display: flex; gap: 22px; flex-wrap: wrap; margin-bottom: 20px; }
footer.site nav a { color: var(--t2); }
footer.site p { margin: 0; max-width: var(--measure); }

@media (max-width: 640px) {
  .hero { padding: 62px 0 48px; }
  .hero h1 { font-size: 38px; }
  .hero .lede { font-size: 19px; }
  section { padding: 60px 0; }
  h2 { font-size: 27px; }
}

/* A site with nothing to disclose should say so where a banner would have been. */
footer.site .nocookies {
  margin-top: 10px;
  font-size: 13px;
  color: var(--t3);
}

/* ---- colour where it carries meaning ----
   The feature grid gets a coloured rule per card so the eye can group them.
   Rotating hue is decoration; it must never be the only thing distinguishing
   two cards, which is why every card also has its own heading. */

.grid > div {
  padding-left: 16px;
  border-left: 3px solid var(--accent);
}
.grid > div:nth-child(6n+2) { border-left-color: var(--pink); }
.grid > div:nth-child(6n+3) { border-left-color: var(--blue); }
.grid > div:nth-child(6n+4) { border-left-color: var(--teal); }
.grid > div:nth-child(6n+5) { border-left-color: var(--good); }
.grid > div:nth-child(6n+6) { border-left-color: var(--warn); }
.grid h3 { color: var(--text); }

/* Section headings pick up the brand violet so a long page has a rhythm. */
section h2 { color: var(--text); }
section .sub a { color: var(--accent); font-weight: 500; }

/* The MCP band is the one place a saturated field earns its keep — it is the
   developer story, and it should read differently from the rest of the page. */
#mcp {
  background:
    radial-gradient(700px 380px at 85% 20%, rgba(31,143,240,0.13) 0%, rgba(31,143,240,0) 65%),
    linear-gradient(180deg, #f4f0ff 0%, #ecf5ff 100%);
}
#mcp h2 { color: #163a63; }

/* Pricing band, kept distinct from the screens band above it. */
#pricing {
  background:
    radial-gradient(800px 400px at 15% 0%, rgba(232,70,127,0.10) 0%, rgba(232,70,127,0) 62%),
    linear-gradient(180deg, var(--desk) 0%, #ffffff 100%);
}

/* Free-tier "off" rows: struck through as well as greyed, so the distinction
   survives for anyone who cannot separate the two greys. */
.plan li.off { color: var(--t3); text-decoration: line-through; text-decoration-color: var(--line-2); }
.plan li::before { background: var(--good); }
.plan li.off::before { background: transparent; box-shadow: inset 0 0 0 2px var(--line-2); }

.cta-note { color: var(--t3); }

/* ---- cookie consent ----
   Anchored, not a full-screen blocker: the visitor can read the page and
   decide, which is the difference between asking and extorting. Reject and
   Accept are deliberately the same size and weight — a banner where declining
   is harder than agreeing is not consent, whatever the buttons say. */

.consent {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 200;
  display: none;
  padding: 16px;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-top: 1px solid var(--line-2);
  box-shadow: 0 -12px 40px -22px rgba(40, 24, 110, 0.45);
}
.consent.is-open { display: block; }

.consent-inner {
  max-width: 1040px;
  margin: 0 auto;
  padding: 0 12px;
  display: flex;
  align-items: center;
  gap: 26px;
}
.consent-text {
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--t2);
  max-width: 78ch;
}
.consent-text b { color: var(--text); font-weight: 600; }
.consent-text a { color: var(--accent); }

.consent-actions { margin-left: auto; display: flex; gap: 10px; flex-shrink: 0; }

.consent-btn {
  font: inherit;
  font-size: 14.5px;
  font-weight: 500;
  padding: 9px 20px;
  min-width: 104px;
  border-radius: 9px;
  border: 1px solid var(--line-2);
  background: #fff;
  color: var(--text);
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.consent-btn:hover { border-color: var(--accent); color: var(--accent); }
.consent-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.consent-yes {
  background: linear-gradient(135deg, var(--accent), #8a4de8 55%, var(--pink));
  border-color: transparent;
  color: #fff;
}
.consent-yes:hover { filter: brightness(1.08); color: #fff; border-color: transparent; }

@media (max-width: 760px) {
  .consent-inner { flex-direction: column; align-items: stretch; gap: 14px; }
  .consent-actions { margin-left: 0; }
  .consent-btn { flex: 1; }
}

/* Tax basis, stated in the footer of every page — the same place a buyer
   looks for it on any other software site, and required disclosure for
   consumers under the Consumer Rights Directive. */
footer.site .taxnote {
  margin-top: 10px;
  font-size: 13px;
  color: var(--t3);
  max-width: var(--measure);
}

/* ---- billing-period toggle ----
   Lives INSIDE the paid card, directly above the figure it changes. Put
   anywhere else and the reader has to connect a control to a number some
   distance away; here the cause sits on top of the effect.

   The displayed figure and the price ID sent to Paddle come from one state in
   checkout.js, so the card cannot show one number and charge another. */

.plan .periods {
  display: flex;
  gap: 3px;
  padding: 3px;
  margin: 0 0 18px;
  border: 1px solid var(--line-2);
  background: var(--desk);
  border-radius: 10px;
}
.plan .periods button {
  flex: 1;
  font: inherit;
  font-size: 13.5px;
  font-weight: 500;
  padding: 7px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--t3);
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s ease, color .15s ease;
}
.plan .periods button:hover { color: var(--text); }
.plan .periods button.is-on {
  background: #fff;
  color: var(--accent);
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(40, 24, 110, 0.18);
}
.periods button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Checkout not configured yet.
   It keeps the gradient — this IS the Subscribe button, not a different
   component — but sits at reduced opacity so it reads as "not live yet"
   rather than "ready to click". A flat grey looked like a styling mistake;
   a full-strength gradient that does nothing would be worse. The hover title
   carries the reason. Delete nothing here: the moment checkout.js has a token
   and price IDs, this class is never applied. */
.btn.is-unavailable { cursor: not-allowed; }
