/* PromptShare base: fonts, reset, typography roots, focus, icons, kbd, scrollbars. Tokens only. */

/* Fonts come from Google Fonts, the site's existing dependency, in the page head (D9.1):
   the Manrope + Space Grotesk request is byte-identical to the one SoundLabs already makes, so it is warm in cache
   for returning visitors; IBM Plex Mono (SIL OFL 1.1) is a second request to the same host for prompt bodies.
   Nothing is self-hosted. See fonts/LICENCE-CHECK.md for why iA Writer Quattro was rejected. */

html { background: var(--bg); -webkit-text-size-adjust: 100%; }
/* the app's own colour, so no frame of any resize can expose the host page's background under the shell (BL4-1) */
body.ps-is-app { background: var(--bg); }
body { margin: var(--sp-0); background: var(--bg); min-height: 100dvh; }

/* App typography lives on the app roots, not <body>, so the shared nav, footer and upgrade modal keep the site's own type. */
.ps-app, .ps-layer, .ps-page {
  color: var(--text);
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-regular);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: left;
  font-feature-settings: "calt", "case";
}
.ps-app *, .ps-app *::before, .ps-app *::after,
.ps-layer *, .ps-layer *::before, .ps-layer *::after,
.ps-page *, .ps-page *::before, .ps-page *::after { box-sizing: border-box; }

.ps-app :where(h1, h2, h3, h4, p, ul, ol, dl, dd, figure),
.ps-layer :where(h1, h2, h3, h4, p, ul, ol, dl, dd, figure),
.ps-page :where(h1, h2, h3, h4, p, ul, ol, dl, dd, figure) { margin: var(--sp-0); padding: var(--sp-0); font: inherit; }
.ps-app :where(ul, ol), .ps-layer :where(ul, ol), .ps-page :where(ul, ol) { list-style: none; }
.ps-app :where(button, input, textarea, select), .ps-layer :where(button, input, textarea, select), .ps-page :where(button, input, textarea, select) {
  font: inherit; color: inherit; letter-spacing: inherit; margin: var(--sp-0);
}
.ps-app :where(button), .ps-layer :where(button), .ps-page :where(button) { background: none; border: 0; padding: var(--sp-0); cursor: pointer; text-align: inherit; }
.ps-app :where(a), .ps-layer :where(a), .ps-page :where(a) { color: inherit; text-decoration: none; }

[hidden] { display: none !important; }

.ps-app :focus, .ps-layer :focus, .ps-page :focus { outline: none; }
.ps-app :focus-visible, .ps-layer :focus-visible, .ps-page :focus-visible,
.is-focus-visible {
  outline: var(--focus-w) solid var(--accent);
  outline-offset: var(--sp-half);
}
.ps-app ::selection, .ps-layer ::selection, .ps-page ::selection { background: var(--accent-tint); color: var(--text); }

.ps-vh {
  position: absolute; width: var(--sp-px); height: var(--sp-px); padding: var(--sp-0); margin: calc(var(--sp-px) * -1);
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.ps-skip {
  position: absolute; left: var(--sp-4); top: var(--sp-2); z-index: var(--z-toast);
  padding: var(--sp-2) var(--sp-4); border-radius: var(--r-md);
  background: var(--accent); color: var(--on-accent); font: var(--fw-bold) var(--fs-body)/var(--lh-body) var(--font-ui);
  transform: translateY(-200%);
}
.ps-skip--2 { left: calc(var(--sp-16) + var(--sp-20)); }
.ps-skip:focus-visible { transform: none; }

.ps-num { font-variant-numeric: tabular-nums; }

/* Icons: one 16px-grid, 1.5px-stroke set. Strokes never scale, so a 20px icon on touch keeps the same weight. */
.ps-i { width: var(--sp-4); height: var(--sp-4); flex: none; display: inline-block; vertical-align: middle; fill: none; stroke: currentColor; stroke-width: var(--stroke); stroke-linecap: round; stroke-linejoin: round; overflow: visible; }
.ps-i--lg { width: var(--sp-5); height: var(--sp-5); }
.ps-i--xl { width: var(--sp-6); height: var(--sp-6); }
.ps-i--fill { fill: currentColor; }

/* Keyboard hint */
.ps-kbd {
  display: inline-grid; place-items: center; min-width: var(--sp-5); height: var(--sp-5); padding: var(--sp-0) var(--sp-1);
  border-radius: var(--r-sm); border: var(--sp-px) solid var(--border-strong); background: var(--surface-2);
  color: var(--text-2); font: var(--fw-medium) var(--fs-meta)/var(--lh-meta) var(--font-ui); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ps-kbds { display: inline-flex; gap: var(--sp-half); }

/* Scrollbars: thin, quiet, only as bright as a divider */
.ps-scroll { overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; overscroll-behavior: contain; }
.ps-scroll::-webkit-scrollbar { width: var(--sp-2); height: var(--sp-2); }
.ps-scroll::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--r-pill); border: var(--sp-half) solid transparent; background-clip: content-box; }

/* The blank. Peach = still to fill. Teal = filled with your value. Text is never rewritten; this is paint only. */
/* MA2-7: a blank is one word. `white-space: nowrap` makes a token that will not fit move to the next line WHOLE
   instead of splitting — {{sender|Sam at Northwind}} was breaking across two lines at 390. The parent keeps
   `overflow-wrap: anywhere` for genuinely over-long text; a variable name is capped at 40 chars by the spec. */
.ps-var { color: var(--var); background: var(--var-tint); border-radius: var(--sp-1); padding: var(--sp-px) var(--sp-half); margin: var(--sp-0) calc(var(--sp-half) * -1); white-space: nowrap; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
.ps-var--filled { color: var(--accent); background: var(--accent-tint); }
.ps-var--plain { background: none; padding: var(--sp-0); margin: var(--sp-0); }
/* a candidate blank ([BRACKETS] before the per-prompt opt-in): underlined, never filled */
.ps-var--maybe { background: none; color: var(--text); box-shadow: inset 0 calc(var(--sp-px) * -1) 0 var(--var); border-radius: var(--sp-0); }
.ps-prompt--maybe .ps-var { background: none; color: var(--text); box-shadow: inset 0 calc(var(--sp-px) * -1) 0 var(--var); border-radius: var(--sp-0); }
.ps-mark { background: var(--mark); color: var(--text); border-radius: var(--sp-half); padding: var(--sp-0) var(--sp-px); margin: var(--sp-0) calc(var(--sp-px) * -1); }

/* Prompt text, set for reading.
 *
 * MA4-7 · THE HANGING INDENT. A prompt is a structured document: bullets, numbered steps, XML tags. When a line
 * wraps, its continuation must not land in the same column as the next bullet's marker, or the reader scanning the
 * left edge counts more rules than exist. At 41ch on a phone five of seven bullets wrap and nine continuation lines
 * were sitting flush at the bullet column — the structure of the prompt dissolved on the one surface strangers see.
 *
 * `padding-left` + negative `text-indent` gives every wrapped line a 2ch indent while the first line of each source
 * line stays flush. It costs 2ch of measure and buys the document back. This is not optional styling: §1 principle 1
 * says the prompt is the most carefully set thing on every surface, and this is what that means in a narrow column.
 */
.ps-prompt {
  font-family: var(--font-prompt); font-size: var(--fs-read); line-height: var(--lh-read); font-weight: var(--fw-read);
  color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; max-width: var(--measure);
  font-variant-ligatures: none; tab-size: 2; hanging-punctuation: first;
}
/* one source line per block, each with its own hanging indent: a wrapped line is inset 2ch so it can never be
   mistaken for the next bullet. Blocks only — one-line contexts never emit .ps-line at all. */
.ps-prompt .ps-line { display: block; padding-left: 2ch; text-indent: -2ch; }
.ps-prompt .ps-dim { color: var(--text-3); }

@media (prefers-reduced-motion: reduce) {
  /* ROUND 7: `transition` was missing here, so "reduce motion" still animated every colour change — and a
     colour sampled mid-transition is not the colour anyone sees. It made contrast.mjs report six false
     failures on a button that settles at 12:1. Honouring the preference properly fixed both. */
  .ps-app *, .ps-layer *, .ps-page * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}
