/* ==========================================================================
   Tidy — design system
   Plain CSS. No framework. Tokens first, components second.
   ========================================================================== */

/* --------------------------------------------------------------- 1. tokens */
:root {
  color-scheme: light;

  /* surfaces */
  --bg:            #ffffff;
  --surface:       #f7f7f6;
  --surface-hover: #efefed;
  --card:          #ffffff;
  --card-alt:      #faf9f8;
  --overlay:       rgba(11, 11, 11, 0.45);

  /* ink */
  --ink:    #0b0b0b;
  --ink-2:  #52514e;
  --ink-3:  #898781;
  --on-accent: #ffffff;

  /* lines */
  --border:        rgba(11, 11, 11, 0.10);
  --border-strong: rgba(11, 11, 11, 0.18);
  --grid:          #e1e0d9;
  --axis:          #c3c2b7;

  /* accent — interface only, never a data series */
  --accent:      #2a78d6;
  --accent-ink:  #1c5cab;
  --accent-soft: rgba(42, 120, 214, 0.10);

  /* status — reserved, always paired with an icon or a word */
  --ok:       #0ca30c;
  --ok-text:  #006300;

  /* starred — a mark the user puts there, so it needs its own colour
     and must never be mistaken for a warning */
  --star:      #e0a109;
  --star-soft: rgba(224, 161, 9, 0.12);
  --warn:     #fab219;
  --danger:   #d03b3b;

  /* categorical slots — the validated eight, light steps */
  --c1: #2a78d6;  /* blue    */
  --c2: #eb6834;  /* orange  */
  --c3: #1baf7a;  /* aqua    */
  --c4: #eda100;  /* yellow  */
  --c5: #e87ba4;  /* magenta */
  --c6: #008300;  /* green   */
  --c7: #4a3aa7;  /* violet  */
  --c8: #e34948;  /* red     */

  /* entry-type identity. Always shown with an icon and a label, never alone. */
  --t-task:    var(--c1);
  --t-spend:   var(--c2);
  --t-food:    var(--c3);
  --t-list:    var(--c4);
  --t-contact: var(--c5);
  --t-income:  var(--c6);
  --t-metric:  var(--c7);
  --t-event:   var(--c8);
  --t-note:    #7a7a74;
  --t-journal: #6f6a86;
  /* The eight categorical slots are spoken for, so exercise gets its own
     hue, sitting in the gap between the blue and the aqua. Like every type
     colour it only ever appears beside the type's name. */
  --t-exercise: #0d7d8f;

  /* type */
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* geometry */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 18px;
  --r-xl: 26px;
  --shadow-sm: 0 1px 2px rgba(11, 11, 11, 0.05);
  --shadow-md: 0 4px 16px rgba(11, 11, 11, 0.08);
  --shadow-lg: 0 12px 40px rgba(11, 11, 11, 0.14);

  --rail: 264px;
  --header-h: 56px;
  --reading: 46rem;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --bg:            #131314;
    --surface:       #1c1c1e;
    --surface-hover: #26262a;
    --card:          #1c1c1e;
    --card-alt:      #232326;
    --overlay:       rgba(0, 0, 0, 0.6);

    --ink:   #ffffff;
    --ink-2: #c3c2b7;
    --ink-3: #898781;

    --border:        rgba(255, 255, 255, 0.10);
    --border-strong: rgba(255, 255, 255, 0.20);
    --grid:          #2c2c2a;
    --axis:          #383835;

    --accent:      #3987e5;
    --accent-ink:  #86b6ef;
    --accent-soft: rgba(57, 135, 229, 0.16);

    --ok-text: #0ca30c;
    --star:      #f0bb3e;
    --star-soft: rgba(240, 187, 62, 0.16);

    --c1: #3987e5;  --c2: #d95926;  --c3: #199e70;  --c4: #c98500;
    --c5: #d55181;  --c6: #008300;  --c7: #9085e9;  --c8: #e66767;
    --t-note:    #8f8f88;
    --t-journal: #9a94b3;
    --t-exercise: #2fa8bd;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.6);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg:            #131314;
  --surface:       #1c1c1e;
  --surface-hover: #26262a;
  --card:          #1c1c1e;
  --card-alt:      #232326;
  --overlay:       rgba(0, 0, 0, 0.6);

  --ink:   #ffffff;
  --ink-2: #c3c2b7;
  --ink-3: #898781;

  --border:        rgba(255, 255, 255, 0.10);
  --border-strong: rgba(255, 255, 255, 0.20);
  --grid:          #2c2c2a;
  --axis:          #383835;

  --accent:      #3987e5;
  --accent-ink:  #86b6ef;
  --accent-soft: rgba(57, 135, 229, 0.16);

  --ok-text: #0ca30c;
  --star:      #f0bb3e;
  --star-soft: rgba(240, 187, 62, 0.16);

  --c1: #3987e5;  --c2: #d95926;  --c3: #199e70;  --c4: #c98500;
  --c5: #d55181;  --c6: #008300;  --c7: #9085e9;  --c8: #e66767;
  --t-note:    #8f8f88;
  --t-journal: #9a94b3;
  --t-exercise: #2fa8bd;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.6);
}

/* --------------------------------------------------------------- 2. reset */
*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }
p { margin: 0 0 0.75em; }
p:last-child { margin-bottom: 0; }
a { color: var(--accent-ink); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font: inherit; color: inherit; }
img { max-width: 100%; }

/* The UA rule for [hidden] is display:none, but any author `display` beats
   it — which silently un-hides every flex row and inline-flex button in
   here. One rule, once, rather than a patch per element. */
[hidden] { display: none !important; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ------------------------------------------------------------- 3. controls */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.06s ease;
  white-space: nowrap;
}
.btn:hover  { background: var(--surface-hover); }
.btn:active { transform: scale(0.98); }
.btn:disabled { opacity: 0.5; cursor: default; transform: none; }

.btn--primary {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
}
.btn--primary:hover { background: var(--ink); opacity: 0.88; }

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

.btn--danger { color: var(--danger); border-color: transparent; background: transparent; }
.btn--danger:hover { background: rgba(208, 59, 59, 0.10); }

/* The one button in the app that destroys something. It looks like it. */
.btn--danger-solid {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}
.btn--danger-solid:hover { filter: brightness(1.06); }
.btn--danger-solid:disabled { opacity: .6; cursor: default; }

.btn--sm { height: 32px; padding: 0 12px; font-size: 13px; }
.btn--block { width: 100%; }

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.icon-btn:hover { background: var(--surface-hover); color: var(--ink); }
.icon-btn i { font-size: 15px; }
.icon-btn--sm { width: 30px; height: 30px; }
.icon-btn--sm i { font-size: 13px; }
.icon-btn.is-on { color: var(--star); }
.icon-btn.is-on:hover { background: var(--star-soft); color: var(--star); }

/* Search inside one page: a magnifier until you need it, so it costs one
   icon of room instead of a whole row on every screen. */
.find { display: inline-flex; align-items: center; flex: 0 0 auto; }
.find__input,
.find__x { display: none; }
.find.is-open [data-find-open] { display: none; }
.find.is-open .find__input,
.find.is-open .find__x { display: inline-flex; }
.find.is-open {
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  padding-left: 11px;
}
.find__input {
  width: 150px;
  max-width: 38vw;
  height: 28px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  outline: none;
}
.find__input::-webkit-search-cancel-button { display: none; }
.find__x {
  width: 26px; height: 26px;
  margin-right: 1px;
  align-items: center; justify-content: center;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-3);
  font-size: 11px;
  cursor: pointer;
}
.find__x:hover { color: var(--ink); background: var(--surface-hover); }

.field { display: block; margin-bottom: 14px; }
.field__label {
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-2);
}
.input, .select, .textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.textarea { resize: vertical; min-height: 84px; }
.select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%),
                    linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: calc(100% - 18px) 18px, calc(100% - 13px) 18px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 34px;
}
.field__hint { margin-top: 5px; font-size: 12px; color: var(--ink-3); }

.segmented {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
}
.segmented button {
  height: 30px;
  padding: 0 13px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.segmented button:hover { color: var(--ink); }
.segmented button[aria-pressed="true"] {
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}

/* ------------------------------------------------------------ 4. app shell */
.app {
  display: flex;
  height: 100dvh;
  overflow: hidden;
}

.rail {
  flex: 0 0 var(--rail);
  width: var(--rail);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-right: 1px solid var(--border);
  transition: transform 0.24s cubic-bezier(0.32, 0.72, 0, 1);
}

.rail__top {
  display: flex;
  align-items: center;
  gap: 10px;
  height: var(--header-h);
  padding: 0 12px 0 16px;
  flex: 0 0 auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
}
.brand:hover { text-decoration: none; }
.brand__mark {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  background: var(--ink);
  color: var(--bg);
  font-size: 12px;
}

.rail__new { padding: 4px 12px 12px; }

.rail__nav { padding: 4px 8px; overflow-y: auto; flex: 1 1 auto; }

.nav-group { margin-bottom: 18px; }
.nav-group__title {
  padding: 6px 10px;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--ink-2);
  font-size: 14px;
  text-align: left;
  cursor: pointer;
  transition: background 0.13s ease, color 0.13s ease;
}
.nav-item:hover { background: var(--surface-hover); color: var(--ink); text-decoration: none; }
.nav-item[aria-current="true"] { background: var(--surface-hover); color: var(--ink); font-weight: 550; }
.nav-item i { width: 16px; text-align: center; font-size: 14px; color: var(--ink-3); }
.nav-item[aria-current="true"] i { color: var(--ink); }
.nav-item__count {
  margin-left: auto;
  font-size: 12px;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.rail__foot { flex: 0 0 auto; padding: 8px; border-top: 1px solid var(--border); }

.who {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  cursor: pointer;
  text-align: left;
}
.who:hover { background: var(--surface-hover); }
.who__avatar {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 12px;
  font-weight: 650;
  flex: 0 0 auto;
}
.who__name  { font-size: 13.5px; font-weight: 550; color: var(--ink); }
.who__email { font-size: 11.5px; color: var(--ink-3); }
.who__text  { min-width: 0; }
.who__text > div { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.scrim {
  position: fixed;
  inset: 0;
  background: var(--overlay);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
  z-index: 40;
}

.main {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--bg);
}

.topbar {
  display: flex;
  align-items: center;
  gap: 8px;
  height: var(--header-h);
  padding: 0 12px;
  flex: 0 0 auto;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease;
}
.topbar--edge { border-bottom-color: var(--border); }
.topbar__title { font-size: 15px; font-weight: 600; }
.topbar__spacer { flex: 1 1 auto; }

.view { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; }

.wrap {
  max-width: 940px;
  margin: 0 auto;
  padding: 22px 20px 104px;
}
.wrap--narrow { max-width: 620px; }

/* --------------------------------------------------------------- 5. chat */
.chat { display: flex; flex-direction: column; height: 100%; min-height: 0; }

.chat__scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  scroll-behavior: smooth;
}
.chat__inner {
  max-width: var(--reading);
  margin: 0 auto;
  padding: 24px 20px 8px;
}

.turn { margin-bottom: 26px; }
.turn--user { display: flex; justify-content: flex-end; }

.bubble {
  max-width: 84%;
  padding: 10px 15px;
  border-radius: var(--r-lg);
  background: var(--surface);
  font-size: 15px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.turn--user .bubble { border-bottom-right-radius: 6px; }

.say {
  display: flex;
  gap: 12px;
  font-size: 15px;
  color: var(--ink);
}
.say__mark {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  margin-top: 1px;
  border-radius: 8px;
  background: var(--ink);
  color: var(--bg);
  font-size: 11px;
}
.say__body { min-width: 0; flex: 1 1 auto; padding-top: 2px; }

/* The "thinking" line. It carries a word as well as the dots, so it still
   reads as activity when the animation is suppressed. */
.thinking {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 6px 0;
  color: var(--ink-3);
  font-size: 13.5px;
}
.thinking__dots { display: inline-flex; gap: 4px; }
.thinking__dots i {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--ink-3);
  animation: blip 1.1s infinite ease-in-out;
}
.thinking__dots i:nth-child(2) { animation-delay: 0.15s; }
.thinking__dots i:nth-child(3) { animation-delay: 0.3s; }
.thinking__word { animation: fadecycle 2.4s ease-in-out infinite; }

@keyframes blip {
  0%, 60%, 100% { opacity: 0.3; transform: translateY(0); }
  30%           { opacity: 1;   transform: translateY(-3px); }
}
@keyframes fadecycle {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 1; }
}

/* ---- entry card ------------------------------------------------------- */
.cards { display: grid; gap: 10px; margin-top: 12px; }

.card {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  overflow: hidden;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
  animation: rise 0.26s cubic-bezier(0.32, 0.72, 0, 1) both;
}
.card:hover { border-color: var(--border-strong); }
@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

.card__head {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 12px 13px;
}

.chip-icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: color-mix(in srgb, var(--tint) 14%, transparent);
  color: var(--tint);
  font-size: 13px;
}

.card__main { flex: 1 1 auto; min-width: 0; }
.card__title {
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.card__title--done { text-decoration: line-through; color: var(--ink-3); }
.card__sub {
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--ink-3);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
/* Separator between meta bits. Used in cards and feed rows alike. */
.dot {
  display: inline-block;
  width: 3px;
  height: 3px;
  border-radius: 999px;
  background: currentColor;
  opacity: 0.5;
  flex: 0 0 auto;
  vertical-align: middle;
}

.card__value {
  flex: 0 0 auto;
  text-align: right;
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.01em;
  padding-left: 6px;
}
.card__value small { display: block; font-size: 11px; font-weight: 500; color: var(--ink-3); }

.card__body {
  padding: 0 13px 12px 54px;
  font-size: 13.5px;
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.facts {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 13px 12px 54px;
}
.fact {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--surface);
  font-size: 12px;
  color: var(--ink-2);
}
.fact b { font-weight: 650; color: var(--ink); font-variant-numeric: tabular-nums; }

.card__acts {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 6px 8px;
  border-top: 1px solid var(--border);
  background: var(--card-alt);
}
.card__acts .spacer { flex: 1 1 auto; }
.mini {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-3);
  font-size: 12.5px;
  cursor: pointer;
  transition: background 0.13s ease, color 0.13s ease;
}
.mini:hover { background: var(--surface-hover); color: var(--ink); }
.mini--danger:hover { background: rgba(208, 59, 59, 0.10); color: var(--danger); }
.mini--on { color: var(--ok-text); }

/* inline editor inside a card */
.editor { padding: 4px 13px 13px; border-top: 1px solid var(--border); background: var(--card-alt); }
.editor__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  padding-top: 12px;
}
.editor .field { margin: 0; }
.editor__foot { display: flex; gap: 8px; justify-content: flex-end; padding-top: 12px; }

/* ---- what a question turned up ---------------------------------------
   The reply is what Tidy says; this is what it read. Kept visibly apart
   from the entry cards a capture makes, because nothing here was saved. */
.found {
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  overflow: hidden;
}
.found__head {
  display: flex; align-items: center; gap: 7px;
  padding: 9px 13px;
  border-bottom: 1px solid var(--border);
  background: var(--card-alt);
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-3);
}
.found__head i { font-size: 11px; }
.found__list .row:last-child { border-bottom: 0; }

/* ---- answer card (a question asked in chat) --------------------------- */
.answer {
  margin-top: 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  overflow: hidden;
}
.answer__head { padding: 14px 16px 6px; }
.answer__label { font-size: 12px; color: var(--ink-3); }
.answer__figure {
  font-size: 30px;
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.2;
}
.answer__range { font-size: 12px; color: var(--ink-3); }
.answer__chart { padding: 6px 12px 14px; }

/* ---- composer --------------------------------------------------------- */
.composer {
  flex: 0 0 auto;
  padding: 8px 20px calc(14px + env(safe-area-inset-bottom));
  background: linear-gradient(to bottom, transparent, var(--bg) 28%);
}
.composer__inner { max-width: var(--reading); margin: 0 auto; }

.composer__box {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  padding: 7px 7px 7px 16px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-xl);
  background: var(--card);
  box-shadow: var(--shadow-md);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.composer__box:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft), var(--shadow-md);
}
.composer__box.is-listening {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(208, 59, 59, 0.14), var(--shadow-md);
}

.composer textarea {
  flex: 1 1 auto;
  max-height: 190px;
  min-height: 24px;
  padding: 8px 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 15.5px;
  line-height: 1.45;
  resize: none;
  outline: none;
}
.composer textarea::placeholder { color: var(--ink-3); }

.composer__btn {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, transform 0.08s ease;
}
.composer__btn:hover { background: var(--surface-hover); color: var(--ink); }
.composer__btn:active { transform: scale(0.94); }

.composer__mic.is-live {
  background: var(--danger);
  color: #fff;
  animation: pulse 1.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(208, 59, 59, 0.45); }
  50%      { box-shadow: 0 0 0 9px rgba(208, 59, 59, 0); }
}

.composer__send { background: var(--ink); color: var(--bg); }
.composer__send:hover { background: var(--ink); color: var(--bg); opacity: 0.88; }
.composer__send:disabled { background: var(--surface-hover); color: var(--ink-3); cursor: default; }

.composer__note {
  margin-top: 7px;
  text-align: center;
  font-size: 11.5px;
  color: var(--ink-3);
  min-height: 17px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* A button that reads as a link. Used for "Keep talking", which has to be
   easy to hit and impossible to mistake for decoration. */
.linkish {
  border: 0;
  background: none;
  padding: 2px 4px;
  font: inherit;
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.linkish:hover { color: var(--accent-ink); }

/* The last seconds, drawn. A countdown you can see coming is the whole
   difference between "it sent" and "it cut me off". */
.settle-bar {
  display: block;
  width: 88px;
  height: 3px;
  border-radius: 3px;
  background: var(--surface-hover);
  overflow: hidden;
  flex: none;
}
.settle-bar i {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--danger);
  transform-origin: left center;
  animation: settle-drain linear forwards;
}
@keyframes settle-drain { from { transform: scaleX(1); } to { transform: scaleX(0); } }

@media (prefers-reduced-motion: reduce) {
  .settle-bar i { animation: none; transform: scaleX(1); }
}

/* ---- empty state / prompt chips --------------------------------------- */
.opener { padding: 8vh 0 20px; text-align: center; }
.opener h1 {
  font-size: 27px;
  letter-spacing: -0.025em;
  margin-bottom: 6px;
}
.opener p { color: var(--ink-3); font-size: 14.5px; }

.suggests {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 8px;
  margin-top: 26px;
  text-align: left;
}
.suggest {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease, transform 0.08s ease;
}
.suggest:hover { background: var(--surface); border-color: var(--border-strong); transform: translateY(-1px); }
.suggest__k { font-size: 11px; font-weight: 650; letter-spacing: 0.05em; text-transform: uppercase; color: var(--tint); }
.suggest__v { margin-top: 3px; font-size: 13.5px; color: var(--ink-2); }

/* --------------------------------------------------------------- 6. feed */
.filters {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  gap: 7px;
  padding: 10px 0 12px;
  margin-bottom: 4px;
  overflow-x: auto;
  background: var(--bg);
  scrollbar-width: none;
  /* Fade the right edge so it reads as "there is more over here". */
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent 100%);
          mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent 100%);
}
.filters::-webkit-scrollbar { display: none; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  height: 32px;
  padding: 0 13px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink-2);
  font-size: 13px;
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease, border-color 0.14s ease;
}
.pill:hover { background: var(--surface); color: var(--ink); }
.pill[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
}
.pill i { font-size: 12px; }
.pill--star[aria-pressed="true"] {
  background: var(--star);
  border-color: var(--star);
  color: #1a1400;
}

.searchbox { position: relative; margin-bottom: 14px; }
.searchbox i {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--ink-3);
  font-size: 13px;
}
.searchbox input {
  width: 100%;
  height: 42px;
  padding: 0 14px 0 38px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
}
.searchbox input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.day { margin-bottom: 26px; }
.day__head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 4px 2px 8px;
}
.day__name { font-size: 13px; font-weight: 650; letter-spacing: -0.005em; }
.day__meta { font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

.rows {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  overflow: hidden;
}
.row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 13px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.12s ease;
}
.row:last-child { border-bottom: 0; }
.row:hover { background: var(--card-alt); }
.row__main { flex: 1 1 auto; min-width: 0; }
.row__title { font-size: 14px; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row__title--done { text-decoration: line-through; color: var(--ink-3); }
.row__sub { font-size: 12px; color: var(--ink-3); display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.row__val { flex: 0 0 auto; font-size: 14px; font-weight: 650; font-variant-numeric: tabular-nums; }
.row__val small { display: block; text-align: right; font-size: 11px; font-weight: 500; color: var(--ink-3); }

/* The foot of a list that grows. It is a real button as well as a trigger:
   an observer that never fires still has to leave a way through. */
.stream-end {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 10px 0 26px;
}
.stream-end__wait {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--ink-3);
}

/* A row unfolds in place. Nesting a whole card inside a row made the list
   jump; growing the row itself keeps everything where the eye left it. */
.row { flex-wrap: wrap; }
.row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.row__chev {
  flex: 0 0 auto;
  font-size: 10px;
  color: var(--ink-3);
  opacity: 0.55;
  transition: transform 0.16s ease, opacity 0.16s ease;
}
.row:hover .row__chev { opacity: 1; }
.row.is-open { background: var(--card-alt); cursor: default; }
.row.is-open .row__chev { transform: rotate(180deg); opacity: 1; }
.row.is-open .row__title { white-space: normal; overflow: visible; }
.row.is-loading .row__chev { opacity: 0.3; }

.row__more {
  flex: 1 0 100%;
  margin: 10px -13px -11px;
  border-top: 1px solid var(--border);
  cursor: default;
  animation: rise 0.16s ease both;
}
.row__body {
  padding: 11px 14px 0;
  font-size: 13.5px;
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.row__more .facts { padding: 11px 14px 0; }
.row__more .files { padding: 11px 14px 0; }
.row__more .post__acts { margin-top: 10px; background: transparent; }
.row__more .editor { background: transparent; }

/* Starred: on a row the mark is the switch; on a card it is just a mark,
   because the card already carries the button. */
.row__star {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 26px; height: 26px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--star);
  font-size: 12px;
  cursor: pointer;
  transition: background 0.13s ease;
}
.row__star:hover { background: var(--star-soft); }
.post__star { font-size: 11px; color: var(--star); margin-left: 5px; vertical-align: 1px; }
.mini--star.is-on { color: var(--star); }
.mini--star:hover { color: var(--star); background: var(--star-soft); }

.check {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  border: 1.5px solid var(--border-strong);
  border-radius: 999px;
  background: transparent;
  cursor: pointer;
  display: grid;
  place-items: center;
  color: transparent;
  font-size: 10px;
  transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease;
}
.check:hover { border-color: var(--ok); }
.check[aria-pressed="true"] { background: var(--ok); border-color: var(--ok); color: #fff; }

/* ------------------------------------------------------------ 7. insights */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  gap: 10px;
  margin-bottom: 18px;
}
.tile {
  padding: 14px 15px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
}
.tile__label { font-size: 12px; color: var(--ink-2); }
.tile__value {
  margin-top: 3px;
  font-size: 25px;
  font-weight: 650;
  letter-spacing: -0.025em;
  line-height: 1.15;
}
.tile__value span { font-size: 14px; font-weight: 550; color: var(--ink-3); letter-spacing: 0; }
.tile__delta { margin-top: 4px; font-size: 12px; color: var(--ink-3); }
.tile__delta.is-good { color: var(--ok-text); }
.tile__delta.is-bad  { color: var(--danger); }

.meter {
  margin-top: 9px;
  height: 6px;
  border-radius: 999px;
  background: var(--accent-soft);
  overflow: hidden;
}
.meter__fill { height: 100%; border-radius: 999px; background: var(--accent); transition: width 0.4s ease; }
.meter__fill.is-warn  { background: var(--warn); }
.meter__fill.is-over  { background: var(--danger); }

.panels {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
  gap: 12px;
}
.panel {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  padding: 16px 16px 12px;
  min-width: 0;
}
.panel--wide { grid-column: 1 / -1; }
.panel__head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 2px; }
.panel__title { font-size: 14px; font-weight: 600; }
.panel__sub { font-size: 12px; color: var(--ink-3); }
.panel__note { margin-left: auto; font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.panel__plot { position: relative; height: 230px; margin-top: 12px; }
.panel__plot--short { height: 190px; }

.legend {
  display: grid;
  gap: 3px;
  margin-top: 12px;
  font-size: 12.5px;
}
.legend__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 0;
}
.legend__key { width: 9px; height: 9px; border-radius: 3px; flex: 0 0 auto; }
.legend__name { color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.legend__val { margin-left: auto; color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }

/* a legend row you can open */
a.legend__row--go {
  border-radius: 8px;
  margin: 0 -8px;
  padding: 4px 8px;
  color: inherit;
  text-decoration: none;
  transition: background 0.12s ease;
}
a.legend__row--go:hover { background: var(--surface-hover); }
a.legend__row--go:hover .legend__name { color: var(--ink); }
.legend__go { font-size: 9px; color: var(--ink-3); margin-left: 2px; }

/* the category on an entry, as a way in */
.cat-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted var(--border-strong);
}
.cat-link:hover { color: var(--ink); border-bottom-color: var(--ink-3); }

.tablet { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 6px; }
.tablet th, .tablet td { padding: 8px 2px; text-align: left; border-bottom: 1px solid var(--border); }
.tablet th { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-3); font-weight: 650; }
.tablet td:last-child, .tablet th:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.tablet tr:last-child td { border-bottom: 0; }

/* ---------------------------------------------------------- 8. misc bits */
.empty { padding: 56px 20px; text-align: center; color: var(--ink-3); }
.empty i { font-size: 26px; opacity: 0.5; }
.empty h3 { margin: 12px 0 4px; font-size: 15px; color: var(--ink); }
.empty p { font-size: 13.5px; }

.section-title {
  font-size: 12px;
  font-weight: 650;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 26px 0 10px;
}

/* ---- completed tasks ----------------------------------------------------
   Kept, but folded away. The header is the only thing on screen when the
   section is shut, so it has to read as a control rather than as a heading —
   hence the chevron and the count sitting in it. */
.done-head {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin: 26px 0 4px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  color: var(--ink-2);
  font: inherit;
  font-size: 13px;
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.done-head:hover { border-color: var(--border-strong); }
.done-head i { font-size: 11px; color: var(--ink-3); width: 10px; }
.done-head__n {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  color: var(--ink-3);
}
.done-body { animation: rise 0.2s ease both; }

/* Ticked-off rows read as background, not as things still wanting doing. */
.done-body .post, .done-body .row { opacity: 0.72; }
.done-body .post:hover, .done-body .row:hover { opacity: 1; }

/* ==========================================================================
   The month grid
   ========================================================================== */

.cal {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--card);
  overflow: hidden;
  margin-bottom: 4px;
}

.cal__bar {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.cal__month {
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.01em;
  min-width: 8.5em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Which kinds of thing are drawn. The colour dot is the key to the grid. */
.cal__filters {
  display: flex;
  gap: 7px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.cal__filter {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--ink-3);
  border-radius: 999px;
  padding: 5px 12px 5px 9px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 550;
  cursor: pointer;
  min-height: 30px;
}
.cal__filter:hover { background: var(--surface-hover); }
.cal__filter-key {
  width: 9px;
  height: 9px;
  border-radius: 3px;
  background: var(--tint);
  opacity: 0.35;
  flex: none;
}
.cal__filter.is-on { color: var(--ink); border-color: color-mix(in srgb, var(--tint) 45%, var(--border)); }
.cal__filter.is-on .cal__filter-key { opacity: 1; }

.cal__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

.cal__wd {
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  text-align: center;
  padding: 9px 0;
  border-bottom: 1px solid var(--border);
}

/* A square. Every one is a button, so the whole cell is the target rather
   than the number in its corner. */
.cal__day {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 3px;
  min-height: 96px;
  padding: 6px 6px 8px;
  border: 0;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--card);
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
}
.cal__day:nth-child(7n + 7) { border-right: 0; }     /* +7 for the weekday row */
.cal__grid > .cal__day:nth-last-child(-n + 7) { border-bottom: 0; }
.cal__day:hover { background: var(--surface-hover); }
.cal__day.is-weekend { background: color-mix(in srgb, var(--surface) 55%, var(--card)); }
.cal__day.is-weekend:hover { background: var(--surface-hover); }
.cal__day.is-out { opacity: 0.4; }

.cal__n {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
  width: 23px;
  height: 21px;
  display: grid;
  place-items: center;
  border-radius: 7px;
  flex: none;
}
.cal__day.is-today .cal__n { background: var(--ink); color: var(--card); }

/* The chosen day is a ring rather than a fill: a filled square would fight
   the coloured chips inside it for the same attention. */
.cal__day.is-on { box-shadow: inset 0 0 0 2px var(--accent); }
.cal__day:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }

.cal__chips { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cal__chip {
  display: block;
  font-size: 11.5px;
  line-height: 1.35;
  padding: 2px 5px;
  border-radius: 5px;
  color: var(--ink);
  background: color-mix(in srgb, var(--tint) 14%, transparent);
  border-left: 2px solid var(--tint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cal__chip b { font-weight: 650; opacity: 0.75; margin-right: 4px; }
.cal__chip.is-done { text-decoration: line-through; opacity: 0.55; }
.cal__more { font-size: 11px; color: var(--ink-3); padding-left: 5px; }

.cal__dots { display: none; gap: 3px; padding-left: 2px; }
.cal__dots i { width: 5px; height: 5px; border-radius: 50%; display: block; }

.cal__note { font-size: 12.5px; color: var(--ink-3); padding: 10px 14px; margin: 0; }

.cal__dayhead { display: flex; align-items: center; gap: 10px; }
.cal__daycount { text-transform: none; letter-spacing: 0; font-weight: 500; }
.empty--quiet { padding: 34px 20px; }

/* On a phone a square is about fifty pixels across, which holds no words.
   The same days become coloured dots, and the day you tap is read in full
   underneath — which is how a phone calendar has always worked. */
@media (max-width: 700px) {
  .cal__day {
    min-height: 58px;
    padding: 5px 3px;
    align-items: center;
    gap: 4px;
  }
  .cal__n { width: 26px; height: 24px; font-size: 13px; }
  .cal__chips, .cal__more { display: none; }
  .cal__dots { display: flex; justify-content: center; }
  .cal__month { font-size: 14px; min-width: 7.5em; }
}

.sheet {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  padding: 18px;
  margin-bottom: 14px;
}

.toast-host {
  position: fixed;
  left: 50%;
  bottom: calc(90px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 90;
  display: grid;
  gap: 8px;
  width: max-content;
  max-width: min(92vw, 460px);
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--bg);
  font-size: 13.5px;
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
  animation: rise 0.22s ease both;
}
.toast button {
  border: 0;
  background: transparent;
  color: inherit;
  font-weight: 650;
  cursor: pointer;
  text-decoration: underline;
  padding: 0;
}
.toast--bad { background: var(--danger); color: #fff; }
.toast__x {
  text-decoration: none;
  opacity: 0.6;
  margin-left: -2px;
  font-size: 12px;
}
.toast__x:hover { opacity: 1; }

/* --------------------------------------------- installing to the device */

.install-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 10px;
  padding: 10px 10px 10px 13px;
  max-width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--shadow-sm);
  animation: rise 0.24s ease both;
}
.install-bar__mark {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--ink);
  color: var(--bg);
  font-size: 14px;
}
.install-bar__text { display: grid; gap: 1px; min-width: 0; flex: 1 1 auto; }
.install-bar__text b { font-size: 14px; font-weight: 600; }
.install-bar__text small {
  font-size: 12.5px;
  color: var(--ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.install-bar__x { flex: 0 0 auto; color: var(--ink-3); }

/* the two taps that add Tidy to an iPhone home screen */
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.steps li { display: flex; align-items: flex-start; gap: 11px; font-size: 14px; line-height: 1.5; }
.steps__n {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--bg);
  font-size: 12px;
  font-weight: 600;
}
.steps i { color: var(--ink-3); }

.modal {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding: 20px;
  background: var(--overlay);
}
.modal__panel {
  width: min(460px, 100%);
  /* A tracker's editor is tall; on a short phone the panel has to scroll
     rather than pushing its own buttons off screen. */
  max-height: min(88dvh, 88vh);
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--shadow-lg);
  padding: 20px;
  animation: rise 0.2s ease both;
}
.modal { align-items: center; padding: 16px; }
.modal__title { font-size: 16px; margin-bottom: 6px; }
.modal__text { font-size: 14px; color: var(--ink-2); }
.modal__foot { display: flex; gap: 8px; justify-content: flex-end; margin-top: 18px; }
.modal__hint { font-size: 13px; color: var(--ink-3); margin-bottom: 14px; line-height: 1.45; }
.modal .chips { gap: 7px; }
.modal .chip[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
}

/* the Report button lives in the type page's header row */
.tv-report { flex: 0 0 auto; }
@media (max-width: 640px) {
  .tv-report span { display: none; }
}

/* ---------------------------------------------------------- 9. auth pages */
.auth {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 24px;
  background: var(--surface);
}
.auth__card {
  width: min(400px, 100%);
  padding: 30px 28px;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: var(--card);
  box-shadow: var(--shadow-md);
}
.auth__brand { display: flex; justify-content: center; margin-bottom: 18px; }
.auth h1 { font-size: 21px; text-align: center; letter-spacing: -0.02em; }
.auth__sub { text-align: center; color: var(--ink-3); font-size: 14px; margin-bottom: 22px; }
.auth__alt { text-align: center; font-size: 13.5px; color: var(--ink-3); margin-top: 18px; }

/* The tick that keeps a phone signed in. Big enough to hit with a thumb. */
.stay {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 2px 0 16px;
  font-size: 13.5px;
  color: var(--ink-2);
  cursor: pointer;
  user-select: none;
  min-height: 32px;
}
.stay input {
  width: 18px;
  height: 18px;
  accent-color: var(--accent);
  cursor: pointer;
  flex: none;
}

.notice {
  display: flex;
  gap: 9px;
  padding: 11px 13px;
  border-radius: var(--r-md);
  font-size: 13.5px;
  margin-bottom: 16px;
}
.notice i { margin-top: 2px; }
.notice--bad  { background: rgba(208, 59, 59, 0.10); color: var(--danger); }
.notice--good { background: rgba(12, 163, 12, 0.10); color: var(--ok-text); }
.notice--info { background: var(--accent-soft); color: var(--accent-ink); }

/* ---------------------------------------------------------- 10. responsive */
@media (max-width: 900px) {
  .rail {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 50;
    transform: translateX(-100%);
    box-shadow: var(--shadow-lg);
  }
  body.rail-open .rail { transform: none; }
  body.rail-open .scrim { opacity: 1; pointer-events: auto; }
  .topbar { border-bottom: 1px solid var(--border); }
  .wrap { padding: 16px 14px 100px; }
  .chat__inner { padding: 18px 14px 8px; }
  .composer { padding: 8px 12px calc(12px + env(safe-area-inset-bottom)); }
  .opener { padding: 5vh 0 16px; }
  .opener h1 { font-size: 23px; }
  .panel__plot { height: 210px; }
}

@media (min-width: 901px) {
  .rail-toggle { display: none; }
}

/* A grab strip along the left edge, so the drawer can be pulled out. */
.edge-grab {
  position: fixed;
  left: 0;
  top: var(--header-h);
  bottom: var(--tabbar-h);
  width: 18px;
  z-index: 44;
  display: none;
}
@media (max-width: 900px) {
  .edge-grab { display: block; }
}

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

  /* Those blanket rules land every animation on its final keyframe. For a
     loading indicator that means a dot sitting at 30% opacity — invisible,
     and the user thinks nothing is happening. Pin the indicator to a
     visible resting state instead. iOS "Reduce Motion" is common. */
  .thinking__dots i,
  .thinking__word {
    opacity: 1 !important;
    transform: none !important;
  }
  .thinking__dots i:nth-child(1) { opacity: 1    !important; }
  .thinking__dots i:nth-child(2) { opacity: 0.65 !important; }
  .thinking__dots i:nth-child(3) { opacity: 0.35 !important; }
}

/* Standalone / installed app: let the status bar area breathe. */
@media (display-mode: standalone) {
  .rail__top, .topbar { padding-top: env(safe-area-inset-top); height: calc(var(--header-h) + env(safe-area-inset-top)); }
}

/* ------------------------------------------------- 11. late-added pieces */
.view--flex { display: flex; flex-direction: column; overflow: hidden; }

.capture-btn {
  position: fixed;
  right: 18px;
  bottom: calc(20px + env(safe-area-inset-bottom));
  z-index: 30;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: 48px;
  padding: 0 20px;
  border: 0;
  border-radius: 999px;
  background: var(--ink);
  color: var(--bg);
  font-size: 14px;
  font-weight: 550;
  cursor: pointer;
  box-shadow: var(--shadow-lg);
  transition: transform 0.1s ease, opacity 0.15s ease;
}
.capture-btn:active { transform: scale(0.96); }

.settings-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 0;
  border-bottom: 1px solid var(--border);
}
.settings-row:last-child { border-bottom: 0; }
.settings-row__text { flex: 1 1 auto; min-width: 0; }
.settings-row__title { font-size: 14px; font-weight: 550; }
.settings-row__sub { font-size: 12.5px; color: var(--ink-3); }
.settings-row > .btn { flex: none; }

/* On a narrow phone a long button squeezes the words next to it into a
   column two characters wide. Below this the row stacks instead. */
@media (max-width: 430px) {
  .settings-row { flex-wrap: wrap; }
  .settings-row > .btn { width: 100%; justify-content: center; }
}

.grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
}

.kbd {
  display: inline-block;
  padding: 1px 5px;
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
  font-size: 11px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--ink-2);
}

.skeleton {
  border-radius: var(--r-md);
  background: linear-gradient(90deg, var(--surface) 25%, var(--surface-hover) 37%, var(--surface) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.3s ease-in-out infinite;
}
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }

/* ================================================== 12. bottom tab bar
   Phones get an app-style fixed tab bar with the microphone raised in the
   middle — the primary action is always one thumb-reach away. Desktop keeps
   the sidebar and never shows this.
   ================================================================== */
:root { --tabbar-h: 62px; }

.tabbar {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 45;
  height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--bg);
  border-top: 1px solid var(--border);
}

@supports (backdrop-filter: blur(12px)) {
  .tabbar {
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    backdrop-filter: saturate(180%) blur(16px);
    -webkit-backdrop-filter: saturate(180%) blur(16px);
  }
}

.tab {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-width: 0;
  height: var(--tabbar-h);
  padding: 0 2px;
  border: 0;
  background: transparent;
  color: var(--ink-3);
  font-size: 10.5px;
  font-weight: 550;
  letter-spacing: 0.01em;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.14s ease;
}
.tab i { font-size: 17px; line-height: 1; }
.tab span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.tab[aria-current="true"] { color: var(--ink); }
.tab:active { opacity: 0.6; }

/* The raised microphone. Absolutely placed so its label still lines up
   with the other tab labels. */
.tab--mic {
  position: relative;
  flex: 0 0 78px;
  justify-content: flex-end;
  padding-bottom: 13px;
}
.tab__mic {
  position: absolute;
  top: -20px;
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--bg);
  font-size: 19px;
  box-shadow: var(--shadow-lg);
  border: 3px solid var(--bg);
  transition: transform 0.1s ease, background 0.18s ease;
}
.tab--mic:active .tab__mic { transform: translateX(-50%) scale(0.93); }
.tab--mic.is-live .tab__mic {
  background: var(--danger);
  color: #fff;
  animation: pulse 1.4s ease-in-out infinite;
}
.tab--mic .tab__label { font-size: 10.5px; line-height: 1; }

@media (max-width: 900px) {
  .tabbar { display: flex; }

  /* The tab bar covers the four main screens; the drawer is how you reach
     everything else — the type pages and their charts. Hiding it made those
     unreachable on a phone. */
  .capture-btn { display: none !important; }

  .rail {
    width: min(84vw, 320px);
    padding-bottom: env(safe-area-inset-bottom);
    z-index: 60;
  }
  .scrim { z-index: 55; }

  /* While a finger is on it, the drawer follows the finger instead of
     animating on a timer. */
  body.rail-dragging .rail,
  body.rail-dragging .scrim { transition: none; }

  .wrap { padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 28px); }
  /* Hidden on a phone, because "Enter to send" is a keyboard's advice. The
     countdown is not advice — it is the only warning before something is
     sent, and this is the screen it matters most on. */
  .composer__note { display: none; }
  .composer__box.is-listening + .composer__note,
  .composer__box.is-settling + .composer__note { display: flex; }
  .composer { padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 22px); }
  .toast-host { bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 18px); }
  .filters { top: 0; }
}

/* Slightly roomier bar on very small phones so labels never clip. */
@media (max-width: 360px) {
  .tab { font-size: 10px; }
  .tab--mic { flex: 0 0 66px; }
}

.input:disabled, .select:disabled, .textarea:disabled {
  color: var(--ink-3);
  background: var(--surface);
  cursor: not-allowed;
}

/* ------------------------------------------- 13. offline-mode banner
   Shown when no OpenAI key is reaching the server. The app still works —
   it just files things badly — so the banner has to be impossible to miss
   without blocking the screen.
   ================================================================== */
.alert-bar {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  max-width: var(--reading);
  margin: 0 auto 18px;
  padding: 12px 14px;
  border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  font-size: 13.5px;
  color: var(--ink);
}
.alert-bar i.lead { margin-top: 2px; color: var(--warn); font-size: 15px; }
.alert-bar__body { flex: 1 1 auto; min-width: 0; }
.alert-bar__title { font-weight: 650; margin-bottom: 2px; }
.alert-bar__text { color: var(--ink-2); }
.alert-bar__text a { font-weight: 600; }
.alert-bar__close {
  flex: 0 0 auto;
  border: 0;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 6px;
}
.alert-bar__close:hover { background: var(--surface-hover); color: var(--ink); }

.say__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

/* ==================================================== 14. the card feed
   The feed reads as a stream of things you added, not a spreadsheet.
   A density toggle keeps the dense list available for long scrolls.
   ================================================================== */
.stream { display: grid; gap: 12px; }

.post {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--card);
  overflow: hidden;
  transition: border-color 0.15s ease, transform 0.1s ease;
}
.post:hover { border-color: var(--border-strong); }
.post:active { transform: scale(0.995); }

.post__top {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 15px 12px;
}
.post .chip-icon { width: 36px; height: 36px; border-radius: 11px; font-size: 15px; }

.post__who { flex: 1 1 auto; min-width: 0; }
.post__title {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}
.post__title--done { text-decoration: line-through; color: var(--ink-3); }
.post__meta {
  margin-top: 3px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--ink-3);
}
.post__badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tint) 13%, transparent);
  color: var(--tint);
  font-size: 11.5px;
  font-weight: 600;
}

.post__value {
  flex: 0 0 auto;
  text-align: right;
  font-size: 19px;
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.2;
  padding-left: 8px;
}
.post__value small {
  display: block;
  font-size: 11px;
  font-weight: 550;
  color: var(--ink-3);
  letter-spacing: 0;
}

.post__body {
  padding: 0 15px 12px 63px;
  font-size: 14px;
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.post .facts { padding: 0 15px 13px 63px; }

.post__media { display: block; width: 100%; border-top: 1px solid var(--border); }

.post__acts {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 7px 9px;
  border-top: 1px solid var(--border);
  background: var(--card-alt);
}
.post__acts .spacer { flex: 1 1 auto; }

@media (max-width: 560px) {
  .post__body, .post .facts { padding-left: 15px; }
}

.density {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
}
.density button {
  width: 32px; height: 28px;
  border: 0; border-radius: 999px;
  background: transparent; color: var(--ink-3);
  cursor: pointer; font-size: 12px;
}
.density button[aria-pressed="true"] { background: var(--card); color: var(--ink); box-shadow: var(--shadow-sm); }

/* ============================================== 15. type pages & groups */
.tv-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.tv-head__title { font-size: 22px; font-weight: 650; letter-spacing: -0.025em; }
.tv-head__sub { font-size: 12.5px; color: var(--ink-3); }
.tv-head .topbar__spacer { flex: 1 1 auto; }

.crumb {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding: 0 13px 0 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink-2);
  font-size: 13px;
  cursor: pointer;
}
.crumb:hover { background: var(--surface-hover); color: var(--ink); }

.groups { display: grid; gap: 10px; }

.group {
  display: flex;
  align-items: center;
  gap: 13px;
  width: 100%;
  padding: 14px 15px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  text-align: left;
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease, transform 0.08s ease;
}
.group:hover { background: var(--card-alt); border-color: var(--border-strong); }
.group:active { transform: scale(0.995); }

.group__body { flex: 1 1 auto; min-width: 0; }
.group__name {
  display: block;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.group__meta { display: block; margin-top: 2px; font-size: 12.5px; color: var(--ink-3); }
.group__bar {
  display: block;
  height: 5px;
  margin-top: 8px;
  border-radius: 999px;
  background: var(--accent-soft);
  overflow: hidden;
}
.group__bar i { display: block; height: 100%; border-radius: 999px; background: var(--tint, var(--accent)); }

.group__right {
  flex: 0 0 auto;
  text-align: right;
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.group__right small { display: block; font-size: 11px; font-weight: 500; color: var(--ink-3); letter-spacing: 0; }
.group__chev { flex: 0 0 auto; color: var(--ink-3); font-size: 12px; }

.spark { flex: 0 0 auto; display: flex; align-items: flex-end; gap: 2px; height: 26px; }
.spark i {
  display: block;
  width: 5px;
  min-height: 2px;
  border-radius: 2px 2px 0 0;
  background: var(--tint, var(--accent));
  opacity: 0.35;
}
.spark i:last-child { opacity: 1; }

.quick-log {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  font-size: 13px;
  transition: background 0.14s ease, transform 0.08s ease;
}
.quick-log:hover { background: var(--surface-hover); }
.quick-log:active { transform: scale(0.9); }

.chips-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.chip-add {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 13px;
  border: 1px dashed var(--border-strong);
  border-radius: 999px;
  background: transparent; color: var(--ink-2);
  font-size: 13px; cursor: pointer;
}
.chip-add:hover { background: var(--surface); color: var(--ink); border-style: solid; }

/* In the feed, the action row is noise until you reach for it. On a mouse it
   waits for hover; on touch there is no hover, so it stays put. */
@media (hover: hover) and (pointer: fine) {
  .stream .post__acts {
    max-height: 0;
    padding-top: 0;
    padding-bottom: 0;
    opacity: 0;
    overflow: hidden;
    border-top-color: transparent;
    transition: max-height 0.16s ease, opacity 0.16s ease, padding 0.16s ease;
  }
  .stream .post:hover .post__acts,
  .stream .post:focus-within .post__acts {
    max-height: 60px;
    padding-top: 7px;
    padding-bottom: 7px;
    opacity: 1;
    border-top-color: var(--border);
  }
}

/* The icon picker inside a collection's editor. */
.icon-pick {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(42px, 1fr));
  gap: 6px;
}
.icon-pick button {
  display: grid;
  place-items: center;
  height: 42px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  color: var(--ink-2);
  font-size: 15px;
  cursor: pointer;
  transition: background 0.13s ease, border-color 0.13s ease, color 0.13s ease;
}
.icon-pick button:hover { background: var(--surface-hover); color: var(--ink); }
.icon-pick button[aria-pressed="true"] {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--bg);
}

/* The settings cog on a collection card — quiet until you go looking. */
.group__cog {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  color: var(--ink-3);
  font-size: 12px;
  cursor: pointer;
  transition: background 0.13s ease, color 0.13s ease, opacity 0.13s ease;
}
.group__cog:hover { background: var(--surface-hover); color: var(--ink); }
@media (hover: hover) and (pointer: fine) {
  .group__cog { opacity: 0; }
  .group:hover .group__cog, .group:focus-within .group__cog { opacity: 1; }
}

/* ================================================= 16. attachments
   Photos and files on the way in, and once they are attached to an entry.
   ================================================================== */
.tray {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 8px;
}
.tray:empty { display: none; }

.tray__item {
  position: relative;
  width: 76px;
  height: 76px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--surface);
  animation: rise 0.2s ease both;
}
.tray__item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tray__file {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 4px;
  width: 100%;
  height: 100%;
  padding: 6px;
  color: var(--ink-2);
  font-size: 10px;
  text-align: center;
  overflow: hidden;
}
.tray__file i { font-size: 17px; }
.tray__file span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }

.tray__x {
  position: absolute;
  top: 4px; right: 4px;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  border: 0;
  border-radius: 999px;
  background: rgba(11, 11, 11, 0.62);
  color: #fff;
  font-size: 10px;
  cursor: pointer;
}
.tray__x:hover { background: rgba(11, 11, 11, 0.85); }

/* Read it, or just keep it. A photo of a receipt is worth reading; a photo
   of the dog is worth keeping. The pill says which, and switches on tap. */
.tray__read {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 21px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border: 0;
  padding: 0 4px;
  background: rgba(11, 11, 11, 0.66);
  color: #fff;
  font: inherit;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.tray__read i { font-size: 9px; }
.tray__read[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
.tray__read:hover { filter: brightness(1.08); }
.tray__read:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* keep the filename clear of the pill */
.tray__item--choice .tray__file { padding-bottom: 25px; }

/* What is about to happen to the files in the tray, said in words. */
.tray__note {
  flex: 1 0 100%;
  display: flex; align-items: center; gap: 7px;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--ink-3);
}
.tray__note i { font-size: 11px; }

.tray__item.is-busy::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--overlay);
  backdrop-filter: blur(1px);
}
.tray__spin {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  z-index: 1;
  color: #fff;
  font-size: 14px;
}

/* the whole chat is a drop target */
.chat.is-dropping::after {
  content: 'Drop to attach';
  position: absolute;
  inset: 10px;
  z-index: 20;
  display: grid;
  place-items: center;
  border: 2px dashed var(--accent);
  border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--accent) 8%, var(--bg));
  color: var(--accent-ink);
  font-size: 15px;
  font-weight: 600;
  pointer-events: none;
}
.chat { position: relative; }

/* attached to a saved entry */
.files {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 15px 13px 63px;
}
.post__top + .files, .post__body + .files { padding-top: 0; }
.files a {
  display: block;
  width: 62px;
  height: 62px;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface);
}
.files a:hover { border-color: var(--border-strong); }
.files img { width: 100%; height: 100%; object-fit: cover; display: block; }
.files .files__doc {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 3px;
  width: 100%; height: 100%;
  padding: 5px;
  color: var(--ink-2);
  font-size: 16px;
}
.files__name {
  max-width: 100%;
  font-size: 8.5px;
  line-height: 1.15;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink-3);
}

/* Each file carries its own save button, tucked into the corner so it does
   not cover the thumbnail you are trying to look at. */
.files__one { position: relative; display: inline-block; }
.files__save {
  position: absolute;
  right: 3px; bottom: 3px;
  width: 22px; height: 22px;
  display: grid; place-items: center;
  border: 0;
  border-radius: 999px;
  background: rgba(11, 11, 11, 0.62);
  color: #fff;
  font-size: 10px;
  cursor: pointer;
  /* Visible without being loud. A save button nobody can find until they
     hover over it is a save button most people never find at all. */
  opacity: 0.82;
  transition: opacity 0.14s ease, background 0.14s ease;
}
.files__save:hover { opacity: 1; background: rgba(11, 11, 11, 0.88); }
.files__one:hover .files__save { opacity: 1; }
.files__save:focus-visible { opacity: 1; outline: 2px solid var(--accent); outline-offset: 1px; }

@media (max-width: 560px) { .files { padding-left: 15px; } }

/* the message the user sent, with its photos */
.bubble__files { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.bubble__files a { display: block; width: 84px; height: 84px; border-radius: 10px; overflow: hidden;
                   border: 1px solid var(--border); background: var(--surface); }
.bubble__files img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bubble__files .files__doc {
  display: grid; place-items: center; align-content: center; gap: 3px;
  width: 100%; height: 100%; padding: 6px; color: var(--ink-2); font-size: 18px;
}

/* full-size viewer */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(0, 0, 0, 0.88);
}
.lightbox img {
  max-width: 100%;
  max-height: calc(100dvh - 96px);
  border-radius: var(--r-md);
  object-fit: contain;
}
.lightbox__bar {
  position: absolute;
  top: calc(14px + env(safe-area-inset-top));
  right: 14px;
  display: flex;
  gap: 8px;
}
.lightbox__btn {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  font-size: 16px;
  cursor: pointer;
}
.lightbox__btn:hover { background: rgba(255, 255, 255, 0.26); }
.lightbox__btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* Once something is queued, the composer needs a solid backdrop — the
   gradient alone lets the cards behind it show through the thumbnails. */
.composer.has-tray { background: var(--bg); }
.composer.has-tray .tray { padding-top: 8px; }

/* ============================================ 17. "what category is this?"
   When Tidy cannot place a merchant it asks once, here, and remembers.
   ================================================================== */
.review {
  margin-top: 12px;
  border: 1px solid color-mix(in srgb, var(--warn) 40%, var(--border));
  border-radius: var(--r-md);
  background: var(--card);
  overflow: hidden;
}
.review__head {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 11px 14px;
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  font-size: 13.5px;
  font-weight: 600;
}
.review__head i { color: var(--warn); }
.review__head small { margin-left: auto; font-weight: 500; color: var(--ink-3); }

.review__row { padding: 12px 14px; border-top: 1px solid var(--border); }
.review__row:first-of-type { border-top: 0; }

.review__who { display: flex; align-items: baseline; gap: 8px; margin-bottom: 9px; }
.review__name { font-size: 14.5px; font-weight: 600; }
.review__meta { font-size: 12.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 31px;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink-2);
  font-size: 13px;
  cursor: pointer;
  transition: background 0.13s ease, color 0.13s ease, border-color 0.13s ease, transform 0.08s ease;
}
.chip:hover { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.chip:active { transform: scale(0.96); }
.chip--other { border-style: dashed; }
.chip[disabled] { opacity: 0.45; cursor: default; }

/* ------------------------------------------------------ the paywall ---- */

.wall {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center; padding: 20px;
  background: var(--bg);
  animation: fade 0.2s ease both;
}
.wall__card { width: min(400px, 100%); text-align: center; }
.wall__mark {
  display: grid; place-items: center;
  width: 52px; height: 52px; margin: 0 auto 20px;
  border-radius: 15px; background: var(--ink); color: var(--bg); font-size: 21px;
}
.wall h2 { font-size: 20px; margin: 0 0 10px; }
.wall p { color: var(--ink-2); font-size: 14.5px; margin: 0 0 22px; }
.wall__alt {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  margin-top: 18px; font-size: 13px; color: var(--ink-3);
}
.wall__alt a { color: var(--ink-3); }
.wall__alt a:hover { color: var(--ink); }

/* a trial running out — a strip, never a wall */
.trial-bar {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 10px; padding: 9px 10px 9px 13px;
  border: 1px solid var(--border); border-left: 3px solid var(--warn);
  border-radius: var(--r-md); background: var(--card);
  font-size: 13.5px;
}
.trial-bar i { color: var(--warn); }
.trial-bar span { flex: 1 1 auto; color: var(--ink-2); }
.trial-bar b { color: var(--ink); }

/* ----------------------------------------------------- first two minutes */

.ob {
  position: fixed; inset: 0; z-index: 95;
  display: grid; place-items: center; padding: 20px;
  background: var(--overlay); backdrop-filter: blur(3px);
  animation: fade 0.22s ease both;
}
.ob.is-going { opacity: 0; transition: opacity 0.2s ease; }
.ob__card {
  position: relative;
  width: min(420px, 100%);
  padding: 34px 28px 26px;
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--shadow-lg);
  text-align: center;
  animation: rise 0.26s ease both;
}
.ob__x {
  position: absolute; top: 14px; right: 16px;
  border: 0; background: none; cursor: pointer;
  font-size: 13px; color: var(--ink-3); padding: 4px 6px;
}
.ob__x:hover { color: var(--ink); }
.ob__icon {
  display: grid; place-items: center;
  width: 54px; height: 54px; margin: 0 auto 18px;
  border-radius: 16px; background: var(--ink); color: var(--bg); font-size: 21px;
}
.ob h2 { font-size: 20px; margin: 0 0 10px; }
.ob p {
  color: var(--ink-2); font-size: 14.5px; line-height: 1.55;
  margin: 0 auto 22px; max-width: 34ch;
}
.ob p i { color: var(--ink); font-style: italic; }
.ob__dots { display: flex; justify-content: center; gap: 6px; margin-bottom: 20px; }
.ob__dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--border-strong); transition: background 0.2s ease, width 0.2s ease;
}
.ob__dot.is-on { width: 18px; border-radius: 99px; background: var(--ink); }
.ob__skip {
  display: block; width: 100%; margin-top: 10px;
  border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 13.5px; color: var(--ink-3); padding: 8px;
}
.ob__skip:hover { color: var(--ink); }

@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* --------------------------------------------- a question, not a guess */

.ask {
  margin-top: 12px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-md);
  background: var(--card-alt);
  padding: 12px 14px;
}
.ask__q {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin-bottom: 11px;
  font-size: 14px;
  line-height: 1.45;
  font-weight: 600;
}
.ask__q i { color: var(--accent); margin-top: 2px; font-size: 13px; }
.ask__answered {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--ok-text);
}
.ask__answered i { font-size: 13px; }

/* free-text category, when none of the offered chips fit */
.review__free { display: flex; flex-wrap: wrap; gap: 6px; width: 100%; }
.review__free .input {
  height: 31px;
  flex: 1 1 140px;
  min-width: 0;
  max-width: 320px;
  font-size: 13px;
  padding: 0 12px;
}
.review__go {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 31px;
  padding: 0 14px;
  border: 1px solid var(--ink);
  border-radius: 999px;
  background: var(--ink);
  color: var(--bg);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.13s ease, transform 0.08s ease;
}
.review__go:hover { opacity: 0.86; }
.review__go:active { transform: scale(0.96); }
.review__go--quiet {
  border-color: var(--border-strong);
  background: transparent;
  color: var(--ink-3);
  font-weight: 500;
}
.review__go--quiet:hover { color: var(--ink); border-color: var(--ink-3); opacity: 1; }
.review__go[disabled] { opacity: 0.45; cursor: default; }

.review__done {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--ok-text);
}
.review__done b { color: var(--ink); }
.review__done small { margin-left: auto; color: var(--ink-3); font-weight: 500; }

/* a container the message started */
.started {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease;
}
.started:hover { background: var(--card-alt); border-color: var(--border-strong); }
.started__body { flex: 1 1 auto; min-width: 0; }
.started__name { font-size: 14.5px; font-weight: 600; }
.started__meta { font-size: 12.5px; color: var(--ink-3); }

/* a banner on a type page when things are waiting */
.needs-bar {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-bottom: 16px;
  padding: 12px 14px;
  border: 1px solid color-mix(in srgb, var(--warn) 40%, var(--border));
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--warn) 9%, transparent);
  font-size: 13.5px;
}
.needs-bar i.lead { color: var(--warn); }
.needs-bar__text { flex: 1 1 auto; }

/* ==================================================== 18. search overlay
   A magnifier in the top bar rather than a permanent box eating a row.
   ================================================================== */
.search-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: max(8vh, 40px) 16px 16px;
  background: var(--overlay);
  backdrop-filter: blur(3px);
}
.search-panel {
  width: min(620px, 100%);
  max-height: min(70dvh, 70vh);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  animation: rise 0.18s ease both;
}
.search-panel__top {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
}
.search-panel__top i { color: var(--ink-3); }
.search-panel__top input {
  flex: 1 1 auto;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 16px;
  outline: none;
}
.search-panel__esc {
  font-size: 11px;
  color: var(--ink-3);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 2px 6px;
}
.search-results { overflow-y: auto; padding: 6px; overscroll-behavior: contain; }
.search-group {
  padding: 10px 10px 4px;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.search-hit {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  text-align: left;
  cursor: pointer;
}
.search-hit:hover, .search-hit.is-active { background: var(--surface-hover); }
.search-hit__body { flex: 1 1 auto; min-width: 0; }
.search-hit__title { font-size: 14px; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-hit__meta { font-size: 12px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-hit__val { flex: 0 0 auto; font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.search-empty { padding: 30px 16px; text-align: center; color: var(--ink-3); font-size: 14px; }

@media (max-width: 900px) {
  .search-overlay { padding: 0; }
  .search-panel {
    width: 100%;
    max-height: 100dvh;
    height: 100dvh;
    border: 0;
    border-radius: 0;
  }
  .search-panel__top { padding-top: calc(12px + env(safe-area-inset-top)); }
}
