/* ───────────────────────────────────────────────────────────────
   Local Test, site stylesheet

   Warm paper, serif headings, system sans body. Same family as
   graysonanderson.com, with a software inflection carried by
   monospace details and framed screenshots rather than decoration.

   Everything is themed through the tokens in section 1. Light is the
   default; dark is the same design with the paper turned down, so no
   rule below this section may hardcode a colour.

    1. Tokens        2. Base          3. Header       4. Hero
    5. Sections      6. Buttons       7. Frames       8. Compare
    9. FAQ          10. Terminal     11. Live status 12. Demo host
   13. Dialog       14. Footer       15. Utilities   16. Motion
   17. Pocket       18. Two audiences (routes, spec sheet, pricing)
   ─────────────────────────────────────────────────────────────── */

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

:root {
  color-scheme: light;

  --paper:      #fcfbf9;
  --paper-2:    #f5f2ec;
  --card:       #ffffff;
  --rule:       #e6e1d9;
  --rule-2:     #d8d1c6;

  --ink:        #2c2a2f;
  --ink-2:      #56525c;
  --ink-3:      #6f6a78;   /* 5.1:1 on paper, carries most small text */

  --accent:     #a55f4c;   /* 4.7:1 on paper */
  --accent-ink: #ffffff;
  --accent-sub: #b98071;

  --sky:        #dce5f1;
  --sage:       #dde8da;
  --blush:      #f6e0da;
  --sky-ink:    #3f5877;
  --sage-ink:   #446341;
  --blush-ink:  #8a5344;

  --code-bg:    #f1ede6;
  --term-bg:    #2e2b33;
  --term-ink:   #efeaf2;
  --term-dim:   #a8a1b2;   /* 4.6:1 on term-bg */

  /* VIP. The only gold on the site, defined once so it stays identical
     wherever the crown appears, and dark enough to read as text. */
  --crown:      #8a6410;   /* 5.4:1 on paper */
  --crown-mark: #c8a13a;   /* the crown glyph itself, never text */
  --crown-bg:   #f8f1de;
  --crown-rule: #e0cd9a;

  --shadow:     0 18px 44px -22px rgba(44, 42, 47, .28);
  --shadow-sm:  0 8px 22px -12px rgba(44, 42, 47, .3);

  --wash-1: rgba(220, 229, 241, .80);
  --wash-2: rgba(221, 232, 218, .55);
  --wash-3: rgba(246, 224, 218, .40);

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua",
           Georgia, "Times New Roman", serif;
  --sans:  -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
           "Helvetica Neue", Arial, sans-serif;
  --mono:  ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  --col:   660px;
  --wide:  980px;
  --pad:   clamp(1.4rem, 6vw, 2.5rem);
  --nav-h: 3.9rem;
  --ease:  cubic-bezier(.4, 0, .2, 1);
}

/* Dark is the same paper with the lights down: still warm, never grey. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --paper:      #17151a;
    --paper-2:    #1e1b22;
    --card:       #201d25;
    --rule:       #322d3a;
    --rule-2:     #423b4c;

    --ink:        #f2eef3;
    --ink-2:      #cac4d0;
    --ink-3:      #9a93a3;   /* 6.2:1 on dark paper */

    --accent:     #e2937c;   /* 7.7:1 on dark paper */
    --accent-ink: #241a17;
    --accent-sub: #a86e5d;

    --sky:        #253044;
    --sage:       #24301f;
    --blush:      #3b2722;
    --sky-ink:    #b7c9e3;
    --sage-ink:   #b9d3b4;
    --blush-ink:  #f0bfae;

    --code-bg:    #2a2531;
    --term-bg:    #100e13;
    --term-ink:   #ece7ef;
    --term-dim:   #9b93a5;

    --crown:      #e0bb55;   /* 8.9:1 on dark paper */
    --crown-mark: #e0bb55;
    --crown-bg:   #2b2418;
    --crown-rule: #4d4028;

    --shadow:     0 18px 44px -22px rgba(0, 0, 0, .75);
    --shadow-sm:  0 8px 22px -12px rgba(0, 0, 0, .7);

    --wash-1: rgba(58, 78, 110, .30);
    --wash-2: rgba(56, 76, 52, .22);
    --wash-3: rgba(110, 62, 50, .22);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --paper:      #17151a;
  --paper-2:    #1e1b22;
  --card:       #201d25;
  --rule:       #322d3a;
  --rule-2:     #423b4c;

  --ink:        #f2eef3;
  --ink-2:      #cac4d0;
  --ink-3:      #9a93a3;

  --accent:     #e2937c;
  --accent-ink: #241a17;
  --accent-sub: #a86e5d;

  --sky:        #253044;
  --sage:       #24301f;
  --blush:      #3b2722;
  --sky-ink:    #b7c9e3;
  --sage-ink:   #b9d3b4;
  --blush-ink:  #f0bfae;

  --code-bg:    #2a2531;
  --term-bg:    #100e13;
  --term-ink:   #ece7ef;
  --term-dim:   #9b93a5;

  --crown:      #e0bb55;
  --crown-mark: #e0bb55;
  --crown-bg:   #2b2418;
  --crown-rule: #4d4028;

  --shadow:     0 18px 44px -22px rgba(0, 0, 0, .75);
  --shadow-sm:  0 8px 22px -12px rgba(0, 0, 0, .7);

  --wash-1: rgba(58, 78, 110, .30);
  --wash-2: rgba(56, 76, 52, .22);
  --wash-3: rgba(110, 62, 50, .22);
}

/* ─── 2. Base ───────────────────────────────────────────────── */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.68;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background-color .25s var(--ease), color .25s var(--ease);
}

.wash {
  position: absolute;
  inset: 0 0 auto;
  height: 640px;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(60% 70% at 16% 0%,  var(--wash-1), transparent 62%),
    radial-gradient(55% 62% at 86% 4%,  var(--wash-2), transparent 60%),
    radial-gradient(70% 50% at 50% 24%, var(--wash-3), transparent 68%);
}

img { display: block; max-width: 100%; height: auto; }

/* A long unbreakable run in prose, a slash-joined list or a menu path, used to
   push the whole page wider than a phone. Prose should break rather than
   overflow; code keeps its own rules below. */
p, li, dd, dt, td, th, figcaption, blockquote { overflow-wrap: break-word; }

a { color: inherit; }
a:hover { color: var(--accent); }

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 400;
  color: var(--ink);
  margin: 0;
  letter-spacing: -.012em;
}

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

code {
  font-family: var(--mono);
  font-size: .86em;
  background: var(--code-bg);
  border-radius: 5px;
  padding: .1em .38em;
}

.mono { font-family: var(--mono); font-size: .92em; }

::selection { background: var(--sky); color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

main { position: relative; z-index: 1; }

.skip {
  position: fixed;
  top: -100px;
  left: 1rem;
  z-index: 200;
  background: var(--ink);
  color: var(--paper);
  padding: .7rem 1.1rem;
  border-radius: 8px;
  font-size: .9rem;
  text-decoration: none;
  transition: top .2s var(--ease);
}
.skip:focus { top: 1rem; }

/* ─── 3. Header ─────────────────────────────────────────────── */

.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: var(--nav-h);
  padding-block: .8rem;
  padding-inline: max(var(--pad), calc((100% - var(--wide)) / 2 + var(--pad)));
}

.nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color .25s var(--ease), border-color .25s var(--ease);
}

.nav.scrolled::before {
  background: color-mix(in srgb, var(--paper) 82%, transparent);
  border-bottom-color: var(--rule);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

@supports not (backdrop-filter: blur(10px)) {
  .nav.scrolled::before { background: var(--paper); }
}

.nav-brand {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  flex: none;
  white-space: nowrap;
  font-family: var(--serif);
  font-size: 1.12rem;
  color: var(--ink);
  text-decoration: none;
}
.mark { width: 13px; height: 13px; fill: var(--accent); flex: none; }
.nav-brand .mark { transition: transform .2s var(--ease); }
.nav-brand:hover .mark { transform: translateX(2px); }

.nav-links {
  display: flex;
  align-items: center;
  gap: 1.15rem;
  font-size: .92rem;
  min-width: 0;
}

.nav-links a {
  position: relative;
  padding-bottom: 3px;
  color: var(--ink-2);
  text-decoration: none;
  white-space: nowrap;
}

.nav-links a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .25s var(--ease);
}
.nav-links a.active::after,
.nav-links a[aria-current="page"]::after,
.nav-links a:hover::after { transform: scaleX(1); }

.theme-btn {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  transition: color .15s var(--ease), border-color .15s var(--ease);
}
.theme-btn:hover { color: var(--ink); border-color: var(--rule); }
.theme-btn svg { width: 16px; height: 16px; }

@media (max-width: 620px) {
  .nav { flex-wrap: wrap; gap: .35rem 1rem; }
  .nav-links { width: 100%; gap: .95rem; font-size: .86rem; overflow-x: auto; scrollbar-width: none; }
  .nav-links::-webkit-scrollbar { display: none; }
  .theme-btn { margin-left: auto; }
}

/* ─── 4. Hero ───────────────────────────────────────────────── */

.hero {
  position: relative;
  width: 100%;
  max-width: var(--wide);
  margin-inline: auto;
  padding: clamp(2.4rem, 7vw, 4rem) var(--pad) 0;
  text-align: center;
}

.hero h1 { font-size: clamp(2.5rem, 7vw, 3.6rem); }

.tagline {
  font-family: var(--serif);
  font-size: clamp(1.15rem, 3vw, 1.4rem);
  color: var(--ink);
  margin: .5rem 0 1rem;
}

.lede { max-width: 34rem; margin: 0 auto 1.6rem; }

.cta {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: .7rem;
  margin-bottom: .9rem;
}

.meta {
  font-family: var(--mono);
  font-size: .78rem;
  letter-spacing: .02em;
  color: var(--ink-3);
  margin-bottom: 2.2rem;
}

/* ─── 5. Sections ───────────────────────────────────────────── */

.block {
  width: 100%;
  max-width: var(--col);
  margin-inline: auto;
  padding: clamp(2.6rem, 7vw, 4.2rem) var(--pad) 0;
}
.block.wide { max-width: var(--wide); }

section[id] { scroll-margin-top: calc(var(--nav-h) + .6rem); }

h2 {
  font-size: clamp(1.5rem, 3.4vw, 1.85rem);
  margin-bottom: 1.1rem;
  padding-bottom: .55rem;
  border-bottom: 1px solid var(--rule);
}

.section-hint { font-size: .9rem; color: var(--ink-3); }
.section-hint a, .muted a { color: var(--accent); }

/* Feature groups */
.features { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem 2.4rem; }
.feature { border-top: 1px solid var(--rule); padding-top: 1rem; }
.features .feature:nth-child(-n+2) { border-top: 0; padding-top: .2rem; }
.feature h3 { font-size: 1.08rem; margin-bottom: .35rem; }
.feature p { font-size: .95rem; }

@media (max-width: 640px) {
  .features { grid-template-columns: 1fr; }
  .features .feature:nth-child(2) { border-top: 1px solid var(--rule); padding-top: 1rem; }
}

/* Numbered steps */
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.4rem; }
.steps li { display: flex; gap: 1.1rem; align-items: flex-start; }
.steps .n {
  flex: none;
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  font-family: var(--mono);
  font-size: .85rem;
  color: var(--sky-ink);
  background: var(--sky);
  border-radius: 50%;
  margin-top: .15rem;
}
.steps li:nth-child(2) .n { background: var(--sage); color: var(--sage-ink); }
.steps li:nth-child(3) .n { background: var(--blush); color: var(--blush-ink); }
.steps h3 { font-size: 1.06rem; margin-bottom: .2rem; }
.steps p { font-size: .95rem; }

/* Plain honest list, used for non-goals */
.limits { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.limits li { display: flex; gap: .7rem; font-size: .95rem; padding-left: .1rem; }
.limits li::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  margin-top: .62em;
  border-radius: 1px;
  background: var(--rule-2);
}

/* ─── 6. Buttons ────────────────────────────────────────────── */

.btn {
  display: inline-block;
  padding: .62rem 1.25rem;
  border: 1px solid var(--rule-2);
  border-radius: 9px;
  background: var(--card);
  color: var(--ink);
  font-family: inherit;
  font-size: .95rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: transform .15s var(--ease), background-color .15s var(--ease),
              color .15s var(--ease), border-color .15s var(--ease);
}
.btn:hover { transform: translateY(-1px); border-color: var(--ink-3); color: var(--ink); }
.btn:active { transform: none; }

.btn-primary { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.btn-primary:hover { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.btn-small { padding: .34rem .8rem; font-size: .85rem; }

/* ─── 7. Frames (screenshots) ───────────────────────────────── */

.frame {
  margin: 0;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: var(--shadow);
}

.hero .frame { max-width: 880px; margin-inline: auto; }

.frame-bar {
  display: flex;
  gap: 6px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
}
.frame-bar i { width: 10px; height: 10px; border-radius: 50%; background: var(--rule-2); }
.frame-bar i:nth-child(1) { background: #d99a8a; }
.frame-bar i:nth-child(2) { background: #d9c48a; }
.frame-bar i:nth-child(3) { background: #a7c4a0; }

.frame figcaption {
  padding: .7rem 1rem .8rem;
  font-size: .88rem;
  color: var(--ink-3);
  border-top: 1px solid var(--rule);
}

.gallery { display: grid; gap: 1.8rem; }

/* Theme gallery: the ten real app themes */
/* Smaller cards than the screenshot grid above, deliberately. Ten pictures of
   the same window at the same size as the seven that each show something
   different reads as ten times the information, and it is one thing shown ten
   ways. */
.theme-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(11.5rem, 100%), 1fr));
  gap: .9rem;
  margin-top: 1.2rem;
}
.theme-card {
  margin: 0;
  border: 1px solid var(--rule);
  border-radius: 10px;
  overflow: hidden;
  background: var(--card);
  box-shadow: var(--shadow-sm);
}
.theme-card .zoomable { cursor: zoom-in; }
.theme-card img { width: 100%; }
.theme-card figcaption {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .6rem;
  padding: .55rem .75rem .65rem;
  border-top: 1px solid var(--rule);
  font-size: .86rem;
  color: var(--ink);
}
.theme-card .mood { color: var(--ink-3); font-size: .8rem; text-align: right; }

/* Screenshots of the app itself. Two up rather than the theme grid's four,
   because these are read rather than glanced at: the point is the content of
   the screen, not the colour of it. Below 52rem they stack, since a 1600px
   screenshot at half a phone's width shows nothing at all. */
.shot-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(26rem, 100%), 1fr));
  gap: 1.4rem;
  margin-top: 1.2rem;
}
.shot-card {
  margin: 0;
  border: 1px solid var(--rule);
  border-radius: 10px;
  overflow: hidden;
  background: var(--card);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
}
.shot-card .zoomable { cursor: zoom-in; }
.shot-card img { width: 100%; height: auto; display: block; }
.shot-card figcaption {
  padding: .7rem .85rem .85rem;
  border-top: 1px solid var(--rule);
  flex: 1;
}
.shot-name {
  display: block;
  font-size: .95rem;
  color: var(--ink);
  margin-bottom: .2rem;
}
.shot-note {
  display: block;
  font-size: .84rem;
  line-height: 1.5;
  color: var(--ink-2);
}

/* ─── 8. Comparison table ───────────────────────────────────── */

.compare-wrap {
  overflow-x: auto;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--card);
}

.compare {
  width: 100%;
  /* Below this the cells wrap to two or three words each and the table stops
     being readable, so it scrolls inside .compare-wrap instead. */
  min-width: 34rem;
  border-collapse: collapse;
  font-size: .93rem;
}
.compare caption {
  text-align: left;
  padding: .7rem .9rem .1rem;
  font-size: .86rem;
  color: var(--ink-3);
}
.compare th, .compare td {
  padding: .65rem .9rem;
  text-align: left;
  border-bottom: 1px solid var(--rule);
}
.compare thead th {
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 500;
  background: var(--paper-2);
}
.compare tbody th { font-weight: 500; color: var(--ink); width: 28%; }
.compare tbody tr:last-child th,
.compare tbody tr:last-child td { border-bottom: 0; }
.compare td { color: var(--ink-2); }
.compare td:nth-child(2) { color: var(--ink); font-weight: 500; background: var(--sage); }

/* ─── 9. FAQ ────────────────────────────────────────────────── */

.faq details { border-top: 1px solid var(--rule); }
.faq details:last-child { border-bottom: 1px solid var(--rule); }
.faq summary {
  list-style: none;
  cursor: pointer;
  padding: .9rem 2rem .9rem 0;
  font-family: var(--serif);
  font-size: 1.06rem;
  color: var(--ink);
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  position: absolute;
  right: .2rem;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--mono);
  color: var(--ink-3);
  transition: transform .2s var(--ease), color .2s var(--ease);
}
.faq details[open] summary::after { transform: translateY(-50%) rotate(45deg); color: var(--accent); }
.faq summary:hover::after { color: var(--accent); }
.faq-a { padding: 0 0 1rem; font-size: .95rem; }

/* ─── 10. Terminal ──────────────────────────────────────────── */

.terminal {
  margin-top: 1.6rem;
  background: var(--term-bg);
  border: 1px solid var(--rule);
  border-radius: 10px;
  overflow: hidden;
}
.terminal-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0;
  padding: .55rem .7rem .55rem 1rem;
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--term-dim);
  border-bottom: 1px solid rgba(255, 255, 255, .09);
}
.terminal pre { margin: 0; padding: .9rem 1rem 1rem; overflow-x: auto; }
.terminal code {
  background: none;
  padding: 0;
  font-size: .84rem;
  line-height: 1.8;
  color: var(--term-ink);
}
.terminal .dim { color: var(--term-dim); }
.terminal pre:focus-visible { outline-offset: -3px; }

.copy-btn {
  flex: none;
  border: 1px solid rgba(255, 255, 255, .22);
  background: transparent;
  color: var(--term-dim);
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  border-radius: 6px;
  padding: .25rem .6rem;
  cursor: pointer;
  transition: color .15s var(--ease), border-color .15s var(--ease);
}
.copy-btn:hover { color: #fff; border-color: rgba(255, 255, 255, .5); }

/* ─── 11. Live status card ──────────────────────────────────── */

.status-card {
  margin-top: 1.6rem;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: 1rem 1.2rem 1.1rem;
}

.status-head { display: flex; align-items: center; gap: .55rem; margin-bottom: .9rem; }
.status-head h3 { font-size: 1.02rem; flex: 1; }
.status-link {
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-3);
  text-decoration: none;
}
.status-link:hover { color: var(--accent); }

.live-dot {
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 50%;
  background: var(--sage-ink);
  animation: live-pulse 2.4s var(--ease) infinite;
}
@keyframes live-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--sage-ink) 45%, transparent); }
  70%  { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

.status-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(7.5rem, 100%), 1fr));
  gap: .9rem 1.2rem;
  margin: 0;
}
.status-grid dt {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: .15rem;
}
.status-grid dd { margin: 0; font-size: 1.02rem; color: var(--ink); font-weight: 500; }

.status-note { margin-top: .9rem; font-size: .88rem; color: var(--ink-3); }

/* ─── 12. Demo host ─────────────────────────────────────────── */
/* The replica's own styling lives in demo.css; this is just its slot. */

.demo-host { margin-top: 1.4rem; }
.demo-hint { margin-top: .75rem; font-size: .88rem; color: var(--ink-3); text-align: center; }

/* ─── 13. Dialog (screenshot viewer) ────────────────────────── */

dialog.lightbox {
  width: min(1200px, 92vw);
  max-height: 92vh;
  padding: 0;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--ink-2);
  overflow: visible;
}
dialog.lightbox::backdrop {
  background: rgba(20, 18, 23, .82);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
dialog.lightbox figure { margin: 0; }
dialog.lightbox img {
  width: 100%;
  max-height: 78vh;
  object-fit: contain;
  border-radius: 10px;
  background: var(--card);
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, .6);
}
dialog.lightbox figcaption {
  padding-top: .75rem;
  text-align: center;
  font-size: .9rem;
  color: #d6d0dc;
}
.lightbox-bar {
  position: absolute;
  top: -3rem;
  right: 0;
  display: flex;
  align-items: center;
  gap: .4rem;
}
.lightbox-count {
  font-family: var(--mono);
  font-size: .75rem;
  color: #d6d0dc;
  margin-right: .4rem;
}
.lightbox-btn {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .14);
  color: #fff;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  transition: background-color .15s var(--ease);
}
.lightbox-btn:hover { background: rgba(255, 255, 255, .28); }
.lightbox-btn svg { width: 16px; height: 16px; }

.zoomable { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }

/* ─── 14. Footer ────────────────────────────────────────────── */

.footer {
  position: relative;
  z-index: 1;
  max-width: var(--col);
  margin: clamp(3rem, 8vw, 4.6rem) auto 0;
  padding: 1.6rem var(--pad) 2.4rem;
  border-top: 1px solid var(--rule);
  text-align: center;
  font-size: .9rem;
  color: var(--ink-3);
}
.footer a { color: var(--ink-2); }
.footer a:hover { color: var(--accent); }

/* Footer links sit on their own rather than inside a sentence, so they need a
   real touch target. Inline padding would collide with the neighbouring link,
   so the height comes from the block axis only. */
.foot-links a {
  display: inline-block;
  padding-block: .35rem;
  min-height: 24px;
}
.dogfood { margin-top: .5rem; font-size: .85rem; font-style: italic; }
.made-by { margin-top: .4rem; }

/* ─── 15. Utilities ─────────────────────────────────────────── */

.to-top {
  position: fixed;
  right: 1.2rem;
  bottom: 1.2rem;
  z-index: 90;
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border: 1px solid var(--rule-2);
  border-radius: 50%;
  background: var(--card);
  color: var(--ink-2);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity .25s var(--ease), transform .25s var(--ease),
              visibility .25s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.to-top.show { opacity: 1; visibility: visible; transform: none; }
.to-top:hover { color: var(--accent); border-color: var(--accent); }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The hidden attribute means hidden, whatever display a rule below gives the
   element. Without this, every new component that is revealed by script needs
   its own `[hidden] { display: none }` line, and the one that gets forgotten
   ships a search box that is visible before its script has said it works.
   The two rules that used to do this one element at a time are gone. */
[hidden] { display: none !important; }

/* ─── 16. Motion ────────────────────────────────────────────── */

/* Content is visible by default. The hide-then-fade is opted into only
   once site.js confirms it is running, and it force-reveals after 1.5s. */
/* The checksum list used to be styled twice, from two different designs. The
   dead half is gone: it dressed the block as a dark terminal, and it set
   grid-template-columns: auto minmax(0, 1fr), which the live rule further down
   did not override. With one checksum published that looked fine, and the day
   a release published three it laid them out in two columns and folded
   "Windows installer" into a vertical column of single letters. The live rule
   is beside .verify-cmd, where the rest of this block is styled.
   .verify-file went with it: nothing produces that element any more. */


.js-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .55s var(--ease), transform .55s var(--ease);
}
.js-reveal [data-reveal].in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js-reveal [data-reveal] { opacity: 1; transform: none; transition: none; }
  .live-dot { animation: none; }
  .nav::before, .to-top, .btn, .theme-btn, body { transition: none; }
  .nav-links a::after, .nav-brand .mark { transition: none; }
}

/* Print used to be four lines here. It is now section 20, at the very end of
   this file, because a print rule has to come after the rule it overrides and
   half of what needed overriding is defined below this line. */

/* ───────────────────────────────────────────────────────────────
   17. Pocket-console layer

   The app took a retro-handheld turn in 1.3.0: moulded-plastic
   shading on the controls, a power-LED that breathes, and two
   pocket-console themes. The site borrows the same vocabulary
   (the same easing, the same press, the same shading), so the two
   read as one product. It is an inflection of the warm paper,
   not a costume over it.
   ─────────────────────────────────────────────────────────────── */

:root { --ease-pop: cubic-bezier(.2, .7, .3, 1); }

/* Pocket: the DMG screen, as a full site theme. */
:root[data-theme="pocket"] {
  color-scheme: light;

  --paper:      #c6d29c;
  --paper-2:    #b7c48c;
  --card:       #d5dfb1;
  --rule:       #9aa96f;
  --rule-2:     #8c9c62;

  --ink:        #16240c;
  --ink-2:      #2d3f16;
  --ink-3:      #46551f;

  --accent:     #2c5a2e;
  --accent-ink: #e7f0c8;
  --accent-sub: #4a7a44;

  --sky:        #b9c9a4;
  --sage:       #b4c188;
  --blush:      #cbc79a;
  --sky-ink:    #24361a;
  --sage-ink:   #2a601c;
  --blush-ink:  #5a4a12;

  --code-bg:    #b9c690;
  --term-bg:    #16240c;
  --term-ink:   #c6d29c;
  --term-dim:   #8ba065;

  /* The console's screen has no gold in it, so VIP borrows the amber the
     handheld does have rather than importing a colour from another theme. */
  --crown:      #5a4a12;   /* 6.3:1 on the pocket paper */
  --crown-mark: #7a6410;
  --crown-bg:   #cbc79a;
  --crown-rule: #a39558;

  --shadow:     0 14px 34px -20px rgba(22, 36, 12, .5);
  --shadow-sm:  0 7px 18px -10px rgba(22, 36, 12, .45);

  --wash-1: rgba(154, 169, 111, .45);
  --wash-2: rgba(120, 140, 80, .35);
  --wash-3: rgba(180, 193, 136, .35);

  --sans: var(--mono);
}

/* Moulded-plastic shading, applied to every theme so the retro
   flavour blends with the original design rather than replacing it.
   Same values the app uses. */
.btn, .theme-btn, .to-top, .copy-btn, .lightbox-btn {
  box-shadow: inset 0 -1.5px 0 rgba(0, 0, 0, .10), inset 0 1px 0 rgba(255, 255, 255, .16);
}
.btn-primary {
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .20), inset 0 1px 0 rgba(255, 255, 255, .22);
}
.to-top { box-shadow: var(--shadow-sm), inset 0 -1.5px 0 rgba(0, 0, 0, .10), inset 0 1px 0 rgba(255, 255, 255, .16); }
.steps .n { box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .07), inset 0 1px 0 rgba(255, 255, 255, .3); }

/* The frame chrome reads as a screen bezel rather than a browser bar. */
.frame-bar { box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .06); }

@media (prefers-reduced-motion: no-preference) {
  /* One press, everywhere something is pressable. */
  .btn:active, .theme-btn:active, .to-top:active,
  .copy-btn:active, .lightbox-btn:active, .zoomable:active {
    transform: translateY(1px) scale(.985);
  }
  .btn { transition: transform .12s var(--ease-pop), background-color .15s var(--ease),
                     color .15s var(--ease), border-color .15s var(--ease), box-shadow .15s var(--ease); }
  .theme-btn, .to-top, .copy-btn, .lightbox-btn, .zoomable {
    transition: transform .12s var(--ease-pop), color .15s var(--ease),
                border-color .15s var(--ease), background-color .15s var(--ease);
  }

  /* Rows lean toward the pointer, the way the app's project list does. */
  .theme-card { transition: transform .16s var(--ease-pop), box-shadow .16s var(--ease); }
  .theme-card:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
  .faq summary { transition: color .15s var(--ease); }
  .faq details[open] .faq-a { animation: rise .22s var(--ease-pop); }

  /* The reveal uses the app's rise, so scrolling feels like the app. */
  .js-reveal [data-reveal] { transition: opacity .5s var(--ease-pop), transform .5s var(--ease-pop); }

  /* Status dot breathes like a power LED instead of pinging. */
  .live-dot { animation: breathe 2.6s ease-in-out infinite; }
}

@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@keyframes breathe {
  0%, 100% { box-shadow: 0 0 4px var(--sage-ink); opacity: 1; }
  50%      { box-shadow: 0 0 9px var(--sage-ink); opacity: .82; }
}

@media (prefers-reduced-motion: reduce) {
  .theme-card, .faq details[open] .faq-a { transition: none; animation: none; }
}

/* A download that has not been built yet: visible, clearly inert, never a
   link that goes nowhere. */
.btn-unavailable {
  opacity: .5;
  cursor: not-allowed;
  box-shadow: none;
}
.btn-unavailable:hover { transform: none; border-color: var(--rule-2); color: var(--ink); }

/* Shown beside a download only when the two platforms are on different
   versions, so the page never claims a build is newer than it is. */
.dl-version-note {
  align-self: center;
  margin-left: -.35rem;
  font-family: var(--mono);
  font-size: .78rem;
  color: var(--ink-3);
  white-space: nowrap;
}

/* 404 */
.not-found { text-align: center; padding-top: clamp(3rem, 12vh, 6rem); }
.not-found h1 { font-size: clamp(3rem, 10vw, 4.5rem); margin-bottom: .4rem; }
.not-found .section-hint { margin-bottom: 1.6rem; }

.themes-note { margin-top: 1rem; }

/* ─── Download verification ─────────────────────────────────── */

.verify {
  margin-top: 1.2rem;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--card);
}
.verify summary {
  list-style: none;
  cursor: pointer;
  padding: .7rem 1rem;
  font-size: .93rem;
  color: var(--ink);
  position: relative;
}
.verify summary::-webkit-details-marker { display: none; }
.verify summary::after {
  content: "+";
  position: absolute; right: 1rem; top: 50%;
  transform: translateY(-50%);
  font-family: var(--mono);
  color: var(--ink-3);
}
.verify[open] summary::after { content: "\2212"; }
.verify-body { padding: 0 1rem 1rem; font-size: .93rem; }
.verify-cmd { display: flex; align-items: baseline; gap: .7rem; margin: .4rem 0; }
.verify-os {
  flex: none; width: 4.5rem;
  font-family: var(--mono); font-size: .72rem;
  letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3);
}
.verify-sums { margin: .9rem 0; display: grid; gap: .6rem; }
.verify-sums dt {
  font-family: var(--mono); font-size: .68rem;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3);
  margin-bottom: .1rem;
}
.verify-sums dd {
  margin: 0;
  font-family: var(--mono); font-size: .74rem;
  color: var(--ink);
  overflow-wrap: anywhere;
  user-select: all;
}

/* ─── Coming soon: one quiet line, never a banner ───────────── */

.soon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: .55rem .9rem;
  margin: -1.4rem 0 2.2rem;
  font-size: .82rem;
  color: var(--ink-3);
}
.soon-item { display: inline-flex; align-items: center; gap: .38rem; }
.soon-icon { width: 13px; height: 13px; fill: var(--ink-3); flex: none; }
/* The crown is the one gold thing on the page, so it stays small. It reads
   from the same token the pricing page uses, so VIP looks identical in both. */
.soon-crown { fill: var(--crown-mark); }
.soon-tag {
  font-family: var(--mono);
  font-size: .64rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: .1rem .45rem;
}
.soon-sep { width: 1px; height: .85rem; background: var(--rule); }
@media (max-width: 480px) { .soon-sep { display: none; } }

/* ─── Ambient background ────────────────────────────────────── */
/* Sits behind everything, ignores the pointer, and never affects layout. */
.ambient {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 0;
  pointer-events: none;
  user-select: none;
}
@media (prefers-reduced-motion: reduce) { .ambient { display: none; } }
@media print { .ambient { display: none; } }

/* ─── First-launch warning dialog ───────────────────────────── */

dialog.gk {
  width: min(640px, 92vw);
  max-height: 88vh;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: var(--card);
  color: var(--ink-2);
  box-shadow: var(--shadow);
  overflow: auto;
}
dialog.gk::backdrop {
  background: rgba(20, 18, 23, .62);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.gk-inner { position: relative; padding: 1.6rem clamp(1.2rem, 4vw, 2rem) 1.5rem; }

.gk-close {
  position: absolute;
  top: .7rem;
  right: .8rem;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-3);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.gk-close:hover { background: var(--paper-2); color: var(--ink); }

.gk-eyebrow {
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--sage-ink);
  margin: 0 0 .3rem;
}
dialog.gk h2 { font-size: 1.35rem; margin-bottom: .7rem; }
.gk-lead { font-size: .95rem; }

.gk-quote {
  margin: .9rem 0 1.1rem;
  padding: .7rem .9rem;
  border-left: 3px solid var(--rule-2);
  background: var(--paper-2);
  border-radius: 0 8px 8px 0;
  font-size: .92rem;
  color: var(--ink);
  font-style: italic;
}

.gk-steps section + section { margin-top: 1.1rem; }
.gk-steps h3 { font-size: 1rem; margin-bottom: .35rem; }
.gk-steps ol { margin: .3rem 0 0; padding-left: 1.3rem; font-size: .93rem; }
.gk-steps li { margin-bottom: .35rem; }
.gk-note { font-size: .86rem; color: var(--ink-3); margin: .2rem 0 .4rem; }

.gk-once {
  margin: 1.1rem 0 0;
  padding: .65rem .85rem;
  border-radius: 8px;
  background: var(--sage);
  color: var(--sage-ink);
  font-size: .9rem;
}

.gk-more { margin-top: .8rem; border-top: 1px solid var(--rule); }
.gk-more summary {
  list-style: none;
  cursor: pointer;
  padding: .6rem 0 .5rem;
  font-size: .9rem;
  color: var(--ink);
  position: relative;
}
.gk-more summary::-webkit-details-marker { display: none; }
.gk-more summary::after {
  content: "+";
  position: absolute; right: .1rem; top: 50%;
  transform: translateY(-50%);
  font-family: var(--mono);
  color: var(--ink-3);
}
.gk-more[open] summary::after { content: "\2212"; }
.gk-more > div { padding-bottom: .7rem; font-size: .9rem; }
.gk-cmd { margin: .45rem 0; }
.gk-cmd code {
  display: block;
  padding: .5rem .7rem;
  background: var(--code-bg);
  border-radius: 7px;
  font-size: .8rem;
  overflow-x: auto;
  user-select: all;
}

.gk-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  margin-top: 1.3rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
}

@media (prefers-reduced-motion: no-preference) {
  dialog.gk[open] { animation: rise .22s var(--ease-pop); }
}

/* ───────────────────────────────────────────────────────────────
   18. Two audiences

   The landing page has to serve someone who has never run a
   server and someone who wants to read the security posture
   before downloading. Rather than averaging them into one bland
   voice, the page forks: a pair of route cards near the top, and
   a spec sheet further down that the second reader is sent
   straight to. Both use the same paper; only the density changes.
   ─────────────────────────────────────────────────────────────── */

/* A small mono label above a heading, for sections that need one. */
.eyebrow {
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 .4rem;
}

/* ─── Route cards ───────────────────────────────────────────── */

.routes { padding-top: clamp(1.6rem, 4vw, 2.4rem); }

.route-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr));
  gap: 1rem;
}

.route {
  border: 1px solid var(--rule);
  border-radius: 12px;
  background: var(--card);
  padding: 1.15rem 1.3rem 1.25rem;
  box-shadow: var(--shadow-sm);
}

.route-kicker {
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--ink-3);
  margin: 0 0 .45rem;
}
.route-kicker code { font-size: .95em; background: none; padding: 0; }

.route h3 { font-size: 1.14rem; margin-bottom: .45rem; }
.route p { font-size: .94rem; }

.route-links {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem .55rem;
  margin: .9rem 0 0;
  font-size: .88rem;
}
.route-links a { color: var(--accent); text-decoration: none; }
.route-links a:hover { text-decoration: underline; }
.route-links span { color: var(--rule-2); }

/* ─── Demo section ──────────────────────────────────────────── */

.demo-section h2 { margin-bottom: .8rem; }
.demo-lede { max-width: 46rem; }

/* ─── Spec sheet (internals) ────────────────────────────────── */

.spec-lede { max-width: 46rem; margin-bottom: 1.6rem; }

.spec-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr));
  gap: 1.4rem 2.4rem;
}

.spec { min-width: 0; }
.spec h3 {
  font-size: 1.02rem;
  padding-bottom: .4rem;
  margin-bottom: .8rem;
  border-bottom: 1px solid var(--rule);
}

/* Term on its own line in mono, definition beneath: a reference layout,
   which is the register this section is written in. */
.spec-list { margin: 0; display: grid; gap: .85rem; }
.spec-list > div { min-width: 0; }
.spec-list dt {
  font-family: var(--mono);
  font-size: .71rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: .18rem;
}
.spec-list dd {
  margin: 0;
  font-size: .91rem;
  line-height: 1.6;
  color: var(--ink-2);
}
.spec-list dd code { font-size: .84em; }

.spec-foot { margin-top: 1.6rem; }

/* ─── Comparison: grouped, including the losing group ───────── */

.compare-lede { max-width: 46rem; margin-bottom: 1rem; }

/* Specificity has to beat `.compare tbody th`, which sets the full ink
   colour every other row header wants. */
.compare tbody th.compare-group {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  font-weight: 500;
  /* ink-2, not ink-3: at this size ink-3 on paper-2 falls to 4.4:1 in the
     pocket theme, just under AA. */
  color: var(--ink-2);
  background: var(--paper-2);
}

/* The win highlight belongs only to rows Local Test actually wins, so the
   second group drops it rather than colouring a loss green. */
.compare-losses td:nth-child(2) {
  background: none;
  font-weight: 400;
  color: var(--ink-2);
}

/* ─── Pricing ───────────────────────────────────────────────── */

.plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr));
  gap: 1.2rem;
  margin-top: 1.6rem;
  align-items: start;
}

.plan {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: var(--card);
  padding: 1.4rem 1.4rem 1.5rem;
  box-shadow: var(--shadow-sm);
}

.plan-vip { border-color: var(--crown-rule); }

.plan-head { display: flex; align-items: center; gap: .5rem; margin-bottom: .2rem; }
.plan-head h3 {
  font-size: 1.3rem;
  margin: 0;
  padding: 0;
  border: 0;
}
.plan-crown { width: 17px; height: 17px; fill: var(--crown-mark); flex: none; }

.plan-for { font-size: .9rem; color: var(--ink-3); margin: 0 0 1rem; }

.plan-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .5rem;
  margin: 0 0 .3rem;
  font-family: var(--serif);
  font-size: 2.1rem;
  color: var(--ink);
  line-height: 1.15;
}
.plan-price .unit {
  font-family: var(--sans);
  font-size: .88rem;
  color: var(--ink-3);
}

/* A price that is not decided yet says so in the price slot. Putting a
   number here that later changes would be the one unrecoverable lie on
   the page, so the placeholder is deliberately not number-shaped. */
.price-tbd {
  font-family: var(--sans);
  font-size: 1.5rem;
  color: var(--ink-2);
}
.plan-price-note {
  font-size: .82rem;
  color: var(--ink-3);
  margin: 0 0 1.1rem;
  min-height: 1.2em;
}

.plan-cta { margin: 0 0 1.2rem; }
.plan-cta .btn { width: 100%; text-align: center; }

.btn-crown {
  background: var(--crown-bg);
  border-color: var(--crown-rule);
  color: var(--crown);
}
.btn-crown:hover { border-color: var(--crown); color: var(--crown); }

/* Not wired to a checkout yet: visibly a button, audibly disabled, and
   never a link that goes nowhere. */
.btn[aria-disabled="true"] { cursor: not-allowed; }

.plan-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.plan-list li {
  display: flex;
  gap: .6rem;
  align-items: flex-start;
  font-size: .92rem;
}
.plan-list svg {
  flex: none;
  width: 15px;
  height: 15px;
  margin-top: .3em;
  stroke: var(--sage-ink);
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.plan-list .plan-no svg { stroke: var(--ink-3); }
.plan-list .plan-no { color: var(--ink-3); }

.plan-foot {
  margin-top: 1.1rem;
  padding-top: .9rem;
  border-top: 1px solid var(--rule);
  font-size: .86rem;
  color: var(--ink-3);
}

/* Everything both tiers share, stated once so neither column has to
   repeat it and neither looks artificially thin. */
.plan-shared {
  margin-top: 1.4rem;
  border: 1px solid var(--rule);
  border-radius: 12px;
  background: var(--paper-2);
  padding: 1.1rem 1.3rem 1.2rem;
}
.plan-shared h3 { font-size: 1.02rem; margin-bottom: .5rem; }
.plan-shared ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
  gap: .35rem 1.4rem;
  font-size: .91rem;
}
.plan-shared li { display: flex; gap: .5rem; }
.plan-shared li::before {
  content: "";
  flex: none;
  width: 5px;
  height: 5px;
  margin-top: .66em;
  border-radius: 50%;
  background: var(--rule-2);
}

.pricing-head { text-align: center; }
.pricing-head .lede { margin-inline: auto; }

/* A CTA row inside a left-aligned section, rather than the centred hero. */
.cta-start { justify-content: flex-start; }

/* ───────────────────────────────────────────────────────────────
   19. Minecraft, price, and the download warning

   Three blocks added when the homepage stopped being able to
   describe the app honestly without them. Nothing here invents a
   colour: every value is a token from section 1, so all four themes
   and the print sheet below get these for free.
   ─────────────────────────────────────────────────────────────── */

/* ─── Minecraft ─────────────────────────────────────────────── */

.mc-lede { font-size: .97rem; color: var(--ink-2); margin-bottom: 1.4rem; max-width: 46rem; }

.mc-table {
  width: 100%;
  /* Under this the four columns wrap to two words each, so it scrolls inside
     .compare-wrap instead of turning into a column of fragments. */
  min-width: 32rem;
  border-collapse: collapse;
  font-size: .93rem;
}
.mc-table caption {
  text-align: left;
  padding: .7rem .9rem .1rem;
  font-size: .86rem;
  color: var(--ink-3);
}
.mc-table th, .mc-table td {
  padding: .62rem .9rem;
  text-align: left;
  border-bottom: 1px solid var(--rule);
}
.mc-table thead th {
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 500;
  background: var(--paper-2);
}
.mc-table tbody th { font-weight: 500; color: var(--ink); width: 22%; }
.mc-table td { color: var(--ink-2); }
/* The column that carries the whole point of the table: which of these is a
   download and which is twenty minutes of compiling. */
.mc-table td.def { color: var(--ink); font-weight: 500; }
.mc-table tbody tr:last-child th,
.mc-table tbody tr:last-child td { border-bottom: 0; }

.mc-caption { margin-top: .7rem; max-width: 46rem; }

.mc-notes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem 2.4rem;
  margin-top: 2rem;
}
.mc-note { border-top: 1px solid var(--rule); padding-top: 1rem; }
.mc-note:nth-child(-n+2) { border-top: 0; padding-top: .2rem; }
.mc-note h3 { font-size: 1.08rem; margin-bottom: .4rem; }
.mc-note p { font-size: .95rem; }
.mc-note p + p { margin-top: .6rem; }

/* A sentence the app itself prints. Set apart so it reads as a quotation from
   the software rather than as this page's own prose, which is the distinction
   the whole data-says="app" convention exists to keep. */
.mc-note .mono,
.mc-rest .mono {
  font-family: var(--mono);
  font-size: .84rem;
  color: var(--ink);
  background: var(--code-bg);
  border-radius: 4px;
  padding: .08rem .3rem;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

.mc-rest {
  margin-top: 1.8rem;
  padding: 1rem 1.2rem;
  border: 1px solid var(--rule);
  border-radius: 12px;
  background: var(--paper-2);
  font-size: .93rem;
  color: var(--ink-2);
}
.mc-cta { justify-content: flex-start; margin-top: 1.4rem; }

@media (max-width: 640px) {
  .mc-notes { grid-template-columns: 1fr; }
  .mc-note:nth-child(2) { border-top: 1px solid var(--rule); padding-top: 1rem; }
}

/* ─── What it costs ─────────────────────────────────────────── */

.price-lede { font-size: 1.02rem; color: var(--ink); max-width: 42rem; }

.price-facts {
  list-style: none;
  margin: 1.3rem 0 0;
  padding: 0;
  display: grid;
  gap: .8rem;
}
.price-facts li {
  font-size: .95rem;
  color: var(--ink-2);
  padding-left: 1.15rem;
  position: relative;
}
/* A tick would be a claim about goodness. This is a plain marker: these are
   facts about an arrangement, not a feature list selling one. */
.price-facts li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .58em;
  width: 6px;
  height: 6px;
  border-radius: 1px;
  background: var(--accent-sub);
}
.price-facts strong { color: var(--ink); }

.price-foot {
  margin-top: 1.3rem;
  font-size: .9rem;
  color: var(--ink-3);
  max-width: 42rem;
}
.price-foot a { color: var(--accent); }

/* ─── The warning that has to arrive first ──────────────────── */

.dl-heads-up {
  margin: 1.3rem 0 1.6rem;
  padding: 1rem 1.2rem 1.1rem;
  border: 1px solid var(--rule-2);
  border-left: 3px solid var(--accent-sub);
  border-radius: 10px;
  background: var(--paper-2);
}
.dl-heads-up h3 { font-size: 1.04rem; margin-bottom: .45rem; }
.dl-heads-up p { font-size: .93rem; color: var(--ink-2); }
.dl-heads-up p + p { margin-top: .6rem; }
.dl-heads-up a { color: var(--accent); }
.dl-heads-up-steps { display: grid; gap: .4rem; }
.dl-heads-up-steps strong { color: var(--ink); }

.dl-platform-note { margin-top: .6rem; }

/* ─── The verify commands ───────────────────────────────────── */

.verify-cmds { display: grid; gap: .5rem; margin: .8rem 0 .6rem; }
.verify-cmds .verify-cmd {
  display: flex;
  align-items: center;
  gap: .7rem;
  margin: 0;
  padding: .5rem .6rem;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--paper-2);
}
.verify-cmds .verify-cmd code {
  flex: 1 1 auto;
  min-width: 0;
  font-size: .78rem;
  /* The whole command has to be visible to be trusted, and it is long. It
     wraps rather than scrolling: a command with its tail hidden off the right
     edge is one somebody copies without having read. */
  overflow-wrap: anywhere;
  background: none;
  padding: 0;
}
.copy-btn { flex: none; align-self: flex-start; }
.verify-shell-note { margin-top: .1rem; }

@media (max-width: 560px) {
  .verify-cmds .verify-cmd { flex-wrap: wrap; }
  .verify-cmds .verify-os { width: auto; }
  .copy-btn { margin-left: auto; }
}

/* ───────────────────────────────────────────────────────────────
   20. Print

   The docs are the page somebody prints or saves as a PDF, and doing
   that used to produce the navigation, the footer links, a demo of an
   app window that does nothing on paper, and, if the reader happened
   to be in dark mode, forty pages of dark grey.

   Two rules govern everything below.

   First, print is not a theme. The tokens are redefined here for
   every theme at once, so a dark-mode reader and a light-mode reader
   print the identical document. Overriding `body { color }` alone
   would not do it: half the page reads its colour from a token.

   Second, ink is expensive and paper does not scroll. Anything that
   exists to be clicked, hovered or watched is removed, anything that
   scrolls sideways is unwrapped, and a link that has gone from being
   clickable to being a piece of text gets its address printed beside
   it so it is still followable.
   ─────────────────────────────────────────────────────────────── */

@media print {
  /* Every theme prints as the light one. The selectors match the four ways a
     theme can be set (default, chosen, and system dark), and print wins by
     coming last rather than by !important.

     The system-dark one has to be spelled out, and was not. That palette is
     set by `:root:not([data-theme="light"])` inside a prefers-color-scheme
     query, which outranks a bare `:root` on specificity, and coming last
     cannot rescue a selector that has already lost on specificity. A reader
     whose system is dark and who has never touched the theme button is the
     default case rather than an edge one, so without this line they are
     precisely the person who prints the dark palette. Chromium reports
     prefers-color-scheme as light while printing, which hid it; that is one
     browser's choice and not a thing to rely on. Repeating the query's own
     selector makes the two rules equal, and then source order is enough. */
  :root,
  :root:not([data-theme="light"]),
  :root[data-theme="light"],
  :root[data-theme="dark"],
  :root[data-theme="pocket"] {
    color-scheme: light;

    --paper:      #ffffff;
    --paper-2:    #f6f5f3;
    --card:       #ffffff;
    --rule:       #cfcbc4;
    --rule-2:     #b4afa6;

    --ink:        #000000;
    --ink-2:      #1a1a1a;
    --ink-3:      #3d3d3d;   /* light grey vanishes on paper */

    --accent:     #6b3a2c;
    --accent-ink: #ffffff;
    --accent-sub: #6b3a2c;

    --sky:        #eef2f8;
    --sage:       #eef4ed;
    --blush:      #fbf1ee;
    --sky-ink:    #1a1a1a;
    --sage-ink:   #1a1a1a;
    --blush-ink:  #1a1a1a;

    --code-bg:    #f2f0ec;
    --term-bg:    #f2f0ec;
    --term-ink:   #000000;
    --term-dim:   #3d3d3d;

    --crown:      #4a3608;
    --crown-mark: #4a3608;
    --crown-bg:   #f8f5ec;
    --crown-rule: #cfcbc4;

    --shadow:     none;
    --shadow-sm:  none;

    --wash-1: transparent;
    --wash-2: transparent;
    --wash-3: transparent;
  }

  @page { margin: 18mm 16mm; }

  html { scroll-behavior: auto; }
  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
    line-height: 1.5;
  }

  /* Furniture: everything whose only purpose is to be operated. The demo is a
     replica of an app window that cannot be pressed on paper, and the ambient
     canvas is a decoration that would print as a grey rectangle. */
  .nav,
  .to-top,
  .theme-btn,
  .wash,
  .skip,
  .ambient,
  .demo-section,
  .lt-demo,
  .copy-btn,
  [data-copy],
  dialog,
  .footer .foot-links,
  .gk,
  .lightbox { display: none !important; }

  /* The reveal animation hides things until a script says otherwise. A printer
     is not going to wait for an IntersectionObserver, and a page printed from a
     tab that never scrolled would otherwise come out blank. */
  .js-reveal [data-reveal],
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  /* Nothing scrolls on paper: a table or a code block inside an overflow box
     prints exactly as much as fits and silently drops the rest. */
  .compare-wrap,
  .table-wrap,
  .code,
  .doc-body pre,
  .verify-body { overflow: visible !important; max-height: none !important; }

  .block, .doc { max-width: none; padding-inline: 0; }

  /* A closed <details> prints as its summary and nothing else, so the FAQ
     answers and the checksums would be missing from the printout with nothing
     to say they had been left out. CSS cannot open one: every engine hides the
     contents from inside its own shadow tree, where an author rule cannot
     reach. site.js opens them all on beforeprint instead, and puts back
     exactly the ones that were open before. This is only the styling for once
     they are. */
  details { display: block; }
  details > summary { list-style: none; font-weight: 600; }
  .faq summary::after, .verify summary::after { display: none; }

  /* A link on paper is a piece of text. Print where it went, except for the
     in-page ones, where "#minecraft" beside the words helps nobody. */
  .doc-body a[href^="http"]::after,
  .faq a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-family: var(--mono);
    font-size: .82em;
    color: #3d3d3d;
    word-break: break-all;
  }

  /* Keep a heading with what it introduces, and never split a code block, a
     table row or a screenshot across a page break. */
  h1, h2, h3, h4 { break-after: avoid-page; page-break-after: avoid; }
  .code, pre, figure, tr, .callout, .mc-note, .price-facts li {
    break-inside: avoid-page;
    page-break-inside: avoid;
  }
  section { break-before: auto; }

  img, .frame { box-shadow: none; border-color: #cfcbc4; }
  /* Twelve full-width screenshots of an app is not what somebody printing the
     documentation is after, and it is most of the toner. */
  .theme-grid, .shot-grid { display: none; }

  /* The table of contents is a list of links to a document the reader is
     holding. Kept, because the section names are a useful map, but not as a
     column of underlined blue. */
  .toc { border: 1px solid #cfcbc4; break-inside: avoid-page; }
  .toc a { text-decoration: none; color: #000; }

  .footer { border-top: 1px solid #cfcbc4; }
}
