/* ════════════════════════════════════════════════════════════════════════
 * Prototype token contract — STRUCTURE ONLY, PLACEHOLDER VALUES
 * ════════════════════════════════════════════════════════════════════════
 *
 * Linked by every chrome-*.html template. This file defines the token
 * *names* those templates depend on. It deliberately does not define a
 * brand.
 *
 * ─── Why there is no palette here ──────────────────────────────────────
 *
 * This file is part of the portable skill core, which travels to every
 * project. A palette is a project fact, not a portable one. The previous
 * version shipped one studio's warm "oatmeal" ramp, cream paper, and a
 * licensed display face — so every project installing this skill inherited
 * another organisation's brand and had to actively fight it off.
 *
 * That is the same defect as naming a client in a portable core. It had a
 * second cost too: a warm cream background with a high-contrast display
 * face is the most recognisable signature of AI-generated design, so every
 * unadapted prototype announced itself as machine-made before anyone read
 * a word of it.
 *
 * What this skill enforces is *conformance to a defined palette*, not
 * conformance to a particular palette. The rules in
 * `fidelity/concept-rules.md` — no raw hex, semantic tokens only, spacing
 * on the rhythm — constrain how colour is used without prescribing which
 * colours exist. Those rules are unchanged; only the values left.
 *
 * ─── Resolution order ──────────────────────────────────────────────────
 *
 *   1. The project adapter's `semantic_tokens` (`_adapters/{project}.md`)
 *   2. Inferred from the project — an existing tokens file, Tailwind
 *      theme, or CSS custom properties already in the repo
 *   3. These placeholders
 *
 * A prototype that reached step 2 or 3 MUST say so on the page, using
 * `.palette-notice` below. Inference can pick up a stale or half-migrated
 * palette, and a silent pickup is indistinguishable from a deliberate
 * choice.
 *
 * ─── What is still prescribed, and why that is fine ────────────────────
 *
 * Spacing rhythm, motion tiers, radii, and the type *scale* stay. They are
 * the structural skeleton the templates are built against, they carry no
 * brand identity, and a project that wants different values overrides the
 * same way it overrides colour.
 * ════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Ink scale — PLACEHOLDER, chroma 0 ───────────────────────────────
   * Achromatic by construction, and that is a signal rather than a taste.
   * A greyscale prototype reads as unfinished, which is exactly what a
   * prototype with no defined palette is: it cannot be mistaken for a
   * finished brand, and it cannot drift into looking like one.
   *
   * This ramp was previously a specific studio's warm "oatmeal" OKLCH at
   * hue 106-107. See the header for why that had to go. */
  --ink-50:  oklch(98.8% 0 0);
  --ink-100: oklch(96.6% 0 0);
  --ink-200: oklch(93.0% 0 0);
  --ink-300: oklch(88.0% 0 0);
  --ink-400: oklch(73.7% 0 0);
  --ink-500: oklch(58.0% 0 0);
  --ink-600: oklch(46.6% 0 0);
  --ink-700: oklch(39.4% 0 0);
  --ink-800: oklch(28.6% 0 0);
  --ink-900: oklch(22.8% 0 0);
  --ink-950: oklch(15.3% 0 0);

  /* ── Paper — PLACEHOLDER, chroma 0 ───────────────────────────────── */
  --paper-white: oklch(99.0% 0 0);
  --paper-cream: oklch(97.0% 0 0);

  /* ── Semantic roles (light defaults) ─────────────────────────────── */
  --surface:       var(--paper-white);
  --surface-2:     var(--paper-cream);
  --surface-raised: var(--ink-50);
  --ink:           var(--ink-900);
  --ink-soft:      var(--ink-800);
  --ink-quiet:     var(--ink-500);
  --ink-faint:     var(--ink-400);
  --ink-ghost:     var(--ink-300);
  --rule:          var(--ink-100);
  --rule-strong:   var(--ink-200);

  /* ── Status — functional defaults, override per project ──────────────
   * These keep hue where the identity tokens do not, because red-for-error
   * is a convention users arrive with rather than a brand decision, and a
   * greyscale error state makes a prototype harder to review without
   * making it more honest.
   *
   * They are still placeholders. A project palette defines its own, and
   * colour must never be the only signal regardless — pair with icon and
   * text (see @steve). */
  --success-100: oklch(93.5% 0.055 150);  --success-600: oklch(54.0% 0.115 150);
  --error-100:   oklch(91.0% 0.055 25);   --error-600:   oklch(51.5% 0.175 25);
  --warning-100: oklch(93.5% 0.065 75);   --warning-600: oklch(56.0% 0.135 55);

  /* ── Fonts — PLACEHOLDER, system stack ───────────────────────────────
   * Previously named a specific commercial typeface. A portable core
   * cannot license a font on a project's behalf, and a fixed display face
   * is half of the "AI-generated design" signature the other half of which
   * was the cream background above.
   *
   * Projects override via the adapter. The system stack renders everywhere
   * and belongs to no one. */
  --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-display: var(--font-sans);

  /* ── Type roles ──────────────────────────────────────────────────── */
  --type-display-size: clamp(2.5rem, 5vw, 4.25rem);
  --type-display-weight: 700;
  --type-display-tracking: -0.035em;
  --type-display-leading: 1.05;

  --type-h1-size: clamp(1.875rem, 3vw, 3rem);
  --type-h1-weight: 700;
  --type-h1-tracking: -0.025em;
  --type-h1-leading: 1.1;

  --type-h2-size: clamp(1.5rem, 2.25vw, 2.25rem);
  --type-h2-weight: 500;
  --type-h2-tracking: -0.015em;
  --type-h2-leading: 1.3;

  --type-body-size: 16px;
  --type-body-weight: 400;
  --type-body-leading: 1.55;

  --type-body-lg-size: 18px;
  --type-body-lg-leading: 1.7;

  /* Meta uses the sans stack by default; mono is reserved for data runs. */
  --type-meta-size: 13px;
  --type-meta-weight: 500;
  --type-meta-tracking: 0;

  --type-meta-sm-size: 12px;
  --type-meta-sm-tracking: 0;

  /* Mono-data: genuine data runs (numbers, timestamps, IDs) */
  --type-mono-data-size: 13px;
  --type-mono-data-weight: 400;

  /* ── Spacing ─────────────────────────────────────────────────────── */
  --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px;
  --space-5:20px; --space-6:24px; --space-8:32px; --space-10:40px;
  --space-12:48px; --space-16:64px; --space-20:80px; --space-24:96px;
  --pad: var(--space-12);
  --pad-sm: var(--space-6);
  --pad-xs: var(--space-4);

  /* ── Motion ──────────────────────────────────────────────────────── */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in:  cubic-bezier(0.4, 0, 1, 1);
  --dur-tier1: 140ms;
  --dur-tier2-in: 200ms; --dur-tier2-out: 160ms;
  --dur-tier3-in: 250ms; --dur-tier3-out: 200ms;

  /* ── Radii ───────────────────────────────────────────────────────── */
  --radius-sm:2px; --radius-md:6px; --radius-lg:16px; --radius-full:9999px;

  /* ── Layout maxes ────────────────────────────────────────────────── */
  --max-w-content: 720px;
  --max-w-wide: 1024px;
  --max-w-shell: 1280px;
  --max-w-column: 1024px;  /* used by "letter on paper" variants */

  /* Floating pill nav offset (used as padding-top on main) */
  --nav-offset: 88px;
}

/* ── Dark mode ──────────────────────────────────────────────────────── */
@media (prefers-color-scheme: dark) {
  :root {
    --surface:       var(--ink-950);
    --surface-2:     var(--ink-900);
    --surface-raised: var(--ink-800);
    --ink:           var(--ink-50);
    --ink-soft:      var(--ink-100);
    --ink-quiet:     var(--ink-400);
    --ink-faint:     var(--ink-500);
    --ink-ghost:     var(--ink-600);
    --rule:          var(--ink-800);
    --rule-strong:   var(--ink-700);
  }
}

/* ── Reduced motion ─────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Base reset ─────────────────────────────────────────────────────── */
*, *::before, *::after { margin:0; padding:0; box-sizing:border-box; }

html, body {
  background: var(--surface);
  color: var(--ink-soft);
  font-family: var(--font-sans);
  font-size: var(--type-body-size);
  font-weight: var(--type-body-weight);
  line-height: var(--type-body-leading);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
  color: var(--ink);
  text-wrap: balance;
  font-weight: 500;
}

p { text-wrap: pretty; }

button, input, textarea, select {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
}
button { cursor: pointer; }
button:focus, input:focus, textarea:focus { outline: none; }
a { color: inherit; text-decoration: none; }

/* ── Mono utilities ─────────────────────────────────────────────────── */
/* Default .mono = data-like runs in the project mono stack, NO uppercase.
   Use for numbers, timestamps, IDs, file paths, keyboard shortcuts. */
.mono {
  font-family: var(--font-mono);
  font-weight: 400;
  letter-spacing: 0;
  font-feature-settings: "tnum" 1;  /* tabular numbers */
}

/* Opt-in uppercase — ONLY for rare micro-labels (tiny shield badges).
   Never apply this broadly. Sentence case is the default. */
.mono-uc {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* Specialized: large mono numbers (stat figures, hero data) */
.mono-num {
  font-family: var(--font-mono);
  font-weight: 300;
  letter-spacing: -0.01em;
  font-feature-settings: "tnum" 1, "ss01" 1;
}

/* ── Pill nav (shared across chrome-minimal + chrome-marketing) ──────────
 * Floating pill at top of viewport, contained, backdrop-blurred.
 * Colours resolve through the semantic tokens above, so this renders in
 * whatever palette the project defined. */

.proto-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  padding: var(--space-4) var(--space-6);
  pointer-events: none;
}

.proto-header-inner {
  max-width: var(--max-w-wide);
  margin: 0 auto;
  pointer-events: auto;
}

.pill-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  padding: 12px 20px;
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-lg);
}

.pill-brand {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.02em;
  color: var(--ink);
  flex-shrink: 0;
}

.pill-links {
  display: flex;
  gap: var(--space-6);
  align-items: center;
}

.pill-link {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 400;
  color: var(--ink-quiet);
  padding: 4px 0;
  transition: color var(--dur-tier1) var(--ease-out);
}
.pill-link:hover { color: var(--ink); }
.pill-link.active { color: var(--ink); font-weight: 500; }

.pill-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 8px 16px;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  color: var(--surface);
  background: var(--ink);
  border-radius: var(--radius-full);
  transition: background var(--dur-tier1) var(--ease-out),
              transform var(--dur-tier1) var(--ease-out);
  flex-shrink: 0;
}
.pill-cta:hover { background: var(--ink-soft); }
.pill-cta:active { transform: scale(0.98); }

@media (max-width: 768px) {
  .proto-header { padding: var(--space-3) var(--space-4); }
  .pill-links { display: none; }
  .pill-nav { padding: 10px 16px; }
}

/* ── Palette provenance notice ──────────────────────────────────────────
 * Required on any prototype whose palette was inferred (resolution step 2)
 * or placeheld (step 3).
 *
 * Deliberately hard to miss. The risk inference carries is picking up a
 * stale or half-migrated palette and presenting it as a decision; a notice
 * nobody notices does not mitigate that. It sticks to the top and stays in
 * print output, because prototypes get screenshotted into decks.
 *
 *   <p class="palette-notice">
 *     Palette inferred from tailwind.config.ts — not declared in the
 *     project adapter. Verify before review.
 *   </p>
 */
.palette-notice {
  position: sticky;
  top: 0;
  z-index: 999;
  margin: 0;
  padding: var(--space-2) var(--space-4);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--paper-white);
  background: var(--ink-900);
  border-bottom: 1px solid var(--ink-700);
}

@media (prefers-color-scheme: dark) {
  .palette-notice {
    color: var(--ink-950);
    background: var(--ink-200);
    border-bottom-color: var(--ink-400);
  }
}

/* Screenshots into decks are the common case — keep it visible on paper. */
@media print {
  .palette-notice { position: static; }
}
