/* GENERATED FILE - DO NOT EDIT.
 * Source: web/src/styles/shared.css and its imports.
 * Run npm run docs:tokens after editing the authored styles.
 */
/* ---- src/styles/shared.css ---- */
/* Shared values and behavior; surface extensions load afterward. */

/* ---- src/styles/foundation/typography.css ---- */
/* Named text roles. Tone is independent of hierarchy. */
.vs-type-h1 {
  font-family: var(--font-display);
  font-size: var(--ms-display);
  line-height: var(--ms-display-line-height);
  font-weight: var(--ms-display-weight);
  letter-spacing: var(--ms-display-tracking);
  text-wrap: pretty;
}
.vs-type-h2 {
  font-family: var(--font-display);
  font-size: var(--ms-h2);
  line-height: var(--ms-h2-line-height);
  font-weight: var(--ms-h2-weight);
  letter-spacing: var(--ms-h2-tracking);
  text-wrap: balance;
}
.vs-type-h3 {
  font-family: var(--font-display);
  font-size: var(--ms-h3);
  line-height: var(--ms-h3-line-height);
  font-weight: var(--ms-h3-weight);
  letter-spacing: var(--ms-h3-tracking);
}
.vs-type-lead {
  font-family: var(--font-sans);
  font-size: var(--ms-lead);
  line-height: var(--ms-lead-line-height);
  font-weight: var(--ms-lead-weight);
  max-width: var(--ms-measure);
  text-wrap: pretty;
}
.vs-type-body {
  font-family: var(--font-sans);
  font-size: var(--ms-body);
  line-height: var(--ms-body-line-height);
  font-weight: var(--ms-body-weight);
  max-width: var(--ms-measure);
  text-wrap: pretty;
}
.vs-type-label {
  font-family: var(--font-sans);
  font-size: var(--ms-label);
  line-height: var(--ms-label-line-height);
  font-weight: var(--ms-label-weight);
  letter-spacing: var(--ms-label-tracking);
}
.vs-type-code {
  font-family: var(--font-mono);
  font-size: var(--ms-mono);
  line-height: var(--ms-mono-line-height);
  font-weight: var(--ms-mono-weight);
}
/* The width axis is set through font-variation-settings rather than
   font-stretch so the value cannot be lost to a shorthand reset. */
.vs-type-marker {
  font-family: var(--font-display);
  font-size: var(--ms-rule-label);
  line-height: var(--ms-rule-label-line-height);
  font-weight: var(--ms-rule-label-weight);
  letter-spacing: var(--ms-rule-label-tracking);
  font-variation-settings: "wdth" var(--ms-rule-label-width);
  text-transform: uppercase;
}
.tabular-nums {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.vs-type-caption {
  font-family: var(--font-sans);
  font-size: var(--text-caption);
  line-height: var(--text-caption-line-height);
  font-weight: var(--text-caption-weight);
}
.vs-tone-primary { color: var(--color-ink); }
.vs-tone-secondary { color: var(--color-ink-muted); }
/* The display role's own breakpoint: below this the wide clamp strands a word
   off the end of the headline. */
@media (max-width: 44rem) {
  .vs-type-h1 { font-size: var(--ms-display-tight); }
}

/* ---- src/styles/foundation/elevation.css ---- */
/* Shared motion helpers and reduced-motion behavior. */
@keyframes vs-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes vs-slide-in-up {
  from { transform: translateY(0.375rem); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
@keyframes vs-slide-in-down {
  from { transform: translateY(-0.25rem); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
@keyframes vs-pulse-live {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---- src/styles/components/materials.css ---- */
/* Shared cutting-mat and stock treatments. */
.vs-acrylic {
  background: color-mix(in srgb, var(--color-paper-raised) var(--acrylic-opacity), transparent);
  backdrop-filter: blur(var(--acrylic-blur));
  border-radius: var(--radius-lg);
  box-shadow: var(--stock-contact-plate);
}
.vs-stock.vs-stock--slip {
  border-radius: var(--radius-cut);
}
.vs-mat {
  position: relative;
  isolation: isolate;
  --vs-gutter: max(
    var(--container-pad),
    calc((100vw - var(--container-width)) / 2 + var(--container-pad))
  );
}
.vs-mat::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--grid-c-ink) 0.0625rem, transparent 0.0625rem),
    linear-gradient(to bottom, var(--grid-c-ink) 0.0625rem, transparent 0.0625rem),
    linear-gradient(to right, var(--grid-f-ink) 0.0625rem, transparent 0.0625rem),
    linear-gradient(to bottom, var(--grid-f-ink) 0.0625rem, transparent 0.0625rem);
  background-size:
    var(--grid-coarse) var(--grid-coarse),
    var(--grid-coarse) var(--grid-coarse),
    var(--grid-fine) var(--grid-fine),
    var(--grid-fine) var(--grid-fine);
  background-position: var(--vs-gutter) 0;
  mask-image: var(--grid-mask, linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent));
}
/* A section shows at most two of the three scales. Fine alone is the quiet
   ground; coarse alone is a divider; together they read as a cutting mat. */
.vs-mat--fine::before {
  background-image:
    linear-gradient(to right, var(--grid-f-ink) 0.0625rem, transparent 0.0625rem),
    linear-gradient(to bottom, var(--grid-f-ink) 0.0625rem, transparent 0.0625rem);
  background-size: var(--grid-fine) var(--grid-fine), var(--grid-fine) var(--grid-fine);
}
.vs-mat--coarse::before {
  background-image:
    linear-gradient(to right, var(--grid-c-ink) 0.0625rem, transparent 0.0625rem),
    linear-gradient(to bottom, var(--grid-c-ink) 0.0625rem, transparent 0.0625rem);
  background-size: var(--grid-coarse) var(--grid-coarse), var(--grid-coarse) var(--grid-coarse);
}
/* Registration crosses. Marks, not lines, so this is the one place the motif
   uses SVG - a data URI tile at major spacing. Masked to the outer margins so a
   cross never lands inside a paragraph or a pipeline cell. */
.vs-mat--marks::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M0 0.5h9M0.5 0v9M0 0.5h-9M0.5 0v-9' stroke='%23000' stroke-opacity='0.28' stroke-width='1' fill='none'/%3E%3C/svg%3E");
  background-size: var(--grid-major) var(--grid-major);
  background-position: var(--vs-gutter) 0;
  mask-image: linear-gradient(to right, #000 0 9%, transparent 9% 91%, #000 91% 100%);
}
[data-theme="dark"] .vs-mat--marks::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M0 0.5h9M0.5 0v9M0 0.5h-9M0.5 0v-9' stroke='%23fff' stroke-opacity='0.30' stroke-width='1' fill='none'/%3E%3C/svg%3E");
}
/* ---------- stock: the two border treatments ----------
   Exactly two, and never both on one element.

     cut edge   - a 1px solid hairline where stock abuts stock.
     score line - 1px dashed in --color-edge, meaning marked but not yet cut.

   Which one an element takes follows from what it is, not from taste. Laid
   stock sits ON the mat, so it casts a contact shadow and takes no border.
   Inlaid stock is cut INTO the mat, so it takes a scored edge and casts
   nothing. The dashed edge is therefore semantic: it is how the page says a
   thing is marked out but not finished.

   Contact shadows live here rather than in elevation.css. The shared elevation
   tokens are flat by design for the application chrome that also reads them,
   and reversing that is not this surface's decision to make. Always
   downward-offset, small blur, no spread - a sheet resting on a mat, never a
   glowing halo.

   The rule is enforced here rather than left to discipline: every class resets
   the property the other one owns, so combining them cannot silently produce an
   element wearing both. */
/* Laid stock: shadow, no border. */
.vs-stock {
  background: var(--color-paper-raised);
  border: 0;
  border-radius: var(--radius-md);
  box-shadow: var(--stock-contact);
}
.vs-stock--stack { box-shadow: var(--stock-contact-stack); }
.vs-stock--plate { border-radius: var(--radius-lg); box-shadow: var(--stock-contact-plate); }
/* Inlaid stock: scored edge, no shadow. */
.vs-scored {
  background: color-mix(in srgb, var(--color-paper-sunken) 60%, transparent);
  border: 0.0625rem dashed var(--color-edge);
  border-radius: var(--radius-md);
  box-shadow: none;
}

/* ---- src/styles/components/controls.css ---- */
/* Shared control states and canonical action rendering.
   Reading navigation can configure row layout; buttons use the finite named
   forms below. Surface styles arrange buttons without redefining them. */
/* ---------- control: anything a reader points at ------------------------ */
/* Quiet is the default role. Primary and secondary actions opt into fill. */
.vs-control {
  box-sizing: border-box;
  min-height: var(--control-min-height, 0);
  display: var(--control-display, inline-flex);
  align-items: center;
  justify-content: var(--control-justify, normal);
  gap: var(--control-gap, var(--space-2));
  padding: var(--control-padding,
    var(--control-pad-y, var(--space-1-5)) var(--control-pad-x, var(--space-3))
    var(--control-pad-y, var(--space-1-5)) var(--control-pad-left, var(--control-pad-x, var(--space-3))));
  border-width: var(--control-border-width, var(--interaction-edge-width));
  border-style: solid;
  border-color: var(--control-edge, transparent);
  border-radius: var(--control-radius, var(--interaction-radius));
  background: var(--control-ground, transparent);
  color: var(--control-ink, var(--interaction-ink));
  font-family: var(--control-font, inherit);
  font-size: var(--control-size, var(--text-meta));
  line-height: var(--control-line-height, var(--text-meta-line-height));
  font-weight: var(--control-weight, var(--interaction-weight));
  letter-spacing: normal;
  text-transform: none;
  vertical-align: middle;
  text-align: var(--control-align, left);
  text-decoration: none;
  cursor: var(--control-cursor, pointer);
  transition: var(--control-transition,
    background-color var(--duration-ui-fast) var(--ease-snap),
    border-color var(--duration-ui-fast) var(--ease-snap),
    color var(--duration-ui-fast) var(--ease-snap));
}
/* Actions, tabs, selects and disclosures share one set of metrics.
   Glyph changes only the aspect ratio; there are no per-surface sizes. */
.vs-control--button {
  --control-display: inline-flex;
  --control-justify: center;
  --control-gap: var(--space-2);
  --control-min-height: var(--interaction-height);
  --control-padding: var(--interaction-pad-y) var(--interaction-pad-x);
  --control-border-width: var(--interaction-edge-width);
  --control-radius: var(--interaction-radius);
  --control-font: var(--font-sans);
  --control-size: var(--interaction-font-size);
  --control-line-height: var(--interaction-line-height);
  --control-weight: var(--interaction-weight);
  --control-align: center;
}
/* Named geometry variants keep layout decisions in the control system. A
   surface may position the resulting box, but it does not redefine how the
   action arranges or spaces its contents. */
.vs-control--menu-row {
  --control-display: grid;
  --control-justify: start;
  --control-align: start;
}
/* A chip is a pill built around a token: a round node, a label beside it, and
   an outline. Its radius is derived rather than taken from the corner scale,
   because fully rounded is a relationship to its own height and not a number
   that stays right when the height changes. Its paint is with the roles
   below, where it has to be read after them. */
.vs-control--chip {
  --control-min-height: 3.25rem;
  --control-gap: var(--space-1-5);
  --control-padding: var(--space-1) var(--space-4) var(--space-1) var(--space-1);
  --control-radius: calc(var(--control-min-height) / 2);
  --control-border-width: var(--border-thick);
}
.vs-control--button.vs-control--glyph {
  width: var(--interaction-height);
  height: var(--interaction-height);
  --control-padding: 0;
  flex: none;
}
.vs-control--button :where(span, code) { font: inherit; letter-spacing: inherit; }
.vs-control--button svg { flex: none; width: var(--space-4); height: var(--space-4); }
/* Keep the browser's select arrow and keyboard interaction. */
.vs-control--select { appearance: auto; --control-align: start; }
.vs-control--disclosure { --control-display: list-item; list-style-position: inside; --control-align: start; }
/* Roles share the same state machinery. */
.vs-control--primary {
  --control-ground: var(--action-primary-ground);
  --control-ground-hover: var(--action-primary-ground-hover);
  --control-ground-pressed: var(--action-primary-ground-pressed);
  --control-edge: var(--interaction-edge);
  --control-edge-hover: var(--interaction-edge);
  --control-edge-pressed: var(--interaction-edge);
  --control-ink: var(--action-primary-ink);
  --control-ink-hover: var(--action-primary-ink);
  --control-ink-pressed: var(--action-primary-ink);
}
.vs-control--secondary {
  --control-ground: var(--action-secondary-ground);
  --control-ground-hover: var(--action-secondary-ground-hover);
  --control-edge: var(--interaction-edge);
  --control-edge-hover: var(--interaction-edge);
  --control-ink: var(--action-secondary-ink);
}
.vs-control--quiet {
  --control-ground: transparent;
  --control-edge: transparent;
  --control-ink: var(--interaction-ink);
}
/* The chip's own paint is one thing: it is outlined in the accent while at
   rest, which is what marks a row of them as a set rather than as loose
   labels. Hover and selection are the shared states, unchanged - a chip is not
   a place to invent a second vocabulary for chosen. Placed after the roles
   because it refines whichever one it is given. */
.vs-control--chip {
  --control-edge: var(--interaction-edge-accent);
  --control-edge-hover: var(--selection-edge);
}
/* Below the width where a row of chips fits, the chip stops being a pill: the
   node sits over its label, and the resting outline goes, because five
   outlines across a phone read as a grid of boxes rather than as a row of
   stages. The shared selection paint still says which one is chosen. */
@media (max-width: 62rem) {
  .vs-control--chip {
    --control-display: flex;
    --control-min-height: 4rem;
    --control-gap: var(--space-1);
    --control-padding: var(--space-1);
    --control-radius: var(--radius-md);
    --control-border-width: 0;
    --control-edge: transparent;
    --control-edge-hover: transparent;
    flex-direction: column;
  }
}
.vs-control[data-status="failed"] {
  --control-ground: var(--interaction-error-ground);
  --control-ground-hover: var(--interaction-error-ground);
  --control-ground-pressed: var(--interaction-error-ground);
  --control-edge: var(--interaction-error-ink);
  --control-edge-hover: var(--interaction-error-ink);
  --control-edge-pressed: var(--interaction-error-ink);
  --control-ink: var(--interaction-error-ink);
  --control-ink-hover: var(--interaction-error-ink);
  --control-ink-pressed: var(--interaction-error-ink);
}
/* Disabled controls and labels for disabled inputs never receive hover paint. */
.vs-control:where(:not(:disabled, [aria-disabled="true"], :disabled + .vs-control)):hover {
  background: var(--control-ground-hover, var(--interaction-ground-hover));
  border-color: var(--control-edge-hover, var(--interaction-edge));
  color: var(--control-ink-hover, var(--interaction-ink));
}
/* Selection is persistent. Tint, border and ink identify it without relying
   on a text-color change or a font-weight change that shifts adjacent tabs. */
.vs-control:is(.is-on, .is-active, [aria-current="page"], [aria-current="true"], [aria-pressed="true"], [aria-selected="true"], [aria-expanded="true"]),
details[open] > .vs-control--disclosure,
:checked + .vs-control {
  background: var(--control-ground-on, var(--selection-ground));
  border-color: var(--control-edge-on, var(--selection-edge));
  color: var(--control-ink-on, var(--selection-ink));
  font-weight: var(--control-weight-on, var(--control-weight, var(--interaction-weight)));
}
.vs-control:is(.is-on, .is-active, [aria-current="page"], [aria-current="true"], [aria-pressed="true"], [aria-selected="true"], [aria-expanded="true"]):where(:not(:disabled, [aria-disabled="true"], :disabled + .vs-control)):hover,
details[open] > .vs-control--disclosure:hover,
:checked:not(:disabled) + .vs-control:where(:not([aria-disabled="true"])):hover {
  background: var(--control-ground-on-hover, var(--control-ground-on, var(--selection-ground-hover)));
  border-color: var(--control-edge-on, var(--selection-edge));
  color: var(--control-ink-on, var(--selection-ink));
}
/* Press is temporary and does not move the target under the pointer. */
.vs-control:where(:not(:disabled, [aria-disabled="true"], :disabled + .vs-control)):active {
  background: var(--control-ground-pressed, var(--interaction-ground-pressed));
  border-color: var(--control-edge-pressed, var(--interaction-edge));
  color: var(--control-ink-pressed, var(--interaction-ink));
}
.vs-control:is(.is-on, .is-active, [aria-current="page"], [aria-current="true"], [aria-pressed="true"], [aria-selected="true"], [aria-expanded="true"]):where(:not(:disabled, [aria-disabled="true"], :disabled + .vs-control)):active,
details[open] > .vs-control--disclosure:active,
:checked:not(:disabled) + .vs-control:where(:not([aria-disabled="true"])):active {
  background: var(--control-ground-on-pressed, var(--control-ground-on, var(--selection-ground-pressed)));
  border-color: var(--control-edge-on, var(--selection-edge));
  color: var(--control-ink-on, var(--selection-ink));
}
/* Native disabled controls suppress activation. For aria-disabled controls,
   the owning component must also suppress activation in its event handler. */
.vs-control:is(:disabled, [aria-disabled="true"]),
:disabled + .vs-control {
  background: var(--interaction-disabled-ground);
  border-color: var(--interaction-disabled-edge);
  color: var(--interaction-disabled-ink);
  cursor: not-allowed;
}
.vs-control:focus-visible,
input:focus-visible + .vs-control {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
}
@media (prefers-reduced-motion: reduce) {
  .vs-control { transition: none; }
}
/* A control carrying a glyph rather than words is square in both axes. Equal
   padding is the whole difference: the horizontal-only padding of a text
   button is what turns a square into a lozenge. */
.vs-control--glyph {
  --control-pad-x: var(--space-2);
  --control-pad-y: var(--space-2);
  --control-justify: center;
}
/* ---------- field: anything a reader types into ------------------------- */
/* Inlaid stock. An input is cut into the page rather than laid on it, so it
   takes the sunken ground and a hairline and casts nothing. */
.vs-field {
  width: var(--field-width, 100%);
  padding: var(--field-pad-y, var(--space-2)) var(--field-pad-x, var(--space-3));
  border: var(--border-hairline) solid var(--field-edge, var(--color-rule));
  border-radius: var(--field-radius, 0);
  background: var(--field-ground, var(--color-paper-sunken));
  color: var(--color-ink);
  font-family: var(--field-font, inherit);
  font-size: var(--field-size, var(--text-meta));
  transition:
    border-color var(--duration-ui-fast) var(--ease-snap),
    background-color var(--duration-ui-fast) var(--ease-snap);
}
.vs-field::placeholder {
  color: var(--color-ink-faint);
}
.vs-field:hover {
  border-color: var(--field-edge-hover, var(--color-rule-strong));
}
.vs-field:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
}
/* ---------- note: something said beside the page, not in it ------------- */
/* A marginal note hangs off a rule. The only thing that legitimately differs
   between one note and another is the weight and colour of that rule, so that
   is the argument and everything else is shared. */
.vs-note {
  margin: var(--note-margin, 0 0 var(--space-8));
  padding-left: var(--note-pad, var(--space-5));
  border-left: var(--note-edge-width, var(--border-hairline)) solid
    var(--note-edge, var(--color-rule));
}
/* The exception to hanging off a rule: a note about work not yet done is cut
   into the mat instead. The dashed score line has exactly one meaning in this
   system - marked out but not yet cut - so it is never decoration. */
.vs-note--scored {
  margin: var(--note-margin, 0 0 var(--space-8));
  padding: var(--space-4) var(--space-5);
  border: var(--border-hairline) dashed var(--color-edge);
  border-left-width: var(--border-hairline);
  border-radius: var(--note-radius, 0);
  background: color-mix(in srgb, var(--color-paper-sunken) 60%, transparent);
  box-shadow: none;
}

/* ---- src/styles/foundation/browser.css ---- */
/* ============================================================================
   BROWSER SURFACES — native chrome shared by every Vaultspec web surface.

   These selectors are global by definition. They live in the shared foundation so the marketing site and generated documentation consume one
   implementation rather than restating scrollbar geometry in page CSS.
   ========================================================================== */
* {
  scrollbar-color: var(--color-edge) var(--color-paper-sunken);
  scrollbar-width: thin;
}
*::-webkit-scrollbar {
  width: var(--space-2);
  height: var(--space-2);
}
*::-webkit-scrollbar-track,
*::-webkit-scrollbar-corner {
  background: var(--color-paper-sunken);
}
*::-webkit-scrollbar-thumb {
  background: var(--color-edge);
  border: var(--border-hairline) solid var(--color-paper-sunken);
  border-radius: var(--radius-cut);
}
*::-webkit-scrollbar-thumb:hover {
  background: var(--color-accent);
}

/* ---- src/styles/foundation/document.css ---- */
/* Defaults shared by the landing page and documentation. */
* { box-sizing: border-box; }
body {
  margin: 0;
  color: var(--color-ink);
  font-family: var(--font-sans);
}
button { font-family: inherit; }
::selection {
  background: var(--color-accent-subtle);
  color: var(--color-accent-text);
}
