/* The component layer, shared by the mail and app origins (SPEC §16).
 * Colours are tokens only (R-UI-10). Motion is transform and opacity only
 * (R-UI-5); durations and easings are tokens (R-UI-3, R-UI-4); the
 * reduced-motion block at the end collapses every animation to an opacity
 * fade of ≤ 80 ms (R-UI-6, A-26). Depth is a lighter surface plus a hairline,
 * never a heavy shadow: on near-black, shadows read as smudges. */

/* ── Reset and type ────────────────────────────────────────────────────── */
:root { color-scheme: dark; }
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg-void);
  color: var(--text-hi);
  font: var(--fs-md) / var(--lh) var(--font-ui);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: anywhere;
}
h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -0.01em; line-height: 1.25; }
h1 { font-size: var(--fs-xl); }
h2 { font-size: var(--fs-lg); }
h3 { font-size: var(--fs-md); }
p { margin: 0; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }
code, kbd, pre, .mono { font-family: var(--font-mono); font-size: 0.93em; }
pre { margin: 0; white-space: pre-wrap; }
::selection { background: var(--accent-tint-strong); }
button, input, textarea, select { font: inherit; color: inherit; letter-spacing: inherit; }
img { max-width: 100%; }
/* An icon has a size everywhere, so no context can inflate it. */
svg { width: 1.15em; height: 1.15em; flex: none; vertical-align: -0.2em; }
.tabular { font-variant-numeric: tabular-nums; }
.muted { color: var(--text-mid); }
.low { color: var(--text-low); }
.small { font-size: var(--fs-sm); }
.xs { font-size: var(--fs-xs); }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
[hidden] { display: none !important; }
hr { border: 0; border-top: 1px solid var(--line); margin: var(--sp-4) 0; }

/* Scrollbars: present, quiet. */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }

/* R-CLI-9: a visible focus ring on everything, keyboard only. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm); }
:focus:not(:focus-visible) { outline: none; }

/* ── Buttons ───────────────────────────────────────────────────────────── */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 34px; padding: 0 var(--sp-4);
  border: 1px solid var(--line-input); border-radius: var(--radius-sm);
  background: var(--bg-raised); color: var(--text-hi);
  font-weight: 500; white-space: nowrap; cursor: pointer; user-select: none;
  transition: background-color var(--motion-transition) var(--ease-enter),
              border-color var(--motion-transition) var(--ease-enter),
              color var(--motion-transition) var(--ease-enter),
              opacity var(--motion-transition) var(--ease-enter);
}
.btn:hover { background: var(--bg-overlay); border-color: var(--text-low); }
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
.btn.primary {
  border-color: transparent; color: var(--text-on-accent); font-weight: 600;
  background: var(--gradient-accent); overflow: hidden; isolation: isolate;
}
.btn.primary::after { content: ''; position: absolute; inset: 0; background: var(--dither); opacity: var(--dither-opacity); pointer-events: none; }
.btn.primary:hover { filter: none; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text-hi) 25%, transparent), var(--glow-accent-soft); }
.btn.ghost { background: transparent; border-color: transparent; color: var(--text-mid); }
.btn.ghost:hover { background: var(--bg-raised); color: var(--text-hi); border-color: transparent; }
.btn.danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.btn.danger:hover { background: var(--danger-tint); border-color: var(--danger); }
.btn.danger.solid { background: var(--danger); color: var(--text-on-accent); border-color: transparent; }
.btn.sm { min-height: 28px; padding: 0 var(--sp-3); font-size: var(--fs-sm); }
.btn.icon { width: 34px; padding: 0; }
.btn.icon.sm { width: 28px; }
.btn svg { width: 16px; height: 16px; flex: none; }
.btn .kbd { margin-left: var(--sp-1); }
.btn.primary .kbd { background: color-mix(in srgb, var(--bg-void) 18%, transparent); border-color: color-mix(in srgb, var(--bg-void) 30%, transparent); color: inherit; }

/* ── Inputs ────────────────────────────────────────────────────────────── */
.input, input:not([type=checkbox]):not([type=radio]), textarea, select {
  width: 100%; min-height: 36px; padding: var(--sp-2) var(--sp-3);
  background: var(--bg-surface); color: var(--text-hi);
  border: 1px solid var(--line-input); border-radius: var(--radius-sm);
  transition: border-color var(--motion-transition) var(--ease-enter), background-color var(--motion-transition) var(--ease-enter);
}
input::placeholder, textarea::placeholder { color: var(--text-low); }
input:hover, textarea:hover, select:hover { border-color: var(--text-low); }
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint), var(--glow-accent-soft); }
textarea { resize: vertical; line-height: 1.5; }
input[type=search] { -webkit-appearance: none; appearance: none; }
input[type=search]::-webkit-search-cancel-button { -webkit-appearance: none; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label, .label { font-size: var(--fs-sm); font-weight: 500; color: var(--text-mid); }
.field .hint { font-size: var(--fs-sm); color: var(--text-low); }
.field.error input { border-color: var(--danger); }
.inline { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
.stack { display: flex; flex-direction: column; gap: var(--sp-3); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
/* A dialog's actions, and the rule that separates them from whatever follows.
   Both were being used before they existed, which is why the forward dialog's
   buttons sat left and its list crowded them (D-159). */
.row-end { display: flex; align-items: center; justify-content: flex-end; gap: var(--sp-3);
           margin-top: var(--sp-4); }
.dialog > .sep { border-top: 1px solid var(--line); margin: var(--sp-5) 0 var(--sp-4); }
.dialog > h3 { margin-bottom: var(--sp-3); }
.dialog > .stack > * + * { margin-top: var(--sp-2); }
.grow { flex: 1 1 auto; min-width: 0; }
.mono-input { font-family: var(--font-mono); }

/* ── Chips: aliases are the product, they should look like precise objects ── */
.chip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  min-height: 24px; padding: 0 9px;
  border: 1px solid var(--line-strong); border-radius: var(--radius-pill);
  background: var(--bg-raised); color: var(--text-hi);
  font-family: var(--font-mono); font-size: var(--fs-sm); line-height: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: border-color var(--motion-transition) var(--ease-enter), background-color var(--motion-transition) var(--ease-enter), opacity var(--motion-transition) var(--ease-enter);
}
.chip .tag { color: var(--accent); font-weight: 600; }
.chip .dim { color: var(--text-low); }
.chip.ui { font-family: var(--font-ui); }
.chip.active { border-color: transparent; color: var(--text-on-accent); background: var(--gradient-accent); position: relative; overflow: hidden; box-shadow: var(--glow-accent-soft); }
.chip.active::after { content: ''; position: absolute; inset: 0; background: var(--dither); opacity: var(--dither-opacity); pointer-events: none; }
.chip.active .tag, .chip.active .dim { color: inherit; }
.chip.positive { border-color: color-mix(in srgb, var(--positive) 45%, transparent); background: var(--positive-tint); color: var(--positive); }
.chip.warning { border-color: color-mix(in srgb, var(--warning) 45%, transparent); background: var(--warning-tint); color: var(--warning); }
.chip.danger { border-color: color-mix(in srgb, var(--danger) 45%, transparent); background: var(--danger-tint); color: var(--danger); }
.chip.quiet { background: transparent; color: var(--text-mid); }
button.chip { cursor: pointer; }
button.chip:hover { border-color: var(--accent); }
.chip svg { width: 13px; height: 13px; flex: none; }

/* ── Surfaces ──────────────────────────────────────────────────────────── */
.card { background: var(--bg-surface); border: 1px solid var(--line); border-radius: var(--radius-md); padding: var(--sp-4); }
.card.raised { background: var(--bg-raised); }
.card > h2, .card > h3 { margin-bottom: var(--sp-2); }
.card + .card { margin-top: var(--sp-3); }
.hairline { border-top: 1px solid var(--line); }
.notice {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  padding: var(--sp-3) var(--sp-4); border: 1px solid var(--line-strong); border-radius: var(--radius-md);
  background: var(--bg-raised); color: var(--text-hi);
}
.notice svg { width: 18px; height: 18px; flex: none; margin-top: 1px; }
.notice .body { flex: 1 1 auto; min-width: 0; }
.notice .body strong { display: block; margin-bottom: 2px; }
.notice.warn { border-color: color-mix(in srgb, var(--warning) 50%, transparent); background: var(--warning-tint); }
.notice.warn svg { color: var(--warning); }
.notice.danger { border-color: color-mix(in srgb, var(--danger) 50%, transparent); background: var(--danger-tint); }
.notice.danger svg { color: var(--danger); }
.notice.positive { border-color: color-mix(in srgb, var(--positive) 50%, transparent); background: var(--positive-tint); }
.notice.positive svg { color: var(--positive); }

/* A checkbox with its reason, in a dialog either origin can open (D-159).
   The app has its own `.check-row`, but that lives in the app's stylesheet and
   the forward dialog is shared — a shared component reaching into one origin's
   CSS is how it ends up looking right in one place and broken in the other,
   which is exactly what happened. */
.choice-row { display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: start;
              padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-md); border: 1px solid var(--line);
              background: var(--bg-raised); cursor: pointer; line-height: 1.45; }
.choice-row:hover { border-color: var(--line-strong); }
.choice-row:has(input:checked) { border-color: color-mix(in srgb, var(--danger) 55%, var(--line)); }
.choice-row input { margin-top: 3px; }
.choice-row strong { display: block; }

/* A forward destination, in the forward dialog (D-159). The state is carried
   by a left edge rather than a badge: three rows of badges read as noise, and
   the sentence beside each one already says what the state means. */
.dest { display: flex; gap: var(--sp-3); align-items: center; padding: var(--sp-3) var(--sp-4);
        border: 1px solid var(--line); border-radius: var(--radius-md); border-left-width: 3px; }
.dest + .dest { margin-top: var(--sp-3); }
.dest .mono { display: block; margin-bottom: 2px; }
/* The forward panel: two numbered steps and a list, each its own block. */
.forward-panel > .notice { padding: var(--sp-4) var(--sp-5); line-height: 1.45; }
.forward-panel > .notice p + p { margin-top: var(--sp-2); }
.forward-panel .step { margin-top: var(--sp-6); }
.forward-panel .step > h3 { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.forward-panel .step > h3 .n { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; background: var(--accent-tint); color: var(--accent); font-size: var(--fs-sm); }
.forward-panel .step > .lede { margin: -4px 0 var(--sp-4); line-height: 1.45; }
.forward-panel .step > .row-end { margin-top: var(--sp-4); }
.dest.confirmed { border-left-color: var(--positive); }
.dest.pending   { border-left-color: var(--warning); }
.dest.expired   { border-left-color: var(--line-strong); }
.notice.accent { border-color: color-mix(in srgb, var(--accent) 50%, transparent); background: var(--accent-tint); }
.notice.accent svg { color: var(--accent); }
.error-text { color: var(--danger); }
.positive-text { color: var(--positive); }
.warning-text { color: var(--warning); }

.kbd {
  display: inline-block; min-width: 20px; padding: 1px 6px; text-align: center;
  border: 1px solid var(--line-strong); border-bottom-width: 2px; border-radius: 5px;
  background: var(--bg-raised); color: var(--text-mid);
  font-family: var(--font-mono); font-size: var(--fs-xs); line-height: 1.5;
}

/* A gradient surface, with its dither (R-UI-1). */
.gradient-surface { position: relative; background: var(--gradient-accent); isolation: isolate; overflow: hidden; }
.gradient-surface::after { content: ''; position: absolute; inset: 0; background: var(--dither); opacity: var(--dither-opacity); pointer-events: none; }

/* ── The stage: the full-bleed ambient gradient behind the gate screens ── */
.stage {
  position: fixed; inset: 0; display: grid; place-items: center; padding: var(--sp-4);
  overflow: auto;
  background:
    radial-gradient(60vmax 60vmax at 30% 20%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 70%),
    radial-gradient(50vmax 50vmax at 75% 85%, color-mix(in srgb, var(--accent-warm) 14%, transparent), transparent 70%),
    var(--bg-void);
}
.stage::before { content: ''; position: fixed; inset: 0; background: var(--dither); opacity: var(--dither-opacity); pointer-events: none; }
.stage-card {
  position: relative; width: min(100%, 420px);
  padding: var(--sp-6) var(--sp-5); border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--bg-surface) 88%, transparent);
  border: 1px solid var(--line-strong);
  backdrop-filter: blur(12px);
  box-shadow: var(--glow-warm);
}
.stage-card h1 { font-size: var(--fs-2xl); letter-spacing: -0.02em; }
.stage .origin { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--text-mid); }
.stage .origin svg { width: 13px; height: 13px; color: var(--positive); }
.stage .origin .host { color: var(--text-hi); }

/* The brand mark: a lock-shaped monogram drawn in CSS from tokens. */
.brand { display: inline-flex; align-items: center; gap: 10px; color: var(--text-hi); font-weight: 600; letter-spacing: -0.01em; text-decoration: none; }
.brand .mark { width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center; color: var(--text-on-accent); flex: none; }
.brand .mark svg { width: 15px; height: 15px; }
.brand .name { font-size: var(--fs-lg); }
.brand .name em { font-style: normal; color: var(--text-mid); font-weight: 500; }

/* ── Skeletons (R-UI-9): the surface palette, a slow sweep, only after a
 * real 200 ms wait — the `is-waiting` class arrives from script. ── */
.skeleton { position: relative; overflow: hidden; background: var(--bg-raised); border-radius: var(--radius-sm); color: transparent !important; }
.skeleton::after {
  content: ''; position: absolute; inset: 0; width: 60%;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--text-hi) 5%, transparent), transparent);
  transform: translateX(-170%);
}
.is-waiting .skeleton::after { animation: cm-shimmer var(--motion-skeleton) var(--ease-enter) infinite; }
.skeleton-line { height: 12px; margin: 5px 0; }

/* ── Motion primitives (R-UI-3 to R-UI-7) ─────────────────────────────── */
@keyframes cm-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes cm-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes cm-scale { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: none; } }
@keyframes cm-slide-in { from { opacity: 0; transform: translateX(-10px); } to { opacity: 1; transform: none; } }
@keyframes cm-shimmer { to { transform: translateX(270%); } }
@keyframes cm-syncline { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
@keyframes cm-pulse { 0% { opacity: 1; } 50% { opacity: 0.35; } 100% { opacity: 1; } }
@keyframes cm-flash { from { opacity: 1; } to { opacity: 0; } }
@keyframes cm-lift { to { opacity: 0; transform: translate(-40px, -24px) scale(0.92); } }
@keyframes cm-fracture {
  0% { opacity: 1; transform: none; }
  30% { opacity: 1; transform: translateX(2px) rotate(0.6deg); }
  55% { opacity: 0.8; transform: translateX(-3px) rotate(-1.2deg) scale(0.99); }
  100% { opacity: 0; transform: translateY(10px) rotate(3deg) scale(0.9); }
}
@keyframes cm-sweep { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

.anim-fade { animation: cm-fade var(--motion-entrance) var(--ease-enter) both; }
.anim-rise { animation: cm-rise var(--motion-entrance) var(--ease-enter) both; }
.anim-scale { animation: cm-scale var(--motion-entrance) var(--ease-enter) both; }
.anim-slide-in { animation: cm-slide-in var(--motion-entrance) var(--ease-enter) both; }
.anim-lift { animation: cm-lift var(--motion-send) var(--ease-exit) forwards; }
.anim-fracture { animation: cm-fracture var(--motion-moment) var(--ease-exit) forwards; }
.anim-pulse { animation: cm-pulse 1200ms var(--ease-enter) infinite; }

/* The gradient sweep: unlock progress, the sync line. A 2px line whose
 * gradient travels by transform, not by width. */
.sweep { position: relative; height: 2px; overflow: hidden; background: transparent; }
.sweep::before { content: ''; position: absolute; inset: 0; background: var(--gradient-accent); opacity: 0; transition: opacity var(--motion-transition) var(--ease-exit); }
.sweep.on::before { opacity: 1; animation: cm-syncline 1100ms var(--ease-enter) infinite; }

/* ── Overlays: toasts, the shortcut layer, popovers ────────────────────── */
.toasts { position: fixed; left: 50%; bottom: var(--sp-5); transform: translateX(-50%); display: flex; flex-direction: column; gap: var(--sp-2); z-index: 60; pointer-events: none; width: min(100%, 460px); padding: 0 var(--sp-4); }
.toast { pointer-events: auto; display: flex; gap: var(--sp-3); align-items: center; padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-md); background: var(--bg-overlay); border: 1px solid var(--line-strong); color: var(--text-hi); }
.toast.positive { border-color: color-mix(in srgb, var(--positive) 50%, transparent); }
.toast.danger { border-color: color-mix(in srgb, var(--danger) 50%, transparent); }
.toast .btn { margin-left: auto; }

.scrim { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: var(--sp-4); background: var(--scrim); backdrop-filter: blur(4px); }
.dialog { width: min(100%, 560px); max-height: 90vh; overflow: auto; padding: var(--sp-6); border-radius: var(--radius-lg); background: var(--bg-overlay); border: 1px solid var(--line-strong); }
.dialog h2 { margin-bottom: var(--sp-3); }
/* A dialog with tabs needs the room; 560px puts four tab labels on two lines. */
.dialog.wide { width: min(100%, 740px); }
@media (max-width: 720px) { .dialog { padding: var(--sp-5) var(--sp-4); } }

/* A real tab bar for switching sections inside a dialog: underlined, not
   pills. The active tab carries the accent on its lower edge and nothing
   else moves, so the eye reads "which section" without a colour block
   competing with the content below it. */
.tabbar { display: flex; gap: var(--sp-1); border-bottom: 1px solid var(--line); margin: var(--sp-4) 0 var(--sp-5); overflow-x: auto; }
.tabbar .tab { appearance: none; background: transparent; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; padding: var(--sp-2) var(--sp-3) var(--sp-3); color: var(--text-mid); font: inherit; font-weight: 500; cursor: pointer; white-space: nowrap; transition: color var(--motion-transition) var(--ease-enter), border-color var(--motion-transition) var(--ease-enter); }
.tabbar .tab:hover { color: var(--text-hi); }
.tabbar .tab.active { color: var(--text-hi); border-bottom-color: var(--accent); }
.tabbar .tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--radius-sm); }

/* Rhythm inside a dialog: a field is label, input, hint, with a full step
   between fields rather than the 6px that reads as one dense block. */
.dialog .field { gap: var(--sp-2); }
.dialog .field + .field, .dialog .choice-row + .field, .dialog .field + .choice-row, .dialog .choice-row + .choice-row { margin-top: var(--sp-4); }
.dialog .field > label { font-size: var(--fs-md); color: var(--text-hi); }
.dialog .field .hint { line-height: 1.45; }
.dialog h3 { font-size: var(--fs-md); font-weight: 600; color: var(--text-hi); }
/* A group of controls under a small heading, inside a tab. */
.dialog .group { margin-top: var(--sp-5); }
.dialog .group > h4 { font-size: var(--fs-sm); font-weight: 600; letter-spacing: .02em; text-transform: uppercase; color: var(--text-low); margin-bottom: var(--sp-3); }
.dialog .group > .lede { margin: -4px 0 var(--sp-3); }
.shortcuts { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--sp-4) var(--sp-5); }
.shortcuts h3 { color: var(--text-mid); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: var(--sp-2); }
.shortcuts dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 6px var(--sp-3); align-items: center; }
.shortcuts dt { text-align: right; white-space: nowrap; }
.shortcuts dd { margin: 0; color: var(--text-mid); }

.popover { position: absolute; z-index: 40; min-width: 220px; padding: var(--sp-2); border-radius: var(--radius-md); background: var(--bg-overlay); border: 1px solid var(--line-strong); }
.popover .item { display: flex; align-items: center; gap: var(--sp-3); width: 100%; padding: 8px 10px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--text-hi); text-align: left; cursor: pointer; }
.popover .item:hover { background: var(--bg-raised); }
.popover .item.danger { color: var(--danger); }
.popover .item svg { width: 15px; height: 15px; flex: none; color: var(--text-low); }
.popover .item.danger svg { color: var(--danger); }
.popover.row-menu { min-width: 200px; }
.popover .item svg { width: 16px; height: 16px; color: var(--text-mid); }
.popover .item .kbd { margin-left: auto; }
.popover .item.danger { color: var(--danger); }
.popover .sep { border-top: 1px solid var(--line); margin: var(--sp-1) 0; }

/* A hover card: what a fact means, on hover or focus, without a click. */
.hover-card { position: absolute; z-index: 45; max-width: 320px; padding: var(--sp-3); border-radius: var(--radius-md); background: var(--bg-overlay); border: 1px solid var(--line-strong); box-shadow: var(--glow-accent-soft); font-size: var(--fs-sm); color: var(--text-mid); }
.hover-card h4 { margin: 0 0 6px; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-low); }
.hover-card ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 4px; }
.hover-card li { display: flex; gap: 8px; align-items: baseline; }
.hover-card li .name { color: var(--text-hi); font-weight: 500; }
.hover-card li .mono { color: var(--text-low); }

/* ── Empty states: each is a moment the app can explain itself ─────────── */
.empty { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: var(--sp-2); padding: var(--sp-7) var(--sp-5); color: var(--text-mid); min-height: 240px; }
.empty .glyph { width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--bg-raised); border: 1px solid var(--line-strong); color: var(--text-mid); margin-bottom: var(--sp-2); }
.empty .glyph svg { width: 20px; height: 20px; }
.empty h2 { color: var(--text-hi); font-size: var(--fs-lg); }
.empty p { max-width: 42ch; }
.empty .chip { margin-top: var(--sp-1); }

/* ── Tables (app origin lists) ─────────────────────────────────────────── */
.table { width: 100%; border-collapse: collapse; }
.table th { text-align: left; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-low); font-weight: 600; padding: var(--sp-2) var(--sp-2); border-bottom: 1px solid var(--line); }
.table td { padding: 10px var(--sp-2); border-bottom: 1px solid var(--line); vertical-align: middle; }
.table tr:last-child td { border-bottom: 0; }
.table-wrap { overflow-x: auto; }

/* ── The header both origins share: brand, where you are, who you are ── */
.identity { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.identity .who { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.identity .who .mailbox { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--text-hi); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.identity .who .where { font-size: var(--fs-xs); color: var(--text-low); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.identity .avatar { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; flex: none; font-family: var(--font-mono); font-weight: 600; font-size: var(--fs-sm); color: var(--text-on-accent); }

/* ── The theme picker (§16, D-138) ──────────────────────────────────────
 * The swatch carries `data-theme` itself, so what it shows is the theme's
 * own tokens rather than a copy of them: a new theme needs no CSS here.
 * It is a miniature of the shell — the void behind a panel, a hairline, the
 * accent bar that marks what is selected, two lines of text. ── */
/* Two to a row wherever it is shown — the Account card and the dialog are
 * both around 500 px of usable width — and one to a row on a phone. */
.theme-picker { display: grid; grid-template-columns: repeat(auto-fit, minmax(212px, 1fr)); gap: var(--sp-3); }
.theme-option {
  position: relative; display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto;
  gap: 2px var(--sp-3); align-items: center; cursor: pointer;
  padding: var(--sp-3); border: 1px solid var(--line); border-radius: var(--radius-md);
  background: var(--bg-raised); min-width: 0;
  transition: border-color var(--motion-transition) var(--ease-enter), background-color var(--motion-transition) var(--ease-enter);
}
.theme-option:hover { border-color: var(--line-strong); }
.theme-option.on { border-color: var(--accent); background: var(--accent-tint); box-shadow: var(--glow-accent-soft); }
.theme-option input { position: absolute; opacity: 0; width: 0; height: 0; }
.theme-option:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.theme-option .theme-swatch { grid-row: span 2; }
.theme-name { color: var(--text-hi); font-weight: 600; align-self: end; min-width: 0; }
.theme-note { color: var(--text-low); font-size: var(--fs-sm); align-self: start; min-width: 0; line-height: 1.35; }

.theme-swatch {
  display: block; width: 84px; height: 56px; flex: none; border-radius: var(--radius-sm);
  overflow: hidden; border: 1px solid var(--line-strong); background: var(--bg-void); padding: 8px 0 0 10px;
}
.theme-swatch .sw-surface {
  display: block; position: relative; height: 100%; border-radius: 4px 0 0 0;
  background: var(--bg-surface); border-left: 1px solid var(--line); border-top: 1px solid var(--line); padding: 9px 0 0 8px;
}
/* A row divider, the way the list has one: the theme's hairline, visible. */
.theme-swatch .sw-line { position: absolute; left: 8px; right: 0; top: 27px; height: 1px; background: var(--line-strong); }
/* The accent bar that marks what is selected, with the theme's own glow. */
.theme-swatch .sw-accent { position: absolute; left: 0; top: 8px; width: 2px; height: 15px; background: var(--accent); box-shadow: var(--glow-accent); border-radius: 2px; }
.theme-swatch .sw-text { display: block; height: 3px; width: 36px; border-radius: 2px; background: var(--text-hi); margin-bottom: 6px; }
.theme-swatch .sw-text.short { width: 24px; background: var(--text-mid); }

/* ── R-UI-6: reduced motion. Every entrance becomes an opacity fade, every
 * transition drops its transform, the loops that are pure decoration stop,
 * and the ones that carry meaning (sync, waiting) become opacity pulses. ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-property: opacity, color, background-color, border-color, outline-color !important;
    transition-duration: var(--motion-transition) !important;
  }
  .anim-rise, .anim-scale, .anim-slide-in, .anim-lift, .anim-fracture { animation-name: cm-fade; animation-duration: var(--motion-entrance); }
  .anim-lift, .anim-fracture { animation-name: cm-flash; animation-fill-mode: forwards; }
  .is-waiting .skeleton::after { animation: none; }
  .sweep.on::before { animation: cm-pulse 80ms var(--ease-enter) 1 both; transform: none; }
  .anim-pulse { animation: none; }
  .btn:active { transform: none; }
}
