/* Bugloos Feedback — dashboard.
   Same token vocabulary as the extension (see DESIGN.md), tuned for a desk
   rather than a 320px side panel: denser rows, a real table, wider measure.
   Achromatic, borders over shadows, one red for refusal. */

:root {
  --background:             oklch(1 0 0);
  --foreground:             oklch(0.145 0 0);
  --card:                   oklch(1 0 0);
  --muted:                  oklch(0.97 0 0);
  --muted-foreground:       oklch(0.556 0 0);
  --primary:                oklch(0.205 0 0);
  --primary-foreground:     oklch(0.985 0 0);
  --secondary:              oklch(0.97 0 0);
  --accent:                 oklch(0.97 0 0);
  --accent-foreground:      oklch(0.205 0 0);
  --destructive:            oklch(0.577 0.245 27.325);
  --destructive-foreground: oklch(0.985 0 0);
  --border:                 oklch(0.922 0 0);
  --ring:                   oklch(0.708 0 0);

  --radius:     0.625rem;
  --radius-sm:  calc(var(--radius) - 4px);
  --radius-md:  calc(var(--radius) - 2px);
  --radius-xl:  calc(var(--radius) + 4px);
  --shadow-xs:  0 1px 2px 0 oklch(0 0 0 / 0.05);
  --popover:            oklch(1 0 0);
  --popover-foreground: oklch(0.145 0 0);
  --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4' stroke='black' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");

  --font-sans: 'Vazirmatn', ui-sans-serif, system-ui, -apple-system, 'Segoe UI',
    Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root {
    --background:         oklch(0.145 0 0);
    --foreground:         oklch(0.985 0 0);
    --card:               oklch(0.205 0 0);
    --muted:              oklch(0.269 0 0);
    --muted-foreground:   oklch(0.708 0 0);
    --primary:            oklch(0.922 0 0);
    --primary-foreground: oklch(0.205 0 0);
    --secondary:          oklch(0.269 0 0);
    --accent:             oklch(0.269 0 0);
    --accent-foreground:  oklch(0.985 0 0);
    --destructive:        oklch(0.704 0.191 22.216);
    /* Dark mode lightens the red rather than darkening it, so the text on top
       has to flip too — white on oklch(0.704 …) is under 3:1. */
    --destructive-foreground: oklch(0.205 0 0);
    --border:             oklch(1 0 0 / 10%);
    --ring:               oklch(0.556 0 0);
    --popover:            oklch(0.269 0 0);
    --popover-foreground: oklch(0.985 0 0);
    color-scheme: dark;
  }
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

::selection { background: color-mix(in oklch, var(--foreground) 20%, transparent); }
:root { accent-color: var(--primary); }
* { scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: color-mix(in oklch, var(--foreground) 22%, transparent);
  border-radius: var(--radius-sm);
  border: 3px solid transparent;
  background-clip: content-box;
}

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 3px solid color-mix(in oklch, var(--ring) 50%, transparent);
  outline-offset: 2px;
  border-color: var(--ring);
}

/* ─── chrome ──────────────────────────────────────────────────────────────── */

.chrome {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 12px 28px;
  background: var(--background);
  border-bottom: 1px solid var(--border);
}
.mark { font-weight: 600; letter-spacing: -0.025em; }
.chrome nav { display: flex; gap: 4px; }
.chrome nav a {
  padding: 5px 12px;
  border-radius: var(--radius-md);
  color: var(--muted-foreground);
  text-decoration: none;
}
.chrome nav a:hover { background: var(--muted); color: var(--foreground); }
.chrome nav a[aria-current="page"] { background: var(--primary); color: var(--primary-foreground); }
/* Not decoration: this process holds a key that bypasses every policy, and the
   operator should never be unsure which surface they are looking at. */
.scope {
  margin-inline-start: auto;
  font-size: 13px;
  color: var(--muted-foreground);
  font-family: var(--font-mono);
}

main { max-width: 1180px; margin: 0 auto; padding: 28px; }

.head { display: flex; align-items: baseline; gap: 16px; margin-bottom: 8px; }
.head h1 { font-size: 24px; font-weight: 600; letter-spacing: -0.025em; margin: 0; }
.exports { margin-inline-start: auto; display: flex; gap: 8px; }

h2 { font-size: 17px; font-weight: 600; letter-spacing: -0.02em; margin: 0 0 4px; }
.lede, .sub, .hint, .tally { color: var(--muted-foreground); }
.lede { max-width: 68ch; margin: 0 0 20px; }
.sub, .hint { font-size: 13px; }
.hint { margin: 4px 0 12px; }
.tally { font-size: 13px; margin: 0 0 12px; }
.back { margin: 0 0 16px; }
.back a, .title a { color: inherit; }
/* Links inside a dense table: underline on intent, not at rest. Three underlined
   titles per screen is noise; the column already says they are links. */
.items .title a { text-decoration: none; }
.items .title a:hover { text-decoration: underline; }

/* Client content is often Persian. Let the bidi algorithm order the characters —
   that is what dir="auto" is for — but keep the BLOCK anchored to this
   interface's own edge. An RTL title aligning to the far right of a 78ch column
   reads as misplaced rather than as localised, and detaches from the metadata
   directly beneath it. When the dashboard itself becomes RTL, this flips. */
[dir="auto"] { text-align: left; }
.items td[dir="auto"], .items .title a { text-align: left; }

.notice {
  margin: 0 0 20px;
  padding: 10px 14px;
  border-radius: var(--radius);
  background: var(--muted);
  border: 1px solid transparent;
}
.notice-warn { border-color: color-mix(in oklch, var(--destructive) 45%, transparent); background: var(--card); }
.code {
  font-family: var(--font-mono);
  font-size: 16px;
  letter-spacing: 0.06em;
  background: var(--background);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 3px 8px;
  user-select: all;
}
.warn { color: var(--destructive); font-size: 13px; margin: 8px 0 0; }
.empty { color: var(--muted-foreground); padding: 28px 0; }
.err {
  font-family: var(--font-mono);
  font-size: 13px;
  white-space: pre-wrap;
  color: var(--destructive);
}

/* ─── forms ───────────────────────────────────────────────────────────────── */

label { display: block; font-size: 13px; color: var(--muted-foreground); }
label.block { margin-bottom: 12px; }
input, select, textarea {
  display: block;
  width: 100%;
  margin-top: 4px;
  font: inherit;
  color: var(--foreground);
  background: var(--background);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 7px 10px;
  box-shadow: var(--shadow-xs);
  transition: border-color .15s ease, background-color .15s ease;
}
input:hover, select:hover, textarea:hover { border-color: var(--ring); }

/* ─── Select ──────────────────────────────────────────────────────────────── */

/* shadcn's Select is a Radix popover, not a native control, so it can render
   its own items. This dashboard is deliberately zero-JS, so the native select
   stays — but everything about it that CAN be styled, is:

     - the OS chevron is removed and redrawn from a token, so it matches the
       text rather than the platform;
     - the control carries --background rather than transparent, which is what
       made it read as a plain white box on the white filter card;
     - the popup items get --popover, the same surface shadcn uses.

   One honest limit: option styling lands on Windows and Linux. macOS draws the
   popup entirely natively and ignores it — color-scheme is what keeps it dark
   there. */
.select {
  position: relative;
  display: block;
  margin-top: 4px;
}
.select select {
  margin-top: 0;
  appearance: none;
  /* Room for the chevron, so a long product name never runs under it. */
  padding-inline-end: 32px;
  cursor: pointer;
}
.select::after {
  content: '';
  position: absolute;
  inset-inline-end: 11px;
  top: 50%;
  width: 10px;
  height: 10px;
  margin-top: -5px;
  pointer-events: none;
  /* Drawn with a mask so it takes its colour from a token instead of being
     baked into a data URI that would need one copy per theme. */
  background-color: var(--muted-foreground);
  -webkit-mask: var(--chevron) center / contain no-repeat;
  mask: var(--chevron) center / contain no-repeat;
}
.select:hover::after { background-color: var(--foreground); }

select option {
  background: var(--popover);
  color: var(--popover-foreground);
}

textarea { resize: vertical; font-family: var(--font-mono); font-size: 13px; }
input::placeholder, textarea::placeholder { color: var(--muted-foreground); }

.filters {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
  padding: 14px 16px;
  margin-bottom: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--card);
}
.filters label { flex: 0 0 auto; }
.filters .grow, .row .grow { flex: 1 1 200px; }
.row { display: flex; gap: 12px; margin-bottom: 12px; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font: inherit;
  font-weight: 500;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 7px 14px;
  background: var(--background);
  color: var(--foreground);
  box-shadow: var(--shadow-xs);
  cursor: pointer;
  text-decoration: none;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.btn:hover { background: var(--muted); }
.btn-primary {
  background: var(--primary);
  color: var(--primary-foreground);
  border-color: var(--primary);
}
.btn-primary:hover { background: color-mix(in oklch, var(--primary) 90%, var(--background)); }
.btn-small { padding: 4px 10px; font-size: 13px; }

.statusbar { display: flex; align-items: center; gap: 6px; margin: 16px 0 20px; }
.statusbar > span { font-size: 13px; color: var(--muted-foreground); margin-inline-end: 4px; }
.btn-status.is-current { background: var(--primary); color: var(--primary-foreground); border-color: var(--primary); }

/* ─── Chips ───────────────────────────────────────────────────────────────── */

/* Type and severity render as chips everywhere, and on the detail page the
   chips ARE the control: a triage pass often starts by fixing what the client
   picked, since spec §14.4 notes real bugs arrive labelled change_request.

   The severity ramp matches the extension exactly — none and nit stay quiet,
   "bothers me" takes the solid fill, and only "blocks me" is allowed to be red.
   The same scale should not read differently either side of the submit. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 2px 8px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.4;
  white-space: nowrap;
  background: var(--background);
  color: var(--foreground);
}
.chip-quiet { color: var(--muted-foreground); }
.chip-none  { color: var(--muted-foreground); border-style: dashed; }
.chip-solid { background: var(--primary); color: var(--primary-foreground); border-color: var(--primary); }
.chip-alert { background: var(--destructive); color: var(--destructive-foreground); border-color: var(--destructive); }

/* Interactive chips: plain submit buttons, so no JS and no dropdown. Only the
   CURRENT choice is filled — see the note on chipbar() in views.js. */
.chipbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 10px;
}
.chipbar > .chipbar-label {
  font-size: 13px;
  color: var(--muted-foreground);
  min-width: 66px;
}
button.chip {
  font-family: inherit;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
button.chip:hover { background: var(--accent); color: var(--accent-foreground); }
/* The current value outranks its hover: clicking it again is a no-op, and it
   should not flicker as though something were about to change. */
button.chip.is-current, button.chip.is-current:hover {
  background: var(--primary);
  color: var(--primary-foreground);
  border-color: var(--primary);
}
/* Except red, which is the one colour allowed to carry meaning rather than
   selection — and it only ever appears on the value that is actually set. */
button.chip.is-current.chip-alert, button.chip.is-current.chip-alert:hover {
  background: var(--destructive);
  color: var(--destructive-foreground);
  border-color: var(--destructive);
}
/* "Not set" keeps its dashed edge while selected: it is a real value, and the
   fill alone would make it look like any other choice. */
button.chip.is-current.chip-none { border-style: dashed; }

/* ─── table ───────────────────────────────────────────────────────────────── */

.items { width: 100%; border-collapse: collapse; font-size: 14px; }
.items th {
  text-align: start;
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted-foreground);
  padding: 0 12px 8px;
  border-bottom: 1px solid var(--border);
}
.items td { padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: top; }
.items tr:hover td { background: var(--muted); }
.items .title { font-weight: 500; max-width: 42ch; }
/* Timestamps and severities only line up when the digits do. */
.num { font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--muted-foreground); }
.sev-high { color: var(--destructive); }
.is-revoked td { opacity: 0.55; }
.actions { display: flex; gap: 6px; }
.actions form { display: contents; }

.status {
  display: inline-block;
  font-size: 12px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}
.status-new { background: var(--secondary); }
.status-triaged { background: transparent; }
.status-done { background: transparent; color: var(--muted-foreground); }

/* ─── detail ──────────────────────────────────────────────────────────────── */

.detail { max-width: 78ch; }
.detail h1 { font-size: 22px; font-weight: 600; letter-spacing: -0.025em; margin: 0 0 6px; }
.meta { color: var(--muted-foreground); font-size: 14px; margin: 0; }
.body {
  white-space: pre-wrap;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--card);
  margin-bottom: 20px;
}
.shot { margin: 0 0 20px; }
.shot img {
  display: block;
  max-width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
}
.shot figcaption { font-size: 13px; color: var(--muted-foreground); margin-top: 6px; }

.facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 8px 20px;
  font-size: 14px;
  margin: 0;
}
.facts dt { color: var(--muted-foreground); }
.facts dd { margin: 0; word-break: break-word; }
.facts code, .detail code {
  font-family: var(--font-mono);
  font-size: 13px;
  background: var(--muted);
  border-radius: var(--radius-sm);
  padding: 1px 5px;
}
.excerpt { display: block; color: var(--muted-foreground); margin-top: 2px; text-align: left; }

.card {
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--card);
  padding: 20px;
  margin-bottom: 20px;
}

@media (max-width: 720px) {
  main { padding: 20px 16px; }
  .chrome { padding: 12px 16px; gap: 12px; flex-wrap: wrap; }
  .scope { display: none; }
  .facts { grid-template-columns: 1fr; gap: 2px 0; }
  .facts dt { margin-top: 10px; }
}

/* A withdrawn item stays in the queue rather than vanishing from under whoever
   was reading it — dimmed and struck, so it is visibly out of play without
   being gone. Clearing withdrawn_at restores it. */
.is-withdrawn td { opacity: 0.55; }
.is-withdrawn .title a { text-decoration: line-through; }
