/* 00.css — the base stylesheet for AI Apps and skill viewers. Classes: docs/app-authoring.md.
 *
 * Copy it into your app folder (`00 app new` does) and link it: <link rel="stylesheet" href="00.css">.
 * A VIEWER must be one file, so paste it inside <style> there — over mobile connect only the entry
 * HTML travels and a sibling stylesheet is never fetched.
 *
 * WHY A STYLESHEET AND NOT A FRAMEWORK: the page has no network. No CDN, no web font, no Tailwind
 * play script — `default-src 'none'` means they never load. The house style has to arrive as bytes
 * in the folder, and these are those bytes: plain CSS, no build step.
 *
 * HOW THE COLOURS WORK: the host sets its own tokens (`--color-ink`, `--color-card`, `--font-sans`,
 * …) on :root. Everything below reads a token with a readable FALLBACK, so the page looks right in
 * the Mac pane, in the phone webview, and opened off disk with no host. With no token,
 * `prefers-color-scheme` decides; `data-theme="light"|"dark"` beats that; an injected token beats
 * both — the app wears the window's colours, it does not choose them.
 */

/* ── tokens ───────────── */

:root {
  /* Semantic name ← host token + fallback. Style against these, so a renamed host token is one
     edit here rather than fifty in your app. */
  --bg: var(--color-void, #0a0b0d);
  --surface: var(--color-card, #0f1114);
  --surface-2: var(--color-panel, #141619);
  --raised: var(--color-panel-2, #1b1e22);
  --line: var(--color-line, #262a30);
  --edge: var(--color-edge, rgba(230, 233, 236, 0.3));
  --ink: var(--color-ink, #e6e9ec);
  --ink-dim: var(--color-ink-dim, #8b95a1);
  --accent: var(--color-phosphor, #4ade9b);
  --accent-dim: var(--color-phosphor-dim, #2b9268);
  --info: var(--color-cyan, #5cc8e8);
  --warn: var(--color-amber, #ecc36b);
  --danger: var(--color-red, #f0555f);
  --sans: var(--font-sans, -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", "Segoe UI", Roboto, system-ui, sans-serif);
  --mono: var(--font-mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);

  /* One 4 px scale, used everywhere below — a 44 px target is a multiple of it, not a magic number. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --radius: 10px;
  --radius-lg: 12px;
  --tap: 44px; /* the one number an app must not shrink: what a thumb can hit */

  color-scheme: dark;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: var(--color-void, #f5f6f8);
    --surface: var(--color-card, #ffffff);
    --surface-2: var(--color-panel, #f0f2f5);
    --raised: var(--color-panel-2, #e8ebef);
    --line: var(--color-line, #dfe3e8);
    --edge: var(--color-edge, rgba(20, 23, 26, 0.24));
    --ink: var(--color-ink, #14171a);
    --ink-dim: var(--color-ink-dim, #5c666f);
    --accent: var(--color-phosphor, #1f8a5a);
    --accent-dim: var(--color-phosphor-dim, #2b9268);
    --danger: var(--color-red, #c8323c);
    color-scheme: light;
  }
}

/* An explicit choice beats the OS preference, both directions. */
:root[data-theme="light"] {
  --bg: var(--color-void, #f5f6f8);
  --surface: var(--color-card, #ffffff);
  --surface-2: var(--color-panel, #f0f2f5);
  --raised: var(--color-panel-2, #e8ebef);
  --line: var(--color-line, #dfe3e8);
  --ink: var(--color-ink, #14171a);
  --ink-dim: var(--color-ink-dim, #5c666f);
  --accent: var(--color-phosphor, #1f8a5a);
  --danger: var(--color-red, #c8323c);
  color-scheme: light;
}
:root[data-theme="dark"] { color-scheme: dark; }

/* ── base ───────────── */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.45;
  -webkit-text-size-adjust: 100%;
}

/* Five sizes and no more: a sixth is usually saying in size what a weight or a colour would say. */
h1, .t1 { margin: 0 0 var(--s3); font-size: 20px; font-weight: 600; line-height: 1.25; }
h2, .t2 { margin: 0 0 var(--s2); font-size: 16px; font-weight: 600; line-height: 1.3; }
h3, .t3 { margin: 0 0 var(--s2); font-size: 14px; font-weight: 600; }
/* The quiet label above a panel's contents. */
.eyebrow {
  margin: 0 0 var(--s2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
p { margin: 0 0 var(--s2); }
a { color: var(--accent); }
code, kbd, samp { font-family: var(--mono); font-size: 0.9em; }
hr { border: 0; border-top: 1px solid var(--line); margin: var(--s3) 0; }
img, video, canvas { max-width: 100%; }
[hidden] { display: none !important; }

/* ── shell & layout ───────────── */

/* Wrap your page in this — the only max width, so a full-pane app is not a 1600 px line of text. */
.app {
  max-width: 860px;
  margin: 0 auto;
  padding: var(--s3) var(--s3) 48px;
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

/* Two panes — but ONE column until there is room: the phone is 360 px and a Mac pane can be
   narrower, so two-pane is the exception at 560 px, not a default to undo. */
.layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s3);
  align-items: start;
}
@media (min-width: 560px) {
  .layout { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .layout.side { grid-template-columns: minmax(0, 240px) minmax(0, 1fr); }
  .layout > .full { grid-column: 1 / -1; }
}
.layout > * { min-width: 0; } /* or one long filename widens the whole column */

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--s3);
}

/* Buttons and inputs on one line that wraps rather than overflows. */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
}
.toolbar.sticky {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: var(--s2) 0;
  background: var(--bg);
}

/* ── list / row ───────────── */

.list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  min-height: 48px;
  padding: var(--s1) var(--s2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
}
/* A bare line of controls inside a panel. */
.row.plain { min-height: 0; padding: 0; border: 0; background: none; }
.row.selected { border-color: var(--accent); }
.row-main { flex: 1 1 auto; min-width: 0; }
.row-title { display: block; font-size: 14px; overflow-wrap: anywhere; }
.row-meta { display: block; font-size: 12px; color: var(--ink-dim); }

/* What a list says when empty. Say what would put something in it. */
.empty {
  margin: 0;
  padding: var(--s4) var(--s3);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  color: var(--ink-dim);
  font-size: 13px;
  text-align: center;
}

/* ── controls ───────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s1);
  min-height: var(--tap);
  min-width: var(--tap);
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--raised);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  text-align: center;
  cursor: pointer;
  touch-action: manipulation;
}
.btn:active { background: var(--line); }
.btn:focus-visible, .input:focus-visible, .select:focus-visible, .check:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.5; cursor: default; }
.btn.primary { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.btn.quiet { background: transparent; color: var(--ink-dim); }
.btn.danger { border-color: var(--danger); color: var(--danger); }
/* A square icon button. Keep a real label in `aria-label` — a glyph is not a name. */
.btn.icon { padding: 0; font-size: 16px; }

.input, .select {
  min-height: var(--tap);
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
}
.input { flex: 1 1 140px; min-width: 96px; }
.input.num { flex: 0 0 92px; min-width: 92px; font-family: var(--mono); font-size: 13px; }
textarea.input { min-height: 96px; padding: var(--s2) 10px; line-height: 1.4; resize: vertical; }
.select {
  appearance: auto; /* the platform's own control is the one that behaves under touch */
  padding-right: var(--s2);
}
.input::placeholder { color: var(--ink-dim); }

/* label + control: stacked on a phone, side by side when there is room. */
.field { display: flex; flex-direction: column; gap: var(--s1); flex: 1 1 180px; min-width: 0; }
.label { font-size: 13px; color: var(--ink-dim); }

/* Box + label as ONE 44 px target — a 13 px checkbox alone is not tappable. */
.check {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: var(--tap);
  padding: 0 var(--s1);
  cursor: pointer;
  font-size: 14px;
}
.check input { width: 18px; height: 18px; accent-color: var(--accent); flex: none; }

/* ── feedback ───────────── */

/* One line the operator reads: what happened, or what to allow. */
.notice {
  margin: 0;
  padding: var(--s3);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 14px;
}
.notice.danger, .notice[data-tone="error"] { border-left-color: var(--danger); }
.notice.warn { border-left-color: var(--warn); }

/* Never the only signal — say the word "delete" too. */
.danger { color: var(--danger); }

.progress {
  height: 8px;
  border-radius: 999px;
  background: var(--raised);
  overflow: hidden;
}
.progress > .bar {
  height: 100%;
  width: 0;
  background: var(--accent);
  transition: width 0.2s linear;
}

/* A job's output tail. Wraps rather than scrolling sideways: the end of the line is the error. */
.tail {
  margin: 0;
  padding: var(--s2);
  max-height: 200px;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  font-family: var(--mono);
  font-size: 12px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ── utilities — the whole set, deliberately not a fortieth one ───────────── */

/* flex */
.flex { display: flex; align-items: center; gap: var(--s2); }
.col { display: flex; flex-direction: column; gap: var(--s2); }
.wrap { flex-wrap: wrap; }
.grow { flex: 1 1 auto; min-width: 0; }
.between { justify-content: space-between; }
.center { justify-content: center; text-align: center; }
.gap-1 { gap: var(--s1); }
.gap-2 { gap: var(--s2); }
.gap-3 { gap: var(--s3); }

/* spacing — vertical only; horizontal rhythm comes from gap */
.mt-1 { margin-top: var(--s1); }
.mt-2 { margin-top: var(--s2); }
.mt-3 { margin-top: var(--s3); }
.mb-0 { margin-bottom: 0; }
.mb-2 { margin-bottom: var(--s2); }
.mb-3 { margin-bottom: var(--s3); }

/* text */
.dim { color: var(--ink-dim); }
.mono { font-family: var(--mono); font-size: 12px; }
.small { font-size: 13px; }
.strong { font-weight: 600; }
/* Long paths: break anywhere rather than push the layout wide. */
.anywhere { overflow-wrap: anywhere; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── motion ───────────── */

/* Asked the OS for less motion, asked this page too. The progress bar still moves — it jumps to
   its width instead of sliding, which is information rather than decoration. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
