/* Jot's look: one ink color on white (or white on black), soft gray fills instead of borders,
   capsule buttons, and the system font. The one other color is blue, kept for voice: the talking
   circle and a microphone that's on. Every text color here keeps at least 4.5:1 contrast against
   the surfaces it sits on, and text-box borders keep 3:1. */

:root {
  --bg: #ffffff;
  /* The page color, see-through: where the pinned header and composer fade out over the thread. */
  --bg-clear: rgb(255 255 255 / 0);
  --elevated: #ffffff;
  --elevated-clear: rgb(255 255 255 / 0);
  /* Fills are see-through grays, so one value reads the same on the page and inside a sheet. */
  --fill: rgb(118 118 128 / 0.09);
  --fill-strong: rgb(118 118 128 / 0.16);
  /* A lighter hover for rows that already sit on a fill, so their gray and red words keep 4.5:1. */
  --fill-hover: rgb(118 118 128 / 0.06);
  --bubble: rgb(118 118 128 / 0.12);
  --ink: #1d1d1f;
  --muted: #636368;
  --line: rgb(0 0 0 / 0.1);
  --hairline: 1px;
  /* Text-box borders need 3:1 against the page to be seen; --line is for dividers. */
  --field-line: #86868b;
  --accent: #1d1d1f;
  --accent-ink: #ffffff;
  --danger: #d70015;
  /* Filled destructive buttons. --danger is for red words. */
  --danger-fill: #d70015;
  --danger-ink: #ffffff;
  --danger-soft: #fdecee;
  /* A pressed control darkens by a see-through gray, the way system controls highlight. */
  --press: rgb(118 118 128 / 0.14);
  --row-press: rgb(118 118 128 / 0.12);
  --focus: #0071e3;
  /* A short test timer's notice is a soft amber, used for nothing else, so it never reads as an
     ordinary gray note. */
  --test-bg: #fff4d4;
  --test-line: #e9c46a;
  --test-ink: #7a4a00;
  /* Voice blue: the talking circle's light, middle and deep tones, and a see-through glow for a
     microphone that's listening. */
  --voice-light: #a8d4ff;
  --voice: #2f80ed;
  --voice-deep: #1546b8;
  --voice-glow: rgb(47 128 237 / 0.18);
  --voice-shadow: rgb(21 70 184 / 0.35);
  --mark-tile: #1d1d1f;
  --mark-glyph: #ffffff;
  --shadow: 0 1px 2px rgb(0 0 0 / 0.05), 0 6px 20px rgb(0 0 0 / 0.06);
  /* One corner size for every gray block: banners, notices, the summary, lists, and text boxes. */
  --radius-block: 16px;
  --font: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', system-ui, Roboto, 'Helvetica Neue', Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --ease: cubic-bezier(0.32, 0.72, 0, 1);
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;
    --bg-clear: rgb(0 0 0 / 0);
    --elevated: #1c1c1e;
    --elevated-clear: rgb(28 28 30 / 0);
    --fill: rgb(120 120 128 / 0.2);
    --fill-strong: rgb(120 120 128 / 0.32);
    /* Darker, not lighter: a lighter row would take gray and red words below 4.5:1. */
    --fill-hover: rgb(0 0 0 / 0.22);
    /* Solid, so a message bubble stands clear of the black page. */
    --bubble: #262628;
    --ink: #f5f5f7;
    --muted: #9a9aa0;
    --line: rgb(255 255 255 / 0.12);
    --field-line: #78787e;
    --accent: #f5f5f7;
    --accent-ink: #000000;
    --danger: #ff6b61;
    /* Red with white words, as system destructive buttons are; the lighter --danger is for words. */
    --danger-fill: #e3201b;
    --danger-ink: #ffffff;
    --danger-soft: #3a1614;
    --press: rgb(120 120 128 / 0.2);
    /* Darker, like --fill-hover, so a row's gray and red words keep 4.5:1 while pressed. */
    --row-press: rgb(0 0 0 / 0.22);
    --focus: #4c9bff;
    --test-bg: #2b2106;
    --test-line: #6b5312;
    --test-ink: #ffcc4d;
    --voice-light: #b4dcff;
    --voice: #3d8bff;
    --voice-deep: #1c4fd6;
    --voice-glow: rgb(61 139 255 / 0.3);
    --voice-shadow: rgb(61 139 255 / 0.35);
    /* A quiet tile, so the mark isn't the brightest thing on a black screen. */
    --mark-tile: #2c2c2e;
    --mark-glyph: #f5f5f7;
    --shadow: 0 0 0 1px rgb(255 255 255 / 0.06), 0 8px 24px rgb(0 0 0 / 0.5);
  }
}

/* On Retina screens dividers are true hairlines, in the system's separator colors. */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {
  :root {
    --hairline: 0.5px;
    --line: rgb(60 60 67 / 0.29);
  }
}

@media (-webkit-min-device-pixel-ratio: 2) and (prefers-color-scheme: dark), (min-resolution: 2dppx) and (prefers-color-scheme: dark) {
  :root {
    --line: rgb(84 84 88 / 0.6);
  }
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 17px/1.47 var(--font);
  letter-spacing: -0.012em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-tap-highlight-color: transparent;
}

button,
input,
textarea {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

button {
  cursor: pointer;
}

/* Keeps a short last word from sitting alone on its own line. */
p,
li {
  text-wrap: pretty;
}

:focus-visible {
  outline: 2.5px solid var(--focus);
  outline-offset: 2px;
}

/* Headings and status lines take focus only so screen readers announce them; they aren't controls. */
[tabindex="-1"]:focus {
  outline: none;
}

[hidden] {
  display: none !important;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.icon {
  width: 1.25em;
  height: 1.25em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon .fill {
  fill: currentColor;
  stroke: none;
}

.mark {
  width: 28px;
  height: 28px;
  flex: none;
}

.mark-tile {
  fill: var(--mark-tile);
}

.mark-stem {
  fill: none;
  stroke: var(--mark-glyph);
  stroke-width: 2.7;
  stroke-linecap: round;
}

.mark-dot {
  fill: var(--mark-glyph);
}

/* ---------- Buttons ---------- */

.btn {
  appearance: none;
  border: 0;
  border-radius: 999px;
  min-height: 52px;
  width: 100%;
  padding: 13px 22px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
  background: var(--accent);
  color: var(--accent-ink);
  transition: transform 0.15s var(--ease), opacity 0.15s, background-color 0.15s, color 0.15s;
}

.btn:active:not(:disabled) {
  transform: scale(0.985);
  opacity: 0.88;
}

/* Disabled: a gray pill with gray words, the way system buttons dim, not a faded black one. */
.btn:disabled {
  background: var(--fill-strong);
  color: var(--muted);
  cursor: default;
}

.btn-secondary {
  background: var(--fill);
  color: var(--ink);
}

.btn-danger {
  background: var(--danger-fill);
  color: var(--danger-ink);
}

.btn-quiet {
  appearance: none;
  background: none;
  border: 0;
  border-radius: 999px;
  min-height: 48px;
  padding: 10px 16px;
  color: var(--ink);
  font-weight: 500;
}

/* Small controls keep their tidy shapes but still take a 44-point tap: an invisible hit area
   reaches past the shape. */
.btn-small {
  appearance: none;
  position: relative;
  border: 0;
  border-radius: 999px;
  min-height: 36px;
  padding: 7px 15px;
  background: var(--fill);
  color: var(--ink);
  font-size: 15px;
  font-weight: 500;
}

/* Up and down only: side by side, small buttons sit just 8px apart. */
.btn-small::after {
  content: '';
  position: absolute;
  inset: -4px 0;
}

.btn-small:disabled {
  opacity: 0.45;
  cursor: default;
}

.btn-small-danger {
  background: var(--danger-fill);
  color: var(--danger-ink);
  font-weight: 600;
}

/* Under a reply: quiet icon-and-word buttons, like the rest of the thread. */
.btn-action {
  appearance: none;
  border: 0;
  background: none;
  border-radius: 999px;
  min-height: 44px;
  padding: 10px 12px 10px 9px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 15px;
  font-weight: 500;
  transition: background-color 0.15s, color 0.15s;
}

.btn-action:active {
  background-color: var(--fill-strong);
  color: var(--ink);
}

.btn-action .icon {
  width: 18px;
  height: 18px;
}

.btn-action .icon-check,
.btn-action.copied .icon-copy {
  display: none;
}

.btn-action.copied {
  color: var(--ink);
}

.btn-action.copied .icon-check {
  display: block;
  animation: pop 0.25s var(--ease);
}

/* Listen turns into Stop while Jot reads the reply out loud. */
.btn-action .icon-stop,
.btn-action.playing .icon-speaker {
  display: none;
}

.btn-action.playing {
  color: var(--ink);
}

.btn-action.playing .icon-stop {
  display: block;
}

@keyframes pop {
  from {
    opacity: 0;
    transform: scale(0.5);
  }
}

.link-button {
  appearance: none;
  position: relative;
  background: none;
  border: 0;
  padding: 4px 0;
  font-size: inherit;
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--field-line);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.link-button::after {
  content: '';
  position: absolute;
  inset: -9px -6px;
}

@media (hover: hover) {
  .btn:hover:not(:disabled) {
    opacity: 0.9;
  }

  .btn-secondary:hover:not(:disabled),
  .btn-small:hover:not(:disabled),
  .btn-quiet:hover,
  .btn-action:hover,
  .menu-button:hover,
  .chip:hover {
    background-color: var(--fill-strong);
  }

  /* Lighter than the other hovers, so a paused status's red words keep 4.5:1 under the pointer. */
  .status-item:is(button):hover {
    background-color: var(--fill);
  }

  /* Darker, not fainter, so the white words keep their contrast. */
  .btn-small-danger:hover:not(:disabled),
  .btn-danger:hover:not(:disabled) {
    background: var(--danger-fill);
    opacity: 1;
    box-shadow: inset 0 0 0 999px rgb(0 0 0 / 0.1);
  }

  .btn-action:hover {
    color: var(--ink);
  }

  .menu-item:hover {
    background: var(--fill-hover);
  }

  .section-copy:hover,
  .mic[data-phase='idle']:hover {
    background-color: var(--fill-strong);
    color: var(--ink);
  }

  .mic.mic-labeled[data-phase='idle']:hover {
    background-color: var(--fill-strong);
  }
}

/* ---------- Onboarding, cleared, and sign-in screens ---------- */

.screen {
  min-height: 100vh;
  min-height: 100dvh;
  max-width: 540px;
  margin: 0 auto;
  padding: calc(20px + env(safe-area-inset-top)) max(24px, env(safe-area-inset-right)) calc(20px + env(safe-area-inset-bottom))
    max(24px, env(safe-area-inset-left));
  display: flex;
  flex-direction: column;
}

.screen-body {
  flex: 1;
}

/* Short screens (sign-in, switching person, can't reach, cleared) set their words in the middle,
   between the logo and the buttons, instead of at the top of an empty page. */
.screen-center .screen-body {
  display: flex;
  flex-direction: column;
}

.screen-center .screen-body > .brand {
  margin-bottom: auto;
}

/* Margins don't collapse in a flex column, so each paragraph keeps only the space below the one
   before it, as it would on a regular page. */
.screen-center .screen-body > p:not(.banner) {
  margin-top: 0;
}

.screen-center .cleared > p:last-child {
  margin-bottom: 0;
}

/* A little room under the words lifts them just above the true middle, where the eye expects them. */
.screen-center .screen-body::after {
  content: '';
  margin-top: auto;
  flex: 0 1 10vh;
}

.screen-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 28px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 600;
  font-size: 19px;
  letter-spacing: -0.02em;
  min-height: 44px;
}

.welcome-title {
  font-size: 32px;
  text-wrap: balance;
  line-height: 1.12;
  letter-spacing: -0.03em;
  font-weight: 700;
  margin: 28px 0 32px;
}

.promises {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 24px;
}

.promises li {
  display: grid;
  grid-template-columns: 30px 1fr;
  gap: 16px;
  align-items: start;
}

.promises .icon {
  width: 30px;
  height: 30px;
  stroke-width: 1.6;
  margin-top: 1px;
}

.promises strong {
  display: block;
  font-weight: 600;
  letter-spacing: -0.015em;
}

.promises span {
  display: block;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.45;
  letter-spacing: -0.005em;
  margin-top: 2px;
}

.step {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  margin: 18px 0 0;
}

.step-bar {
  display: flex;
  gap: 4px;
}

.step-bar i {
  width: 22px;
  height: 4px;
  border-radius: 2px;
  background: var(--fill-strong);
}

.step-bar i.done {
  background: var(--ink);
}

.question {
  font-size: 28px;
  text-wrap: balance;
  line-height: 1.18;
  letter-spacing: -0.025em;
  font-weight: 700;
  margin: 8px 0 24px;
}

/* Without a step line above it, a question needs room below the logo. */
.brand + .question {
  margin-top: 28px;
}

.hint {
  color: var(--muted);
  font-size: 15px;
  line-height: 1.45;
  margin: 12px 0 0;
}

/* The one-screen start says how Jot will write and help, with a way to change it. */
.quick-setup {
  color: var(--muted);
  font-size: 15px;
  line-height: 1.45;
  margin: 10px 0 18px;
}

.banner {
  background: var(--test-bg);
  box-shadow: inset 0 0 0 1px var(--test-line);
  border-radius: var(--radius-block);
  padding: 12px 16px;
  font-size: 15px;
  line-height: 1.45;
  color: var(--ink);
  margin: 24px 0 0;
}

.banner strong {
  color: var(--test-ink);
  font-weight: 600;
}

.banner + .banner {
  margin-top: 8px;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 0;
}

.chip {
  appearance: none;
  border: 0;
  background: var(--fill);
  border-radius: 999px;
  padding: 11px 16px;
  min-height: 44px;
  font-size: 15px;
  line-height: 1.3;
  text-align: left;
  transition: background-color 0.15s, color 0.15s;
}

/* Picked: the chip turns solid ink, a change in lightness rather than only in color. */
.chip[aria-pressed='true'] {
  background: var(--accent);
  color: var(--accent-ink);
}

/* The task examples lead with a small picture of what each is about. */
.chip-icon {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding-left: 13px;
}

.chip-icon .icon {
  width: 18px;
  height: 18px;
  color: var(--muted);
}

.chip-icon[aria-pressed='true'] .icon {
  color: inherit;
}

.field {
  display: block;
  width: 100%;
  min-height: 52px;
  border: 1px solid var(--field-line);
  border-radius: var(--radius-block);
  background: var(--bg);
  padding: 13px 16px;
  font-size: 17px;
  line-height: 1.45;
  resize: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.field::placeholder {
  color: var(--muted);
  opacity: 1;
}

/* The transparent outline is invisible normally and becomes the system's ring in forced colors,
   where box shadows are dropped. */
.field:focus {
  border-color: var(--ink);
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: 0 0 0 1px var(--ink);
}

.field-label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  margin: 24px 0 8px;
}

.summary {
  background: var(--fill);
  border-radius: var(--radius-block);
  margin: 0;
}

.summary-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 1px 12px;
  padding: 12px 8px 12px 16px;
  position: relative;
}

/* Hairlines between rows, inset from the left the way grouped lists are. */
.summary-row + .summary-row::before {
  content: '';
  position: absolute;
  top: 0;
  left: 16px;
  right: 0;
  border-top: var(--hairline) solid var(--line);
}

.summary-row dt {
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
}

.summary-row dd {
  margin: 0;
  grid-column: 1;
  overflow-wrap: anywhere;
}

.summary-row dd.missing {
  color: var(--muted);
  font-style: italic;
}

.summary-row .btn-small {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  background: none;
  font-weight: 600;
  min-height: 44px;
}

.account {
  margin: 6px 0 0;
  text-align: center;
  font-size: 15px;
  color: var(--muted);
}

.account .link-button {
  padding: 12px 4px;
  color: var(--ink);
  font-weight: 500;
}

.consent {
  display: grid;
  grid-template-columns: 24px 1fr;
  gap: 12px;
  align-items: start;
  margin: 16px 0 0;
  padding: 16px;
  border-radius: var(--radius-block);
  background: var(--fill);
  cursor: pointer;
}

/* A plain checkbox, drawn to match: the tick shows by shape, not only color. */
.consent input {
  appearance: none;
  width: 24px;
  height: 24px;
  margin: 0;
  border: 1.5px solid var(--field-line);
  border-radius: 7px;
  background: var(--bg);
  display: grid;
  place-content: center;
  cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s;
}

.consent input::before {
  content: '';
  width: 11px;
  height: 6px;
  border-left: 2.4px solid var(--accent-ink);
  border-bottom: 2.4px solid var(--accent-ink);
  transform: translateY(-1.5px) rotate(-45deg);
  opacity: 0;
}

.consent input:checked {
  background: var(--accent);
  border-color: var(--accent);
}

.consent input:checked::before {
  opacity: 1;
}

.consent input:disabled {
  opacity: 0.5;
}

.consent > span {
  line-height: 1.4;
}

.consent small {
  display: block;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.4;
  margin-top: 4px;
}

.notice {
  border-radius: var(--radius-block);
  padding: 12px 16px;
  font-size: 15px;
  line-height: 1.45;
  background: var(--fill);
  color: var(--muted);
  margin: 14px 0 0;
}

.notice.error {
  background: var(--danger-soft);
  color: var(--ink);
}

.cleared-title {
  font-size: 28px;
  text-wrap: balance;
  line-height: 1.18;
  letter-spacing: -0.025em;
  font-weight: 700;
  margin: 28px 0 16px;
}

/* On a phone, Safari already tracks 28px system text; tightening it more pinches the titles. */
@media (max-width: 719px) {
  .question,
  .cleared-title {
    letter-spacing: 0;
  }
}

.cleared p {
  margin: 0 0 12px;
}

.muted {
  color: var(--muted);
}

/* "Say it" under the task box: the microphone and a line saying what it's doing. */
.mic-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  margin: 10px 0 0;
}

.mic-row .mic-status {
  flex: 1 1 14em;
  margin: 0;
}

/* Talk instead, on the one-screen start: listening, it turns voice blue and its edge follows the
   voice it hears. */
.btn-talk {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.btn-talk .icon {
  width: 22px;
  height: 22px;
  stroke-width: 2.2;
}

.btn.btn-talk:is([data-phase='listening'], [data-phase='hearing']) {
  background: var(--voice-glow);
  color: var(--ink);
  box-shadow: 0 0 0 calc(var(--level, 0) * 6px) var(--voice-glow);
  transition: box-shadow 0.1s ease-out;
}

.btn-talk:is([data-phase='listening'], [data-phase='hearing']) .icon {
  color: var(--voice);
}

.btn.btn-talk[data-phase='transcribing'] {
  cursor: progress;
}

.btn-talk[data-phase='transcribing'] .icon {
  animation: soft-pulse 1.2s ease-in-out infinite;
}

.screen-actions .mic-status {
  margin: 0;
  text-align: center;
}

/* Words that were still in the box when a conversation cleared, handed back to copy or reuse. */
.unsent {
  margin: 20px 0 0;
  padding: 14px 16px 4px;
  border-radius: var(--radius-block);
  background: var(--fill);
}

.unsent .unsent-label {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
}

.unsent .unsent-text {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.unsent .reply-actions {
  margin-top: 4px;
}

/* ---------- Conversation ---------- */

.chat {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}

.bar {
  position: sticky;
  top: 0;
  z-index: 5;
  /* Solid behind the status lines, so the thread scrolling underneath can't show through them.
     Only the strip below them fades, where the thread slides under. */
  background: linear-gradient(to bottom, var(--bg) calc(100% - 12px), var(--bg-clear));
  padding: calc(6px + env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) 16px max(16px, env(safe-area-inset-left));
  margin-bottom: -12px;
}

.bar-inner {
  max-width: 720px;
  margin: 0 auto;
}

.bar-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 44px;
}

.bar-top .brand {
  font-size: 17px;
}

.bar-top .mark {
  width: 26px;
  height: 26px;
}

.menu-button {
  appearance: none;
  position: relative;
  border: 0;
  border-radius: 999px;
  background: var(--fill);
  min-height: 36px;
  padding: 6px 16px;
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
}

.menu-button::after {
  content: '';
  position: absolute;
  inset: -4px;
}

/* New sits beside Menu, so a fresh conversation is one tap away, as in other chat apps. */
.bar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.new-button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding-left: 12px;
}

.new-button .icon {
  width: 18px;
  height: 18px;
}

/* Processing and Saved share the first row as full-size tap targets. A long status wraps inside
   its own cell, so the header keeps its shape; the clearing time has a row of its own. */
.bar-status {
  display: grid;
  grid-template-columns: repeat(2, auto);
  justify-content: start;
  align-items: center;
  gap: 0 4px;
  margin: 0 0 0 -8px;
  font-size: 13px;
  line-height: 1.3;
  letter-spacing: -0.005em;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.status-item {
  appearance: none;
  border: 0;
  background: none;
  border-radius: 12px;
  min-height: 44px;
  padding: 4px 8px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: inherit;
  color: inherit;
  text-align: left;
  text-wrap: balance;
}

.bar-status > span.status-item {
  grid-column: 1 / -1;
  min-height: 0;
  padding: 0 8px 6px;
}

.status-item .icon {
  width: 15px;
  height: 15px;
  stroke-width: 1.9;
}

.status-item .icon-paused,
.status-item.unavailable .icon-mac {
  display: none;
}

.status-item.unavailable .icon-paused {
  display: block;
}

.bar-status .unavailable {
  color: var(--danger);
  font-weight: 500;
}

.thread {
  flex: 1;
  width: 100%;
  max-width: 752px;
  margin: 0 auto;
  padding: 18px max(16px, env(safe-area-inset-right)) 28px max(16px, env(safe-area-inset-left));
}

/* The pinned bars' heights come from app.js (padForPinnedBars). */
.thread :is(button, a, summary, [tabindex]) {
  scroll-margin-top: calc(var(--bar-height, 0px) + 8px);
  scroll-margin-bottom: calc(var(--composer-height, 0px) + 28px);
}

/* Heads the thread the way a messages app does: small, centered, no card, so it doesn't compete
   with the first message, which repeats the task. */
.anchor {
  max-width: 480px;
  margin: 4px auto 32px;
  text-align: center;
  text-wrap: balance;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
}

.anchor b {
  display: block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  margin-bottom: 4px;
}

.anchor strong {
  color: var(--ink);
  font-weight: 600;
}

.anchor .task {
  color: var(--ink);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -0.01em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0 0 6px;
}

/* A question sits close to its own reply, and each exchange gets room after it. */
.msg {
  margin: 0 0 26px;
}

.msg-user {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 20px;
}

.msg-assistant {
  margin-bottom: 36px;
}

/* The last message's gap isn't added to the thread's own bottom padding. */
.messages > :last-child {
  margin-bottom: 0;
}

.bubble {
  max-width: min(82%, 560px);
  background: var(--bubble);
  border-radius: 22px;
  padding: 10px 16px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.reply {
  overflow-wrap: anywhere;
  line-height: 1.55;
}

.reply > :first-child {
  margin-top: 0;
}

.reply p,
.reply ul,
.reply ol,
.reply blockquote {
  margin: 0 0 14px;
}

.reply h3,
.reply h4 {
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.02em;
}

.reply h3 {
  font-size: 20px;
  margin: 32px 0 8px;
}

.reply h4 {
  font-size: 17px;
  margin: 24px 0 8px;
}

.reply ul,
.reply ol {
  padding-left: 22px;
}

.reply li {
  margin: 6px 0;
  padding-left: 2px;
}

.reply li::marker {
  color: var(--muted);
}

.reply ol > li::marker {
  font-variant-numeric: tabular-nums;
}

.reply li.nested {
  margin-left: 18px;
}

.reply strong {
  font-weight: 600;
}

/* The assumptions a reply opens with are set in a quieter voice than its advice. */
.reply p.meta {
  color: var(--muted);
  font-size: 15px;
  line-height: 1.5;
  margin-bottom: 18px;
}

.reply p.ask {
  border-top: var(--hairline) solid var(--line);
  padding-top: 14px;
  margin-top: 20px;
}

.reply blockquote {
  border-left: 3px solid var(--fill-strong);
  padding: 2px 0 2px 14px;
  color: var(--ink);
}

.reply code {
  font-family: var(--mono);
  font-size: 0.88em;
  background: var(--fill);
  border-radius: 6px;
  padding: 1px 5px;
}

.reply hr {
  border: 0;
  border-top: var(--hairline) solid var(--line);
  margin: 18px 0;
}

/* A checklist has boxes to tick instead of bullets, like a list in Reminders. Each row is a
   44-point tap, words included. Ticks stay on this page and go out with Copy. */
.reply ul.checklist {
  padding-left: 0;
  margin: -4px 0 6px;
}

.reply li.check {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

.check-row {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 10px;
  align-items: start;
  padding: 9px 0;
  cursor: pointer;
}

/* Round, as in Reminders, with a tick that shows by shape, not only color. */
.check-box {
  appearance: none;
  width: 22px;
  height: 22px;
  margin: 2px 0 0;
  border: 1.5px solid var(--field-line);
  border-radius: 50%;
  background: var(--bg);
  display: grid;
  place-content: center;
  cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s;
}

.check-box::before {
  content: '';
  width: 10px;
  height: 5px;
  border-left: 2.2px solid var(--accent-ink);
  border-bottom: 2.2px solid var(--accent-ink);
  transform: translateY(-1px) rotate(-45deg);
  opacity: 0;
}

.check-box:checked {
  background: var(--accent);
  border-color: var(--accent);
}

.check-box:checked::before {
  opacity: 1;
}

.check-box:checked + .check-text {
  color: var(--muted);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

/* Steps under a box line up with its words. */
.reply li.check > :is(ul, ol) {
  margin: 0 0 4px 32px;
}

/* Wide tables scroll sideways inside the reply instead of squeezing every column. */
.table-wrap {
  margin: 0 0 14px;
  overflow-x: auto;
  border-radius: 12px;
  box-shadow: inset 0 0 0 1px var(--line);
}

.reply table {
  border-collapse: collapse;
  min-width: 100%;
  font-size: 15px;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
  /* Whole words: breaking anywhere would let a column shrink to one letter. */
  overflow-wrap: normal;
}

.reply th,
.reply td {
  padding: 9px 14px;
  text-align: start;
  vertical-align: top;
  min-width: 4.5em;
}

.reply th {
  font-weight: 600;
  background: var(--fill);
}

.reply tbody tr + tr td {
  border-top: var(--hairline) solid var(--line);
}

.reply .align-left {
  text-align: left;
}

.reply .align-center {
  text-align: center;
}

.reply .align-right {
  text-align: right;
}

/* Code keeps its lines and spacing, and scrolls sideways rather than wrapping. */
.reply pre {
  margin: 0 0 14px;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--fill);
  overflow-x: auto;
  font-size: 14px;
  line-height: 1.5;
  tab-size: 4;
  overflow-wrap: normal;
}

.reply pre code {
  font-size: inherit;
  background: none;
  border-radius: 0;
  padding: 0;
}

/* A link shows its address as words: nothing in a reply opens a page. */
.reply .address {
  color: var(--muted);
}

.reply del {
  color: var(--muted);
}

/* A section's heading with a Copy for just that section at the end of its line. */
.reply .section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.reply .section-h3 {
  margin: 32px 0 8px;
}

.reply .section-h4 {
  margin: 24px 0 8px;
}

.reply > .section-head:first-child {
  margin-top: 0;
}

.reply .section-head > :is(h3, h4) {
  margin: 0;
}

.section-copy {
  appearance: none;
  position: relative;
  flex: none;
  border: 0;
  border-radius: 50%;
  width: 36px;
  height: 36px;
  margin: -4px -8px -4px 0;
  display: grid;
  place-items: center;
  background: none;
  color: var(--muted);
  transition: background-color 0.15s, color 0.15s;
}

.section-copy::after {
  content: '';
  position: absolute;
  inset: -4px;
}

.section-copy .icon {
  width: 18px;
  height: 18px;
}

.section-copy:active {
  background-color: var(--fill-strong);
  color: var(--ink);
}

.section-copy .icon-check,
.section-copy.copied .icon-copy {
  display: none;
}

.section-copy.copied {
  color: var(--ink);
}

.section-copy.copied .icon-check {
  display: block;
  animation: pop 0.25s var(--ease);
}

.working {
  color: var(--muted);
  font-size: 15px;
  line-height: 21px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 4px;
}

/* The dots stay level with the first line when the words beside them wrap. */
.dots {
  flex: none;
  display: inline-flex;
  align-items: center;
  height: 21px;
  gap: 4px;
}

.dots i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink);
  animation: pulse 1.2s infinite ease-in-out;
}

.dots i:nth-child(2) {
  animation-delay: 0.15s;
}

.dots i:nth-child(3) {
  animation-delay: 0.3s;
}

@keyframes pulse {
  0%,
  80%,
  100% {
    opacity: 0.2;
    transform: scale(0.85);
  }
  40% {
    opacity: 0.85;
    transform: scale(1);
  }
}

.receipt {
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted);
  max-width: 38em;
  margin: 16px 0 0;
}

.receipt.problem {
  color: var(--danger);
}

.reply-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 6px 0 0 -9px;
}

/* One-tap changes under the latest reply. */
.revise {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 8px 0 0;
}

.chip-small {
  position: relative;
  min-height: 36px;
  padding: 7px 14px;
}

.chip-small::after {
  content: '';
  position: absolute;
  inset: -4px 0;
}

/* A message said out loud has a small microphone beside its bubble, level with its last line. */
.said-mark {
  align-self: flex-end;
  display: grid;
  margin: 0 8px 14px 0;
  color: var(--muted);
}

.said-mark .icon {
  width: 16px;
  height: 16px;
}

/* A kept note shows as a small centered pill between turns. The icon sits in the line of text,
   so a long note wraps evenly under it instead of beside it. */
.event {
  width: fit-content;
  max-width: min(100% - 48px, 34em);
  margin: 0 auto 32px;
  padding: 6px 12px;
  border-radius: 14px;
  background: var(--fill);
  text-align: center;
  /* Balanced lines would leave the pill wider than its text. */
  text-wrap: pretty;
  overflow-wrap: anywhere;
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted);
}

.event .icon {
  width: 14px;
  height: 14px;
  vertical-align: -2px;
  margin-right: 5px;
}

/* New messages and reply buttons arrive with a short rise; what was already on screen doesn't
   move. Receipts, kept-note lines and status words never animate: they're readable the moment
   they appear. */
/* --enter-age is how far into its rise a redrawn node already was, so it carries on from there. */
.msg-user.enter .bubble {
  transform-origin: 100% 100%;
  animation: bubble-in 0.25s var(--ease) both;
  animation-delay: calc(0ms - var(--enter-age, 0ms));
}

.msg-assistant.enter,
.reply-actions.enter,
.revise.enter {
  animation: fade-up 0.25s var(--ease) both;
  animation-delay: calc(0ms - var(--enter-age, 0ms));
}

.reply-actions.enter {
  animation-delay: calc(60ms - var(--enter-age, 0ms));
}

.revise.enter {
  animation-delay: calc(120ms - var(--enter-age, 0ms));
}

@keyframes bubble-in {
  from {
    opacity: 0;
    transform: translateY(12px) scale(0.96);
  }
}

@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
}

.composer {
  position: sticky;
  bottom: 0;
  z-index: 5;
  background: var(--bg);
  padding: 6px max(16px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
}

/* Brings the newest message into view. Shown only while the end of the thread is out of sight. */
.jump {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  z-index: 1;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  margin-left: -20px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--elevated);
  color: var(--ink);
  box-shadow: var(--shadow);
  cursor: pointer;
  animation: fade-in 0.2s var(--ease);
}

.jump[hidden] {
  display: none;
}

.jump .icon {
  width: 20px;
  height: 20px;
}

.jump:active {
  background: var(--fill-strong);
}

/* The thread fades out above the composer rather than stopping at a hard edge. Taps pass through. */
.composer::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 24px;
  background: linear-gradient(to bottom, var(--bg-clear), var(--bg));
  pointer-events: none;
}

.composer-inner {
  max-width: 720px;
  margin: 0 auto;
}

/* The message box: a capsule with the send button inside it. */
.composer-row {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  background: var(--elevated);
  border: 1px solid var(--field-line);
  border-radius: 26px;
  padding: 3px 5px 3px 18px;
  box-shadow: var(--shadow);
  transition: border-color 0.15s, box-shadow 0.15s;
}

.composer-row:focus-within {
  border-color: var(--ink);
  box-shadow: 0 0 0 1px var(--ink), var(--shadow);
}

/* With the keyboard on the send button, its own focus ring is the only one shown. */
.composer-row:has(.send:focus-visible) {
  border-color: var(--field-line);
  box-shadow: var(--shadow);
}

.composer .field {
  min-height: 44px;
  max-height: 168px;
  padding: 10px 0;
  line-height: 24px;
  border: 0;
  border-radius: 0;
  background: transparent;
}

.composer .field:focus {
  box-shadow: none;
}

.send {
  appearance: none;
  position: relative;
  flex: none;
  border: 0;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  margin: 2px 0;
  display: grid;
  place-items: center;
  background: var(--accent);
  color: var(--accent-ink);
  transition: transform 0.15s var(--ease), background-color 0.15s;
}

/* A 44-point square to tap, corners included, around the 40-point circle. */
.send::after {
  content: '';
  position: absolute;
  inset: -2px;
}

.send .icon {
  width: 21px;
  height: 21px;
  stroke-width: 2.4;
}

.send .icon-stop,
.send .icon-wave,
.send.stop .icon-send,
.send.talk .icon-send {
  display: none;
}

.send.stop .icon-stop,
.send.talk .icon-wave {
  display: block;
}

.send:active:not(:disabled) {
  transform: scale(0.94);
}

.send:disabled {
  background: var(--fill-strong);
  color: var(--muted);
  cursor: default;
}

.composer-note {
  font-size: 13px;
  line-height: 1.4;
  color: var(--muted);
  margin: 0 8px 8px;
}

.composer-note.error {
  color: var(--danger);
}

/* Kept in the page while empty so screen readers announce what appears in it. */
.composer-note:empty {
  margin: 0;
}

/* Above the box, only near the end: time before the conversation clears, or messages left. */
.composer-aside {
  font-size: 13px;
  line-height: 1.4;
  color: var(--muted);
  margin: 0 8px 8px;
}

.composer-aside:empty {
  display: none;
}

/* Counts down near a box's limit, and says plainly when the words are over it. */
.length-note {
  font-size: 13px;
  line-height: 1.4;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  margin: 8px 0 0;
}

.length-note.over {
  color: var(--danger);
  font-weight: 500;
}

.length-note:empty {
  display: none;
}

.composer .length-note {
  margin: 0 8px 8px;
}

.mic-status {
  font-size: 13px;
  line-height: 1.4;
  color: var(--muted);
  margin: 0 8px 8px;
}

/* Kept in the page while empty, like the note above, so what appears in it is announced. */
.mic-status:empty {
  margin: 0;
}

/* The microphone beside Send writes what's said into the box, to check before sending. While
   it listens it turns voice blue, and a ring follows the voice it hears. */
.mic {
  appearance: none;
  position: relative;
  flex: none;
  border: 0;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  margin: 2px -4px 2px 0;
  display: grid;
  place-items: center;
  background: none;
  color: var(--muted);
  transition: background-color 0.15s, color 0.15s, box-shadow 0.1s ease-out;
}

.mic::after {
  content: '';
  position: absolute;
  inset: -2px;
}

.mic .icon {
  width: 22px;
  height: 22px;
}

.mic:active {
  background-color: var(--fill-strong);
  color: var(--ink);
}

.mic:is([data-phase='listening'], [data-phase='hearing']) {
  background: var(--voice-glow);
  color: var(--voice);
  box-shadow: 0 0 0 calc(var(--level, 0) * 7px) var(--voice-glow);
}

.mic[data-phase='transcribing'] {
  color: var(--ink);
  cursor: progress;
}

.mic[data-phase='transcribing'] .icon {
  animation: soft-pulse 1.2s ease-in-out infinite;
}

/* "Say it": the same microphone, with its word beside it. */
.mic.mic-labeled {
  width: auto;
  height: auto;
  min-height: 44px;
  margin: 0;
  padding: 8px 16px 8px 12px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--fill);
  color: var(--ink);
  font-size: 15px;
  font-weight: 500;
}

.mic-labeled .icon {
  width: 20px;
  height: 20px;
  color: var(--muted);
}

.mic.mic-labeled:is([data-phase='listening'], [data-phase='hearing']) {
  background: var(--voice-glow);
}

.mic-labeled:is([data-phase='listening'], [data-phase='hearing']) .icon {
  color: var(--voice);
}

@keyframes soft-pulse {
  50% {
    opacity: 0.4;
  }
}

/* Talking with Jot takes the message box's place: the circle, a line saying what's happening,
   and End. */
.talk-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--elevated);
  border: 1px solid var(--field-line);
  border-radius: 34px;
  padding: 4px 8px 4px 4px;
  box-shadow: var(--shadow);
}

.talk-text {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: 15px;
  line-height: 1.35;
  text-wrap: balance;
}

.talk-end {
  flex: none;
}

/* The circle: it breathes while waiting for words, grows with the voice while someone talks,
   and a light runs around it while Jot is thinking. */
.orb {
  appearance: none;
  position: relative;
  flex: none;
  width: 56px;
  height: 56px;
  border: 0;
  border-radius: 50%;
  padding: 0;
  display: grid;
  place-items: center;
  background: none;
}

.orb[aria-disabled='true'] {
  cursor: default;
}

/* The halo behind the circle. */
.orb::before {
  content: '';
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  background: var(--voice);
  opacity: calc(0.16 + var(--level, 0) * 0.3);
  transform: scale(calc(1 + var(--level, 0) * 0.3));
  transition: transform 0.1s ease-out, opacity 0.1s ease-out;
}

.orb-core {
  position: relative;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  overflow: hidden;
  background: radial-gradient(circle at 34% 30%, var(--voice-light), var(--voice) 55%, var(--voice-deep));
  box-shadow: 0 2px 10px var(--voice-shadow);
  transform: scale(calc(1 + var(--level, 0) * 0.06));
  transition: transform 0.1s ease-out, filter 0.3s, opacity 0.3s;
}

/* The light that runs around the circle while Jot works. */
.orb-core::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 55%, rgb(255 255 255 / 0.6) 80%, transparent 95%);
  opacity: 0;
  transition: opacity 0.3s;
}

.talk-bar[data-phase='listening'] .orb::before {
  animation: breathe 2.4s ease-in-out infinite;
}

.talk-bar:is([data-phase='transcribing'], [data-phase='thinking'], [data-phase='waiting']) .orb-core::after {
  opacity: 1;
  animation: spin 1.1s linear infinite;
}

.talk-bar[data-phase='paused'] .orb::before {
  opacity: 0;
}

.talk-bar[data-phase='paused'] .orb-core {
  filter: saturate(0.25);
  opacity: 0.8;
}

.orb:active:not([aria-disabled='true']) .orb-core {
  transform: scale(0.94);
}

@keyframes breathe {
  0%,
  100% {
    opacity: 0.22;
    transform: scale(1);
  }
  50% {
    opacity: 0.08;
    transform: scale(1.22);
  }
}

@keyframes spin {
  to {
    transform: rotate(1turn);
  }
}

/* ---------- Sheets ---------- */

dialog.sheet {
  border: 0;
  padding: 0;
  background: var(--elevated);
  color: var(--ink);
  width: 100%;
  max-width: 100%;
  max-height: 90dvh;
  margin: auto 0 0;
  border-radius: 26px 26px 0 0;
  box-shadow: 0 -10px 40px rgb(0 0 0 / 0.16);
  animation: sheet-up 0.42s var(--ease);
}

dialog.sheet::backdrop {
  background: rgb(0 0 0 / 0.32);
  animation: fade-in 0.3s ease-out;
}

@keyframes sheet-up {
  from {
    transform: translateY(100%);
  }
}

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

@keyframes fade-in {
  from {
    opacity: 0;
  }
}

@media (min-width: 720px) {
  dialog.sheet {
    max-width: 540px;
    margin: auto;
    border-radius: 26px;
    max-height: 84vh;
    box-shadow: 0 24px 80px rgb(0 0 0 / 0.22);
    animation: sheet-in 0.28s var(--ease);
  }
}

/* On black a shadow can't lift a sheet, so a faint edge does, and the dim is deeper. */
@media (prefers-color-scheme: dark) {
  dialog.sheet {
    box-shadow: 0 0 0 0.5px rgb(255 255 255 / 0.12), 0 -10px 40px rgb(0 0 0 / 0.5);
  }

  dialog.sheet::backdrop {
    background: rgb(0 0 0 / 0.5);
  }
}

@media (prefers-color-scheme: dark) and (min-width: 720px) {
  dialog.sheet {
    box-shadow: 0 0 0 0.5px rgb(255 255 255 / 0.12), 0 24px 80px rgb(0 0 0 / 0.6);
  }
}

/* A sheet opened from the menu takes the menu's place: no second slide, no second dim. */
dialog.sheet.swap {
  animation: sheet-swap 0.3s var(--ease);
}

dialog.sheet.swap::backdrop {
  animation: none;
}

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

/* Closing slides the sheet back down (on a wide screen, fades it) and lifts the dim. */
dialog.sheet.closing {
  animation: sheet-down 0.26s cubic-bezier(0.32, 0, 0.67, 0) forwards;
  pointer-events: none;
}

dialog.sheet.closing::backdrop {
  animation: fade-out 0.26s ease-in forwards;
}

@keyframes sheet-down {
  to {
    transform: translateY(100%);
  }
}

@keyframes fade-out {
  to {
    opacity: 0;
  }
}

@media (min-width: 720px) {
  dialog.sheet.closing {
    animation: sheet-out 0.2s cubic-bezier(0.32, 0, 0.67, 0) forwards;
  }

  /* The dim lifts as fast as the sheet fades, so none is left to snap off when it closes. */
  dialog.sheet.closing::backdrop {
    animation-duration: 0.2s;
  }
}

@keyframes sheet-out {
  to {
    opacity: 0;
    transform: translateY(12px) scale(0.98);
  }
}

.sheet-inner {
  padding: 24px 24px calc(24px + env(safe-area-inset-bottom));
}

.sheet h2 {
  font-size: 22px;
  line-height: 1.25;
  font-weight: 700;
  margin: 0 0 8px;
  letter-spacing: -0.012em;
}

.sheet h3 {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.015em;
  margin: 24px 0 8px;
}

/* Defaults only: :where() keeps them below any class that sets its own size or spacing. */
:where(.sheet) p,
.sheet li {
  font-size: 16px;
  line-height: 1.5;
}

:where(.sheet) p {
  margin: 0 0 12px;
}

/* The test-version reminder in Keep a note: room above, and the sheet's usual space below. */
.sheet .banner {
  margin: 24px 0 12px;
}

.sheet ul {
  padding-left: 20px;
  margin: 6px 0;
}

.sheet li {
  margin: 8px 0;
  padding-left: 2px;
}

.sheet li::marker {
  color: var(--muted);
}

/* In a dark sheet, a text box is part of the sheet rather than a black well cut into it. */
.sheet .field:not([readonly]) {
  background: var(--elevated);
}

.sheet-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 24px;
}

.sheet-actions-pinned {
  position: sticky;
  bottom: 0;
  margin: 24px -24px 0;
  padding: 12px 24px calc(12px + env(safe-area-inset-bottom));
  background: var(--elevated);
}

/* What scrolls under the pinned buttons fades out, as the thread does under the header. */
.sheet-actions-pinned::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 20px;
  background: linear-gradient(to bottom, var(--elevated-clear), var(--elevated));
  pointer-events: none;
}

.sheet-inner:has(> .sheet-actions-pinned) {
  padding-bottom: 0;
}

dialog.sheet:has(.sheet-actions-pinned) :is(button, a, summary, [tabindex]):not(.sheet-actions-pinned *) {
  scroll-margin-bottom: calc(104px + env(safe-area-inset-bottom));
}

/* The menu: one grouped list, an icon on each row and a chevron at the end. */
.menu-list {
  margin: 8px 0 0;
  background: var(--fill);
  border-radius: var(--radius-block);
  overflow: hidden;
}

.menu-item {
  appearance: none;
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: 24px 1fr 16px;
  gap: 14px;
  align-items: center;
  text-align: left;
  border: 0;
  background: none;
  padding: 13px 14px 13px 16px;
  min-height: 54px;
  font-size: 17px;
  line-height: 1.3;
}

.menu-item:focus-visible {
  outline-offset: -4px;
  border-radius: 14px;
}

.menu-item + .menu-item::before {
  content: '';
  position: absolute;
  top: 0;
  left: 54px;
  right: 0;
  border-top: var(--hairline) solid var(--line);
}

.menu-item .icon {
  width: 22px;
  height: 22px;
}

.menu-item .icon-chevron {
  width: 16px;
  height: 16px;
  stroke-width: 2.2;
  color: var(--muted);
}

.menu-item.danger {
  color: var(--danger);
}

.menu-item small {
  display: block;
  font-size: 13px;
  color: var(--muted);
  margin-top: 2px;
}

.sheet .note-list {
  list-style: none;
  padding: 0;
  margin: 10px 0 0;
}

/* Restates the card's padding, which the general .sheet li rule would otherwise override. */
.sheet .note-list li {
  margin: 0 0 10px;
  padding: 14px 16px;
}

.note {
  background: var(--fill);
  border-radius: var(--radius-block);
  padding: 14px 16px;
  margin: 0 0 10px;
}

/* A note being written or edited is a text box with its buttons under it; a card around it would
   be a box in a box. */
div.note:has(> .field) {
  background: none;
  padding: 0;
  margin: 0 0 18px;
}

.sheet .note-list li.note:has(> .field) {
  background: none;
  padding: 0;
}

/* Out of its card, a kept note's Save and Cancel need their own gray pills. */
li.note:has(> .field) .note-actions .btn-small:not(.btn-small-danger) {
  background: var(--fill);
}

.note-text {
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.field[readonly] {
  border-color: transparent;
  background: var(--fill);
  box-shadow: none;
  min-height: 0;
}

.field[readonly]:focus-visible {
  outline: 2.5px solid var(--focus);
  outline-offset: 2px;
}

.note-question {
  margin: 12px 0 0;
  font-weight: 600;
}

.unkept {
  margin: 0 0 4px;
  font-weight: 600;
}

/* A failed keep under that question: as far from the question as from the buttons. */
.sheet-actions > .notice {
  margin: 0 0 4px;
}

.note-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
  align-items: center;
}

li.note .note-actions .btn-small:not(.btn-small-danger),
div.note:not(:has(> .field)) .btn-small {
  background: var(--elevated);
}

.note-actions .muted {
  font-size: 13px;
}

.suggestion-label {
  font-size: 13px;
  color: var(--muted);
  margin: 18px 0 8px;
}

.kept-mark {
  color: var(--muted);
  font-size: 15px;
}

details.technical summary {
  font-weight: 600;
  color: var(--ink);
  margin-top: 22px;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 10px;
  list-style: none;
  cursor: pointer;
}

details.technical summary::-webkit-details-marker {
  display: none;
}

details.technical summary::after {
  content: '';
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}

details.technical[open] summary::after {
  transform: translateY(2px) rotate(-135deg);
}

.draft-note {
  font-size: 13px;
  color: var(--muted);
  border-top: var(--hairline) solid var(--line);
  margin-top: 24px;
  padding-top: 14px;
}

/* An empty list: the Keep symbol in a soft disc above centered words, as empty lists are on iOS. */
.empty-state {
  text-align: center;
  text-wrap: balance;
  padding: 12px 8px 4px;
}

.empty-state .icon {
  display: block;
  box-sizing: content-box;
  width: 24px;
  height: 24px;
  padding: 12px;
  margin: 0 auto 10px;
  border-radius: 50%;
  background: var(--fill);
  color: var(--muted);
}

@media (min-width: 720px) {
  /* Each setup step starts at the same height, so the logo and question don't jump between steps.
     Short screens sit in the middle. */
  .screen {
    justify-content: flex-start;
    padding-top: max(56px, 10vh);
    padding-bottom: 56px;
  }

  .screen-center {
    justify-content: center;
    padding-top: 56px;
  }

  .screen-body {
    flex: none;
  }

  .welcome-title {
    font-size: 40px;
  }

  .question,
  .cleared-title {
    font-size: 30px;
  }

  .bar-status {
    grid-template-columns: repeat(3, auto);
  }

  .bar-status > span.status-item {
    grid-column: auto;
    min-height: 44px;
    padding: 4px 8px;
  }

  .thread {
    padding-top: 28px;
  }

  .composer {
    padding-bottom: max(24px, env(safe-area-inset-bottom));
  }
}

/* ---------- Presses ---------- */

/* A press shows at once and fades on release, as on iOS. Safari shows presses on iPhone only
   because app.js listens for touches. The tint is an inset shadow, so it follows each shape and
   leaves backgrounds and hovers alone. */
.btn-small,
.btn-quiet,
.menu-button,
.chip {
  box-shadow: inset 0 0 0 999px rgb(118 118 128 / 0);
  transition: box-shadow 0.25s ease-out, background-color 0.15s, color 0.15s;
}

.btn-small:not(.btn-small-danger):active:not(:disabled),
.btn-quiet:active:not(:disabled),
.menu-button:active:not(:disabled),
.chip:active:not(:disabled) {
  box-shadow: inset 0 0 0 999px var(--press);
  transition-duration: 0s;
}

/* Red buttons darken, so their white words keep their contrast. */
.btn-small-danger:active:not(:disabled),
.btn-danger:active:not(:disabled) {
  box-shadow: inset 0 0 0 999px rgb(0 0 0 / 0.16);
  transition-duration: 0s;
}

.status-item:is(button),
.menu-item {
  transition: background-color 0.2s ease-out;
}

.status-item:is(button):active {
  background-color: var(--fill);
  transition-duration: 0s;
}

.menu-item:active {
  background-color: var(--row-press);
  transition-duration: 0s;
}

/* Lighter, so the red words keep 4.5:1. */
.menu-item.danger:active {
  background-color: var(--fill-hover);
}

.link-button,
details.technical summary {
  transition: opacity 0.2s ease-out;
}

.link-button:active,
details.technical summary:active {
  opacity: 0.65;
  transition-duration: 0s;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after,
  dialog.sheet::backdrop {
    animation: none !important;
    transition: none !important;
  }

  .dots i {
    opacity: 0.6;
  }

  /* The circle doesn't grow or spin: a voice shows as its halo brightening, and Jot's thinking as
     the circle dimming. */
  .orb::before,
  .orb-core,
  .orb:active:not([aria-disabled='true']) .orb-core {
    transform: none;
  }

  .talk-bar:is([data-phase='transcribing'], [data-phase='thinking'], [data-phase='waiting']) .orb-core {
    opacity: 0.65;
  }

  .talk-bar:is([data-phase='transcribing'], [data-phase='thinking'], [data-phase='waiting']) .orb-core::after {
    opacity: 0;
  }

  .mic:is([data-phase='listening'], [data-phase='hearing']),
  .btn.btn-talk:is([data-phase='listening'], [data-phase='hearing']) {
    box-shadow: none;
  }
}

/* A short window, as on a phone turned sideways or with zoomed text: the header scrolls away with
   the thread, and the box grows less, so the conversation keeps most of the screen. */
@media (max-height: 560px) {
  .bar {
    position: static;
    margin-bottom: 0;
    padding-bottom: 4px;
  }

  .thread :is(button, a, summary, [tabindex]) {
    scroll-margin-top: 8px;
  }

  .composer {
    padding-top: 4px;
  }

  .composer .field {
    max-height: 96px;
  }

  .orb {
    width: 48px;
    height: 48px;
  }

  .orb-core {
    width: 38px;
    height: 38px;
  }
}

/* Forced colors drop backgrounds and shadows, so notices and controls keep plain borders. */
@media (forced-colors: active) {
  .banner {
    border: 1px solid CanvasText;
  }

  .btn,
  .btn-small,
  .btn-action,
  .menu-button,
  .chip,
  .send,
  .mic,
  .section-copy,
  .talk-bar,
  .unsent,
  .table-wrap,
  .jump {
    border: 1px solid ButtonText;
  }

  /* A picked choice is filled with the system's highlight, so it doesn't look like the others. */
  .chip[aria-pressed='true'],
  .mic:is([data-phase='listening'], [data-phase='hearing']),
  .btn.btn-talk:is([data-phase='listening'], [data-phase='hearing']) {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
    border-color: Highlight;
  }

  .mic:is([data-phase='listening'], [data-phase='hearing']) .icon,
  .btn-talk:is([data-phase='listening'], [data-phase='hearing']) .icon {
    color: HighlightText;
  }

  .check-box,
  .consent input {
    border-color: CanvasText;
  }

  .check-box:checked,
  .consent input:checked {
    forced-color-adjust: none;
    background: Highlight;
    border-color: Highlight;
  }

  .check-box::before,
  .consent input::before {
    border-color: HighlightText;
  }

  /* The circle keeps its own colors, with a border so it reads as a button. */
  .orb {
    forced-color-adjust: none;
    border: 2px solid ButtonText;
  }

  /* The header's gradient is dropped too, so it gets a solid fill and a rule instead. */
  .bar {
    background: Canvas;
    border-bottom: 1px solid CanvasText;
  }

  /* So do the fades over a sheet's pinned buttons. */
  .sheet-actions-pinned {
    border-top: 1px solid CanvasText;
  }
}
