/* Ducter phone client. Pebble tokens (design/ui.md, D76-D78); components read only these vars. */
@font-face {
  font-family: "Bricolage Grotesque";
  src: url("bricolage.woff") format("woff");
  font-weight: 200 800;
  font-display: swap;
}
/* zh headings (>= 20, where Latin is 800): Resource Han Rounded CN Bold at 94%, CJK only (D78). */
@font-face {
  font-family: "Ducter Rounded SC";
  src: url("fonts/rounded-sc-bold.woff2") format("woff2");
  font-weight: 700 900;
  font-display: swap;
  size-adjust: 94%;
  unicode-range: U+2E80-9FFF, U+3000-303F, U+F900-FAFF, U+FF00-FFEF;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/jetbrains-mono.woff2") format("woff2");
  font-weight: 100 800;
  font-display: swap;
}

:root {
  color-scheme: light dark;
  --bg: #fff6ea;
  --bg-deep: #fcecd7;
  --surface: #ffffff;
  --sunken: #f7ebda;
  --surface-sunken: #f3e6d3; /* sunken-2 */
  --surface-raised: #fffbf0;
  --ink: #2b2118;
  --ink-soft: #4a3d30;
  --ink-muted: #75654f;
  --faint: #c7b49a;
  --accent: #ff8a3d;
  --on-accent: #2b2118;
  /* The two voices (D129): the user in the accent with ink (6.9:1), the partner in white. */
  --user-bubble: #ff8a3d;
  --on-user-bubble: #2b2118;
  --partner-bubble: #ffffff;
  --on-partner-bubble: #2b2118;
  --line: #e8d9c4;
  --line-2: #e0c9b0;
  --line-soft: #f3e6d3;
  --highlight: #ffe9a8;
  --highlight-ink: #6b5000;

  --needs-dot: #ff8a3d;
  --needs-surface: #ffe3cf;
  --needs-ink: #8a3a0c;
  --needs-ledge: #f0c29e;
  --working-dot: #4ba8f0;
  --working-surface: #dcefff;
  --working-ink: #174a75;
  --waiting-dot: #ffc94d;
  --waiting-surface: #fff0bf;
  --waiting-ink: #6b5000;
  --done-dot: #7fd99a;
  --done-surface: #d6f5dc;
  --done-ink: #1f5e2f;
  --failed-dot: #e5577a;
  --failed-surface: #fbdde4;
  --failed-ink: #8a1f3b;
  --dusk-ink: #4b4a7a;

  /* Depth: one clay (D76). A card rests on a solid 4px base and never moves; a button stands
     on a 3px ledge in a darker shade of its fill, with a drop and a top highlight, and sinks
     into the ledge when pressed. */
  --base: 0 4px 0 var(--line);
  --ledge: 3px;
  --press-primary: #140d07;
  --press-quiet: #cdae8c; /* secondary */
  --press-accent: #c9642a;
  /* The ink button reads as clay too: a lighter top, a warm seam above its ledge. */
  --primary-top: #3b2d22;
  --seam-primary: #5a4434;
  --rim-primary: rgba(255, 236, 214, 0.08);
  --seam-quiet: #ead6bc;
  --seam-accent: #ffa466;
  --hi-primary: rgba(255, 246, 234, 0.26);
  --drop-primary: 0 7px 12px -4px rgba(43, 33, 24, 0.38);
  --hi-secondary: rgba(255, 255, 255, 0.95);
  --hi-accent: rgba(255, 255, 255, 0.38);
  --rim: rgba(43, 33, 24, 0.09);
  --drop: 0 7px 12px -4px rgba(43, 33, 24, 0.28);
  --drop-pressed: 0 1px 3px rgba(43, 33, 24, 0.22);
  --floating: 0 10px 32px rgba(43, 33, 24, 0.14);
  /* Under a sheet the page only dims a little, in warm brown: grey at this weight reads as dark mode. */
  --scrim: rgba(60, 40, 20, 0.14);

  --font: "Bricolage Grotesque", "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", system-ui, -apple-system, "Segoe UI", sans-serif;
  --head: "Bricolage Grotesque", "Ducter Rounded SC", "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", system-ui, -apple-system, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  /* Type scale: 12 13 15 16 18 20 28 34 56 (D76). */
  --xs: 12px;
  --sm: 13px;
  --md: 15px;
  --body: 16px; /* the conversation's one body size: both bubbles, the composer (D129) */
  --lg: 18px;
  --partner: 16px;
  --t20: 20px;
  --t28: 28px;
  --t34: 34px;
  --lh-read: 1.55;
  --lh-voice: 1.65;

  /* One 4-pt spacing scale and one radius scale (same as the desktop's tokens). */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s7: 48px;
  --r-xs: 8px; /* inline code */
  --r-sm: 12px; /* small buttons, fields */
  --r-btn: 14px; /* buttons */
  --r-md: 16px; /* sheets, notices, the segmented track */
  --r-btn-lg: 18px;
  --r-lg: 24px; /* cards */
  --r-xl: 28px; /* hero cards, the composer */
  --pill: 999px;
  --bubble: 20px 20px 6px 20px; /* the user's; the partner's mirrors it */
  --bubble-partner: 20px 20px 20px 6px;
  --bubble-join: 6px; /* the tail side's top corner of a bubble stacked on one of its voice */
  --bubble-measure: 38em;

  --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --t-press: 70ms;
  --t-fast: 120ms;
  --t-med: 320ms;

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  /* A phone on its side, a foldable's vertical bar (D176). */
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
}
/* Chinese reads looser and keeps its own rules (D78). */
:root:lang(zh) {
  --lh-read: 1.75;
  --lh-voice: 1.75;
}

/* Pebble dark: Pebble shapes and motion on Midnight-like surfaces (ui.md token schema, mode). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #17120e;
    --bg-deep: #120e0b;
    --surface: #231c16;
    --sunken: #1d1712;
    --surface-raised: #2a221b;
    --surface-sunken: #1d1712;
    --ink: #f6ebdd;
    --ink-soft: #dccbb6;
    --ink-muted: #a8957e;
    --faint: #5a4c3e;
    --user-bubble: #ff8a3d;
    --on-user-bubble: #2b2118;
    --partner-bubble: #2a221b;
    --on-partner-bubble: #f6ebdd;
    --line: #3a3027;
    --line-2: #0d0a07;
    --line-soft: #2c241d;
    --highlight: #5a4512;
    --highlight-ink: #ffe9a8;
    --needs-surface: #3d2414;
    --needs-ink: #ffc39b;
    --needs-ledge: #24150b;
    --working-surface: #15283a;
    --working-ink: #a9d6fb;
    --waiting-surface: #362b0e;
    --waiting-ink: #ffe08a;
    --done-surface: #163222;
    --done-ink: #a6ecbb;
    --failed-surface: #3a1621;
    --failed-ink: #f8a9bc;
  --dusk-ink: #c9c4f0;
    --base: 0 4px 0 #0d0a07;
    --floating: 0 10px 32px rgba(0, 0, 0, 0.5);
    --scrim: rgba(0, 0, 0, 0.42);
    --press-primary: #8a7a66;
  --primary-top: var(--ink);
  --seam-primary: #8a7a66;
  --rim-primary: transparent;
  --seam-quiet: #0d0a07;
  --seam-accent: #c9642a;
    --primary-top: var(--ink);
    --seam-primary: #8a7a66;
    --rim-primary: transparent;
    --seam-quiet: #0d0a07;
    --seam-accent: #c9642a;
    --press-quiet: #0d0a07;
    --hi-primary: rgba(255, 255, 255, 0.35);
    --hi-secondary: rgba(255, 255, 255, 0.06);
    --rim: rgba(255, 255, 255, 0.06);
    --drop: 0 7px 12px -4px rgba(0, 0, 0, 0.5);
  --drop-primary: var(--drop);
    --drop-primary: var(--drop);
    --drop-pressed: 0 1px 3px rgba(0, 0, 0, 0.4);
  }
}
:root[data-theme="dark"] {
  --bg: #17120e;
  --bg-deep: #120e0b;
  --surface: #231c16;
  --sunken: #1d1712;
  --surface-raised: #2a221b;
  --surface-sunken: #1d1712;
  --ink: #f6ebdd;
  --ink-soft: #dccbb6;
  --ink-muted: #a8957e;
  --faint: #5a4c3e;
  --user-bubble: #ff8a3d;
  --on-user-bubble: #2b2118;
  --partner-bubble: #2a221b;
  --on-partner-bubble: #f6ebdd;
  --line: #3a3027;
  --line-2: #0d0a07;
  --line-soft: #2c241d;
  --highlight: #5a4512;
  --highlight-ink: #ffe9a8;
  --needs-surface: #3d2414;
  --needs-ink: #ffc39b;
  --needs-ledge: #24150b;
  --working-surface: #15283a;
  --working-ink: #a9d6fb;
  --waiting-surface: #362b0e;
  --waiting-ink: #ffe08a;
  --done-surface: #163222;
  --done-ink: #a6ecbb;
  --failed-surface: #3a1621;
  --failed-ink: #f8a9bc;
  --dusk-ink: #c9c4f0;
  --base: 0 4px 0 #0d0a07;
  --floating: 0 10px 32px rgba(0, 0, 0, 0.5);
  --scrim: rgba(0, 0, 0, 0.42);
  --press-primary: #8a7a66;
  --primary-top: var(--ink);
  --seam-primary: #8a7a66;
  --rim-primary: transparent;
  --seam-quiet: #0d0a07;
  --seam-accent: #c9642a;
  --press-quiet: #0d0a07;
  --hi-primary: rgba(255, 255, 255, 0.35);
  --hi-secondary: rgba(255, 255, 255, 0.06);
  --rim: rgba(255, 255, 255, 0.06);
  --drop: 0 7px 12px -4px rgba(0, 0, 0, 0.5);
  --drop-primary: var(--drop);
  --drop-pressed: 0 1px 3px rgba(0, 0, 0, 0.4);
}

* {
  box-sizing: border-box;
}
html,
body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--md);
  line-height: var(--lh-read);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;
}
button,
input,
textarea {
  font: inherit;
  color: inherit;
}
/* Chinese typography (D78): kinsoku at line start and end, compressed adjacent punctuation, a
   1/4-em gap between CJK and Latin or digits (where the browser can't, autospace.ts inserts a
   U+2005 at display time), and no tracking on CJK. */
:lang(zh) {
  line-break: strict;
  text-spacing-trim: normal;
  text-autospace: normal;
}
/* Titles and asks: 800, rounded CJK (D78), Latin tightened, CJK never. */
.top .name,
.living h2,
.decision .q,
.ask .q,
.hello h1,
.page-title,
.task-head h1,
.task-head .headline,
.sec-title,
.sheet h2,
.pairing h1 {
  font-family: var(--head);
  font-weight: 800;
  text-wrap: balance;
}
/* Balance is for short headings only. A question or an outcome is a sentence: balancing a long
   CJK one cuts it into short ragged lines and splits words ("调 / 用"); it fills the measure
   instead, with no lone last character. */
.decision .q,
.ask .q,
.task-head .headline {
  text-wrap: pretty;
}
:lang(zh) .top .name,
:lang(zh) .living h2,
:lang(zh) .decision .q,
:lang(zh) .ask .q,
:lang(zh) .hello h1,
:lang(zh) .page-title,
:lang(zh) .task-head h1,
:lang(zh) .task-head .headline,
:lang(zh) .sec-title,
:lang(zh) .sheet h2,
:lang(zh) .pairing h1 {
  letter-spacing: 0;
}
button {
  cursor: pointer;
  border: 0;
  background: none;
  padding: 0;
}
a {
  color: inherit;
}
:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

/* One column at most 640 wide, clear of a phone's side insets when it lies on its side (D176). */
#app {
  height: 100%;
  display: flex;
  flex-direction: column;
  width: min(640px, calc(100% - var(--safe-left) - var(--safe-right)));
  margin-left: max(var(--safe-left), calc((100% - 640px) / 2));
}

/* Side by side (D176; wide.ts's WIDE): the conversation on the left, On hand or the opened task
   beside it on a hairline, each pane scrolling on its own. The conversation keeps its reading
   measure (720) centered in its pane; the side pane is a phone's width and a little more, the
   width every On hand and task component was drawn for. */
@media (min-width: 1000px) {
  #app {
    width: auto;
    margin: 0;
    padding-left: var(--safe-left);
    padding-right: var(--safe-right);
  }
}
.panes {
  flex: 1;
  min-height: 0;
  display: flex;
}
.pane {
  display: flex;
  flex-direction: column;
  min-width: 0;
  height: 100%;
  position: relative;
}
.pane.conv {
  flex: 1 1 0;
}
.pane.side {
  flex: 0 0 clamp(400px, 40%, 560px);
  border-left: 1px solid var(--line);
}
.pane.conv > .top,
.pane.conv > .conn,
.pane.conv > .scroll,
.pane.conv > .composer-wrap {
  padding-left: max(16px, calc((100% - 720px) / 2));
  padding-right: max(16px, calc((100% - 720px) / 2));
}
/* The level's name in a pane's header, where a phone has its back button (18/800, the chrome). */
.top .level {
  margin: 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  font-family: var(--head);
  font-size: var(--lg);
  font-weight: 800;
  letter-spacing: -0.2px;
}

/* ---------- header ---------- */
.top {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: calc(var(--safe-top) + 10px) 16px 10px;
  background: var(--bg);
  position: sticky;
  top: 0;
  z-index: 5;
}
.top .who {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
  text-align: left;
}
.top .name {
  font-size: var(--t20);
  letter-spacing: -0.3px;
  line-height: 1.15;
}
.top .sum {
  font-size: var(--sm);
  color: var(--ink-muted);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.top .back {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  min-height: 44px;
  padding-right: 8px;
}
 /* The clay partner (D76, D77): it breathes (3.8 s, from its feet) and the idle face blinks
   (its closed frame for 150 ms, every 3-6 s). Status never animates; reduced motion stills
   it all. Faces cross-fade on a change of state, standing on the box's bottom edge. */
.avatar {
  position: relative;
  display: inline-block;
  flex-shrink: 0;
}
.avatar > * {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  opacity: 0;
  transition: opacity 400ms var(--ease);
}
.avatar > .on {
  opacity: 1;
}
.avatar > img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: 50% 100%;
}
.avatar .idle {
  aspect-ratio: 360 / 324;
}
.avatar .idle img {
  display: block;
  width: 100%;
  height: 100%;
}
.breathe {
  transform-origin: 50% 100%;
  animation: breathe 3.8s ease-in-out infinite;
}
@keyframes breathe {
  0%,
  100% {
    transform: scale(1, 1);
  }
  50% {
    transform: scale(1.012, 1.03);
  }
}
/* How to connect: numbered steps, one per line. */
.accounts .steps {
  white-space: pre-line;
}

/* The blink's closed frame, over the open one: hidden but for a blink. */
.avatar .idle .shut {
  position: absolute;
  inset: 0;
  opacity: 0;
}

.conn {
  margin: 0 16px 6px;
  padding: 8px 12px;
  border-radius: var(--r-md);
  background: var(--waiting-surface);
  color: var(--waiting-ink);
  font-size: var(--sm);
  font-weight: 700;
}

/* ---------- conversation ---------- */
.scroll {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 6px 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
/* Rhythm (D129): a run of one voice stacks 4 apart, other things one voice says 12 apart, 16
   where the turn passes. */
.scroll > .user + :not(.user),
.scroll > :not(.user):not(.when):not(.spacer) + .user {
  margin-top: 4px;
}
.scroll > .join {
  margin-top: -8px;
}
.scroll > .spacer {
  flex: 1;
}
/* The two voices as a messaging app (D129): one body size, at most about 38em wide. */
.user {
  align-self: flex-end;
  max-width: min(80%, var(--bubble-measure));
  background: var(--user-bubble);
  color: var(--on-user-bubble);
  padding: 10px 14px;
  border-radius: var(--bubble);
  font-size: var(--body);
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.user.join {
  border-top-right-radius: var(--bubble-join);
}
.user.pending {
  opacity: 0.65;
}
:lang(zh) .user {
  line-height: 1.7;
}
.partner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  font-size: var(--partner);
  line-height: 1.5;
  max-width: min(88%, var(--bubble-measure));
  overflow-wrap: anywhere;
}
:lang(zh) .partner {
  line-height: 1.7;
}
.partner > .bubble {
  max-width: 100%;
  background: var(--partner-bubble);
  color: var(--on-partner-bubble);
  padding: 10px 14px;
  border-radius: var(--bubble-partner);
}
.partner.join > .bubble:first-child {
  border-top-left-radius: var(--bubble-join);
}
/* What sits under a bubble (the quiet row, a status line, the default) is set in to its text. */
.partner > :not(.bubble):not(.tray):not(.reply):not(.routine-facts):not(.said) {
  margin-left: 14px;
}
.partner p {
  margin: 0 0 0.6em;
}
.partner p:last-child {
  margin-bottom: 0;
}
.partner ul,
.partner ol {
  margin: 0 0 0.6em;
  padding-left: 1.3em;
}
.partner code {
  font-family: var(--mono);
  font-size: 0.86em;
  background: var(--sunken);
  padding: 1px 0.3em;
  border-radius: 6px;
  white-space: nowrap; /* short tokens never break mid-word */
}
.partner code.long {
  white-space: normal;
  overflow-wrap: anywhere;
}
.partner pre {
  font-family: var(--mono);
  font-size: var(--sm);
  line-height: 1.6;
  background: var(--sunken);
  padding: 10px 12px;
  border-radius: 12px;
  overflow-x: auto;
  margin: 0 0 0.6em;
}
.partner pre code {
  background: none;
  padding: 0;
}
.partner h3,
.partner h4 {
  font-size: 1em;
  margin: 0.4em 0;
  font-weight: 800;
}
.footer {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 10px;
}
/* A task in the partner's words, and a line of proof: drawn marks and plain words, no
   capsules (D73). */
.taskline {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 6px;
  font-size: var(--sm);
  text-align: left;
  color: var(--ink-muted);
  max-width: 100%;
}
.taskline .ic {
  display: inline-flex;
  color: var(--ink-muted);
}
.taskline .t {
  font-weight: 700;
  color: var(--ink-soft);
  overflow-wrap: anywhere;
}
.taskline:active .t {
  text-decoration: underline;
}
.status-line.failed {
  color: var(--failed-ink);
}
.status-line {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--sm);
  color: var(--ink-muted);
}
.proof {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  font-size: var(--sm);
  color: var(--ink-muted);
  line-height: 1.45;
}
.mk {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  overflow-wrap: anywhere;
}
.mk svg {
  flex-shrink: 0;
}
/* A passed check's mark is a drawn ✓ in the done ink, never on a tile (D76). */
.mk .ok {
  display: inline-flex;
  color: var(--done-ink);
}
/* A reproduction (the run before the fix) failed on purpose: a quiet ×, muted, never red. */
.mk .repro {
  display: inline-flex;
  color: var(--ink-muted);
}
/* Why an action didn't work stays on the task, in the failed ink. */
.small.fail-line {
  color: var(--failed-ink);
  overflow-wrap: anywhere;
}
.qlink {
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-soft);
  text-align: left;
  overflow-wrap: anywhere;
}
.qlink:active {
  text-decoration: underline;
}
@media (hover: hover), (any-hover: hover) {
  .qlink:hover,
  .taskline:hover .t {
    color: var(--ink);
    text-decoration: underline;
  }
}
.more {
  font-size: var(--xs);
  font-weight: 800;
  color: var(--ink-muted);
}

/* ---------- buttons ---------- */
/* One clay family (D76): primary (ink), secondary (cream on a rim), accent (orange), text
   (flat), icon (a square of any). Heights 36 / 44 / 52, radius 12 / 14 / 18. */
.btn {
  --fill: var(--bg);
  --on: var(--ink);
  --ledge-c: var(--press-quiet);
  --hi: var(--hi-secondary);
  --rim-c: var(--rim);
  --lh: var(--ledge);
  --seam: var(--seam-quiet);
  --fill-top: var(--fill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  min-width: 0;
  padding: 0 20px;
  border-radius: var(--r-btn);
  background: linear-gradient(var(--fill-top), var(--fill));
  color: var(--on);
  font-weight: 700;
  font-size: var(--md);
  line-height: 1.2;
  white-space: nowrap;
  box-shadow: inset 0 1.5px 0 var(--hi), inset 0 0 0 1px var(--rim-c), 0 1px 0 var(--seam), 0 var(--lh) 0 var(--ledge-c), var(--drop);
  transition: transform var(--t-press) var(--ease), box-shadow var(--t-press) var(--ease), filter var(--t-fast) var(--ease);
}
.btn > .lbl {
  overflow: hidden;
  text-overflow: ellipsis;
}
.btn.primary {
  --fill: var(--ink);
  --on: var(--bg);
  --ledge-c: var(--press-primary);
  --hi: var(--hi-primary);
  --rim-c: var(--rim-primary);
  --seam: var(--seam-primary);
  --fill-top: var(--primary-top);
  --drop: var(--drop-primary);
}
.btn.secondary {
  --fill: var(--bg);
  --ledge-c: var(--press-quiet);
}
.btn.accent {
  --fill: var(--accent);
  --on: var(--on-accent);
  --ledge-c: var(--press-accent);
  --hi: var(--hi-accent);
  --rim-c: transparent;
  --seam: var(--seam-accent);
}
.btn.sm {
  height: 36px;
  padding: 0 14px;
  border-radius: var(--r-sm);
  font-size: var(--sm);
}
.btn.lg {
  height: 52px;
  padding: 0 24px;
  border-radius: var(--r-btn-lg);
  font-size: var(--body);
  --lh: 4px;
}
.btn.icon {
  width: 44px;
  padding: 0;
}
.btn.text {
  height: 44px;
  padding: 0 12px;
  border-radius: var(--r-sm);
  color: var(--ink-soft);
  background: transparent;
  box-shadow: none;
}
.btn.text.sm {
  height: 36px;
  padding: 0 10px;
}
.btn:active:not(:disabled):not(.text) {
  transform: translateY(var(--lh));
  box-shadow: inset 0 1.5px 0 var(--hi), inset 0 0 0 1px var(--rim-c), 0 0 0 var(--seam), 0 0 0 var(--ledge-c), var(--drop-pressed);
}
@media (hover: hover), (any-hover: hover) {
  .btn:hover:not(:disabled):not(.text) {
    filter: brightness(1.04);
  }
  .btn.primary:hover:not(:disabled) {
    filter: brightness(1.25);
  }
}
.btn.text:active:not(:disabled),
.btn.text:hover:not(:disabled) {
  background: color-mix(in srgb, var(--ink) 6%, transparent); /* flat: a soft tint only */
}
.btn:disabled {
  opacity: 0.5;
}
.btns {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}
.btns .grow {
  flex: 1;
}
/* A decision's row: Reply… · Hold · Go, primary last. When the Go action is long, Reply… (a
   flat text button) drops to its own line under the pair instead of splitting it; Go's own
   words only shorten when even Hold and Go alone can't share a line. */
.btns.decide {
  flex-wrap: wrap-reverse;
  gap: 10px 12px;
}
.btns.decide .pair {
  display: flex;
  gap: 12px;
  min-width: 0;
  max-width: 100%;
}
.btns.decide .pair .btn.secondary {
  flex-shrink: 0;
}
.btns.decide .pair .btn.primary {
  flex: 0 1 auto;
}
.btns.decide > .btn.text {
  margin-left: -12px;
}

/* ---------- living message and decisions ---------- */
/* The living message has no card (D104): the partner speaking, its asks, a divider when away. */
.living {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.living h2 {
  margin: 0 2px;
  font-size: var(--t20);
  letter-spacing: -0.2px;
  line-height: 1.3;
}
/* The count once, with Go on all defaults at its end. */
.needs-head {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  margin: 0 2px -4px;
  font-size: var(--sm);
  font-weight: 700;
  color: var(--needs-ink);
}
.needs-head > span {
  flex: 1;
}
.needs-head .btn {
  margin-right: -10px;
}
.decision {
  background: var(--needs-surface);
  border-radius: var(--r-lg);
  box-shadow: 0 4px 0 var(--needs-ledge);
  padding: 18px 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  scroll-margin: 90px;
}
.decision.flash {
  animation: flash 1.4s var(--ease);
}
.decision .asker {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-soft);
  text-align: left;
  min-height: 24px;
}
.decision .asker .coin-art {
  flex: none;
  border-radius: 50%;
}
.decision .asker span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.decision .asker:active {
  text-decoration: underline;
}
/* D170 (X1): asked for one of the user's own agents; not a link, so no underline. */
.decision .asker.peer,
.askq .asker.peer {
  color: var(--needs-ink);
}
.askq .asker.peer {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--sm);
  font-weight: 700;
  margin: 0 0 6px 4px;
}
.askq .asker.peer small {
  font-weight: 600;
  color: var(--ink-muted);
}
.askq .dflt .sug {
  font-size: var(--xs);
  font-weight: 800;
  color: var(--needs-ink);
  background: var(--needs-surface);
  border-radius: 6px;
  padding: 1px 7px;
  margin-right: 6px;
}
.decision .asker.peer:active {
  text-decoration: none;
}
.decision .asker.peer small {
  font-weight: 600;
  color: var(--ink-muted);
}
.decision .sug {
  align-self: flex-end;
  font-size: var(--xs);
  font-weight: 800;
  color: var(--needs-ink);
  background: var(--needs-surface);
  border-radius: 6px;
  padding: 1px 7px;
}
/* One quiet line about the user's other agents (D170). */
.peerline {
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 92%;
  font-size: var(--xs);
  color: var(--ink-muted);
  background: var(--surface-sunken);
  border-radius: 999px;
  padding: 3px 12px;
}
.peerline span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.decision .q {
  font-size: var(--t20);
  line-height: 1.35;
  letter-spacing: -0.2px;
}
/* On a phone the question is a sentence read in a card, not a title: one step down (18). */
@media (max-width: 600px) {
  .decision .q,
  .ask .q {
    font-size: var(--lg);
  }
}
:lang(zh) .decision .q {
  line-height: 1.45;
}
.decision .dl {
  font-size: var(--sm);
  color: var(--needs-ink);
  line-height: 1.45;
}
/* D157: a choice that would give the task the user's Chrome says so, in the accent's own weight. */
.decision .dl.widen {
  font-weight: 700;
  color: var(--ink);
}
/* The default as a small timer and one caption (D127), never a bar and the words twice. */
.decision .dl.timer {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.decision .dl.timer span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pie {
  flex: none;
  color: var(--needs-ink);
}
.pie .left {
  fill: var(--accent);
}
/* Secondary on a tinted card: white, standing on the card's own ledge color, no rim. */
.decision .btn.secondary {
  --fill: var(--surface);
  --rim-c: transparent;
  --ledge-c: #e99a65; /* the card's ledge deepened toward its strong tone, as tall-looking as ink */
  --seam: var(--needs-ledge);
}
.decision .btn.text {
  color: var(--needs-ink);
}
.countdown {
  height: 4px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--needs-dot) 22%, transparent);
  overflow: hidden;
}
.countdown i {
  display: block;
  height: 100%;
  background: var(--needs-dot);
  border-radius: 4px;
  transition: width 1s linear;
}
.resolved {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-soft);
  animation: settle 320ms var(--spring);
}
.tick {
  width: 16px;
  height: 16px;
  color: var(--ink-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.reply {
  display: flex;
  gap: 8px;
  align-items: flex-end;
  padding: 6px 6px 6px 14px;
  border-radius: var(--r-md);
  background: var(--surface);
}
.reply textarea {
  flex: 1;
  border: 0;
  background: transparent;
  resize: none;
  padding: 10px 0;
  font-size: var(--body);
  line-height: 1.45;
  outline: none;
  max-height: 120px;
}
.line {
  display: flex;
  gap: 12px;
  align-items: center;
  text-align: left;
  width: 100%;
}
/* A plain mark in muted ink: no tile. */
.line .ic {
  width: 18px;
  height: 18px;
  color: var(--ink-muted);
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.line .tx {
  flex: 1;
  min-width: 0;
  font-size: var(--md);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.line .tx {
  color: var(--ink-soft);
}

/* ---------- composer ---------- */
.composer-wrap {
  padding: 8px 12px calc(var(--safe-bottom) + 10px);
  background: linear-gradient(to bottom, transparent, var(--bg) 30%);
}
.held {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 10px 12px;
  margin-bottom: 10px;
  border-radius: var(--r-md);
  background: var(--failed-surface);
  color: var(--failed-ink);
  font-size: var(--sm);
  font-weight: 700;
}
.held span {
  flex: 1 1 200px;
}
.composer {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  padding: 7px 7px 7px 18px;
  margin-bottom: 4px;
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--base);
}
.composer textarea {
  flex: 1;
  border: 0;
  background: transparent;
  resize: none;
  font-size: var(--body); /* 16px keeps iOS from zooming on focus */
  line-height: 1.45;
  padding: 10px 0;
  outline: none;
  max-height: 140px;
  min-width: 0;
}
.composer textarea::placeholder,
.reply textarea::placeholder {
  color: var(--ink-muted);
}
.send {
  flex-shrink: 0;
}
.send:disabled {
  opacity: 0.45;
}

/* ---------- empty conversation ---------- */
.hello {
  margin: auto 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
  padding: 16px 4px;
  animation: settle 500ms var(--spring);
}
.hello h1 {
  margin: 0;
  font-size: var(--t28);
  letter-spacing: -0.4px;
  line-height: 1.2;
}
.hello p {
  margin: -4px 0 0;
  color: var(--ink-soft);
  font-size: var(--lg);
  line-height: var(--lh-voice);
  text-wrap: pretty;
}
/* What it can do, then its promise: a line each (D149). */
.hello p > span {
  display: block;
}
/* The partner waves once when it appears (two rocks from its feet that settle, and a small hop),
   then leans toward the composer while there are words in it. Reduced motion: still. */
.hello-face {
  display: inline-block;
  transform-origin: 50% 100%;
  animation: hello-wave 1.6s var(--ease) 0.2s backwards;
  transition: transform 480ms var(--spring);
}
.hello-face.leaning {
  transform: rotate(-5deg) translate(4px, 2px);
}
@keyframes hello-wave {
  0% { transform: none; }
  9% { transform: translateY(-8px) rotate(5deg); }
  18% { transform: translateY(-3px) rotate(-6deg); }
  30% { transform: rotate(5deg); }
  45% { transform: rotate(-4deg); }
  62% { transform: rotate(2deg); }
  80% { transform: rotate(-1deg); }
  100% { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hello-face.leaning { transform: none; }
}
.hello-news {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin-top: 2px;
}
.hello-news .bubble {
  background: var(--partner-bubble);
  color: var(--on-partner-bubble);
  padding: 10px 16px;
  border-radius: var(--bubble-partner);
  font-size: var(--partner);
  line-height: 1.5;
  max-width: min(100%, var(--bubble-measure));
  text-align: left;
}
:lang(zh) .hello-news .bubble {
  line-height: 1.7;
}
.hello .try {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 20px;
  text-align: left;
}
.hello .try .grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
@media (max-width: 600px) {
  .hello .try .grid {
    grid-template-columns: minmax(0, 1fr);
  }
  /* A phone: each sentence of the line on one line. */
  .hello p {
    font-size: var(--md);
  }
}
.hello .try .label {
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-muted);
}
.suggest.btn {
  justify-content: flex-start;
  height: auto;
  min-height: 52px;
  padding: 12px 18px;
  border-radius: var(--r-btn-lg);
  font-size: var(--md);
  font-weight: 500; /* a sentence to say, not a command */
  white-space: normal;
  text-align: left;
  line-height: var(--lh-read);
  --lh: 4px;
}

/* ---------- ask cards (notifications) ---------- */
.ask {
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--base);
  padding: 18px 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ask .q {
  font-size: var(--t20);
  line-height: 1.35;
}
.ask .note {
  font-size: var(--sm);
  color: var(--ink-muted);
  line-height: 1.5;
}
.hint {
  font-size: var(--sm);
  color: var(--ink-muted);
  line-height: 1.5;
  padding: 10px 12px;
  border-radius: var(--r-md);
  background: var(--sunken);
}

/* ---------- On hand ---------- */
.section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.page-title {
  margin: 4px 2px 0;
  font-size: var(--t34);
  letter-spacing: -0.5px;
  line-height: 1.15;
}
.section h3 {
  margin: 8px 2px 0;
  min-height: 36px;
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-muted);
  display: flex;
  gap: 8px;
  align-items: center;
}
.section h3 .n {
  font-variant-numeric: tabular-nums;
}
.calm {
  font-size: var(--lg);
  line-height: var(--lh-voice);
  color: var(--ink-soft);
  padding: 4px 2px;
}
.row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px 14px 18px;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--base);
  text-align: left;
  width: 100%;
  min-height: 64px;
}
.row .main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.row .t {
  font-size: var(--body);
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row .m {
  font-size: var(--sm);
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row .chev {
  color: var(--ink-muted);
}

/* ---------- opened task: one column (D74) ---------- */
.task-page {
  gap: 20px;
}
.task-head {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  gap: 6px 16px;
  align-items: center;
}
.task-head .face {
  grid-row: span 2;
  align-self: end;
}
.task-head .head-words {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.task-head h1 {
  margin: 0;
  font-size: var(--t20);
  letter-spacing: -0.2px;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
/* The outcome, said once (D74): its first sentence big, the rest in the partner's voice. */
.task-head .headline {
  grid-column: 1 / -1;
  margin: 8px 0 0;
  font-size: var(--t28);
  letter-spacing: -0.4px;
  line-height: 1.2;
  overflow-wrap: anywhere;
}
:lang(zh) .task-head .headline {
  line-height: 1.3;
}
/* Where it stands, in words in the state's ink: no capsule. */
.standing {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 6px;
  font-size: var(--sm);
  line-height: 1.45;
  color: var(--ink-muted);
}
.standing b {
  font-weight: 800;
}
.standing .when {
  color: var(--ink-muted);
}
.standing svg,
.standing b {
  color: var(--state-ink, var(--ink));
}
.st-needs_you {
  --state-ink: var(--needs-ink);
}
.st-working,
.st-queued {
  --state-ink: var(--working-ink);
}
.st-blocked {
  --state-ink: var(--waiting-ink);
}
.st-done,
.st-done_claimed {
  --state-ink: var(--done-ink);
}
.st-failed,
.st-dropped,
.st-superseded {
  --state-ink: var(--failed-ink);
}
.outcome {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.outcome .said {
  font-size: var(--partner);
  line-height: var(--lh-voice);
  color: var(--ink-soft);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.sec-title {
  margin: 0 2px;
  font-size: var(--t20);
  letter-spacing: -0.2px;
  line-height: 1.3;
}
.meta {
  font-size: var(--sm);
  color: var(--ink-muted);
  line-height: 1.5;
}
.tx-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.tx {
  font-size: var(--md);
  line-height: var(--lh-read);
  overflow-wrap: anywhere;
}
.tx.assistant {
  white-space: pre-wrap;
}
.tx.said {
  color: var(--ink-soft);
  white-space: pre-wrap;
}
.tx.said small,
.tx.note {
  display: block;
  font-size: var(--xs);
  font-weight: 700;
  color: var(--ink-muted);
}
.tx.failed {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--failed-ink);
  font-size: var(--sm);
}
.tx.failed code {
  font-family: var(--mono);
  font-size: var(--xs);
  color: var(--ink-soft);
  padding-left: 19px;
}
.tx.you {
  align-self: flex-end;
  max-width: 85%;
  background: var(--user-bubble);
  color: var(--on-user-bubble);
  padding: 10px 14px;
  border-radius: 18px 18px 6px 18px;
  white-space: pre-wrap;
}
.tx.you small {
  display: block;
  opacity: 0.7;
  font-size: 11px;
  margin-top: 3px;
}
.fold-line {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--sm);
  color: var(--ink-muted);
  text-align: left;
  align-self: flex-start;
  min-height: 32px;
}
.fold-line .chev {
  display: inline-block;
  font-weight: 700;
  transition: transform var(--t-fast) var(--ease);
}
.fold-line.open .chev {
  transform: rotate(90deg);
}
/* What it did (D127): each step one quiet line, a mark, a verb, a one-line summary. */
.steps {
  display: flex;
  flex-direction: column;
}
.step {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 400;
  min-height: 28px;
  min-width: 0;
  font-size: var(--sm);
  line-height: 1.3;
  color: var(--ink-muted);
  text-align: left;
  width: 100%;
}
.step .g {
  flex: none;
  width: 16px;
  height: 16px;
  color: var(--ink-muted);
}
.step b {
  flex: none;
  font-weight: 600;
  color: var(--ink-soft);
}
.step .sum {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.step .sum.code {
  font-family: var(--mono);
  font-size: var(--xs);
  padding: 1px 6px;
  border-radius: 6px;
  background: var(--sunken);
}
.step .times {
  flex: none;
  font-size: var(--xs);
  font-variant-numeric: tabular-nums;
}
.step .chev {
  flex: none;
  font-weight: 700;
  opacity: 0;
  transition: transform var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease);
}
.step:hover .chev,
.step:focus-visible .chev,
.stretch .rows .step.bad {
  width: calc(100% + 4px);
  margin-right: 0;
}
.step.bad .chev,
.step.open .chev {
  opacity: 1;
}
.step.open .chev {
  transform: rotate(90deg);
}
.step.bad {
  padding: 0 8px 0 4px;
  margin: 0 -8px 0 -4px;
  width: calc(100% + 12px);
  border-radius: var(--r-xs);
  background: color-mix(in srgb, var(--failed-surface) 60%, transparent);
}
.step.bad .g,
.step.bad b {
  color: var(--failed-ink);
}
.step.bad .sum {
  color: var(--ink-soft);
}
.step.saved,
.step.note {
  font-size: var(--xs);
}
.step.saved .g {
  color: var(--faint);
}
.step.saved .times {
  color: var(--faint);
}
.step.more .g {
  display: inline-block;
}
.raw {
  margin: 2px 0 6px 24px;
  padding: 8px 12px;
  border-radius: var(--r-xs);
  background: var(--sunken);
  font-family: var(--mono);
  font-size: var(--xs);
  line-height: 1.5;
  color: var(--ink-soft);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.tx.assistant.md {
  white-space: normal;
}
.tx.assistant.md p {
  margin: 0;
}
.tx.assistant.md p + p {
  margin-top: 8px;
}
/* D152: the opened task as the agent tells it. */
.standing .sep {
  color: var(--ink-muted);
}
.standing .who {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.standing .when {
  font-variant-numeric: tabular-nums;
}
.standing .coin-art {
  flex: none;
  border-radius: 50%;
}
.standing .inline-link {
  font-size: var(--sm);
}
/* D157: which computer it runs on; a tap (or a hover) says why there. */
.standing .where-on {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline dotted color-mix(in srgb, currentColor 45%, transparent);
  text-underline-offset: 3px;
}
.where-why {
  margin-top: 2px;
}
/* D157: who and where together: the list grouped by computer, what a move does above Go. */
.switch-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.switch-head {
  display: flex;
  gap: 6px;
  padding-top: 6px;
  font-size: var(--sm);
  color: var(--ink-muted);
}
.switch-head b {
  color: var(--ink-soft, var(--ink));
}
.move-lines {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.move-lines .widen {
  font-weight: 800;
  color: var(--ink);
}
/* A pending ask over the task's composer (D152). */
.ask-dock {
  padding: 8px 16px 0;
  max-height: 55vh;
  overflow-y: auto;
}
/* What you asked: a quiet sunken card, three lines until opened. */
.brief {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 16px;
  border-radius: var(--r-md);
  background: var(--surface-sunken);
  font-size: var(--sm);
  line-height: 1.55;
  color: var(--ink-soft);
}
.brief small {
  font-size: var(--xs);
  font-weight: 700;
  color: var(--ink-muted);
}
.brief-text {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}
.brief.open .brief-text {
  display: block;
}
.brief-foot {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: var(--xs);
  color: var(--ink-muted);
}
.brief-foot .grow {
  flex: 1;
}
.brief-foot .qlink {
  font-size: var(--xs);
  min-height: 28px;
}
.hidden-key {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.hidden-key .g {
  width: 14px;
  height: 14px;
}
/* The agent's voice: the readable layer. */
.voice {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.voice .tx {
  color: var(--ink);
}
.voice .saved {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--xs);
  color: var(--ink-muted);
}
.voice .saved .g {
  width: 14px;
  height: 14px;
  color: var(--faint);
}
/* A stretch of steps: one gist line, its rows under it. */
.stretch {
  display: flex;
  flex-direction: column;
}
.gist {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  max-width: 100%;
  min-height: 32px;
  padding: 0 6px;
  margin: 0 -6px;
  border-radius: var(--r-xs);
  font-size: var(--sm);
  color: var(--ink-muted);
  text-align: left;
}
.gist .g {
  flex: none;
  width: 16px;
  height: 16px;
}
.gist .sum {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
  color: var(--ink-soft);
}
.stretch.underway .gist .sum {
  color: var(--ink);
}
.gist .n {
  flex: none;
  font-variant-numeric: tabular-nums;
}
.gist .errs {
  flex: none;
  font-weight: 600;
  color: var(--failed-ink);
}
.gist .chev,
.step .chev {
  display: inline-flex;
  flex: none;
  transition: transform var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease);
}
.gist .chev .g,
.step .chev .g {
  width: 12px;
  height: 12px;
}
.gist.open .chev {
  transform: rotate(90deg);
}
@media (hover: hover), (any-hover: hover) {
  .gist:hover {
    background: var(--surface-sunken);
  }
}
.spin {
  flex: none;
  width: 12px;
  height: 12px;
  margin: 2px;
  border-radius: 50%;
  border: 1.6px solid var(--faint);
  border-top-color: var(--ink-soft);
  animation: spin 0.9s linear infinite;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .spin {
    animation-duration: 2.4s;
  }
}
.stretch .rows {
  display: flex;
  flex-direction: column;
  padding-left: 22px;
}
.step.quiet .sum {
  color: var(--ink-muted);
}
.step .sum {
  color: var(--ink-soft);
}
.step.quiet .sum,
.step.note .sum {
  color: var(--ink-muted);
}
.step .sum.code {
  flex: 0 1 auto;
}
.step .bad-tag {
  flex: none;
  font-size: var(--xs);
  font-weight: 700;
  color: var(--failed-ink);
}
.outside {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.outside small {
  font-size: var(--xs);
  font-weight: 700;
  color: var(--ink-muted);
}
.outside code {
  font-family: var(--mono);
  font-size: var(--xs);
  color: var(--ink-soft);
  overflow-wrap: anywhere;
}
.details-box .fold-line {
  font-weight: 700;
}
.kv {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px 16px;
  margin: 8px 2px 0;
  font-size: var(--sm);
}
.kv dt {
  color: var(--ink-muted);
}
.kv dd {
  margin: 0;
  color: var(--ink-soft);
  min-width: 0;
  overflow-wrap: anywhere;
}
.kv code {
  display: block;
  font-family: var(--mono);
  font-size: var(--xs);
}

/* ---------- sheets, toasts, pairing ---------- */
.scrim {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  z-index: 20;
  animation: fade 200ms var(--ease);
}
.sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  max-width: 640px;
  margin: 0 auto;
  z-index: 21;
  background: var(--bg);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  box-shadow: var(--floating);
  padding: 10px 16px calc(var(--safe-bottom) + 20px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-height: 88vh;
  overflow-y: auto;
  animation: rise 360ms var(--spring);
}
/* Close is a secondary button, not a full-width bar (tapping outside closes too). */
.sheet > .sheet-close {
  align-self: center;
  min-width: 120px;
}
.sheet .grab {
  width: 40px;
  height: 5px;
  border-radius: 5px;
  background: var(--line);
  align-self: center;
}
/* An iPad or a wide window (D176): a sheet stands in the middle as a card, like an iPad form
   sheet, not pinned to a far-away bottom edge; it has no grab. */
@media (min-width: 700px) and (min-height: 640px) {
  .sheet {
    top: 50%;
    bottom: auto;
    translate: 0 -50%;
    width: calc(100% - 48px);
    border-radius: var(--r-xl);
    padding-top: 20px;
    padding-bottom: 24px;
    max-height: min(88vh, 900px);
  }
  .sheet .grab {
    display: none;
  }
}
.sheet h2 {
  margin: 0;
  font-size: var(--t20);
  line-height: 1.3;
}
.switch {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--base);
  min-height: 52px;
  margin-bottom: 4px;
}
.switch span {
  flex: 1;
  line-height: 1.4;
}
.switch input {
  width: 22px;
  height: 22px;
  accent-color: var(--accent);
}
/* The Settings sheet (D71): compact and calm; sections are plain groups on the paper. */
.partner-head {
  display: flex;
  align-items: center;
  gap: var(--s3);
}
.partner-head .grow {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.name-input {
  flex: 1;
  min-width: 0;
  height: 44px;
  padding: 0 var(--s3);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-family: var(--head);
  font-size: var(--lg);
  font-weight: 800;
}
.set {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}
/* A group's title on the paper, the same as the Mac's (D150). */
.set h3 {
  margin: var(--s4) 4px 0;
  font-family: var(--head);
  font-size: var(--lg);
  font-weight: 800;
  line-height: 1.3;
  color: var(--ink);
}
/* Settings (D150): a list of sections, each a pushed page; the same groups as the Mac. */
.set-page {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}
.set-page.pushed {
  animation: push-in 280ms var(--ease);
}
@keyframes push-in {
  from {
    transform: translateX(24px);
    opacity: 0;
  }
}
.set-hero {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3) var(--s4);
  border-radius: var(--r-xl);
  background: var(--surface-raised);
  box-shadow: var(--base);
  text-align: start;
  color: inherit;
}
.set-hero b {
  display: block;
  font-family: var(--head);
  font-size: var(--t20);
  font-weight: 800;
}
.set-hero small,
.set-row small,
.switch small,
.set-item small {
  display: block;
  margin-top: 2px;
  font-size: var(--sm);
  font-weight: 400;
  line-height: 1.5;
  color: var(--ink-muted);
}
.set-hero .grow,
.set-row .grow {
  flex: 1;
  min-width: 0;
}
.set-card {
  display: flex;
  flex-direction: column;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--base);
  overflow: hidden;
  margin-bottom: 4px;
}
.set-row {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: 68px;
  padding: var(--s2) var(--s4);
  text-align: start;
  color: inherit;
}
.set-row + .set-row,
.set-item + .set-item {
  border-top: 1px solid var(--line-soft);
}
.set-row:active,
.set-hero:active {
  background: var(--surface-sunken);
}
.set-row b {
  font-size: var(--md);
  font-weight: 700;
}
.set-row img {
  flex: none;
  width: 40px;
  height: 40px;
  object-fit: contain;
}
.set-item {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  padding: var(--s3) var(--s4) var(--s4);
}
.set-item b {
  font-size: var(--md);
  font-weight: 700;
}
.set-item small {
  margin-top: -6px;
}
.set-item .set-go {
  align-self: flex-end;
}
.set-back {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 2px;
  min-height: 36px;
  padding: 0 var(--s2) 0 2px;
  border-radius: var(--r-sm);
  font-size: var(--md);
  font-weight: 700;
  color: var(--ink-soft);
}
.set-back .back-chev {
  font-size: 24px;
  line-height: 1;
  margin-top: -2px;
}
.set-back:active {
  background: var(--surface-sunken);
}
.sheet h2.set-title {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-family: var(--head);
  font-size: var(--t28);
}
.set-title img {
  object-fit: contain;
}
.trust-card {
  padding: var(--s4);
  gap: var(--s4);
}
.trust b {
  font-size: var(--md);
  font-weight: 800;
}
.trust.own b {
  color: var(--done-ink);
}
.trust.asks b {
  color: var(--needs-ink);
}
.trust ul {
  margin: var(--s2) 0 0;
  padding: 0 0 0 1.2em;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: var(--md);
  line-height: 1.5;
}
.btns.end {
  justify-content: flex-end;
}
.set .sub,
.set .more {
  margin: var(--s1) 2px 0;
}
/* Choices: a segmented clay control (D76). A sunken track; the chosen one a white surface on a
   2px base, the others muted. */
.seg {
  display: flex;
  gap: 4px;
  padding: 4px;
  border-radius: var(--r-md);
  background: var(--surface-sunken);
}
.seg button {
  /* equal shares while they fit; never narrower than the words */
  flex: 1 1 0;
  min-width: max-content;
  min-height: 40px;
  padding: 0 var(--s2);
  border-radius: var(--r-sm);
  font-size: var(--sm);
  font-weight: 500;
  line-height: 1.3;
  color: var(--ink-muted);
  white-space: nowrap;
  transition: background var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
/* When the words don't fit side by side (Seg measures), the options stack, one per row; a label
   longer than the row wraps inside its own option. */
.seg.stack {
  flex-direction: column;
}
.seg.stack button {
  flex: none;
  min-width: 0;
  padding: 9px var(--s3);
  white-space: normal;
  text-align: start;
  overflow-wrap: anywhere;
}
.seg button.on {
  background: var(--surface);
  color: var(--ink);
  font-weight: 700;
  box-shadow: 0 2px 0 var(--line-2);
}
.quiet-range {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 0 2px;
  color: var(--ink-muted);
  font-size: var(--sm);
}
.quiet-range input {
  flex: 1;
  min-width: 0;
  height: 44px;
  padding: 0 var(--s3);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: var(--md);
}
.noted {
  display: flex;
  flex-direction: column;
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--base);
  margin-bottom: 4px;
}
.noted-row {
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-height: 48px;
  padding: 0 var(--s1) 0 14px;
}
.noted-row + .noted-row {
  border-top: 1px solid var(--line-soft);
}
.noted-row span {
  flex: 1;
  min-width: 0;
  font-size: var(--md);
  line-height: 1.4;
}
/* 它能看的账号 / Accounts it can read (D96): one card, a clay mailbox per connection. */
.acct-row {
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-height: 64px;
  padding: 8px var(--s1) 8px 12px;
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--base);
}
.acct-row .grow {
  flex: 1;
  min-width: 0;
}
.acct-row:has(.acct-remove-ask) {
  flex-wrap: wrap;
}
.acct-remove-ask {
  flex: 1 0 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s1) var(--s2);
  padding: 8px 4px 4px 4px;
  border-top: 1px solid var(--line-soft, var(--line));
  color: var(--ink-soft);
}
.acct-remove-ask .small {
  flex: 1 1 12em;
}
.acct-remove-ask .acts {
  display: flex;
  gap: var(--s1);
  margin-left: auto;
}
.acct-name {
  font-size: var(--md);
  font-weight: 700;
}
.acct-row .sub {
  margin: 2px 0 0;
}
.mailbox {
  flex: none;
}
.small.warn {
  color: var(--failed-ink);
  font-weight: 700;
}
.acct-apps {
  margin: 2px 0 0;
  color: var(--ink-soft);
  font-weight: 600;
}
/* The one tap (D122): oo is signed in. A sunken panel: what it will read, where mail passes, one button. */
.acct-offer {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s4);
  border-radius: var(--r-md);
  background: var(--surface-sunken);
}
.acct-offer-head {
  display: flex;
  align-items: center;
  gap: var(--s3);
}
.acct-offer-head .grow {
  flex: 1;
  min-width: 0;
}
.acct-offer-head .sub {
  margin: 2px 0 0;
}
.acct-offer > .sub {
  margin: 0;
}
.acct-offer-apps {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: var(--s2) var(--s3);
  margin: 0;
  padding: var(--s3) var(--s4);
  border-radius: var(--r-sm);
  background: var(--surface);
  list-style: none;
}
.acct-offer-apps li {
  display: contents;
}
.acct-offer-apps b {
  align-self: baseline;
  font-size: var(--md);
  font-weight: 700;
}
.acct-offer-apps span {
  align-self: baseline;
  min-width: 0;
  overflow: hidden;
  color: var(--ink-soft);
  font-size: var(--sm);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.accounts > .qlink {
  align-self: flex-start;
}
.acct-oo,
.acct-form {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}
.acct-form .row {
  display: flex;
  justify-content: flex-end;
  gap: var(--s2);
}
.acct-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.acct-field input {
  height: 44px;
  min-width: 0;
  padding: 0 var(--s3);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: var(--md);
}
/* D158: the key field, Show beside it; a missing key marks the field in the failed ink. */
.acct-key {
  display: flex;
  align-items: center;
  gap: var(--s2);
}
.acct-key input {
  flex: 1;
}
.acct-field input.wrong {
  border-color: var(--failed-ink);
}
.acct-key .qlink {
  flex: none;
  min-height: 44px;
  padding: 0 var(--s1);
}
/* OOMOL Hosted's three steps, each with the page it needs. */
.acct-steps {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  margin: 0;
  padding: var(--s3) var(--s3) var(--s3) calc(var(--s3) + 1.4em);
  border-radius: var(--r-sm);
  background: var(--surface-sunken);
  font-size: var(--md);
  line-height: 1.45;
}
.acct-steps li > span {
  display: block;
}
.acct-steps li > a {
  display: inline-flex;
  margin-top: 6px;
}
.acct-steps li::marker {
  color: var(--ink-soft);
  font-weight: 700;
}
.acct-steps a.btn,
.acct-refusal a.btn {
  text-decoration: none;
}
/* A refusal: the failed look, never the done look. */
.acct-refusal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  padding: 8px 8px 8px 12px;
  border-radius: var(--r-md);
  background: var(--failed-surface);
  color: var(--failed-ink);
  font-size: var(--sm);
  font-weight: 700;
  line-height: 1.4;
}
.acct-refusal .grow {
  flex: 1 1 12em;
  min-width: 0;
}
.acct-refusal-mark {
  flex: none;
  width: 1em;
  text-align: center;
  font-size: var(--md);
}
.acct-empty {
  margin: 2px 0 0;
  color: var(--ink-soft);
  font-weight: 700;
}
.toasts {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--safe-bottom) + 84px);
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
  padding: 0 16px;
}
.toast {
  pointer-events: auto;
  max-width: 100%;
  background: var(--ink);
  color: var(--bg);
  padding: 10px 16px;
  border-radius: var(--r-md);
  box-shadow: 0 4px 0 #000;
  font-size: var(--sm);
  font-weight: 700;
  display: flex;
  gap: 12px;
  align-items: center;
  animation: rise 300ms var(--spring);
}
.toast button {
  color: var(--accent);
  font-weight: 800;
}
.pairing {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 16px;
  padding: calc(var(--safe-top) + 24px) 20px calc(var(--safe-bottom) + 24px);
}
.pairing .face {
  align-self: center;
}
.pairing h1 {
  margin: 0;
  font-size: var(--t28);
  line-height: 1.2;
  text-align: center;
}
.pairing p {
  margin: 0;
  color: var(--ink-soft);
  line-height: var(--lh-read);
}
.pairing code {
  font-family: var(--mono);
  font-size: 0.86em;
  background: var(--sunken);
  padding: 1px 6px;
  border-radius: 6px;
}
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.field label {
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-muted);
}
.field input {
  height: 52px;
  border-radius: var(--r-sm);
  border: 2px solid var(--line-2);
  background: var(--surface);
  padding: 0 14px;
  font-size: 20px;
  font-family: var(--mono);
  letter-spacing: 2px;
  text-transform: uppercase;
}
.err {
  color: var(--failed-ink);
  background: var(--failed-surface);
  padding: 10px 12px;
  border-radius: var(--r-md);
  font-size: var(--sm);
  font-weight: 700;
  line-height: 1.5;
}
.small {
  font-size: var(--sm);
  color: var(--ink-muted);
  line-height: 1.5;
}

@keyframes settle {
  from {
    transform: translateY(8px) scale(0.985);
    opacity: 0.35;
  }
}
@keyframes rise {
  from {
    transform: translateY(24px);
    opacity: 0;
  }
}
@keyframes fade {
  from {
    opacity: 0;
  }
}
/* Found you: a one-time deepening of the card's own tint, never a glow ring. */
@keyframes flash {
  0%,
  100% {
    background: var(--needs-surface);
  }
  30% {
    background: color-mix(in srgb, var(--needs-surface) 70%, var(--needs-dot));
  }
}
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ---------- the quiet conversation (D104) ---------- */
/* A messaging app's time line: small, centered, muted; the away divider is one too. */
.when {
  align-self: center;
  margin: 12px 0 0;
  font-size: var(--xs);
  color: var(--ink-muted);
  letter-spacing: 0.2px;
  font-variant-numeric: tabular-nums;
}
:lang(zh) .when {
  letter-spacing: 0;
}
.living > .when {
  margin-bottom: 0;
}
/* The one quiet row under a message: Merge into main, Details. Text buttons, 13, no fill. */
.qrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 16px;
  margin-top: 4px;
}
.tb {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 32px;
  font-size: var(--sm);
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink-muted);
  text-align: left;
}
.tb.act {
  font-weight: 700;
  color: var(--ink);
}
.tb .chev {
  transition: transform var(--t-fast) var(--ease);
}
.tb[aria-expanded="true"] .chev {
  transform: rotate(90deg);
}
@media (hover: hover), (any-hover: hover) {
  .tb:hover {
    color: var(--ink);
  }
}
.tb:active {
  text-decoration: underline;
}
.qs {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 32px;
  font-size: var(--sm);
  color: var(--ink-muted);
}
.qs.done {
  color: var(--done-ink);
  font-weight: 700;
}
/* Details, open in place: the same quiet lines as before, set in from a hairline. */
.det {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 2px 0 2px;
  padding: 4px 0 4px 14px;
  box-shadow: inset 1.5px 0 0 var(--line);
}
.det.lines {
  gap: 4px;
}
/* An ask (D129): the question in the partner's bubble, one compact tray under it (Reply… · Hold
   as quiet text, Go last and named by the action), the default as one small grey line; once
   answered, a tiny line on the user's side in their own words. */
.partner.askq {
  max-width: 100%;
  align-self: stretch;
}
.askq > .bubble,
.askq > .tray,
.askq > .reply,
.askq > .routine-facts {
  max-width: min(88%, var(--bubble-measure));
}
.askq > .tray {
  align-self: stretch;
  width: min(88%, var(--bubble-measure));
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  padding: 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: 0 3px 0 var(--line);
}
.askq > .tray .grow {
  flex: 1;
}
.askq > .tray .btn.text {
  font-weight: 600;
  color: var(--ink-soft);
}
.askq .dflt {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 12px;
  font-size: var(--xs);
  line-height: 1.45;
  color: var(--ink-muted);
}
.askq .dflt .tb {
  min-height: 24px;
  font-size: var(--xs);
}
.askq > .said {
  align-self: flex-end;
  max-width: 72%;
  margin-right: 8px;
  font-size: var(--sm);
  line-height: 1.4;
  color: var(--ink-muted);
  text-align: right;
}
.det .its {
  font-size: var(--sm);
  line-height: 1.5;
  color: var(--ink-muted);
}
.askq.flash {
  animation: flash 1.4s var(--ease);
  border-radius: var(--r-sm);
}
.gather {
  margin-top: -4px;
}
/* While the user waits: the clay partner where its words will appear, one line beside it. */
.presence {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 40px;
  margin-top: 12px;
}
.presence .pline {
  padding-top: 7px;
  font-size: var(--md);
  color: var(--ink-muted);
  line-height: 1.4;
}
.presence .sub {
  display: block;
  font-size: var(--sm);
}
/* Character may move; status never blinks (D77): the partner bobs while it works. */
.presence .bob {
  display: inline-flex;
  transform-origin: 50% 100%;
  animation: bob 1.4s ease-in-out infinite;
}
@keyframes bob {
  0%,
  100% {
    transform: translateY(0) rotate(0);
  }
  30% {
    transform: translateY(-2px) rotate(-3deg);
  }
  65% {
    transform: translateY(0) rotate(2deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .presence .bob {
    animation: none;
  }
}
/* What it thinks with, and who does the tasks (D89): an AI agent's row (its clay token, its
   name, one line) and a task's Switch who does it list. */
.agent {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: 56px;
  padding: var(--s2) var(--s1);
}
.agent + .agent {
  border-top: 1px solid var(--line-soft);
}
.agent .coin-art.generic.off img {
  opacity: 0.45;
  filter: grayscale(1);
}
.agent .grow,
.cand .grow {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  text-align: left;
}
.agent b,
.cand b {
  font-size: var(--md);
  font-weight: 800;
}
.agent small,
.cand small {
  font-size: var(--sm);
  color: var(--ink-muted);
  line-height: 1.45;
}
.agent small.paid {
  color: var(--needs-ink);
  font-weight: 700;
}
.switch-list {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  margin-top: var(--s2);
}
.cand {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: 56px;
  padding: var(--s2) var(--s3);
  border-radius: var(--r-md);
  background: var(--bg);
  box-shadow: 0 3px 0 var(--line);
  color: var(--ink);
}
.cand.on {
  box-shadow: 0 3px 0 var(--line), inset 0 0 0 2px var(--ink);
}
.cand.off {
  opacity: 0.55;
}
.cand.off .coin-art.generic img {
  filter: grayscale(1);
}
.cand .now {
  flex: none;
  font-weight: 700;
}
.agent input {
  flex: none;
  width: 22px;
  height: 22px;
  accent-color: var(--accent);
}
/* A quiet link inside a line of Details (Switch who does it): words, no button shape. */
.inline-link {
  display: block;
  margin-top: var(--s1);
  padding: 0;
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-soft);
  text-align: left;
}
.inline-link:hover {
  color: var(--ink);
  text-decoration: underline;
}

/* ---------- work over time (D112–D115) ---------- */
/* What a wait waits for: a small clay thing in a cream bubble. Still; only the partner breathes (D77). */
.wait-bub {
  position: relative;
  flex: none;
  width: 40px;
  height: 36px;
  border-radius: 50%;
  background: var(--surface-raised);
  box-shadow: 0 2px 0 var(--line-2);
  display: grid;
  place-items: center;
}
.wait-bub img {
  width: 26px;
  height: 26px;
  object-fit: contain;
}
.wait-bub::after {
  content: "";
  position: absolute;
  left: -3px;
  bottom: -1px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--surface-raised);
  box-shadow: 0 1px 0 var(--line-2);
}
.task-head .face {
  position: relative;
}
.wait-bub.lg {
  position: absolute;
  right: -14px;
  top: -10px;
  width: 46px;
  height: 40px;
}
.wait-bub.lg img {
  width: 30px;
  height: 30px;
}
.task-head .waitline {
  margin: 2px 0 0;
  font-size: var(--body);
  color: var(--ink);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.task-head .waitline span {
  font-size: var(--sm);
  color: var(--ink-muted);
}
/* The try strip: one pebble per try, the current one hollow (D113). */
.beads {
  display: flex;
  gap: 6px;
  margin: 4px 0 2px;
}
.bd {
  width: 22px;
  height: 18px;
  border-radius: 50% 50% 46% 46%;
  display: inline-grid;
  place-items: center;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  font-style: normal;
  color: var(--ink-muted);
  background: radial-gradient(circle at 35% 30%, var(--surface), var(--surface-sunken) 70%, var(--line-2));
  box-shadow: 0 2px 0 var(--line-2);
  transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
.bd.v-worse {
  color: var(--failed-ink);
}
.bd.v-met {
  color: var(--done-ink);
}
.bd.cur {
  background: transparent;
  box-shadow: inset 0 0 0 2px var(--line-2);
}
.trystrip {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.trystrip .try {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 72px;
  max-width: 120px;
}
.trystrip .bd {
  width: 34px;
  height: 28px;
  font-size: 14px;
}
.trystrip b {
  font-size: var(--sm);
}
.trystrip span {
  font-size: var(--xs);
  color: var(--ink-muted);
  text-align: center;
  overflow-wrap: anywhere;
}
.kv .k {
  color: var(--ink-muted);
}
.kv .v {
  color: var(--ink-soft);
  min-width: 0;
  overflow-wrap: anywhere;
}
.kv .sub {
  display: block;
  color: var(--ink-muted);
  font-size: var(--xs);
  font-variant-numeric: tabular-nums;
}
.kv code.check {
  display: block;
  font-family: var(--mono);
  font-size: var(--xs);
  background: var(--sunken);
  border-radius: 8px;
  padding: 6px 8px;
  overflow-x: auto;
}
.routine-facts {
  margin: 4px 0 8px;
}
/* Routines: a shelf at the bottom of On hand (D115). */
.section.shelf {
  border-top: 1px dashed var(--line-2);
  padding-top: 16px;
}
.row.routine .m {
  white-space: normal;
}
.row.routine.paused .t {
  color: var(--ink-muted);
}
.clockface {
  flex: none;
  width: 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.clockface img {
  width: 30px;
  height: 30px;
  object-fit: contain;
}
.clockface b {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--ink-soft);
}
/* Time, drawn (D115): a wait's deadline groove, Ducter sitting at now. */
.groove-track {
  display: block;
  position: relative;
  height: 30px;
  margin: 4px 10px 0 0;
}
.groove-track .groove,
.groove-track .gone {
  position: absolute;
  left: 0;
  top: 15px;
  height: 8px;
  border-radius: 8px;
}
.groove-track .groove {
  right: 0;
  background: var(--sunken);
  box-shadow: inset 0 1px 2px rgba(43, 33, 24, 0.12);
}
.groove-track .gone {
  background: var(--waiting-surface);
}
.groove-track .who {
  position: absolute;
  top: -2px;
  width: 26px;
  height: 26px;
  margin-left: -13px;
}
.groove-track .who img {
  width: 26px;
  height: 26px;
  object-fit: contain;
}
.groove-track .end {
  position: absolute;
  right: -3px;
  top: 11px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 2px 0 var(--line-2), inset 0 0 0 2px var(--line-2);
}
.groove-track.big {
  height: 40px;
}
.groove-track.big .groove,
.groove-track.big .gone {
  top: 22px;
  height: 10px;
}
.groove-track.big .who {
  width: 36px;
  height: 36px;
  margin-left: -18px;
}
.groove-track.big .who img {
  width: 36px;
  height: 36px;
}
.groove-track.big .end {
  top: 18px;
  width: 18px;
  height: 18px;
}
.tcap {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: var(--xs);
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}
/* One strip for every routine: today an ink mark at the left, a clay bead per run, its date under it. */
.runstrip {
  display: block;
  position: relative;
  height: 40px;
  margin: 8px 12px 2px 2px;
  max-width: 360px;
}
.runstrip .line {
  position: absolute;
  left: 0;
  right: 0;
  top: 9px;
  height: 4px;
  border-radius: 4px;
  background: var(--sunken);
}
.runstrip .nowmark {
  position: absolute;
  left: 0;
  top: 2px;
  width: 3px;
  height: 18px;
  border-radius: 2px;
  background: var(--ink-soft);
}
.runstrip .rb {
  position: absolute;
  top: 2px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.runstrip .rb i {
  display: block;
  width: 18px;
  height: 16px;
  border-radius: 50% 50% 46% 46%;
  background: radial-gradient(circle at 35% 30%, #ffc89a, var(--accent) 70%, #c9642a);
  box-shadow: 0 2px 0 #c9642a;
}
.runstrip .rb em {
  font-style: normal;
  font-size: 11px;
  color: var(--ink-muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.row .m.cap {
  margin-top: 2px;
  white-space: normal;
}
.clk {
  flex: none;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
}
.clk img {
  width: 32px;
  height: 32px;
  object-fit: contain;
}
/* How it checks: the mechanism, folded, for people who want it. */
details.how {
  border-top: 1px dashed var(--line-2);
  padding-top: 10px;
}
details.how summary {
  cursor: pointer;
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-muted);
}
.routine-facts {
  grid-template-columns: max-content 1fr;
}
:lang(zh) .routine-facts .v {
  line-break: strict;
}

/* The moment a wait comes true (D115): the bubble pops, the card springs up into Working.
   Reduced motion: a crossfade. */
.row.arrived {
  position: relative;
  animation: arrive 560ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
@keyframes arrive {
  from {
    transform: translateY(56px) scale(0.98);
    opacity: 0.4;
  }
}
.pop-bub {
  position: absolute;
  left: 14px;
  top: 50%;
  width: 40px;
  height: 36px;
  margin-top: -18px;
  border-radius: 50%;
  background: var(--surface-raised);
  box-shadow: 0 2px 0 var(--line-2);
  animation: pop 320ms ease-out both;
  pointer-events: none;
}
@keyframes pop {
  to {
    transform: scale(1.4);
    opacity: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .row.arrived {
    animation: arrive-fade 300ms ease-out both;
  }
  .pop-bub {
    display: none;
  }
}
@keyframes arrive-fade {
  from {
    opacity: 0;
  }
}
/* The groove's captions sit by time: "now" under Ducter. */
.tcap {
  position: relative;
}
.tcap .tnow {
  position: absolute;
  transform: translateX(-50%);
  white-space: nowrap;
}

/* A keep-going loop's goal (D115, legible): clay lights for checks, or a flag to climb to. */
.goal {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 6px 0 2px;
}
.goal .cap {
  font-size: var(--sm);
  color: var(--ink-soft);
}
.goal.lights .row-of {
  display: flex;
  gap: 4px;
  align-items: flex-end;
}
.goal.lights img {
  width: 20px;
  height: 24px;
  object-fit: contain;
}
.goal.lights.big img {
  width: 32px;
  height: 38px;
}
ol.tries {
  margin: 4px 0 0;
  padding-left: 0;
  list-style: none;
  font-size: var(--sm);
  color: var(--ink-muted);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
ol.tries b {
  color: var(--ink-soft);
  font-weight: 700;
}
/* A routine's next run on a clay tear-off calendar. */
.cal-badge {
  position: relative;
  flex: none;
  width: 46px;
  height: 52px;
  display: block;
}
.cal-badge img {
  width: 46px;
  height: 52px;
  object-fit: contain;
}
.cal-badge b {
  position: absolute;
  left: 3px;
  right: 9px;
  top: 17px;
  text-align: center;
  font-size: 17px;
  line-height: 1;
  font-weight: 800;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.cal-badge em {
  position: absolute;
  left: 3px;
  right: 9px;
  top: 35px;
  text-align: center;
  font-style: normal;
  font-size: 10px;
  line-height: 1;
  color: var(--ink-muted);
}
.cal-badge.big {
  width: 64px;
  height: 72px;
}
.cal-badge.big img {
  width: 64px;
  height: 72px;
}
.cal-badge.big b {
  top: 23px;
  right: 12px;
  font-size: 24px;
}
.cal-badge.big em {
  top: 49px;
  right: 12px;
  font-size: 12px;
}
.when-cal {
  display: flex;
  gap: 12px;
  align-items: center;
}

/* Nothing countable: Ducter at work and the latest try in one line (D115). */
.goal.plain {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}
.goal.plain .worker {
  width: 26px;
  height: 26px;
  object-fit: contain;
}
.goal.plain.big .worker {
  width: 40px;
  height: 40px;
}
/* D78 line breaking for titles that wrap: Latin words and short Chinese words stay whole, breaks
   prefer spaces and punctuation, and two-line titles are balanced. */
.task-head h1,
.task-head .waitline,
.decision .q {
  word-break: keep-all;
  overflow-wrap: anywhere;
  line-break: strict;
  text-wrap: balance;
}
/* A question is a sentence in a bubble: it fills the measure (D78), never balanced. */
.partner > .bubble {
  line-break: strict;
  text-wrap: pretty;
}

/* ---------- 开一件事 / New task (D128): a quiet ＋ on On hand, a bottom sheet ---------- */
.top .plus {
  width: 44px;
  height: 44px;
  border-radius: var(--pill);
  display: grid;
  place-items: center;
  color: var(--ink);
  flex: none;
}
.top .plus:hover,
.top .plus:active {
  background: var(--surface-sunken);
}
.sheet.newtask {
  gap: var(--s4);
}
.sheet.newtask h2 {
  margin-top: 2px;
}
.nt-row {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}
.nt-row h3 {
  margin: 0;
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-muted);
}
.nt-row .chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}
.nt-row .chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  max-width: 100%;
  padding: 0 14px;
  border-radius: var(--r-sm);
  background: var(--surface-sunken);
  color: var(--ink-soft);
  font-size: var(--md);
}
.nt-row .chip b {
  font-weight: 700;
  white-space: nowrap;
}
.nt-row .chip.on {
  background: var(--surface);
  color: var(--ink);
  box-shadow: inset 0 0 0 1.5px var(--ink);
}
.nt-row .chip code {
  font-family: var(--mono);
  font-size: var(--xs);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.nt-row .chip .dot {
  color: var(--faint);
}
.nt-row .chip svg {
  transform: rotate(90deg);
  width: 12px;
  height: 12px;
  color: var(--ink-muted);
  flex: none;
}
.nt-row .chip.coin {
  padding-left: 7px;
}
.nt-row .chip.off {
  opacity: 0.55;
}
.nt-row .chip.off .coin-art.generic img {
  filter: grayscale(1);
}
/* 推荐 / Suggested: the best fit's small tag, on its coin. */
.nt-row .chip .suggested {
  font-size: var(--xs);
  font-weight: 700;
  line-height: 1;
  padding: 4px 7px;
  border-radius: 6px;
  background: var(--highlight);
  color: var(--highlight-ink);
  white-space: nowrap;
}
.nt-row .branches {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--s2);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--base);
  max-height: 240px;
  overflow-y: auto;
}
.nt-row .branches > small {
  font-size: var(--xs);
  font-weight: 700;
  color: var(--ink-muted);
  padding: 4px 10px;
}
.nt-row .branches button {
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-height: 40px;
  padding: 0 10px;
  border-radius: var(--r-sm);
  text-align: left;
}
.nt-row .branches button code {
  flex: 1;
  min-width: 0;
  font-family: var(--mono);
  font-size: var(--sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nt-row .branches button small {
  font-size: var(--xs);
  color: var(--ink-muted);
}
.nt-row .branches button.on {
  background: var(--surface-sunken);
}
.nt-row textarea {
  width: 100%;
  min-height: 112px;
  resize: none;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--surface);
  padding: 12px 14px;
  font-size: var(--body);
  line-height: var(--lh-read);
  color: var(--ink);
}
.nt-row textarea::placeholder {
  color: var(--ink-muted);
}
.nt-row textarea:focus {
  outline: none;
  border-color: var(--accent);
}
.nt-err {
  color: var(--failed-ink);
  font-size: var(--sm);
  line-height: 1.45;
}
.sheet.newtask .btns {
  flex-wrap: nowrap;
}

/* D142: a folder task's Changes (a folder that isn't a git repo). */
.folder-changes .said { margin: 0 0 4px; }
.folder-changes .btns { margin-top: 10px; }
.folder-changes .confirm { margin-top: 10px; padding: 12px 14px; background: var(--surface); border-radius: 14px; box-shadow: 0 3px 0 var(--line-soft); }
.folder-list { list-style: none; margin: 10px 0 0; padding: 0; background: var(--surface); border-radius: 14px; box-shadow: 0 3px 0 var(--line-soft); overflow: hidden; }
.folder-list li { display: flex; align-items: center; gap: 10px; padding: 9px 14px; font-size: 14px; border-top: 1px solid var(--line-soft); }
.folder-list li:first-child { border-top: 0; }
.folder-list .mono-ish { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.folder-list li .qlink { flex: none; }

/* An AI agent's clay coin (coin.tsx). While that agent works a soft light turns a quarter of
   the way round its rim (the sheen layer never covers the print); while it waits on you the coin
   bobs. Clay may move, status never (D77); reduced motion stops both. */
.coin-art { position: relative; display: inline-block; flex: none; line-height: 0; }
.coin-art img { display: block; width: 100%; height: 100%; }
.coin-art .sheen { position: absolute; inset: 0; opacity: 0; pointer-events: none; animation: coin-sweep 4.2s ease-in-out infinite; }
.coin-art.m-needs_you { animation: coin-bob 2.6s ease-in-out infinite; }
@keyframes coin-sweep {
  0% { transform: rotate(-30deg); opacity: 0; }
  30% { opacity: 1; }
  65% { transform: rotate(60deg); opacity: 0; }
  100% { transform: rotate(60deg); opacity: 0; }
}
@keyframes coin-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-2px); }
}
/* In the dark an unavailable coin's pale veil would read as lit: a second veil of the page's own
   colour lies over the whole coin (never a fade of the print itself). */
:root[data-theme="dark"] .coin-art.off::after { content: ""; position: absolute; inset: 1%; border-radius: 50%; background: var(--bg); opacity: 0.5; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .coin-art.off::after { content: ""; position: absolute; inset: 1%; border-radius: 50%; background: var(--bg); opacity: 0.5; }
}
@media (prefers-reduced-motion: reduce) {
  .coin-art .sheen,
  .coin-art.m-needs_you { animation: none; }
}
/* 你的设备 / Your devices (D148): one card per device; its name renamed in place, a quiet clay
   dot when it's behind, the update's step in words, Disconnect at the bottom. */
.dev-name {
  min-width: 0;
  padding: 0;
  font-family: var(--head);
  font-size: var(--lg);
  font-weight: 800;
  color: var(--ink);
  text-align: start;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
button.dev-name {
  cursor: text;
}
.dev-edit {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
}
.dev-input {
  height: 40px;
  padding: 0 var(--s2);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-family: var(--head);
  font-size: var(--lg);
  font-weight: 800;
}
.dev-phase {
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-soft);
}
.dev-phase.done {
  color: var(--done-ink);
}
.dev-phase.failed {
  color: var(--failed-ink);
}
.dev-bar {
  height: 4px;
  max-width: 220px;
  border-radius: 2px;
  background: var(--line-2);
  overflow: hidden;
}
.dev-bar i {
  display: block;
  height: 4px;
  border-radius: 2px;
  background: var(--accent);
}
.dev-cut {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: var(--s1);
  padding: var(--s2) var(--s3);
  border-radius: var(--r-sm);
  background: var(--bg);
}
.dev-cut-q {
  font-size: var(--sm);
  font-weight: 800;
}
/* Nothing in a long sheet is squeezed: it scrolls instead (D150). */
.sheet > * {
  flex-shrink: 0;
}
/* ---------- D151: signing in to a site, and the live view of Ducter's browser ---------- */
.signin-why { display: flex; gap: 8px; align-items: flex-start; font-size: var(--sm); line-height: 1.5; color: var(--ink-soft); }
.signin-why svg { flex: none; margin-top: 2px; color: var(--ink-muted); }
.askq.signin > .signin-why { padding: 2px 4px 0; }
.askq.signin > .tray, .askq.signin > .said { margin-top: 2px; }
.live { position: fixed; inset: 0; z-index: 60; display: flex; flex-direction: column; background: var(--bg); padding: env(safe-area-inset-top) var(--safe-right) env(safe-area-inset-bottom) var(--safe-left); }
.live-top, .live-bottom { flex: none; display: flex; align-items: center; gap: 10px; padding: 8px 12px; }
.live-top { min-height: 56px; border-bottom: 1px solid var(--line-soft); }
.live-where { flex: 1; min-width: 0; text-align: center; }
.live-host { font-weight: 800; font-size: var(--md); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-sub { display: flex; align-items: center; justify-content: center; gap: 5px; font-size: var(--xs); color: var(--ink-muted); }
.live-sub svg { flex: none; }
.live-page { position: relative; flex: 1; min-height: 0; overflow: hidden; display: flex; align-items: flex-start; justify-content: center; background: var(--sunken); }
.live-page img { display: block; max-width: 100%; max-height: 100%; object-fit: contain; touch-action: none; user-select: none; -webkit-user-select: none; background: #fff; }
.live-wait { margin: auto; color: var(--ink-muted); font-size: var(--sm); }
/* Takes the keyboard (a phone's too) without showing: what it gets goes to the page and is cleared. */
.live-keys { position: absolute; left: 0; bottom: 0; width: 1px; height: 1px; opacity: 0; border: 0; padding: 0; font-size: 16px; }
.live-bottom { border-top: 1px solid var(--line-soft); min-height: 72px; }
.live-bottom .btns { flex: 1; display: flex; gap: 10px; }
.live-bottom .btns .btn { flex: 1; }
/* D154: Try it says what this is beside Done. */
.live-note { flex: 1; min-width: 0; font-size: var(--sm); line-height: 1.45; color: var(--ink-soft); }
.live-note + .btns { flex: none; }
.dev-try { display: flex; align-items: center; gap: var(--s3); }
.dev-try > .small { flex: 1; min-width: 0; }
/* D151: 上网 on a server in the device card (Ducter's own browser, its signed-in sites). */
.dev-web { display: flex; flex-direction: column; gap: var(--s2); margin-top: var(--s2); }
.dev-web > .btn { align-self: flex-start; }
.dev-sub { font-size: var(--xs); font-weight: 800; color: var(--ink-muted); }
.dev-note { font-size: var(--sm); line-height: 1.5; color: var(--ink-soft); padding: var(--s2) var(--s3); border-radius: var(--r-sm); background: var(--bg); }
.dev-cmd { display: block; font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 12px; padding: var(--s2) var(--s3); border-radius: var(--r-sm); background: var(--sunken); overflow-wrap: anywhere; user-select: all; }
.dev-site { display: flex; align-items: center; gap: var(--s3); padding: var(--s2) var(--s3); border-radius: var(--r-sm); background: var(--bg); }
.dev-site-what { flex: 1; min-width: 0; }
.dev-site-name { font-size: var(--sm); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- D161: the device card as a character sheet (design/prototypes/device-card.html) ---------- */
.plist { display: flex; flex-direction: column; padding: 6px; border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--base); }
.li-row { display: flex; align-items: center; gap: 10px; height: 56px; padding: 0 10px; border: 0; border-radius: 14px; background: none; color: inherit; font: inherit; text-align: start; cursor: pointer; }
.li-row:active { background: var(--sunken); }
.li-row img { flex: none; width: 36px; height: 32px; object-fit: contain; }
.li-row .t { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.li-row .t b { font-size: var(--md); overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.li-row .t small { flex: none; font-size: var(--sm); color: var(--ink-muted); }
.li-row .t small.working { color: var(--working-ink); }
.li-row .t small.asleep { color: var(--dusk-ink); }
.li-row .t small.away { color: var(--failed-ink); }
.li-row .t .dot { flex: none; align-self: center; width: 8px; height: 8px; border-radius: 4px; background: var(--accent); }
.li-row .chev { flex: none; color: var(--faint); font-weight: 800; }

.dc { display: flex; flex-direction: column; padding: 4px 18px 16px; border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--base); }
.dc-hero { position: relative; height: 146px; display: flex; justify-content: center; align-items: flex-end; }
.dc-hero .ground { position: absolute; bottom: 6px; left: 50%; width: 200px; height: 36px; margin-left: -100px; border-radius: 50%; background: radial-gradient(closest-side, var(--line), var(--sunken) 70%, transparent); }
.dc-hero .art { position: relative; width: 128px; margin-bottom: 14px; filter: drop-shadow(0 6px 5px rgb(60 50 20 / 0.16)); }
.dc-hero .art.tall { width: 64px; }
.dc-hero .art.grey { filter: grayscale(0.7) opacity(0.7); }
.dc-hero .mist { position: absolute; inset: 30% 18% 4%; border-radius: 50%; background: radial-gradient(closest-side, rgb(255 255 255 / 0.75), transparent); }
.dc-hero .float { animation: dc-float 5.6s ease-in-out infinite; }
.dc-hero .drift { animation: dc-drift 11s ease-in-out infinite; }
.dc-hero .blanket { animation: dc-blanket 4.8s ease-in-out infinite; transform-origin: 50% 100%; }
@keyframes dc-float { 50% { transform: translateY(-5px); } }
@keyframes dc-drift { 50% { transform: translateX(4px); } }
@keyframes dc-blanket { 50% { transform: scaleY(1.045); } }
.dc-name { display: flex; justify-content: center; margin-top: 2px; }
.dc-name .dev-name { position: relative; padding: 2px 10px; border: 0; border-radius: 10px; background: none; font-size: 26px; text-align: center; overflow: visible; white-space: normal; overflow-wrap: anywhere; text-wrap: balance; max-width: 100%; }
.dc-name button.dev-name:active { background: var(--sunken); }
/* The pencil beside a name that renames in place: always there, quiet, so the name reads as editable
   on a phone too (no hover there); full ink on hover. Drawn by mask so it takes the ink token. */
.dev-name .pen {
  display: inline-block;
  width: 0.55em;
  height: 0.55em;
  margin-inline-start: 0.3em;
  vertical-align: 0.1em;
  background: var(--muted);
  opacity: 0.6;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M3 11 10.5 3.5' stroke='%23000' stroke-width='2.2' stroke-linecap='round'/%3E%3Cpath d='M1.5 12.5 2.4 9.4 4.6 11.6Z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M3 11 10.5 3.5' stroke='%23000' stroke-width='2.2' stroke-linecap='round'/%3E%3Cpath d='M1.5 12.5 2.4 9.4 4.6 11.6Z'/%3E%3C/svg%3E") center / contain no-repeat;
}
@media (any-hover: hover) { button.dev-name:hover .pen { opacity: 1; background: var(--ink); } }
.dc-name .dev-edit { align-items: center; }
.dc-status { margin: 0 0 var(--s4); text-align: center; font-size: var(--md); color: var(--ink-muted); }
.dc-status.working { color: var(--working-ink); font-weight: 700; }
.dc-status.asleep { color: var(--dusk-ink); font-weight: 700; }
.dc-status.away { color: var(--failed-ink); font-weight: 700; }

.dc-tray { display: flex; flex-wrap: wrap; justify-content: center; gap: 2px; padding: 12px 8px 8px; border-radius: 18px; background: var(--sunken); }
.coin-tile { display: flex; flex-direction: column; align-items: center; gap: 2px; width: 70px; padding: 4px 0 2px; border: 0; border-radius: 14px; background: none; color: inherit; font: inherit; cursor: pointer; }
.coin-tile.sel { background: var(--surface); box-shadow: 0 2px 0 var(--line-2); }
.coin-tile .c { position: relative; display: grid; place-items: center; width: 52px; height: 52px; transition: transform var(--press, 70ms) ease-out; }
.coin-tile:active .c { transform: translateY(2px); }
.coin-tile .c.pop { animation: dc-pop 420ms cubic-bezier(0.34, 1.56, 0.64, 1); }
.coin-tile .c.pop::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: linear-gradient(115deg, transparent 35%, rgb(255 255 255 / 0.7) 50%, transparent 65%); background-size: 260% 100%; animation: dc-sheen 520ms ease-out forwards; pointer-events: none; mix-blend-mode: soft-light; }
@keyframes dc-pop { 45% { transform: scale(1.16); } }
@keyframes dc-sheen { from { background-position: 100% 0; } to { background-position: -60% 0; } }
.coin-tile .cdot { position: absolute; right: 1px; top: 1px; width: 12px; height: 12px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2.5px var(--sunken); }
.coin-tile.sel .cdot { box-shadow: 0 0 0 2.5px var(--surface); }
.coin-tile .cring { position: absolute; inset: -3px; border-radius: 50%; border: 2.5px solid transparent; border-top-color: var(--accent); animation: dc-spin 1.1s linear infinite; }
@keyframes dc-spin { to { transform: rotate(360deg); } }
.coin-tile .cn { font-size: var(--xs); font-weight: 700; color: var(--ink-soft); white-space: nowrap; }
.coin-tile.off .cn { color: var(--ink-muted); font-weight: 600; }
.coin-tile.socket .c { border: 2px dashed var(--line-2); border-radius: 50%; color: var(--ink-muted); font-size: 22px; font-weight: 700; background: rgb(255 255 255 / 0.35); }
.coin-tile.socket .cn { color: var(--ink-muted); font-weight: 600; }

.dc-detail { position: relative; display: flex; flex-direction: column; gap: 2px; margin-top: 10px; padding: 14px 16px; border-radius: var(--r-md); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line), 0 2px 0 var(--line); animation: dc-enter 220ms cubic-bezier(0.2, 0.8, 0.2, 1); }
.dc-detail::before { content: ""; position: absolute; top: -7px; left: var(--notch, 50%); width: 12px; height: 12px; background: var(--surface); transform: translateX(-50%) rotate(45deg); box-shadow: -1px -1px 0 var(--line); }
@keyframes dc-enter { from { opacity: 0; transform: translateY(6px); } }
.dc-detail .dh { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.dc-detail .dh b { font-size: var(--md); }
.dc-detail .dh small { font-size: var(--sm); color: var(--ink-muted); }
.dc-detail .ln { font-size: var(--sm); line-height: 1.5; color: var(--ink-muted); }
.dc-detail .ln.soft { color: var(--ink-soft); }
.dc-detail .ln.small { font-size: var(--xs); }
.dc-detail .switch { margin: 6px 0 0; padding: 0; min-height: 40px; background: none; box-shadow: none; font-size: 14px; font-weight: 700; }
.dc-missing { display: flex; align-items: center; gap: var(--s3); min-height: 36px; }
.dc-upd { display: flex; align-items: center; gap: 12px; margin: 8px 0 4px; padding: 10px 12px; border-radius: 12px; background: var(--bg); }
.dc-upd .tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; font-size: var(--sm); }
.dc-upd .tx b { font-size: 14px; }
.dc-upd .tx b.done { color: var(--done-ink); }
.dc-upd .tx b.failed { color: var(--failed-ink); }
.dc-upd .tx small { font-size: var(--xs); color: var(--ink-muted); }

.dc-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 14px; }
.chip-wrap { position: relative; display: inline-flex; }
.ach { display: inline-flex; align-items: center; gap: 6px; height: 40px; padding: 0 14px 0 6px; border: 0; border-radius: var(--r-btn); color: var(--ink); font: inherit; font-size: 14px; font-weight: 700; white-space: nowrap; cursor: pointer; transition: transform var(--press, 70ms) ease-out, box-shadow var(--press, 70ms) ease-out; }
.ach img { width: 30px; height: 30px; object-fit: contain; transition: filter 160ms, opacity 160ms; }
.ach.on { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-2), 0 3px 0 var(--line-2); }
.ach.off { background: var(--sunken); color: var(--ink-muted); box-shadow: 0 2px 0 var(--line); }
.ach.off img { filter: grayscale(0.85); opacity: 0.55; }
.ach.add { padding-left: 12px; background: transparent; color: var(--ink-muted); outline: 1.5px dashed var(--line-2); outline-offset: -1.5px; }
.ach.fail { background: var(--failed-surface); color: var(--failed-ink); box-shadow: 0 3px 0 var(--failed-ledge, #efb7c4); }
.ach:active { transform: translateY(2px); }
.ach.on:active { box-shadow: inset 0 0 0 1px var(--line-2), 0 1px 0 var(--line-2); }
.ach.squish { animation: dc-squish 240ms cubic-bezier(0.34, 1.56, 0.64, 1); transform-origin: 50% 100%; }
.ach.squish.on img { animation: dc-hop 300ms cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes dc-squish { 0% { transform: translateY(2px) scale(1.06, 0.94); } 100% { transform: none; } }
@keyframes dc-hop { 40% { transform: translateY(-3px); } }
/* ⓘ on the chip's corner: on hover, always on touch, so nothing moves. */
.chip-i { position: absolute; right: -6px; top: -7px; width: 20px; height: 20px; padding: 0; border: 0; border-radius: 50%; background: var(--surface); box-shadow: inset 0 0 0 1.2px var(--faint); color: var(--ink-muted); font: 700 11px/20px var(--font); text-align: center; cursor: pointer; opacity: 0; }
.chip-wrap:hover .chip-i, .chip-i.open, .chip-i:focus-visible { opacity: 1; }
@media (hover: none) { .chip-i { opacity: 1; } }
.dc-note { margin-top: 10px; padding: 10px 12px; border-radius: 12px; background: var(--bg); font-size: var(--sm); line-height: 1.55; color: var(--ink-soft); animation: dc-enter 220ms cubic-bezier(0.2, 0.8, 0.2, 1); }
:lang(zh) .dc-note { line-height: 1.75; }
.dc-note .acts { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }

.dc-via { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 16px; font-size: var(--sm); color: var(--ink-muted); }
.more-btn { height: 24px; padding: 0 6px; border: 0; border-radius: 8px; background: none; color: var(--ink-muted); font: inherit; font-weight: 800; letter-spacing: 1px; cursor: pointer; }
.more-btn:hover, .more-btn.open { background: var(--sunken); color: var(--ink); }
.dc-conns { margin-top: 8px; border-radius: 12px; background: var(--bg); overflow: hidden; animation: dc-enter 200ms cubic-bezier(0.2, 0.8, 0.2, 1); }
.dc-conn { display: flex; align-items: center; gap: 8px; padding: 6px 12px; font-size: var(--sm); }
.dc-conn + .dc-conn { border-top: 1px solid var(--line-soft); }
.dc-conn small { flex: 1; min-width: 0; color: var(--ink-muted); }
.danger-text { height: 32px; padding: 0 8px; border: 0; border-radius: var(--r-sm); background: none; color: var(--failed-ink); font: inherit; font-size: var(--sm); font-weight: 700; white-space: nowrap; cursor: pointer; }
.danger-text:hover, .danger-text:active { background: var(--failed-surface); }

.dc-ver { display: flex; flex-direction: column; gap: 4px; margin-top: 14px; padding: 10px 12px; border-radius: 12px; background: var(--bg); font-size: var(--sm); }
.dc-ver .row1 { display: flex; align-items: center; gap: 10px; }
.dc-ver .vd { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.dc-ver .tx { flex: 1; min-width: 0; font-weight: 700; }
.dc-ver .tx.done { color: var(--done-ink); }
.dc-ver .tx.failed { color: var(--failed-ink); }
.dc-versions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 8px 4px 0; }
.dc-ver .row1 .btn.tx { flex: 1; justify-content: flex-start; padding-left: 0; color: var(--failed-ink); }
.dc-foot { display: flex; flex-direction: column; margin-top: 16px; padding-top: 10px; border-top: 1px solid var(--line-soft); align-items: flex-start; }
.dc-foot .dev-cut { align-self: stretch; }
@media (prefers-reduced-motion: reduce) {
  .dc *, .dc *::before, .dc *::after { animation: none !important; transition: none !important; }
}
/* D161: the switch sheet's subtitle and its group heads as mini cards. */
.switch-sub { font-size: var(--sm); font-weight: 700; color: var(--ink-soft); }
.switch-head { align-items: center; }
.switch-head img { flex: none; width: 36px; height: 28px; object-fit: contain; }
.switch-head span.asleep { color: var(--dusk-ink); font-weight: 700; }

/* D166: the accounts card as a character sheet (design/connectors.md §12; prototype accounts.html). */
.src-cards { display: flex; flex-direction: column; gap: var(--s4); }
.proactive { display: flex; flex-direction: column; gap: 8px; }
.proactive h4 { margin: var(--s2) 4px 0; font-size: var(--md); font-weight: 800; color: var(--ink); }
.proactive > .small { padding: 0 4px; }
.src-card { display: flex; flex-direction: column; gap: 12px; padding: 18px 16px 14px; border-radius: var(--r-lg); background: var(--surface); box-shadow: 0 4px 0 var(--line); }
.src-who { display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center; }
.src-who h3 { margin: 0; font-family: var(--head); font-size: var(--lg); font-weight: 800; color: var(--ink); }
.src-who .warn { color: var(--failed-ink); font-weight: 700; }
.mailbox-hero { display: block; margin-bottom: 4px; }
.tray { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; padding: 12px 8px; border-radius: var(--r-md); background: var(--surface-sunken); }
.app-tile { display: flex; flex-direction: column; align-items: center; gap: 3px; width: 74px; padding: 8px 2px 6px; border: 0; border-radius: 14px; background: none; color: inherit; font: inherit; cursor: pointer; }
.app-tile.sel { background: var(--surface); box-shadow: 0 2px 0 var(--line-2); }
.app-tile .sq { display: grid; place-items: center; width: 52px; height: 52px; border-radius: 12px; background: var(--surface); box-shadow: 0 3px 0 var(--line); transition: transform var(--press, 70ms) ease-out; }
.app-tile:active .sq { transform: translateY(2px); }
.app-tile.off .sq, .app-tile.grey .sq { opacity: 0.5; }
.app-tile.grey .an { color: var(--ink-muted); }
.app-tile.add .sq { background: rgb(255 255 255 / 0.35); box-shadow: none; border: 1.5px dashed var(--line-2); color: var(--ink-muted); font-size: 22px; font-weight: 700; }
.app-tile .an { font-size: var(--xs); font-weight: 700; color: var(--ink); white-space: nowrap; }
.app-tile .as { font-size: 11px; color: var(--ink-muted); white-space: nowrap; max-width: 70px; overflow: hidden; text-overflow: ellipsis; }
.tile-detail { display: flex; flex-direction: column; gap: 4px; padding: 14px 16px; border-radius: var(--r-md); box-shadow: inset 0 0 0 1px var(--line); animation: dc-enter 220ms cubic-bezier(0.2, 0.8, 0.2, 1); }
.tile-detail .td-name { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.tile-detail .small { line-height: 1.5; color: var(--ink-soft); }
.tile-detail .switch { margin: 6px 0 0; padding: 0; min-height: 40px; background: none; box-shadow: none; font-size: 14px; font-weight: 700; }
.tile-detail .td-foot { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; margin-left: -8px; }
.tile-detail .td-foot .small { padding-left: 8px; }
.tile-detail .td-foot .btn .lbl { white-space: normal; }
.src-conn { display: flex; align-items: center; justify-content: center; gap: 6px; text-align: center; }
.reads { display: flex; flex-direction: column; gap: 4px; padding: 10px 14px; border-radius: var(--r-md); background: var(--surface-sunken); font-size: var(--sm); }
.reads .read { display: flex; gap: 10px; }
.reads .read .at { color: var(--ink-muted); width: 40px; flex: none; }
.reads .honest { margin-top: 4px; padding-top: 6px; border-top: 1px solid var(--line); }
.src-foot { padding-top: 10px; border-top: 1px solid var(--line); }
.stop-ask { display: flex; flex-direction: column; gap: 8px; }
.stop-ask .acts { display: flex; justify-content: flex-end; align-items: center; gap: 8px; }
.accounts.quiet-add { align-items: flex-start; }
@media (prefers-reduced-motion: reduce) { .tile-detail { animation: none; } }

/* D165: a note the partner said by itself, in the conversation. */
.partner > .bubble.note { display: flex; flex-direction: column; gap: 8px; font-size: 15px; line-height: 1.5; background: var(--surface); box-shadow: 0 3px 0 var(--line); }
.bubble.note .find { display: flex; flex-direction: column; gap: 4px; padding-top: 8px; border-top: 1px solid var(--line); }
.bubble.note .find:first-child { padding-top: 0; border-top: 0; }
.bubble.note .kind { font-size: var(--xs); font-weight: 800; color: var(--ink-muted); letter-spacing: 0.02em; }
.bubble.note .fstep { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.bubble.note .freact { display: flex; align-items: center; gap: 0; margin: -6px -8px -4px; }
.bubble.note .fstep .btn { min-height: 34px; }
.bubble.note .freact .grow { flex: 1; }
.bubble.note .freact .btn.text { font-size: var(--xs); color: var(--ink-muted); }
.bubble.note .fhow { display: flex; flex-direction: column; gap: 2px; color: var(--ink-soft); }
.bubble.note .note-ask { display: flex; flex-direction: column; gap: 8px; padding-top: 10px; border-top: 1px solid var(--line); }
