
@import url('https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&display=swap');

:root {
  color-scheme: light only;

  --paper:      #fff1e5;   /* page background — cream */
  --surface:    #fffaf3;   /* warm card / input material */
  --surface-2:  #f6ede1;   /* warm inset / off-white */
  --ink:        #1a1412;   /* body text — warm dark stone */
  --ink-2:      #5a4e4a;   /* secondary text */
  --ink-3:      #9e8d81;   /* muted / captions */
  --line:       #e2d4c8;   /* warm stone border */
  --line-2:     #efe7dc;
  --accent:     #0d7680;   /* FT teal */
  --accent-ink: #0a5e66;   /* darker teal for text/links */
  --accent-soft:rgba(13,118,128,.10);
  --amber:      #b5651d;   /* annotation / secret key / signal */
  --amber-ink:  #97530f;
  --amber-soft: rgba(181,101,29,.12);
  --green:      #2f7d5b;   /* success / data */
  --green-soft: rgba(47,125,91,.12);
  --red:        #a4362f;   /* destructive — delete, and nothing else */
  --red-ink:    #8c2a24;
  --red-soft:   rgba(164,54,47,.10);

  --radius:   12px;
  --radius-s: 8px;
  --radius-l: 16px;
  --shadow:   0 1px 2px rgba(60,40,30,.05), 0 10px 30px -18px rgba(60,40,30,.20);
  --shadow-lg:0 2px 4px rgba(60,40,30,.06), 0 34px 70px -34px rgba(60,40,30,.30);

  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --sans: 'EB Garamond', Georgia, 'Times New Roman', serif;   /* serif body — editorial voice */
  --label: Georgia, 'Times New Roman', serif;                 /* small-caps labels */

  --stage-pad: clamp(1rem, 4vw, 3rem);
}

* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  font-family: var(--sans);
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  line-height: 1.6;
}
a { color: inherit; }
button { font-family: inherit; }
::selection { background: rgba(13,118,128,.16); }

/* ---------- shared bits ---------- */
.wordmark { display: inline-flex; align-items: center; gap: .5rem; text-decoration: none; color: var(--ink); }
.wordmark svg { width: 26px; height: 26px; display: block; }
.wordmark b { font-family: var(--sans); font-weight: 600; font-size: 1.06rem; letter-spacing: -.005em; }
.wordmark b span { color: var(--accent); }

.pill {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--label); font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-2);
  border: 1px solid var(--line); border-radius: 999px; padding: .3rem .65rem;
  background: var(--surface);
}
.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 3px var(--green-soft); }

.btn {
  --_bg: var(--accent); --_fg: #fff1e5;
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font-size: .95rem; font-weight: 600; text-decoration: none; cursor: pointer;
  padding: .62rem 1.15rem; border-radius: 10px; border: 1px solid transparent;
  background: var(--_bg); color: var(--_fg); white-space: nowrap;
  transition: transform .12s ease, box-shadow .2s ease, background .15s;
}
.btn:hover { transform: translateY(-1px); box-shadow: 0 8px 22px -12px var(--accent); }
.btn:active { transform: translateY(0); }
.btn--ghost { --_bg: transparent; --_fg: var(--ink); border-color: var(--line); }
.btn--ghost:hover { border-color: var(--ink-3); box-shadow: none; background: var(--surface-2); }
.btn--sm { padding: .46rem .8rem; font-size: .86rem; border-radius: 9px; }
.btn:focus-visible, .navlink:focus-visible, .copy:focus-visible {
  outline: none; box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px rgba(13,138,145,.4);
}

.badge { font-family: var(--label); font-size: .64rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; padding: .18rem .42rem; border-radius: 5px; }
.badge--pub { color: var(--green); background: var(--green-soft); }
.badge--sec { color: var(--amber-ink); background: var(--amber-soft); }

.navlink {
  font-size: .9rem; font-weight: 550; color: var(--ink-2); text-decoration: none;
  padding: .34rem .7rem; border-radius: 8px; background: transparent; border: 0; cursor: pointer;
}
.navlink:hover { color: var(--ink); background: var(--surface-2); }

/* ---------- shared components (used by later pages too) ---------- */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; }
.card__h { padding: 1rem 1.2rem .2rem; }
.card__h h2 { font-family: var(--label); font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); margin: 0; font-weight: 600; }
/* minmax(0,…), not the default auto: a card body holds keylines, and a key is
   one unbreakable 40-character string, so an auto track sizes itself to the
   longest key on the page. On a phone that is wider than the card — and the
   card clips (overflow:hidden), so the Copy buttons and the right-hand end of
   every row simply vanished off the edge. */
.card__b { padding: .8rem 1.2rem 1.2rem; display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; }

.keyline { display: flex; align-items: center; gap: .5rem; min-width: 0; background: var(--surface-2); border: 1px solid var(--line); border-radius: 9px; padding: .5rem .6rem; }
.keyline code { font-family: var(--mono); font-size: .82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; color: var(--ink); }
.copy { appearance: none; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); cursor: pointer; border-radius: 7px; padding: .28rem .5rem; font-size: .72rem; font-weight: 600; display: inline-flex; gap: .3rem; align-items: center; flex: none; }
.copy:hover { color: var(--ink); border-color: var(--ink-3); }
.copy.ok { color: var(--green); border-color: var(--green); }

.callout { display: flex; gap: .7rem; border: 1px solid var(--line); border-left: 3px solid var(--accent); background: var(--surface); border-radius: 0 10px 10px 0; padding: .8rem .9rem; margin: 1.2rem 0; font-size: .95rem; color: var(--ink-2); }
.callout svg { flex: none; color: var(--accent); margin-top: .1rem; }
.callout.is-warn { border-left-color: var(--amber); }
.callout.is-warn svg { color: var(--amber-ink); }
.callout b { color: var(--ink); }

/* ============================================================
   LANDING (no scroll)
   ============================================================ */
.landing {
  min-height: 100dvh;
  display: grid; grid-template-rows: auto 1fr;
  padding: 0 var(--stage-pad) var(--stage-pad);
  background:
    radial-gradient(120% 80% at 50% -10%, var(--accent-soft), transparent 60%),
    var(--paper);
  overflow: hidden;
}
.landing__top { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; padding: 1.1rem 0; gap: 1rem; }
.landing__top .left { justify-self: start; }
.landing__top .center { justify-self: center; }
.landing__top .right { justify-self: end; display: flex; gap: .5rem; align-items: center; }
.landing__hero { display: grid; grid-template-columns: 1.02fr .98fr; gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center; max-width: 1120px; width: 100%; margin: 0 auto; }
@media (max-width: 820px) {
  .landing { overflow: visible; }
  .landing__hero { grid-template-columns: 1fr; text-align: left; }
  .demo { display: none; }
}
.landing__copy { max-width: 30rem; }
.eyebrow { font-family: var(--label); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--accent-ink); margin: 0 0 1rem; display: inline-flex; align-items: center; gap: .5rem; }
.eyebrow::before { content: ""; width: 22px; height: 1px; background: var(--accent); }
.landing h1 { font-size: clamp(2.1rem, 4.3vw, 3.3rem); line-height: 1.06; margin: 0 0 1rem; letter-spacing: -.02em; text-wrap: balance; font-weight: 700; }
.landing h1 em { font-style: italic; color: var(--accent); }

/* The rotating blocker word.
   The headline gives up a little leading so the roll's clipping mask can match
   the line box exactly — at 1.06 a descender ("tagging") would be shaved. */
.h-rot { line-height: 1.15; }
.roll {
  display: inline-block; overflow: hidden; height: 1.15em;
  vertical-align: bottom; color: var(--accent); font-style: italic;
  transition: width .42s cubic-bezier(.4,0,.2,1);
}
.roll__list { display: block; transition: transform .52s cubic-bezier(.55,0,.15,1); }
.roll__item { display: block; height: 1.15em; line-height: 1.15em; width: max-content; white-space: nowrap; }
@media (prefers-reduced-motion: reduce) {
  .roll, .roll__list { transition: none; }
}
.landing__sub { font-size: clamp(1.02rem, 1.5vw, 1.16rem); color: var(--ink-2); margin: 0 0 1.6rem; text-wrap: pretty; font-style: italic; }
.landing__cta { display: flex; gap: .7rem; align-items: center; flex-wrap: wrap; }
.landing__meta { margin: 1.4rem 0 0; font-family: var(--mono); font-size: .74rem; color: var(--ink-3); }

.demo { position: relative; }
.demo__app { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-l); box-shadow: var(--shadow-lg); padding: 1rem 1rem 1.15rem; position: relative; }
.demo__bar { display: flex; align-items: center; gap: .4rem; padding-bottom: .85rem; border-bottom: 1px solid var(--line-2); margin-bottom: .95rem; }
.demo__bar i { width: 9px; height: 9px; border-radius: 50%; background: var(--line); display: inline-block; }
.demo__bar span { margin-left: .5rem; font-family: var(--mono); font-size: .68rem; color: var(--ink-3); }
.demo__row { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin: .55rem 0; }
.demo__title { font-weight: 600; font-size: .98rem; }
.demo__muted { color: var(--ink-3); font-size: .86rem; font-style: italic; }
.demo__card { border: 1px solid var(--line-2); border-radius: 10px; padding: .7rem .8rem; background: var(--surface-2); }
.demo__btns { display: flex; gap: .5rem; margin-top: .8rem; }
.fake-btn { font-size: .84rem; font-weight: 600; padding: .5rem .85rem; border-radius: 8px; border: 1px solid var(--line); background: var(--surface); position: relative; }
.fake-btn.is-primary { background: var(--accent); color: #fff1e5; border-color: var(--accent); }
.fake-btn--sm { font-size: .76rem; padding: .34rem .6rem; }

/* Skeleton content. The example app is anonymous on purpose, so its copy is
   bars and the only words on the screen are the two button labels. */
.wire { display: grid; gap: .42rem; }
.wire__bar { height: 8px; border-radius: 5px; background: var(--line-2); }
.wire__bar--h { height: 11px; background: var(--line); }

/* "This was captured, and nobody set it up." The inner ring is what keeps the
   dot legible when it lands on the accent itself. */
.cap-dot {
  position: absolute; z-index: 3; top: -4px; right: -4px;
  width: 9px; height: 9px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 5px var(--accent-soft);
}
.capbar {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  margin-top: .9rem; padding-top: .7rem; border-top: 1px dashed var(--line);
  font-family: var(--mono); font-size: .68rem; color: var(--ink-3);
}
.capbar > span { white-space: nowrap; }
.capbar b { color: var(--accent-ink); font-weight: 700; font-variant-numeric: tabular-nums; }
.capbar .live { display: inline-flex; align-items: center; gap: .35rem; }
.capbar .live i { width: 6px; height: 6px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 3px var(--green-soft); animation: pulse 2.4s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .capbar .live i { animation: none; } }

.readout { margin-top: -18px; margin-left: auto; width: min(92%, 340px); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: .85rem .95rem; position: relative; z-index: 4; }
.readout__q { display: flex; gap: .5rem; align-items: flex-start; font-size: .9rem; }
/* nowrap, or "you →" breaks over two lines whenever the readout narrows: .who
   is a shrinkable flex item and the arrow is a separate word. */
.readout__q .who { font-family: var(--mono); font-size: .62rem; color: var(--ink-3); padding-top: .18rem; font-style: normal; white-space: nowrap; }
.readout__q span:not(.who) { font-style: italic; }
.readout__a { margin-top: .7rem; padding-top: .7rem; border-top: 1px dashed var(--line); }
.bars { display: grid; gap: .38rem; margin-top: .55rem; }
.bar { display: grid; grid-template-columns: 92px 1fr auto; align-items: center; gap: .5rem; font-size: .78rem; }
.bar .lbl { font-family: var(--mono); color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .72rem; }
.bar .track { height: 7px; border-radius: 4px; background: var(--line-2); overflow: hidden; }
/* display:block is load-bearing: .fill is a <span>, so as an inline box it
   ignores both height:100% and the inline width: the markup sets, and every
   bar renders as an empty track. */
.bar .fill { display: block; height: 100%; border-radius: 4px; background: var(--accent); }
.bar .val { font-family: var(--mono); color: var(--ink-2); font-variant-numeric: tabular-nums; font-size: .72rem; }
.bar.is-cold .fill { background: var(--amber); }
.bar.is-cold .val { color: var(--amber-ink); }

/* Funnel readout: every row shares one denominator — the sessions that saw the
   first element — so derived rows are indented under it and carry their own
   percentage. That is also exactly how session_funnel counts. */
.bars--funnel .bar { grid-template-columns: 88px 1fr auto 30px; gap: .4rem; }
.bars--funnel .pct { font-family: var(--mono); font-size: .68rem; color: var(--ink-3); font-variant-numeric: tabular-nums; text-align: right; }
.bar--sub .lbl { padding-left: .5rem; position: relative; }
.bar--sub .lbl::before { content: ""; position: absolute; left: 0; top: 50%; width: 3px; height: 1px; background: var(--line); }
.bar.is-top .lbl { color: var(--ink); font-weight: 600; }
.bar.is-top .val, .bar.is-top .pct { color: var(--accent-ink); font-weight: 700; }
.readout__note { margin: .6rem 0 0; font-size: .78rem; color: var(--accent-ink); font-style: italic; font-variant-numeric: tabular-nums; }

/* ============================================================
   ACCOUNT
   ============================================================ */
.app { min-height: 100dvh; background: var(--paper); }
.appbar { display: flex; align-items: center; gap: 1rem; padding: .8rem var(--stage-pad); border-bottom: 1px solid var(--line); background: var(--surface); }
.appbar .wordmark b { font-size: 1rem; }
.appbar__tabs { display: flex; gap: .15rem; margin-left: .5rem; }
.appbar__tabs a { font-size: .9rem; font-weight: 550; color: var(--ink-2); text-decoration: none; padding: .35rem .7rem; border-radius: 8px; }
.appbar__tabs a[aria-current] { color: var(--ink); background: var(--surface-2); }
.appbar__tabs a:hover { color: var(--ink); }
.appbar__spacer { flex: 1; }
.avatar { flex: none; width: 32px; height: 32px; border-radius: 50%; background: var(--accent); color: #fff1e5; display: grid; place-items: center; font-weight: 600; font-size: .82rem; font-family: var(--label); letter-spacing: .02em; }

.account { max-width: 62rem; margin: 0 auto; padding: clamp(1.4rem, 4vw, 2.6rem) var(--stage-pad) 3rem; }
.account__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; margin-bottom: 1.6rem; flex-wrap: wrap; }
.account__head h1 { font-size: 1.65rem; margin: 0 0 .25rem; letter-spacing: -.015em; font-weight: 700; }
.account__head p { margin: 0; color: var(--ink-2); font-size: .96rem; font-style: italic; }

.cards { display: grid; gap: 1.1rem; grid-template-columns: 1fr; }
@media (min-width: 780px){ .cards { grid-template-columns: 1fr 1fr; } .card--wide { grid-column: 1 / -1; } }

.kv { display: grid; grid-template-columns: minmax(0, 1fr); gap: .3rem; }
.kv dt { font-size: .82rem; color: var(--ink-3); margin: 0; }
.kv-note { font-size: .82rem; color: var(--ink-3); overflow-wrap: break-word; }

/* An email address is one long unbreakable token, so on a phone it used to push
   its badge out through the side of the card. Wrapping the row keeps the badge
   under the value instead of off the screen. */
.name-static { display: flex; align-items: center; justify-content: space-between; gap: .6rem; flex-wrap: wrap; }
.name-static strong { font-size: 1.05rem; min-width: 0; overflow-wrap: anywhere; }
.name-static .muted { color: var(--ink-3); font-style: italic; font-weight: 400; }
.name-edit { display: flex; gap: .55rem; align-items: center; }
.name-edit input { font: inherit; font-size: 1rem; padding: .5rem .65rem; border-radius: 9px; border: 1px solid var(--line); background: var(--surface-2); color: var(--ink); flex: 1; min-width: 0; }
.name-edit input:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px rgba(13,138,145,.4); border-color: var(--accent); }
.name-err { color: var(--amber-ink); font-size: .82rem; margin: .1rem 0 0; }
/* Progressive enhancement: without JS the input is always shown and the form
   posts normally. With JS we collapse to a static value + Edit toggle. */
.js .name-form .name-static { display: none; }
.js .name-form.is-editing .name-static { display: none; }
.js .name-form:not(.is-editing) .name-static { display: flex; }
.js .name-form:not(.is-editing) .name-edit { display: none; }

.warn { display: flex; gap: .6rem; border: 1px solid var(--amber); background: var(--amber-soft); border-radius: 10px; padding: .7rem .8rem; font-size: .9rem; color: var(--ink); }
.warn svg { flex: none; color: var(--amber-ink); margin-top: .1rem; }
.secret-reveal { display: grid; grid-template-columns: minmax(0, 1fr); gap: .6rem; }
/* Inline so the button and its note sit on one line; the phone rules below
   break them apart, which they can only do from the stylesheet. */
.rotate-form { display: inline; }
.secret-note { font-size: .82rem; color: var(--ink-3); margin-left: .6rem; }

/* auto-fit, so the three counts stay a row for as long as they read as one —
   three across on a phone, two on a narrow one — instead of a fixed break that
   turns every source into three full-width tiles. */
.usage { display: grid; grid-template-columns: repeat(auto-fit, minmax(5.4rem, 1fr)); gap: .8rem; }
.stat { border: 1px solid var(--line-2); border-radius: 10px; padding: .7rem .8rem; background: var(--surface-2); }
.stat .n { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.stat .l { font-family: var(--label); font-size: .74rem; color: var(--ink-3); text-transform: uppercase; letter-spacing: .04em; }
.spark { height: 26px; margin-top: .4rem; display: block; width: 100%; }

/* Sources roster: one block per app/environment, keys + per-source usage. */
.sources { display: flex; flex-direction: column; gap: 1rem; margin-top: .6rem; min-width: 0; }
.source { border: 1px solid var(--line-2); border-radius: 12px; padding: .9rem 1rem; background: var(--surface-2); min-width: 0; }
.source + .source { margin-top: 0; }
.source__head { display: flex; align-items: center; gap: .5rem; margin-bottom: .55rem; min-width: 0; }
.source__head strong { font-size: 1rem; font-weight: 650; min-width: 0; overflow-wrap: anywhere; }
/* A source now carries a labelled public key and a labelled secret, so the
   two key blocks need separating from each other the way stacked rows do. */
.source .kv + .kv { margin-top: .8rem; }
.source .usage { margin-top: .7rem; }

/* Reset and delete. Folded away behind a summary because the roster is a column
   of near-identical cards and neither act can be undone — the controls should
   take a deliberate click to reach, not sit under the cursor's resting place. */
.source__danger { margin-top: .8rem; border-top: 1px solid var(--line-2); padding-top: .6rem; }
.source__danger summary { font-family: var(--label); font-size: .74rem; color: var(--ink-3); text-transform: uppercase; letter-spacing: .04em; cursor: pointer; list-style: none; }
.source__danger summary::-webkit-details-marker { display: none; }
.source__danger summary::before { content: '▸ '; }
.source__danger[open] summary::before { content: '▾ '; }
.source__danger summary:hover { color: var(--ink-2); }
.danger-body { margin-top: .7rem; display: grid; gap: .6rem; }
.danger-body p { font-size: .86rem; color: var(--ink-2); margin: 0; }
.danger-row { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.danger-row input { flex: 1 1 14rem; min-width: 0; font-family: var(--mono); font-size: .82rem; padding: .45rem .6rem; border: 1px solid var(--line); border-radius: var(--radius-s); background: var(--surface); color: var(--ink); }
.danger-row input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.btn--danger { --_bg: transparent; --_fg: var(--red-ink); border-color: var(--red); }
.btn--danger:hover { background: var(--red-soft); border-color: var(--red-ink); box-shadow: none; }
.danger-err { font-size: .84rem; color: var(--red-ink); margin: 0; }

/* An acted-upon banner: what just happened, at the top of the page that no
   longer shows it. Deleting a source removes its card, so without this the only
   evidence of a destructive click is an absence. */
.notice { display: flex; gap: .6rem; align-items: flex-start; border: 1px solid var(--green); background: var(--green-soft); border-radius: 10px; padding: .7rem .85rem; font-size: .9rem; margin-bottom: 1rem; }
.notice svg { flex: none; color: var(--green); margin-top: .15rem; }

/* ---------- the account page on a phone ----------
   The card is the same card; it just has ~330px of usable width, so the rows
   that pair a control with a note beside it stack that note underneath. */
@media (max-width: 640px) {
  /* Wordmark, both tabs and the avatar, in 320px of bar: the gutters between
     them are what gives, not the things themselves. */
  .appbar { gap: .5rem; padding: .7rem 1rem; }
  .appbar__tabs { margin-left: 0; }
  .appbar__tabs a { padding: .35rem .5rem; }

  .account { padding-bottom: 2rem; }
  .account__head h1 { font-size: 1.45rem; }
  .usage { gap: .5rem; }
  .stat { padding: .6rem .55rem; }
  .stat .n { font-size: 1.3rem; }
  .stat .l { font-size: .68rem; }
  .card__b { padding: .8rem 1rem 1.1rem; }
  .card__h { padding: 1rem 1rem .2rem; }
  .source { padding: .85rem .8rem; }

  /* "Rotate secret key" and what it costs: side by side the note wrapped into
     an orphan line under the button. Put it on its own line deliberately. */
  .rotate-form { display: block; }
  .secret-note { display: block; margin: .45rem 0 0; }

  /* Both are destructive-ish controls a thumb has to hit accurately. */
  .btn--sm { padding: .55rem .9rem; }
}

/* ============================================================
   LOGIN (Clerk-styled)
   ============================================================ */
.login { min-height: 100dvh; display: grid; grid-template-columns: 1fr; place-items: center; padding: var(--stage-pad); background: radial-gradient(90% 60% at 80% 0%, var(--accent-soft), transparent 55%), var(--paper); }
@media (min-width: 940px) {
  .login { grid-template-columns: 1.1fr 1fr; place-items: stretch; gap: 0; padding: 0; }
  .login__aside { display: flex; }
  .login__main { display: grid; place-items: center; padding: var(--stage-pad); }
}
.login__aside { display: none; flex-direction: column; justify-content: space-between; gap: 2rem; padding: clamp(2rem, 4vw, 3.4rem); background: linear-gradient(165deg, #0d7680, #0a5e66); color: #eaf6f5; }
.login__aside .wordmark b { color: #fff1e5; font-weight: 600; }
.login__aside .wordmark b span { color: #a8d9db; }
.login__aside h2 { font-size: 1.65rem; line-height: 1.2; letter-spacing: -.01em; margin: 0 0 .6rem; max-width: 18rem; text-wrap: balance; font-weight: 700; }
.login__aside p { color: #cfeceb; margin: 0; max-width: 22rem; font-style: italic; }
.login__aside code { color: #fff1e5; background: rgba(255,255,255,.14); font-family: var(--mono); font-size: .82em; padding: .08em .35em; border-radius: 5px; }
.login__facts { display: grid; gap: .9rem; }
.login__fact { display: flex; gap: .6rem; align-items: flex-start; font-size: .95rem; color: #eaf6f5; }
.login__fact svg { flex: none; margin-top: .2rem; color: #a8d9db; }
.login__main { width: 100%; }

.clerk { width: 100%; max-width: 25rem; margin: 0 auto; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-l); box-shadow: var(--shadow-lg); padding: 2rem 1.9rem 1.4rem; }
.clerk__head { text-align: center; margin-bottom: 1.4rem; }
.clerk__head .wordmark { justify-content: center; margin-bottom: 1.1rem; }
.clerk__head h3 { font-size: 1.35rem; margin: 0 0 .3rem; letter-spacing: -.01em; font-weight: 700; }
.clerk__head p { margin: 0; color: var(--ink-2); font-size: .95rem; font-style: italic; }
.oauth { display: grid; gap: .55rem; }
.oauth button { display: flex; align-items: center; justify-content: center; gap: .6rem; width: 100%; padding: .62rem 1rem; font-size: .92rem; font-weight: 550; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--ink); cursor: pointer; }
.oauth button:hover:not([disabled]) { background: var(--surface-2); border-color: var(--ink-3); }
.oauth button[disabled] { opacity: .55; cursor: not-allowed; }
.oauth svg { width: 17px; height: 17px; }
.oauth__soon { margin-left: .35rem; font-family: var(--label); font-size: .6rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); border: 1px solid var(--line); border-radius: 5px; padding: .05rem .3rem; }
.divider { display: flex; align-items: center; gap: .8rem; margin: 1.1rem 0; color: var(--ink-3); font-size: .8rem; font-style: italic; }
.divider::before, .divider::after { content: ""; height: 1px; background: var(--line); flex: 1; }
.field { display: grid; gap: .35rem; margin-bottom: .9rem; }
.field label { font-size: .85rem; font-weight: 550; color: var(--ink-2); }
.field input { font: inherit; font-size: .98rem; padding: .6rem .7rem; border-radius: 10px; border: 1px solid var(--line); background: var(--surface-2); color: var(--ink); }
.field input:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px rgba(13,138,145,.4); border-color: var(--accent); }
.clerk .btn { width: 100%; }
.clerk__alt { text-align: center; font-size: .9rem; color: var(--ink-2); margin: 1.1rem 0 0; }
.clerk__alt a { color: var(--accent-ink); font-weight: 600; text-decoration: none; }
.clerk__secured { display: flex; align-items: center; justify-content: center; gap: .4rem; margin-top: 1.4rem; padding-top: 1rem; border-top: 1px solid var(--line-2); font-size: .75rem; color: var(--ink-3); }
.clerk__secured b { color: var(--ink-2); font-weight: 600; }
.login__err { background: var(--amber-soft); border: 1px solid var(--amber); color: var(--ink); border-radius: 9px; padding: .55rem .7rem; font-size: .88rem; margin-bottom: .9rem; }

/* ============================================================
   MESSAGE PAGES (check-email, friendly errors)
   ============================================================ */
.msg { min-height: 100dvh; display: grid; place-items: center; padding: var(--stage-pad); }
.msg__card { width: 100%; max-width: 30rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-l); box-shadow: var(--shadow); padding: 2rem 1.9rem; }
.msg__card .wordmark { margin-bottom: 1.2rem; }
.msg__card h1 { font-size: 1.5rem; margin: 0 0 .5rem; letter-spacing: -.015em; font-weight: 700; }
.msg__card p { color: var(--ink-2); margin: .5rem 0; }
.msg__card code { font-family: var(--mono); font-size: .86em; background: var(--surface-2); border: 1px solid var(--line); padding: .08em .35em; border-radius: 5px; }
.msg__card a { color: var(--accent-ink); font-weight: 600; text-decoration: none; }
.msg__foot { margin-top: 1.4rem; padding-top: 1rem; border-top: 1px solid var(--line-2); font-size: .88rem; }

/* ============================================================
   DOCS
   ============================================================ */
.docs { display: grid; grid-template-columns: 240px minmax(0,1fr); background: var(--paper); min-height: calc(100dvh - 57px); }
@media (min-width: 1080px){ .docs { grid-template-columns: 250px minmax(0,1fr) 210px; } }
@media (max-width: 800px){ .docs { grid-template-columns: 1fr; } .docs__side { display: none; } }

.docs__side { border-right: 1px solid var(--line); padding: 1.4rem 1rem 2rem 1.4rem; position: sticky; top: 57px; align-self: start; height: calc(100dvh - 57px); overflow-y: auto; }
.docs__search { display: flex; align-items: center; gap: .5rem; width: 100%; margin-bottom: 1.3rem; padding: .5rem .6rem; border: 1px solid var(--line); border-radius: 9px; background: var(--surface); color: var(--ink-3); font-size: .88rem; font-style: italic; }
.docs__search kbd { margin-left: auto; font-family: var(--mono); font-size: .68rem; border: 1px solid var(--line); border-radius: 5px; padding: .05rem .3rem; color: var(--ink-3); }
.navgroup { margin-bottom: 1.3rem; }
.navgroup > p { font-family: var(--label); font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 .5rem; }
.navgroup a { display: block; font-size: .92rem; color: var(--ink-2); text-decoration: none; padding: .34rem .6rem; border-radius: 8px; }
.navgroup a:hover { color: var(--ink); background: var(--surface); }
.navgroup a[aria-current="true"] { color: var(--accent-ink); background: var(--accent-soft); font-weight: 600; }

.docs__main { padding: clamp(1.6rem, 4vw, 3rem) clamp(1.2rem, 4vw, 3.4rem) 4rem; min-width: 0; }
.docs__crumb { font-family: var(--mono); font-size: .72rem; color: var(--ink-3); margin-bottom: .9rem; }
.docs__crumb span { color: var(--accent-ink); }
.prose { max-width: 44rem; }
.prose h1 { font-size: 2rem; letter-spacing: -.02em; margin: 0 0 .5rem; line-height: 1.1; text-wrap: balance; font-weight: 700; }
.prose .lede { font-size: 1.12rem; color: var(--ink-2); margin: 0 0 2rem; text-wrap: pretty; font-style: italic; }
.prose h2 { font-size: 1.35rem; letter-spacing: -.015em; margin: 2.6rem 0 .3rem; scroll-margin-top: 72px; display: flex; align-items: baseline; gap: .55rem; font-weight: 700; }
.prose h2 .num { font-family: var(--sans); font-size: .95rem; color: var(--accent); font-weight: 700; }
.prose h3 { font-size: 1.05rem; margin: 1.7rem 0 .3rem; font-weight: 700; }
.prose p { color: var(--ink); margin: .6rem 0; }
.prose a { color: var(--accent-ink); text-decoration: none; border-bottom: 1px solid var(--accent-soft); }
.prose a:hover { border-bottom-color: var(--accent); }
.prose ul, .prose ol { color: var(--ink); padding-left: 1.2rem; margin: .6rem 0; }
.prose li { margin: .3rem 0; }
.prose li::marker { color: var(--ink-3); }
.prose strong { font-weight: 650; }
/* Inline code is often a URL or an env var name with no break opportunity in
   it, which on a phone is exactly wide enough to push the whole page sideways.
   Let those break; ordinary prose still breaks on spaces. */
.prose code:not(pre code) { font-family: var(--mono); font-size: .84em; background: var(--surface); border: 1px solid var(--line); padding: .08em .35em; border-radius: 5px; overflow-wrap: anywhere; }
.prose p, .prose li { overflow-wrap: break-word; }

.code { position: relative; margin: 1rem 0; border-radius: 12px; overflow: hidden; border: 1px solid var(--line); background: var(--surface); }
.code__top { display: flex; align-items: center; justify-content: space-between; gap: .6rem; padding: .45rem .7rem; border-bottom: 1px solid var(--line-2); background: var(--surface-2); }
.code__lang { font-family: var(--mono); font-size: .68rem; color: var(--ink-3); letter-spacing: .04em; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A long command line scrolls inside its own block. overscroll-behavior keeps
   that swipe from turning into a page pan once the line runs out. */
.code pre { margin: 0; padding: .9rem 1rem; overflow-x: auto; overscroll-behavior-x: contain; }
.code code { font-family: var(--mono); font-size: .82rem; line-height: 1.7; color: var(--ink); white-space: pre; }
.tok-c { color: var(--ink-3); }
.tok-k { color: var(--accent-ink); }
.tok-s { color: var(--green); }
.tok-f { color: var(--amber-ink); }

.keytable { width: 100%; border-collapse: collapse; margin: 1rem 0; font-size: .9rem; }
.keytable th, .keytable td { text-align: left; padding: .55rem .6rem; border-bottom: 1px solid var(--line-2); vertical-align: top; }
.keytable th { font-family: var(--label); font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-3); font-weight: 600; }
.keytable code { font-family: var(--mono); font-size: .8rem; }

.toolgrid { display: grid; gap: .7rem; margin: 1rem 0; }
.tool { border: 1px solid var(--line); border-radius: 10px; padding: .8rem .9rem; background: var(--surface); }
.tool h4 { margin: 0 0 .2rem; font-family: var(--mono); font-size: .9rem; color: var(--accent-ink); }
.tool p { margin: 0; font-size: .9rem; color: var(--ink-2); }

/* ---------- docs: the three steps, and everything hidden behind them --------
   The page shows a heading, one line, and one command per step. Detail lives in
   .more blocks (click) and .hint popovers (hover/focus), so the default view is
   about ninety words rather than nineteen hundred.

   minmax(0,…) on both grids is load-bearing on a phone: a grid track's default
   minimum is the item's min-content, and a step's min-content is its widest
   unwrappable code line (~476px). Without it the step is wider than the screen,
   the whole document scrolls sideways, and Safari zooms the page out to fit. */
.steps { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; margin: 2.2rem 0 0; }
.stepq { border-top: 1px solid var(--line); padding: 2rem 0; min-width: 0; }
.stepq:last-child { border-bottom: 1px solid var(--line); }
.stepq__head { display: grid; grid-template-columns: 3.2rem minmax(0, 1fr); gap: 1.2rem; align-items: start; }
.stepq__n { font-size: 2.6rem; line-height: 1; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; letter-spacing: -.03em; }
.prose .stepq h2 { display: block; font-size: 1.75rem; margin: 0 0 .3rem; font-weight: 700; letter-spacing: -.015em; scroll-margin-top: 72px; }
.stepq__say { font-size: 1.08rem; color: var(--ink-2); margin: 0; font-style: italic; }
.stepq__body { grid-column: 2; margin-top: 1rem; }
.stepq__body > .code:first-child { margin-top: 0; }
.stepq__aside { font-family: var(--mono); font-size: .72rem; color: var(--ink-3); margin-top: .7rem; }

details.more { border-top: 1px dashed var(--line); margin-top: .9rem; }
details.more > summary {
  list-style: none; cursor: pointer; padding: .6rem 0 0;
  font-family: var(--label); font-size: .74rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent-ink); font-weight: 600;
  display: inline-flex; align-items: center; gap: .4rem;
}
details.more > summary::-webkit-details-marker { display: none; }
details.more > summary::after { content: "+"; font-family: var(--mono); font-size: .95rem; line-height: 1; color: var(--accent); }
details.more[open] > summary { color: var(--ink-3); }
details.more[open] > summary::after { content: "–"; }
details.more > summary:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px rgba(13,138,145,.4); border-radius: 4px; }
.more__body { padding: .3rem 0 .4rem; }
.more__body p, .more__body ul { font-size: .95rem; color: var(--ink-2); }

/* Vocabulary only — a step's instructions never live in one of these, because
   they have to survive a reader who never hovers anything. */
.hint { border-bottom: 1px dotted var(--accent); cursor: help; }
/* The popover hangs off the sentence, not off the term: anchored to an inline
   span it runs past the right edge of the screen whenever the term lands near
   the end of a line — which on a phone is most of the time, and is what used to
   make the whole document scroll sideways. The sentence is the containing block
   at every width, so it can never be wider than the column it sits in. */
.stepq__say, .prose p { position: relative; }
.hint__pop {
  position: absolute; left: 0; bottom: calc(100% + .5rem); z-index: 20;
  width: min(19rem, 100%); background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; box-shadow: var(--shadow-lg); padding: .7rem .8rem;
  font-size: .86rem; font-style: normal; color: var(--ink-2); line-height: 1.5;
  opacity: 0; visibility: hidden; transform: translateY(3px);
  transition: opacity .13s ease, transform .13s ease, visibility .13s;
}
.hint:hover .hint__pop, .hint:focus .hint__pop, .hint:focus-within .hint__pop {
  opacity: 1; visibility: visible; transform: none;
}
.hint__pop b { color: var(--ink); }
@media (prefers-reduced-motion: reduce) { .hint__pop { transition: none; } }

.askline { border: 1px solid var(--line); border-radius: 12px; background: var(--surface); padding: 1rem 1.1rem; font-size: 1.12rem; font-style: italic; color: var(--ink); box-shadow: var(--shadow); margin: 1rem 0 0; }
.askline .who { font-family: var(--mono); font-size: .64rem; font-style: normal; color: var(--ink-3); display: block; margin-bottom: .35rem; letter-spacing: .1em; text-transform: uppercase; }

.nextlinks { display: grid; gap: .6rem; grid-template-columns: 1fr 1fr; margin-top: 2.2rem; }
@media (max-width: 560px){ .nextlinks { grid-template-columns: 1fr; } }
.nextlink { border: 1px solid var(--line); border-radius: 10px; padding: .8rem .9rem; text-decoration: none; color: var(--ink); background: var(--surface); transition: border-color .15s; }
.nextlink:hover { border-color: var(--accent); }
.nextlink small { font-family: var(--label); font-size: .68rem; color: var(--ink-3); text-transform: uppercase; letter-spacing: .05em; }
.nextlink b { display: block; margin-top: .2rem; }

.docs__toc { padding: 1.6rem 1.2rem; position: sticky; top: 57px; align-self: start; height: calc(100dvh - 57px); overflow-y: auto; }
@media (max-width: 1079px){ .docs__toc { display: none; } }
.docs__toc p { font-family: var(--label); font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 .7rem; }
.docs__toc a { display: block; font-size: .85rem; color: var(--ink-3); text-decoration: none; padding: .22rem 0 .22rem .7rem; border-left: 2px solid var(--line); }
.docs__toc a:hover { color: var(--ink); }
.docs__toc a[aria-current="true"] { color: var(--accent-ink); border-left-color: var(--accent); }

/* ============================================================
   DOCS ON A PHONE
   The desktop page is a three-column reading rig; on a phone it is one column
   with no room to spare, so the pieces sized for that rig are re-cut here.
   Nothing is hidden that carries instructions.
   ============================================================ */
@media (max-width: 800px) {
  /* Upwards is where a definition goes on a desktop, where the sentence has a
     screenful above it. On a phone a step's one line sits near the top of the
     viewport and the popover opens off the top of the screen, so it drops
     under the sentence instead — over the command, which is still on screen
     and is what the definition is explaining. */
  .hint__pop { bottom: auto; top: calc(100% + .5rem); transform: translateY(-3px); }
  .hint:hover .hint__pop, .hint:focus .hint__pop, .hint:focus-within .hint__pop { transform: none; }
}

@media (max-width: 640px) {
  /* A 3.2rem number column plus a 1.2rem gutter is a seventh of the screen
     spent on a numeral. Keep the number beside the heading, just smaller. */
  .stepq { padding: 1.5rem 0; }
  .stepq__head { grid-template-columns: 1.9rem minmax(0, 1fr); gap: .7rem; }
  .stepq__n { font-size: 1.9rem; }
  .prose .stepq h2 { font-size: 1.35rem; }
  .stepq__say { font-size: 1rem; }
  .prose h1 { font-size: 1.7rem; }
  .prose .lede { font-size: 1.04rem; margin-bottom: 1.4rem; }
  .askline { font-size: 1rem; padding: .85rem .95rem; }

  .code pre { padding: .8rem .85rem; }
  .code code { font-size: .78rem; }

  /* Touch targets: the copy button and a detail's summary are the two things
     on this page a thumb has to hit. */
  .copy { padding: .45rem .7rem; font-size: .78rem; }
  details.more > summary { padding: .8rem 0; }
  .hint { padding: .1rem 0; }

  /* The two-keys table is three columns of prose; stacked, each cell keeps its
     column heading from data-l so a row still reads as key / where / why. */
  .keytable, .keytable tbody, .keytable tr, .keytable td { display: block; width: 100%; }
  .keytable thead { display: none; }
  .keytable tr { padding: .8rem 0; border-bottom: 1px solid var(--line-2); }
  .keytable td { border: 0; padding: .15rem 0; }
  .keytable td[data-l]::before {
    content: attr(data-l); display: block;
    font-family: var(--label); font-size: .64rem; letter-spacing: .06em;
    text-transform: uppercase; color: var(--ink-3); margin-top: .45rem;
  }
  .keytable td:first-child { font-size: .95rem; }
  .keytable td:first-child::before { display: none; }
}

.visually-hidden { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
