/* Memex Web — design system v2
   Colors: warm-gold accent on clean white/light-gray.
   Spacing: 4px base grid. Typography: 15px body, 4-level hierarchy. */

/* ── Z-index scale ──────────────────────────────────────────────────────── */
:root {
  --z-sticky:   100;
  --z-dropdown: 200;
  --z-toast:    300;
  --z-bar:      290;
  --z-backdrop: 400;
  --z-modal:    410;
}

/* ── Reset ────────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box;margin:0}
img,svg,video{display:block;max-width:100%}
input,button,textarea,select{font:inherit}
/* Ensure [hidden] always wins over explicit display values */
[hidden]{display:none!important}

/* ── Design tokens ─────────────────────────────────────────────────────── */
:root {
  /* Spacing (4px base × 2^n) */
  --sp-2xs: 4px;
  --sp-xs:  8px;
  --sp-sm:  12px;
  --sp-md:  16px;
  --sp-lg:  24px;
  --sp-xl:  32px;
  --sp-2xl: 48px;
  --sp-3xl: 64px;

  /* Typography */
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", "SF Mono", "Cascadia Code", "Fira Code", monospace;
  --fs-xs: 12px; --fs-sm: 13px; --fs-base: 15px; --fs-lg: 18px;
  --fs-h3: 16px; --fs-h2: 20px; --fs-h1: 28px;
  --lh-tight: 1.25; --lh-base: 1.55; --lh-relaxed: 1.7;

  /* Motion */
  --ease-out: cubic-bezier(.16,1,.3,1);
  --dur-fast: 120ms; --dur-base: 200ms; --dur-slow: 400ms;

  /* Radii */
  --radius-sm: 5px; --radius-md: 8px; --radius-lg: 12px; --radius-full: 999px;

  /* ── Colors (oklch) ── */
  /* Light base */
  --ink:       oklch(15% 0.005 95);        /* primary text */
  --ink-dim:   oklch(42% 0.008 90);        /* secondary text */
  --ink-faded: oklch(46% 0.007 90);        /* tertiary text — AA 4.5:1 even at 11px on surface */

  /* Surfaces */
  --paper:     oklch(97% 0.002 95);        /* page bg */
  --surface:   oklch(100% 0 0);            /* card bg */
  --raised:    oklch(94% 0.003 95);        /* hover/active bg */
  --raised-hover: oklch(90% 0.004 95);     /* hover step on raised controls */
  --overlay:   oklch(96% 0.002 95);        /* input bg */

  /* Borders */
  --rule:        oklch(86% 0.004 95);      /* default border */
  --rule-subtle: oklch(91% 0.003 95);      /* subtle border */
  --rule-strong: oklch(80% 0.005 95);      /* hover border */
  --border:      var(--rule);              /* legacy alias — some inline styles use --border */
  --rule-hover:  var(--rule-strong);       /* card hover border */

  /* Brand accent — warm gold */
  --accent:        oklch(62% 0.14 75);
  --accent-soft:   oklch(62% 0.14 75 / .15);
  --accent-hover:  oklch(55% 0.15 72);
  --accent-ink:    oklch(50% 0.15 72);     /* gold text on accent-soft — AA 4.5:1 */

  /* Filled controls that carry text (primary buttons, active filter pills).
     Deeper than --accent so --accent-contrast text meets AA 4.5:1 on them;
     dark mode flips to light-gold fill + dark text. */
  --accent-fill:        oklch(56% 0.15 72);
  --accent-fill-hover:  oklch(50% 0.15 72);
  --accent-contrast:    oklch(100% 0 0);
  --danger-contrast:    oklch(100% 0 0);   /* text on solid --danger fill */

  /* Semantic */
  --success:        oklch(45% 0.16 145);
  --success-soft:   oklch(45% 0.16 145 / .12);
  --success-border: oklch(40% 0.14 142);
  --danger:         oklch(46% 0.19 25);
  --danger-soft:    oklch(46% 0.19 25 / .12);
  --warning:        oklch(52% 0.13 78);
  --warning-soft:   oklch(52% 0.13 78 / .12);
  --info:           oklch(48% 0.12 230);
  --info-soft:      oklch(48% 0.12 230 / .12);

  /* Card accent tints */
  --card-upload:   oklch(65% 0.12 230 / .08);
  --card-butler:   oklch(68% 0.13 78 / .08);
  --card-budget:   oklch(62% 0.16 145 / .08);

  /* Elevation — shadow color is a token so dark mode can redefine it */
  --shadow-color: 15% 0.01 95;
  --shadow-sm:
    0 1px 2px oklch(var(--shadow-color) / .04),
    0 1px 1px oklch(var(--shadow-color) / .03);
  --shadow-md:
    0 6px 20px oklch(var(--shadow-color) / .08),
    0 2px 6px oklch(var(--shadow-color) / .05);
}

/* ── Dark mode ──────────────────────────────────────────────────────────
   Token-only override: every surface/card consumes these vars, so the dark
   theme needs no per-component rules. Opt in with the OS setting; the
   [data-theme] hooks let a future toggle force either mode. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink:       oklch(92% 0.005 95);
    --ink-dim:   oklch(72% 0.008 90);
    --ink-faded: oklch(66% 0.008 90);      /* AA on dark surface even at 11px */

    --paper:     oklch(18% 0.004 95);
    --surface:   oklch(22% 0.004 95);
    --raised:    oklch(27% 0.005 95);
    --raised-hover: oklch(32% 0.006 95);
    --overlay:   oklch(25% 0.004 95);

    --rule:        oklch(34% 0.006 95);
    --rule-subtle: oklch(29% 0.005 95);
    --rule-strong: oklch(42% 0.007 95);

    --accent:        oklch(72% 0.13 78);
    --accent-soft:   oklch(72% 0.13 78 / .18);
    --accent-hover:  oklch(78% 0.12 80);
    --accent-ink:    oklch(80% 0.12 80);   /* gold text on dark accent-soft */

    --accent-fill:        oklch(72% 0.13 78);
    --accent-fill-hover:  oklch(78% 0.12 80);
    --accent-contrast:    oklch(20% 0.03 78);  /* dark ink on light-gold fill — 7.2:1 */
    --danger-contrast:    oklch(18% 0.02 27);  /* dark ink on light-red fill — 6.1:1 */

    --success:        oklch(72% 0.15 150);
    --success-soft:   oklch(72% 0.15 150 / .16);
    --success-border: oklch(60% 0.14 148);
    --danger:         oklch(68% 0.17 27);
    --danger-soft:    oklch(68% 0.17 27 / .16);
    --warning:        oklch(76% 0.13 80);
    --warning-soft:   oklch(76% 0.13 80 / .16);
    --info:           oklch(70% 0.12 232);
    --info-soft:      oklch(70% 0.12 232 / .16);

    /* Shadows read as depth via a darker, slightly stronger cast on dark bg. */
    --shadow-color: 0% 0 0;
    --shadow-sm:
      0 1px 2px oklch(var(--shadow-color) / .35),
      0 1px 1px oklch(var(--shadow-color) / .25);
    --shadow-md:
      0 6px 20px oklch(var(--shadow-color) / .45),
      0 2px 6px oklch(var(--shadow-color) / .3);
  }
}

/* ── Base ──────────────────────────────────────────────────────────────── */
body {
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  background: var(--paper);
  color: var(--ink);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* ── Typography ────────────────────────────────────────────────────────── */
h1 { font-size: var(--fs-h1); font-weight: 700; line-height: var(--lh-tight);
     color: var(--ink); margin-bottom: var(--sp-lg); letter-spacing: -.01em;
     text-wrap: balance; }
h2 { font-size: var(--fs-h2); font-weight: 600; line-height: 1.3;
     color: var(--ink); margin: var(--sp-xl) 0 var(--sp-sm);
     text-wrap: balance; }
h3 { font-size: var(--fs-h3); font-weight: 600; line-height: 1.35;
     color: var(--ink-dim); margin-bottom: var(--sp-sm);
     text-wrap: balance; }

/* ── Navigation ────────────────────────────────────────────────────────── */
nav {
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
  padding: 0 var(--sp-lg); height: 56px;
  display: flex; align-items: center; gap: var(--sp-lg);
  position: sticky; top: 0; z-index: var(--z-sticky);
  box-shadow: 0 1px 3px oklch(0% 0 0 / .06);
}
nav a { color: var(--ink-dim); text-decoration: none; font-size: var(--fs-sm);
        font-weight: 500; transition: color var(--dur-fast); }
nav a:hover { color: var(--ink); }
nav .brand {
  color: var(--accent); font-weight: 700; font-size: 17px;
  letter-spacing: -.01em;
}

/* ── Layout ────────────────────────────────────────────────────────────── */
main { max-width: 1120px; margin: 0 auto; padding: var(--sp-xl) var(--sp-lg); }

/* ── Cards ─────────────────────────────────────────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  padding: var(--sp-lg);
  margin-bottom: var(--sp-lg);
  transition: border-color var(--dur-fast);
}
.card:hover { border-color: var(--rule-hover); }
.card-header {
  font-size: var(--fs-lg); font-weight: 600;
  margin-bottom: var(--sp-md); color: var(--ink);
  display: flex; align-items: center; gap: var(--sp-xs);
}

.card-upload  { background: color-mix(in oklch, var(--surface), oklch(65% 0.12 230) 5%); }
.card-wiki    { background: color-mix(in oklch, var(--surface), oklch(75% 0.12 75) 4%); }
.card-butler  { background: color-mix(in oklch, var(--surface), oklch(68% 0.13 78) 4%); }

/* ── Forms ─────────────────────────────────────────────────────────────── */
.form-group { margin-bottom: var(--sp-md); }
.form-group label {
  display: block; font-size: var(--fs-sm); color: var(--ink-dim);
  margin-bottom: var(--sp-2xs); font-weight: 500;
}
.form-group input, .form-group select {
  width: 100%; padding: var(--sp-sm) var(--sp-md);
  background: var(--overlay); border: 1px solid var(--rule);
  border-radius: var(--radius-sm); color: var(--ink); font-size: var(--fs-base);
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.form-group input:focus, .form-group select:focus {
  border-color: var(--accent); outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.form-group input:disabled {
  background: var(--raised); color: var(--ink-dim); cursor: not-allowed;
}
.form-group input[type=file] { padding: var(--sp-xs) var(--sp-sm); }

/* ── Buttons ───────────────────────────────────────────────────────────── */
.btn {
  padding: var(--sp-xs) var(--sp-md); border: 1px solid var(--rule);
  border-radius: var(--radius-sm); background: var(--raised);
  color: var(--ink); cursor: pointer; font-size: var(--fs-sm); font-weight: 500;
  transition: background var(--dur-fast), border-color var(--dur-fast);
  display: inline-flex; align-items: center; gap: var(--sp-2xs);
}
.btn:hover { background: var(--raised-hover); border-color: var(--rule-strong); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
.btn-primary { background: var(--accent-fill); border-color: var(--accent-fill);
               color: var(--accent-contrast); font-weight: 600; }
.btn-primary:hover { background: var(--accent-fill-hover); border-color: var(--accent-fill-hover); }
.btn-danger { background: var(--danger-soft); border-color: var(--danger);
              color: var(--danger); font-weight: 600; }
.btn-danger:hover { background: var(--danger); color: var(--danger-contrast); }
.btn-sm { padding: var(--sp-2xs) var(--sp-sm); font-size: var(--fs-xs); min-height: 36px; }

/* ── Badges ────────────────────────────────────────────────────────────── */
.badge {
  display: inline-block; padding: var(--sp-2xs) var(--sp-sm);
  border-radius: var(--radius-full); font-size: var(--fs-xs);
  font-weight: 600; line-height: 1.4;
}
.badge-queued    { background: var(--raised); color: var(--ink-dim); }
.badge-starting  { background: var(--info-soft); color: var(--info); }
.badge-running   { background: var(--info-soft); color: var(--info); }
.badge-ready     { background: var(--warning-soft); color: var(--warning); }
.badge-completed { background: var(--success-soft); color: var(--success); }
.badge-failed    { background: var(--danger-soft); color: var(--danger); }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:.45} }
.badge-running { animation: pulse 2s var(--ease-out) infinite; }

/* Auth/token state badges — shared by console and settings pages. */
.auth-badge { padding: 1px 8px; border-radius: var(--radius-full); font-size: var(--fs-xs); }
.auth-required { background: var(--danger-soft); color: var(--danger); }
.auth-optional { background: var(--success-soft); color: var(--success); }

/* ── Tables ────────────────────────────────────────────────────────────── */
table { width: 100%; border-collapse: collapse; }
th, td { padding: var(--sp-sm) var(--sp-md); text-align: left;
         border-bottom: 1px solid var(--rule-subtle); font-size: var(--fs-sm); }
th { color: var(--ink-dim); font-weight: 600; font-size: var(--fs-xs); }
tr:hover td { background: var(--raised); }
.job-row { cursor: pointer; }

/* ── Log ───────────────────────────────────────────────────────────────── */
.log {
  background: var(--paper); border: 1px solid var(--rule);
  border-radius: var(--radius-sm); padding: var(--sp-md);
  max-height: 600px; overflow-y: auto;
  font-family: var(--font-mono); font-size: var(--fs-sm); line-height: 1.65;
}
.log-entry { padding: 1px 0; white-space: pre-wrap; word-break: break-all; }
.log-phase  { color: var(--accent); font-weight: 600; }
.log-text   { color: var(--ink-dim); padding-left: var(--sp-xs); }
.log-token  { color: var(--success); padding-left: var(--sp-xs); }
.log-error  { color: var(--danger); padding-left: var(--sp-xs); }
.log-done   { color: var(--success); font-weight: 600; }
.log-step   { color: var(--ink); padding-left: var(--sp-xs); }
.log-dim    { color: var(--ink-dim); font-size: 11px; }
.log-ts     { color: var(--ink-dim); font-size: 11px; margin-right: var(--sp-xs); }
.log-tag    {
  color: var(--accent); font-size: 11px; font-weight: 600;
  border: 1px solid var(--rule-subtle); border-radius: var(--radius-full);
  padding: 0 6px; margin-right: var(--sp-xs); white-space: nowrap;
}

/* ── Info grid ─────────────────────────────────────────────────────────── */
.info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-xs); }
.info-item { display: flex; gap: var(--sp-xs); }
.info-label { color: var(--ink-dim); min-width: 60px; font-size: var(--fs-sm); }
.info-value { color: var(--ink); font-weight: 500; }

/* ── Token cards / stats ───────────────────────────────────────────────── */
.token-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-sm); }
.token-card {
  background: var(--paper); border: 1px solid var(--rule-subtle);
  border-radius: var(--radius-sm); padding: var(--sp-md);
  text-align: center;
  display: flex; flex-direction: column-reverse; gap: var(--sp-2xs);
}
.token-card .num { font-size: 22px; font-weight: 700; color: var(--accent); letter-spacing: -.01em; }
.token-card .lbl { font-size: var(--fs-xs); color: var(--ink-dim); }

/* ── Toast notifications ───────────────────────────────────────────────── */
#toast-container {
  position: fixed; top: 72px; right: var(--sp-lg); z-index: var(--z-toast);
  display: flex; flex-direction: column; gap: var(--sp-xs); min-width: 320px;
}
.toast {
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius-md); padding: var(--sp-sm) var(--sp-md);
  display: flex; align-items: flex-start; gap: var(--sp-sm);
  box-shadow: 0 4px 24px oklch(0% 0 0 / .12);
  animation: toast-in var(--dur-slow) var(--ease-out);
}
@keyframes toast-in  { from{opacity:0;transform:translateX(16px)} to{opacity:1;transform:translateX(0)} }
@keyframes toast-out { from{opacity:1;transform:translateX(0)} to{opacity:0;transform:translateX(16px)} }
.toast-removing { animation: toast-out var(--dur-base) ease-in forwards; }
.toast-icon { font-size: 15px; flex-shrink: 0; line-height: 1.4; }
.toast-msg  { flex:1; font-size: var(--fs-sm); line-height: var(--lh-base); }
.toast-close { background:none; border:none; color:var(--ink-dim); cursor:pointer;
               font-size:14px; padding:6px 8px; line-height:1; min-width:32px; min-height:32px; }
.toast-close:hover { color: var(--ink); }
.toast-success { border-color: var(--success); }
.toast-error   { border-color: var(--danger); }
.toast-warn    { border-color: var(--warning); }
.toast-info    { border-color: var(--accent); }

/* ── Wiki list ─────────────────────────────────────────────────────────── */
.wiki-actions { display:flex; gap:var(--sp-xs); flex-wrap:wrap; align-items:center; }
.wiki-stat { font-size:var(--fs-xs); color:var(--ink-dim); display:flex; align-items:center; gap:var(--sp-2xs); }
.wiki-progress { display:flex; gap:3px; align-items:center; }
.wiki-progress-dot { width:8px; height:8px; border-radius:50%; }
.wiki-progress-dot.done { background:var(--success); }
.wiki-progress-dot.pending { background:var(--rule); }
.wiki-name { font-weight:600; }
.wiki-name a { color:var(--ink); text-decoration:none; }
.wiki-name a:hover { color:var(--accent); }
.wiki-card-times { display:inline-block; font-size:11px; color:var(--ink-faded); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%; min-width:0; }
.wiki-card-model { flex-basis:100%; }

/* ── Next-step card ────────────────────────────────────────────────────── */
.next-step {
  background: var(--info-soft); border:1px solid oklch(48% 0.12 230 / .25);
  border-radius: var(--radius-md); padding: var(--sp-md); margin-top: var(--sp-md);
}
.next-step .title { font-weight:600; color:var(--info); margin-bottom:var(--sp-xs); }
.next-step code { font-size:var(--fs-sm); color:var(--ink); background:var(--paper);
                  padding: 2px 8px; border-radius: var(--radius-sm); }
.next-step .hint { color:var(--ink-dim); font-size:var(--fs-xs); margin-top:var(--sp-xs); }

/* ── Utilities ─────────────────────────────────────────────────────────── */
.flex { display:flex; gap:var(--sp-sm); align-items:center; }
.flex-wrap { flex-wrap:wrap; }
.text-dim { color:var(--ink-dim); font-size:var(--fs-sm); }
.grid-2 { display:grid; grid-template-columns:repeat(auto-fit, minmax(400px, 1fr)); gap:var(--sp-lg); }
.token-grid-2col { grid-template-columns:1fr 1fr; }
.card-header-spread { display:flex; justify-content:space-between; align-items:center; }
.status-ok { color:var(--success); }
.status-missing { color:var(--danger); }
.mb-16 { margin-bottom: var(--sp-md); }
.mt-sm { margin-top: var(--sp-sm); }
.ml-sm { margin-left: var(--sp-sm); }
.text-xs { font-size: var(--fs-xs); }
.status-dot { display:inline-block; width:6px; height:6px; border-radius:50%; vertical-align:middle; }
.dot-green { background: var(--success); }
.dot-gray  { background: var(--ink-faded); }

/* ── Confirm modal ─────────────────────────────────────────────────────── */
.confirm-overlay {
  position: fixed; inset: 0; background: oklch(0% 0 0 / .35);
  display: flex; align-items: center; justify-content: center;
  z-index: var(--z-backdrop); backdrop-filter: blur(4px);
  animation: fade-in var(--dur-base) var(--ease-out);
}
@keyframes fade-in { from{opacity:0} to{opacity:1} }
.confirm-dialog {
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius-lg); padding: var(--sp-xl);
  max-width: 420px; width: 90vw; text-align: center;
  box-shadow: 0 8px 40px oklch(0% 0 0 / .12);
  animation: modal-in var(--dur-slow) var(--ease-out);
}
@keyframes modal-in { from{opacity:0;transform:scale(.95) translateY(8px)} to{opacity:1;transform:scale(1) translateY(0)} }
.confirm-icon { font-size: 32px; margin-bottom: var(--sp-sm); }
.confirm-message { font-size: var(--fs-base); color: var(--ink); line-height: 1.5; margin-bottom: var(--sp-lg); }
.confirm-actions { display: flex; gap: var(--sp-sm); justify-content: center; }
.confirm-actions .btn { min-width: 80px; }

/* ── API Token 登录 modal ──────────────────────────────────────────────── */
.token-dialog {
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius-lg); padding: var(--sp-xl);
  max-width: 420px; width: 90vw;
  box-shadow: 0 8px 40px oklch(0% 0 0 / .12);
  animation: modal-in var(--dur-slow) var(--ease-out);
}
.token-head { text-align: center; margin-bottom: var(--sp-lg); }
.token-badge {
  width: 52px; height: 52px; margin: 0 auto var(--sp-sm);
  display: flex; align-items: center; justify-content: center;
  font-size: 26px; border-radius: var(--radius-full);
  background: var(--accent-soft);
}
.token-title { font-size: var(--fs-h2); font-weight: 600; color: var(--ink); margin: 0 0 var(--sp-2xs); }
.token-sub { font-size: var(--fs-sm); color: var(--ink-dim); line-height: 1.5; margin: 0; }
.token-field { position: relative; }
.token-input {
  width: 100%; padding: var(--sp-sm) 42px var(--sp-sm) var(--sp-md);
  background: var(--overlay); border: 1px solid var(--rule);
  border-radius: var(--radius-sm); color: var(--ink);
  font-size: var(--fs-base); font-family: var(--font-mono, monospace);
  letter-spacing: .02em;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.token-input:focus {
  border-color: var(--accent); outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.token-reveal {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  width: 32px; height: 32px; padding: 0; border: none;
  background: transparent; cursor: pointer; opacity: .5;
  border-radius: var(--radius-sm); font-size: 15px;
  transition: opacity var(--dur-fast), background var(--dur-fast);
}
.token-reveal:hover { opacity: .85; background: var(--raised); }
.token-reveal--on { opacity: 1; }
.token-error {
  margin: var(--sp-sm) 0 0; font-size: var(--fs-sm);
  color: var(--danger); line-height: 1.4;
}
.token-hint {
  margin: var(--sp-md) 0 0; font-size: var(--fs-sm);
  color: var(--ink-dim); line-height: 1.5;
}
.token-hint a { color: var(--accent-ink); text-decoration: none; }
.token-hint a:hover { text-decoration: underline; }
.token-actions {
  display: flex; gap: var(--sp-sm); justify-content: flex-end;
  margin-top: var(--sp-lg);
}
.token-actions .btn { min-width: 88px; justify-content: center; }

/* ── Connection bar ────────────────────────────────────────────────────── */
.connection-bar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: var(--z-bar);
  padding: var(--sp-xs) var(--sp-lg); text-align: center;
  font-size: var(--fs-xs); font-weight: 500;
  display: flex; align-items: center; justify-content: center; gap: var(--sp-xs);
}
.connection-lost { background: var(--danger-soft); color: var(--danger); }
.connection-restored { background: var(--success-soft); color: var(--success); }
.connection-dot { width: 6px; height: 6px; border-radius: 50%; }
.connection-lost .connection-dot { background: var(--danger); animation: pulse 1s infinite; }
.connection-restored .connection-dot { background: var(--success); }

/* ── Skeleton loading ──────────────────────────────────────────────────── */
@keyframes shimmer { 0%{background-position:-400px 0} 100%{background-position:400px 0} }
.skeleton {
  background: linear-gradient(90deg, var(--surface) 25%, var(--raised) 50%, var(--surface) 75%);
  background-size: 800px 100%;
  animation: shimmer 1.5s infinite;
  border-radius: var(--radius-sm);
}
.skeleton-row { display: flex; gap: var(--sp-md); padding: var(--sp-sm) var(--sp-md); }
.skeleton-row .sk-text { height: 14px; flex: 1; }
.skeleton-row .sk-text.sk-short { flex: 0.4; }
.skeleton-row .sk-badge { height: 20px; width: 56px; border-radius: var(--radius-full); }
.skeleton-table .sk-header { height: 32px; margin-bottom: var(--sp-xs); }
.skeleton-table .sk-row { height: 40px; margin-bottom: 2px; }

/* ── Accessibility ─────────────────────────────────────────────────────── */
/* Visually hidden but available to screen readers (labels for icon-only or
   placeholder-only controls). */
.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;
}
:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft), 0 0 0 1px var(--accent);
}
a:focus-visible { border-radius: var(--radius-sm); }

@media (prefers-reduced-motion: reduce) {
  *,*::before,*::after { animation-duration:0.01ms !important; transition-duration:0.01ms !important; }
}

/* ── Mobile ────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
  :root { --fs-h1: 22px; --fs-h2: 17px; --fs-base: 15px; }
  main { padding: var(--sp-md) var(--sp-sm); max-width:100%; }
  h1 { margin-bottom: var(--sp-md); }
  h2 { margin: var(--sp-lg) 0 var(--sp-xs); }
  nav { padding:0 var(--sp-sm); gap:var(--sp-sm); height:48px; }
  nav a { font-size:var(--fs-xs); min-height:44px; display:flex; align-items:center; }
  nav .brand { font-size:15px; }
  .card { padding:var(--sp-md); margin-bottom:var(--sp-md); }
  .grid-2 { grid-template-columns:1fr; }
  .info-grid { grid-template-columns:1fr; }
  .token-grid { grid-template-columns:repeat(2,1fr); }
  /* Scrollable table on mobile */
  .card table { display:block; overflow-x:auto; -webkit-overflow-scrolling:touch; }
  th,td { padding:var(--sp-xs) var(--sp-sm); font-size:var(--fs-xs); white-space:nowrap; }
  .btn { padding:6px 12px; font-size:var(--fs-xs); }
  /* Touch targets: lift small buttons + the card job/status row to the 44px minimum */
  .btn-sm { min-height:44px; }
  .wiki-card-footer .btn { min-height:44px; }
  .wiki-card-job { min-height:44px; padding-block:10px; }
  #toast-container { right:var(--sp-sm); min-width:auto; left:var(--sp-sm); }
  /* Butler drawer: respect safe area + keyboard */
  .butler-drawer { padding-bottom: env(safe-area-inset-bottom, 0px); max-height:50vh; }
  .butler-drawer-close { min-width:44px; min-height:44px; font-size:18px; }
  /* Wiki card footer: keep action rows readable on touch screens. */
  .wiki-card-footer { gap:var(--sp-sm); }
  .wiki-card-actions { justify-content:stretch; }
  .wiki-card-actions .btn, .wiki-card-more > summary { flex:1; justify-content:center; }
  .wiki-card-more { flex:1 1 100%; }
  .wiki-card-more-menu { justify-content:stretch; }
}

/* ── Super-small (< 375px) ─────────────────────────────────────────────── */
@media (max-width: 374px) {
  :root { --fs-h1: 20px; --fs-base: 14px; }
  main { padding: var(--sp-sm) var(--sp-xs); }
  nav a:not(.brand) { display:none; }  /* hide nav links, keep brand */
  #toast-container { left: var(--sp-xs); right: var(--sp-xs); }
}
