/* ============================================================================
   protocol.css — the Protocol page
   ----------------------------------------------------------------------------
   The v2 design study's vocabulary (prototype/v2/shared/style.css, §protocol),
   restated as a page stylesheet on the shipped shell. Load order is the shell's:
   tokens.css, tokens-dark.css, shell.css, then this file.

   Nothing below invents a colour, blur, shadow, radius or type value. Every
   declaration resolves through src/shared/tokens.css, which is what lets the
   [data-theme="dark"] block in tokens-dark.css re-point all of it — INCLUDING
   the architecture SVG, whose strokes and fills are CSS classes on this sheet
   rather than literals in the generator. That is the whole re-theming contract:
   the graphic is repainted by the cascade, not regenerated by JavaScript.

   Two deliberate exceptions, both authorised by docs/design/v2-pages.md
   §Components and measurements, which extends the display role for editorial
   titles beyond the UI scale's 26px ceiling. They are declared once, at the
   top, rather than scattered: --pr-title, --pr-title-phone, --pr-privacy.

   Three token names exist only in the dark sheet — --label-ground, --on-brand
   and --surface — so every use here carries the light fallback the study used.

   NOTE ON THE SPACING SCALE: it is a list, not a multiplier. --sp-9 is 10px,
   --sp-16 is 18px, --sp-22 is 40px. Sizes below are chosen by VALUE.
   ========================================================================== */

:root{
  /* the design's editorial title sizes: 43px desktop maximum, 31px on phone */
  --pr-title:       clamp(29px, 3.5vw, 43px);
  --pr-title-phone: 31px;
  /* the "not stored onchain" line — a display statement, not a heading */
  --pr-privacy:     23px;
  /* the opaque ground behind a label plate sitting on the mesh */
  --pr-label:       var(--label-ground, var(--paper));
}

/* -- page ground -----------------------------------------------------------
   One warm wash off the top right, behind everything, so the panels have
   something to be glass over. Fixed, so it does not travel with the scroll. */
.pr-ground{
  position:fixed; inset:0; z-index:-1; pointer-events:none;
  background:radial-gradient(1000px 550px at 75% 2%, var(--brand-06), transparent 65%);
}

body{ font-size:var(--fs-lg); line-height:var(--lh-loose); }
.page p, .page h1, .page h2, .page h3, .page figure{ margin:0; }
.page p + p{ margin-top:var(--sp-9); }
.page a{ color:inherit; text-underline-offset:3px; }

.pr-skip{
  position:fixed; top:-80px; left:var(--sp-9); z-index:80;
  padding:var(--sp-11); background:var(--paper); color:var(--ink);
  border:1px solid var(--border); border-radius:var(--r-8);
}
.pr-skip:focus{ top:var(--sp-7); }

/* the route label beside the wordmark, at the shell's mono-note size */
.pr-route{
  font:var(--fs-sm) var(--font-mono); color:var(--graphite);
  letter-spacing:var(--ls-01);
}
.pr-boot{ padding:var(--sp-22) 0; color:var(--graphite); }

/* -- the document frame ---------------------------------------------------
   1180px including 18px side padding, centred, 40px of top air. */
.page{
  width:100%; max-width:1180px; margin:0 auto; min-width:0;
  padding:var(--sp-22) var(--sp-16) var(--sp-18);
}

/* -- editorial type -------------------------------------------------------- */
.page-heading{ margin-bottom:var(--sp-20); max-width:850px; }
.eyebrow{
  font:var(--fs-sm) var(--font-mono); letter-spacing:var(--ls-12);
  color:var(--graphite); margin-bottom:var(--sp-12);
}
.page h1{
  font-family:var(--font-display); font-size:var(--pr-title);
  font-weight:var(--fw-medium); letter-spacing:-.045em; line-height:1.15;
}
.lead{
  margin-top:var(--sp-13); color:var(--graphite);
  font-size:var(--fs-xl); line-height:var(--lh-loose); max-width:690px;
}
.page h2{ font:var(--fw-semibold) var(--fs-xl) var(--font-display); letter-spacing:-.015em; }
.page h3{ font:var(--fw-semibold) var(--fs-17)/1.3 var(--font-display); letter-spacing:var(--ls-tight); }
.note{ color:var(--graphite); font-size:var(--fs-md); line-height:var(--lh-loose); }
.label{
  font:var(--fw-semibold) var(--fs-sm) var(--font-display); letter-spacing:var(--ls-10);
  color:var(--graphite); text-transform:uppercase;
}
.protocol-intro{ max-width:670px; }

/* -- the six operations ----------------------------------------------------
   A mono row between two hairlines: the protocol's verbs, each an anchor into
   its own explanation further down the page. */
.operations{
  display:flex; gap:var(--sp-9); flex-wrap:wrap;
  padding:var(--sp-15) 0; margin-top:var(--sp-16);
  border-top:1px solid var(--border); border-bottom:1px solid var(--border);
  font:var(--fs-sm) var(--font-mono); letter-spacing:var(--ls-06);
}
.operations a{
  text-decoration:none; padding:var(--sp-3) var(--sp-8);
  border-radius:var(--r-5); color:var(--ink);
  transition:background var(--dur-140) var(--ease), color var(--dur-140) var(--ease);
}
.operations a:hover{ background:var(--brand-08); color:var(--brand); }

/* -- the figure ------------------------------------------------------------ */
.net-figure{ position:relative; width:100%; min-width:0; }
.protocol-figure{ margin-top:var(--sp-17); }
.net-figure svg{ width:100%; display:block; overflow:visible; }
.net-figure figcaption{
  display:flex; justify-content:space-between; gap:var(--sp-16);
  padding:var(--sp-12) 0; border-top:1px solid var(--border);
  color:var(--graphite); font:var(--fs-sm)/1.6 var(--font-mono);
}

/* the ambient drape: decorative geometry, aria-hidden, drawn from the same two
   ink tokens as everything else, so it darkens with the page */
.net-thread{ fill:none; stroke:var(--graphite); stroke-width:.7; }
.mesh-dot{ fill:var(--ink); }
.mesh-face{ fill:var(--graphite); stroke:none; }

/* the architecture nodes. Fills and strokes are classes, never literals — this
   is why a theme change repaints the diagram without regenerating it. */
.arch-connector{ stroke:var(--graphite); fill:none; stroke-width:1; opacity:.65; }
.arch-node{ fill:var(--paper-93); stroke:var(--border); }
.arch-primary{ stroke:var(--brand); }
.arch-dot{ fill:var(--brand); }
.arch-layer{ font:var(--fs-sm) var(--font-mono); fill:var(--graphite); letter-spacing:var(--ls-08); }
.arch-title{ font:var(--fw-medium) var(--fs-xl) var(--font-display); fill:var(--ink); }
.arch-copy{ font:var(--fs-sm) var(--font-mono); fill:var(--graphite); }
.graphic-plate{ fill:var(--pr-label); }

/* -- the line that must never hide in a tooltip ---------------------------- */
.privacy-line{
  font:var(--fw-medium) var(--pr-privacy)/1.35 var(--font-display);
  letter-spacing:var(--ls-tight);
  padding:var(--sp-18) 0; border-top:1px solid var(--border); color:var(--ink);
}

/* -- panels ---------------------------------------------------------------- */
.panel{
  border:1px solid var(--brand-20); background:var(--paper-66);
  border-radius:var(--r-16); box-shadow:var(--sh-4-panel);
  -webkit-backdrop-filter:var(--blur-panel); backdrop-filter:var(--blur-panel);
  min-width:0; overflow:hidden;
}
.panel-head{
  display:flex; gap:var(--gap-row); padding:var(--sp-13) var(--sp-15);
  align-items:center; border-bottom:1px solid var(--border);
}
.ordinal{ font:var(--fs-sm) var(--font-mono); color:var(--graphite); }
.panel-tail{ margin-left:auto; color:var(--graphite); font:var(--fs-sm) var(--font-mono); }
.panel-body{ padding:var(--sp-16); }
.two-even{ display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-17); align-items:start; }
.section-space{ margin-top:var(--sp-21); }

/* the key/value row: label left, tabular value right, hairline under */
.kv{
  display:flex; align-items:baseline; justify-content:space-between; gap:var(--sp-15);
  border-bottom:1px solid var(--border); padding:var(--sp-8) 0;
  font-size:var(--fs-md); color:var(--graphite);
}
.kv:last-child{ border:0; }
.kv b{
  color:var(--ink); font:var(--fw-medium) var(--fs-base)/1.5 var(--font-mono);
  font-variant-numeric:tabular-nums; text-align:right;
}
.panel-body .note{ margin-top:var(--sp-11); }

/* -- the storage rule -----------------------------------------------------
   Protocol §15's two lists, side by side, because the boundary IS the rule. */
.storage-lede{
  font:var(--fw-semibold) var(--fs-17)/1.35 var(--font-display);
  letter-spacing:var(--ls-tight); color:var(--ink); margin-bottom:var(--sp-13);
}
.storage-list{ list-style:none; margin:var(--sp-11) 0 0; padding:0; }
.storage-list li{
  padding:var(--sp-7) 0; border-bottom:1px solid var(--border);
  font:var(--fs-md)/1.6 var(--font-mono); color:var(--ink);
}
.storage-list li:last-child{ border:0; }
.storage-side .label{ display:block; }
.storage-side.onchain .label{ color:var(--brand); }

/* -- the six explanations -------------------------------------------------- */
.editorial-sections{
  display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-17) 50px;
  margin-top:var(--sp-19);
}
.editorial-sections article{
  padding:var(--sp-18) 0; border-top:1px solid var(--border);
  /* clears the sticky header when an operation anchor lands here */
  scroll-margin-top:80px;
}
.editorial-sections h3{ margin-bottom:var(--sp-9); }
.editorial-sections p{ color:var(--graphite); font-size:var(--fs-base); }
.editorial-sections article:target h3{ color:var(--brand); }

.inline-note{
  margin-top:var(--sp-17);
  padding:var(--sp-11) var(--sp-15); background:var(--glass-fill-50);
  border:1px solid var(--border); border-radius:var(--r-9);
}
.inline-note code{ font-family:var(--font-mono); font-size:var(--fs-md); }

/* -- the unavailable-snapshot state ---------------------------------------- */
.empty{ padding:var(--sp-22) var(--sp-18); text-align:center; }
.empty .button{ margin:var(--sp-17) var(--sp-4) 0; }
.button{
  display:inline-flex; justify-content:center; align-items:center; gap:var(--gap-row);
  padding:var(--sp-9) var(--sp-16); min-height:40px;
  border:1px solid var(--brand); background:var(--brand);
  color:var(--on-brand, var(--ink));
  text-decoration:none; font-size:var(--fs-base); font-weight:var(--fw-semibold);
  border-radius:var(--r-11); white-space:nowrap;
  transition:background var(--dur-140) var(--ease);
}
.button.ghost{ background:var(--glass-fill-50); color:var(--ink); border-color:var(--border); }
@media (hover:hover) and (pointer:fine){
  .button:hover{ background:var(--brand-88); }
  .button.ghost:hover{ background:var(--brand-08); }
}
.button:active{ transform:scale(.98); }

/* -- phone -----------------------------------------------------------------
   The figure is not scaled down: protocol.js recomposes it vertically below
   900px of FIGURE width, so its text keeps its own diagram scale while the
   editorial copy wraps. Nothing here clips or pans to hide excess width. */
@media (max-width:768px){
  .page{ padding:var(--sp-19) var(--sp-15) var(--sp-18); }
  .page h1{ font-size:var(--pr-title-phone); }
  .lead{ font-size:var(--fs-lg); }
  .pr-route{ display:none; }
  .two-even, .editorial-sections{ grid-template-columns:1fr; gap:var(--sp-17); }
  .net-figure figcaption{ gap:var(--sp-11); font-size:var(--fs-xs); flex-wrap:wrap; }
  .operations{ display:grid; grid-template-columns:repeat(3, 1fr); gap:var(--sp-7); }
  .operations a{ padding:var(--sp-5) var(--sp-1); text-align:center; }
  .panel{ -webkit-backdrop-filter:var(--blur-md); backdrop-filter:var(--blur-md); }
}

/* -- accessibility fallbacks ---------------------------------------------- */
@media (prefers-reduced-transparency: reduce){
  .panel{ background:var(--surface, var(--paper)); backdrop-filter:none; -webkit-backdrop-filter:none; }
  .pr-ground{ display:none; }
}
/* This is a reading page: the diagram never animates, and the only motion is
   the shell's own. The rule is kept so a later addition cannot slip past it. */
@media (prefers-reduced-motion: reduce){
  .page *, .page *::before, .page *::after{ animation:none !important; transition:none !important; }
}
