/* MeshVault docs — Read-mode surface.
   Colour, type, radius and spacing all come from /assets/tokens.css, which mirrors
   the bound Figma variables. This file declares no colour of its own; if you find
   yourself typing a hex here, the token is missing and belongs upstream.

   Load order matters: tokens.css, then this file.

   Note for the next editor: an earlier version of this header claimed these pages
   shared "the same tokens and the same class names as the landing page's inline
   CSS". They did not — this file declared its own off-white paper against the
   landing page's canvas, and the two drifted for exactly as long as the comment promised
   they could not. The tokens are now shared for real, in one file. */

*{box-sizing:border-box;margin:0;padding:0}
html{background:var(--c-canvas);-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  background:var(--c-canvas);color:var(--c-ink);
  font-family:var(--f-ui);font-weight:300;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img{display:block;max-width:100%}

/* ================= CHROME ================= */
header{position:sticky;top:0;z-index:8;display:flex;align-items:center;
  justify-content:space-between;gap:var(--sp-4);padding:var(--sp-5) clamp(22px,4vw,56px);
  background:var(--c-canvas); /* fallback: a sticky header must never be see-through */
  background:color-mix(in srgb, var(--c-canvas) 94%, transparent);
  -webkit-backdrop-filter:saturate(180%) blur(14px);
  backdrop-filter:saturate(180%) blur(14px);border-bottom:1px solid var(--c-border)}
.brand{display:flex;align-items:center;gap:10px;font-weight:500;font-size:var(--t-sm);
  letter-spacing:-.012em;color:var(--c-ink);text-decoration:none;flex:none}
.brand .cube{width:22px;height:22px;flex:none}
.brand .ctx{font-family:var(--f-mono);font-size:var(--t-2xs);letter-spacing:.16em;
  text-transform:uppercase;color:var(--c-secondary);padding-left:10px;
  border-left:1px solid var(--c-border)}
nav{display:flex;gap:clamp(14px,2vw,26px);font-size:var(--t-sm);flex-wrap:wrap;
  justify-content:flex-end}
nav a{color:var(--c-secondary);text-decoration:none;transition:color var(--dur)}
nav a:hover,nav a:focus-visible{color:var(--c-ink)}
nav a[aria-current="page"]{color:var(--c-ink);font-weight:500}
@media(max-width:820px){
  header{flex-direction:column;align-items:flex-start;gap:var(--sp-3);position:static}
  nav{justify-content:flex-start}
}

/* ================= PAGE ================= */
main{max-width:1180px;margin:0 auto;padding:0 clamp(22px,7vw,120px)}

/* Jump targets clear the sticky header. Every section carries an id so a claim on
   these pages can be linked to, and without this a jump lands with the heading
   sitting behind the header. The skip link's own #main target had the same bug
   before any section id existed. Below 820px the header is static, so the offset
   drops to a reading gap. */
main,.sec{scroll-margin-top:calc(var(--sp-16) + var(--sp-4))}
@media(max-width:820px){main,.sec{scroll-margin-top:var(--sp-4)}}
.beat{max-width:660px;padding:clamp(56px,8vh,92px) 0 clamp(26px,4vh,40px)}
.kicker{font-family:var(--f-mono);font-size:var(--t-2xs);letter-spacing:.2em;
  text-transform:uppercase;color:var(--c-secondary);margin-bottom:var(--sp-5);
  display:flex;align-items:center;gap:var(--sp-3)}
.kicker::after{content:"";height:1px;width:46px;background:var(--c-border)}
h1{font-weight:300;letter-spacing:-.037em;line-height:1.05;font-size:var(--t-3xl);
  margin-bottom:var(--sp-5)}
h1 em{font-style:normal;font-weight:500}
.lede{font-size:var(--t-lg);line-height:1.6;color:var(--c-ink);max-width:46ch}
.meta{margin-top:var(--sp-6);font-family:var(--f-mono);font-size:var(--t-2xs);
  letter-spacing:.16em;color:var(--c-secondary)}

.sec{padding:clamp(40px,5.5vh,62px) 0 0;border-top:1px solid var(--c-border);
  margin-top:clamp(34px,5vh,54px)}
.sec:first-of-type{border-top:0;margin-top:0}
.lbl{font-family:var(--f-mono);font-size:var(--t-2xs);letter-spacing:.2em;
  text-transform:uppercase;color:var(--c-secondary);margin-bottom:var(--sp-4);
  display:flex;align-items:center;gap:var(--sp-3)}
.lbl::after{content:"";height:1px;flex:1;max-width:110px;background:var(--c-border)}
.sec h2{font-weight:300;letter-spacing:-.028em;line-height:1.15;font-size:var(--t-xl);
  margin-bottom:var(--sp-3);max-width:26ch}
.sec h2 em{font-style:normal;font-weight:500}
h3{font-weight:500;font-size:var(--t-lg);letter-spacing:-.018em;
  margin:var(--sp-8) 0 var(--sp-2)}
/* .sub was 62ch while .prose ran 68ch, so a section deck and the body under it
   measured differently at the same 16px. One measure for all 16px prose. */
.sub{font-size:var(--t-base);line-height:1.65;color:var(--c-secondary);max-width:68ch;
  margin-bottom:var(--sp-6)}

/* Rag control, not layout. balance evens the short lines of a heading (it respects
   the authored <br> and balances each side of it); pretty keeps a one-word last line
   off a 68ch paragraph. Both are ignored where unsupported, so neither is load-bearing. */
h1,.sec h2,h3{text-wrap:balance}
.lede,.sub,.prose p,.prose li,.plan p,.note p,.fineprint{text-wrap:pretty}

/* ================= PROSE ================= */
.prose{max-width:68ch}
.prose p{font-size:var(--t-base);line-height:1.7;color:var(--c-ink);
  margin-bottom:var(--sp-4)}
.prose ul,.prose ol{margin:0 0 var(--sp-5) var(--sp-5)}
.prose li{font-size:var(--t-base);line-height:1.65;color:var(--c-ink);
  margin-bottom:var(--sp-2)}
.prose a{color:var(--c-brand);text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--c-secondary);
  transition:text-decoration-color var(--dur)}
.prose a:hover,.prose a:focus-visible{text-decoration-color:var(--c-brand)}
.prose strong{font-weight:500}
/* Inline code carries a tint, not a border: an outlined inline chip cannot hold the
   8px minimum padding without wrecking the line box, so it does not get an outline. */
code{font-family:var(--f-mono);font-size:.9em;
  background:var(--c-brand-tint);color:var(--c-brand);
  padding:.12em .38em;border-radius:4px}
/* Every pre and every .tw carries tabindex="0" in the markup. That is not decoration:
   both scroll horizontally, and a scroll container that only a pointer can reach puts
   the overflowing half of the content out of a keyboard user's hands. Do not remove the
   attribute to tidy the tab order. A pre announces its own text so it needs no role;
   an empty div does not, which is why .tw also carries role="region" and a name. */
pre{font-family:var(--f-mono);font-size:var(--t-xs);line-height:1.65;
  background:var(--c-card);border:1px solid var(--c-border);border-radius:var(--r-input);
  padding:var(--sp-4);overflow-x:auto;margin:0 0 var(--sp-5);max-width:100%}
pre code{background:none;padding:0;border-radius:0;font-size:inherit;color:var(--c-ink)}

/* ================= TABLE ================= */
.tw{overflow-x:auto;margin:0 0 var(--sp-6);border:1px solid var(--c-border);
  border-radius:var(--r-input);background:var(--c-card)}
table{border-collapse:collapse;width:100%;min-width:520px}
th,td{text-align:left;padding:var(--sp-3) var(--sp-4);
  border-bottom:1px solid var(--c-border);font-size:var(--t-sm);line-height:1.5;
  vertical-align:top}
th{font-family:var(--f-mono);font-size:var(--t-2xs);letter-spacing:.14em;
  text-transform:uppercase;color:var(--c-secondary);font-weight:500;white-space:nowrap}
tr:last-child td{border-bottom:0}
td code{font-size:var(--t-xs)}

/* ================= CARDS + CALLOUT ================= */
.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1px;
  background:var(--c-border);border:1px solid var(--c-border);
  border-radius:var(--r-card);overflow:hidden;margin:0 0 var(--sp-8);max-width:900px}
.plan{background:var(--c-canvas);padding:var(--sp-6)}
.plan h3{font-family:var(--f-mono);font-size:var(--t-2xs);font-weight:500;
  letter-spacing:.14em;margin:0 0 var(--sp-3);color:var(--c-secondary);
  text-transform:uppercase}
.plan p{font-size:var(--t-sm);line-height:1.6;color:var(--c-secondary)}
.plan p+p{margin-top:var(--sp-2)}

/* A tinted block, not a 2px rule. The old treatment was a coloured left border on a
   callout, which reads as decoration and cannot hold interior padding. */
.note{background:var(--c-brand-tint);border-radius:var(--r-input);
  padding:var(--sp-4) var(--sp-5);margin:0 0 var(--sp-6);max-width:64ch}
.note p{font-size:var(--t-base);line-height:1.65;color:var(--c-ink);
  margin-bottom:var(--sp-2)}
.note p:last-child{margin-bottom:0}
.note .tag{font-family:var(--f-mono);font-size:var(--t-2xs);letter-spacing:.18em;
  text-transform:uppercase;color:var(--c-brand);display:block;margin-bottom:var(--sp-2);
  font-weight:500}

/* ================= LINKS OUT ================= */
.cta{display:inline-flex;align-items:center;gap:10px;background:var(--c-brand);
  color:var(--c-canvas);padding:var(--sp-4) var(--sp-6);border-radius:var(--r-pill);
  text-decoration:none;font-size:var(--t-sm);font-weight:500;letter-spacing:-.01em;
  transition:background var(--dur),transform var(--dur-fast) ease-out}
.cta:hover,.cta:focus-visible{background:var(--c-brand-deep)}
.cta:active{transform:scale(.97)}
.cta.ghost{background:none;color:var(--c-brand);border:1px solid var(--c-border)}
.cta.ghost:hover,.cta.ghost:focus-visible{background:var(--c-hover-subtle)}
.fineprint{font-size:var(--t-xs);line-height:1.6;color:var(--c-secondary);
  margin-top:var(--sp-4);max-width:52ch}
.fineprint a{color:var(--c-brand)}

.next{display:flex;flex-wrap:wrap;gap:var(--sp-3);margin-top:var(--sp-2)}

/* The footer sat inside main on all six pages. A footer scoped to sectioning content
   has no contentinfo role, so the serialised DOM showed it as a generic div and every
   page shipped with no contentinfo landmark at all. It is now a sibling of main, which
   means it also has to carry main's gutter itself: footer holds the width and the side
   padding, .fbar holds the rule and the row. That keeps the top rule at the same
   content width the section rules use instead of widening it by the gutter. */
footer{max-width:1180px;margin:clamp(48px,7vh,84px) auto 0;
  padding:0 clamp(22px,7vw,120px)}
.fbar{padding:var(--sp-12) 0;border-top:1px solid var(--c-border);
  font-family:var(--f-mono);font-size:var(--t-2xs);letter-spacing:.09em;
  color:var(--c-secondary);display:flex;justify-content:space-between;
  flex-wrap:wrap;align-items:center;gap:var(--sp-4)}
footer a{color:inherit;text-decoration:none}
footer a:hover{color:var(--c-ink)}
footer .mail{border:1px solid var(--c-border);border-radius:var(--r-pill);
  padding:var(--sp-3) var(--sp-4);
  transition:background var(--dur),color var(--dur),border-color var(--dur)}
footer .mail:hover,footer .mail:focus-visible{background:var(--c-brand);
  color:var(--c-canvas);border-color:var(--c-brand)}

:focus-visible{outline:2px solid var(--c-brand);outline-offset:3px}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
  white-space:nowrap}
.skip{position:absolute;left:-9999px;z-index:20;padding:var(--sp-3) var(--sp-4);
  border-radius:var(--r-input);background:var(--c-brand);color:var(--c-canvas)}
.skip:focus{left:12px;top:12px}

@media(prefers-reduced-transparency:reduce){
  header{background:var(--c-canvas);-webkit-backdrop-filter:none;backdrop-filter:none}
}

/* Scoped, not a blanket kill. Movement goes; state feedback stays, because a reader
   who asked for less motion still needs to see that a link is hovered and a button
   was pressed. A global animation-duration:.001ms!important would delete both. */
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .cta{transition:background var(--dur-fast) linear}
  .cta:active{transform:none}
}
