/* Printwright — tokens are the only source of visual truth.
   No framework. Tiering: global (raw material) → alias (semantic role) →
   component. Component rules read ALIAS tokens only; a raw ramp value or a
   literal hex inside a component rule breaks theming silently.

   Three laws this sheet enforces:
     1. Green (--chain) marks issuance and nothing else. Links and buttons
        are ink (--action). A green pixel that can't name an issuance is a bug.
     2. Elevation is tonal. No shadows, no gradients, no container outlines —
        surfaces step --bg → --bg-inset → --bg-card and padding does the
        grouping. The only box-shadow permitted is an inset control ring.
     3. A rule survives only where data is tabulated: certificate fact rows,
        the model title block, and spec tables. Nowhere else. */

/* ═══ self-hosted faces · both SIL OFL 1.1 ══════════════════════════════
   Propshaft resolves these from app/assets/fonts with no extra config.
   The font-stretch/weight ranges on the variable face are load-bearing:
   without the descriptors the browser refuses to vary the font and every
   display rule silently renders at normal width. */
@font-face {
  font-family: "Archivo";
  src: url("/assets/archivo-variable-2348e0b4.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("/assets/ibm-plex-mono-400-d803141a.woff2") format("woff2");
  font-weight: 400; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("/assets/ibm-plex-mono-500-3f7bbac1.woff2") format("woff2");
  font-weight: 500; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("/assets/ibm-plex-mono-600-b71798d4.woff2") format("woff2");
  font-weight: 600; font-display: swap;
}

:root {
  /* ── global · bond ramp (cool green-blue cast, hue ≈150°) ───────────── */
  --bond-50:  #FBFCFB;
  --bond-100: #F0F3F1;
  --bond-200: #E2E7E4;
  --bond-300: #CBD3CE;
  --bond-400: #A3AEA8;
  --bond-500: #838F89;
  --ink-600:  #566059;
  --ink-700:  #3C453F;
  --ink-800:  #262D28;
  --ink-900:  #141916;

  /* ── global · surfaces ──────────────────────────────────────────────
     All three share one hue family (chroma spread 5/5/4). A near-neutral
     white card on tinted bond reads as a different material. */
  --surf-ground-l: #E5EAE7;
  --surf-inset-l:  #EDF2EF;
  --surf-card-l:   #F4F8F5;

  --surf-ground-d: #121614;
  --surf-inset-d:  #1A201D;
  --surf-card-d:   #232B27;

  /* ── global · accents · ONE accent, ONE meaning ─────────────────────── */
  --assay-700: #1B5E45;   /* issuance text, light  */
  --assay-500: #2E9370;   /* issuance mark, light  */
  --assay-300: #4FB98D;   /* issuance, dark        */

  --brass-l: #7C6423;     /* pending, light */
  --brass-d: #A78D43;     /* pending, dark  */
  --wax-l:   #9B3226;     /* void, light    */
  --wax-d:   #E26C5A;     /* void, dark     */

  /* ── alias · light theme (default) ──────────────────────────────────── */
  --bg:       var(--surf-ground-l);
  --bg-inset: var(--surf-inset-l);
  --bg-card:  var(--surf-card-l);

  --text:   var(--ink-900);   /* 14.62:1 on bg  AAA */
  --text-2: var(--ink-700);   /*  8.16:1 on bg  AAA */
  --text-3: var(--ink-600);   /*  5.37:1 on bg  AA  */

  --hairline:   var(--bond-300); /* tabulated data only — decorative divider */
  --field-edge: var(--ink-600);  /* input underline, 6.10:1 on card — WCAG 1.4.11 */

  --chain:      var(--assay-700); /* on-chain truth + issuance. NOTHING else. */
  --chain-mark: var(--assay-500);

  --action:       var(--ink-900);  /* buttons + links. Never green. */
  --action-hover: var(--ink-700);  /* primary drops ~8% lightness */
  --on-action:    var(--bond-50);  /* 17.30:1 on --action  AAA */

  --state-settled: var(--ink-900);
  --state-pending: var(--brass-l);
  --state-void:    var(--wax-l);

  --focus: var(--action);       /* ≥14.6:1 on every surface */

  /* ── spacing · 4px base. No arbitrary values in layout. ─────────────── */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px;

  /* ── radius · inner ≈ outer − padding when nesting ──────────────────── */
  --r-xs:   10px;
  --r-sm:   14px;
  --r-md:   20px;
  --r-lg:   28px;
  --r-xl:   36px;
  --r-pill: 999px;

  /* ── type ───────────────────────────────────────────────────────────── */
  --font-sans: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --t-label: 13px; --t-small: 14px; --t-body: 16px; --t-sub: 20px;
  --t-h3: 25px; --t-h2: 31px; --t-h1: 39px; --t-display: 49px;

  /* ── layout ─────────────────────────────────────────────────────────── */
  --measure: 65ch;
  --container: 1120px;

  /* ── texture ────────────────────────────────────────────────────────── */
  --texture-alpha: 0.05;
}

/* ═══ dark · "night bond" ═══════════════════════════════════════════════
   Not an inversion. Surfaces step LIGHTER for elevation; text is warm
   off-white, never #FFF; accents brighten to hold AA on --bg-card, which
   is the worst case because it is the most elevated surface. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: var(--surf-ground-d); --bg-inset: var(--surf-inset-d); --bg-card: var(--surf-card-d);
    --text: #E4EAE6; --text-2: #A9B4AE; --text-3: #8B968F;
    --hairline: #333D38; --field-edge: #8B968F;
    --chain: var(--assay-300); --chain-mark: var(--assay-300);
    --action: #E4EAE6; --action-hover: var(--bond-200); --on-action: #121614;
    --state-settled: #E4EAE6; --state-pending: var(--brass-d); --state-void: var(--wax-d);
    --focus: var(--action);
    /* light-on-dark reads stronger at equal opacity */
    --texture-alpha: 0.035;
  }
}

/* Manual override must beat the media query in BOTH directions. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: var(--surf-ground-d); --bg-inset: var(--surf-inset-d); --bg-card: var(--surf-card-d);
  --text: #E4EAE6; --text-2: #A9B4AE; --text-3: #8B968F;
  --hairline: #333D38; --field-edge: #8B968F;
  --chain: var(--assay-300); --chain-mark: var(--assay-300);
  --action: #E4EAE6; --action-hover: var(--bond-200); --on-action: #121614;
  --state-settled: #E4EAE6; --state-pending: var(--brass-d); --state-void: var(--wax-d);
  --focus: var(--action);
  --texture-alpha: 0.035;
}
:root[data-theme="light"] {
  color-scheme: light;
  --bg: var(--surf-ground-l); --bg-inset: var(--surf-inset-l); --bg-card: var(--surf-card-l);
  --text: var(--ink-900); --text-2: var(--ink-700); --text-3: var(--ink-600);
  --hairline: var(--bond-300); --field-edge: var(--ink-600);
  --chain: var(--assay-700); --chain-mark: var(--assay-500);
  --action: var(--ink-900); --action-hover: var(--ink-700); --on-action: var(--bond-50);
  --state-settled: var(--ink-900); --state-pending: var(--brass-l); --state-void: var(--wax-l);
  --focus: var(--action);
  --texture-alpha: 0.05;
}

/* ═══ base ══════════════════════════════════════════════════════════════ */
* { box-sizing: border-box; }

html { color-scheme: light dark; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 var(--t-body)/1.55 var(--font-sans);
  font-stretch: 100%;
  -webkit-font-smoothing: antialiased;
}

img, svg, canvas { max-width: 100%; }
img { display: block; height: auto; }

a { color: var(--action); text-underline-offset: 2px; }

/* With no outlines anywhere, the focus ring is the only boundary a keyboard
   user ever sees. Never remove it without an equally visible replacement. */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 8px;
}

/* ── the contour ground ──────────────────────────────────────────────────
   One texture per page, on the ground only, never inside a card. It is a
   substrate, not a pattern: above 6% alpha the page starts to look
   decorated. Content sits above it at z-index 1. */
#ground-tex {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
body > *:not(:where(#ground-tex, w3m-modal, appkit-modal)) { position: relative; z-index: 1; }

/* ═══ typography ════════════════════════════════════════════════════════
   Width axis via font-stretch, weight via font-weight — never
   font-variation-settings, which does not compose: a child setting "wght"
   wipes the parent's width and collapses display type to normal. */
h1, h2, h3, h4 {
  margin: 0 0 var(--s4);
  color: var(--text);
  text-wrap: balance;
}
h1 { font-size: var(--t-h1); line-height: 1.1;  letter-spacing: -.02em;  font-stretch: 118%; font-weight: 700; }
h2 { font-size: var(--t-h2); line-height: 1.15; letter-spacing: -.02em;  font-stretch: 118%; font-weight: 700; }
h3 { font-size: var(--t-h3); line-height: 1.25; letter-spacing: -.01em;  font-stretch: 112%; font-weight: 700; }
h4 { font-size: var(--t-sub); line-height: 1.3; font-stretch: 112%; font-weight: 600; }

p { margin: 0 0 var(--s3); }
p:last-child { margin-bottom: 0; }

.t-small   { font-size: var(--t-small); line-height: 1.5; }
.t-caption { font-size: var(--t-label); line-height: 1.45; }
.muted     { color: var(--text-3); }
.prose     { max-width: var(--measure); }
.prose p   { color: var(--text-2); }

/* Uppercase only ever at label size with ≥.16em tracking. Never a sentence. */
.label, .eyebrow {
  font-size: var(--t-label); line-height: 1.2; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-3);
}

/* Every number, identifier, hash and measurement. On-chain facts
   additionally take --chain and never render below the body text
   around them — they are the product's differentiator, not chrome. */
.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-small);
}
a.mono, .mono a { color: var(--chain); text-decoration: underline; }
.price { font-stretch: 118%; font-weight: 700; font-variant-numeric: tabular-nums; }

.container { max-width: var(--container); margin: 0 auto; padding: 0 var(--s5); }
@media (max-width: 480px) { .container { padding: 0 var(--s4); } }

/* The gap under the header is the page's own, not each view's — otherwise
   every view that happens not to open with a hero sits flush against the
   chrome. Views keep their internal rhythm and drop their leading margin. */
main.container { padding-top: var(--s7); }
main.container > *:first-child { margin-top: 0; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ═══ shell ═════════════════════════════════════════════════════════════ */
body > .site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--bg-card); padding: var(--s4) 0;
}
.site-header .container {
  display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap;
}

.wordmark {
  display: inline-flex; align-items: center; gap: 11px;
  color: var(--text); text-decoration: none; flex: none;
}
/* The one licensed green in the chrome — it *is* the issuance mark. */
.wordmark svg, .wordmark img { width: 40px; height: 40px; flex: none; color: var(--chain); }
.wordmark-copy { display: block; }
.wordmark-name {
  display: block; font-size: var(--t-sub); line-height: 1.05;
  font-stretch: 118%; font-weight: 700; letter-spacing: -.03em;
}
.wordmark .tagline {
  display: block; margin-top: 3px; font-size: 12px; line-height: 1.2;
  font-stretch: 100%; font-weight: 400; color: var(--text-3);
}

/* A filled pill, not a bordered input. min-width:0 on the inner field is
   required — flex items default to min-width:auto and it overflows at 360. */
.catalog-search {
  position: relative; flex: 1; min-width: min(280px, 100%); z-index: 10;
}
.search-form {
  width: 100%; min-width: 0;
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s2) var(--s3) var(--s2) var(--s4);
  background: var(--bg-inset); border-radius: var(--r-pill);
}
.search-form input[type="search"] {
  flex: 1; min-width: 0; padding: var(--s1) 0;
  font: inherit; color: var(--text);
  background: transparent; border: 0; outline: none;
  -webkit-appearance: none; appearance: none;
}
/* The field clears its own outline, so the focus ring — the only boundary a
   keyboard user gets — has to live on the pill it sits inside. */
.search-form:focus-within { outline: 2px solid var(--focus); outline-offset: 3px; }
.search-form input[type="search"]::placeholder { color: var(--text-3); }
.search-form input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
.search-clear {
  flex: none; width: 32px; height: 32px; padding: 0; cursor: pointer;
  border: 0; border-radius: var(--r-pill); background: transparent;
  color: var(--text-3); font: 24px/1 var(--font-sans);
}
.search-clear:hover { background: var(--bg-card); color: var(--text); }
.search-clear[hidden] { display: none; }
/* Inside the inset pill the submit steps UP a tone, which is the elevation
   direction that reads as "control" without adding an outline. */
.search-form .btn {
  flex: none; padding: var(--s2) var(--s4); min-height: 40px;
  background: var(--bg-card); font-size: 14.5px;
}
.search-form .btn:hover { background: var(--action); color: var(--on-action); }
.search-suggestions {
  position: absolute; top: calc(100% + var(--s2)); left: 0; right: 0;
  max-height: min(480px, 70vh); overflow-y: auto;
  z-index: 2; padding: 2px; pointer-events: auto;
  border-radius: var(--r-lg); background: var(--action);
}
.search-suggestions[hidden] { display: none; }
.search-suggestion-list {
  display: flex; flex-direction: column; padding: var(--s2);
  border-radius: calc(var(--r-lg) - 2px); background: var(--bg-card);
}
.search-suggestion {
  display: grid; grid-template-columns: 56px minmax(0, 1fr) auto;
  align-items: center; gap: var(--s3); padding: var(--s2);
  border-radius: var(--r-sm); color: var(--text); text-decoration: none;
}
.search-suggestion:hover, .search-suggestion:focus-visible { background: var(--bg-inset); }
.search-suggestion img, .search-suggestion-thumb {
  width: 56px; aspect-ratio: 4 / 3; display: block; object-fit: cover;
  border-radius: var(--r-xs); background: var(--bg-inset);
}
.search-suggestion-copy { display: flex; flex-direction: column; min-width: 0; }
.search-suggestion-copy strong, .search-suggestion-copy span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.search-suggestion-copy span { color: var(--text-3); font-size: var(--t-label); }
.search-suggestion-price { white-space: nowrap; font-size: var(--t-label); font-weight: 600; }
.search-suggestion-all {
  margin-top: var(--s1); padding: var(--s3); border-radius: var(--r-sm);
  color: var(--text-2); font-size: var(--t-small);
}
.search-suggestion-empty { margin: 0; padding: var(--s4) var(--s3); color: var(--text-3); }

.header-actions {
  display: flex; align-items: center; justify-content: flex-end;
  gap: var(--s3); flex-wrap: wrap;
}
.header-actions a, .header-actions button { white-space: nowrap; }
.designer-site-header .container { justify-content: space-between; }
.designer-header-actions { margin-left: auto; }
.designer-header-actions a {
  display: inline-flex; align-items: center; min-height: 40px; padding: var(--s2);
  border-radius: var(--r-sm); text-decoration: none;
}
.designer-header-actions a:hover { background: var(--bg-inset); }
.designer-site-footer { color: var(--text-2); }
.designer-site-footer .footer-links { margin-top: var(--s2); }
.theme-toggle {
  min-height: 40px; margin-left: auto; padding: var(--s2) var(--s3); cursor: pointer;
  border: 0; border-radius: var(--r-pill);
  background: var(--bg-inset); color: var(--text); font: inherit;
}
.theme-toggle:hover { background: var(--action); color: var(--on-action); }
.wallet-control { display: inline-flex; align-items: center; gap: var(--s2); }
.wallet-control[data-connected="true"] .wallet-account {
  max-width: 9.5rem; overflow: hidden; text-overflow: ellipsis;
  color: var(--chain); font-family: var(--font-mono); font-size: 12px;
}
.wallet-disconnect { color: var(--text-3); font-size: 12px; }
.wallet-help { display: block; margin-top: var(--s1); }
/* In the header the pointer sits beside a connected/disconnected pair, where a
   block would push the row apart; once a wallet is connected it has served its
   purpose and goes away. */
.wallet-control .wallet-help { display: inline; margin-top: 0; }
.wallet-control[data-connected="true"] .wallet-help { display: none; }

@media (max-width: 760px) {
  .header-actions { flex: 1 0 100%; justify-content: flex-start; }
  .designer-header-actions { margin-left: 0; }
}
@media (max-width: 480px) {
  .designer-header-actions { gap: var(--s1); }
  .designer-header-actions a { padding: var(--s2) var(--s1); }
  .designer-header-actions .theme-toggle { padding: var(--s2); }
}

.site-footer {
  margin-top: var(--s7); padding: var(--s5) 0;
  color: var(--text-3); font-size: var(--t-small);
}
.site-footer a { color: var(--text-2); }
.footer-links { display: block; margin-top: var(--s3); }

/* ═══ buttons and actions ═══════════════════════════════════════════════
   Never green: a button is navigation, not an issuance. */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 15px var(--s5);
  font: 600 15.5px/1.2 var(--font-sans); font-stretch: 100%;
  text-align: center; text-decoration: none; cursor: pointer;
  border: 0; border-radius: var(--r-pill);
  background: var(--bg-inset); color: var(--text);
}
.btn:hover:not(:disabled) { background: var(--bg-card); }
.btn-primary { background: var(--action); color: var(--on-action); }
.btn-primary:hover:not(:disabled) { background: var(--action-hover); }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-block { width: 100%; }

.copy-btn {
  display: inline-flex; align-items: center;
  padding: var(--s1) var(--s3);
  font: 600 12px/1.4 var(--font-sans); cursor: pointer;
  border: 0; border-radius: var(--r-pill);
  background: var(--bg-inset); color: var(--text-3);
}
.copy-btn:hover { color: var(--text); }

.linklike {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--action); font: inherit; text-decoration: underline;
}

/* ═══ filters ═══════════════════════════════════════════════════════════
   The selected state is ink, not green — a filter is not an issuance. */
.filters { display: flex; gap: var(--s2); flex-wrap: wrap; margin: var(--s5) 0; }
.pill {
  display: inline-flex; align-items: center;
  padding: 9px 17px; border: 0; border-radius: var(--r-pill);
  background: var(--bg-card); color: var(--text-2);
  font-size: 13.5px; font-weight: 500; text-decoration: none;
}
.pill:hover { color: var(--text); }
.pill[aria-current="true"] { background: var(--action); color: var(--on-action); font-weight: 600; }

/* ═══ catalogue ═════════════════════════════════════════════════════════ */
.catalog-results {
  scroll-margin-top: calc(var(--sticky-header-height, 80px) + var(--s4));
}
.catalog-results-head {
  display: flex; align-items: end; justify-content: space-between; gap: var(--s4); flex-wrap: wrap;
  margin-top: var(--s7);
}
.catalog-results-head h2 { margin: var(--s1) 0 0; font-size: var(--t-h2); }
.card-grid, .model-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: var(--s4);
  margin: var(--s5) 0;
}

.model-card {
  display: flex; flex-direction: column;
  background: var(--bg-card); border-radius: var(--r-lg);
  overflow: hidden; text-decoration: none; color: var(--text);
}
.model-card:hover { background: var(--bond-100); }
@media (prefers-color-scheme: dark) { .model-card:hover { background: #2A332E; } }
:root[data-theme="dark"] .model-card:hover { background: #2A332E; }
:root[data-theme="light"] .model-card:hover { background: var(--bond-100); }

.model-card img,
.model-card .card-thumb {
  aspect-ratio: 4 / 3; width: 100%; object-fit: cover;
  background: var(--bg-inset);
}
.model-card .card-body {
  display: flex; flex-direction: column; gap: var(--s2);
  padding: var(--s4);
}
.model-card h3, .card-name {
  margin: 0; font-size: 17.5px; line-height: 1.25;
  font-stretch: 112%; font-weight: 600; letter-spacing: -.01em;
}
/* Taxonomy is not issuance — it never takes the accent. */
.card-taxonomy, .card-taxo {
  margin: 0; font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--text-3);
}
.card-price-row, .card-foot {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); padding-top: var(--s2);
}
.card-price-row .price, .card-price { font-size: var(--t-sub); }
.card-units {
  font-family: var(--font-mono); font-size: 10.5px;
  font-variant-numeric: tabular-nums; color: var(--text-3);
}

.empty-state {
  display: flex; flex-direction: column; align-items: center; gap: var(--s3);
  padding: var(--s8) var(--s5); text-align: center; color: var(--text-3);
}
.empty-state h2, .empty-state h3 {
  margin: 0; font-size: var(--t-sub); font-stretch: 112%; color: var(--text);
}
.empty-state p { margin: 0; max-width: 46ch; }

/* ═══ landing ═══════════════════════════════════════════════════════════ */
.hero {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(340px, 4fr);
  align-items: center; gap: var(--s7); margin: 0 0 var(--s7);
}
.hero-compact { display: block; max-width: var(--measure); }
.hero h1 {
  margin: 0 0 var(--s4);
  font-size: clamp(40px, 8vw, 74px); line-height: 1.0;
  font-stretch: 125%; font-weight: 700; letter-spacing: -.025em;
}
.hero p { margin: 0; max-width: 58ch; font-size: 17px; color: var(--text-2); }
.hero-shopkeeper {
  min-width: 0; padding: var(--s5); border-radius: var(--r-xl); background: var(--bg-card);
}
.hero-shopkeeper-head {
  display: flex; align-items: start; justify-content: space-between; gap: var(--s3);
}
.hero-shopkeeper-head h2 { margin: var(--s1) 0 0; font-size: var(--t-sub); }
.hero-shopkeeper-head p { font-size: 10px; }
.hero-shopkeeper-actions {
  display: flex; align-items: center; justify-content: flex-end; gap: var(--s3); flex-wrap: wrap;
}
.hero-shopkeeper-actions a, .hero-shopkeeper-actions button { white-space: nowrap; }
.hero-chat-messages {
  min-height: 170px; max-height: 440px; margin: var(--s3) 0;
  padding-right: var(--s2); overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: var(--text-3) transparent;
}
.hero-chat-messages::-webkit-scrollbar { width: 8px; }
.hero-chat-messages::-webkit-scrollbar-track { background: transparent; }
.hero-chat-messages::-webkit-scrollbar-thumb {
  border-radius: var(--r-pill); background: var(--text-3);
}
.hero-chat-messages::-webkit-scrollbar-button { display: none; }
.hero-shopkeeper .chat-trace { display: none; }
.hero-shopkeeper .chat-model-result:nth-child(n + 3) { display: none; }
.hero-shopkeeper #chat_empty_state { padding: var(--s4) var(--s2); background: transparent; }
.hero-shopkeeper #chat_empty_state > p { font-size: var(--t-small); }
.hero-shopkeeper .chat-prompts { justify-content: flex-start; }
.hero .hero-shopkeeper-note { margin-top: var(--s3); font-size: var(--t-label); }
@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; gap: var(--s5); }
}

.doors-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s3); margin-bottom: var(--s5);
}
.door {
  display: flex; flex-direction: column; gap: var(--s2);
  padding: var(--s5); border-radius: var(--r-lg); background: var(--bg-card);
}
.door h2 { margin: 0; font-size: var(--t-sub); font-stretch: 112%; font-weight: 600; letter-spacing: 0; }
.door p { margin: 0; font-size: var(--t-small); color: var(--text-2); }

.steps-strip {
  display: flex; gap: var(--s4); flex-wrap: wrap; align-items: center;
  margin-bottom: var(--s5); padding: var(--s3) var(--s4);
  border-radius: var(--r-md); background: var(--bg-inset);
  font-size: var(--t-small); color: var(--text-2);
}
.step { display: flex; align-items: center; gap: var(--s2); }
.step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; flex: none; border-radius: var(--r-pill);
  background: var(--action); color: var(--on-action);
  font-family: var(--font-mono); font-size: 12px; font-weight: 700;
}

.catalog-browse {
  display: grid; gap: var(--s4); margin: var(--s5) 0;
  padding: var(--s5); border-radius: var(--r-xl); background: var(--bg-card);
}
/* Grid children default to min-width:auto and refuse to shrink under their
   content — which lets the compact scroll strip below drag the whole page
   sideways at 360 instead of scrolling inside itself. */
.catalog-browse > * { min-width: 0; }
.catalog-browse h2 {
  margin: 0 0 var(--s2); font-size: var(--t-label); font-stretch: 100%;
  font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-3);
}
.browse-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--s2); }
.browse-card {
  display: block; padding: var(--s3) var(--s4);
  border-radius: var(--r-md); background: var(--bg-inset);
  color: var(--text); text-decoration: none; font-size: var(--t-small);
}
.browse-card strong, .browse-card span { display: block; }
.browse-card strong { font-weight: 600; }
.browse-card span {
  margin-top: 2px; color: var(--text-3); white-space: nowrap;
  font-family: var(--font-mono); font-size: 11.5px; font-variant-numeric: tabular-nums;
}
.browse-card:hover, .browse-card[aria-current="page"] { background: var(--action); color: var(--on-action); }
.browse-card:hover span, .browse-card[aria-current="page"] span { color: var(--on-action); opacity: .75; }

@media (max-width: 480px) {
  .catalog-browse { padding: var(--s4); }
  .browse-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .catalog-browse-compact .browse-grid {
    display: flex; overflow-x: auto; padding-bottom: var(--s1);
    scroll-snap-type: x proximity;
  }
  .catalog-browse-compact .browse-card { flex: 0 0 150px; scroll-snap-align: start; }
}

.early-access-panel {
  display: flex; gap: var(--s5); align-items: end; justify-content: space-between;
  margin: var(--s7) 0; padding: var(--s5);
  border-radius: var(--r-xl); background: var(--bg-card);
}
.early-access-panel h2 { margin: 0 0 var(--s1); font-size: var(--t-h3); }
.early-access-panel p { margin: 0; color: var(--text-2); }
.early-access-form { display: flex; gap: var(--s2); flex: 0 1 460px; }
.early-access-form input[type="email"] {
  flex: 1; min-width: 0; padding: var(--s3) var(--s4); font: inherit;
  color: var(--text); background: var(--bg-inset);
  border: 0; border-bottom: 1.5px solid var(--field-edge); border-radius: var(--r-sm);
}
@media (max-width: 640px) {
  .early-access-panel, .early-access-form { align-items: stretch; flex-direction: column; }
  .early-access-form { flex-basis: auto; }
}

/* ═══ model page ════════════════════════════════════════════════════════ */
.model-page {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  align-items: start; gap: var(--s5) var(--s4); margin-top: 0;
}
/* align-items: start — never let the grid stretch a short panel and leave
   dead space under it. */
@media (max-width: 860px) { .model-page { grid-template-columns: 1fr; gap: var(--s5); } }
.model-main { display: flex; flex-direction: column; gap: var(--s5); min-width: 0; }
.model-head {
  grid-column: 1 / -1;
  display: flex; flex-direction: column; gap: var(--s2);
}
.model-head h1 { margin: 0; font-size: var(--t-h2); }
.model-head p { margin: 0; }

.model-preview, .gallery {
  display: flex; flex-direction: column; gap: var(--s4);
  padding: var(--s5); border-radius: var(--r-lg); background: var(--bg-card);
}
.model-preview-stage {
  position: relative; width: 100%; aspect-ratio: 16 / 10; min-height: 240px;
  overflow: hidden; border-radius: var(--r-md); background: var(--bg-inset);
}
.model-preview-stage canvas, .model-preview-stage img, .model-preview-placeholder {
  width: 100%; height: 100%; display: block;
}
.model-preview-stage [hidden] { display: none !important; }
.model-preview-stage canvas { cursor: grab; touch-action: none; }
.model-preview-stage canvas:active { cursor: grabbing; }
.model-preview-stage img { position: absolute; inset: 0; object-fit: contain; }
.render-turntable-stage {
  aspect-ratio: 4 / 3; min-height: 0;
  cursor: ew-resize; touch-action: none; user-select: none; outline-offset: 3px;
}
.render-turntable-stage:focus-visible { outline: 2px solid var(--focus); }
.render-turntable-stage img {
  pointer-events: none; transform-origin: center; will-change: transform;
}
.model-preview[data-dragging="true"] .render-turntable-stage { cursor: grabbing; }
.model-preview-placeholder {
  display: grid; place-items: center; color: var(--text-3); background: var(--bg-inset);
}
.model-preview-status { margin: 0; color: var(--text-3); }
.gallery img { border-radius: var(--r-md); }

/* The drawing-sheet device — one of the two licensed hairline uses. */
.title-block {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
  gap: 0 var(--s4); margin: 0;
}
/* Each cell stacks its own label over its value and carries the rule, the way
   a drawing sheet's title block does. Row subgrid is what keeps the values on
   one baseline when a longer label wraps to two lines — without it a single
   wrapping label drops its own value below every other cell's and the
   tabulated read falls apart. */
.title-block > div {
  display: grid; grid-template-rows: subgrid; grid-row: span 2; row-gap: var(--s1);
  border-top: 1px solid var(--hairline);
  padding: var(--s3) var(--s3) var(--s3) 0;
}
@supports not (grid-template-rows: subgrid) {
  .title-block > div { display: flex; flex-direction: column; gap: var(--s1); }
}
.title-block dt {
  font-size: 10px; font-weight: 600; letter-spacing: .13em;
  text-transform: uppercase; color: var(--text-3);
}
.title-block dd {
  margin: 0;
  font-family: var(--font-mono); font-size: 13px; font-weight: 500;
  font-variant-numeric: tabular-nums; color: var(--text);
  overflow-wrap: anywhere;
}

.buy-panel {
  position: sticky; top: calc(var(--sticky-header-height, 80px) + var(--s4));
  display: flex; flex-direction: column; gap: var(--s3);
  padding: var(--s5); border-radius: var(--r-lg); background: var(--bg-card);
}
.buy-panel h2, .buy-panel h3 { margin: 0; font-size: var(--t-sub); font-stretch: 118%; letter-spacing: -.015em; }

.offer-row {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) var(--s4); border: 0; border-radius: var(--r-md);
  background: var(--bg-inset); color: var(--text); cursor: pointer;
}
.offer-row input[type="radio"] {
  appearance: none; -webkit-appearance: none; margin: 0;
  width: 16px; height: 16px; flex: none; border-radius: 6px;
  /* the one permitted box-shadow: a control indicator, not elevation */
  box-shadow: inset 0 0 0 2px currentColor; cursor: pointer;
}
.offer-row:has(input:checked) { background: var(--action); color: var(--on-action); }
.offer-row:has(input:checked) input[type="radio"] { box-shadow: inset 0 0 0 5px currentColor; }
.offer-row .price { margin-left: auto; font-stretch: 118%; font-weight: 600; }
.offer-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.offer-copy .t-caption { color: inherit; opacity: .72; }

.license-quantity {
  display: grid; grid-template-columns: auto 76px minmax(0, 1fr); align-items: center; gap: var(--s3);
  padding: var(--s3) var(--s4); border-radius: var(--r-md); background: var(--bg-inset);
}
.license-quantity[hidden] { display: none; }
.license-quantity label { font-size: var(--t-small); font-weight: 600; }
.license-quantity input {
  width: 100%; padding: var(--s2); border: 1px solid var(--field-edge); border-radius: var(--r-sm);
  background: var(--bg); color: var(--text); font: inherit; font-variant-numeric: tabular-nums;
}
.license-quantity-total { text-align: right; color: var(--text-2); }
@media (max-width: 420px) {
  .license-quantity { grid-template-columns: auto 76px; }
  .license-quantity-total { grid-column: 1 / -1; text-align: left; }
}

.offer-terms { display: flex; flex-direction: column; gap: var(--s2); }
.offer-terms summary { cursor: pointer; color: var(--text-2); }
.offer-terms pre { max-height: 16em; overflow-y: auto; white-space: pre-wrap; margin: var(--s2) 0 0; }
.checkout-status { min-height: 24px; }
.checkout-status:empty { min-height: 0; }
[data-checkout-target="status"], [data-checkout-target="receipt"] {
  scroll-margin-top: calc(var(--sticky-header-height, 80px) + var(--s4));
}

/* ═══ purchase batch ════════════════════════════════════════════════════ */
.cart-page { margin-top: 0; }
.cart-page .page-head h1 { margin-bottom: var(--s2); }
.cart-empty { border-radius: var(--r-xl); background: var(--bg-card); }
.cart-layout {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(300px, 4fr);
  align-items: start; gap: var(--s5);
}
.cart-lines { display: flex; flex-direction: column; gap: var(--s3); }
.cart-line {
  display: grid; grid-template-columns: 80px minmax(0, 1fr) auto auto;
  align-items: center; gap: var(--s4); padding: var(--s4);
  border-radius: var(--r-lg); background: var(--bg-card);
}
.cart-line-thumb, .cart-line-thumb img, .cart-line-thumb span {
  width: 80px; aspect-ratio: 4 / 3; display: block;
}
.cart-line-thumb img {
  object-fit: cover; border-radius: var(--r-sm); background: var(--bg-inset);
}
.cart-line-thumb span { border-radius: var(--r-sm); background: var(--bg-inset); }
.cart-line-copy h2 { margin: var(--s1) 0; font-size: var(--t-sub); }
.cart-line-copy h2 a { color: inherit; text-decoration: none; }
.cart-line-copy p { margin: 0; }
.cart-line-actions { display: flex; align-items: center; gap: var(--s3); }
.cart-quantity-form { display: flex; align-items: center; gap: var(--s2); }
.cart-quantity-form label { font-size: var(--t-small); font-weight: 600; }
.cart-quantity-form input {
  width: 68px; padding: var(--s2); border: 1px solid var(--field-edge); border-radius: var(--r-sm);
  background: var(--bg-inset); color: var(--text); font: inherit;
}
.cart-quantity-form .btn { min-height: 38px; padding: var(--s2) var(--s3); font-size: var(--t-small); }
.cart-remove { color: var(--text-3); }
.cart-line-subtotal { white-space: nowrap; font-variant-numeric: tabular-nums; }
.cart-summary {
  position: sticky; top: var(--s4); padding: var(--s5);
  border-radius: var(--r-xl); background: var(--bg-card);
}
.cart-summary h2 { margin: var(--s1) 0 0; font-size: var(--t-sub); }
.cart-total {
  margin: var(--s2) 0 var(--s4); font-size: var(--t-h2); line-height: 1;
  font-weight: 700; font-variant-numeric: tabular-nums;
}
.batch-license-list { display: flex; flex-direction: column; gap: var(--s3); padding-left: var(--s5); }
.batch-license { padding-left: var(--s1); }
.batch-license a { display: block; margin-top: var(--s1); }
@media (max-width: 860px) {
  .cart-layout { grid-template-columns: 1fr; }
  .cart-summary { position: static; }
}
@media (max-width: 620px) {
  .cart-line { grid-template-columns: 72px minmax(0, 1fr); }
  .cart-line-thumb, .cart-line-thumb img, .cart-line-thumb span { width: 72px; }
  .cart-line-actions { grid-column: 1 / -1; align-items: flex-start; flex-wrap: wrap; }
  .cart-line-subtotal { grid-column: 1 / -1; justify-self: end; }
}

.trust-strip {
  display: flex; gap: var(--s4); align-items: center; flex-wrap: wrap;
  padding: var(--s3) var(--s4); border-radius: var(--r-md);
  background: var(--bg-inset); font-size: var(--t-small); color: var(--text-2);
}

/* ═══ demo banner ═══════════════════════════════════════════════════════
   First element inside <main> on every page, so it is above the fold
   everywhere without any view opting in. It steps to --bg-card (the most
   elevated surface) rather than tinting: per the colour law a filled
   coloured panel would claim a state the page does not have. Prominence
   comes from the brass badge and the bold lead clause. Brass is the
   provisional/pending accent — green is issuance only, wax is failure, and
   this is neither. */
.demo-banner {
  display: flex; align-items: center; gap: var(--s3) var(--s4); flex-wrap: wrap;
  margin-bottom: var(--s5); padding: var(--s3) var(--s4);
  border-radius: var(--r-md); background: var(--bg-card);
  font-size: var(--t-small); color: var(--text-2);
}
.demo-banner-copy { margin: 0; flex: 1 1 24ch; max-width: var(--measure); }
.demo-banner-copy strong { color: var(--text); font-weight: 600; }
.demo-banner-link { flex: none; margin-left: auto; white-space: nowrap; }

/* The badge is the only element allowed to carry the brass fill: it is a
   label, not a surface, so it cannot be mistaken for page-wide state. */
.demo-badge {
  flex: none; padding: var(--s1) var(--s3); border-radius: var(--r-pill);
  background: var(--state-pending); color: var(--bg-card);
  font-size: 12px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase;
}

@media (max-width: 620px) {
  .demo-banner { gap: var(--s2) var(--s3); }
  .demo-banner-copy { flex-basis: 100%; }
  .demo-banner-link { margin-left: 0; }
}

/* ═══ status marks ══════════════════════════════════════════════════════
   Shape carries the meaning so it survives greyscale and every form of
   colour blindness; hue only reinforces. The word is mandatory — never
   ship the mark alone. Green never appears here: "settled" is a judgement,
   not an issuance. */
.state {
  display: inline-flex; align-items: center; gap: var(--s2);
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
}
.state svg { flex: none; }
.st-settled { color: var(--state-settled); }
.st-pending { color: var(--state-pending); }
.st-void    { color: var(--state-void); }

/* ═══ certificate — the hero artifact ═══════════════════════════════════ */
.verify-page { max-width: 720px; margin: 0 auto; }

/* No coloured background fill: the status colour lives in the mark and the
   label, not in a tinted panel. */
.verify-banner {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  margin-bottom: var(--s4); padding: var(--s3) var(--s4);
  border-radius: var(--r-md); background: var(--bg-inset);
  font-size: var(--t-body); color: var(--text-2);
}
.banner-ok      { --state-color: var(--state-settled); }
.banner-pending { --state-color: var(--state-pending); }
.banner-bad     { --state-color: var(--state-void); }
.verify-banner .state, .verify-banner > .state-mark { color: var(--state-color, var(--text)); }
.verify-banner > .state-mark { flex: none; }

.cert-card {
  display: flex; flex-direction: column; gap: var(--s5);
  padding: var(--s5); border-radius: var(--r-lg); background: var(--bg-card);
}
.cert-top { display: flex; align-items: start; justify-content: space-between; gap: var(--s4); }
.cert-eyebrow {
  display: block; margin-bottom: var(--s2);
  font-size: 10px; font-weight: 600; letter-spacing: .19em;
  text-transform: uppercase; color: var(--text-3);
}
/* The largest object on the verify page. Nothing outranks it. */
.cert-id {
  margin: 0; font-family: var(--font-mono); font-weight: 500;
  font-size: clamp(30px, 5.4vw, 42px); line-height: 1.05;
  letter-spacing: -.035em; font-variant-numeric: tabular-nums lining-nums;
  color: var(--text); overflow-wrap: anywhere;
}
.cert-model { display: flex; gap: var(--s4); align-items: center; }
.cert-thumb { width: 96px; flex: none; border-radius: var(--r-md); background: var(--bg-inset); }
.cert-model-title { margin: 0 0 var(--s1); font-size: var(--t-sub); font-stretch: 112%; }
.cert-model-title a { color: inherit; text-decoration: none; }
.cert-model-title a:hover { text-decoration: underline; }

/* Fact rows — the second licensed hairline use. */
.cert-facts, .fact-grid { display: grid; grid-template-columns: 88px minmax(0, 1fr); margin: 0; }
.cert-facts dt, .fact-grid dt {
  padding: var(--s3) var(--s4) var(--s3) 0;
  font-size: 11.5px; color: var(--text-3);
}
.cert-facts dd, .fact-grid dd {
  margin: 0; padding: var(--s3) 0;
  font-family: var(--font-mono); font-size: var(--t-small);
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
/* dt of every row after the first, and its dd, share the rule */
.cert-facts dt:not(:first-of-type), .cert-facts dt:not(:first-of-type) + dd,
.fact-grid dt:not(:first-of-type), .fact-grid dt:not(:first-of-type) + dd {
  border-top: 1px solid var(--hairline);
}
/* Topic, sequence and consensus timestamp are on-chain facts. */
.cert-facts .chain, .fact-grid .chain, .cert-facts dd.mono a { color: var(--chain); }

/* A qualifier on a fact — "network consensus time" — sits under the value in
   prose type, never in the label column where it would wrap the row. */
.fact-note {
  display: block; margin-top: var(--s1);
  font-family: var(--font-sans); font-size: var(--t-label);
  color: var(--text-3); overflow-wrap: normal;
}

@media (max-width: 480px) {
  .cert-facts, .fact-grid { grid-template-columns: 1fr; }
  .cert-facts dt, .fact-grid dt { padding: var(--s3) 0 var(--s1); }
  .cert-facts dd, .fact-grid dd { padding: 0 0 var(--s3); }
  .cert-facts dt:not(:first-of-type) + dd, .fact-grid dt:not(:first-of-type) + dd { border-top: 0; }
}

/* A failed row takes the void colour on the value — never a red background wash. */
.mismatch-row, .mismatch-row + dd, dd.mismatch-row { color: var(--state-void); }

.evidence-footer {
  display: flex; gap: var(--s4); flex-wrap: wrap; align-items: baseline;
  margin-top: var(--s4); color: var(--text-3); font-size: var(--t-small);
}

/* ═══ badges ════════════════════════════════════════════════════════════
   Always carries a word. Taxonomy is not issuance, so .badge-kind is
   never green. */
.badge {
  display: inline-flex; align-items: center; gap: var(--s1);
  padding: var(--s1) var(--s3); border-radius: var(--r-pill);
  background: var(--bg-inset); color: var(--text-2);
  font-size: 12px; font-weight: 600;
}
.badge-kind { background: var(--bg-inset); color: var(--text-2); }
.badge-ok      { color: var(--state-settled); }
.badge-pending { color: var(--state-pending); }
.badge-bad     { color: var(--state-void); }

/* ═══ forms ═════════════════════════════════════════════════════════════ */
.form-page { max-width: var(--measure); margin: 0 auto; }
.field { margin-bottom: var(--s4); }
.field label, .field legend {
  display: block; margin-bottom: var(--s1);
  font-size: var(--t-small); font-weight: 600; color: var(--text);
}
.field input[type="text"], .field input[type="email"], .field input[type="password"],
.field input[type="number"], .field input[type="url"], .field input[type="search"],
.field textarea, .field select {
  width: 100%; padding: var(--s3) var(--s4); font: inherit;
  color: var(--text); background: var(--bg-inset);
  border: 0; border-bottom: 1.5px solid var(--field-edge);
  border-radius: var(--r-sm);
}
.field textarea { min-height: 120px; resize: vertical; }
.field input:focus-visible, .field textarea:focus-visible, .field select:focus-visible {
  border-bottom-color: var(--action);
}
.field input::placeholder, .field textarea::placeholder { color: var(--text-3); }
.field .hint { display: block; margin-top: var(--s1); font-size: var(--t-label); color: var(--text-3); }
.field-row { display: flex; gap: var(--s4); flex-wrap: wrap; }
.field-row label { flex: 1; min-width: 140px; }
fieldset.field {
  border: 0; border-radius: var(--r-md); padding: var(--s4);
  background: var(--bg-inset); margin-inline: 0;
}
fieldset.field input[type="text"], fieldset.field input[type="number"],
fieldset.field textarea, fieldset.field select { background: var(--bg-card); }

/* Errors say what happened and what to do next — no tinted wash. */
.field-error { display: block; margin-top: var(--s1); font-size: var(--t-label); color: var(--state-void); }

/* Rodauth auth pages: map the gem's Bootstrap-flavored markup onto our tokens
   so login / signup / reset / MFA read as part of the site. */
.form-page h1 { margin-bottom: var(--s5); }
.form-page .form-group { margin-bottom: var(--s4); }
.form-page .form-label { display: block; margin-bottom: var(--s1); font-size: var(--t-small); font-weight: 600; color: var(--text); }
.form-page .form-control, .form-page .form-control-plaintext {
  width: 100%; padding: var(--s3) var(--s4); font: inherit;
  color: var(--text); background: var(--bg-inset);
  border: 0; border-bottom: 1.5px solid var(--field-edge); border-radius: var(--r-sm);
}
.form-page .form-control:focus-visible { border-bottom-color: var(--action); outline: none; }
.form-page .form-control::placeholder { color: var(--text-3); }
.form-page .form-control.is-invalid { border-bottom-color: var(--state-void); }
.form-page .form-text { display: block; margin-top: var(--s1); font-size: var(--t-label); color: var(--text-3); }
.form-page .invalid-feedback { display: block; margin-top: var(--s1); font-size: var(--t-label); color: var(--state-void); }
.form-page ul { list-style: none; padding: 0; margin-top: var(--s4); display: flex; flex-direction: column; gap: var(--s2); }
.form-page .recovery-codes, .form-page pre { background: var(--bg-inset); padding: var(--s4); border-radius: var(--r-sm); overflow-x: auto; }

/* Account settings hub */
.account-section { margin-bottom: var(--s6); padding-bottom: var(--s5); border-bottom: 1px solid var(--field-edge); }
.account-section:last-child { border-bottom: 0; }
.account-actions { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s3); }
.account-facts dt { font-size: var(--t-label); color: var(--text-3); }
.account-facts dd { margin: 0 0 var(--s3); }
.notice-card { border: 1px solid var(--field-edge); padding: var(--s4); margin: var(--s3) 0; }
.account-sessions { width: 100%; border-collapse: collapse; margin-bottom: var(--s4); }
.account-sessions th, .account-sessions td { text-align: left; padding: var(--s2) var(--s3); border-bottom: 1px solid var(--field-edge); font-size: var(--t-small); }
.btn.btn-danger { color: var(--state-void); }

/* Sales and payouts keep ledger proof dense without mixing wallet controls
   into the sales statement. */
.business-tabs { display: flex; gap: var(--s4); margin-bottom: var(--s5); border-bottom: 1px solid var(--hairline); }
.business-tabs a { padding: var(--s2) 0; color: var(--text-2); text-decoration: none; }
.business-tabs a[aria-current="page"] { color: var(--text); font-weight: 700; border-bottom: 2px solid var(--action); }
.money-heading { margin-bottom: var(--s5); }
.money-heading h1 { margin-bottom: var(--s2); }
.money-periods { display: flex; flex-wrap: wrap; gap: var(--s3); margin-bottom: var(--s5); }
.money-periods a[aria-current="page"] { color: var(--text); font-weight: 700; text-decoration-thickness: 2px; }
.sales-date-filter { display: flex; flex-wrap: wrap; align-items: end; gap: var(--s3); margin: calc(-1 * var(--s2)) 0 var(--s5); }
.sales-date-filter .field { margin: 0; }
.sales-date-filter input { min-height: 42px; }
.money-summary { margin-bottom: var(--s5); }
.money-metrics-two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.sales-table { min-width: 940px; }
.sale-proof summary { cursor: pointer; white-space: nowrap; }
.sale-proof dl { min-width: 210px; margin-bottom: 0; }
.sale-proof dt { margin-top: var(--s2); color: var(--text-3); font-size: var(--t-label); }
.sale-proof dd { margin: 0; }
.money-forward { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s5); }
.money-empty { margin-bottom: var(--s5); }
.payout-issues { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s4); }
.payout-issue { margin: 0; }
.payout-issue h3 { margin-top: 0; }
.home-metrics.analytics-summary { grid-template-columns: repeat(5, minmax(0, 1fr)); margin-bottom: var(--s3); }
.analytics-breakdowns > .home-card { min-width: 0; }
.analytics-breakdowns h2 { margin: var(--s1) 0 var(--s4); font-size: var(--t-sub); }
.analytics-compact-table { width: 100%; }
.analytics-compact-table th:not(:first-child), .analytics-compact-table td:not(:first-child),
.analytics-model-table th:not(:first-child), .analytics-model-table td:not(:first-child) { text-align: right; }
.analytics-model-table { min-width: 980px; }
.analytics-privacy, .analytics-payout-health {
  display: flex; align-items: start; justify-content: space-between; gap: var(--s4);
}
.analytics-privacy span, .analytics-payout-health span { display: block; margin-top: var(--s1); color: var(--text-2); }
.analytics-privacy a, .analytics-payout-health a { flex: none; }

/* OAuth sign-in buttons on login / signup */
.oauth-buttons { margin-top: var(--s5); }
.oauth-buttons p { margin-bottom: var(--s2); }
.oauth-buttons form { display: inline-block; margin-right: var(--s3); }

.flash {
  display: flex; align-items: center; gap: var(--s3);
  margin-bottom: var(--s4); padding: var(--s3) var(--s4);
  border-radius: var(--r-md); background: var(--bg-inset);
  overflow-wrap: anywhere; color: var(--text-2);
}
.flash-ok  { --state-color: var(--state-settled); }
.flash-bad { --state-color: var(--state-void); }
.flash > .state-mark { flex: none; color: var(--state-color, var(--text)); }

/* ═══ dashboard ═════════════════════════════════════════════════════════ */
.dash { display: grid; grid-template-columns: 200px 1fr; gap: var(--s6); margin-top: 0; }
.dash-nav { display: flex; flex-direction: column; gap: var(--s2); align-items: flex-start; }
.dash-nav a { color: var(--text-2); text-decoration: none; }
.dash-nav a:hover { color: var(--text); }
.dash-nav a[aria-current="page"] { color: var(--text); font-weight: 600; }
.dash-nav > strong { font-stretch: 112%; }
.dash-who { margin-bottom: var(--s2); font-size: var(--t-label); color: var(--text-3); }
.dash-nav-group { display: flex; flex-direction: column; align-items: stretch; gap: var(--s1); width: 100%; }
.dash-nav-group + .dash-nav-group { margin-top: var(--s3); }
.dash-nav-group-title {
  margin: 0 0 var(--s1); color: var(--text-3); font-family: var(--font-mono);
  font-size: 10px; font-stretch: 100%; font-weight: 600; letter-spacing: .12em;
  line-height: 1.3; text-transform: uppercase;
}
.dash-nav-group a { padding: var(--s1) 0; }
.dash-menu { display: none; }
.dash-content { display: flex; flex-direction: column; gap: var(--s5); min-width: 0; }
.dash-content > h1 { margin: 0; }

@media (max-width: 780px) {
  .dash { grid-template-columns: 1fr; gap: var(--s4); }
  .dash-nav-desktop { display: none; }
  .dash-menu { display: block; }
  .dash-menu > summary {
    display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
    min-height: 56px; padding: var(--s2) var(--s4); cursor: pointer; list-style: none;
    border: 1px solid var(--field-edge); border-radius: var(--r-md); background: var(--bg-card);
  }
  .dash-menu > summary::-webkit-details-marker { display: none; }
  .dash-menu > summary:hover { background: var(--bg-inset); }
  .dash-menu > summary:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
  .dash-menu-context { display: flex; flex-direction: column; min-width: 0; }
  .dash-menu-context small {
    overflow: hidden; color: var(--text-3); font-size: var(--t-label);
    text-overflow: ellipsis; white-space: nowrap;
  }
  .dash-menu-action { color: var(--text-2); font-size: var(--t-small); font-weight: 600; }
  .dash-menu-action::after { content: " +"; }
  .dash-menu[open] .dash-menu-action::after { content: " −"; }
  .dash-nav-mobile {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch;
    gap: var(--s2); margin-top: var(--s2); padding: var(--s2);
    border: 1px solid var(--field-edge); border-radius: var(--r-md); background: var(--bg-card);
  }
  .dash-nav-mobile .dash-nav-group { display: contents; }
  .dash-nav-mobile .dash-nav-group-title {
    grid-column: 1 / -1; margin: var(--s2) var(--s3) 0; padding-top: var(--s2);
    border-top: 1px solid var(--hairline);
  }
  .dash-nav-mobile .dash-nav-group:first-child .dash-nav-group-title {
    margin-top: 0; padding-top: 0; border-top: 0;
  }
  .dash-nav-mobile a, .dash-nav-mobile .linklike {
    display: flex; align-items: center; min-height: 44px; padding: var(--s2) var(--s3);
    border-radius: var(--r-sm); text-align: left;
  }
  .dash-nav-mobile a:hover, .dash-nav-mobile .linklike:hover { background: var(--bg-inset); }
  .dash-nav-mobile a[aria-current="page"] { background: var(--bg-inset); }
  .dash-nav-mobile form { margin: 0; }
  .dash-nav-mobile form .linklike { width: 100%; }
}

.designer-home { display: flex; flex-direction: column; gap: var(--s7); }
.home-heading, .home-section-heading {
  display: flex; align-items: start; justify-content: space-between; gap: var(--s4);
}
.home-heading h1 { margin: var(--s1) 0 var(--s2); }
.home-heading p { margin: 0; color: var(--text-2); }
.home-heading-actions { display: flex; gap: var(--s2); flex-wrap: wrap; justify-content: flex-end; }
.home-section-heading { align-items: end; margin-bottom: var(--s4); }
.home-section-heading h2, .home-card > h2 { margin: var(--s1) 0 0; font-size: var(--t-sub); }
.home-card { padding: var(--s5); border-radius: var(--r-lg); background: var(--bg-card); }
.home-checklist, .home-task-list, .home-ranking, .home-activity {
  list-style: none; padding: 0; margin: 0;
}
.home-checklist { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3); }
.home-checklist li {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: start;
  gap: var(--s3); padding: var(--s3); border: 1px solid var(--hairline); border-radius: var(--r-md);
}
.home-checklist small, .home-metric small, .home-activity small, .home-activity span span {
  display: block; color: var(--text-3); font-size: var(--t-label);
}
.home-check-state { color: var(--text-3); font-size: var(--t-label); }
/* The guided payout steps: numbered, because their order is load-bearing —
   signing before the wallet can receive USDC is the failure this flow exists
   to prevent. */
.payout-steps { list-style: decimal inside none; padding: 0; margin: var(--s5) 0 0; }
.payout-steps > li {
  list-style: none; padding: var(--s4) 0; border-top: 1px solid var(--hairline);
}
.payout-steps h2 { margin: 0 0 var(--s2); }
.home-task-list { display: flex; flex-direction: column; gap: var(--s3); }
.home-task {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding: var(--s4); border: 1px solid var(--hairline); border-radius: var(--r-md);
}
.home-task h3 { margin: 0 0 var(--s1); font-size: var(--t-body); }
.home-task p { margin: 0; color: var(--text-2); font-size: var(--t-small); }
.home-task .btn { flex: none; }
.home-task form { flex: none; margin: 0; }
.home-recovery-support { margin: var(--s3) 0 0; }
.home-metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s3); }
.home-metric { min-width: 0; padding: var(--s4); border-radius: var(--r-md); background: var(--bg-card); }
.home-metric > span { display: block; color: var(--text-3); font-size: var(--t-label); }
.home-metric strong { display: block; margin-top: var(--s2); font-size: var(--t-sub); overflow-wrap: anywhere; }
.home-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s4); }
.home-ranking, .home-activity { margin-top: var(--s4); }
.home-ranking li {
  display: flex; justify-content: space-between; gap: var(--s3); padding: var(--s3) 0;
  border-bottom: 1px solid var(--hairline);
}
.home-ranking li:last-child { border-bottom: 0; }
.home-activity { display: flex; flex-direction: column; gap: var(--s3); }
.home-activity li { padding-bottom: var(--s3); border-bottom: 1px solid var(--hairline); }
.home-activity li:last-child { padding-bottom: 0; border-bottom: 0; }
.home-activity a { display: block; margin: var(--s1) 0; font-weight: 600; }
/* The generic span-span rule above makes descendants block; a status badge
   stays an inline pill beside its timestamp (notifications stream). */
.home-activity .badge { display: inline-block; }
.home-sample-grid { display: grid; grid-template-columns: minmax(180px, 1fr) 2fr; gap: var(--s5); margin-top: var(--s4); }
.home-sample-image {
  display: grid; place-items: center; min-height: 160px; border-radius: var(--r-md);
  background: var(--bg-inset); color: var(--text-3); font-family: var(--font-mono);
  font-size: var(--t-label); letter-spacing: .08em; text-transform: uppercase;
}
.home-sample-grid h3 { margin-top: 0; }
.home-sample-grid ul { padding-left: var(--s5); color: var(--text-2); }

@media (max-width: 980px) {
  .home-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .home-metrics.analytics-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .home-heading, .home-section-heading, .home-task { align-items: stretch; flex-direction: column; }
  .home-heading-actions { justify-content: flex-start; }
  .home-checklist, .home-columns, .home-metrics, .home-sample-grid { grid-template-columns: 1fr; }
  .home-metrics.analytics-summary { grid-template-columns: 1fr; }
  .home-task .btn { align-self: flex-start; }
  .home-card { padding: var(--s4); }
  .money-metrics-two { grid-template-columns: 1fr; }
  .payout-issues { grid-template-columns: 1fr; }
  .analytics-privacy, .analytics-payout-health { flex-direction: column; }
  .sales-date-filter { align-items: stretch; flex-direction: column; }
  .sales-date-filter .btn { align-self: flex-start; }
}

.page-heading-row {
  display: flex; align-items: start; justify-content: space-between;
  gap: var(--s4); flex-wrap: wrap;
}
.section-stack { display: flex; flex-direction: column; gap: var(--s5); }
.section-block { display: flex; flex-direction: column; gap: var(--s4); margin-top: var(--s6); }
.section-head { margin-top: var(--s7); }
.publish-note { display: block; margin-top: var(--s4); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.field-error { margin: var(--s1) 0 0; color: var(--state-void); font-size: var(--t-small); }

/* ═══ catalog manager · seller model list ═════════════════════════════ */
.catalog-tabs { display: flex; flex-wrap: wrap; gap: var(--s3); margin: var(--s4) 0; }
.catalog-tabs a {
  padding: var(--s1) var(--s3); border: 1px solid var(--hairline);
  border-radius: var(--r-pill); color: var(--text-2); font-size: var(--t-small);
}
.catalog-tabs a.is-current { border-color: var(--text-1); color: var(--text-1); font-weight: 600; }
.catalog-tab-count { color: var(--text-3); }
.catalog-toolbar { display: flex; flex-wrap: wrap; align-items: end; gap: var(--s3); margin-bottom: var(--s4); }
.catalog-toolbar .field { margin: 0; }
.catalog-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--s3); }
.catalog-row {
  display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; gap: var(--s4);
  align-items: center; padding: var(--s3); border: 1px solid var(--hairline); border-radius: var(--r-md);
}
.catalog-thumb {
  width: 64px; height: 64px; border-radius: var(--r-sm); overflow: hidden;
  background: var(--bg-inset); flex: none;
}
.catalog-thumb img { width: 100%; height: 100%; object-fit: cover; }
.catalog-main { min-width: 0; }
.catalog-title { font-weight: 600; }
.catalog-meta, .catalog-offers { margin: var(--s1) 0 0; }
.catalog-side { text-align: right; display: flex; flex-direction: column; gap: var(--s1); align-items: end; }
.catalog-sales strong { font-size: var(--t-body); }
.catalog-actions { display: flex; gap: var(--s3); }
.webhook-row { grid-template-columns: minmax(0, 1fr) auto; }
.webhook-actions { flex-wrap: wrap; justify-content: end; }
.webhook-actions form { margin: 0; }
@media (max-width: 560px) {
  .catalog-row { grid-template-columns: 48px minmax(0, 1fr); }
  .catalog-thumb { width: 48px; height: 48px; }
  .catalog-side { grid-column: 1 / -1; flex-direction: row; justify-content: space-between; align-items: center; }
}

/* ═══ listing editor · explicit saved state, local buyer preview ═══════ */
.listing-editor {
  display: grid; grid-template-columns: minmax(0, 1fr) 310px;
  align-items: start; gap: var(--s5); margin-top: var(--s5);
}
.listing-editor-main { min-width: 0; }
.listing-editor-form { display: flex; flex-direction: column; gap: var(--s5); }
.editor-section-nav {
  display: flex; gap: var(--s2); flex-wrap: wrap; margin-bottom: var(--s4);
}
.editor-section-nav a {
  flex: none; min-height: 40px; padding: var(--s2) var(--s3); border-radius: var(--r-pill);
  background: var(--bg-inset); color: var(--text-2); font-size: var(--t-small); text-decoration: none;
}
.editor-section-nav a:hover, .editor-section-nav a:focus-visible { background: var(--bg-card); color: var(--text); }
.editor-section, .editor-side-card, .editor-advanced {
  scroll-margin-top: calc(var(--sticky-header-height, 80px) + var(--s4));
  padding: var(--s5); border-radius: var(--r-lg); background: var(--bg-card);
}
.editor-section > header { max-width: var(--measure); margin-bottom: var(--s5); }
.editor-section > header h2, .editor-side-card h2 { margin: var(--s1) 0 var(--s2); font-size: var(--t-sub); }
.editor-section > header p:last-child { margin: 0; color: var(--text-2); }
.editor-section .field:last-child { margin-bottom: 0; }
.field-help { margin: var(--s1) 0 0; color: var(--text-3); font-size: var(--t-label); }
.editor-taxonomy-fieldset { margin: 0 0 var(--s4); padding: 0; border: 0; }
.editor-taxonomy-fieldset legend { margin-bottom: var(--s1); font-weight: 600; }
.editor-taxonomy-fieldset > .field-help { margin-bottom: var(--s3); }
.editor-taxonomy-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s2); }
.editor-taxonomy-option {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: var(--s2);
  min-height: 76px; padding: var(--s3); border-radius: var(--r-md); background: var(--bg-inset);
}
.editor-taxonomy-option input { margin-top: 3px; }
.editor-taxonomy-option span { display: flex; flex-direction: column; }
.editor-taxonomy-option small { margin-top: 2px; color: var(--text-3); font-weight: 400; line-height: 1.35; }
.editor-tag-suggestions { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; margin-top: var(--s3); }
.editor-tag-suggestions > span { color: var(--text-3); font-size: var(--t-label); }
.editor-tag-suggestion {
  min-height: 36px; padding: var(--s1) var(--s3); border: 1px solid var(--border);
  border-radius: var(--r-pill); background: var(--bg-inset); color: var(--text-2); font-size: var(--t-label);
}
.editor-tag-suggestion:hover, .editor-tag-suggestion:focus-visible { border-color: var(--accent); color: var(--text); }
.editor-check-row { display: flex; align-items: center; gap: var(--s2); min-height: 44px; margin-bottom: var(--s4); }
.editor-file-list, .editor-media-grid, .editor-readiness-list {
  margin: 0; padding: 0; list-style: none;
}
.editor-file-list { display: flex; flex-direction: column; gap: var(--s2); }
.editor-file-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: var(--s3); padding: var(--s3); border-radius: var(--r-md); background: var(--bg-inset);
}
.editor-file-position {
  display: grid; place-items: center; width: 32px; height: 32px; border-radius: var(--r-pill);
  background: var(--bg-card); color: var(--text-3); font-family: var(--font-mono); font-size: var(--t-label);
}
.editor-file-copy { display: flex; flex-direction: column; min-width: 0; }
.editor-file-copy strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.editor-file-copy span, .editor-media-copy span { color: var(--text-3); font-size: var(--t-label); }
.editor-file-actions, .editor-media-actions, .editor-save-actions {
  display: flex; align-items: center; justify-content: flex-end; gap: var(--s1); flex-wrap: wrap;
}
.editor-file-action {
  display: inline-flex; align-items: center; min-height: 40px; padding: var(--s2);
  border-radius: var(--r-sm); font-size: var(--t-label); text-decoration: none;
}
.editor-file-action:hover, .editor-file-action:focus-visible { background: var(--bg-card); }
.editor-file-action-danger { color: var(--state-void); }
.editor-empty-state, .editor-upload-zone, .editor-analysis, .editor-frozen-note {
  padding: var(--s4); border-radius: var(--r-md); background: var(--bg-inset); color: var(--text-2);
}
.editor-empty-state { text-align: center; }
.editor-analysis { display: flex; flex-direction: column; gap: var(--s1); margin-top: var(--s3); }
.editor-analysis-actions { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s2); }
.editor-analysis[data-analysis-status="passed"] strong { color: var(--state-settled); }
.editor-analysis[data-analysis-status="failed"] strong { color: var(--state-void); }
.editor-analysis ul { margin: var(--s1) 0 0; }
.editor-upload-zone { margin-top: var(--s3); }
.editor-upload-zone label { display: flex; flex-direction: column; gap: var(--s2); font-weight: 600; }
.editor-upload-zone p { margin: var(--s2) 0 0; font-size: var(--t-label); }
.editor-media-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3); }
.editor-media-card { min-width: 0; overflow: hidden; border-radius: var(--r-md); background: var(--bg-inset); }
.editor-media-card img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.editor-media-copy { display: flex; flex-direction: column; min-width: 0; padding: var(--s3) var(--s3) 0; }
.editor-media-copy strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.editor-media-actions { justify-content: flex-start; padding: var(--s2); }
.editor-license-products { display: flex; flex-direction: column; gap: var(--s3); }
.editor-license-card { overflow: hidden; border-radius: var(--r-md); background: var(--bg-inset); }
.editor-license-card > summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  min-height: 64px; padding: var(--s3) var(--s4); cursor: pointer; list-style-position: inside;
}
.editor-license-card > summary > span:first-of-type { display: flex; flex: 1; flex-direction: column; }
.editor-license-card > summary small { margin-top: 2px; color: var(--text-3); font-size: var(--t-label); font-weight: 400; }
.editor-license-card[data-license-state="available"] > summary { background: var(--bg-card); }
.editor-license-body { padding: 0 var(--s4) var(--s4); }
.editor-license-example { margin: 0 0 var(--s4); color: var(--text-2); font-size: var(--t-small); }
.editor-money-field {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center;
  gap: var(--s2); border-radius: var(--r-sm); background: var(--bg-card);
}
.field .editor-money-field input[type="number"] { margin: 0; padding-inline: 0; background: transparent; }
.editor-money-field > span { color: var(--text-3); font-size: var(--t-small); }
.editor-money-field > span:first-child { padding-left: var(--s3); }
.editor-money-field > span:last-child { padding-right: var(--s3); }
.editor-license-net { padding: var(--s3); border-radius: var(--r-sm); background: var(--bg-card); }
.editor-license-net strong { display: block; margin-top: var(--s1); }
.editor-remove-offer { display: flex; align-items: center; gap: var(--s2); min-height: 44px; margin-top: var(--s3); font-size: var(--t-small); }
.editor-license-terms details { margin-top: var(--s3); }
.editor-license-card pre { max-height: 320px; }
.editor-advanced { font-size: var(--t-small); }
.editor-advanced > summary { min-height: 44px; cursor: pointer; font-weight: 600; }
.editor-advanced p:last-child { margin-bottom: 0; overflow-wrap: anywhere; }
.editor-review-section { background: var(--bg-inset); }
.editor-save-row { display: flex; align-items: center; justify-content: space-between; gap: var(--s4); }
.editor-save-status { color: var(--text-3); font-size: var(--t-small); }
.editor-save-status[data-state="dirty"] { color: var(--state-pending); font-weight: 600; }
.listing-editor-aside {
  position: sticky; top: calc(var(--sticky-header-height, 80px) + var(--s4));
  display: flex; flex-direction: column; gap: var(--s4);
}
.editor-readiness-list { display: flex; flex-direction: column; gap: var(--s3); }
.editor-readiness-list li { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: var(--s2); }
.editor-readiness-list li > span:last-child { display: flex; flex-direction: column; }
.editor-readiness-list a { font-weight: 600; }
.editor-readiness-list small { margin-top: 2px; color: var(--text-3); font-size: var(--t-label); line-height: 1.35; }
.editor-readiness-action {
  align-self: flex-start; min-height: 36px; margin-top: var(--s2); padding: var(--s1) var(--s2);
  border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--bg-inset);
  color: var(--text-2); font-size: var(--t-label);
}
.editor-readiness-action:hover, .editor-readiness-action:focus-visible { border-color: var(--accent); color: var(--text); }
.editor-readiness-mark { color: var(--text-3); font-weight: 700; }
.editor-readiness-list [data-readiness-status="complete"] .editor-readiness-mark { color: var(--state-settled); }
.editor-readiness-list [data-readiness-status="blocked"] .editor-readiness-mark { color: var(--state-void); }
.editor-preview-image {
  display: grid; place-items: center; min-height: 180px; overflow: hidden;
  border-radius: var(--r-md); background: var(--bg-inset); color: var(--text-3); font-size: var(--t-label);
}
.editor-preview-image img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.editor-preview-copy { padding: var(--s3) 0; }
.editor-preview-copy h3 { margin-bottom: var(--s2); font-size: var(--t-body); }
.editor-preview-copy p { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 3; }
.editor-preview-discovery { margin: var(--s3) 0; padding: var(--s2) var(--s3); border-radius: var(--r-sm); background: var(--bg-inset); }
.editor-preview-discovery p { margin: 0; color: var(--text-2); font-size: var(--t-label); }
.editor-preview-discovery p + p { margin-top: var(--s1); }
.editor-preview-discovery-note { margin: 0; color: var(--text-3); font-size: var(--t-label); }
.editor-preview-note { margin-top: var(--s2); color: var(--text-3); font-size: var(--t-label); }
.editor-mobile-readiness { display: none; }

@media (max-width: 900px) {
  .listing-editor { grid-template-columns: 1fr; }
  .listing-editor-aside { position: static; }
  .editor-mobile-readiness { display: block; margin-bottom: var(--s4); }
  .editor-mobile-readiness a {
    display: flex; justify-content: space-between; gap: var(--s3); padding: var(--s3) var(--s4);
    border-radius: var(--r-md); background: var(--bg-card); color: var(--text); text-decoration: none;
  }
  .editor-mobile-readiness span { color: var(--text-3); font-size: var(--t-label); text-align: right; }
}
@media (max-width: 600px) {
  .editor-section-nav { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .editor-section-nav::-webkit-scrollbar { display: none; }
  .editor-section, .editor-side-card, .editor-advanced { padding: var(--s4); }
  .editor-file-row { grid-template-columns: auto minmax(0, 1fr); }
  .editor-file-actions { grid-column: 1 / -1; justify-content: flex-start; padding-left: 44px; }
  .editor-media-grid { grid-template-columns: 1fr; }
  .editor-taxonomy-options { grid-template-columns: 1fr; }
  .editor-save-row, .editor-mobile-readiness a { align-items: stretch; flex-direction: column; }
  .editor-save-actions { justify-content: flex-start; }
  .editor-save-actions .btn { flex: 1 1 100%; }
  .editor-mobile-readiness span { text-align: left; }
}

/* ═══ tables · data is tabulated, so the rule survives here ═════════════ */
.facts-table { border-collapse: collapse; width: 100%; font-size: var(--t-small); }
.facts-table th, .facts-table td {
  text-align: left; padding: var(--s3) var(--s4) var(--s3) 0;
  border-bottom: 1px solid var(--hairline); vertical-align: top;
}
.facts-table th {
  color: var(--text-3); font-weight: 600; font-size: var(--t-label);
  letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
}
.facts-table td { color: var(--text-2); }
.facts-table tr:last-child td { border-bottom: 0; }

/* Wide content scrolls inside its own box — the page body never scrolls
   sideways. */
.table-scroll { overflow-x: auto; }
.container pre { max-width: 100%; }
.container h3 code { overflow-wrap: anywhere; word-break: break-all; }

.code-block, pre {
  overflow-x: auto; padding: var(--s4);
  border: 0; border-radius: var(--r-md); background: var(--bg-inset);
  font-family: var(--font-mono); font-size: 12px; line-height: 1.65;
  color: var(--text-2);
}
.code-block pre { padding: 0; background: none; }
code { font-family: var(--font-mono); font-size: .92em; }
pre code { font-size: inherit; }

/* ═══ designer profile ══════════════════════════════════════════════════ */
.designer-page { margin-top: 0; }

/* ═══ chat · door 3 ═════════════════════════════════════════════════════ */
.chat-page { max-width: var(--measure); margin: 0 auto; }
.chat-messages {
  display: flex; flex-direction: column; gap: var(--s3);
  min-height: 200px; margin: var(--s5) 0;
}
.chat-exchange { display: flex; flex-direction: column; gap: var(--s3); }
.chat-msg {
  padding: var(--s3) var(--s4); border-radius: var(--r-lg); max-width: 85%;
}
.chat-msg p { margin: 0; }
.chat-msg-user { align-self: flex-end; background: var(--action); color: var(--on-action); }
/* `.hero p` sets muted copy with greater specificity. Keep message text on
   the action colour instead of letting that landing-page rule win. */
.chat-msg-user p { color: inherit; }
.chat-msg-assistant { align-self: flex-start; background: var(--bg-card); color: var(--text); }
.chat-catalog-results {
  display: flex; flex-direction: column; align-self: stretch; gap: var(--s2);
}
.chat-model-result {
  display: grid; grid-template-columns: 72px minmax(0, 1fr) auto;
  align-items: center; gap: var(--s3); padding: var(--s2);
  border-radius: var(--r-md); background: var(--bg-inset);
  color: var(--text); text-decoration: none;
}
.chat-model-result:hover, .chat-model-result:focus-visible {
  background: var(--action); color: var(--on-action);
}
.chat-model-result img, .chat-model-result-thumb {
  display: block; width: 72px; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--r-sm); background: var(--bg-card);
}
.chat-model-result-copy { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.chat-model-result-copy > strong {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-model-result-designer { color: var(--text-3); font-size: var(--t-label); }
.chat-model-result-offers {
  display: flex; flex-wrap: wrap; gap: var(--s1) var(--s3);
  margin-top: var(--s1); font-size: var(--t-label); color: var(--text-2);
}
.chat-model-result:hover .chat-model-result-designer,
.chat-model-result:hover .chat-model-result-offers,
.chat-model-result:focus-visible .chat-model-result-designer,
.chat-model-result:focus-visible .chat-model-result-offers { color: inherit; }
.chat-model-result-arrow { padding-right: var(--s2); font-size: 20px; }
.chat-catalog-more { display: none; }
.hero-shopkeeper .chat-catalog-more {
  display: block; align-self: flex-start; padding: var(--s2);
  color: var(--text-2); font-size: var(--t-label);
}
.chat-trace {
  align-self: flex-start; margin: 0; max-width: 100%;
  padding: var(--s3); border-radius: var(--r-md); background: var(--bg-inset);
  font-family: var(--font-mono); font-size: 12px; color: var(--text-3);
  overflow-x: auto;
}
@media (max-width: 480px) {
  .chat-model-result { grid-template-columns: 60px minmax(0, 1fr) auto; }
  .chat-model-result img, .chat-model-result-thumb { width: 60px; }
}
.chat-form {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s2) var(--s2) var(--s2) var(--s4);
  border-radius: var(--r-pill); background: var(--bg-inset);
}
.chat-form input[type="text"] {
  flex: 1; min-width: 0; padding: var(--s1) 0; font: inherit;
  color: var(--text); background: transparent; border: 0; outline: none;
}
.chat-form:focus-within { outline: 2px solid var(--focus); outline-offset: 3px; }
.chat-form input[type="text"]::placeholder { color: var(--text-3); }
.chat-cap-banner {
  padding: var(--s3) var(--s4); border-radius: var(--r-md);
  background: var(--bg-inset); color: var(--text-2); font-size: var(--t-small);
}
/* A card, not an issuance mark — so no green border. The on-chain lines
   inside it are what take --chain. */
.chat-purchase-card {
  display: flex; flex-direction: column; gap: var(--s2);
  margin: 0 0 var(--s3); padding: var(--s5);
  border-radius: var(--r-lg); background: var(--bg-card);
}
.chat-purchase-card > p { margin: 0; }
.chat-purchase-title { margin: 0; font-size: var(--t-sub); font-stretch: 118%; letter-spacing: -.015em; }
.chat-page > h1 { margin-bottom: var(--s3); }
.chat-page > .muted { margin-bottom: var(--s4); }
/* An empty conversation still needs a surface — otherwise the guidance floats
   in the middle of a void with nothing to belong to. */
#chat_empty_state {
  gap: var(--s2); padding: var(--s7) var(--s5);
  border-radius: var(--r-lg); background: var(--bg-card);
}
.chat-prompts {
  display: flex; justify-content: center; gap: var(--s2); flex-wrap: wrap;
  margin-top: var(--s2);
}
.prompt-chip {
  padding: var(--s2) var(--s3); cursor: pointer;
  border: 0; border-radius: var(--r-pill);
  background: var(--bg-inset); color: var(--text-2); font: inherit;
}
.prompt-chip:hover { background: var(--action); color: var(--on-action); }
/* Centre only the empty state — a real conversation top-aligns and grows down. */
.chat-messages:has(#chat_empty_state) { justify-content: center; }

/* ═══ print ═════════════════════════════════════════════════════════════
   Not a supported surface. The certificate's artifact of record is the HCS
   message and the way you share it is a URL, not a printout. */
@media print {
  .site-header, .site-footer, .copy-btn, .evidence-footer p, #ground-tex { display: none; }
  body { background: #fff; color: #000; }
}
