/*
  verify-code-relay 管理介面 — 設計系統

  方向：郵務。深郵筒綠撐起結構（導覽軌、主要按鈕、登入頁底色），信封上的郵遞區號格是
  招牌元素：驗證碼輸入框畫成一格一字的方格（.otp-input，空白時為墨色細框，聚焦轉綠，
  只有出錯時才轉紅），唯讀的代碼顯示（.postcode）用紅框。紅色只留給郵遞區號格與錯誤。
  其餘元件保持安靜：白卡、細線、系統字型。

  版面：桌機為左側導覽軌（目前頁面的分頁「接」進內容區）；860px 以下改為頂部列與
  可橫向捲動的分頁列。

  元件配方（範本請照抄結構）：
    頁首    <header class="page-head"><div><h1 class="page-title">…</h1><p class="page-desc">…</p></div><div class="page-actions">…</div></header>
    卡片    <section class="card"><header class="card-head"><div><h2 class="card-title">…</h2><p class="card-desc">…</p></div>…</header><div class="card-body">…</div><footer class="card-foot">…</footer></section>
    欄位    <div class="field"><label class="label" for="x">名稱<span class="opt">選填</span></label><input class="input" id="x"><p class="hint">…</p>{{template "field-error" …}}</div>
            錯誤時在 input 加 aria-invalid="true"。並排欄位放在 .grid-2 裡。
    機密    <div class="secret"><input class="input" type="password" placeholder="已設定，留空表示不變"><button type="button" class="secret-toggle" data-reveal="id" aria-label="顯示" aria-pressed="false">…</button></div>
            已儲存的機密在標籤旁放 <span class="tag tag-set">…lock icon…已設定</span>。
    按鈕    .btn ＋ .btn-primary | .btn-danger | .btn-ghost；尺寸 .btn-sm | .btn-lg；.btn-block 撐滿；只有圖示用 .icon-btn。
    徽章    .badge ＋ .badge-ok | .badge-warn | .badge-err | .badge-info | .badge-idle；進行中加 .badge-live（圓點脈動）。
    表格    <div class="table-wrap"><table class="table">…</table></div>；數字欄 td.num，等寬 .mono。
    空狀態  <section class="empty"><span class="empty-icon">icon</span><h2 class="empty-title">…</h2><p class="empty-text">…</p>動作按鈕</section>
    提示框  .callout ＋ .callout-error | .callout-warn | .callout-info | .callout-ok（icon ＋ <p>）。
    彈出    <dialog class="modal" id="x"><div class="modal-head"><h2 class="modal-title">…</h2><button class="icon-btn" data-modal-close>…</button></div><div class="modal-body">…</div><div class="modal-foot">…</div></dialog>
            以 data-modal-open="x" 開啟。
    代碼    <p class="postcode"><span>8</span><span>3</span>…</p>
    清單    <ul class="tg-list"><li class="tg-item">主要文字 | 使用情況 | .tg-actions</li></ul>（Telegram 頁；每列一筆可操作的項目）
    郵票    <label class="stamp-pick"><input type="radio"><span class="stamp"><span class="stamp-face">…</span></span></label>
            信箱頁的服務選擇：打孔邊緣（mask）、刻字縮寫；選中時蓋上郵戳。每頁只用在一處。
    勾選卡  <label class="route-pick"><input type="checkbox"><span class="route-card">…<span class="route-check">check icon</span></span></label>
    路徑    <p class="route"><span class="route-bot">bot</span><span class="route-line"></span><span class="route-chat">chat_id</span></p>
    表單彈出 <dialog class="modal modal-form" data-open?><form>modal-head／modal-body／modal-foot</form></dialog>；
            伺服器退回表單時在 dialog 加 data-open，載入後自動開啟。
    授權    頁面放一份 {{template "oauth-dialog"}}（_oauth.html），按鈕加 data-oauth-start="信箱"；
            清單上的授權按鈕用 .btn-auth（琥珀色，表示需要處理）。
    子分頁  {{template "rules-nav" "rules"}}（_rules_nav.html）：同一導覽項目下的幾個頁面，放在頁首之前。
    規則鏈  <ol class="rule-chain"><li class="rule">.rule-head（.rule-no 以 CSS counter 編號）＋ .rule-body</li></ol>＋ .rule-end；
            處理方式選「略過」時列首顯示琥珀色橡皮章 .rule-badge-ignore。
    標籤    <div class="field kw-field" data-tags><textarea data-tags-source>一行一個</textarea></div>，app.js 轉成 .tags-box。
    未儲存  form[data-dirty-watch] 內放 <p class="save-note" data-dirty-note hidden>…</p>（通常在 .save-bar 裡）。
    預覽    figure.tg-phone：Telegram 對話的樣子（.tg-bar／.tg-chat 裡的 .tg-bubble 與 .tg-kb／.tg-meta）。
    健康    總覽頁首的 section.health：郵戳（.health-mark）的顏色與中間字是整體狀態，底弧是最近一次更新時間；
            顏色來自外層 [data-state]（ok｜info｜warn｜err｜idle），信箱卡片 .dash-card[data-state] 為 ok｜busy｜bad。
    紀錄    table.table.log-table，每列用 {{template "log-row" …}}（_logs.html）；640px 以下每列變成一張小卡。
*/

:root {
  --green-950: #08291e;
  --green-900: #0d3d2c;
  --green-800: #124a36;
  --green-700: #136246;
  --green-600: #187653;
  --green-300: #8fc2a5;
  --green-200: #bdd9c9;
  --green-100: #dcebe2;
  --green-50: #eef6f1;

  --paper: #f2f4ef;
  --surface: #ffffff;
  --surface-2: #f8faf7;
  --sunken: #e8ece5;
  --ink: #17201b;
  --ink-2: #39463f;
  --muted: #5b6861;
  --faint: #87938c;
  --line: #dae0d7;
  --line-2: #c2cbc1;

  --red: #c8332b;
  --red-700: #a2261f;
  --red-100: #f6d3cf;
  --red-50: #fcefed;
  --amber: #c98a12;
  --amber-ink: #835200;
  --amber-100: #f4ddb0;
  --amber-50: #fdf5e4;
  --blue: #1f6aa5;
  --blue-100: #cbe0f0;
  --blue-50: #ebf3fa;

  --radius: 10px;
  --radius-sm: 7px;
  --shadow-1: 0 1px 2px rgba(13, 61, 44, 0.06), 0 1px 1px rgba(13, 61, 44, 0.03);
  --shadow-2: 0 18px 40px -12px rgba(8, 41, 30, 0.35), 0 3px 8px rgba(8, 41, 30, 0.08);
  --ring: 0 0 0 3px rgba(24, 118, 83, 0.2);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang TC", "Noto Sans TC", "Noto Sans CJK TC",
    "Microsoft JhengHei", "Heiti TC", system-ui, sans-serif;
  /* an engraved face for stamp initials only */
  --engrave: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, "Noto Serif TC", serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "JetBrains Mono", Menlo, Consolas, "Liberation Mono", monospace;

  --rail-w: 232px;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* ---------- base ---------- */

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

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, p, ol, ul, dl, dd, figure { margin: 0; }
img, svg { display: block; }
a { color: var(--green-700); text-underline-offset: 3px; }
a:hover { color: var(--green-600); }
code, kbd, .mono { font-family: var(--mono); font-size: 0.9em; }
code { padding: 0.1em 0.4em; border-radius: 4px; background: var(--sunken); }
b, strong { font-weight: 700; }

:focus-visible { outline: 2.5px solid var(--green-600); outline-offset: 2px; }
::selection { background: var(--green-100); }

.icon { width: 18px; height: 18px; flex: none; }

.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;
}

.skip-link {
  position: absolute; left: 12px; top: -48px; z-index: 50;
  padding: 8px 14px; border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink); font-weight: 600; box-shadow: var(--shadow-2);
}
.skip-link:focus { top: 12px; }

.muted { color: var(--muted); }
.hint { margin: 0; font-size: 13px; line-height: 1.55; color: var(--muted); }
.eyebrow { margin-bottom: 6px; font-size: 12.5px; font-weight: 700; letter-spacing: 0.14em; color: var(--green-700); }
.link { font-weight: 600; }
.stack > * + * { margin-top: 20px; }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 20px; }

/* ---------- brand ---------- */

.brand {
  display: flex; align-items: center; gap: 11px;
  color: #fff; text-decoration: none;
}
.brand:hover { color: #fff; }

/* three postcode boxes on a stamp-white tile */
.brand-mark {
  display: inline-flex; align-items: center; justify-content: center; gap: 2px;
  width: 36px; height: 36px; flex: none;
  border-radius: 9px; background: var(--paper);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4), 0 1px 0 rgba(0, 0, 0, 0.25);
}
.brand-mark i { width: 8px; height: 11px; border: 1.5px solid var(--red); background: #fff; }

.brand-name { display: flex; flex-direction: column; font-size: 16px; font-weight: 700; line-height: 1.2; letter-spacing: 0.04em; }
.brand-name small { font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.02em; opacity: 0.62; }

/* ---------- app shell ---------- */

/* the rail's green is painted by the shell so it runs the full page height, however long
   the content; the rail itself stays in view while scrolling */
.shell {
  display: grid; grid-template-columns: var(--rail-w) minmax(0, 1fr); min-height: 100vh;
  background: linear-gradient(90deg, var(--green-900) var(--rail-w), transparent var(--rail-w));
}

.rail {
  position: sticky; top: 0; height: 100vh;
  display: grid; grid-template-rows: auto 1fr auto; grid-template-areas: "brand" "nav" "logout";
  padding: 22px 0 18px 14px;
  background: var(--green-900);
  color: #cde1d5;
}
.rail .brand { grid-area: brand; padding: 0 14px 26px 6px; }

.nav { grid-area: nav; display: flex; flex-direction: column; gap: 3px; }

.nav-item {
  position: relative;
  display: flex; align-items: center; gap: 12px;
  margin-right: 14px; padding: 9px 14px;
  border-radius: 9px;
  color: #cde1d5; text-decoration: none; font-weight: 500; letter-spacing: 0.03em;
  transition: background-color 0.15s, color 0.15s;
}
.nav-item .icon { opacity: 0.8; }
.nav-item:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }

/* the current page is a tab joined to the content area */
.nav-item[aria-current="page"] {
  margin-right: 0;
  border-radius: 9px 0 0 9px;
  background: var(--paper);
  color: var(--green-900);
  font-weight: 700;
}
.nav-item[aria-current="page"] .icon { opacity: 1; color: var(--green-700); }
.nav-item[aria-current="page"]::before,
.nav-item[aria-current="page"]::after {
  content: ""; position: absolute; right: 0; width: 12px; height: 12px; pointer-events: none;
}
.nav-item[aria-current="page"]::before { top: -12px; background: radial-gradient(circle at 0 0, transparent 11.5px, var(--paper) 12px); }
.nav-item[aria-current="page"]::after { bottom: -12px; background: radial-gradient(circle at 0 100%, transparent 11.5px, var(--paper) 12px); }
.nav-item[aria-current="page"]:focus-visible { outline-color: var(--green-300); }

.rail-logout { grid-area: logout; margin-right: 14px; }
.logout-btn {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 9px 14px; border: 0; border-radius: 9px;
  background: transparent; color: #a9c5b5;
  font: inherit; font-weight: 500; cursor: pointer; text-align: left;
}
.logout-btn:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
.logout-btn:focus-visible { outline-color: var(--green-300); }

.main { width: 100%; max-width: 1120px; padding: 36px 44px 72px; }
.main:focus { outline: none; }

/* ---------- page header ---------- */

.page-head {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 14px 24px;
  margin-bottom: 28px; padding-bottom: 20px;
  border-bottom: 1px solid var(--line);
}
.page-title { font-size: 28px; line-height: 1.25; font-weight: 800; letter-spacing: 0.04em; }
.page-desc { margin-top: 6px; max-width: 62ch; color: var(--muted); }
.page-actions { display: flex; flex-wrap: wrap; gap: 10px; }

.section-title { margin: 36px 0 14px; font-size: 18px; font-weight: 700; letter-spacing: 0.03em; }

/* ---------- cards ---------- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
}
.card + .card, .card + .empty, .empty + .card { margin-top: 20px; }
.card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 15px 20px; border-bottom: 1px solid var(--line);
}
.card-title { font-size: 16px; font-weight: 700; letter-spacing: 0.02em; }
.card-desc { margin-top: 2px; font-size: 13.5px; color: var(--muted); }
.card-body { padding: 20px; }
.card-foot {
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px;
  padding: 14px 20px; border-top: 1px solid var(--line);
  background: var(--surface-2); border-radius: 0 0 var(--radius) var(--radius);
}

/* key–value summary */
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.facts > div { padding: 16px 20px; border-right: 1px solid var(--line); }
.facts > div:last-child { border-right: 0; }
.facts dt { font-size: 13px; color: var(--muted); }
.facts dd { margin-top: 2px; font-family: var(--mono); font-size: 22px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---------- badges & tags ---------- */

.badge {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 2px 10px 2px 9px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface-2); color: var(--ink-2);
  font-size: 12.5px; font-weight: 600; line-height: 20px; white-space: nowrap;
}
.badge::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--faint); flex: none; }
.badge-ok { background: var(--green-50); border-color: var(--green-100); color: var(--green-700); }
.badge-ok::before { background: var(--green-600); }
.badge-warn { background: var(--amber-50); border-color: var(--amber-100); color: var(--amber-ink); }
.badge-warn::before { background: var(--amber); }
.badge-err { background: var(--red-50); border-color: var(--red-100); color: var(--red-700); }
.badge-err::before { background: var(--red); }
.badge-info { background: var(--blue-50); border-color: var(--blue-100); color: var(--blue); }
.badge-info::before { background: var(--blue); }
.badge-idle { color: var(--muted); }
.badge-live::before { animation: pulse 1.6s ease-in-out infinite; }

.tag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 0 8px; border-radius: 5px;
  background: var(--sunken); color: var(--ink-2);
  font-size: 12px; font-weight: 600; line-height: 22px; white-space: nowrap;
}
.tag .icon { width: 13px; height: 13px; }
.tag-set { background: var(--green-50); color: var(--green-700); }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px; padding: 0 16px;
  border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: 14.5px; font-weight: 600; letter-spacing: 0.03em; line-height: 1.2;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.btn:hover { background: var(--green-50); border-color: var(--green-200); color: var(--ink); }
.btn:active { transform: translateY(1px); }
.btn .icon { width: 17px; height: 17px; }

.btn-primary {
  background: var(--green-700); border-color: var(--green-700); color: #fff;
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.16);
}
.btn-primary:hover { background: var(--green-600); border-color: var(--green-600); color: #fff; }

.btn-danger { color: var(--red-700); border-color: var(--red-100); }
.btn-danger:hover { background: var(--red-50); border-color: var(--red); color: var(--red-700); }
.btn-danger-solid { background: var(--red); border-color: var(--red); color: #fff; box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.16); }
.btn-danger-solid:hover { background: var(--red-700); border-color: var(--red-700); color: #fff; }

.btn-ghost { background: transparent; border-color: transparent; color: var(--ink-2); }
.btn-ghost:hover { background: var(--sunken); border-color: transparent; }

.btn-sm { min-height: 32px; padding: 0 12px; font-size: 13.5px; gap: 6px; }
.btn-sm .icon { width: 15px; height: 15px; }
.btn-lg { min-height: 48px; padding: 0 22px; font-size: 16px; }
.btn-block { width: 100%; }

.btn[disabled] { opacity: 0.55; cursor: not-allowed; }
.btn[aria-busy="true"] { cursor: progress; opacity: 0.85; }
.btn[aria-busy="true"]::before {
  content: ""; width: 15px; height: 15px; flex: none;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

.icon-btn {
  display: inline-grid; place-items: center; width: 34px; height: 34px; flex: none;
  padding: 0; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--muted); cursor: pointer;
}
.icon-btn:hover { background: var(--sunken); color: var(--ink); }

.is-copied { border-color: var(--green-600); color: var(--green-700); }

/* ---------- forms ---------- */

.form { display: grid; gap: 18px; }
.field { display: grid; gap: 6px; align-content: start; min-width: 0; }
.label { font-size: 14px; font-weight: 700; letter-spacing: 0.02em; color: var(--ink); }
.label .opt { margin-left: 6px; font-size: 12.5px; font-weight: 400; color: var(--muted); }
.label-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }

.input, .select, .textarea {
  width: 100%; min-height: 42px; padding: 9px 12px;
  border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  background: #fff; color: var(--ink);
  font: inherit; font-size: 16px; line-height: 1.4;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.input::placeholder, .textarea::placeholder { color: var(--faint); }
.input:hover, .select:hover, .textarea:hover { border-color: #a6b3a8; }
.input:focus, .select:focus, .textarea:focus { outline: none; border-color: var(--green-600); box-shadow: var(--ring); }
.input[aria-invalid="true"], .select[aria-invalid="true"], .textarea[aria-invalid="true"] { border-color: var(--red); background: #fffbfa; }
.input[aria-invalid="true"]:focus, .select[aria-invalid="true"]:focus, .textarea[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px rgba(200, 51, 43, 0.15); }
.input[readonly] { background: var(--surface-2); color: var(--ink-2); }
.input-mono { font-family: var(--mono); font-size: 15px; }
.textarea { min-height: 120px; resize: vertical; line-height: 1.55; }
.select {
  appearance: none; padding-right: 38px;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235b6861' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 12px center / 16px;
}

input[type="checkbox"], input[type="radio"] { width: 18px; height: 18px; margin: 0; accent-color: var(--green-700); flex: none; }
.check { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
.check input { margin-top: 3px; }

.field-error { display: flex; align-items: flex-start; gap: 6px; font-size: 13.5px; font-weight: 600; color: var(--red-700); }
.field-error .icon { width: 16px; height: 16px; margin-top: 2.5px; }

.fieldset { min-width: 0; margin: 0; padding: 0; border: 0; }
.fieldset > legend { padding: 0; margin-bottom: 8px; font-size: 14px; font-weight: 700; }
.form-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; }

/* write-only secrets: show/hide what was typed */
.secret { position: relative; }
.secret .input { padding-right: 48px; }
.secret-toggle {
  position: absolute; top: 50%; right: 4px; transform: translateY(-50%);
  display: grid; place-items: center; width: 38px; height: 34px;
  border: 0; border-radius: 6px; background: transparent; color: var(--faint); cursor: pointer;
}
.secret-toggle:hover { color: var(--ink-2); background: var(--sunken); }
.secret-toggle[aria-pressed="true"] { color: var(--green-700); }

/* ---------- the signature: postcode boxes ---------- */

/* One real <input>; the six boxes are its background, aligned to the monospace
   advance (1ch + letter-spacing), so typing, pasting and autofill all just work. */
.otp-input {
  --cell: 2.75ch;
  --box: calc(var(--cell) - 0.6ch);
  --bw: 1.5px;
  --edge: var(--ink-2);
  --fill: #fff;
  display: block;
  width: calc(var(--cell) * 6 + (var(--box) - 1ch) / 2 + 2px);
  height: 50px;
  padding: 0 0 0 calc((var(--box) - 1ch) / 2);
  border: 0; border-radius: 3px;
  font-family: var(--mono); font-size: 26px; font-weight: 600; font-variant-numeric: tabular-nums;
  letter-spacing: calc(var(--cell) - 1ch);
  color: var(--ink); caret-color: var(--red);
  background:
    repeating-linear-gradient(90deg, var(--edge) 0 var(--box), transparent var(--box) var(--cell)) 0 0 / calc(var(--cell) * 6) var(--bw) no-repeat,
    repeating-linear-gradient(90deg, var(--edge) 0 var(--box), transparent var(--box) var(--cell)) 0 100% / calc(var(--cell) * 6) var(--bw) no-repeat,
    repeating-linear-gradient(90deg, var(--edge) 0 var(--bw), var(--fill) var(--bw) calc(var(--box) - var(--bw)), var(--edge) calc(var(--box) - var(--bw)) var(--box), transparent var(--box) var(--cell)) 0 0 / calc(var(--cell) * 6) 100% no-repeat;
  -webkit-appearance: none; appearance: none;
}
/* focus: the boxes themselves turn green and thicker instead of a ring around the field */
.otp-input:focus { outline: none; --edge: var(--green-600); --bw: 2.5px; --fill: var(--green-50); }
.otp-input[aria-invalid="true"] { --edge: var(--red); --fill: var(--red-50); animation: shake 0.4s var(--ease); }
.otp-input[aria-invalid="true"]:focus { --edge: var(--red); }

/* read-only code / number in boxes */
.postcode { display: inline-flex; gap: 6px; font-family: var(--mono); font-weight: 600; font-size: 22px; }
.postcode span {
  display: grid; place-items: center; width: 1.55em; height: 1.9em;
  border: 1.5px solid var(--red); background: #fff; color: var(--ink);
}

/* ---------- tables ---------- */

.table-wrap { overflow-x: auto; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-1); }
.card .table-wrap { border: 0; border-radius: 0 0 var(--radius) var(--radius); box-shadow: none; }
.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th {
  padding: 10px 16px; text-align: left; white-space: nowrap;
  font-size: 12.5px; font-weight: 700; letter-spacing: 0.06em; color: var(--muted);
  background: var(--surface-2); border-bottom: 1px solid var(--line);
}
.table td { padding: 12px 16px; vertical-align: top; border-bottom: 1px solid var(--line); }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: #fafcf9; }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table .actions { text-align: right; white-space: nowrap; }

/* ---------- empty state ---------- */

.empty {
  padding: 44px 24px; text-align: center;
  border: 1.5px dashed var(--line-2); border-radius: var(--radius);
  background: var(--surface-2);
}
.empty-icon {
  display: inline-grid; place-items: center; width: 52px; height: 52px; margin-bottom: 14px;
  border-radius: 50%; background: var(--green-50); color: var(--green-700);
}
.empty-icon .icon { width: 24px; height: 24px; }
.empty-title { font-size: 18px; font-weight: 700; letter-spacing: 0.03em; }
.empty-text { max-width: 46ch; margin: 6px auto 20px; color: var(--muted); }
.empty-steps {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 28px;
  margin: 0 auto 24px; padding: 0; list-style: none; counter-reset: es;
}
.empty-steps li { display: flex; align-items: center; gap: 8px; counter-increment: es; font-weight: 600; }
.empty-steps li::before {
  content: counter(es); display: grid; place-items: center; width: 24px; height: 24px;
  border-radius: 50%; background: var(--green-700); color: #fff;
  font-family: var(--mono); font-size: 12.5px;
}

/* ---------- callouts, flash, toast ---------- */

.callout {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px; margin-bottom: 18px;
  border: 1px solid; border-radius: var(--radius-sm);
  font-size: 14px; line-height: 1.6;
}
.callout .icon { margin-top: 2px; }
.callout p { margin: 0; }
.callout-error { background: var(--red-50); border-color: var(--red-100); color: var(--red-700); font-weight: 600; }
.callout-warn { background: var(--amber-50); border-color: var(--amber-100); color: var(--amber-ink); }
.callout-info { background: var(--blue-50); border-color: var(--blue-100); color: #174f7c; }
.callout-ok { background: var(--green-50); border-color: var(--green-100); color: var(--green-700); }

.flash {
  display: flex; align-items: flex-start; gap: 12px;
  margin-bottom: 24px; padding: 12px 10px 12px 16px;
  background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--blue);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-1);
  animation: drop-in 0.35s var(--ease);
  transition: opacity 0.3s, transform 0.3s;
}
.flash-icon { display: grid; place-items: center; height: 24px; color: var(--blue); }
.flash-text { flex: 1; margin-top: 1px; font-weight: 600; }
.flash-close { width: 28px; height: 28px; margin: -2px 0; }
.flash-close .icon { width: 16px; height: 16px; }
.flash-success { border-left-color: var(--green-600); }
.flash-success .flash-icon { color: var(--green-600); }
.flash-error { border-left-color: var(--red); background: #fffbfa; }
.flash-error .flash-icon, .flash-error .flash-text { color: var(--red-700); }
.flash.is-leaving { opacity: 0; transform: translateY(-6px); }

.toasts {
  position: fixed; right: 20px; bottom: 20px; z-index: 100;
  display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
  pointer-events: none;
}
/* shown as a popover so toasts stay above an open modal dialog */
.toasts[popover] { inset: auto 20px 20px auto; width: auto; height: auto; margin: 0; padding: 0; border: 0; background: transparent; overflow: visible; }
.toast {
  display: flex; align-items: center; gap: 10px;
  max-width: min(420px, calc(100vw - 32px)); padding: 11px 16px;
  border-radius: 9px; background: var(--green-950); color: #fff;
  box-shadow: var(--shadow-2); font-size: 14px; font-weight: 600;
  pointer-events: auto;
  animation: rise-in 0.25s var(--ease);
  transition: opacity 0.25s, transform 0.25s;
}
.toast .icon { color: var(--green-300); }
.toast-error { background: var(--red-700); }
.toast-error .icon { color: #ffd2cd; }
.toast.is-leaving { opacity: 0; transform: translateY(6px); }

/* ---------- modal ---------- */

dialog.modal {
  width: min(520px, calc(100vw - 24px)); max-height: calc(100vh - 48px);
  padding: 0; border: 0; border-radius: 14px;
  background: var(--surface); color: var(--ink); box-shadow: var(--shadow-2);
}
dialog.modal[open] { display: flex; flex-direction: column; animation: pop-in 0.2s var(--ease); }
dialog.modal::backdrop { background: rgba(8, 41, 30, 0.5); }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 18px 16px 4px 22px; }
.modal-title { padding-top: 3px; font-size: 18px; font-weight: 700; letter-spacing: 0.02em; }
.modal-body { padding: 10px 22px 22px; overflow: auto; }
.modal-foot {
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px;
  padding: 14px 22px; border-top: 1px solid var(--line); background: var(--surface-2);
}
.modal-confirm { width: min(420px, calc(100vw - 24px)); }
.modal-confirm .modal-body { padding-top: 4px; color: var(--ink-2); white-space: pre-line; }

/* ---------- centred pages (login, TOTP, errors) ---------- */

.bare-body {
  min-height: 100vh;
  background:
    radial-gradient(900px 520px at 50% -12%, rgba(255, 255, 255, 0.08), transparent 70%),
    var(--green-900);
}
.bare {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 22px;
  min-height: 100vh; padding: 40px 16px 48px;
}
.bare > .flash { width: min(440px, 100%); margin: 0; }
.brand-bare .brand-name small { opacity: 0.55; }

.auth-card {
  width: min(440px, 100%); padding: 32px 32px 30px;
  background: var(--surface); border-radius: 16px;
  box-shadow: 0 30px 70px -24px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.12);
  animation: rise-in 0.4s var(--ease);
}
.auth-card-wide { width: min(720px, 100%); }
.auth-head { margin-bottom: 24px; }
.auth-title { font-size: 24px; line-height: 1.3; font-weight: 800; letter-spacing: 0.05em; }
.auth-sub { margin-top: 8px; color: var(--muted); }
.auth-actions { display: flex; justify-content: center; gap: 10px; margin-top: 24px; }
.auth-foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px;
  margin: 28px -32px -30px; padding: 12px 20px 12px 32px;
  border-top: 1px solid var(--line); background: var(--surface-2); border-radius: 0 0 16px 16px;
}
.bare-note { max-width: 440px; text-align: center; font-size: 13.5px; color: rgba(255, 255, 255, 0.7); }
.bare-note code { background: rgba(255, 255, 255, 0.12); color: #fff; }

.error-card { text-align: center; }
.error-card .postcode { margin-bottom: 18px; }

/* numbered setup steps (a real sequence) */
.steps { margin: 0; padding: 0; list-style: none; counter-reset: step; }
.step { position: relative; padding: 0 0 28px 50px; counter-increment: step; }
.step::before {
  content: counter(step);
  position: absolute; left: 0; top: -2px;
  display: grid; place-items: center; width: 32px; height: 32px;
  border-radius: 50%; border: 1.5px solid var(--green-200); background: var(--green-50);
  color: var(--green-700); font-family: var(--mono); font-weight: 700;
}
.step::after { content: ""; position: absolute; left: 15.5px; top: 36px; bottom: 6px; width: 1.5px; background: var(--line); }
.step:last-child { padding-bottom: 0; }
.step:last-child::after { display: none; }
.step-title { margin-bottom: 4px; font-size: 16px; font-weight: 700; letter-spacing: 0.02em; }
.step-text { color: var(--ink-2); }

.scan { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 22px; margin-top: 14px; }
.qr {
  width: 200px; height: 200px; flex: none;
  padding: 6px; border: 1px solid var(--line); border-radius: 10px; background: #fff;
  image-rendering: pixelated;
}
.manual { flex: 1; min-width: 220px; }
.key { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 12px; font-family: var(--mono); font-size: 15px; font-weight: 600; }
.key span { padding: 3px 8px; border-radius: 5px; background: var(--sunken); letter-spacing: 0.08em; }

.otp-form { margin-top: 12px; }
.otp-row { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 22px; margin-bottom: 8px; }

/* ---------- settings page ---------- */

.back-link {
  display: inline-flex; align-items: center; gap: 6px; margin-bottom: 8px;
  font-size: 13.5px; font-weight: 600; text-decoration: none; color: var(--muted);
}
.back-link:hover { color: var(--green-700); }
.back-link .icon { width: 16px; height: 16px; }

.btn .tag { margin-left: 2px; font-family: var(--mono); font-weight: 600; }

/* label + explanation on the left, a compact control on the right */
.setting-row {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(180px, 220px); gap: 8px 32px; align-items: start;
  padding: 16px 20px; border-bottom: 1px solid var(--line);
}
.setting-text .hint { margin-top: 2px; max-width: 54ch; }
.setting-control { display: grid; gap: 4px; }
.setting-default { font-size: 12.5px; color: var(--faint); }
.setting-note {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 12px 20px; border-bottom: 1px solid var(--line);
  background: var(--surface-2); font-size: 13px; color: var(--muted);
}
.setting-note .icon { width: 16px; height: 16px; margin-top: 3px; }
.card-section { padding: 20px; }
.foot-note { margin-right: auto; align-self: center; font-size: 13px; color: var(--muted); }

/* segmented radio group */
.segmented {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 3px; padding: 3px;
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: var(--sunken);
}
.segment { position: relative; cursor: pointer; }
.segment input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.segment-label {
  display: flex; flex-direction: column; align-items: center;
  padding: 5px 4px; border-radius: 5px;
  font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--ink-2);
  transition: background-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.segment-label small { font-size: 11px; font-weight: 500; color: var(--faint); }
.segment:hover .segment-label { color: var(--ink); }
.segment input:checked + .segment-label { background: #fff; color: var(--green-800); box-shadow: var(--shadow-1), inset 0 0 0 1px var(--green-200); }
.segment input:checked + .segment-label small { color: var(--green-600); }
.segment input:focus-visible + .segment-label { outline: 2.5px solid var(--green-600); outline-offset: 1px; }
.segment-hints { margin: 8px 0 0; padding: 0; list-style: none; font-size: 13px; color: var(--muted); }
.segment-hints li { display: none; }
.fieldset:has(input[value="debug"]:checked) [data-for="debug"],
.fieldset:has(input[value="info"]:checked) [data-for="info"],
.fieldset:has(input[value="warn"]:checked) [data-for="warn"],
.fieldset:has(input[value="error"]:checked) [data-for="error"] { display: block; }

/* two cards side by side, equal height, footers aligned */
.grid-cards { align-items: stretch; }
.grid-cards > .card { display: flex; flex-direction: column; margin-top: 0; }
.grid-cards > .card > .card-body { flex: 1; align-content: start; }
.card-icon {
  display: grid; place-items: center; width: 34px; height: 34px; flex: none;
  border-radius: 50%; background: var(--green-50); color: var(--green-700);
}

/* a smaller row of code boxes for forms with other fields */
.otp-sm { font-size: 22px; height: 44px; }

.mini-steps { margin: 0; padding: 0; list-style: none; counter-reset: ms; display: grid; gap: 6px; }
.mini-steps li { position: relative; padding-left: 28px; counter-increment: ms; font-size: 14px; color: var(--ink-2); }
.mini-steps li::before {
  content: counter(ms); position: absolute; left: 0; top: 2px;
  display: grid; place-items: center; width: 20px; height: 20px;
  border-radius: 50%; background: var(--green-50); color: var(--green-700);
  font-family: var(--mono); font-size: 11.5px; font-weight: 700;
}

/* the detected IP, cancelled with a postmark */
.ip-card {
  display: grid; grid-template-columns: 172px minmax(0, 1fr); gap: 12px 28px; align-items: center;
  padding: 24px 24px 22px;
}
.ip-stamp { display: grid; place-items: center; }
.postmark {
  width: 160px; height: 160px; overflow: visible;
  color: var(--green-800); opacity: 0.82; transform: rotate(-9deg);
  animation: stamp 0.45s 0.15s var(--ease) backwards;
}
.pm-ring { fill: none; stroke: currentColor; stroke-width: 2.6; }
.pm-thin { stroke-width: 1.1; }
.pm-band { fill: none; stroke: currentColor; stroke-width: 1.4; }
.pm-arc { fill: currentColor; font-family: var(--font); font-size: 14px; font-weight: 700; letter-spacing: 0.32em; text-anchor: middle; }
.pm-mid { fill: currentColor; font-family: var(--font); font-size: 19px; font-weight: 800; letter-spacing: 0.3em; text-anchor: middle; }
.ip-label { font-size: 13.5px; font-weight: 600; color: var(--muted); }
.ip-value { margin: 2px 0 6px; font-size: 30px; font-weight: 700; line-height: 1.2; letter-spacing: 0.01em; overflow-wrap: anywhere; color: var(--ink); }
.ip-facts { display: grid; gap: 0; margin-top: 14px; border-top: 1px solid var(--line); }
.ip-facts > div { display: grid; grid-template-columns: 9.5em minmax(0, 1fr); gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.ip-facts dt { color: var(--muted); }
.ip-facts dd { overflow-wrap: anywhere; }
.ip-card .callout { margin: 14px 0 0; }

/* Microsoft application: fields beside the Azure registration steps */
.ms-app-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr); gap: 20px 28px; align-items: start; }
.ms-uses { margin-top: 0; }
.ms-uses > div { grid-template-columns: 10.5em minmax(0, 1fr); }
.ms-uses dd { display: flex; flex-wrap: wrap; align-items: flex-start; align-content: flex-start; gap: 6px; }
.ms-box {
  display: inline-block; padding: 1px 8px; border-radius: 999px;
  background: var(--sunken); color: var(--ink-2); font-size: 13px;
}
.ms-guide {
  padding: 14px 16px; border-radius: var(--radius-sm);
  background: var(--blue-50); color: #174f7c; font-size: 14px;
}
.ms-guide-title { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; list-style: none; cursor: pointer; }
.ms-guide-title::-webkit-details-marker { display: none; }
.ms-guide-title .icon { width: 17px; height: 17px; flex: none; }
.ms-guide-title:focus-visible { outline: 2.5px solid var(--green-600); outline-offset: 3px; border-radius: 4px; }
.ms-guide[open] > .ms-guide-title { margin-bottom: 10px; }
.ms-guide-chevron {
  width: 8px; height: 8px; margin-left: auto; margin-right: 4px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); transition: transform 0.2s var(--ease);
}
.ms-guide[open] .ms-guide-chevron { transform: rotate(-135deg); }
.ms-guide .mini-steps li { color: #174f7c; font-size: 13.5px; }
.ms-guide .mini-steps li::before { background: #fff; color: var(--blue); }
@media (max-width: 860px) {
  .ms-app-body { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- version history ---------- */

.ledger {
  margin: 0; padding: 0; list-style: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-1);
}
.ledger-item {
  display: grid; grid-template-columns: 4.5em minmax(0, 1fr) auto; gap: 4px 18px; align-items: center;
  padding: 14px 20px; border-bottom: 1px solid var(--line);
}
.ledger-item:last-child { border-bottom: 0; }
.ledger-item:hover { background: #fafcf9; }
.ledger-no { font-size: 14px; font-weight: 700; color: var(--muted); font-variant-numeric: tabular-nums; }
/* the version in force wears the postcode box */
.is-current { background: var(--green-50); border-radius: var(--radius) var(--radius) 0 0; }
.is-current:hover { background: var(--green-50); }
.is-current .ledger-no { justify-self: start; padding: 1px 6px; border: 1.5px solid var(--green-700); background: #fff; color: var(--green-800); }
.ledger-summary { font-weight: 600; overflow-wrap: anywhere; }
.ledger-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 12px; margin-top: 2px; font-size: 13px; color: var(--muted); }
.ledger-ago { color: var(--faint); }
.ledger-ip { font-size: 12.5px; }
.ledger-action { display: flex; justify-content: flex-end; }
.tag-src-restore { background: var(--blue-50); color: var(--blue); }
.tag-src-import, .tag-src-bootstrap { background: var(--amber-50); color: var(--amber-ink); }

/* ---------- telegram page ---------- */

/* a section title with its action on the right */
.section-head {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 10px 20px;
  margin: 36px 0 14px;
}
.page-head + section > .section-head { margin-top: 0; }
.section-head .section-title { margin: 0; }
.section-desc { margin-top: 2px; font-size: 13.5px; color: var(--muted); }

.tg-list {
  margin: 0; padding: 0; list-style: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-1);
}
.tg-item {
  display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) auto; gap: 6px 22px; align-items: center;
  padding: 14px 20px; border-bottom: 1px solid var(--line);
}
.tg-item:last-child { border-bottom: 0; }
.tg-item:hover { background: #fafcf9; }
.tg-bot { grid-template-columns: 38px minmax(0, 1.2fr) minmax(0, 1fr) auto; }
.tg-avatar {
  display: grid; place-items: center; width: 38px; height: 38px;
  border-radius: 50%; background: var(--green-50); color: var(--green-700);
}
.tg-main { min-width: 0; }
.tg-name { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 15.5px; font-weight: 700; overflow-wrap: anywhere; }
.tg-handle { margin-top: 1px; font-size: 13.5px; color: var(--muted); overflow-wrap: anywhere; }
.tg-handle.is-ok { color: var(--green-700); font-weight: 600; }
.tg-handle.is-err { color: var(--red-700); font-weight: 600; }
.tg-handle .icon { display: inline-block; width: 15px; height: 15px; margin-right: 4px; vertical-align: -2.5px; }
.tg-uses { font-size: 13.5px; color: var(--ink-2); overflow-wrap: anywhere; }
.tg-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px; }
.tg-actions form { display: contents; }

/* bot → chat: the routing line of an address label; the chat id sits in a box like a postcode */
.route { display: flex; align-items: center; gap: 0; margin-top: 6px; font-size: 13.5px; }
.route-bot {
  padding: 0 8px; border-radius: 999px; line-height: 22px;
  background: var(--green-50); color: var(--green-800); font-weight: 600;
}
.route-line {
  position: relative; width: 34px; height: 0; margin: 0 8px 0 6px; flex: none;
  border-top: 1.5px dashed var(--line-2);
}
.route-line::after {
  content: ""; position: absolute; right: -3px; top: -4.75px;
  width: 7px; height: 7px; border-top: 1.5px solid var(--faint); border-right: 1.5px solid var(--faint);
  transform: rotate(45deg);
}
.route-chat {
  padding: 0 7px; line-height: 21px; font-weight: 600; font-variant-numeric: tabular-nums;
  border: 1.5px solid var(--green-700); background: #fff; color: var(--ink);
}

/* forms in dialogs: the form is the dialog's column */
.modal-form { width: min(560px, calc(100vw - 24px)); }
.modal-form > form { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.modal-form .modal-body { padding-top: 14px; }
.modal-form .modal-body .callout { margin-bottom: 0; }
.modal-title .mono { font-size: 0.92em; }
.modal-sub { margin-top: 2px; font-size: 13.5px; color: var(--muted); }

.token-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: start; }
.token-row > .btn { min-height: 42px; }
.getme-out { min-height: 0; font-size: 13.5px; color: var(--muted); }
.getme-out:empty { display: none; }
.getme-out.is-ok { color: var(--green-700); font-weight: 600; }
.getme-out.is-err { color: var(--red-700); font-weight: 600; }
.result-note { margin-left: 6px; font-weight: 400; color: var(--muted); }
.getme-out .icon { display: inline-block; width: 15px; height: 15px; margin-right: 5px; vertical-align: -2.5px; }

/* chat picker */
.modal-chats { width: min(540px, calc(100vw - 24px)); }
.modal-chats .modal-body { padding: 8px 0 0; }
.chats-hint {
  display: flex; align-items: flex-start; gap: 8px; margin: 0 22px 12px;
  padding: 10px 12px; border-radius: var(--radius-sm);
  background: var(--blue-50); color: #174f7c; font-size: 13.5px;
}
.chats-hint .icon { width: 16px; height: 16px; margin-top: 3px; }
.chats { border-top: 1px solid var(--line); min-height: 132px; }
.chat-row {
  display: grid; grid-template-columns: 38px minmax(0, 1fr) auto; gap: 12px; align-items: center;
  width: 100%; padding: 11px 22px; border: 0; border-bottom: 1px solid var(--line);
  background: transparent; color: var(--ink); font: inherit; text-align: left; cursor: pointer;
  transition: background-color 0.12s;
}
.chat-row:hover { background: var(--green-50); }
.chat-row:focus-visible { outline-offset: -3px; }
.chat-row:last-child { border-bottom: 0; }
.chat-icon { display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%; background: var(--green-50); color: var(--green-700); }
.chat-group .chat-icon { background: var(--blue-50); color: var(--blue); }
.chat-channel .chat-icon { background: var(--amber-50); color: var(--amber-ink); }
.chat-text { min-width: 0; }
.chat-title { display: block; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-meta { display: block; font-size: 12.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-id { display: flex; align-items: center; gap: 8px; font-family: var(--mono); font-size: 13.5px; font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.chat-pick { font-family: var(--font); font-size: 12.5px; font-weight: 700; color: var(--green-700); opacity: 0; transition: opacity 0.12s; }
.chat-row:hover .chat-pick, .chat-row:focus-visible .chat-pick { opacity: 1; }
.chats-state { display: grid; justify-items: center; gap: 6px; padding: 30px 22px; text-align: center; color: var(--muted); }
.chats-state .icon { width: 26px; height: 26px; color: var(--faint); }
.chats-state strong { color: var(--ink); }
.chats-state.is-err strong { color: var(--red-700); }
.chats-state.is-err .icon { color: var(--red); }
.spinner { width: 22px; height: 22px; border: 2.5px solid var(--green-200); border-right-color: var(--green-700); border-radius: 50%; animation: spin 0.7s linear infinite; }

/* ---------- mailboxes ---------- */

/* list: one address label per mailbox — engraved initial, account, folders with their
   live status, and the routing line to the targets */
.mb-list {
  margin: 0; padding: 0; list-style: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-1);
}
.mb-item {
  display: grid; grid-template-columns: 44px minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 0.8fr) auto; gap: 8px 20px; align-items: center;
  padding: 16px 20px; border-bottom: 1px solid var(--line);
}
.mb-item:last-child { border-bottom: 0; }
.mb-item:hover { background: #fafcf9; }
.mb-glyph {
  display: grid; place-items: center; width: 44px; height: 50px;
  border: 1.5px solid var(--green-700); outline: 3px solid var(--green-50); outline-offset: -6px;
  background: #fff; color: var(--green-800);
  font-family: var(--engrave); font-size: 24px; font-weight: 700; line-height: 1;
}
.mb-main { min-width: 0; }
.mb-title { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 16px; font-weight: 700; }
.mb-link { color: var(--ink); text-decoration: none; overflow-wrap: anywhere; }
.mb-link:hover { color: var(--green-700); text-decoration: underline; }
.mb-account { margin-top: 1px; font-size: 13.5px; color: var(--ink-2); overflow-wrap: anywhere; }
.mb-host { color: var(--muted); }
.mb-folders { display: grid; gap: 5px; margin: 0; padding: 0; list-style: none; min-width: 0; }
.mb-folder { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 13.5px; }
.mb-folder-name { overflow-wrap: anywhere; color: var(--ink-2); }
.mb-folder .badge { font-size: 12px; line-height: 18px; }
.mb-route { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 13.5px; }
.mb-route .route-line { margin: 0 4px 0 0; width: 22px; }
.mb-actions { display: flex; justify-content: flex-end; }
.mb-after { margin-top: 18px; }
.empty-steps li.is-done::before { content: "✓"; background: var(--green-100); color: var(--green-800); }

/* the form: one column of cards, the save bar stays at the bottom of the viewport */
.mb-form { max-width: 860px; }
.mb-form > .card + .card { margin-top: 18px; }
.mb-form .card-head .btn { flex: none; }
.grid-host { display: grid; grid-template-columns: minmax(0, 1fr) 7.5em; gap: 18px 20px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px 20px; }
.fixed-value {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  min-height: 42px; padding: 9px 12px; border: 1px dashed var(--line-2); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--ink-2); font-size: 15px;
}
.fixed-value .icon { width: 15px; height: 15px; color: var(--faint); }

/* service cards are postage stamps: a perforated edge (a mask punches the holes), an
   engraved initial and the port as the denomination; the chosen one is postmarked */
.stamps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.stamp-pick { position: relative; display: block; cursor: pointer; filter: drop-shadow(0 1px 1.5px rgba(13, 61, 44, 0.16)); }
.stamp-pick input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; z-index: 1; }
.stamp {
  --hole: 3.5px; --pitch: 11px;
  display: block; padding: 8px;
  background: var(--sunken);
  -webkit-mask:
    linear-gradient(#000 0 0) var(--hole) var(--hole) / calc(100% - 2 * var(--hole)) calc(100% - 2 * var(--hole)) no-repeat,
    radial-gradient(circle at center, transparent var(--hole), #000 calc(var(--hole) + 0.5px)) calc(var(--pitch) / -2) calc(var(--pitch) / -2) / var(--pitch) var(--pitch) round;
  mask:
    linear-gradient(#000 0 0) var(--hole) var(--hole) / calc(100% - 2 * var(--hole)) calc(100% - 2 * var(--hole)) no-repeat,
    radial-gradient(circle at center, transparent var(--hole), #000 calc(var(--hole) + 0.5px)) calc(var(--pitch) / -2) calc(var(--pitch) / -2) / var(--pitch) var(--pitch) round;
  transition: transform 0.18s var(--ease);
}
.stamp-face {
  position: relative; display: grid; grid-template-rows: auto 1fr auto; min-height: 128px;
  padding: 8px 10px 9px; border: 1.5px solid var(--line-2); background: #fff;
  transition: background-color 0.15s, border-color 0.15s;
}
.stamp-top { display: flex; align-items: baseline; justify-content: space-between; gap: 6px; }
.stamp-label { font-size: 14.5px; font-weight: 700; letter-spacing: 0.03em; color: var(--ink); }
.stamp-value { font-size: 12px; font-weight: 600; color: var(--muted); }
.stamp-glyph {
  display: grid; place-items: center; padding: 2px 0;
  font-family: var(--engrave); font-size: 46px; font-weight: 700; line-height: 1; color: var(--ink-2);
}
.stamp-note { font-size: 12px; color: var(--muted); text-align: center; letter-spacing: 0.02em; }
.stamp-pick:hover .stamp { transform: translateY(-2px); }
.stamp-pick:hover .stamp-face { border-color: var(--green-300); }
.stamp-pick input:focus-visible + .stamp { outline: 2.5px solid var(--green-600); outline-offset: 3px; }
.stamp-pick input:checked + .stamp { background: var(--green-100); }
.stamp-pick input:checked + .stamp .stamp-face { border-color: var(--green-700); background: #fff; }
.stamp-pick input:checked + .stamp .stamp-glyph { color: var(--green-800); }
.stamp-pick input:checked + .stamp .stamp-value { color: var(--green-700); }
/* the postmark: two rings and wavy cancel lines over the corner */
.stamp-pick input:checked + .stamp .stamp-face::after {
  content: ""; position: absolute; right: 4px; bottom: 16px; width: 50px; height: 50px;
  border: 2px solid var(--green-700); border-radius: 50%;
  box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 4.5px var(--green-700);
  background:
    repeating-linear-gradient(0deg, transparent 0 6px, rgba(19, 98, 70, 0.55) 6px 7.5px) center / 100% 60% no-repeat;
  opacity: 0.8; transform: rotate(-14deg);
  animation: stamp 0.35s var(--ease) backwards;
  pointer-events: none;
}

.preset-hints { margin-top: 16px; }
.preset-hint {
  display: none; gap: 10px; padding: 12px 14px;
  border-radius: var(--radius-sm); background: var(--blue-50); color: #174f7c; font-size: 14px;
}
.preset-hint > .icon { margin-top: 3px; }
.preset-hint p + p, .preset-hint p + .mini-steps { margin-top: 6px; }
.preset-hint .mini-steps li { color: #174f7c; font-size: 13.5px; }
.preset-hint .mini-steps li::before { background: #fff; color: var(--blue); }
.mb-form:has(input[name="preset"][value="gmail"]:checked) [data-preset-hint="gmail"],
.mb-form:has(input[name="preset"][value="icloud"]:checked) [data-preset-hint="icloud"],
.mb-form:has(input[name="preset"][value="outlook"]:checked) [data-preset-hint="outlook"],
.mb-form:has(input[name="preset"][value="custom"]:checked) [data-preset-hint="custom"] { display: flex; }

/* authentication: only the chosen method's fields are shown */
.segmented-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.segmented-2 .segment-label { padding: 7px 6px; }
.auth-panel { display: grid; gap: 18px; }
.mb-form:has(#auth-password:checked) .auth-ms,
.mb-form:has(#auth-ms:checked) .auth-password { display: none; }
.oauth-state {
  display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; gap: 12px; align-items: center;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2);
}
.oauth-icon { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: var(--sunken); color: var(--muted); }
.oauth-icon.is-ok { background: var(--green-50); color: var(--green-700); }
.oauth-icon.is-warn { background: var(--amber-50); color: var(--amber-ink); }
.oauth-title { font-weight: 700; }
.oauth-icon.is-warn + .oauth-text .oauth-title { color: var(--amber-ink); }

/* filled in from a service card: a short green flash on the changed fields */
.input.is-filled { animation: filled 0.9s var(--ease); }
@keyframes filled { from { border-color: var(--green-600); background: var(--green-50); } }

/* connection test and folders */
.probe {
  display: flex; align-items: flex-start; gap: 10px; margin-bottom: 14px;
  padding: 11px 14px; border-radius: var(--radius-sm); background: var(--surface-2); border: 1px solid var(--line);
  font-size: 14px; color: var(--muted);
}
.probe-icon { display: grid; place-items: center; height: 22px; flex: none; }
.probe-icon .spinner { width: 17px; height: 17px; border-width: 2px; }
.probe-text { min-width: 0; overflow-wrap: anywhere; }
.probe-text b { color: var(--ink); }
.probe-time { margin-left: 6px; font-family: var(--mono); font-size: 12.5px; color: var(--faint); }
.probe.is-busy { color: var(--ink-2); }
.probe.is-ok { background: var(--green-50); border-color: var(--green-100); color: var(--green-800); }
.probe.is-err { background: var(--red-50); border-color: var(--red-100); color: var(--red-700); font-weight: 600; }

.folders { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.folders:empty::before { content: "未勾選任何資料夾：將監看 INBOX"; font-size: 13.5px; color: var(--muted); }
.folder {
  display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 5px 12px 5px 10px;
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: #fff; cursor: pointer;
  font-size: 14px; transition: background-color 0.15s, border-color 0.15s;
}
.folder input { width: 16px; height: 16px; }
.folder:hover { border-color: var(--green-300); }
.folder:has(input:checked) { border-color: var(--green-600); background: var(--green-50); }
.folder:has(input:focus-visible) { outline: 2.5px solid var(--green-600); outline-offset: 2px; }
.folder-name { overflow-wrap: anywhere; }
.folder-tag { padding: 0 6px; border-radius: 4px; background: var(--sunken); color: var(--muted); font-size: 11.5px; font-weight: 600; line-height: 18px; white-space: nowrap; }
.folder-tag.is-warn { background: var(--amber-50); color: var(--amber-ink); }
.folder.is-new { animation: rise-in 0.3s var(--ease); }
.folders.is-invalid .folder { border-color: var(--red); }
.folder-add { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; max-width: 520px; margin-top: 14px; }
.folder-add .btn { min-height: 42px; }
#f-folders-err:not(:empty), #f-targets-err:not(:empty) { margin-top: 10px; }

/* forwarding routes: one card per target, ticked like a checklist */
.routes { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.route-pick { position: relative; display: block; cursor: pointer; }
.route-pick input { position: absolute; top: 14px; left: 14px; opacity: 0; }
.route-card {
  position: relative; display: grid; gap: 2px; padding: 12px 44px 12px 14px;
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: #fff;
  transition: background-color 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.route-card .route { margin-top: 4px; }
.route-name { font-size: 15px; font-weight: 700; }
.route-check {
  position: absolute; top: 12px; right: 12px; display: grid; place-items: center; width: 22px; height: 22px;
  border: 1.5px solid var(--line-2); border-radius: 6px; background: #fff; color: transparent;
}
.route-check .icon { width: 15px; height: 15px; stroke-width: 2.6; }
.route-pick:hover .route-card { border-color: var(--green-300); }
.route-pick input:checked + .route-card { border-color: var(--green-600); background: var(--green-50); box-shadow: inset 0 0 0 1px var(--green-600); }
.route-pick input:checked + .route-card .route-check { border-color: var(--green-700); background: var(--green-700); color: #fff; }
.route-pick input:focus-visible + .route-card { outline: 2.5px solid var(--green-600); outline-offset: 2px; }
.route-pick input[aria-invalid="true"] + .route-card { border-color: var(--red); }

/* advanced settings: a card that opens */
.advanced > summary { list-style: none; cursor: pointer; border-bottom: 0; }
.advanced > summary::-webkit-details-marker { display: none; }
.advanced[open] > summary { border-bottom: 1px solid var(--line); }
.advanced > summary:hover .card-title { color: var(--green-700); }
.advanced .card-desc .tag { margin-left: 8px; }
.advanced-chevron {
  width: 10px; height: 10px; flex: none; margin-right: 6px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(45deg); transition: transform 0.2s var(--ease);
}
.advanced[open] .advanced-chevron { transform: rotate(-135deg); }

.save-bar {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; justify-content: flex-end; gap: 10px;
  margin-top: 18px; padding: 12px 0 calc(12px + env(safe-area-inset-bottom));
  background: linear-gradient(to bottom, rgba(242, 244, 239, 0), var(--paper) 14px);
}

.danger-zone { max-width: 860px; margin-top: 36px; border-color: var(--red-100); }
.danger-body { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 24px; padding: 16px 20px; }
.danger-body .card-title { color: var(--red-700); }

/* ---------- Microsoft authorisation dialog ----------
   The user code is the hero, in red postcode boxes; once the sign-in is done a postmark
   cancels it like a used stamp, and an expired code turns grey. The time left drains
   along a thin meter (scaled through --left, set from script). */
.modal-oauth { width: min(540px, calc(100vw - 24px)); }
.modal-oauth [hidden] { display: none !important; }
.modal-oauth .modal-body { padding-top: 6px; }
.modal-oauth .modal-foot { align-items: center; }
.modal-sub .mono { color: var(--ink-2); }

.oauth-loading { display: grid; justify-items: center; gap: 12px; padding: 36px 0 30px; color: var(--muted); }

.oauth-steps { display: grid; gap: 18px; margin: 4px 0 0; padding: 0; list-style: none; counter-reset: os; }
.oauth-step { position: relative; padding-left: 38px; counter-increment: os; }
.oauth-step::before {
  content: counter(os); position: absolute; left: 0; top: 0;
  display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  background: var(--green-700); color: #fff; font-family: var(--mono); font-size: 13px; font-weight: 700;
}
.oauth-step-title { min-height: 26px; padding-top: 1px; font-weight: 700; color: var(--ink); }
.oauth-step-hint { margin-top: 2px; font-size: 13.5px; color: var(--muted); overflow-wrap: anywhere; }
.oauth-step-hint .mono { color: var(--green-800); font-weight: 600; }
/* once finished, only the (cancelled or void) code remains of the steps */
.modal-oauth:not([data-state="pending"]) .oauth-step { padding-left: 0; }
.modal-oauth:not([data-state="pending"]) .oauth-step::before,
.modal-oauth:not([data-state="pending"]) .oauth-step-title,
.modal-oauth:not([data-state="pending"]) .oauth-step + .oauth-step { display: none; }

.oauth-ticket { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; margin-top: 10px; }
.oauth-code {
  display: block; padding: 6px; margin: -6px; border: 0; border-radius: var(--radius-sm);
  background: transparent; cursor: copy; font: inherit; color: inherit;
}
.oauth-code:hover .postcode span { background: var(--red-50); }
.postcode-lg { gap: 4px; font-size: clamp(19px, 5.6vw, 26px); font-weight: 700; letter-spacing: 0; }
.postcode-lg span { width: 1.3em; height: 1.7em; border-width: 2px; }
.postcode-lg .postcode-sep { width: 0.55em; border: 0; background: none; color: var(--faint); }
.oauth-code.is-copied .postcode span:not(.postcode-sep) { border-color: var(--green-600); }

/* the cancelling postmark (done) */
.oauth-postmark {
  position: absolute; left: clamp(120px, 42%, 200px); top: 50%; display: none;
  place-items: center; width: 92px; height: 92px; margin-top: -46px;
  border: 2.5px solid var(--green-700); border-radius: 50%;
  box-shadow: inset 0 0 0 4px rgba(255, 255, 255, 0.85), inset 0 0 0 6px var(--green-700);
  background:
    repeating-linear-gradient(0deg, transparent 0 7px, rgba(19, 98, 70, 0.5) 7px 9px) center / 100% 46% no-repeat,
    rgba(255, 255, 255, 0.55);
  color: var(--green-800); font-weight: 800; font-size: 15px; letter-spacing: 0.18em;
  transform: rotate(-14deg); pointer-events: none;
}
.oauth-postmark span { padding: 1px 4px 1px 7px; background: #fff; }
.modal-oauth[data-state="done"] .oauth-postmark { display: grid; animation: stamp 0.4s var(--ease) backwards; }
.modal-oauth[data-state="done"] .postcode-lg span,
.modal-oauth[data-state="error"] .postcode-lg span { border-color: var(--line-2); color: var(--faint); }
.modal-oauth[data-state="error"] .postcode-lg span:not(.postcode-sep) { border-style: dashed; background: var(--surface-2); }
.modal-oauth:not([data-state="pending"]) .oauth-code { cursor: default; pointer-events: none; }
.modal-oauth:not([data-state="pending"]) .oauth-copy,
.modal-oauth:not([data-state="pending"]) .oauth-link { display: none; }

.oauth-timer { display: flex; align-items: center; gap: 10px; max-width: 360px; margin-top: 12px; }
.oauth-meter { position: relative; flex: 1; height: 4px; border-radius: 2px; background: var(--sunken); overflow: hidden; }
.oauth-meter > span {
  position: absolute; inset: 0; border-radius: inherit; background: var(--green-600);
  transform: scaleX(var(--left, 1)); transform-origin: left; transition: transform 1s linear;
}
.oauth-left { font-family: var(--mono); font-size: 13px; font-variant-numeric: tabular-nums; color: var(--muted); white-space: nowrap; }
.oauth-timer.is-low .oauth-meter > span { background: var(--amber); }
.oauth-timer.is-low .oauth-left { color: var(--amber-ink); font-weight: 700; }
.modal-oauth:not([data-state="pending"]) .oauth-timer { display: none; }

.oauth-link { margin-top: 10px; }
.oauth-uri { margin-top: 6px; font-size: 12.5px; color: var(--faint); overflow-wrap: anywhere; }
.modal-oauth:not([data-state="pending"]) .oauth-uri { display: none; }

.oauth-status {
  display: flex; align-items: flex-start; gap: 10px; margin-top: 20px;
  padding: 11px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2); font-size: 14px; color: var(--ink-2);
}
.oauth-status-icon { display: grid; place-items: center; width: 18px; height: 22px; flex: none; }
.oauth-status-text { min-width: 0; overflow-wrap: anywhere; }
.oauth-status-text b { margin-right: 6px; color: var(--ink); }
.oauth-status-text b:empty { display: none; }
.oauth-status .pulse-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--blue); animation: pulse 1.6s ease-in-out infinite; }
.oauth-status.is-ok { background: var(--green-50); border-color: var(--green-100); color: var(--green-800); }
.oauth-status.is-ok b { color: var(--green-800); }
.oauth-status.is-warn { background: var(--amber-50); border-color: var(--amber-100); color: var(--amber-ink); }
.oauth-status.is-warn b { color: var(--amber-ink); }
.oauth-status.is-err { background: var(--red-50); border-color: var(--red-100); color: var(--red-700); }
.oauth-status.is-err b { color: var(--red-700); }
.modal-oauth[data-state="loading"] .oauth-status { display: none; }

.oauth-note { margin-right: auto; font-size: 13px; color: var(--muted); }
.btn-auth { color: var(--amber-ink); border-color: var(--amber-100); background: var(--amber-50); }
.btn-auth:hover { color: var(--amber-ink); border-color: var(--amber); background: #fbeccc; }
.mb-actions { gap: 8px; flex-wrap: wrap; }

/* the list's five columns need room: below that, folders and route go under the account */
@media (max-width: 1080px) {
  .mb-item { grid-template-columns: 44px minmax(0, 1fr) auto; gap: 10px 16px; }
  .mb-glyph { grid-row: span 3; align-self: start; }
  .mb-actions { grid-column: 3; grid-row: 1; align-self: start; }
  .mb-folders { grid-column: 2 / 4; display: flex; flex-wrap: wrap; gap: 6px 16px; }
  .mb-route { grid-column: 2 / 4; }
}

.callout p, .flash-text { white-space: pre-line; }

/* ---------- rules and templates ----------
   Rules are a sorting chain: each rule sits in a numbered slot (the number is its place in
   the order, drawn as an ink postcode box), the chain ends at the fixed built-in step, and
   a rule that discards mail wears a rubber 「略過」 stamp. The templates page shows the
   message as it lands in Telegram: chat wallpaper, white bubble, inline keys; while the
   preview is fetched the bot "正在輸入…". */

.subnav { display: flex; gap: 4px; margin: -8px 0 18px; border-bottom: 1px solid var(--line); }
.subnav-item {
  position: relative; padding: 6px 14px 10px; color: var(--muted); font-weight: 600; letter-spacing: 0.03em;
  text-decoration: none;
}
.subnav-item:hover { color: var(--ink); }
.subnav-item[aria-current="page"] { color: var(--green-900); }
.subnav-item[aria-current="page"]::after {
  content: ""; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 3px; border-radius: 3px 3px 0 0;
  background: var(--green-700);
}
.subnav + .page-head { margin-top: 4px; }

.rules-form, .tpl-form { max-width: 980px; }
.rules-form .card-head { flex-wrap: wrap; }
.rules-form .card-head > div:first-child { flex: 1 1 360px; }

.rule-guide { margin-bottom: 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); }
.rule-guide > summary {
  display: inline-flex; align-items: center; gap: 8px; padding: 9px 14px;
  font-size: 14px; font-weight: 600; color: var(--green-700); cursor: pointer; list-style: none;
}
.rule-guide > summary::-webkit-details-marker { display: none; }
.rule-guide > summary .icon { width: 16px; height: 16px; }
.rule-guide-list { display: grid; gap: 8px; margin: 0; padding: 0 14px 14px; font-size: 13.5px; }
.rule-guide-list > div { display: grid; grid-template-columns: 5.5em minmax(0, 1fr); gap: 12px; }
.rule-guide-list dt { font-weight: 700; color: var(--ink); }
.rule-guide-list dd { color: var(--ink-2); }

.rule-chain { display: grid; gap: 12px; margin: 0; padding: 0; list-style: none; counter-reset: rule; }
.rule {
  position: relative; counter-increment: rule;
  border: 1px solid var(--line-2); border-radius: var(--radius); background: #fff;
}
.rule.is-invalid { border-color: var(--red-100); box-shadow: inset 3px 0 0 var(--red); }
.rule.is-moved { animation: moved 0.9s var(--ease); }
.rule.is-new { animation: rise-in 0.3s var(--ease); }
@keyframes moved { from { background: var(--green-50); border-color: var(--green-300); } }

.rule-head {
  display: flex; align-items: center; gap: 12px; min-width: 0;
  padding: 10px 10px 10px 14px; border-bottom: 1px solid var(--line);
  background: var(--surface-2); border-radius: var(--radius) var(--radius) 0 0;
}
.rule-no::before {
  content: counter(rule);
  display: grid; place-items: center; width: 30px; height: 34px;
  border: 1.5px solid var(--ink-2); background: #fff;
  font-family: var(--mono); font-size: 16px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums;
}
.rule-title { flex: 1; min-width: 0; font-family: var(--mono); font-size: 15px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rule-badge { flex: none; font-size: 12.5px; font-weight: 700; letter-spacing: 0.08em; white-space: nowrap; }
.rule-badge-take { padding: 1px 8px; border-radius: 5px; background: var(--green-50); color: var(--green-700); }
.rule-badge-ignore {
  display: none; padding: 0 7px 0 9px; border: 2px solid var(--amber-ink); border-radius: 4px;
  color: var(--amber-ink); letter-spacing: 0.32em; transform: rotate(-4deg);
  box-shadow: inset 0 0 0 1.5px #fff, inset 0 0 0 2.5px rgba(131, 82, 0, 0.45);
}
.rule:has(option[value="1"]:checked) .rule-badge-take { display: none; }
.rule:has(option[value="1"]:checked) .rule-badge-ignore { display: inline-block; animation: stamp 0.3s var(--ease) backwards; }
.rule-tools { display: flex; flex: none; gap: 2px; }
.rule-tools .icon-btn[disabled] { opacity: 0.3; cursor: default; background: transparent; }
.icon-btn-danger:hover { background: var(--red-50); color: var(--red-700); }

.rule-error { padding: 10px 16px 0; }
.rule-error .field-error span { white-space: pre-line; }
.rule-head-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.btn-compact[aria-pressed="true"] { background: var(--green-50); color: var(--green-800); }
.rule-sum { display: none; margin-left: 12px; font-size: 13px; font-weight: 500; color: var(--muted); }
.rule-sum:empty { display: none !important; }
/* compact: only the heads, to see and change the order; rows with problems and new rows stay open */
.rule-chain.is-compact { gap: 8px; }
.rule-chain.is-compact .rule:not(.is-invalid):not(.is-new) .rule-body { display: none; }
.rule-chain.is-compact .rule:not(.is-invalid):not(.is-new) .rule-head { border-bottom: 0; border-radius: var(--radius); }
.rule-chain.is-compact .rule-sum { display: inline; }
.rule-body { padding: 14px 16px 16px; }
.rule-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 18px; }
.rule-extract {
  grid-column: 1 / -1; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 18px;
  padding-top: 14px; border-top: 1px dashed var(--line);
  transition: opacity 0.15s;
}
.rule:has(option[value="1"]:checked) .rule-extract { opacity: 0.45; }
.rule-grid .input { min-height: 40px; font-size: 14.5px; }
.rule-grid .hint { font-size: 12.5px; }

.rule-empty { display: grid; gap: 4px; justify-items: center; padding: 22px 16px; text-align: center; border: 1px dashed var(--line-2); border-radius: var(--radius); }
.rule-empty-title { font-weight: 700; }
.rule-chain:has(> li) + .rule-empty { display: none; }

.rule-end {
  display: flex; align-items: center; gap: 12px; margin-top: 12px; padding: 10px 14px;
  border: 1.5px dashed var(--line-2); border-radius: var(--radius); color: var(--muted); font-size: 13.5px;
}
.rule-end-mark { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: var(--sunken); color: var(--ink-2); }
.rule-end p { display: flex; flex-wrap: wrap; gap: 2px 10px; }
.rule-end b { color: var(--ink-2); }

/* keyword tags (the textarea stays as the submitted field) */
.kw-field.is-enhanced .kw-text { display: none; }
.tags-box {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 46px; padding: 6px 8px;
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: #fff; cursor: text;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.tags-box:hover { border-color: #a6b3a8; }
.tags-box:focus-within { border-color: var(--green-600); box-shadow: var(--ring); }
.tags-box:has([aria-invalid="true"]) { border-color: var(--red); }
.tags-list { display: contents; margin: 0; padding: 0; list-style: none; }
.tag-chip {
  display: inline-flex; align-items: center; gap: 2px; max-width: 100%; padding: 2px 2px 2px 10px;
  border: 1px solid var(--green-200); border-radius: 6px; background: var(--green-50); color: var(--green-800);
  font-family: var(--mono); font-size: 14px; line-height: 24px;
}
.tag-chip.is-new { animation: pop-in 0.2s var(--ease); }
.tag-chip.is-dup { animation: shake 0.35s; border-color: var(--amber); }
.tag-chip-text { overflow-wrap: anywhere; }
.tag-chip-x { display: grid; place-items: center; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 4px; background: transparent; color: var(--green-700); cursor: pointer; }
.tag-chip-x .icon { width: 14px; height: 14px; }
.tag-chip-x:hover, .tag-chip-x:focus-visible { background: var(--green-100); color: var(--green-900); }
.tags-input { flex: 1 1 8em; min-width: 6em; min-height: 32px; padding: 2px 4px; border: 0; background: transparent; font: inherit; font-size: 16px; color: var(--ink); }
.tags-input:focus { outline: none; }
.tags-input::placeholder { color: var(--faint); }

.save-note { display: flex; align-items: center; gap: 6px; margin-right: auto; font-size: 13.5px; font-weight: 600; color: var(--amber-ink); }
.save-note[hidden] { display: none; }
.save-note .icon { width: 16px; height: 16px; }

/* templates: tabs, editor, preview */
.tpl-tabs { display: none; gap: 6px; margin-bottom: 14px; overflow-x: auto; scrollbar-width: none; }
.tpl-form.is-tabbed .tpl-tabs { display: flex; }
.tpl-tab {
  display: inline-flex; align-items: center; gap: 10px; flex: none; min-height: 42px; padding: 0 8px 0 16px;
  border: 1px solid var(--line-2); border-radius: 999px; background: var(--surface); color: var(--ink-2);
  font: inherit; font-size: 15px; font-weight: 700; letter-spacing: 0.03em; cursor: pointer;
}
.tpl-tab:hover { border-color: var(--green-300); color: var(--ink); }
.tpl-tab[aria-selected="true"] { background: var(--green-900); border-color: var(--green-900); color: #fff; }
.tpl-tab-state { padding: 0 8px; border-radius: 999px; background: var(--sunken); color: var(--muted); font-size: 12px; font-weight: 600; line-height: 22px; }
.tpl-tab-state.is-custom { background: var(--green-100); color: var(--green-800); }
.tpl-tab-state.is-err { background: var(--red-100); color: var(--red-700); }
.tpl-tab[aria-selected="true"] .tpl-tab-state { background: rgba(255, 255, 255, 0.16); color: #fff; }
.tpl-tab[aria-selected="true"] .tpl-tab-state.is-err { background: var(--red); }

.tpl-panel + .tpl-panel { margin-top: 20px; }
.tpl-form.is-tabbed .tpl-panel + .tpl-panel { margin-top: 0; }
.tpl-panel[hidden] { display: none; }
.tpl-grid { display: grid; grid-template-columns: minmax(0, 1fr) 360px; }
.tpl-editor { display: grid; gap: 12px; align-content: start; padding: 20px; min-width: 0; }
.tpl-editor-head .card-title { display: block; }
.tpl-vars { display: flex; flex-wrap: wrap; gap: 6px; }
.var-chip {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 4px 10px;
  border: 1px solid var(--line-2); border-radius: 999px; background: #fff; color: var(--ink-2);
  font: inherit; font-size: 12.5px; cursor: pointer; transition: background-color 0.15s, border-color 0.15s;
}
.var-chip code { padding: 0; background: none; color: var(--green-800); font-size: 13px; font-weight: 700; }
.var-chip:hover { background: var(--green-50); border-color: var(--green-300); }
.var-chip:active { transform: translateY(1px); }
.tpl-format { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.fmt-btn {
  display: grid; place-items: center; min-width: 32px; height: 30px; padding: 0 8px;
  border: 1px solid var(--line-2); border-radius: 6px; background: #fff; color: var(--ink); font: inherit; font-size: 14px; cursor: pointer;
}
.fmt-btn:hover { background: var(--green-50); border-color: var(--green-300); }
.fmt-btn .mono { font-size: 12.5px; font-weight: 700; }
.fmt-note { margin-left: 6px; font-size: 12.5px; color: var(--muted); }
.fmt-note code { font-size: 11.5px; padding: 0 0.3em; }
.tpl-text { min-height: 220px; font-size: 14px; line-height: 1.6; tab-size: 2; }
.tpl-actions { display: flex; flex-wrap: wrap; gap: 8px; }

/* the Telegram phone */
.tg-phone {
  display: flex; flex-direction: column; margin: 0; min-width: 0;
  border-left: 1px solid var(--line); background: var(--surface-2); border-radius: 0 var(--radius) var(--radius) 0;
  overflow: hidden;
}
.tg-bar { display: flex; align-items: center; gap: 10px; padding: 10px 14px; background: #fff; border-bottom: 1px solid #e3e7e4; }
.tg-ava {
  display: inline-flex; align-items: center; justify-content: center; gap: 2px; width: 38px; height: 38px; flex: none;
  border-radius: 50%; background: var(--green-900);
}
.tg-ava i { width: 6px; height: 9px; border: 1.3px solid var(--red); background: #fff; }
.tg-who { min-width: 0; }
.tg-name { font-size: 15px; font-weight: 700; line-height: 1.3; }
.tg-sub { font-size: 13px; line-height: 1.3; color: #8b9590; }
.tg-sub.is-typing { color: #3390ec; }
.tg-sub.is-typing::after { content: ""; display: inline-block; width: 1.2em; animation: dots 1s steps(4) infinite; }
@keyframes dots { 0% { width: 0; } }
.tg-chat {
  flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 10px; min-height: 300px; padding: 14px 12px 18px;
  background:
    radial-gradient(circle at 20% 30%, rgba(255, 255, 255, 0.28) 0 1.2px, transparent 1.8px) 0 0 / 22px 22px,
    radial-gradient(circle at 70% 80%, rgba(13, 61, 44, 0.08) 0 1.4px, transparent 2px) 0 0 / 30px 30px,
    linear-gradient(160deg, #d4e3b6 0%, #b8d4a3 48%, #9fc6a6 100%);
}
.tg-day { align-self: center; padding: 1px 10px; border-radius: 999px; background: rgba(28, 58, 40, 0.28); color: #fff; font-size: 12.5px; font-weight: 600; }
.tg-msg { display: grid; gap: 4px; max-width: 94%; transition: opacity 0.2s, filter 0.2s; }
.tg-msg.is-stale { opacity: 0.45; filter: grayscale(0.6); }
.tg-bubble {
  position: relative; padding: 7px 10px 7px 11px; border-radius: 14px 14px 14px 4px; background: #fff;
  box-shadow: 0 1px 1.5px rgba(0, 0, 0, 0.16);
  font-family: var(--font); font-size: 15px; line-height: 1.42; color: #000; overflow-wrap: anywhere;
}
.tg-bubble::before {
  content: ""; position: absolute; left: -7px; bottom: 0; width: 12px; height: 14px; background: #fff;
  clip-path: path("M12 0 V14 H0 C5 13 8 9 12 0 Z");
}
.tg-text { display: inline; }
.tg-text b, .tg-text strong { font-weight: 700; }
.tg-text code { padding: 0 3px; border-radius: 4px; background: rgba(0, 0, 0, 0.055); color: #12507a; font-size: 0.92em; }
.tg-text pre {
  margin: 4px 0; padding: 6px 9px; border-radius: 6px; border-left: 3px solid #3390ec; background: rgba(51, 144, 236, 0.07);
  font-family: var(--mono); font-size: 13.5px; white-space: pre-wrap; color: #12507a;
}
.tg-text pre code { padding: 0; background: none; }
.tg-text a { color: #168acd; text-decoration: none; }
.tg-text a:hover { text-decoration: underline; }
.tg-text blockquote { margin: 3px 0; padding: 2px 8px; border-left: 3px solid #3390ec; border-radius: 3px; background: rgba(51, 144, 236, 0.07); }
.tg-placeholder { color: #8b9590; font-size: 14px; }
/* Telegram starts the next line right after a quote or code block */
.tg-text blockquote + br, .tg-text pre + br { display: none; }
.tg-msg[hidden] { display: none; }
.tg-time { float: right; margin: 8px 0 -6px 12px; font-size: 12px; line-height: 1; color: #95a39a; font-variant-numeric: tabular-nums; }
.tg-time:empty { display: none; }
.tg-kb { display: flex; gap: 4px; }
.tg-kb[hidden] { display: none; }
.tg-key {
  position: relative; flex: 1 1 0; min-width: 0; padding: 9px 14px; border-radius: 10px;
  background: rgba(32, 66, 46, 0.36); color: #fff; font-size: 14px; font-weight: 600; text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  backdrop-filter: blur(2px);
}
.tg-key-url::after { content: "↗"; position: absolute; top: 2px; right: 6px; font-size: 10px; opacity: 0.85; }

.tg-alert {
  display: flex; align-items: flex-start; gap: 10px; padding: 11px 14px;
  border-top: 1px solid var(--red-100); background: var(--red-50); color: var(--red-700); font-size: 13.5px;
}
.tg-alert[hidden] { display: none; }
.tg-alert > .icon { margin-top: 2px; }
.tg-alert-title { font-weight: 700; }
.tg-alert-text { margin-top: 2px; font-size: 12.5px; white-space: pre-wrap; overflow-wrap: anywhere; }
.tg-alert-warn { border-top-color: var(--amber-100); background: var(--amber-50); color: var(--amber-ink); }
.tg-alert-warn .tg-alert-text { font-family: var(--font); font-size: 13px; }
.tg-meta {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 12px; padding: 9px 14px;
  border-top: 1px solid var(--line); font-size: 12.5px; color: var(--muted);
}
.tg-len { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.tg-len.is-near { color: var(--amber-ink); font-weight: 700; }
.tg-raw { padding: 0 14px 12px; font-size: 12.5px; }
.tg-raw > summary { color: var(--muted); cursor: pointer; }
.tg-raw > summary:hover { color: var(--ink); }
.tg-raw pre {
  max-height: 220px; margin: 6px 0 0; padding: 8px 10px; overflow: auto;
  border: 1px solid var(--line); border-radius: 6px; background: #fff; white-space: pre-wrap; overflow-wrap: anywhere; font-size: 12.5px;
}

@media (max-width: 1100px) {
  .tpl-grid { grid-template-columns: minmax(0, 1fr); }
  .tg-phone { border-left: 0; border-top: 1px solid var(--line); border-radius: 0 0 var(--radius) var(--radius); }
  .tg-chat { min-height: 220px; }
}

@media (max-width: 640px) {
  .subnav { margin-top: -4px; }
  .rule-chain.is-compact .rule-sum { display: block; margin: 0; white-space: normal; }
  .rule-head { flex-wrap: wrap; gap: 8px 10px; padding: 8px 8px 8px 12px; }
  .rule-title { flex-basis: calc(100% - 140px); }
  .rule-badge { order: 3; }
  .rule-tools { margin-left: auto; }
  .rule-body { padding: 12px; }
  .rule-grid, .rule-extract { grid-template-columns: minmax(0, 1fr); }
  .rule-error { padding: 10px 12px 0; }
  .rule-guide-list > div { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .tpl-editor { padding: 16px; }
  .tpl-tab { padding-left: 12px; font-size: 14px; }
  .tg-msg { max-width: 100%; }
}

/* ---------- overview ----------
   The health verdict is a postmark: its colour and middle word carry the state, the
   bottom arc the time of the last refresh (written by app.js). Every colour on the page
   follows [data-state] on the board, a card or the seal: ok green, info blue, warn amber,
   err red, idle grey. Mailbox cards keep the engraved initial of the mailbox list; a card
   in trouble turns red and carries its action. */
.live-note { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); }
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green-600); animation: pulse 1.6s ease-in-out infinite; }
.live-note.is-off { color: var(--amber-ink); }
.live-note.is-off .live-dot { background: var(--amber); animation: none; }

.board { --tone: var(--green-800); --tone-soft: var(--green-50); --tone-line: var(--green-100); }
.board[data-state="info"] { --tone: var(--blue); --tone-soft: var(--blue-50); --tone-line: var(--blue-100); }
.board[data-state="warn"] { --tone: var(--amber-ink); --tone-soft: var(--amber-50); --tone-line: var(--amber-100); }
.board[data-state="err"] { --tone: var(--red); --tone-soft: var(--red-50); --tone-line: var(--red-100); }
.board[data-state="idle"] { --tone: var(--faint); --tone-soft: var(--surface-2); --tone-line: var(--line); }

.health {
  display: grid; grid-template-columns: 176px minmax(0, 1fr); gap: 8px 30px; align-items: center;
  padding: 22px 26px 22px 22px;
  background: linear-gradient(100deg, var(--tone-soft) 0, var(--surface) 46%);
  border: 1px solid var(--tone-line); border-radius: var(--radius); box-shadow: var(--shadow-1);
  transition: border-color 0.3s, background-color 0.3s;
}
.health-seal { display: grid; place-items: center; }
.health .health-mark { width: 156px; height: 156px; color: var(--tone); opacity: 0.88; transition: color 0.3s; }
.health-mark.is-restamp { animation: stamp 0.45s var(--ease); }
.pm-arc-time { font-family: var(--mono); font-size: 13px; letter-spacing: 0.18em; }
.health-body { min-width: 0; }
.health .eyebrow { color: var(--tone); }
.health-title { font-size: 23px; line-height: 1.3; font-weight: 800; letter-spacing: 0.04em; }
.health-text { margin-top: 4px; max-width: 60ch; color: var(--ink-2); }
.health-facts {
  display: flex; flex-wrap: wrap; margin: 16px 0 0; padding-top: 4px;
  border-top: 1px solid var(--line);
}
.health-facts > div { padding: 10px 22px 0 0; margin-right: 22px; border-right: 1px solid var(--line); }
.health-facts > div:last-child { border-right: 0; margin-right: 0; }
.health-facts dt { font-size: 12.5px; color: var(--muted); }
.health-facts dd { font-family: var(--mono); font-size: 22px; font-weight: 600; line-height: 1.35; font-variant-numeric: tabular-nums; color: var(--ink); }
.health-facts .is-hot.fact-ok dd { color: var(--green-700); }
.health-facts .is-hot.fact-bad dd { color: var(--red); }
.health-facts .is-hot.fact-pending dd { color: var(--amber-ink); }
.health-facts .fact-time dd { font-family: var(--font); font-size: 15px; font-weight: 600; line-height: 33px; }
.health-facts .fact-time time { font-variant-numeric: tabular-nums; }

/* first run: three steps, each number in a postcode box, joined by the routing line */
.setup .section-title { margin-top: 30px; }
.setup-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin: 0; padding: 0; list-style: none; }
.setup-step {
  position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  padding: 18px 18px 18px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-1); color: var(--muted);
}
.setup-step + .setup-step::before {
  content: ""; position: absolute; left: -15px; top: 35px; width: 16px; border-top: 1.5px dashed var(--line-2);
}
.setup-no {
  display: grid; place-items: center; width: 30px; height: 36px; margin-bottom: 4px;
  border: 1.5px solid var(--line-2); background: #fff; color: var(--faint);
  font-family: var(--mono); font-size: 18px; font-weight: 700;
}
.setup-no .icon { width: 17px; height: 17px; }
.setup-title { font-size: 16px; font-weight: 700; letter-spacing: 0.02em; color: var(--ink-2); }
.setup-text { flex: 1; margin-bottom: 8px; font-size: 13.5px; line-height: 1.6; }
.setup-wait { font-size: 13px; color: var(--faint); line-height: 32px; }
.setup-step.is-current { border-color: var(--green-300); box-shadow: var(--shadow-1), 0 0 0 3px var(--green-50); color: var(--ink-2); }
.setup-step.is-current .setup-no { border-color: var(--red); color: var(--ink); }
.setup-step.is-current .setup-title { color: var(--ink); }
.setup-step.is-done .setup-no { border-color: var(--green-700); background: var(--green-50); color: var(--green-700); }
.setup-step.is-done .setup-title { color: var(--ink); }

.board-changed { margin-top: 20px; }
.board-changed[hidden] { display: none; }

.dash-section .section-title { font-size: 18px; }
.section-link { display: inline-flex; align-items: center; gap: 5px; font-size: 14px; font-weight: 600; text-decoration: none; }
.section-link:hover { text-decoration: underline; }
.section-link .icon { width: 15px; height: 15px; }

.dash-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 16px; margin: 0; padding: 0; list-style: none; }
.dash-card {
  --tone: var(--green-600);
  display: flex; flex-direction: column; min-width: 0;
  padding: 16px 18px 14px 20px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-1), inset 4px 0 0 var(--tone);
  transition: border-color 0.3s, box-shadow 0.3s, background-color 0.3s;
}
.dash-card[data-state="busy"] { --tone: var(--blue); }
.dash-card[data-state="bad"] { --tone: var(--red); border-color: var(--red-100); background: linear-gradient(180deg, var(--red-50), var(--surface) 70px); }
.dash-card-head { display: flex; align-items: center; gap: 12px; }
.dash-glyph { width: 38px; height: 44px; font-size: 20px; flex: none; }
.dash-card[data-state="bad"] .dash-glyph { border-color: var(--red); outline-color: var(--red-50); color: var(--red-700); }
.dash-id { min-width: 0; }
.dash-name { display: block; font-size: 15.5px; font-weight: 700; color: var(--ink); text-decoration: none; overflow-wrap: anywhere; }
.dash-name:hover { color: var(--green-700); text-decoration: underline; }
.dash-user { font-size: 12.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-folders { margin: 12px 0 0; padding: 0; list-style: none; }
.dash-folder {
  display: flex; align-items: center; justify-content: space-between; gap: 6px 12px;
  padding: 7px 0; border-top: 1px dashed var(--line);
}
.dash-folder-name { min-width: 0; font-size: 13px; color: var(--ink-2); overflow-wrap: anywhere; }
.dash-folder .badge { font-size: 12px; line-height: 18px; }
.dash-foot { display: grid; gap: 10px; margin-top: auto; padding-top: 12px; border-top: 1px solid var(--line); }
.dash-foot[hidden] { display: none; }
.dash-card[data-state="bad"] .dash-foot { border-top-color: var(--red-100); }
.dash-note { font-size: 13.5px; line-height: 1.55; color: var(--muted); }
.dash-card[data-state="bad"] .dash-note { color: var(--red-700); font-weight: 600; }
.dash-action { display: flex; flex-wrap: wrap; gap: 8px; }
.dash-action:empty { display: none; }

/* forward log rows (the overview's latest and the log page) */
.log-table td { vertical-align: middle; }
.log-table .c-time { white-space: nowrap; font-size: 13px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.log-table .c-mb { min-width: 7em; }
.log-mb { display: block; font-weight: 600; overflow-wrap: anywhere; }
/* the config key beside a display name, as on the mailbox cards */
.log-key { margin-left: 6px; font-size: 11.5px; font-weight: 500; color: var(--muted); }
/* a folder path never breaks mid-word ("[Gmail]/Spa m"); a long one ends in … (full name in title) */
.log-folder { display: block; max-width: 16em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: var(--muted); }
.log-table .c-msg { width: 100%; min-width: 14em; }
.log-subject { display: block; overflow-wrap: anywhere; color: var(--ink); }
.log-from { display: block; font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
.log-table .c-kind, .log-table .c-result { white-space: nowrap; }
.log-table .c-rule { min-width: 8.5em; max-width: 14em; font-size: 13px; overflow-wrap: break-word; }
.log-rule { color: var(--ink-2); }
.faint { color: var(--faint); }
.tag-hit { background: var(--green-50); color: var(--green-800); }
.log-table .badge { font-size: 12px; line-height: 18px; }

.quiet-empty {
  display: flex; align-items: center; gap: 10px; padding: 18px 20px;
  border: 1.5px dashed var(--line-2); border-radius: var(--radius); background: var(--surface-2); color: var(--muted);
}
.quiet-empty[hidden], .table-wrap[hidden] { display: none; }
.quiet-empty .icon { color: var(--faint); }

/* log page */
.log-filter {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px 16px;
  margin-bottom: 18px; padding: 16px 18px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-1);
}
.log-filter .field { flex: 1 1 200px; max-width: 300px; }
.log-filter-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.log-count { margin: 0 0 10px; font-size: 13.5px; color: var(--muted); }
.pager { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: 18px; }
.pager-pos { font-size: 14px; font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.pager [aria-disabled="true"] { opacity: 0.45; pointer-events: none; }

@media (max-width: 860px) {
  .health { grid-template-columns: 132px minmax(0, 1fr); gap: 8px 20px; padding: 18px; }
  .health .health-mark { width: 124px; height: 124px; }
  .setup-steps { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .setup-step + .setup-step::before { left: 33px; top: -11px; width: 0; height: 12px; border-top: 0; border-left: 1.5px dashed var(--line-2); }
}

@media (max-width: 640px) {
  .page-head .live-note { order: -1; }
  /* seal beside the verdict, then the text and figures across the full width */
  .health { grid-template-columns: 96px minmax(0, 1fr); align-items: center; gap: 0 14px; padding: 16px; }
  .health-body { display: contents; }
  .health-seal { grid-row: 1 / span 2; }
  .health .eyebrow { align-self: end; margin-bottom: 2px; }
  .health-title { align-self: start; }
  .health-text, .health-facts { grid-column: 1 / -1; }
  .health-text { margin-top: 10px; }
  .health .health-mark { width: 96px; height: 96px; }
  .health-title { font-size: 19px; }
  .health-text { font-size: 14px; }
  .health-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 12px; }
  .health-facts > div { padding: 8px 0 6px; margin: 0; border-right: 0; border-bottom: 1px solid var(--line); }
  .health-facts > div:nth-child(odd) { padding-right: 12px; }
  .health-facts > div:nth-child(even) { padding-left: 12px; border-left: 1px solid var(--line); }
  .health-facts .fact-time { grid-column: 1 / -1; border-bottom: 0; }
  .health-facts .fact-time dd { line-height: 1.5; }
  .health-facts dd { font-size: 20px; }
  .dash-cards { grid-template-columns: minmax(0, 1fr); gap: 12px; }

  /* log rows become cards: time and result on top, then subject, then mailbox and kind */
  .log-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .log-table, .log-table tbody { display: block; }
  .log-table tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px;
    grid-template-areas: "time result" "msg msg" "mb kind" "rule rule";
    padding: 12px 16px; border-bottom: 1px solid var(--line);
  }
  .log-table tbody tr:last-child { border-bottom: 0; }
  .log-table td { display: block; padding: 0; border: 0; }
  .log-table .c-time { grid-area: time; align-self: center; }
  .log-table .c-result { grid-area: result; justify-self: end; }
  .log-table .c-msg { grid-area: msg; width: auto; min-width: 0; }
  .log-table .c-mb { grid-area: mb; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px; font-size: 13px; }
  .log-table .c-mb .log-mb { display: inline; }
  .log-table .c-mb .log-folder { display: inline-block; max-width: 100%; vertical-align: bottom; }
  .log-table .c-kind { grid-area: kind; justify-self: end; align-self: center; }
  .log-table .c-rule { grid-area: rule; font-size: 12.5px; color: var(--muted); }
  .log-table .c-rule:has(.faint) { display: none; }
  .log-table .c-rule .log-rule::before { content: "規則："; color: var(--faint); }
  .log-filter { padding: 14px 16px; }
  .log-filter .field { max-width: none; }
  .log-filter-actions { width: 100%; }
  .log-filter-actions .btn { flex: 1; }
  .pager { justify-content: space-between; }
}

/* ---------- motion ---------- */

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 50% { opacity: 0.35; transform: scale(0.8); } }
@keyframes drop-in { from { opacity: 0; transform: translateY(-6px); } }
@keyframes rise-in { from { opacity: 0; transform: translateY(8px); } }
@keyframes pop-in { from { opacity: 0; transform: translateY(6px) scale(0.98); } }
@keyframes stamp { from { opacity: 0; transform: rotate(-2deg) scale(1.25); } }
@keyframes shake { 20%, 60% { transform: translateX(-5px); } 40%, 80% { transform: translateX(5px); } }

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

/* ---------- narrow screens ---------- */

@media (max-width: 860px) {
  .shell { grid-template-columns: minmax(0, 1fr); background: none; }
  .rail {
    position: sticky; top: 0; z-index: 30; height: auto;
    grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto auto;
    grid-template-areas: "brand logout" "nav nav";
    padding: 10px 12px 0;
  }
  .rail .brand { padding: 2px 0 10px 2px; }
  .brand-mark { width: 32px; height: 32px; }
  .rail-logout { margin: 0 0 10px; align-self: center; }
  .logout-btn { padding: 6px 10px; gap: 6px; font-size: 14px; }
  .logout-btn .icon { width: 16px; height: 16px; }

  /* tabs that do not fit fade out at the edges, so the clipped ones read as "scroll for
     more"; the fades only cover the padding once scrolled to either end (the ::after
     spacer keeps room at the end), so no tab stays faded */
  .nav {
    flex-direction: row; gap: 2px;
    margin: 0 -12px; padding: 0 12px;
    overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 12px, #000 calc(100% - 36px), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 12px, #000 calc(100% - 36px), transparent);
  }
  .nav::after { content: ""; flex: none; width: 24px; }
  .nav::-webkit-scrollbar { display: none; }
  .nav-item { flex: none; margin: 0; padding: 8px 14px 10px; border-radius: 9px 9px 0 0; font-size: 14.5px; }
  .nav-item .icon { display: none; }
  .nav-item[aria-current="page"] { border-radius: 9px 9px 0 0; }
  .nav-item[aria-current="page"]::before { top: auto; right: auto; bottom: 0; left: -12px; background: radial-gradient(circle at 0 0, transparent 11.5px, var(--paper) 12px); }
  .nav-item[aria-current="page"]::after { bottom: 0; right: -12px; background: radial-gradient(circle at 100% 0, transparent 11.5px, var(--paper) 12px); }

  .main { padding: 24px 16px 56px; }
  .page-head { margin-bottom: 22px; padding-bottom: 16px; }
  .page-title { font-size: 24px; }
}

@media (max-width: 640px) {
  .grid-2 { grid-template-columns: minmax(0, 1fr); }
  .card-head, .card-body { padding-left: 16px; padding-right: 16px; }
  .card-foot { padding-left: 16px; padding-right: 16px; }
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .facts > div { border-right: 0; border-bottom: 1px solid var(--line); }
  .facts > div:nth-child(odd) { border-right: 1px solid var(--line); }
  .facts > div:nth-last-child(-n + 2):nth-child(odd), .facts > div:last-child { border-bottom: 0; }
  .page-actions, .form-actions { width: 100%; }
  .form-actions .btn { flex: 1; }

  .toasts, .toasts[popover] { inset: auto 16px calc(16px + env(safe-area-inset-bottom)) 16px; align-items: stretch; }
  .toast { max-width: none; }

  dialog.modal {
    width: 100%; max-width: 100%; max-height: 88vh;
    margin: auto 0 0; border-radius: 16px 16px 0 0;
  }
  dialog.modal[open] { animation-name: sheet-in; }

  .auth-card { padding: 26px 20px 24px; }
  .auth-foot { margin: 24px -20px -24px; padding: 10px 12px 10px 20px; }
  .step { padding-left: 44px; }

  .setting-row { grid-template-columns: minmax(0, 1fr); padding: 14px 16px; }
  .setting-note { padding-left: 16px; padding-right: 16px; }
  .card-section { padding: 16px; }
  .foot-note { flex-basis: 100%; }
  .ip-card { grid-template-columns: minmax(0, 1fr); padding: 20px 16px; }
  .postmark { width: 132px; height: 132px; }
  .ip-value { font-size: 26px; }
  .ip-facts > div { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .ledger-item { grid-template-columns: 3.6em minmax(0, 1fr); gap: 4px 12px; padding: 14px 16px; }
  .ledger-action { grid-column: 2; justify-content: flex-start; margin-top: 6px; }
  .qr { width: 176px; height: 176px; }

  .tg-item, .tg-bot { grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 14px 16px; }
  .tg-bot { grid-template-columns: 38px minmax(0, 1fr); column-gap: 12px; }
  .tg-bot .tg-avatar { align-self: start; }
  .tg-bot .tg-uses, .tg-bot .tg-actions { grid-column: 2; }
  .tg-actions { justify-content: flex-start; }
  .tg-btn-text { display: none; }
  .token-row { grid-template-columns: minmax(0, 1fr); }
  .token-row > .btn { justify-self: start; }
  .chats-hint { margin: 0 16px 12px; }
  .chat-row { padding: 11px 16px; }
  .chat-pick { display: none; }
  .mb-item { padding: 14px 16px; }
  .stamps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .stamp-face { min-height: 112px; }
  .stamp-glyph { font-size: 40px; }
  .grid-3 { grid-template-columns: minmax(0, 1fr); }
  .oauth-state { grid-template-columns: 34px minmax(0, 1fr); }
  .oauth-state .btn { grid-column: 2; justify-self: start; }
  .mb-form .card-head { flex-wrap: wrap; }
  .mb-form .advanced > summary { flex-wrap: nowrap; }
  .stamp-pick input:checked + .stamp .stamp-face::after { width: 38px; height: 38px; right: 2px; bottom: 24px; }
  .save-bar .btn { flex: 1; }
  .danger-body { padding: 14px 16px; }
  .modal-oauth .modal-body { padding-left: 16px; padding-right: 16px; }
  .modal-oauth .modal-foot { padding-left: 16px; padding-right: 16px; }
  .oauth-step { padding-left: 34px; }
  .oauth-note { flex-basis: 100%; }
  .modal-oauth .modal-foot .btn { flex: 1; }
  .oauth-link { width: 100%; }
  /* with an authorise button the actions need a row of their own */
  .mb-item:has(.btn-auth) .mb-actions { grid-column: 2 / 4; grid-row: auto; justify-content: flex-start; }
}

@keyframes sheet-in { from { transform: translateY(24px); opacity: 0; } }
