/* The site, in the app's own design.
   src/index.css is the source of truth — claymorphism is fiffy's design
   language and not one of its themes, so the site is the same material as
   the app rather than a page that resembles it. Copied rather than
   imported because the site ships no build step and no framework; if they
   drift, the app wins, and site/test/site.test.mjs fails rather than
   letting them.

   The light palette here is the app's Clay colourway, which is what the
   app opens in. */
:root {
  --bg-primary: #fdfbff;
  --bg-secondary: #f5f1ff;
  --bg-raised: #ffffff;
  /* The app's own panel, and the reason the cards below can be seen at
     all: #ffffff on #fdfbff is 1.028:1 — the same colour, to the eye —
     so every card on this page was an invisible rectangle holding text.
     On this warm near-white a white card is 1.087:1, which is the
     separation the app's own panel was chosen to give, and it still
     clears the desk at 2.017:1. Matches src/index.css. */
  --bg-panel: #fdf3f6;
  /* THE FOUR TINTS, from the app's dashboard tiles (.dash-tile-* in
     src/index.css) — hand-chosen literals there, not generated output,
     so copying them is reading a decision rather than duplicating a
     derivation. One hue per card, so the quartet reads as four things.
     Nothing accent-coloured may go on these: they sit at luminance
     0.795-0.840 and --accent needs 0.8822. No card here holds a link;
     if one ever does, it takes the deep ink instead. */
  --tint-keys: #e0eeda;
  --tint-keeps-going: #fbe0e6;
  --tint-memory: #fbead1;
  --tint-tells-you: #dcecfa;
  /* The surface the page lies on, as the app's shell lies on a desk. */
  --bg-desk: #b7a4f0;
  --text-primary: #2d2255;
  --text-secondary: #62568c;
  /* No hairlines. Separation is surface and elevation, as in the app. */
  --border: transparent;
  --accent: #6c4dff;
  --accent-hover: #421aff;
  --accent-contrast: #ffffff;
  --radius: 14px;
  --radius-card: 26px;
  --radius-pill: 999px;
  --measure: 34rem;
  --app-font: ui-rounded, "SF Pro Rounded", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* THE RECIPE, the app's own: a preset says what its clay is made of and
     the shapes are spent from that one ink. See src/index.css. */
  --depth-ink: 84 58 160;
  --depth-rim: 255 255 255;
  --depth-ink-strength: 1;
  --depth-rim-strength: 1;
  --lift:
    0 16px 32px -16px rgb(var(--depth-ink) / calc(0.42 * var(--depth-ink-strength))),
    0 4px 10px -6px rgb(var(--depth-ink) / calc(0.18 * var(--depth-ink-strength))),
    inset 0 2px 0 rgb(var(--depth-rim) / calc(0.95 * var(--depth-rim-strength))),
    inset 0 -3px 6px -3px rgb(var(--depth-ink) / calc(0.14 * var(--depth-ink-strength)));
  --lift-control:
    0 8px 16px -9px rgb(var(--depth-ink) / calc(0.40 * var(--depth-ink-strength))),
    inset 0 2px 0 rgb(var(--depth-rim) / calc(0.45 * var(--depth-rim-strength))),
    inset 0 -4px 7px -3px rgb(var(--depth-ink) / calc(0.20 * var(--depth-ink-strength)));
  --lift-inset:
    inset 0 3px 7px -2px rgb(var(--depth-ink) / calc(0.22 * var(--depth-ink-strength))),
    inset 0 -1px 0 rgb(var(--depth-rim) / calc(0.95 * var(--depth-rim-strength)));
  --wall: 0 4px 0 rgb(var(--depth-ink) / calc(0.20 * var(--depth-ink-strength)));
  --wall-pressed: 0 1px 0 rgb(var(--depth-ink) / calc(0.20 * var(--depth-ink-strength)));
  --press-drop: 3px;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg-primary: #14101a;
    --bg-secondary: #1b1524;
    --bg-raised: #221a2d;
    --bg-desk: #0d0a13;
    --text-primary: #f6eef8;
    --text-secondary: #b9a5c2;
    --border: #35283f;
    --accent: #ff3ea5;
    --accent-hover: #ff6bb8;
    --accent-contrast: #14101a;
    /* Black ink and the rim almost off, exactly as the app's dark
       colourways do it: a bright top edge on an ink page is a scratch
       rather than a highlight. */
    --depth-ink: 0 0 0;
    --depth-ink-strength: 1.5;
    --depth-rim-strength: 0.1;
    /* NO TINTS IN THE DARK. The four above are fitted to one canvas —
       the app's light colourway, which is the only one the app has — and
       a #e0eeda card under #f6eef8 text is 1.1:1, i.e. unreadable.
       Inventing four dark tints would mean inventing a canvas this
       product does not have and measuring it nowhere, so the cards stay
       raised surfaces here and the quartet is a light-mode idea. */
    --bg-panel: #1b1524;
    --tint-keys: var(--bg-raised);
    --tint-keeps-going: var(--bg-raised);
    --tint-memory: var(--bg-raised);
    --tint-tells-you: var(--bg-raised);
  }
}

/* A line break chosen for a wide screen, dropped on a narrow one. The
   headline breaks as "Ten AI agents, one window, / your own keys." on a
   desktop; on a phone that same break leaves the word "window," alone on a
   line of its own, which reads as a typo. Below this width the text wraps
   where it wants to.

   The space before the <br> in the markup is load-bearing: hiding a <br>
   removes the break and puts nothing in its place, so without it the two
   halves run together as "window,your". A trailing space before a line
   break is collapsed away when the break IS shown, so it costs nothing. */
br.wide-only { display: none; }
@media (min-width: 34rem) { br.wide-only { display: inline; } }

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

body {
  margin: 0;
  font-family: var(--app-font);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--text-primary);
  background: var(--bg-desk);
  -webkit-text-size-adjust: 100%;
}

/* A 16px gutter on a phone, and never a horizontal scroll. */
/* The page as an object on the desk — the same move the app's shell
   makes, and every page is one <div class="wrap"> holding header, main
   and footer, so the wrap IS the card. */
.wrap {
  /* width: min(), NOT max-width. A max-width cannot make a gutter: once
     the viewport is narrower than 58rem the card is simply full-width,
     so from 34rem (where the full-bleed phone rule below stops) up to
     928px it sat flush against both edges with its 26px corners sliced
     off by the viewport. Measured at 768px before this line: left gap
     0, right gap 0. Every page shares this rule, so it was all eight. */
  width: min(58rem, calc(100% - 2.5rem));
  margin: 1.25rem auto 2.5rem;
  padding: 0 1.75rem 1.75rem;
  background: var(--bg-panel);
  border-radius: var(--radius-card);
  box-shadow: var(--lift);
}
/* On a phone the desk is a frame around a card narrower than the text
   inside it, which wastes the only width there is. The card goes
   full-bleed and keeps the 16px gutter the comment above promised. */
@media (max-width: 34rem) {
  .wrap {
    /* width back to full, or the min() above survives into here: the
       card keeps its 2.5rem of gutter while `margin: 0` pins it left,
       so the page is flush on the left and 40px short on the right.
       Measured at 375px before this line: left 0, right 40. */
    width: 100%;
    margin: 0;
    padding: 0 1rem 1.5rem;
    border-radius: 0;
    box-shadow: none;
    min-height: 100dvh;
  }
}

header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.25rem 0;
  flex-wrap: wrap;
}
/* font-size is load-bearing here even though .brand holds no text any
   more: the wordmark is sized in em, so it tracks the header the way the
   typeset name used to. */
.brand { display: flex; align-items: center; gap: 0.55rem; font-size: 1.15rem; text-decoration: none; color: inherit; }
.brand img { width: 2rem; height: 2rem; }
/* The drawn logotype. currentColor, so it follows .brand's inherited text
   colour into the dark palette exactly as the typeset name did — which is
   the reason it is inline in the markup and not one more <img>. Width is
   left to the viewBox so the aspect ratio cannot be set wrong here. */
.wordmark { height: 1.45em; width: auto; display: block; }
nav { display: flex; gap: 1.25rem; flex-wrap: wrap; }
nav a { color: var(--text-secondary); text-decoration: none; }
nav a:hover { color: var(--text-primary); }

h1 { font-size: clamp(2rem, 6vw, 3rem); line-height: 1.15; letter-spacing: -0.02em; margin: 2rem 0 0.75rem; }
h2 { font-size: 1.5rem; margin: 2.5rem 0 0.5rem; letter-spacing: -0.01em; }
h3 { font-size: 1.1rem; margin: 1.75rem 0 0.25rem; }
p, li { max-width: var(--measure); }
.lead { font-size: 1.25rem; color: var(--text-secondary); max-width: var(--measure); }

.actions { display: flex; gap: 0.75rem; flex-wrap: wrap; margin: 1.75rem 0 0.5rem; }
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  /* 44px, Apple's minimum target and a real review finding. */
  min-height: 44px;
  padding: 0 1.15rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--accent-contrast);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  /* A slab with a side, not a rectangle wearing a shadow — and it
     travels by exactly what its wall shrinks, so the base stays put. */
  box-shadow: var(--lift-control), var(--wall);
}
.btn:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn:active { transform: translateY(var(--press-drop)); box-shadow: var(--lift-control), var(--wall-pressed); }
.btn-quiet { background: var(--bg-raised); color: var(--text-primary); border-color: var(--border); }
.btn-quiet:hover { background: var(--bg-secondary); }

.note { color: var(--text-secondary); font-size: 0.95rem; }

/* TWO COLUMNS, NOT auto-fit. There are four cards, and auto-fit with a
   15rem floor resolves to THREE at the width this page actually has —
   measured at 1280px: "280px 280px 280px", with the fourth card's top at
   1003 while the others sat at 596. Three features and an afterthought,
   and the afterthought was remote notifications, which is the one on the
   list people pay for.
   
   A fixed 1 -> 2 is right rather than clever here because the count is
   known and even. /brand has two cards and is unaffected either way. */
.cards { display: grid; gap: 1rem; grid-template-columns: 1fr; margin: 1.5rem 0; }
@media (min-width: 46rem) { .cards { grid-template-columns: 1fr 1fr; } }
/* THE PRODUCT SHOT. A photograph of the running app, taken in a real
   WKWebView by scripts/build-hero-shot.ts — which is also where the
   reasons for all three of those words are written.

   NO SHADOW AND NO RADIUS OF ITS OWN. The picture already has them:
   its own edge is the app's --bg-desk, and the two slabs inside it are
   rounded and lifted off that desk. A card drawn around it would be a
   second frame around a frame. What it needs instead is to sit on the
   panel as a block of colour, and --bg-desk on --bg-panel is 2.02:1,
   which is the same separation the app relies on for the same reason.

   WIDTH AND HEIGHT ARE ON THE <img>, so the space is reserved before
   the file arrives; a 400kB image reflowing the whole page on arrival
   is the one thing a hero image must not do. */
.shot { margin: 1.75rem 0 2rem; }
.shot img { display: block; width: 100%; height: auto; border-radius: var(--radius-card); }
.shot figcaption {
  margin-top: 0.75rem;
  color: var(--text-secondary);
  font-size: 0.95rem;
  max-width: var(--measure);
}
.card { background: var(--card-tint, var(--bg-raised)); border: 1px solid var(--border); border-radius: var(--radius-card); padding: 1.4rem 1.5rem; box-shadow: var(--lift); }
/* One hue per card. Set here rather than inline because the CSP is
   `style-src 'self'` with no 'unsafe-inline' (site/constants.js), so a
   style attribute on each card would simply not paint. */
.card-keys { --card-tint: var(--tint-keys); }
.card-keeps-going { --card-tint: var(--tint-keeps-going); }
.card-memory { --card-tint: var(--tint-memory); }
.card-tells-you { --card-tint: var(--tint-tells-you); }
.card h3 { margin-top: 0; }
.card p { margin-bottom: 0; }

.price { display: flex; align-items: baseline; gap: 0.4rem; margin: 0.5rem 0 0; }
.price .amount { font-size: 2.5rem; font-weight: 700; letter-spacing: -0.02em; }
.price .per { color: var(--text-secondary); }

table { border-collapse: collapse; margin: 1rem 0; width: 100%; max-width: var(--measure); }
th, td { text-align: left; padding: 0.5rem 0.75rem 0.5rem 0; border-bottom: 1px solid var(--border); vertical-align: top; }
th { font-weight: 600; }

code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.9em; background: var(--bg-secondary); padding: 0.1em 0.35em; border-radius: 6px; box-shadow: var(--lift-inset); }

footer { border-top: 1px solid var(--border); margin-top: 4rem; padding: 1.5rem 0 3rem; color: var(--text-secondary); font-size: 0.95rem; }
footer nav { gap: 1rem; }
footer a { color: var(--text-secondary); }

a { color: var(--accent); }
a:focus-visible, .btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.legal { padding-bottom: 2rem; }
.legal p, .legal li { max-width: 40rem; }
.legal .updated { color: var(--text-secondary); font-size: 0.95rem; }
