/* Theque — design tokens and base styles.
 * Generated from branding/BRAND.md §2–4. Values here must match that document;
 * it is the authority.
 *
 * No framework, no build step. BRAND.md §4 (DESIGN.md §4): reading surfaces ship
 * minimal CSS and zero JS, and must work with JavaScript disabled.
 */

:root {
  /* Neutrals — BRAND.md §2.1 */
  --bg: #FFFFFF;
  --bg-subtle: #F7F8F9;
  --bg-inset: #EEF0F2;
  --border: #D8DCE0;
  --border-strong: #B9C0C7;
  --fg-subtle: #6B7783;
  --fg-muted: #48525C;
  --fg: #14171A;

  /* Semantic — BRAND.md §2.2 */
  --accent: #1B62D4;
  --success: #136F3B;
  --warn: #8A5B00;
  --danger: #B0242A;
  --open: #136F3B;
  --merged: #6B3FCC;
  --closed: #8A939C;
  --agent: #0E6E75;

  /* Diff — never pure red/green */
  --diff-add-bg: #E6F4EA;
  --diff-del-bg: #FCE9E9;

  /* Type — BRAND.md §3.1, 14px base */
  --text-xs: 12px; --lh-xs: 16px;
  --text-sm: 13px; --lh-sm: 20px;
  --text-base: 14px; --lh-base: 22px;
  --text-md: 16px; --lh-md: 24px;
  --text-lg: 20px; --lh-lg: 28px;
  --text-xl: 24px; --lh-xl: 32px;

  /* Space — 4px grid, BRAND.md §4 */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s6: 24px; --s8: 32px; --s12: 48px;

  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 10px;

  --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.06);
  --shadow-md: 0 4px 12px rgb(0 0 0 / 0.10);

  --font-ui: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-code: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
}

/* Dark mode is first-class — BRAND.md §2.3. True dark, not desaturated gray. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0D0F12;
    --bg-subtle: #15181D;
    --bg-inset: #1D2126;
    --border: #2A2F36;
    --border-strong: #3A4149;
    --fg-subtle: #8B95A1;
    --fg-muted: #A9B3BE;
    --fg: #F2F4F6;
    --accent: #5B9BFF;
    --success: #3FC97A;
    --warn: #E8B54D;
    --danger: #FF6B70;
    --open: #3FC97A;
    --merged: #A98BFF;
    --closed: #6E7883;
    --agent: #3FBFC9;
    --diff-add-bg: #0F2E1B;
    --diff-del-bg: #331416;
  }
}

*, *::before, *::after { box-sizing: border-box; }
body {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--text-base);
  line-height: var(--lh-base);
  color: var(--fg);
  background: var(--bg);
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Focus ring — BRAND.md §13, always visible, 2px + 2px offset */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

code, pre { font-family: var(--font-code); font-size: var(--text-sm); }
.tabnum { font-variant-numeric: tabular-nums; }

/* Layout — BRAND.md §5 */
.wrap { max-width: 1280px; margin: 0 auto; padding: 0 var(--s6); }
.wrap-wide { max-width: none; padding: 0 var(--s6); }
.prose { max-width: 72ch; }
.prose img { max-width: 100%; }
.prose pre { background: var(--bg-subtle); padding: var(--s3); border-radius: var(--radius-md); overflow-x: auto; }
.prose table { border-collapse: collapse; }
.prose th, .prose td { border: 1px solid var(--border); padding: var(--s1) var(--s2); }

header.site {
  border-bottom: 1px solid var(--border);
  background: var(--bg-subtle);
  padding: var(--s3) 0;
  margin-bottom: var(--s6);
}
header.site .wrap { display: flex; align-items: center; gap: var(--s4); }
.brand { display: flex; align-items: center; gap: var(--s2); font-weight: 600; color: var(--fg); }
.brand svg { width: 22px; height: 22px; }
.spacer { flex: 1; }

/* Buttons — BRAND.md §6.1 */
.btn {
  font: inherit; font-weight: 500;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-strong);
  background: var(--bg);
  color: var(--fg);
  padding: 0 var(--s3);
  height: 32px;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: var(--s2);
}
.btn-compact { height: 28px; font-size: var(--text-sm); }
.btn-comfortable { height: 40px; padding: 0 var(--s4); }
.btn:hover { background: var(--bg-inset); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { filter: brightness(0.94); }
.btn-subtle { border-color: transparent; background: transparent; color: var(--accent); }
.btn-danger { border-color: var(--danger); color: var(--danger); }
.btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.icon-btn {
  font: inherit; background: none; border: 1px solid transparent;
  border-radius: var(--radius-sm); cursor: pointer; color: var(--fg-muted);
  padding: var(--s1) var(--s2);
}
.icon-btn:hover { background: var(--bg-inset); }

/* Blame: commit sha and author share one column, so a reader can see who last
 * touched a line without opening the commit. Author is the question people
 * actually ask of blame. */
.blame-meta {
  white-space: nowrap;
  width: 1%;
  padding: 0 var(--s3) !important;
  border-right: 1px solid var(--border);
  font-size: var(--text-xs);
  vertical-align: top;
}
.blame-meta a { text-decoration: none; }
.blame-author {
  color: var(--fg-subtle);
  margin-left: var(--s2);
  /* Long names must not push the code column off screen. */
  display: inline-block;
  max-width: 12ch;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}

/* Settings gear in the site header. Icon-only, so §7.1 requires the tooltip and
 * accessible name the markup provides. */
.gear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  color: var(--fg-muted);
  transition: background-color 120ms ease-out, color 120ms ease-out;
}
.gear:hover { background: var(--bg-inset); color: var(--fg); text-decoration: none; }
.gear svg { width: 20px; height: 20px; display: block; }

.hint { color: var(--fg-subtle); cursor: help; font-size: var(--text-sm); }
.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;
}

/* Status — icon + label + color, BRAND.md §6.3 */
.status { display: inline-flex; align-items: center; gap: var(--s1); font-size: var(--text-sm); }
.status-success, .status-open { color: var(--success); }
.status-failure { color: var(--danger); }
.status-pending { color: var(--warn); }
.status-stale { color: var(--warn); }
.status-none { color: var(--fg-subtle); }
.status-merged { color: var(--merged); }
.status-closed { color: var(--closed); }

.agent-badge {
  display: inline-block; font-size: var(--text-xs); font-weight: 500;
  color: var(--agent); border: 1px solid var(--agent);
  border-radius: var(--radius-sm); padding: 0 var(--s1);
}

/* Fields — BRAND.md §6.2 */
.field { margin-bottom: var(--s4); }
.field-label { display: block; font-weight: 500; margin-bottom: var(--s1); }
.field-required { color: var(--danger); margin-left: 2px; }
.field-input {
  font: inherit; width: 100%; padding: var(--s2) var(--s3);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--bg-inset); color: var(--fg);
}
.field-help { font-size: var(--text-sm); color: var(--fg-subtle); margin: var(--s1) 0 0; }

/* Settings — BRAND.md §8 */
.setting { padding: var(--s4) 0; border-bottom: 1px solid var(--border); }
.setting-label { font-weight: 600; font-size: var(--text-md); }
.setting-description { color: var(--fg-muted); margin: var(--s1) 0; }
.setting-consequence { color: var(--fg); background: var(--bg-subtle); padding: var(--s2) var(--s3); border-radius: var(--radius-sm); margin: var(--s2) 0; font-size: var(--text-sm); }
.setting-control { margin: var(--s3) 0; }
.setting-effective { font-size: var(--text-sm); color: var(--fg-subtle); margin: var(--s1) 0 0; }
.setting-learn { font-size: var(--text-sm); }
.danger-zone { margin-top: var(--s12); border: 1px solid var(--danger); border-radius: var(--radius-md); padding: var(--s4); }
.danger-zone-title { color: var(--danger); font-size: var(--text-md); margin: 0 0 var(--s2); }

/* Empty states — BRAND.md §6.6 */
.empty-state { padding: var(--s12) var(--s6); text-align: center; border: 1px dashed var(--border); border-radius: var(--radius-md); }
.empty-title { font-weight: 600; font-size: var(--text-md); margin: 0 0 var(--s2); }
.empty-body { color: var(--fg-muted); margin: 0 0 var(--s4); }

/* Tables and file lists */
.card { border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; }
.card-head { background: var(--bg-subtle); padding: var(--s2) var(--s3); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: var(--s3); font-size: var(--text-sm); }
.rows { list-style: none; margin: 0; padding: 0; }
.rows li { display: flex; align-items: center; gap: var(--s2); padding: var(--s2) var(--s3); border-bottom: 1px solid var(--border); }
.rows li:last-child { border-bottom: none; }
.rows li:hover { background: var(--bg-subtle); }
.row-icon { color: var(--fg-subtle); width: 1em; }
.row-meta { margin-left: auto; color: var(--fg-subtle); font-size: var(--text-sm); }

/* Code view */
.code { border: 1px solid var(--border); border-radius: var(--radius-md); overflow-x: auto; background: var(--bg-subtle); }
table.blob { border-collapse: collapse; width: 100%; }
table.blob td { padding: 0 var(--s3); vertical-align: top; }
table.blob td.ln {
  text-align: right; color: var(--fg-subtle); user-select: none;
  width: 1%; white-space: nowrap; font-variant-numeric: tabular-nums;
  border-right: 1px solid var(--border);
}
table.blob td.ln a { color: inherit; }
table.blob tr:target { background: color-mix(in srgb, var(--accent) 12%, transparent); }
table.blob pre { margin: 0; white-space: pre; }
.tok-k { color: var(--merged); font-weight: 500; }
.tok-s { color: var(--success); }
.tok-c { color: var(--fg-subtle); font-style: italic; }

/* Diff */
.diff { border: 1px solid var(--border); border-radius: var(--radius-md); margin-bottom: var(--s4); overflow: hidden; }
.diff-head { background: var(--bg-subtle); padding: var(--s2) var(--s3); border-bottom: 1px solid var(--border); font-family: var(--font-code); font-size: var(--text-sm); }
.diff pre { margin: 0; padding: var(--s2) var(--s3); overflow-x: auto; }
.diff .add { background: var(--diff-add-bg); display: block; }
.diff .del { background: var(--diff-del-bg); display: block; }

/* Pull request diff table.
   Every colour below is a theme token. An earlier version hardcoded a light
   fallback on comment rows, which rendered light-on-light and was unreadable in
   dark mode. */
.diff-table { width: 100%; border-collapse: collapse; font-family: var(--font-code); font-size: var(--text-sm); line-height: var(--lh-sm); }
.diff-table td { padding: 0; vertical-align: top; }

.diff-hunk-head td { background: var(--bg-inset); color: var(--fg-subtle); padding: var(--s1) var(--s3); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }

/* Line numbers: fixed, narrow, non-selectable so copying a diff yields code. */
.diff-lineno { width: 1%; min-width: 3rem; text-align: right; padding: 0 var(--s2) !important; color: var(--fg-subtle); user-select: none; white-space: nowrap; }
.diff-marker { width: 1ch; text-align: center; color: var(--fg-subtle); user-select: none; }
.diff-content { width: 100%; }
.diff-content pre { padding: 0 var(--s2) !important; white-space: pre-wrap; word-break: break-word; }

.diff-row.diff-add { background: var(--diff-add-bg); }
.diff-row.diff-del { background: var(--diff-del-bg); }

/* The comment affordance. Hidden until the row is hovered or something inside it
   takes focus — :focus-within is what keeps it keyboard-reachable, since BRAND.md
   §7 requires these not be hover-only. */
.diff-gutter { width: 1%; padding: 0 !important; }
.diff-comment-add {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; margin: 1px 2px;
  border-radius: var(--radius-sm);
  background: var(--accent); color: #fff;
  font-weight: 600; line-height: 1; text-decoration: none;
  opacity: 0; transition: opacity 80ms ease-in;
}
.diff-row:hover .diff-comment-add,
.diff-row:focus-within .diff-comment-add { opacity: 1; }
.diff-comment-add:focus { opacity: 1; outline: 2px solid var(--accent); outline-offset: 1px; }

/* Comment rows read as prose, not code: proportional type at body size. */
.diff-comment > td, .diff-comment-form > td { background: var(--bg-subtle); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.diff-comment-body { font-family: var(--font-sans); font-size: var(--text-sm); line-height: var(--lh-sm); color: var(--fg); padding: var(--s3); }
.diff-comment-head { display: flex; align-items: center; gap: var(--s2); margin-bottom: var(--s1); color: var(--fg); }
.diff-comment-text { color: var(--fg); }
.diff-comment-text :is(p, ul, ol) { margin: var(--s1) 0; }
.diff-comment-text code { background: var(--bg-inset); border-radius: var(--radius-sm); padding: 0 var(--s1); }
.diff-comment-actions { display: flex; gap: var(--s2); margin-top: var(--s2); }

.suggestion { border: 1px solid var(--border); border-radius: var(--radius-md); margin-top: var(--s2); overflow: hidden; }
.suggestion-head { background: var(--bg-inset); color: var(--fg-muted); font-size: var(--text-xs); padding: var(--s1) var(--s2); border-bottom: 1px solid var(--border); }
.suggestion-body { margin: 0; padding: var(--s2); font-family: var(--font-code); font-size: var(--text-sm); color: var(--fg); background: var(--diff-add-bg); overflow-x: auto; }

/* The form is revealed by the gutter link via :target — no JavaScript. */
.diff-comment-form { display: none; }
.diff-comment-form:target { display: table-row; }

/* Edit and delete, on your own comments only. Pushed to the right of the header
   so they do not compete with the author's name. */
.diff-comment-tools { margin-left: auto; display: flex; align-items: center; gap: var(--s2); font-size: var(--text-xs); }
.diff-comment-tools a, .diff-comment-tools .linklike { color: var(--fg-subtle); text-decoration: none; }
.diff-comment-tools a:hover, .diff-comment-tools .linklike:hover { color: var(--accent); text-decoration: underline; }

/* A button that reads as a link: deleting must be a POST for CSRF, but it should
   not look like a primary action sitting next to Edit. */
.linklike { background: none; border: none; padding: 0; font: inherit; cursor: pointer; }

.diff-comment-edit { display: none; margin-top: var(--s2); }
.diff-comment-edit:target { display: block; }

.badge { font-size: var(--text-xs); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 0 var(--s1); color: var(--fg-muted); }
.flash { padding: var(--s3); border-radius: var(--radius-md); margin-bottom: var(--s4); }
.flash-info { background: var(--bg-subtle); border: 1px solid var(--border); }
.flash-error { background: var(--diff-del-bg); border: 1px solid var(--danger); }
.muted { color: var(--fg-subtle); }
.timestamp { color: var(--fg-subtle); }
h1 { font-size: var(--text-xl); line-height: var(--lh-xl); margin: 0 0 var(--s3); }
h2 { font-size: var(--text-lg); line-height: var(--lh-lg); margin: var(--s6) 0 var(--s3); }
.breadcrumb { font-family: var(--font-code); font-size: var(--text-sm); }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* Drag-selected diff rows (issue #17). A left border rather than a background,
   so the add/delete colours underneath stay readable. */
.diff-row.diff-selected { box-shadow: inset 3px 0 0 var(--accent); }
.diff-gutter { cursor: pointer; user-select: none; }
/* Find-file modal (issue #16). Hidden until the enhancement script reveals it;
   `[hidden]` keeps it out of the layout and out of the accessibility tree for a
   reader with scripting off, who gets the full-page finder instead. */
.finder[hidden] { display: none; }
.finder { position: fixed; inset: 0; z-index: 50; }
.finder-backdrop { position: absolute; inset: 0; background: rgb(0 0 0 / 0.45); }
.finder-panel {
  position: relative;
  max-width: 640px;
  margin: 10vh auto 0;
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: var(--s3);
}
.finder-input { font-family: var(--font-code); }
.finder-results { list-style: none; margin: var(--s2) 0 0; padding: 0; max-height: 50vh; overflow-y: auto; }
.finder-results li { border-radius: var(--radius-sm); }
.finder-results a {
  display: block;
  padding: var(--s1) var(--s2);
  font-family: var(--font-code);
  font-size: var(--text-sm);
  color: var(--fg);
  text-decoration: none;
  /* Long paths truncate at the front, so the file name stays visible. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  direction: rtl;
  text-align: left;
}
.finder-results a:hover, .finder-results a:focus { background: var(--bg-inset); }
.finder-results li:first-child a { background: var(--bg-subtle); }
.finder-empty { padding: var(--s2); color: var(--fg-subtle); font-size: var(--text-sm); }
.finder-hint { font-size: var(--text-xs); margin: var(--s2) 0 0; }
/* Volume capacity bar (issue #13). A percentage read as a number is easy to
   dismiss; a bar that is visibly nearly full is not. */
.capacity-bar { height: 10px; background: var(--bg-inset); border-radius: var(--radius-sm); overflow: hidden; }
.capacity-fill { height: 100%; transition: width 120ms ease-out; }
.capacity-success { background: var(--success); }
.capacity-stale { background: var(--warn); }
.capacity-failure { background: var(--danger); }

/* Latest-run badge in the repository header.
   Icon plus label, never colour alone (BRAND.md §6.3): a red cross and a green
   check are the same glyph to a red-green colourblind reader without the word. */
.run-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 1px 8px;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: var(--text-xs);
  line-height: 1.6;
  text-decoration: none;
  white-space: nowrap;
}
.run-badge:hover { text-decoration: underline; }
.run-badge-success { color: var(--success); }
.run-badge-failure { color: var(--danger); }
.run-badge-running { color: var(--warn); }
.run-badge-icon { font-size: 1.05em; }

/* The spinner is the only animation on a reading surface, and it earns its place
   by replacing an indefinite one: BRAND.md §7.4 forbids a spinner that never
   says how long, and the badge's tooltip carries the commit and state. */
.run-badge-spin {
  display: inline-block;
  animation: run-badge-rotate 1.4s linear infinite;
}

@keyframes run-badge-rotate {
  to { transform: rotate(360deg); }
}

/* Respect a reader who has asked for less motion (BRAND.md accessibility): the
   glyph still reads as in-progress without rotating. */
@media (prefers-reduced-motion: reduce) {
  .run-badge-spin { animation: none; }
}

/* Stripe Elements mount point.
   The iframe styles only its own text (see billing.js); the field's border,
   padding, and background are ours, or the input has no visible edges at all. */
.card-field {
  margin: 12px 0;
  padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
