/* 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;
  /* D206: pictures. One picture at most 70% of the column and a little over a third of the
     screen tall; a grid's tiles 2px apart inside one rounded box; the viewer on the theme's paper. */
  --pics-w: min(70%, 22rem);
  --pics-h: min(52vh, 380px);
  --pic-gap: 2px;
  --r-pics: var(--r-btn-lg);
  --viewer-scrim: rgba(255, 246, 234, 0.97);
  --pic-dim: rgba(43, 33, 24, 0.42);
  --ring-back: rgba(43, 33, 24, 0.38);

  --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);
    --viewer-scrim: rgba(10, 8, 6, 0.96);
    --pic-dim: rgba(0, 0, 0, 0.5);
  }
}
:root[data-theme="dark"] {
  --viewer-scrim: rgba(10, 8, 6, 0.96);
  --pic-dim: rgba(0, 0, 0, 0.5);
  --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);
}
/* D184: the level at the whole screen (On hand, or an opened task, as the Mac shows them). Its
   page and the side pane share one transition name, so taking the whole screen grows the pane
   into it and going back shrinks it to its place (app.ts morph; none under reduced motion). */
.full {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  view-transition-name: level;
}
.pane.side {
  view-transition-name: level;
}
.pane.conv {
  view-transition-name: conv;
}
::view-transition-group(level),
::view-transition-group(conv) {
  animation-duration: 320ms;
  animation-timing-function: var(--ease);
}
::view-transition-old(level),
::view-transition-new(level) {
  height: 100%;
  object-fit: cover;
  object-position: left top;
}
/* At a foldable's fold (D182; fold.ts): the page spans the screen and the panes meet at the fold,
   never across it. --fold-a is where the fold starts, --fold-gap a hinge's width (0 on a seamless
   fold). Each pane keeps only the insets on its own outer edges. */
:root[data-split] #app {
  width: auto;
  margin: 0;
  padding: 0;
}
.panes.book .pane.conv {
  flex: 0 0 var(--fold-a);
  padding-left: var(--safe-left);
  --safe-right: 0px;
}
.panes.book .pane.side {
  flex: 1 1 0;
  margin-left: var(--fold-gap);
  padding-right: var(--safe-right);
  --safe-left: 0px;
}
.panes.table {
  flex-direction: column;
  padding-left: var(--safe-left);
  padding-right: var(--safe-right);
}
.panes.table .pane {
  height: auto;
  min-height: 0;
}
.panes.table .pane.conv {
  flex: 0 0 var(--fold-a);
  --safe-bottom: 0px;
}
.panes.table .pane.side {
  flex: 1 1 0;
  margin-top: var(--fold-gap);
  border-left: 0;
  border-top: 1px solid var(--line);
  --safe-top: 0px;
}
/* Below a tabletop's fold, On hand keeps the conversation's measure rather than the whole width. */
.panes.table .pane.side > .top,
.panes.table .pane.side > .scroll {
  padding-left: max(16px, calc((100% - 720px) / 2));
  padding-right: max(16px, calc((100% - 720px) / 2));
}
.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;
}

/* ---------- 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):not(.cal-card):not(.cal-change):not(.cal-settle) {
  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;
}
/* A text button that opens something in place: a drawn chevron, turned down while open (D211). */
.btn .btn-chev {
  flex: none;
  margin-left: -4px;
  transition: transform 160ms ease;
}
.btn[aria-expanded="true"] .btn-chev {
  transform: rotate(90deg);
}
@media (prefers-reduced-motion: reduce) {
  .btn .btn-chev {
    transition: none;
  }
}
/* The one drawn chevron everywhere else (D213): links, rows, the way back. Same stroke and size as
   the button's; it sits on the text's baseline in the text's ink, and turns down while open. */
.chev-g {
  flex: none;
  display: inline-block;
  vertical-align: -0.06em;
  margin-inline-start: 3px;
  transition: transform 160ms ease;
}
.chev-g.open,
[aria-expanded="true"] > .chev-g {
  transform: rotate(90deg);
}
.chev-g.back {
  margin-inline: 0 3px;
  transform: rotate(180deg);
}
@media (prefers-reduced-motion: reduce) {
  .chev-g {
    transition: none;
  }
}
.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 .chev-g {
  margin-inline-start: -5px;
}
.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;
}
/* D210: the command or path in mono beside the words, in muted ink: no chip. */
.step .sum.code {
  font-family: var(--mono);
  font-size: var(--xs);
  color: var(--ink-muted);
}
.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 .chev {
  opacity: 1;
  color: var(--faint);
}
.step .chev .g {
  width: 12px;
  height: 12px;
  color: inherit;
}
.step.open .chev {
  transform: rotate(90deg);
}
.step.bad .g,
.step.bad b,
.step.bad .sum {
  color: var(--failed-ink);
}
.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 {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 2px 0 8px 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;
}
/* A group's leading dot sits in the gap before it, outside the group: when the group wraps to the
   start of a line its dot falls past the line's left edge and is clipped, so no line starts with
   "·" (D211, D213: no coin there to start the group any more). */
.standing {
  column-gap: 10px;
  clip-path: inset(-12px -12px -12px 0);
}
.standing .who {
  position: relative;
}
.standing > :first-child + b {
  margin-inline-start: -4px;
}
.standing .who > .sep:first-child {
  position: absolute;
  right: 100%;
  margin-right: 3px;
}
.standing .inline-link {
  font-size: var(--sm);
}
.standing .inline-link .chev-g {
  color: inherit;
}
/* 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);
}
.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;
  }
}
.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 {
  flex: 0 1 auto;
}
.step .sum:first-of-type {
  flex-shrink: 0.35;
}
.step .sum.code {
  flex: 0 1 auto;
}
/* ---------- D210: the opened task as turns ---------- */
.turns {
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.turn {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
/* A settled turn off screen costs nothing to lay out (a long task holds hundreds of steps). */
.turn:not(:last-child) {
  content-visibility: auto;
  contain-intrinsic-size: auto 480px;
}
.turns .earlier {
  align-self: flex-start;
  font-size: var(--sm);
}
.lines {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.sline {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.sline > .step {
  padding: 0 6px;
  margin: 0 -6px;
  width: calc(100% + 12px);
  border-radius: var(--r-xs);
}
@media (hover: hover), (any-hover: hover) {
  .sline > button.step:hover {
    background: var(--surface-sunken);
  }
}
.step .plus,
.step .minus {
  flex: none;
  font-family: var(--mono);
  font-size: var(--xs);
  font-variant-numeric: tabular-nums;
}
.step .plus {
  color: var(--done-ink);
}
.step .minus {
  color: var(--failed-ink);
}
/* A failure's telling line, in place under its step. */
.sline .errline {
  margin: -2px 0 4px 24px;
  font-family: var(--mono);
  font-size: var(--xs);
  line-height: 1.5;
  color: var(--failed-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sline .looks {
  display: flex;
  flex-direction: column;
  padding: 0 0 4px 22px;
}
.raw pre {
  margin: 0;
  font: inherit;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.raw .more {
  align-self: flex-start;
  font-family: var(--font);
  font-size: var(--xs);
  min-height: 24px;
}
/* An edit's lines: put in on the done tint, taken out on the failed tint. */
.diff {
  margin: 2px 0 8px 24px;
  padding: 4px 0;
  border-radius: var(--r-xs);
  background: var(--sunken);
  font-family: var(--mono);
  font-size: var(--xs);
  line-height: 1.6;
  color: var(--ink-soft);
  overflow-x: auto;
}
.diff .dl {
  padding: 0 12px 0 8px;
  white-space: pre;
  min-width: max-content;
}
.diff .dl .sign {
  display: inline-block;
  width: 1.4em;
  color: var(--ink-muted);
}
.diff .dl.add {
  background: color-mix(in srgb, var(--done-surface) 70%, transparent);
  color: var(--done-ink);
}
.diff .dl.del {
  background: color-mix(in srgb, var(--failed-surface) 70%, transparent);
  color: var(--failed-ink);
}
.diff .dl.add .sign,
.diff .dl.del .sign {
  color: inherit;
}
.diff .dl.head {
  padding-top: 4px;
  font-weight: 700;
  color: var(--ink-muted);
}
.diff .dl.gap {
  color: var(--faint);
  font-family: var(--font);
}
/* Your words while they wait their turn: lighter until it answers. */
.tx.you.waits {
  opacity: 0.72;
}
/* Where it stands, over the composer: working with its clock and latest step, or over to you. */
.task-foot {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  min-height: 36px;
  padding: 2px 16px 0;
  font-size: var(--sm);
  color: var(--ink-muted);
}
.task-foot b {
  flex: none;
  font-weight: 800;
  color: var(--state-ink, var(--ink));
}
.task-foot .clock {
  flex: none;
  font-variant-numeric: tabular-nums;
}
.task-foot .now {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink-soft);
}
.task-foot .grow {
  flex: 1;
}
.task-foot .esc {
  flex: none;
  font-size: var(--xs);
}
.task-foot .btn {
  flex: none;
}
.full > .task-foot {
  padding-left: max(24px, calc((100% - 720px) / 2));
  padding-right: max(24px, calc((100% - 720px) / 2));
}
/* Jump to latest: a round raised button over the transcript's foot, never a pill. */
.jump-dock {
  position: relative;
  height: 0;
  display: flex;
  justify-content: center;
  z-index: 2;
}
.jump {
  position: absolute;
  bottom: 10px;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink-soft);
  box-shadow: var(--floating), 0 0 0 1px var(--rim);
}
.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 {
  font-weight: 700; /* a row's name at the weight of every other row's (the Mac's) */
}
.switch span {
  flex: 1;
  line-height: 1.4;
}
/* The one switch looks like a switch on every browser (the Mac's pill), never a checkbox. */
.switch input {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: none;
  width: 44px;
  height: 26px;
  margin: 0;
  border-radius: 999px;
  background: var(--line-2);
  cursor: pointer;
  transition: background 160ms ease-out;
}
.switch input::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.22);
  transition: transform 160ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.switch input:checked {
  background: var(--accent);
}
.switch input:checked::before {
  transform: translateX(18px);
}
.switch input:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.switch input:disabled {
  opacity: 0.5;
  cursor: default;
}
@media (prefers-reduced-motion: reduce) {
  .switch input,
  .switch input::before {
    transition: none;
  }
}
/* 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;
}
/* D205: the persona's connection: the exact identity, place and id it uses, said literally. */
.set-item small.bridge-id {
  margin-top: -4px;
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: var(--xs);
  overflow-wrap: anywhere;
}
.set-item .bridge-acts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  justify-content: 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 {
  display: inline-flex;
}
.set-back .back-chev .chev-g {
  width: 13px;
  height: 13px;
}
.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);
  /* A row of its own like the switches above it, never loose on the paper (D192). */
  padding: 12px 16px;
  margin-bottom: 4px;
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--base);
  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(--bg);
  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;
}
/* A button that is a link is still a button: never underlined. */
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 {
  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;
}
/* D185: the words first, then one row of pills, each opening its list in place. */
.nt-what {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}
.nt-what textarea {
  width: 100%;
  min-height: 112px;
  resize: none;
  border-radius: var(--r-md);
  border: 1px solid var(--line-soft);
  background: var(--bg);
  padding: 12px 14px;
  font-size: var(--body);
  line-height: var(--lh-read);
  color: var(--ink);
}
.nt-what textarea::placeholder,
.nt-field::placeholder {
  color: var(--ink-muted);
}
.nt-what textarea:focus,
.nt-field:focus {
  outline: none;
  border-color: var(--accent);
}
.nt-pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
}
/* The shared Pill (controls.tsx): one height, flat on the sunken tint; open, white with an ink hairline. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 36px;
  max-width: 100%;
  padding: 0 12px;
  border-radius: var(--r-sm);
  background: var(--surface-sunken);
  color: var(--ink);
  font-size: var(--sm);
  cursor: pointer;
}
.pill:hover {
  background: color-mix(in srgb, var(--surface-sunken) 50%, var(--line));
}
.pill.open {
  background: var(--surface);
  box-shadow: inset 0 0 0 1.5px var(--ink);
}
.pill b {
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.pill code {
  font-family: var(--mono);
  font-size: var(--xs);
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  max-width: 180px;
}
.pill .caret {
  width: 10px;
  height: 10px;
  color: var(--ink-muted);
  flex: none;
}
.nt-glyph {
  width: 15px;
  height: 15px;
  color: var(--ink-muted);
  flex: none;
}
.nt-glyph.faint {
  color: var(--faint);
}
.nt-wait {
  padding: 0 4px;
}
/* 推荐 / Suggested: the best fit's small word in the highlight's ink, never a capsule (D73, D211). */
.sheet.newtask .suggested {
  display: inline-block;
  font-size: var(--xs);
  font-weight: 700;
  line-height: 1;
  color: var(--highlight-ink);
  white-space: nowrap;
  vertical-align: 1px;
}
/* The list a pill opens, in place under the row. */
.nt-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--s2);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--line-soft), var(--base);
  max-height: 300px;
  overflow-y: auto;
}
/* A long list scrolls; its rows keep their height (a column flexbox under max-height would squeeze them). */
.nt-list > * {
  flex-shrink: 0;
}
.nt-list > small {
  font-size: var(--xs);
  font-weight: 700;
  color: var(--ink-muted);
  padding: 4px 10px 2px;
}
/* D203: a line in a list that isn't a choice (an empty computer, an empty folder), and Find a folder…'s head and foot. */
.nt-empty {
  padding: 6px 10px;
}
.nt-err-line {
  color: var(--failed-ink);
}
.nt-browse-head {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  padding: 4px 10px 2px;
  min-width: 0;
}
.nt-browse-head > small {
  font-size: var(--xs);
  font-weight: 700;
  color: var(--ink-muted);
  white-space: nowrap;
}
.nt-browse-head > code {
  font-size: var(--xs);
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.nt-browse {
  max-height: 340px;
}
.nt-browse-foot {
  position: sticky;
  bottom: calc(-1 * var(--s2));
  display: flex;
  justify-content: flex-end;
  gap: var(--s2);
  margin: 4px calc(-1 * var(--s2)) calc(-1 * var(--s2));
  padding: var(--s2);
  background: var(--surface);
  box-shadow: 0 -1px 0 var(--line-soft);
}
/* D204: Add from a Git address…: the address field in the list, and the cloning line with its spinner. */
.nt-clone > .nt-field {
  margin: 4px 6px 0;
  font-family: var(--mono);
  font-size: var(--sm);
}
.nt-cloning {
  display: flex;
  align-items: center;
  gap: var(--s2);
}
/* D202: under the chosen agent, its Model and Effort rows: short rows of chips that wrap. */
.nt-agent {
  display: flex;
  flex-direction: column;
}
.nt-tune {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 4px 10px 8px 50px;
}
.nt-chips {
  display: flex;
  align-items: flex-start;
  gap: var(--s2);
}
.nt-chips > small {
  flex: 0 0 5em;
  padding-top: 7px;
  font-size: var(--xs);
  font-weight: 700;
  color: var(--ink-muted);
}
.nt-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  flex: 1;
  min-width: 0;
}
.nt-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 30px;
  padding: 0 10px;
  border-radius: var(--r-sm);
  background: var(--surface-sunken);
  font-size: var(--sm);
  color: var(--ink-soft);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.nt-chip.on {
  background: var(--surface);
  color: var(--ink);
  font-weight: 700;
  box-shadow: 0 0 0 1px var(--line-2), 0 2px 0 var(--line-2);
}
.nt-chip .nt-dflt {
  font-size: var(--xs);
  font-weight: 500;
  color: var(--ink-muted);
}
@media (max-width: 480px) {
  .nt-tune {
    padding-left: 10px;
  }
}
/* The shared MenuRow (controls.tsx). */
.menu-row {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: 36px;
  padding: 6px 10px;
  border-radius: var(--r-sm);
  text-align: left;
  color: var(--ink);
  cursor: pointer;
}
.menu-row:hover {
  background: color-mix(in srgb, var(--surface-sunken) 50%, var(--surface));
}
.menu-row.on {
  background: var(--surface-sunken);
}
.menu-row:disabled {
  opacity: 0.5;
  cursor: default;
}
.menu-row .mr-body {
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex: 1;
  min-width: 0;
}
.menu-row .mr-t {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.menu-row .mr-t b {
  font-size: var(--sm);
  font-weight: 700;
}
.menu-row .mr-t small,
.menu-row > .mr-body > small {
  font-size: var(--xs);
  color: var(--ink-muted);
}
.menu-row code {
  font-family: var(--mono);
  font-size: var(--xs);
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.menu-row code.grow {
  flex: 1;
  min-width: 0;
  color: var(--ink);
}
.menu-row .mr-check {
  width: 14px;
  height: 14px;
  flex: none;
  color: var(--ink);
}
/* When it doesn't start now: the day and time, the schedule, or the condition. */
.nt-detail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3);
}
.nt-detail .seg {
  flex: none;
  max-width: 100%;
}
.nt-field {
  height: 44px;
  border-radius: var(--r-md);
  border: 1px solid var(--line-soft);
  background: var(--bg);
  padding: 0 14px;
  font-size: var(--md);
  color: var(--ink);
  min-width: 0;
}
.nt-time {
  width: 96px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.nt-cond > span {
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-soft);
}
.nt-cond .nt-field {
  flex: 1 1 220px;
}
.nt-err {
  color: var(--failed-ink);
  font-size: var(--sm);
  line-height: 1.45;
}
.nt-started {
  display: flex;
  align-items: center;
  gap: var(--s2);
  color: var(--done-ink);
  font-size: var(--sm);
  font-weight: 600;
  min-width: 0;
}
.nt-started > svg {
  flex: none;
}
.nt-started > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.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, D183): the agent's own mark in clay. While that agent works
   it rocks gently on its base; while it waits on you it 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.m-working img { transform-origin: 50% 92%; animation: coin-rock 4.2s ease-in-out infinite; }
.coin-art.m-needs_you { animation: coin-bob 2.6s ease-in-out infinite; }
@keyframes coin-rock {
  0%, 100% { transform: rotate(0deg); }
  25% { transform: rotate(5deg); }
  75% { transform: rotate(-5deg); }
}
@keyframes coin-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-2px); }
}
/* A coin with a dark-theme rendition (D213) shows it only on the dark ground. */
.coin-art img.dk { position: absolute; inset: 0; visibility: hidden; }
:root[data-theme="dark"] .coin-art.has-dark img:not(.dk) { visibility: hidden; }
:root[data-theme="dark"] .coin-art.has-dark img.dk { visibility: visible; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .coin-art.has-dark img:not(.dk) { visibility: hidden; }
  :root:not([data-theme="light"]) .coin-art.has-dark img.dk { visibility: visible; }
}
/* In the dark an unavailable coin's grey clay would read as lit: it sits back a little. */
:root[data-theme="dark"] .coin-art.off img { opacity: 0.6; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .coin-art.off img { opacity: 0.6; }
}
@media (prefers-reduced-motion: reduce) {
  .coin-art.m-working img,
  .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; }
/* ---------- D190: 看它上网 / Watch it browse, and taking turns ---------- */
.live-nav { flex: none; display: flex; min-width: 44px; }
.live-host.as-btn { display: block; max-width: 100%; margin: 0 auto; padding: 2px 10px; border: 0; border-radius: var(--r-sm); background: var(--surface-sunken); color: var(--ink); font: inherit; font-weight: 800; font-size: var(--md); cursor: text; }
.live-addr input { width: 100%; box-sizing: border-box; padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface); color: var(--ink); font: inherit; font-size: 16px; text-align: center; }
.live-sub .live-task { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; color: var(--ink-soft); font-weight: 700; }
.live-sub .live-dev { flex: none; }
/* The user's turn: one calm band says so, in the waiting tone (it waits for you). */
.live-band { flex: none; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 7px 14px; font-size: var(--sm); line-height: 1.4; background: var(--waiting-surface); color: var(--waiting-ink); text-align: center; }
.live-band svg { flex: none; }
.live.yours .live-top { border-bottom-color: transparent; }
.live-page.watching { align-items: center; }
.live-page.watching img { touch-action: manipulation; cursor: zoom-in; }
.live-page.zoomed { display: block; overflow: auto; -webkit-overflow-scrolling: touch; }
.live-page.zoomed img { max-width: none; max-height: none; cursor: zoom-out; }
.live-wait { max-width: 320px; padding: 0 var(--s4); text-align: center; line-height: 1.5; }
/* Where the task just clicked or typed: one soft ring, gone in a second. */
.live-ring { position: absolute; width: 34px; height: 34px; margin: -17px 0 0 -17px; border-radius: 50%; border: 3px solid var(--accent); pointer-events: none; animation: live-ring 1.1s var(--spring, ease-out) forwards; }
@keyframes live-ring { 0% { transform: scale(0.4); opacity: 0.95; } 100% { transform: scale(1.5); opacity: 0; } }
.live-doing { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; font-size: var(--sm); color: var(--ink-muted); }
.live-doing > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-doing.on { color: var(--ink-soft); }
.live-pulse { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--working-dot); animation: live-pulse 1.4s ease-in-out infinite; }
@keyframes live-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }
.live-doing + .btns { flex: none; }
.live-kbd { flex: none; }
@media (prefers-reduced-motion: reduce) { .live-ring { animation: none; opacity: 0.6; } .live-pulse { animation: none; opacity: 0.8; } }
/* Landscape on a phone: the page gets the height; the bars slim down. */
@media (orientation: landscape) and (max-height: 500px) { .live-top { min-height: 44px; padding: 4px 12px; } .live-bottom { min-height: 52px; padding: 4px 12px; } .live-band { padding: 4px 12px; } }
.outcome.watch-row { display: flex; align-items: center; justify-content: flex-start; gap: var(--s3); flex-wrap: wrap; text-align: start; }
.outcome.watch-row > .said { flex: 1; min-width: 0; }
.dev-browsing { display: flex; flex-direction: column; gap: var(--s2); margin-top: var(--s2); }
.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); }
/* D213: an update is said in words in the highlight's ink, never a dot (D69). */
.li-row .t small.update { color: var(--highlight-ink); font-weight: 700; }
.li-row .chev { flex: none; display: inline-flex; color: var(--faint); }
.li-row .chev .chev-g { width: 12px; height: 12px; }

.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); }
/* D199: still to come: a ghost on no base (the clay is already desaturated), its words faint. */
.ach.later { background: var(--sunken); color: var(--ink-muted); box-shadow: none; opacity: 0.8; }
.ach.later:active { transform: none; }
.ach-later { margin-left: 2px; font-size: var(--xs); font-weight: 600; color: var(--ink-muted); }
.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; align-items: flex-start; 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: 92px; 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 { max-width: 86px; overflow: hidden; text-overflow: ellipsis; font-size: var(--xs); font-weight: 700; color: var(--ink); white-space: nowrap; }
/* The account under the app: up to two lines, then cut; the whole name is the tile's title (D192). */
.app-tile .as { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; max-width: 86px; overflow: hidden; font-size: var(--xs); line-height: 1.3; color: var(--ink-muted); text-align: center; overflow-wrap: break-word; }
.tile-detail { display: flex; flex-direction: column; gap: 12px; 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; align-items: center; gap: 12px; }
.tile-detail .td-name .sq { display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 10px; background: var(--surface); box-shadow: 0 2px 0 var(--line); }
.tile-detail .td-name .sq svg { width: 24px; height: 24px; }
.tile-detail .td-name > div { min-width: 0; }
.tile-detail .td-name b { font-size: var(--md); font-weight: 800; color: var(--ink); }
.tile-detail .td-name .small { line-height: 1.4; overflow-wrap: anywhere; }
.tile-detail .td-facts { display: grid; grid-template-columns: max-content 1fr; gap: 6px 12px; margin: 0; padding-top: 12px; border-top: 1px solid var(--line-soft); font-size: var(--sm); line-height: 1.5; }
.tile-detail .td-facts dt { font-weight: 700; color: var(--ink-muted); }
.tile-detail .td-facts dd { margin: 0; color: var(--ink); }
.tile-detail .td-watch { padding-top: 4px; border-top: 1px solid var(--line-soft); }
.tile-detail .switch { margin: 0; padding: 0; min-height: 44px; background: none; box-shadow: none; font-size: var(--md); font-weight: 700; }
.tile-detail .switch small { white-space: pre-line; }
.tile-detail .td-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; margin-left: -10px; }
.tile-detail .td-foot .btn .lbl { white-space: normal; }
.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); }
/* The connection, last and quiet (D192): where it passes, then 看了哪些 and the one destructive on one row. */
.src-foot { display: flex; flex-direction: column; gap: 6px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.src-foot > .small.soft { color: var(--ink-soft); line-height: 1.45; }
.src-acts { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 -8px 0 -10px; }
.src-acts .btn.text::after { content: ""; width: 6px; height: 6px; margin-left: -2px; border-right: 1.8px solid currentColor; border-bottom: 1.8px solid currentColor; transform: rotate(-45deg); transition: transform 160ms ease-out; }
.src-acts .btn.text[aria-expanded="true"]::after { transform: translateY(-2px) rotate(45deg); }
.stop-ask { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border-radius: var(--r-md); background: var(--failed-surface); }
.stop-ask .small { color: var(--ink); line-height: 1.5; }
.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); }

/* ---------- D184: On hand at the whole screen, the Mac's (onhand.go, byproject.go) ---------- */
/* The header: the crumbs (对话 / 手头的事, the counts beside), then the controls at its end, on
   the chrome's hairline. */
.top.crumbs {
  min-height: 60px;
  padding: calc(var(--safe-top) + 8px) 24px 8px;
  border-bottom: 1px solid var(--line);
  gap: 16px;
}
.top.crumbs .trail {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex: 1;
  min-width: 0;
  white-space: nowrap;
}
.top.crumbs .crumb {
  font-size: var(--md);
  font-weight: 600;
  color: var(--ink-muted);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  flex: none;
}
.top.crumbs .slash {
  color: var(--faint);
  font-size: var(--md);
  flex: none;
}
.top.crumbs .here {
  margin: 0;
  font-family: var(--head);
  font-size: var(--lg);
  font-weight: 800;
  letter-spacing: -0.2px;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.top.crumbs .sum {
  font-size: var(--xs);
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.top.crumbs .acts {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 12px;
  flex: none;
}
.top.crumbs .seg {
  flex: none;
}
.top.crumbs .seg button {
  min-height: 36px;
  padding: 0 16px;
}
@media (hover: hover), (any-hover: hover) {
  .top.crumbs .crumb:hover {
    color: var(--ink);
  }
}
.board {
  padding: 16px 24px calc(var(--safe-bottom) + 32px);
  gap: 24px;
}
/* The board scrolls; nothing in it shrinks to make room (a one-line Next would fold to nothing). */
.board > * {
  flex-shrink: 0;
}
.board .next,
.scroll > .next {
  margin: 0;
  font-size: var(--sm);
  color: var(--ink-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 4px;
}
.board .next b,
.scroll > .next b {
  font-weight: 700;
  margin-right: 8px;
}
.board .calm-band {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 24px;
  border-radius: var(--r-lg);
  background: var(--done-surface);
  color: var(--done-ink);
  font-size: var(--md);
  font-weight: 600;
}
.board-empty {
  align-self: center;
  width: min(640px, 100%);
  margin-top: 24px;
  padding: 24px;
  border: 2px dashed var(--line);
  border-radius: var(--r-xl);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
  font-size: var(--lg);
  color: var(--ink-soft);
}
/* Four lanes side by side, wrapping when narrow, each only when it has something: what needs you
   the widest, then working, waiting, done today (the Mac's grow and basis). */
.lanes {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: flex-start;
}
.lanes > .col {
  display: contents;
}
.lane {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
.lane.needs {
  flex: 2 1 400px;
  max-width: 880px;
}
.lane.working {
  flex: 1 1 240px;
  max-width: 528px;
}
.lane.waiting {
  flex: 1 1 220px;
  max-width: 484px;
}
.lane.done {
  flex: 1 1 260px;
  max-width: 572px;
}
.lane h2,
.group h2 {
  margin: 0;
  min-height: 40px;
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--head);
  font-size: var(--t20);
  font-weight: 800;
  letter-spacing: -0.3px;
}
.lane h2 .n,
.group h2 .n {
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}
.lane h2 .end,
.group h2 .end {
  margin-left: auto;
}
/* A lane's card (Mac: workingCard, waitingCard, doneList): white on the card's base, its title
   at 15/800, where it stands at 13 in soft ink, the rest at 12 muted. */
.bcard {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  padding: 16px;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--base);
  text-align: left;
  width: 100%;
  min-width: 0;
}
.bcard .t {
  font-size: var(--md);
  font-weight: 800;
  line-height: 1.35;
  text-wrap: balance;
}
.bcard .s {
  font-size: var(--sm);
  line-height: 1.5;
  color: var(--ink-soft);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.bcard .m {
  font-size: var(--xs);
  line-height: 1.45;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}
.bcard .m.two {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.bcard .wrow {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--sm);
  line-height: 1.5;
  color: var(--ink-soft);
}
.bcard .wrow > svg {
  color: var(--ink-muted);
  flex: none;
}
.bcard.wait .btn {
  align-self: flex-start;
}
.bcard.list {
  padding: 4px 16px;
  gap: 0;
}
.drow,
.prow {
  display: flex;
  text-align: left;
  width: 100%;
  min-width: 0;
  padding: 12px 0;
  min-height: 52px;
}
.drow + .drow,
.prow + .prow {
  border-top: 1px solid var(--line-soft);
}
.drow {
  flex-direction: column;
  gap: 6px;
}
.drow .dtop {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}
.drow .t {
  flex: 1;
  min-width: 0;
  font-weight: 700;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.drow .failed {
  font-size: var(--xs);
  color: var(--failed-ink);
  flex: none;
}
.drow .s {
  font-size: var(--xs);
  line-height: 1.45;
  -webkit-line-clamp: 2;
}
.drow .ev {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
button.bcard {
  transition: transform 160ms var(--ease), box-shadow 160ms var(--ease);
}
button.bcard:active {
  transform: translateY(2px);
  box-shadow: 0 2px 0 var(--line);
}
@media (hover: hover), (any-hover: hover) {
  .drow:hover .t,
  .prow:hover .t {
    text-decoration: underline;
    text-decoration-thickness: 1.5px;
    text-underline-offset: 3px;
  }
  button.bcard:hover {
    box-shadow: 0 6px 0 var(--line), var(--drop);
    transform: translateY(-2px);
  }
}
/* By project: groups at most 960 wide, centered, each a card of one-line rows. */
.board .pd,
.groups {
  width: min(960px, 100%);
  align-self: center;
}
.groups {
  display: flex;
  flex-direction: column;
  gap: 32px;
}
.group {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.group .gname {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.group h2 .plus {
  width: 40px;
  height: 40px;
  border-radius: var(--pill);
  display: grid;
  place-items: center;
  color: var(--ink);
}
.prow {
  align-items: center;
  gap: 12px;
}
.prow .t {
  flex: 1;
  min-width: 0;
  font-size: var(--md);
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.prow .br {
  font-family: var(--mono);
  font-size: var(--xs);
  color: var(--ink-muted);
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 0 2 auto;
  min-width: 0;
}
.prow .stat {
  display: inline-flex;
  gap: 6px;
  font-family: var(--mono);
  font-size: var(--xs);
  font-variant-numeric: tabular-nums;
  flex: none;
}
.prow .stat i {
  font-style: normal;
}
.prow .stat .add {
  color: var(--done-ink);
}
.prow .stat .del {
  color: var(--failed-ink);
}
.prow .st {
  width: 64px;
  text-align: right;
  font-size: var(--xs);
  color: var(--ink-muted);
  flex: none;
}
.prow .st.needs {
  color: var(--needs-ink);
}
.prow .st.failed {
  color: var(--failed-ink);
}
/* An opened task at the whole screen: the Mac's one centered column, the composer and a pending
   ask on the same measure. */
.full > .task-page,
.full > .ask-dock,
.full > .composer-wrap {
  padding-left: max(24px, calc((100% - 720px) / 2));
  padding-right: max(24px, calc((100% - 720px) / 2));
}
.full > .task-page {
  padding-top: 24px;
}
/* On a book fold the lanes meet at the fold (D182): what needs you on the first half, the rest
   on the second; nothing lies across it. */
.full.book .top.crumbs {
  padding-left: calc(var(--safe-left) + 16px);
  padding-right: calc(var(--safe-right) + 16px);
}
.full.book .top.crumbs .trail {
  max-width: calc(var(--fold-a) - var(--safe-left) - 32px);
}
.full.book .board {
  padding-left: 0;
  padding-right: 0;
}
.full.book .board > .next,
.full.book .board > .calm-band {
  margin-left: calc(var(--safe-left) + 16px);
  max-width: calc(var(--fold-a) - var(--safe-left) - 32px);
}
.full.book .board > .shelf {
  margin: 0 calc(var(--safe-right) + 16px) 0 calc(var(--fold-a) + var(--fold-gap) + 16px);
}
.full.book .lanes {
  flex-wrap: nowrap;
  gap: 0;
}
.full.book .lanes > .col {
  display: flex;
  flex-direction: column;
  gap: 24px;
  min-width: 0;
}
.full.book .lanes > .col:first-child {
  flex: 0 0 var(--fold-a);
  padding: 0 16px 0 calc(var(--safe-left) + 16px);
}
.full.book .lanes > .col:last-child {
  flex: 1 1 0;
  margin-left: var(--fold-gap);
  padding: 0 calc(var(--safe-right) + 16px) 0 16px;
}
.full.book .lane {
  max-width: none;
  flex: none;
}
.full.book .board .pd,
.full.book .groups {
  width: auto;
  align-self: stretch;
  margin: 0 calc(var(--safe-right) + 16px) 0 calc(var(--safe-left) + 16px);
}
.full.book .groups {
  display: grid;
  grid-template-columns: calc(var(--fold-a) - var(--safe-left) - 32px) 1fr;
  column-gap: calc(var(--fold-gap) + 32px);
  row-gap: 32px;
  align-items: start;
}

/* D191: 自动填充 / Autofill. A sign-in is its site's letter on a clay pebble, a card a small
   clay card with its last four; secrets only ever as a dot row. */
.af-lede {
  margin: 0 0 var(--s3);
  color: var(--ink-soft);
  font-size: var(--md);
  line-height: 1.5;
}
.af-mark,
.af-plus {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--surface-sunken);
  box-shadow: 0 var(--ledge) 0 var(--line-2);
  font-family: var(--head);
  font-size: var(--lg);
  font-weight: 800;
  color: var(--ink-soft);
}
/* Add: a drawn ＋ in the row's ink, never a glyph on a tile (D73, D211). */
.af-plus {
  background: none;
  box-shadow: none;
  color: var(--ink-soft);
}
.af-dots {
  flex: none;
  color: var(--faint);
  letter-spacing: 2px;
}
.af-card {
  flex: none;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  width: 52px;
  height: 36px;
  padding: 3px 6px;
  border-radius: 8px;
  background: var(--working-surface);
  box-shadow: 0 var(--ledge) 0 var(--line-2);
  font-family: var(--mono);
  font-size: var(--xs);
  font-weight: 700;
  color: var(--working-ink);
}
.af-card.mastercard,
.af-card.jcb {
  background: var(--needs-surface);
  color: var(--needs-ink);
}
.af-card.amex,
.af-card.discover {
  background: var(--done-surface);
  color: var(--done-ink);
}
.af-card.unionpay {
  background: var(--failed-surface);
  color: var(--failed-ink);
}
.af-form .grow {
  flex: 1;
}
.af-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: var(--s2);
}
.af-clear {
  align-self: flex-start;
  min-height: 32px;
}
.af-uses {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--base);
  overflow: hidden;
}
.af-uses li {
  display: flex;
  gap: var(--s3);
  align-items: baseline;
  padding: var(--s3) var(--s4);
  font-size: var(--sm);
  line-height: 1.45;
}
.af-uses li + li {
  border-top: 1px solid var(--line-soft);
}
.af-uses li.no {
  color: var(--ink-muted);
}
.af-uses .grow {
  flex: 1;
  min-width: 0;
}
.af-uses small {
  display: block;
  color: var(--ink-muted);
}
.af-uses time {
  flex: none;
  color: var(--ink-muted);
  font-size: var(--xs);
}
.af-kept {
  margin-top: var(--s2);
}
/* 付款 / Pay: the facts as a small receipt, the amount biggest. */
.pay-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s1) var(--s3);
  margin: var(--s2) 0;
  padding: var(--s3);
  border-radius: var(--r-sm);
  background: var(--surface-sunken);
  font-size: var(--sm);
}
.pay-facts dt {
  color: var(--ink-muted);
}
.pay-facts dd {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
  color: var(--ink);
  font-weight: 600;
}
.pay-facts .pay-amount {
  font-family: var(--head);
  font-size: var(--t20);
  font-weight: 800;
}
.pay-first {
  margin-inline-start: var(--s2);
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--waiting-surface);
  color: var(--waiting-ink);
  font-size: var(--xs);
  font-weight: 700;
}
.pay-cvc input {
  max-width: 9em;
  letter-spacing: 4px;
}
/* ---------- D193: phone calls (phone.tsx): the Go card, a question from the line, the call row,
   the device sign-in and the phone card. Tokens only. ---------- */
.call-card { display: flex; flex-direction: column; gap: 10px; }
.call-head { display: flex; align-items: center; gap: 12px; }
.call-head .q { flex: 1; }
.call-art { display: block; flex: none; object-fit: contain; }
.call-plan { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 0; padding: 12px 14px; border-radius: var(--r-md); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); font-size: var(--sm); }
.call-plan > div { display: contents; }
.call-plan dt { color: var(--ink-muted); font-weight: 700; white-space: nowrap; }
.call-plan dd { margin: 0; color: var(--ink); line-height: 1.45; overflow-wrap: anywhere; }
.call-plan .when dd { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.call-plan .when .why { color: var(--ink-soft); font-size: var(--xs); line-height: 1.5; }
.call-plan .when .btn { margin-top: 2px; }
.call-open { padding: 0 2px; }
/* D215: the call sheet: the line to speak first is set apart as a quote on the sunken ground. */
.call-num { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.call-num .v { font-variant-numeric: tabular-nums; font-weight: 700; }
.call-num .btn { margin: -6px 0; }
.call-say { margin: 0; padding: 12px 14px; border-radius: var(--r-md); background: var(--surface-sunken); display: flex; flex-direction: column; gap: 4px; }
.call-say figcaption { font-size: var(--xs); font-weight: 800; color: var(--ink-muted); }
.call-say blockquote { margin: 0; font-family: var(--head); font-size: var(--lg); font-weight: 700; line-height: 1.45; color: var(--ink); overflow-wrap: anywhere; }
.call-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 2px; }
.call-card a.btn { text-decoration: none; display: inline-flex; align-items: center; justify-content: center; }
.call-summary { margin: 0; padding: 10px 12px; border-radius: var(--r-sm); background: var(--surface-sunken); color: var(--ink-soft); line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
dl.call-summary { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; white-space: normal; }
dl.call-summary > div { display: contents; }
dl.call-summary dt { color: var(--ink-muted); font-weight: 700; white-space: nowrap; }
dl.call-summary dd { margin: 0; }
.call-reply { display: flex; gap: 8px; align-items: center; }
.call-reply input { flex: 1; min-width: 0; min-height: 40px; padding: 0 12px; border: 0; border-radius: var(--r-sm); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-2); color: var(--ink); font: inherit; font-size: var(--sm); }
.call-card.question .q { font-size: var(--lg); font-family: var(--head); font-weight: 800; line-height: 1.3; }
.call-q-head { display: flex; align-items: center; gap: 8px; font-size: var(--sm); font-weight: 800; color: var(--needs-ink); }
.call-q-head .sub { color: var(--ink-muted); font-weight: 700; }
.call-choices { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
.call-row { gap: 6px; }
.call-row-top { display: flex; align-items: center; gap: 12px; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.call-row-top:disabled { cursor: default; }
.call-row-top .grow { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.call-row .s { color: var(--ink-soft); line-height: 1.45; }
.call-row .s.warn { color: var(--failed-ink); }
.call-row .chev { flex: none; color: var(--ink-muted); font-weight: 700; }
.call-row > .btn { align-self: flex-start; margin-left: 48px; }
.call-row > .call-result { margin-left: 48px; }
.call-check { flex: none; color: var(--ink-muted); vertical-align: -2px; margin-right: 6px; }
.call-result { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; border-radius: var(--r-md); background: var(--surface-sunken); }
.call-result p, .call-result ul { margin: 0; color: var(--ink-soft); line-height: 1.5; }
.call-result ul { padding-left: 18px; }
.call-lines { display: flex; flex-direction: column; gap: 4px; line-height: 1.5; }
.phone-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.phone-day { text-align: center; font-weight: 700; color: var(--ink); }
.phone-card > .small.sub, .phone-offer > .small.sub { text-align: center; }
.phone-cap { display: flex; flex-direction: column; gap: 6px; align-items: stretch; }
.phone-cap > .small.sub { text-align: center; }
.phone-cap h4 { margin: 0; font-size: var(--sm); font-weight: 800; color: var(--ink); text-align: center; }
.phone-rails { display: flex; flex-direction: column; gap: 6px; padding: 14px 16px; border-radius: var(--r-md); box-shadow: inset 0 0 0 1px var(--line); }
.phone-rails h4 { margin: 0 0 2px; font-size: var(--sm); font-weight: 800; color: var(--ink); }
.phone-rails .small { color: var(--ink-soft); line-height: 1.45; }
.phone-voice { display: flex; flex-direction: column; gap: 8px; padding: 14px 16px; border-radius: var(--r-md); box-shadow: inset 0 0 0 1px var(--line); }
.phone-voice h4 { margin: 0; font-size: var(--md); font-weight: 800; color: var(--ink); }
.phone-voice .phone-acts { justify-content: flex-start; }
/* D218: 用你自己的号码打 / Call from your own number: five steps; only the open one unfolds. */
.own-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.own-step { border-radius: var(--r-md); box-shadow: inset 0 0 0 1px var(--line); }
.own-step.open { background: var(--surface-raised); box-shadow: inset 0 0 0 1.5px var(--line-2); }
.own-step-top { display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 14px; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.own-step-top .grow { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.own-step-top .t { font-size: var(--md); font-weight: 800; color: var(--ink); }
.own-step.later .own-step-top .t { color: var(--ink-muted); }
.own-step-top .s { font-size: var(--sm); color: var(--ink-muted); overflow-wrap: anywhere; }
.own-mark { flex: none; display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; font-size: 12px; font-weight: 800; }
.own-mark.next { background: var(--accent); color: var(--on-accent); }
.own-mark.later { box-shadow: inset 0 0 0 1.5px var(--faint); color: var(--ink-muted); }
.own-body { display: flex; flex-direction: column; gap: 10px; padding: 0 14px 14px 48px; }
.own-body .small { line-height: 1.5; }
.own-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px; }
.own-row .acct-field { flex: 1 1 180px; min-width: 0; }
.own-pick select { width: 100%; padding: 10px 12px; border-radius: 12px; border: 0; background: var(--surface-sunken); color: var(--ink); font: inherit; font-size: var(--md); }
.own-cmd { align-self: flex-start; max-width: 100%; overflow-x: auto; padding: 6px 10px; border-radius: 10px; background: var(--surface-sunken); font-family: var(--mono); font-size: var(--sm); color: var(--ink); user-select: all; }
.own-parts { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.own-parts ol { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 4px; color: var(--ink-soft); }
.own-cable { width: 100%; max-width: 320px; height: auto; }
.own-live { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: var(--r-md); background: var(--working-surface); color: var(--working-ink); }
.own-live .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--working-dot); animation: own-pulse 1.6s ease-in-out infinite; }
.own-live .grow { flex: 1; min-width: 0; }
@keyframes own-pulse { 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .own-live .dot { animation: none; } }
.own-card .center { text-align: center; }
.own-card .phone-acts.left { justify-content: flex-start; }
.own-busy { text-align: center; }
@media (max-width: 480px) { .own-body { padding-left: 14px; } }
.signin-card { align-items: stretch; text-align: center; }
.signin-code { align-self: center; padding: 10px 18px; border-radius: var(--r-md); background: var(--surface-sunken); font-family: var(--mono); font-size: 30px; font-weight: 700; letter-spacing: 0.12em; color: var(--ink); user-select: all; }
.call-qr { align-self: center; border-radius: 12px; box-shadow: 0 3px 0 var(--line); }
.signin-wait { text-align: center; line-height: 1.5; }
@media (max-width: 600px) { .call-qr { display: none; } }
/* D190: a working card whose task uses Ducter's browser: 看看 / Watch at its corner (wide On hand). */
.bwatch { position: relative; }
.bwatch > .bcard { width: 100%; padding-right: 72px; }
.bwatch > .btn { position: absolute; right: 8px; bottom: 8px; }


/* ---------- pictures and files (D206, design/media.md) ---------- */
.user-m {
  align-self: flex-end;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}
.user-m > .user {
  max-width: min(80%, var(--bubble-measure));
}
.media {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  width: 100%;
}
.media.on-user {
  align-items: flex-end;
}
.media.on-partner,
.media.on-task {
  align-items: flex-start;
}
.partner > .media {
  margin-left: 0;
}
.pics {
  position: relative;
  width: var(--pics-w);
  border-radius: var(--r-pics);
  overflow: hidden;
  background: var(--sunken);
}
.media.on-task .pics {
  --pics-w: min(100%, 22rem);
}
/* D210: in a turn, a picture stays small: the transcript is for reading; a tap opens it big. */
.turns .media.on-task .pics {
  --pics-w: min(100%, 15rem);
  --pics-h: 14rem;
}
.tx.you .media {
  margin-bottom: var(--s2);
}
.pics .tile {
  position: absolute;
  padding: 0;
  margin: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  -webkit-tap-highlight-color: transparent;
}
.pics .tile > img,
.pics .tile > .ph {
  position: absolute;
  inset: calc(var(--pic-gap) / 2);
  width: calc(100% - var(--pic-gap));
  height: calc(100% - var(--pic-gap));
  object-fit: cover;
  display: block;
}
.pics.one .tile > img,
.pics.one .tile > .ph {
  inset: 0;
  width: 100%;
  height: 100%;
}
.pics .tile > .ph {
  background-size: cover;
  background-position: center;
  filter: blur(14px);
  transform: scale(1.15);
}
.pics .tile > img {
  opacity: 0;
  transition: opacity var(--t-med) var(--ease);
}
.pics .tile.in > img {
  opacity: 1;
}
.pics .tile:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: -3px;
}
.pics .tile .more {
  position: absolute;
  inset: calc(var(--pic-gap) / 2);
  display: grid;
  place-items: center;
  background: var(--pic-dim);
  color: #fff;
  font: 800 var(--t20) / 1 var(--head);
}
.pics .tile.in.failed > img {
  opacity: 0.45;
}
.ring {
  position: absolute;
  left: 50%;
  top: 50%;
  margin: -18px 0 0 -18px;
  border-radius: 50%;
  background: var(--ring-back);
}
.ring circle {
  fill: none;
  stroke-width: 2.6;
}
.ring .track {
  stroke: rgba(255, 255, 255, 0.28);
}
.ring .arc {
  stroke: #fff;
  stroke-linecap: round;
  transform: rotate(-90deg);
  transform-origin: 18px 18px;
  transition: stroke-dashoffset var(--t-fast) linear;
}
.unsent {
  display: flex;
  align-items: center;
  gap: var(--s1);
  font-size: var(--sm);
  font-weight: 700;
  color: var(--failed-ink);
}
.unsent .btn.text {
  color: var(--failed-ink);
}
/* A file a task showed: one line on a card, Open at its end. */
.filecard {
  display: flex;
  align-items: center;
  gap: var(--s3);
  width: min(100%, 22rem);
  padding: 6px 6px 6px 14px;
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--base);
  color: var(--ink);
}
.filecard .fi {
  flex-shrink: 0;
  color: var(--ink-muted);
}
.filecard .fn {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--md);
  font-weight: 700;
}
.filecard .fs {
  flex-shrink: 0;
  font-size: var(--sm);
  color: var(--ink-muted);
}
.filecard .btn.text {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  color: var(--ink);
  font-weight: 700;
}
/* The composer: 加图片 / Add images first, the tray of what is picked above it. */
.composer .add-pic {
  flex-shrink: 0;
  align-self: flex-end;
  margin-left: -10px;
  color: var(--ink-muted);
}
.tray-pics {
  display: flex;
  gap: var(--s2);
  overflow-x: auto;
  padding: 8px 4px 10px;
  scrollbar-width: none;
}
.tray-pics::-webkit-scrollbar {
  display: none;
}
.chosen {
  position: relative;
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  border-radius: var(--r-sm);
  background: var(--sunken);
  box-shadow: var(--base);
  animation: pop-in 220ms var(--spring);
}
.chosen > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--r-sm);
  display: block;
}
.chosen .ring {
  transform: scale(0.72);
}
.chosen.failed > img {
  opacity: 0.4;
}
.chosen .retry {
  position: absolute;
  inset: 0;
  border: 0;
  background: none;
  font-size: var(--xs);
  font-weight: 800;
  color: var(--failed-ink);
}
.chosen .x {
  position: absolute;
  top: -7px;
  right: -7px;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--ink);
  color: var(--bg);
  box-shadow: var(--drop-pressed);
}
.chosen .x::after {
  content: "";
  position: absolute;
  inset: -10px;
}
@keyframes pop-in {
  from {
    opacity: 0;
    transform: scale(0.86);
  }
}
.composer-wrap,
.nt-what,
.scroll {
  position: relative;
}
.drop-hint {
  position: absolute;
  inset: 6px;
  z-index: 5;
  display: grid;
  place-items: center;
  border-radius: var(--r-lg);
  border: 2px solid var(--accent);
  background: color-mix(in srgb, var(--bg-deep) 88%, transparent);
  pointer-events: none;
  font-weight: 800;
  color: var(--needs-ink);
}
.scroll > .drop-hint {
  position: sticky;
  top: 6px;
  min-height: 30vh;
}
.nt-what-foot {
  display: flex;
  align-items: center;
  gap: var(--s2);
}
.nt-what-foot .small {
  flex: 1;
}
/* The viewer: the picture on the theme's paper, everything else out of its way. */
.viewer {
  position: fixed;
  inset: 0;
  z-index: 60;
  color: var(--ink);
  touch-action: none;
  animation: fade-in 180ms var(--ease);
}
.viewer.closing {
  animation: fade-out 200ms var(--ease) forwards;
}
.viewer .scrim {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--viewer-scrim);
  animation: none;
}
.viewer .stage,
.viewer .v-top,
.viewer .v-bar {
  z-index: 1;
}
.viewer .stage {
  position: absolute;
  inset: calc(var(--safe-top) + 56px) 0 calc(var(--safe-bottom) + 64px);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.viewer .stage img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  background-size: cover;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  will-change: transform;
  transition: transform 220ms var(--ease);
  border-radius: 0;
}
.viewer .v-top,
.viewer .v-bar {
  position: absolute;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 6px max(12px, var(--safe-right)) 6px max(12px, var(--safe-left));
}
.viewer .v-top {
  top: 0;
  padding-top: calc(var(--safe-top) + 6px);
}
.viewer .v-bar {
  bottom: 0;
  padding-bottom: calc(var(--safe-bottom) + 10px);
}
.viewer .v-top .count {
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}
.viewer .btn.text {
  color: var(--ink);
  font-weight: 700;
}
.viewer .from {
  min-width: 0;
  max-width: 55%;
  height: 44px;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--ink-soft);
  font-size: var(--sm);
  font-weight: 700;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-decoration: underline;
  text-decoration-color: var(--line-2);
  text-underline-offset: 3px;
}
.viewer .grow {
  flex: 1;
}
@keyframes fade-in {
  from {
    opacity: 0;
  }
}
@keyframes fade-out {
  to {
    opacity: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .viewer,
  .viewer.closing,
  .chosen {
    animation: none;
  }
  .viewer .stage img,
  .pics .tile > img {
    transition: none;
  }
}

/* ---------- On hand as a workspace (D216): one list in every room ---------- */
.onhand-list {
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
}
.onhand-list .tools {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}
.onhand-list .find {
  flex: 1 1 220px;
  min-width: 0;
  height: 40px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  border-radius: var(--r-sm);
  background: var(--sunken);
  color: var(--ink-muted);
}
.onhand-list .find:focus-within {
  box-shadow: 0 0 0 2px var(--accent);
}
.onhand-list .find input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  font-size: var(--md);
  color: var(--ink);
}
.onhand-list .find input::-webkit-search-cancel-button {
  -webkit-appearance: none;
}
.onhand-list .none,
.switcher .none {
  margin: 0;
  padding: 8px 4px;
  color: var(--ink-muted);
  font-size: var(--md);
}
.tsec {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.tsec h3 {
  margin: 0 2px;
  min-height: 32px;
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-muted);
  display: flex;
  gap: 8px;
  align-items: center;
}
.tsec h3 .n {
  font-variant-numeric: tabular-nums;
}
.tsec h3 .end {
  margin-left: auto;
  display: flex;
  align-items: center;
}
.tsec .calm-line {
  margin: 0 2px;
  font-size: var(--md);
  line-height: var(--lh-read);
  color: var(--ink-soft);
}
/* A section's tasks are one clay card of rows: one shadow, rows parted by a soft line. */
.trows {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--base);
  overflow: hidden;
}
.trow {
  position: relative;
  display: flex;
  align-items: stretch;
  min-width: 0;
  /* Hundreds of rows stay smooth: rows off screen are not laid out or painted. */
  content-visibility: auto;
  contain-intrinsic-size: auto 66px;
}
.trows > .trow + .trow,
.tsec > .trow.loose + .trow.loose {
  border-top: 1px solid var(--line-soft);
}
.tsec > .trow.loose {
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--base);
}
.trow .tmain {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 13px 18px;
  text-align: left;
  color: inherit;
  background: transparent;
}
.trow .tmain.static {
  cursor: default;
}
.trow .l1,
.trow .l2 {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.trow .l1 .t {
  flex: 1;
  min-width: 0;
  font-size: var(--md);
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.trow .stat {
  display: flex;
  gap: 6px;
  font-family: var(--mono);
  font-size: var(--xs);
  font-variant-numeric: tabular-nums;
  flex: none;
}
.trow .stat i {
  font-style: normal;
}
.trow .stat .add {
  color: var(--done-ink);
}
.trow .stat .del {
  color: var(--failed-ink);
}
.trow .pr {
  flex: none;
  font-size: var(--xs);
  font-weight: 700;
  color: var(--ink-soft);
}
.trow .st {
  flex: none;
  font-size: var(--xs);
  font-weight: 700;
  color: var(--ink-muted);
}
.trow .st.needs {
  color: var(--needs-ink);
}
.trow .st.failed {
  color: var(--failed-ink);
}
.trow .time {
  flex: none;
  min-width: 3.2em;
  text-align: right;
  font-size: var(--xs);
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}
.trow .l2 {
  font-size: var(--sm);
  color: var(--ink-soft);
}
.trow .l2 > .g {
  flex: none;
  width: 14px;
  height: 14px;
  color: var(--ink-muted);
}
.trow .l2 .w {
  min-width: 0;
  flex: 0 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.trow .l2 .c,
.trow .l2 .br {
  min-width: 0;
  font-family: var(--mono);
  font-size: var(--xs);
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.trow .l2 .c {
  flex: 0 3 auto;
}
.trow .l2 .br {
  flex: 0 2 auto;
  margin-left: auto;
  max-width: 34%;
}
.trow .l2 .meta {
  flex: none;
  font-size: var(--xs);
  color: var(--ink-muted);
  white-space: nowrap;
}
.trow .l2 .br + .meta {
  margin-left: 0;
}
.trow .l2 .w + .meta,
.trow .l2 .c + .meta {
  margin-left: auto;
}
.trow .l2.needs {
  color: var(--needs-ink);
}
.trow .l2.failed {
  color: var(--failed-ink);
}
.trow .l2.failed > .g {
  color: var(--failed-ink);
}
/* Finished work recedes a little; what needs you never does. */
.trow.a-done .l1 .t,
.trow.a-done_claimed .l1 .t {
  color: var(--ink-soft);
  font-weight: 600;
}
.trow .groove-track,
.trow .goal {
  margin-top: 4px;
}
/* The one next step on hover (pointer, wide), over the row's right end. */
.trow .tacts {
  position: absolute;
  top: 8px;
  right: 12px;
  display: none;
  align-items: center;
  gap: 4px;
  padding-left: 24px;
  background: linear-gradient(to right, transparent, var(--surface-raised) 24px);
}
.trow .tacts.on {
  display: flex;
  position: static;
  align-self: center;
  padding: 0 12px 0 0;
  background: none;
}
.trow .tacts .busy {
  font-size: var(--xs);
  color: var(--ink-muted);
  padding: 0 8px;
}
@media (hover: hover) {
  .trow:hover {
    background: var(--surface-raised);
  }
  .trow:hover .tacts,
  .trow:focus-within .tacts {
    display: flex;
  }
}
/* Where the keys are, what is selected, what is open beside the list. */
.trow.kfocus {
  background: var(--surface-raised);
  box-shadow: inset 4px 0 0 var(--accent);
}
.trow.sel {
  background: var(--working-surface);
}
.trow.sel .tacts {
  background: linear-gradient(to right, transparent, var(--working-surface) 24px);
}
.trow.opened {
  background: var(--sunken);
  box-shadow: inset 4px 0 0 var(--ink);
}
/* Many at once: one raised bar at the foot of the list, while something is selected. */
.onhand-list .bulk {
  position: sticky;
  bottom: calc(var(--safe-bottom) + 16px);
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  padding: 8px 10px 8px 20px;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--floating), var(--base);
  animation: rise 200ms var(--ease);
}
.onhand-list .bulk > b {
  font-size: var(--md);
  margin-right: 8px;
}
.onhand-list .bulk .ask {
  font-size: var(--md);
  color: var(--ink-soft);
  margin-right: 8px;
}
.onhand-list .bulk .grow {
  flex: 1;
}
@keyframes rise {
  from {
    transform: translateY(8px);
    opacity: 0;
  }
}
/* The whole screen: the list on a wide measure. */
.board-col {
  width: min(960px, 100%);
  align-self: center;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
/* A task at the whole screen with the list beside it as a rail (ROOMY in wide.ts). */
.with-rail {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 340px minmax(0, 1fr);
}
.rail {
  min-height: 0;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--line);
  background: var(--bg-deep);
}
.rail-head {
  min-height: 60px;
  padding: calc(var(--safe-top) + 8px) 20px 8px;
  display: flex;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.rail-head .crumb {
  font-size: var(--lg);
  font-weight: 800;
  font-family: var(--head);
}
.rail-head .sum {
  font-size: var(--xs);
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
}
.rail-list {
  padding: 16px 12px calc(var(--safe-bottom) + 24px);
}
.room-rail .trow .tmain {
  padding: 11px 14px;
}
.room-rail .tsec h3 {
  min-height: 24px;
}
.beside-rail {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  position: relative;
}
.beside-rail > .task-page,
.beside-rail > .ask-dock,
.beside-rail > .composer-wrap,
.beside-rail > .task-foot {
  padding-left: max(24px, calc((100% - 720px) / 2));
  padding-right: max(24px, calc((100% - 720px) / 2));
}
.beside-rail > .task-page {
  padding-top: 24px;
}
/* 打开一件事 / Open a task (⌘O): one field and the tasks under it, over everything. */
.switcher {
  position: fixed;
  z-index: 21;
  top: max(10vh, calc(var(--safe-top) + 24px));
  left: 50%;
  transform: translateX(-50%);
  width: min(640px, calc(100vw - 32px));
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--r-xl);
  box-shadow: var(--floating), var(--base);
  overflow: hidden;
  animation: rise 160ms var(--ease);
}
.switcher .sw-in {
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  font-size: var(--lg);
  color: var(--ink);
  padding: 20px 24px;
  border-bottom: 1px solid var(--line-soft);
}
.switcher .sw-list {
  max-height: min(60vh, 520px);
  overflow: auto;
  padding: 8px;
  display: flex;
  flex-direction: column;
}
.switcher .sw-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 10px 16px;
  border-radius: var(--r-md);
  text-align: left;
  color: inherit;
  background: transparent;
  min-width: 0;
}
.switcher .sw-row.on {
  background: var(--sunken);
}
.switcher .sw-row .t {
  flex: 1;
  min-width: 0;
  font-size: var(--md);
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.switcher .sw-row .m {
  flex: 0 2 auto;
  min-width: 0;
  font-family: var(--mono);
  font-size: var(--xs);
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.switcher .sw-row .st {
  flex: none;
  font-size: var(--xs);
  font-weight: 700;
  color: var(--ink-muted);
}
.switcher .sw-row .st.needs {
  color: var(--needs-ink);
}
.switcher .sw-row .st.failed {
  color: var(--failed-ink);
}
@media (prefers-reduced-motion: reduce) {
  .onhand-list .bulk,
  .switcher {
    animation: none;
  }
}
/* ---------- D214: 工作台 / Workbench, beside the opened task ---------- */
:root {
  --bench-w: clamp(380px, 42vw, 760px);
  --code-bg: var(--surface);
  --code-ln: var(--faint);
  --code-add: #e3f6e6;
  --code-add-ink: #1f5e2f;
  --code-del: #fbe3e9;
  --code-del-ink: #8a1f3b;
  --code-hunk: var(--sunken);
  --tk-k: #b4511b;
  --tk-s: #2f7a46;
  --tk-c: #9a8a73;
  --tk-n: #7a4fb8;
  --tk-t: #1e6fb0;
  --tk-y: #8a5a12;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --code-bg: #1d1712;
    --code-add: #1b3322;
    --code-add-ink: #9fe3b1;
    --code-del: #3a1c24;
    --code-del-ink: #ffb3c4;
    --code-hunk: #231c16;
    --tk-k: #ffab73;
    --tk-s: #93d9a6;
    --tk-c: #8a7a66;
    --tk-n: #c9a7ff;
    --tk-t: #8cc8ff;
    --tk-y: #f2cf8a;
  }
}
:root[data-theme="dark"] {
  --code-bg: #1d1712;
  --code-add: #1b3322;
  --code-add-ink: #9fe3b1;
  --code-del: #3a1c24;
  --code-del-ink: #ffb3c4;
  --code-hunk: #231c16;
  --tk-k: #ffab73;
  --tk-s: #93d9a6;
  --tk-c: #8a7a66;
  --tk-n: #c9a7ff;
  --tk-t: #8cc8ff;
  --tk-y: #f2cf8a;
}

/* The toggle: a drawn panel mark in the header, raised like the header's other round buttons. */
.bench-toggle {
  width: 40px;
  height: 40px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: var(--r-btn);
  color: var(--ink-soft);
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), transform var(--t-press) var(--ease);
}
.bench-toggle:active { transform: translateY(1px); }
.bench-toggle.on {
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 3px 0 var(--line-2), inset 0 0 0 1px var(--rim);
}
@media (hover: hover), (any-hover: hover) {
  .bench-toggle:hover { background: var(--surface-sunken); color: var(--ink); }
  .bench-toggle.on:hover { background: var(--surface); }
}

/* Wide: the task keeps its column, the workbench stands at the right on a hairline. */
.full.benched { padding-right: var(--bench-w); }
.bench.as-column {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: var(--bench-w);
  display: flex;
  flex-direction: column;
  background: var(--bg-deep);
  border-left: 1px solid var(--line);
  padding-right: var(--safe-right);
  animation: bench-in var(--t-med) var(--ease);
}
@keyframes bench-in {
  from { transform: translateX(24px); opacity: 0; }
}
.bench-resize {
  position: absolute;
  left: -5px;
  top: 0;
  bottom: 0;
  width: 10px;
  cursor: col-resize;
  z-index: 2;
  touch-action: none;
}
.bench-resize::after {
  content: "";
  position: absolute;
  left: 3px;
  top: 50%;
  width: 4px;
  height: 40px;
  margin-top: -20px;
  border-radius: var(--pill);
  background: var(--line-2);
  opacity: 0;
  transition: opacity var(--t-fast) var(--ease);
}
.bench-resize:hover::after,
.bench-resize:focus-visible::after { opacity: 1; }

/* Phone: a sheet over the task; its pages swipe, the strip follows. */
.bench.as-sheet {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  background: var(--bg-deep);
  padding: var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left);
  animation: bench-up var(--t-med) var(--ease);
}
@keyframes bench-up {
  from { transform: translateY(32px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .bench.as-column, .bench.as-sheet { animation: none; }
}
.bench-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 60px;
  padding: 8px 10px 8px 12px;
  border-bottom: 1px solid var(--line);
}
.bench-tabs {
  flex: 1;
  min-width: 0;
  display: flex;
  gap: 4px;
  padding: 4px;
  border-radius: var(--r-md);
  background: var(--surface-sunken);
  overflow-x: auto;
  scrollbar-width: none;
}
.bench-tabs::-webkit-scrollbar { display: none; }
.bench-tab {
  flex: none;
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 14px;
  border-radius: var(--r-sm);
  font-size: var(--sm);
  font-weight: 600;
  color: var(--ink-muted);
  white-space: nowrap;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.bench-tab.on {
  background: var(--surface);
  color: var(--ink);
  font-weight: 800;
  box-shadow: 0 2px 0 var(--line-2);
}
.bench-count {
  font-family: var(--mono);
  font-size: var(--xs);
  font-weight: 600;
  min-width: 20px;
  padding: 1px 6px;
  border-radius: var(--pill);
  background: var(--bg);
  color: var(--ink-soft);
  text-align: center;
}
.bench-x {
  flex: none;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: var(--pill);
  color: var(--ink-soft);
}
@media (hover: hover), (any-hover: hover) {
  .bench-x:hover { background: var(--surface-sunken); color: var(--ink); }
}
.bench-pages {
  flex: 1;
  min-height: 0;
  display: flex;
}
.bench.as-sheet .bench-pages {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.bench.as-sheet .bench-pages::-webkit-scrollbar { display: none; }
.bench-page {
  flex: 0 0 100%;
  min-width: 0;
  overflow-y: auto;
  scroll-snap-align: start;
  padding: 16px 16px 32px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.bench-page.page-preview, .bench-page.page-browser, .bench-page.page-phone { padding: 12px; }
.bench-note {
  margin: 0;
  font-size: var(--sm);
  line-height: var(--lh-read);
  color: var(--ink-soft);
}
.bench-note.quiet { color: var(--ink-muted); }
.bench-note.warn { padding: 8px 12px; border-radius: var(--r-sm); background: var(--waiting-surface); color: var(--waiting-ink); }
.wb-h { margin: 4px 0 8px; font-size: var(--xs); font-weight: 800; letter-spacing: 0.02em; color: var(--ink-muted); }

/* Changes: one header line, then a list of files on a raised card. */
.wb-sum {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink);
}
.wb-sum .grow, .wb-acts .grow, .wb-bar .grow { flex: 1; }
.wb-base { font-weight: 500; color: var(--ink-muted); font-size: var(--xs); }
.wb-n { display: inline-flex; gap: 6px; font-family: var(--mono); font-size: var(--xs); font-weight: 600; flex: none; color: var(--ink-muted); }
.wb-n .add { color: var(--done-ink); }
.wb-n .del { color: var(--failed-ink); }
.wb-list {
  list-style: none;
  margin: 0;
  padding: 4px;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--base), inset 0 0 0 1px var(--rim);
}
.wb-row {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 6px 12px;
  border-radius: var(--r-md);
  text-align: left;
  color: var(--ink);
}
@media (hover: hover), (any-hover: hover) {
  .wb-row:hover { background: var(--surface-sunken); }
}
.wb-row .fmark { flex: none; color: var(--ink-muted); }
.wb-row.st-added .fmark { color: var(--done-ink); }
.wb-row.st-deleted .fmark { color: var(--failed-ink); }
.wb-row.st-modified .fmark, .wb-row.st-renamed .fmark { color: var(--working-ink); }
.wb-path { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 8px; }
.wb-path .nm { font-family: var(--mono); font-size: var(--sm); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: none; max-width: 70%; }
.wb-path .dir { font-family: var(--mono); font-size: var(--xs); color: var(--ink-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.wb-path.big { flex-direction: column; gap: 2px; }
.wb-path.big .nm { font-size: var(--md); font-weight: 800; max-width: 100%; }
.wb-st { flex: none; font-size: var(--xs); color: var(--ink-muted); }
.wb-crumb { display: flex; }
.wb-back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 32px;
  padding: 0 10px 0 4px;
  border-radius: var(--r-sm);
  font-size: var(--sm);
  font-weight: 700;
  color: var(--ink-soft);
}
@media (hover: hover), (any-hover: hover) {
  .wb-back:hover { background: var(--surface-sunken); color: var(--ink); }
}
.wb-file-head { display: flex; align-items: flex-end; gap: 12px; }
.wb-file-head .wb-path { flex: 1; }
.wb-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wb-unsaved { font-size: var(--xs); color: var(--waiting-ink); font-weight: 700; }
.wb-confirm { margin: 0; }

/* Code: on the theme's paper, in a sunken well; numbers in the faint ink. */
.code {
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 20px;
  border-radius: var(--r-md);
  background: var(--code-bg);
  box-shadow: inset 0 0 0 1px var(--line), inset 0 2px 0 var(--line-soft);
  overflow: auto;
  tab-size: 2;
  -webkit-text-size-adjust: 100%;
  flex: none;
}
.code.view, .code.wdiff { padding: 8px 0; }
.code .cl, .code .wl { display: flex; min-width: max-content; }
.code .ln {
  flex: none;
  width: 3.4em;
  padding-right: 10px;
  text-align: right;
  color: var(--code-ln);
  user-select: none;
  -webkit-user-select: none;
}
.code .tx { white-space: pre; padding-right: 16px; color: var(--ink); }
.code .sg { flex: none; width: 1.2em; text-align: center; user-select: none; -webkit-user-select: none; }
.code .wl .ln { width: 3em; }
.code .wl.add { background: var(--code-add); }
.code .wl.add .sg { color: var(--code-add-ink); }
.code .wl.del { background: var(--code-del); }
.code .wl.del .sg { color: var(--code-del-ink); }
.code .wl.hunk { background: var(--code-hunk); margin: 6px 0; }
.code .wl.hunk:first-child { margin-top: 0; }
.code .wl.hunk .tx { color: var(--ink-muted); font-style: italic; }
.code .wl.hunk .ln { min-height: 20px; }
.wb-more { margin: 8px 16px; }
.tk-k { color: var(--tk-k); }
.tk-s { color: var(--tk-s); }
.tk-c { color: var(--tk-c); font-style: italic; }
.tk-n { color: var(--tk-n); }
.tk-t { color: var(--tk-t); }
.tk-y { color: var(--tk-y); }
/* The editor: the textarea sits exactly over its coloured copy and scrolls with it (both in .ed). */
.code.editor { display: flex; padding: 8px 0; }
.code.editor .gutter { flex: none; display: flex; flex-direction: column; width: 3.4em; padding-right: 10px; text-align: right; color: var(--code-ln); user-select: none; -webkit-user-select: none; }
.code.editor .ed { position: relative; flex: 1; min-width: max-content; }
.code.editor .ed-hl, .code.editor .ed-ta {
  margin: 0;
  padding: 0 16px 0 0;
  font: inherit;
  line-height: inherit;
  white-space: pre;
  tab-size: 2;
  border: 0;
  letter-spacing: 0;
}
.code.editor .ed-hl { color: var(--ink); pointer-events: none; }
.code.editor .ed-ta {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  resize: none;
  overflow: hidden;
  background: transparent;
  color: transparent;
  -webkit-text-fill-color: transparent;
  caret-color: var(--accent);
  outline: none;
}
.code.editor .ed-ta::selection { background: var(--highlight); }
@media (pointer: coarse) {
  /* iOS zooms into a field under 16px: the editor reads at 16 there. */
  .code.editor { font-size: 16px; line-height: 24px; }
}
.wb-image { padding: 16px; border-radius: var(--r-md); background: var(--code-bg); box-shadow: inset 0 0 0 1px var(--line); display: grid; place-items: center; }
.wb-image img { max-width: 100%; max-height: 60vh; }

/* Files: a windowed tree; changed files carry their status ink and a small dot. */
.bench-page.page-files { padding-bottom: 0; }
.wb-tree { flex: 1; min-height: 240px; overflow: auto; margin: -4px -8px 0; }
.wb-node {
  position: absolute;
  left: 0;
  right: 0;
  height: 30px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding-right: 12px;
  border-radius: var(--r-sm);
  font-family: var(--mono);
  font-size: var(--sm);
  color: var(--ink);
  text-align: left;
}
@media (hover: hover), (any-hover: hover) {
  .wb-node:hover { background: var(--surface-sunken); }
}
.wb-node .caret { width: 12px; flex: none; color: var(--ink-muted); transition: transform var(--t-fast) var(--ease); }
.wb-node .fmark { flex: none; color: var(--ink-muted); }
.wb-node .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wb-node.heavy .nm { color: var(--ink-muted); }
.wb-node.st-added .nm { color: var(--done-ink); }
.wb-node.st-modified .nm, .wb-node.st-renamed .nm, .wb-node.has .nm { color: var(--working-ink); }
.wb-node.st-deleted .nm { color: var(--failed-ink); text-decoration: line-through; }
.wb-node .dot { width: 6px; height: 6px; border-radius: 50%; flex: none; background: var(--working-dot); }
.wb-node .dot.st-added { background: var(--done-dot); }

/* Preview: a bar, then the page on a stage; narrower widths center the page like a device. */
.wb-preview { flex: 1; display: flex; flex-direction: column; gap: 10px; min-height: 0; }
.wb-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wb-where { min-width: 0; display: flex; flex-direction: column; }
.wb-where .nm { font-weight: 800; font-size: var(--sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wb-where .dir { font-size: var(--xs); color: var(--ink-muted); }
.wb-select { max-width: 60%; min-height: 36px; padding: 0 10px; border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--surface); color: var(--ink); font: inherit; font-size: var(--sm); }
.seg.sm { padding: 3px; gap: 2px; }
.seg.sm button { min-height: 30px; padding: 0 10px; font-size: var(--xs); flex: none; }
.wb-icon { width: 36px; height: 36px; display: grid; place-items: center; border-radius: var(--r-sm); color: var(--ink-soft); }
.wb-icon:disabled { opacity: 0.4; }
@media (hover: hover), (any-hover: hover) {
  .wb-icon:not(:disabled):hover { background: var(--surface-sunken); color: var(--ink); }
}
.wb-stage {
  flex: 1;
  min-height: 320px;
  display: flex;
  justify-content: center;
  border-radius: var(--r-lg);
  background: var(--sunken);
  box-shadow: inset 0 0 0 1px var(--line);
  overflow: auto;
}
.wb-stage.w-phone, .wb-stage.w-tablet { padding: 20px 0; }
.wb-frame {
  flex: none;
  width: 100%;
  min-height: 300px;
  border: 0;
  border-radius: var(--r-lg);
  background: #fff;
}
.wb-stage.w-phone .wb-frame, .wb-stage.w-tablet .wb-frame {
  border-radius: 28px;
  box-shadow: 0 0 0 8px var(--surface), 0 0 0 9px var(--line-2), var(--floating);
}
.wb-far { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; padding: 8px 0; }

/* One screen frame for every screen a task drives: the browser, a phone, a computer. */
.screen { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 8px; }
.screen-head { display: flex; align-items: center; gap: 10px; min-height: 28px; }
.screen-where { font-size: var(--xs); color: var(--ink-muted); }
.driver {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 12px 4px 8px;
  border-radius: var(--pill);
  font-size: var(--xs);
  font-weight: 800;
}
.driver.agent { background: var(--working-surface); color: var(--working-ink); }
.driver.you { background: var(--waiting-surface); color: var(--waiting-ink); }
.driver-mark { width: 14px; height: 14px; border-radius: 50%; background: currentColor; box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.18), 0 1px 0 rgba(0, 0, 0, 0.12); }
.screen-body {
  flex: 1;
  min-height: 360px;
  display: flex;
  flex-direction: column;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--base), inset 0 0 0 1px var(--rim);
}
.screen-wait { margin: auto; padding: 24px; display: flex; flex-direction: column; gap: 14px; align-items: center; text-align: center; max-width: 28em; }
/* The live view, inside the frame instead of over the screen. */
.live.in-bench { position: relative; inset: auto; z-index: auto; flex: 1; min-height: 0; padding: 0; background: var(--surface); }
.live.in-bench .live-bottom { min-height: 64px; }

/* Results */
.wb-made { display: flex; flex-direction: column; gap: 16px; }
.code .wl.hunk.bare { margin: 0; height: 6px; overflow: hidden; }
.code .wl.hunk.bare:first-child { display: none; }
.code { font-variant-ligatures: none; font-feature-settings: "liga" 0, "calt" 0; }
.code .cl, .code .wl { align-items: baseline; }
.code .ln { font-variant-numeric: tabular-nums; }
.as-sheet .wb-bar .seg { display: none; }
.as-sheet .code .wl .ln:first-child { display: none; }
.as-sheet .bench-tab { padding: 0 12px; }
/* D217 · Ducter's phone. The live view is D190's (.live) with the screen shown as a phone's: its
   own rounded glass on the sunken page, the Android keys under it in the user's turn. */
.phone-live .phone-page { align-items: center; padding: var(--s3) var(--s3) 0; box-sizing: border-box; }
.phone-live .phone-page img.phone-screen { max-height: 100%; max-width: 100%; border-radius: var(--r-xl); box-shadow: var(--base); background: #000; }
.phone-live.embedded { position: relative; inset: auto; z-index: auto; height: 100%; padding: 0; }
.phone-keys { flex: none; display: flex; justify-content: center; gap: var(--s5, 28px); padding: 4px 12px 0; background: var(--sunken); }
.phone-keys .btn { min-width: 52px; color: var(--ink-soft); }
.phone-block .phone-bar { height: 6px; margin: 8px 0 4px; border-radius: 3px; background: var(--line-soft); overflow: hidden; }
.phone-block .phone-bar > span { display: block; height: 100%; border-radius: 3px; background: var(--accent); transition: width 400ms var(--ease, ease-out); }
.sheet.phone-install .phone-install-art { display: block; width: 64px; height: auto; margin: 4px auto 6px; }
.sheet.phone-install h2 { text-align: center; }
.sheet.phone-install .lede { margin: 0 0 var(--s3); font-size: var(--sm); line-height: 1.55; color: var(--ink-soft); text-align: center; }
.phone-facts { display: grid; grid-template-columns: max-content 1fr; gap: 6px 14px; margin: 0 0 var(--s3); font-size: var(--sm); line-height: 1.45; }
.phone-facts dt { color: var(--ink-muted); }
.phone-facts dd { margin: 0; color: var(--ink); }
.phone-lic { display: flex; flex-direction: column; gap: 4px; padding: 10px 12px; border-radius: 12px; background: var(--bg); }
.phone-lic-head { display: flex; width: 100%; align-items: baseline; gap: 10px; padding: 8px 0; border: 0; background: none; color: var(--ink); font: inherit; font-size: var(--sm); font-weight: 700; text-align: left; cursor: pointer; }
.phone-lic-head > span { flex: 1; min-width: 0; }
.phone-lic-head > small { flex: none; color: var(--accent-ink, var(--ink-muted)); font-weight: 700; }
.phone-lic-text { max-height: 220px; overflow: auto; margin: 4px 0 6px; padding: 8px 10px; border-radius: var(--r-sm); background: var(--surface); font: inherit; font-size: var(--xs); line-height: 1.5; white-space: pre-wrap; color: var(--ink-soft); }
.phone-agree { display: flex; align-items: flex-start; gap: 8px; margin-top: 6px; font-size: var(--sm); line-height: 1.45; color: var(--ink); cursor: pointer; }
.phone-agree input { margin-top: 3px; accent-color: var(--accent); }
.sheet.phone-install .btns { display: flex; gap: 10px; margin-top: var(--s3); }
.sheet.phone-install .btns .btn { flex: 1; }

/* D220 · the iOS Simulator on the Phone page: the screen at its own shape on the sunken stage,
   the rail of simctl's controls beside it (under it on a phone), the view-only line under all. */
.screens { flex: none; }
.sim { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 10px; padding: 12px; }
.sim-main { flex: 1; min-height: 0; display: flex; gap: 10px; }
.sim-stage { flex: 1; min-width: 0; min-height: 300px; display: flex; align-items: center; justify-content: center; }
.sim-screen {
  display: block;
  max-width: 100%;
  max-height: 100%;
  height: 100%;
  width: auto;
  object-fit: contain;
  border-radius: 9% / 4.2%; /* an iPhone's own corners, in proportion */
  background: #000;
  box-shadow: 0 0 0 6px var(--surface), 0 0 0 7px var(--line-2), var(--base);
  user-select: none;
  -webkit-user-drag: none;
}
.sim-wait { margin: auto; text-align: center; }
.sim-rail {
  flex: none;
  align-self: center;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px;
  border-radius: var(--pill);
  background: var(--surface-sunken);
  box-shadow: inset 0 0 0 1px var(--line);
}
.sim-btn {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: var(--pill);
  color: var(--ink-soft);
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), transform var(--t-press) var(--ease);
}
.sim-btn:active { transform: translateY(1px); }
.sim-btn.on { background: var(--surface); color: var(--ink); box-shadow: 0 2px 0 var(--line-2); }
.sim-btn.busy { color: var(--working-ink); }
@media (hover: hover), (any-hover: hover) {
  .sim-btn:hover { background: var(--surface); color: var(--ink); }
}
.sim-pop { align-self: flex-end; display: flex; gap: 2px; padding: 3px; border-radius: var(--r-md); background: var(--surface-sunken); }
.sim-pop button { min-height: 32px; padding: 0 12px; border-radius: var(--r-sm); font-size: var(--xs); font-weight: 600; color: var(--ink-muted); }
.sim-pop button.on { background: var(--surface); color: var(--ink); font-weight: 800; box-shadow: 0 2px 0 var(--line-2); }
.sim-link { display: flex; gap: 8px; align-items: center; }
.sim-link-in { flex: 1; min-width: 0; min-height: 36px; padding: 0 12px; border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--surface); color: var(--ink); font: inherit; font-size: var(--sm); }
.sim-note { text-align: center; font-size: var(--xs); }
.as-sheet .sim-main { flex-direction: column; }
.as-sheet .sim-rail { flex-direction: row; }
.as-sheet .sim-pop { align-self: center; }

/* D220 · 工作副本 / Working copy: its branch (or folder) in the header, and what it opens. */
.info-anchor { position: relative; display: inline-flex; flex: none; }
.info-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 40px;
  max-width: 280px;
  padding: 0 10px 0 12px;
  border-radius: var(--r-btn);
  color: var(--ink-soft);
  font-size: var(--sm);
  font-weight: 700;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.info-btn .info-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono); font-size: var(--xs); font-weight: 600; }
.info-btn .chev-g { flex: none; opacity: 0.7; }
.info-btn.on { background: var(--surface); color: var(--ink); box-shadow: 0 3px 0 var(--line-2), inset 0 0 0 1px var(--rim); }
@media (hover: hover), (any-hover: hover) {
  .info-btn:hover { background: var(--surface-sunken); color: var(--ink); }
  .info-btn.on:hover { background: var(--surface); }
}
@media (max-width: 699px) {
  .info-btn { width: 40px; padding: 0; justify-content: center; }
  .info-btn .info-label, .info-btn .chev-g { display: none; }
}
.info-mk { flex: none; }
.info-pop:not(.as-sheet) {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 40;
  width: min(380px, calc(100vw - 32px));
  padding: 8px;
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--floating), inset 0 0 0 1px var(--rim);
  animation: info-in var(--t-fast) var(--ease);
  text-align: left;
}
@keyframes info-in {
  from { transform: translateY(-4px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .info-pop { animation: none; }
}
.info-pop.as-sheet { z-index: 60; }
.info-rows { margin: 0; display: flex; flex-direction: column; }
.info-row { display: grid; grid-template-columns: 92px 1fr; gap: 10px; align-items: baseline; padding: 9px 8px; }
.info-row + .info-row { border-top: 1px solid var(--line-soft); }
.info-pop:focus { outline: none; }
.info-row dt { display: flex; align-items: center; gap: 7px; font-size: var(--xs); font-weight: 700; color: var(--ink-muted); }
.info-row dd { margin: 0; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; font-size: var(--sm); color: var(--ink); }
.info-row code { font-family: var(--mono); font-size: var(--xs); overflow-wrap: anywhere; color: var(--ink); user-select: text; }
.info-path code { flex-basis: 100%; }
.info-sub { font-size: var(--xs); color: var(--ink-muted); }
.info-changes { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; padding: 0; text-align: left; color: var(--ink); font-size: var(--sm); }
.info-changes .info-n { color: var(--ink-soft); }
.info-changes .add { font-family: var(--mono); font-size: var(--xs); color: var(--done-ink); }
.info-changes .del { font-family: var(--mono); font-size: var(--xs); color: var(--failed-ink); }
.info-changes .chev-g { align-self: center; color: var(--ink-muted); }
@media (hover: hover), (any-hover: hover) {
  .info-changes:not(:disabled):hover > span:first-child { text-decoration: underline; text-underline-offset: 3px; }
}
.info-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px; padding: 10px 8px 6px; border-top: 1px solid var(--line-soft); margin-top: 2px; }
.info-acts .done-ink { color: var(--done-ink); font-weight: 700; }
.info-who { padding: 8px 8px 4px; border-top: 1px solid var(--line-soft); margin-top: 2px; }
.info-who h3 { margin: 0 0 6px; display: flex; align-items: center; gap: 7px; font-size: var(--xs); font-weight: 700; color: var(--ink-muted); }
.info-who ol { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px; }
.info-who li { display: flex; align-items: center; gap: 8px; font-size: var(--sm); line-height: 1.3; }
.info-who li .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.info-who li .when { font-size: var(--xs); color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.info-who li:last-child .nm { font-weight: 700; }
/* ---------- D222: calendars (design/calendar.md §6; calendar.tsx). A literal agenda in Pebble clay:
   tokens only; a calendar's own colour appears only as an 8px dot or a 3px rail (inline, from data). ---------- */
.partner.has-cal { max-width: 100%; align-self: stretch; }
.partner.has-cal > .bubble { max-width: min(88%, var(--bubble-measure)); }
/* 6.1 the day card: a surface card on its clay ledge, the partner's column wide (at most 560). */
.cal-card { display: flex; flex-direction: column; gap: var(--s3); width: min(100%, 560px); box-sizing: border-box; padding: var(--s4); border-radius: var(--r-md); background: var(--surface); box-shadow: var(--base); animation: cal-rise 220ms var(--ease) both; }
.cal-card.week { gap: var(--s4); }
@keyframes cal-rise { from { opacity: 0; transform: translateY(8px); } }
.cal-day { display: flex; flex-direction: column; gap: 6px; }
.cal-card.week .cal-day + .cal-day { padding-top: var(--s3); border-top: 1px solid var(--line-soft); }
.cal-head { font-family: var(--head); font-size: var(--md); font-weight: 800; color: var(--ink); line-height: 1.3; }
.cal-dh { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; font-size: var(--sm); font-weight: 700; color: var(--ink-soft); line-height: 1.35; }
.cal-dh .none, .cal-none { font-size: var(--xs); font-weight: 500; color: var(--ink-muted); }
.cal-day.empty .cal-dh { font-weight: 500; }
.cal-marks { margin-top: -4px; font-size: var(--xs); color: var(--ink-muted); line-height: 1.4; }
.cal-rows { display: flex; flex-direction: column; margin: 0 calc(-1 * var(--s2)); }
.cal-row { position: relative; display: grid; grid-template-columns: 3.1em 3px minmax(0, 1fr); column-gap: var(--s3); align-items: stretch; padding: 7px var(--s2); border-radius: var(--r-xs); color: inherit; text-decoration: none; -webkit-tap-highlight-color: transparent; transition: background var(--t-fast) ease-out; }
a.cal-row { cursor: pointer; }
@media (hover: hover) { a.cal-row:hover { background: var(--sunken); } }
a.cal-row:active { background: var(--sunken); }
a.cal-row:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.cal-row.past > * { opacity: 0.55; }
.cal-t { display: flex; flex-direction: column; padding-top: 1px; font-variant-numeric: tabular-nums; white-space: nowrap; line-height: 1.3; }
.cal-t .s { font-size: var(--sm); font-weight: 600; color: var(--ink-soft); }
.cal-t .e { font-size: var(--xs); color: var(--ink-muted); }
.cal-row.allday .cal-t .s { font-size: var(--xs); font-weight: 700; color: var(--ink-muted); }
.cal-rail { display: block; width: 3px; min-height: 18px; border-radius: 3px; background: var(--faint); }
.cal-b { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cal-tl { display: flex; align-items: center; gap: 6px; min-width: 0; }
.cal-ti { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--md); font-weight: 600; color: var(--ink); line-height: 1.35; }
.cal-row.allday .cal-ti { font-size: var(--sm); }
.cal-row.free .cal-ti { color: var(--ink-soft); font-weight: 500; }
.cal-meta { font-size: var(--xs); color: var(--ink-muted); line-height: 1.45; overflow-wrap: anywhere; }
.cal-meta .part { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: pre; vertical-align: bottom; }
.cal-chip { flex: none; padding: 0 7px; border-radius: var(--pill); font-size: 11px; font-weight: 700; line-height: 18px; white-space: nowrap; }
.cal-chip.ask { background: var(--waiting-surface); color: var(--waiting-ink); }
.cal-chip.maybe { background: var(--sunken); color: var(--ink-soft); }
.cal-chip.clash { background: var(--failed-surface); color: var(--failed-ink); }
/* A clash: a thin bracket at the time column's edge joins the rows that overlap. */
.cal-row.clash::before { content: ""; position: absolute; left: 1px; top: 0; bottom: 0; width: 4px; border-left: 1.5px solid var(--failed-dot); }
.cal-row.clash.ctop::before { top: 10px; border-top: 1.5px solid var(--failed-dot); border-top-left-radius: 4px; }
.cal-row.clash.cbot::before { bottom: 10px; border-bottom: 1.5px solid var(--failed-dot); border-bottom-left-radius: 4px; }
/* Now: an accent line with a dot on the rails' line (today only). */
.cal-now { position: relative; height: 0; margin: 1px var(--s2) 1px calc(var(--s2) + 3.1em + var(--s3) - 1.5px); border-top: 1.5px solid var(--accent); animation: fade 220ms ease-out 120ms both; }
.cal-now .dot { position: absolute; left: -1.5px; top: -4.25px; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
@media (prefers-reduced-motion: reduce) { .cal-card, .cal-now { animation: none; } }

/* 6.2 the change card: one sunken block under the question, then the tray. */
.cal-change { display: flex; flex-direction: column; gap: 5px; width: min(88%, var(--bubble-measure)); box-sizing: border-box; padding: var(--s3) var(--s3) var(--s3) 14px; border-radius: var(--r-sm); background: var(--sunken); color: var(--ink-soft); }
.cal-change > * { font-size: var(--sm); line-height: 1.5; }
.decision .cal-change { width: 100%; margin: var(--s2) 0; }
.cc-title { display: flex; align-items: stretch; gap: 10px; margin-bottom: 2px; }
.cc-title .cal-rail { min-height: 20px; flex: none; }
.cc-title b { font-size: var(--md); font-weight: 700; color: var(--ink); line-height: 1.4; }
.cc-when { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.cc-when.move { display: flex; flex-direction: column; gap: 1px; }
.cc-move { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; }
.cc-was { color: var(--ink-muted); font-weight: 500; }
.cc-was s { text-decoration-thickness: 1px; }
.cal-arrow { flex: none; color: var(--ink-muted); }
.cc-their { color: var(--ink-soft); }
.cc-line { display: flex; align-items: center; gap: 6px; }
.cc-k { color: var(--ink-muted); }
.cc-whose { color: var(--ink-muted); }
.cc-line.clash { color: var(--failed-ink); font-weight: 600; }
.cal-dot { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--faint); }
/* After Go or Hold: the card settles in place. */
.cal-settle { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; min-height: 32px; padding-left: 14px; font-size: var(--sm); font-weight: 700; color: var(--ink-soft); animation: settle 320ms var(--spring); }
.cal-settle .mark { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; }
.cal-settle.done .mark { background: var(--done-surface); color: var(--done-ink); }
.cal-settle.done .btn { margin-left: -4px; }
.cal-settle.failed { color: var(--failed-ink); }
.cal-settle.failed .mark { background: var(--failed-surface); color: var(--failed-ink); }
.cal-settle.failed .why { display: block; font-weight: 500; font-size: var(--xs); }
.cal-settle.quiet { font-weight: 500; color: var(--ink-muted); }
.cal-settle.said { align-self: flex-end; font-weight: 500; color: var(--ink-muted); }
.decision .cal-settle { padding-left: 0; }

/* 6.3 the greeting's today line: quiet, one row, a drawn calendar. */
.hello-today { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; margin-top: 2px; padding: 8px 14px; border: 0; border-radius: var(--pill); background: var(--sunken); color: var(--ink-soft); font: inherit; font-size: var(--sm); font-weight: 600; line-height: 1.4; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: transform var(--t-press) ease-out; }
.hello-today:active { transform: translateY(1px); }
.hello-today .cal-glyph { flex: none; color: var(--accent); }

/* §4 Accounts: the calendars inside a calendar account, and the lines under the tray. */
.tile-detail .td-cals { display: flex; flex-direction: column; padding-top: 10px; border-top: 1px solid var(--line-soft); }
.tile-detail .td-cals .td-k { margin-bottom: 2px; font-size: var(--sm); font-weight: 700; color: var(--ink-muted); }
.tile-detail .td-cals .switch { min-height: 0; padding: 10px 0; align-items: flex-start; font-size: var(--sm); font-weight: 600; }
.tile-detail .td-cals .switch input { margin-top: -4px; }
.tile-detail .td-cals .switch > span.cal-dot { margin-top: 5px; }
.switch.lead > span.cal-dot { flex: none; width: 8px; height: 8px; margin-right: -2px; }
.tile-detail .td-cals .switch small { display: block; font-size: var(--xs); font-weight: 500; color: var(--ink-muted); }
.cal-line { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 0 4px; }
.cal-line .small.soft { color: var(--ink-soft); line-height: 1.5; }
.cal-line .btn.text { margin-left: -10px; }
.cal-line.nudge .acts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 4px; }

/* D224: 全部更新 / Update all — one card at the top of 你的设备; a list that ticks itself off. */
.ua { display: flex; flex-direction: column; gap: var(--s2); margin: 0 0 var(--s4); padding: var(--s4); border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--base); }
.ua-head b { font-size: var(--md); font-weight: 800; }
.ua-list { display: flex; flex-direction: column; }
.ua-row { display: grid; grid-template-columns: 18px minmax(0, 1fr); column-gap: 10px; align-items: center; padding: 7px 0; }
.ua-row + .ua-row { border-top: 1px solid var(--line-soft); }
.ua-what { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s2); min-width: 0; }
.ua-name { font-size: var(--sm); font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.ua-ver { flex: none; font-size: var(--xs); color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.ua-state, .ua-why { grid-column: 2; font-size: var(--xs); line-height: 1.45; color: var(--ink-muted); }
.ua-state.running, .ua-state.waiting { color: var(--working-ink); }
.ua-state.done { color: var(--done-ink); }
.ua-state.failed { color: var(--failed-ink); font-weight: 650; }
.ua-why { color: var(--ink-soft); }
.ua-mark { grid-row: 1; align-self: center; }
.ua-mark .spin { transform-origin: 9px 9px; animation: ua-spin 1.1s linear infinite; }
.ua-mark.done { animation: ua-pop 420ms cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes ua-spin { to { transform: rotate(360deg); } }
@keyframes ua-pop { 0% { transform: scale(0.6); } 100% { transform: scale(1); } }
.ua-more { padding: 6px 0 0 28px; font-size: var(--xs); color: var(--ink-muted); }
.ua-note { font-size: var(--sm); line-height: 1.5; color: var(--ink-soft); }
.ua-note.quiet { font-size: var(--xs); color: var(--ink-muted); }
.ua-act { display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap; }
.ua-act:empty { display: none; }
.set-row small.update { color: var(--highlight-ink); font-weight: 700; }
@media (prefers-reduced-motion: reduce) {
  .ua-mark .spin, .ua-mark.done { animation: none; }
}
/* D226: 今天看了什么 / What it looked at today, under the switch (Settings › Notifications). */
.quiet-day { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 0 4px; }
.quiet-day .reads { align-self: stretch; }
/* The reading problem, two lines at most on a phone: balanced, never a lone clause on the second. */
.quiet-day > .warn { text-wrap: balance; }
/* D226: the day in short groups (came in · read and said · held · how it stands); a rule's leftovers and a status softer. */
.reads.day { gap: 10px; padding: 12px 14px; line-height: 1.5; font-variant-numeric: tabular-nums; }
.reads.day .day-group { display: flex; flex-direction: column; gap: 2px; }
.reads.day .read.soft { color: var(--ink-muted); }
.reads.day .honest { margin-top: 0; padding-top: 8px; }
