/* One stylesheet for five pages. No build step, no framework, no fonts to fetch:
   the whole site is legal text and one link handler, and it should load on a phone
   with two bars of signal in the middle of a conversation. */
/* Taken from the app icon rather than invented: deep navy ground, parchment continents, and the
   coral/teal the timeline dots use. The app's own UI is near-black on white with a #A6424E brand
   accent. That is the reading surface, and this is the cover. */
:root {
  --bg: #f4ede0;
  --surface: #fffdf8;
  --ink: #16283d;
  --ink-soft: #5c6b7d;
  --rule: #ddd0b8;
  --accent: #b8452f;
  --navy: #12314f;
  --navy-deep: #0d2340;
  --parchment: #e8dcc4;
  --coral: #e2725b;
  --teal: #4a9aa8;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0d2340;
    --surface: #14304c;
    --ink: #eee5d4;
    --ink-soft: #9fb0c2;
    --rule: #24425f;
    --accent: #e89b7f;
  }
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* The hidden attribute must win over the display rules below it, or the waitlist row (display:
   flex) and its label stay on screen after a signup the script has just hidden them for. */
[hidden] { display: none !important; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: Georgia, "Iowan Old Style", "Times New Roman", serif;
  font-size: 17px;
  line-height: 1.65;
  margin: 0;
  padding: 0 20px 72px;
}
.wrap { margin: 0 auto; max-width: 44rem; }
header { border-bottom: 1px solid var(--rule); padding: 40px 0 20px; margin-bottom: 40px; }
header a.brand {
  color: var(--ink); font-size: 1.35rem; font-weight: 600; letter-spacing: 0.01em;
  text-decoration: none;
}
header .tag { color: var(--ink-soft); font-size: 0.95rem; margin-top: 2px; }
/* Type scale. h3 used to be 1rem (16px) against a 17px body, so a subheading rendered SMALLER than
   the paragraph under it and carried the hierarchy on weight alone. Every step is now a real step.
   Vertical rhythm runs on one scale: ~54px between sections, ~30px between subsections, and the
   space below a heading is roughly a fifth of the space above it, so a heading sits with the text
   it introduces rather than floating between two blocks. */
h1 { font-size: 2rem; line-height: 1.22; margin: 0 0 8px; }
h2 { font-size: 1.35rem; line-height: 1.3; margin: 2.6em 0 0.55em; }
h3 { font-size: 1.1rem; line-height: 1.35; margin: 1.9em 0 0.35em; }
.updated { color: var(--ink-soft); font-size: 0.9rem; margin: 0 0 2.6em; }
a { color: var(--accent); }
ul, ol { padding-left: 1.3em; }
li { margin: 0.5em 0; }
code { background: var(--surface); border: 1px solid var(--rule); border-radius: 3px;
       font-size: 0.86em; padding: 1px 5px; }
table { border-collapse: collapse; display: block; overflow-x: auto; width: 100%; }
th, td { border-bottom: 1px solid var(--rule); padding: 12px 14px 12px 0; text-align: left;
         vertical-align: top; font-size: 0.95rem; }
/* A three-column table of dense legal text does not fit the reading measure: the middle column ends
   up six lines deep while the prose around it sits comfortably. Tables break the measure on a wide
   screen for the same reason the pricing grid does, and by the same amount, so the two line up.
   The explicit width is needed because width:100% resolves against .wrap, so negative margins alone
   would not widen it. */
@media (min-width: 900px) {
  .wrap table { margin-inline: -4rem; width: calc(100% + 8rem); }
}
th { color: var(--ink-soft); font-weight: 600; }
.card { background: var(--surface); border: 1px solid var(--rule); border-radius: 10px;
        margin: 1.9em 0; padding: 22px 24px; }
.card p:first-child { margin-top: 0; }
.card p:last-child { margin-bottom: 0; }
footer { border-top: 1px solid var(--rule); color: var(--ink-soft); font-size: 0.9rem;
         margin-top: 72px; padding-top: 22px; }
footer a { margin-right: 14px; }
.cta { background: var(--accent); border-radius: 9px; color: var(--bg); display: inline-block;
       font-family: -apple-system, system-ui, sans-serif; font-size: 1rem; font-weight: 600;
       margin: 6px 0; padding: 12px 22px; text-decoration: none; }
.muted { color: var(--ink-soft); font-size: 0.92rem; }

/* ---------------------------------------------------------------------------
   Landing page only. The legal pages stay plain text on a plain ground. This
   is the one page that has to say what the app IS before anyone will care.
   --------------------------------------------------------------------------- */
.hero {
  /* flex-start, not center: centring pinned the icon to the middle of a tall text column, which put
     it 165px below the headline it is supposed to sit beside. The 5px nudge is optical, lining the
     icon's top edge up with the cap height of the h1 rather than with its line box. */
  align-items: flex-start;
  border-bottom: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 34px;
  padding: 52px 0 56px;
}
.hero-icon {
  border-radius: 22px;
  margin-top: 5px;
  box-shadow: 0 10px 30px rgba(13, 35, 64, 0.22);
  flex: 0 0 auto;
  height: 128px;
  width: 128px;
}
.hero-copy { flex: 1 1 320px; min-width: 280px; }
.hero h1 { font-size: 2.35rem; letter-spacing: -0.015em; margin: 0 0 14px; }
.lede { font-size: 1.12rem; line-height: 1.6; margin: 0 0 26px; }
.status {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 999px;
  color: var(--ink-soft);
  display: inline-block;
  font-family: -apple-system, system-ui, sans-serif;
  font-size: 0.82rem;
  padding: 6px 14px;
}

/* The launch waitlist. The app cannot be downloaded yet, so this is the home page's only real
   call to action; it sits directly under the "coming soon" pill so the promise and the way to
   hold us to it read as one thing. */
.waitlist { margin: 26px 0 0; max-width: 26rem; }
.waitlist label[for="waitlist-email"] {
  color: var(--ink-soft);
  display: block;
  font-size: 0.92rem;
  margin-bottom: 7px;
}
.waitlist-row { display: flex; flex-wrap: wrap; gap: 8px; }
.waitlist input[type="email"] {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 9px;
  color: var(--ink);
  flex: 1 1 12rem;
  font: inherit;
  font-size: 0.95rem;
  min-width: 0;
  padding: 9px 12px;
}
.waitlist input[type="email"]:focus-visible {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.waitlist button { border: 0; cursor: pointer; font: inherit; font-size: 0.95rem; padding: 9px 18px; }
.waitlist button[disabled] { cursor: default; opacity: 0.55; }
.waitlist-note { color: var(--ink-soft); font-size: 0.85rem; margin: 9px 0 0; }
.waitlist-said { font-size: 0.9rem; margin: 9px 0 0; }
.waitlist-said:empty { display: none; }
.waitlist-said.is-ok { color: var(--ink); font-weight: 600; }
.waitlist-said.is-bad { color: var(--accent); }
/* Off-screen rather than display:none — some bots skip what is not rendered at all. */
.waitlist-hp {
  height: 0;
  left: -9999px;
  overflow: hidden;
  position: absolute;
  width: 0;
}

/* The reader, drawn rather than screenshotted. It is a diagram of how the app works and is
   labelled as one. A mocked-up "screenshot" of an app nobody can download yet would be a
   picture of something that does not exist. */
.figure { margin: 52px 0 10px; }
.figure svg { display: block; height: auto; width: 100%; }
/* The popup that confirms a waitlist signup. The inline line under the form says the same thing,
   but it is small and sits where the eye has already left; this is the part you cannot miss. It is
   visual only (aria-hidden): the inline line is the live region, so a screen reader hears the
   result once, not twice. */
.toast {
  align-items: flex-start; animation: toast-in 220ms ease-out; background: var(--ink);
  border-radius: 12px; bottom: 20px; box-shadow: 0 10px 28px rgba(13, 35, 64, 0.28); color: var(--bg);
  display: flex; gap: 14px; left: 50%; max-width: min(26rem, calc(100% - 32px)); padding: 14px 16px;
  position: fixed; transform: translateX(-50%); z-index: 20;
}
.toast p { margin: 0; }
.toast b { display: block; font-size: 1rem; }
.toast span { display: block; font-size: 0.88rem; margin-top: 2px; opacity: 0.85; }
.toast.is-bad { background: var(--accent); color: #fff; }
.toast button {
  background: none; border: 0; color: inherit; cursor: pointer; font: inherit; font-size: 1.35rem;
  line-height: 1; margin: -4px -6px 0 auto; opacity: 0.8; padding: 4px 6px;
}
.toast button:hover { opacity: 1; }
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 10px); } to { opacity: 1; transform: translate(-50%, 0); } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }

.figcaption { color: var(--ink-soft); font-size: 0.88rem; margin-top: 10px; text-align: center; }

/* Three tiers do not fit the 44rem reading column: (704 - 36) / 3 is 223px a card, which is under
   the old 240px floor, so auto-fit silently dropped to a 2 + 1 layout. Pricing does not need the
   reading measure, so it breaks out wider when the viewport can take it and stacks when it cannot.
   The 900px threshold is where -4rem each side still clears the body padding without overflowing:
   at 900px the content box is 860px, .wrap is 704px centred, and 64px of the 78px margin is used. */
.tiers { display: grid; gap: 22px; grid-template-columns: 1fr; }
@media (min-width: 900px) {
  .tiers { grid-template-columns: repeat(3, 1fr); margin-inline: -4rem; }
}
/* Vertical padding stays generous; horizontal comes back in, because at three columns every px of
   side padding is taken straight out of a 262px measure and the price lines start wrapping to three
   ragged lines. */
.tier { background: var(--surface); border: 1px solid var(--rule); border-radius: 12px; padding: 24px 22px; }
.tier.plus { border-color: var(--accent); }
.tier h3 { margin: 0 0 4px; }
.tier .price { color: var(--ink-soft); font-size: 0.92rem; margin: 0 0 12px; }
/* The Plus tier carries two prices. The monthly one tightens up so the annual line reads as part of
   the same block rather than as the first bullet, and the annual takes the accent because saving
   20% is the thing worth noticing. */
.tier .price.has-annual { margin-bottom: 3px; }
/* The annual line is muted everywhere except the headline tier. With three cards, an accent on
   every annual price makes them compete and nothing leads. */
.tier .price-annual { color: var(--ink-soft); font-size: 0.92rem; font-weight: 600; margin: 0 0 12px; }
.tier.plus .price-annual { color: var(--accent); }
.tier ul { margin: 0; padding-left: 1.15em; }
.tier li { font-size: 0.95rem; }

/* The library sampler: ten real storylines as chips, so breadth is shown by names rather than
   claimed by adjectives. The same pill as .status, because it is the same kind of object: a small
   true thing about the app. The date is set in the system face so it reads as a label, not prose. */
.sampler { display: flex; flex-wrap: wrap; gap: 9px 11px; list-style: none; margin: 26px 0 30px; padding: 0; }
.sampler li {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-size: 0.9rem;
  line-height: 1.35;
  margin: 0;
  padding: 6px 13px;
}
.sampler span {
  color: var(--ink-soft);
  font-family: -apple-system, system-ui, sans-serif;
  font-size: 0.78rem;
  margin-left: 6px;
  white-space: nowrap;
}
/* On a phone the titles wrap and ten full-width pills read as ten buttons that do nothing. A plain
   ruled list is the honest shape there: a table of contents, not a control panel. */
@media (max-width: 640px) {
  .sampler { display: block; margin: 14px 0 20px; }
  .sampler li {
    background: none; border: 0; border-bottom: 1px solid var(--rule); border-radius: 0;
    padding: 7px 0;
  }
  .sampler li:last-child { border-bottom: 0; }
}

/* Real screenshots, from a Release build against prod. Three phones abreast on a wide screen and a
   snap-scroller on a narrow one, never shrunk past the point where the app's own text is readable,
   which is the only reason to show a screenshot rather than describe it. */
/* Four shots. Four across inside the 44rem reading column would be 159px a phone, which is not a
   screenshot any more, so the row breaks the measure by the SAME 4rem the tables and the pricing
   grid do: three broken-out blocks on one page should share an edge rather than each pick a width.
   That gives 832px, so a shot renders at 191px against the 220px it had at three across.
   Between 640 and 900px there is not room for four, and two rows of two at 341px reads better than
   four cramped ones; below 640px the snap-scroller below takes over and handles any number. */
.shots { display: grid; gap: 22px; grid-template-columns: repeat(2, 1fr); margin: 52px 0 8px; }
@media (min-width: 900px) {
  .shots { grid-template-columns: repeat(4, 1fr); margin-inline: -4rem; }
}
.shot figure { margin: 0; }
.shot img {
  border: 1px solid var(--rule);
  border-radius: 14px;
  box-shadow: 0 8px 22px rgba(13, 35, 64, 0.14);
  display: block;
  /* height:auto is not optional next to width:100%. Without it the HTML height attribute is taken
     literally and the shot is stretched to that many pixels tall. Which is exactly what happened. */
  height: auto;
  width: 100%;
}
.shot figcaption { color: var(--ink-soft); font-size: 0.88rem; line-height: 1.45; margin-top: 10px; }
.shot b { color: var(--ink); font-weight: 600; }
@media (max-width: 640px) {
  .shots {
    grid-auto-columns: 76%; grid-auto-flow: column; grid-template-columns: none;
    overflow-x: auto; padding-bottom: 10px; scroll-snap-type: x mandatory;
  }
  .shot { scroll-snap-align: start; }
}

/* ---------------------------------------------------------------------------
   Shared story page (functions/s/[id].js). A page from a book laid on the atlas:
   the title over a faint graticule, chapter one set for reading, then what the app
   holds for the rest. System sans for labels only, the serif for everything read.
   --------------------------------------------------------------------------- */
.story-page .wrap { max-width: 40rem; }
.site-top { align-items: center; display: flex; gap: 12px; justify-content: space-between;
            margin-bottom: 0; padding: 22px 0 16px; }
.site-top a.brand { align-items: center; display: inline-flex; font-size: 1.12rem; gap: 10px; }
.site-top a.brand img { border-radius: 7px; display: block; }
.site-top .tag { font-family: -apple-system, system-ui, sans-serif; font-size: 0.74rem;
                 letter-spacing: 0.1em; margin: 0; text-align: right; text-transform: uppercase; }

.story-hero { border-bottom: 0; isolation: isolate; margin: 0; padding: 46px 0 36px;
              position: relative; text-align: center; }
/* The graticule the app draws under its sea, faded out toward the edges so it reads as texture. */
.story-hero::before {
  background-image: linear-gradient(var(--rule) 1px, transparent 1px),
                    linear-gradient(90deg, var(--rule) 1px, transparent 1px);
  background-position: center;
  background-size: 44px 44px;
  content: "";
  inset: 0;
  -webkit-mask-image: radial-gradient(ellipse at center, #000 20%, transparent 72%);
  mask-image: radial-gradient(ellipse at center, #000 20%, transparent 72%);
  opacity: 0.55;
  position: absolute;
  z-index: -1;
}
.kicker { color: var(--accent); font-family: -apple-system, system-ui, sans-serif; font-size: 0.76rem;
          font-weight: 600; letter-spacing: 0.16em; margin: 0 0 14px; text-transform: uppercase; }
.story-hero h1 { font-size: clamp(1.9rem, 6.4vw, 2.6rem); letter-spacing: -0.015em; line-height: 1.14;
                 margin: 0 auto 16px; max-width: 34rem; text-wrap: balance; }
.story-hero .lede { color: var(--ink-soft); font-size: 1.07rem; margin: 0 auto 24px; max-width: 33rem; }
.story-meta { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; list-style: none;
              margin: 0; padding: 0; }
.story-meta li { align-items: center; background: var(--surface); border: 1px solid var(--rule);
                 border-radius: 999px; color: var(--ink-soft); display: inline-flex;
                 font-family: -apple-system, system-ui, sans-serif; font-size: 0.8rem; gap: 6px;
                 margin: 0; padding: 5px 12px 5px 9px; }
.story-meta svg { fill: none; flex: none; height: 15px; stroke: currentColor; stroke-linecap: round;
                  stroke-linejoin: round; stroke-width: 1.8; width: 15px; }

/* A double rule, like the edge of an atlas plate, opens the chapter. */
.chapter { border-top: 3px double var(--rule); padding-top: 38px; }
.chapter-label { color: var(--accent); font-family: -apple-system, system-ui, sans-serif; font-size: 0.74rem;
                 font-weight: 600; letter-spacing: 0.18em; margin: 0 0 8px; text-align: center;
                 text-transform: uppercase; }
.chapter h2 { font-size: 1.6rem; line-height: 1.25; margin: 0 0 8px; text-align: center; text-wrap: balance; }
.chapter-setting { color: var(--ink-soft); font-style: italic; margin: 0 0 32px; text-align: center; }
/* No automatic hyphenation: on a phone's narrow measure it broke a word on nearly every other line. */
.chapter-body p { font-size: 1.08rem; line-height: 1.75; margin: 0 0 1.15em; }
.chapter-body p.first::first-letter { color: var(--accent); float: left; font-size: 3.5em; font-weight: 600;
                                      line-height: 0.82; margin: 7px 10px 0 0; }
/* Illustrations run to the screen edge on a phone and a little past the text column on a wide one.
   The wide bleed waits for 820px so the column has room for it and the page never scrolls sideways. */
.chapter-figure { margin: 32px -20px; }
@media (min-width: 820px) { .chapter-figure { margin: 36px -3rem; } }
.chapter-figure img { background: var(--parchment); display: block; height: auto; max-height: 72vh;
                      object-fit: contain; width: 100%; }
@media (min-width: 820px) { .chapter-figure img { border-radius: 6px; } }
.chapter-figure figcaption { color: var(--ink-soft); font-size: 0.86rem; line-height: 1.5; margin-top: 10px;
                             padding: 0 20px; }
@media (min-width: 820px) { .chapter-figure figcaption { padding: 0 3rem; } }
.chapter-figure .caption { display: block; }
.chapter-figure .credit { display: block; font-family: -apple-system, system-ui, sans-serif; font-size: 0.74rem;
                          margin-top: 4px; }
.chapter-figure .credit a { color: inherit; }

.continues { margin-top: 52px; }
.continues h2 { font-size: 1.3rem; margin: 0 0 16px; text-align: center; }
.toc { background: var(--surface); border: 1px solid var(--rule); border-radius: 12px; list-style: none;
       margin: 0 0 22px; padding: 4px 0; }
.toc li { align-items: baseline; border-bottom: 1px solid var(--rule); display: flex; gap: 14px; margin: 0;
          padding: 12px 20px; }
.toc li:last-child { border-bottom: 0; }
.toc-n { color: var(--accent); flex: 0 0 1.5em; font-family: -apple-system, system-ui, sans-serif;
         font-size: 0.8rem; font-variant-numeric: tabular-nums; font-weight: 600; text-align: right; }

/* The app, on the icon's own navy, so it reads as the cover of the thing the page is from. */
.app-cta { background: var(--navy); border: 1px solid var(--rule); border-radius: 14px; color: #eee5d4;
           padding: 28px 24px; text-align: center; }
.app-cta-title { font-size: 1.25rem; font-weight: 600; margin: 0 0 8px; }
.app-cta-body { color: #c9d3de; font-size: 0.98rem; margin: 0 auto 18px; max-width: 30rem; }
.app-cta .status { background: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.2); color: #eee5d4; }
.app-cta .cta { background: var(--coral); color: var(--navy-deep); }
.app-cta .muted { color: #9fb0c2; margin: 16px 0 0; }
.app-cta a:not(.cta) { color: #f0a58f; }
.disclaimer { margin-top: 36px; text-align: center; }
.story-miss { padding: 36px 0 0; }
/* The waitlist inside the navy box: the home page's form, recoloured for the dark ground. */
.app-cta .waitlist { margin: 0 auto; max-width: 25rem; text-align: left; }
/* On a phone the button wraps under the field; centred, it reads as the form's end, not a stray. */
.app-cta .waitlist-row { justify-content: center; }
.app-cta .waitlist label[for="waitlist-email"] { color: #c9d3de; text-align: center; }
.app-cta .waitlist input[type="email"] { background: #fffdf8; border-color: transparent; color: #16283d; }
.app-cta .waitlist input[type="email"]:focus-visible { border-color: var(--coral); outline-color: var(--coral); }
.app-cta .waitlist-note { color: #9fb0c2; text-align: center; }
/* The way from a shared story to what Cartalore is: the home page, at the end of the app box. */
.app-cta-more { border-top: 1px solid rgba(255, 255, 255, 0.14); margin: 20px 0 0; padding-top: 18px; }
.app-cta-more a { font-family: -apple-system, system-ui, sans-serif; font-size: 0.95rem; font-weight: 600;
                  text-decoration: none; }
.app-cta-more a:hover, .app-cta-more a:focus-visible { text-decoration: underline; }
/* Five other library stories, each its own share page: somewhere to go after this one. */
.more-stories { margin-top: 44px; }
.more-stories h2 { font-size: 1.3rem; margin: 0 0 16px; text-align: center; }
.more-list { list-style: none; margin: 0; padding: 0; }
.more-list li { border-top: 1px solid var(--rule); margin: 0; }
.more-list li:last-child { border-bottom: 1px solid var(--rule); }
.more-list a { align-items: baseline; color: var(--ink); display: flex; gap: 14px; justify-content: space-between;
               padding: 14px 2px; text-decoration: none; }
.more-list a:hover span:first-child, .more-list a:focus-visible span:first-child { color: var(--accent);
               text-decoration: underline; }
.more-arrow { color: var(--accent); flex: none; font-family: -apple-system, system-ui, sans-serif; }
