/* Keim — styling follows design/prototype.html.
   Tokens, type and card shapes are taken from that file rather than
   reinvented here. The prototype is light-only; dark is a person's
   choice in Settings (data-theme on <html>, see partials/head.ejs), and
   is nothing but these tokens redefined. Every colour below the token
   blocks goes through a token for that reason -- a hex value added lower
   down will stay light in the dark theme. */

:root {
  color-scheme: light;

  --stone: #f0ebe3;
  --ink: #2a2723;
  --ink-soft: #6b655b;
  --moss: #5b6b4c;
  --moss-light: #edf0e7;
  --clay: #a6613d;
  --clay-light: #f5e9e2;
  --hairline: #d8d2c6;
  --card: #ffffff;

  --page-top: #f6f2ec;
  --card-edge: #e3ded3;
  --card-edge-hover: #d5cec0;
  --rule: #ece7dd;
  --faint: #a39c8e;
  --label: #9a9284;
  --on-moss: #fff;
  --moss-deep: #4d5c40;
  --moss-ink: #3f4a34;
  --wash: rgba(255, 255, 255, 0.6);
  /* Text on an ink fill: your chat bubbles, the undo bar. */
  --on-ink: #f2eee7;
  --on-ink-soft: #a09889;
  --on-ink-accent: #d9c7a6;
}

/* Warm charcoal rather than black, so it is still the same stone. Written
   out twice because CSS cannot share a block between a selector and a
   media query: once chosen outright, once for "match device". */
:root[data-theme="dark"] {
  color-scheme: dark;

  --stone: #1c1a17;
  --ink: #ece6dc;
  --ink-soft: #a89f92;
  --moss: #9bb087;
  --moss-light: #2a3224;
  --clay: #d98f66;
  --clay-light: #3a2a22;
  --hairline: #3d3833;
  --card: #26231f;

  --page-top: #221f1b;
  --card-edge: #34302b;
  --card-edge-hover: #4a443d;
  --rule: #302c27;
  --faint: #7d7569;
  --label: #8a8276;
  --on-moss: #1a1f14;
  --moss-deep: #adc19a;
  --moss-ink: #c5d2b6;
  --wash: rgba(255, 255, 255, 0.06);
  --on-ink: #1f1c19;
  --on-ink-soft: #6d665c;
  --on-ink-accent: #8a4f2f;
}

@media (prefers-color-scheme: dark) {
  :root[data-theme="auto"] {
    color-scheme: dark;

    --stone: #1c1a17;
    --ink: #ece6dc;
    --ink-soft: #a89f92;
    --moss: #9bb087;
    --moss-light: #2a3224;
    --clay: #d98f66;
    --clay-light: #3a2a22;
    --hairline: #3d3833;
    --card: #26231f;

    --page-top: #221f1b;
    --card-edge: #34302b;
    --card-edge-hover: #4a443d;
    --rule: #302c27;
    --faint: #7d7569;
    --label: #8a8276;
    --on-moss: #1a1f14;
    --moss-deep: #adc19a;
    --moss-ink: #c5d2b6;
    --wash: rgba(255, 255, 255, 0.06);
    --on-ink: #1f1c19;
    --on-ink-soft: #6d665c;
    --on-ink-accent: #8a4f2f;
  }
}

/* Large: everything here is sized in rem, so raising the root raises the
   lot -- text, padding, tap targets -- in proportion. */
:root[data-layout="large"] {
  font-size: 118.75%;
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

body {
  margin: 0;
  /* bottom clears the fixed nav, and the iPhone home indicator under it */
  padding: 1.5rem 1rem calc(6rem + env(safe-area-inset-bottom));
  max-width: 430px;
  margin-inline: auto;
  font-family: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  /* A slight warm lift at the top rather than one flat fill. Barely
     perceptible on its own, which is the point -- it stops the screen
     reading as a sheet of grey card stock. */
  background: var(--stone);
  /* Deliberately not background-attachment: fixed -- iOS Safari handles it
     badly, and the gradient resolves to --stone by 22rem anyway, so
     scrolling with the page looks the same and costs nothing. */
  background-image: linear-gradient(180deg, var(--page-top) 0%, var(--stone) 22rem);
  background-repeat: no-repeat;
  color: var(--ink);
  /* Stops iOS enlarging the text when the phone is turned sideways. */
  -webkit-text-size-adjust: 100%;
}

h1,
h2 {
  font-family: Fraunces, Georgia, "Times New Roman", serif;
  font-weight: 600;
  margin: 0;
}

header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 1rem;
}

header h1 {
  font-size: 1.75rem;
  letter-spacing: -0.02em;
}

header .date {
  font-size: 0.75rem;
  color: var(--ink-soft);
}

/* The capture bar. One field, always at the top, same as the prototype. */
/* The primary affordance on every screen, so it sits slightly proud of the
   page rather than blending into it. */
.chat-box {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 18px;
  /* Thin, so the field itself fills the bar: a tap anywhere on it lands
     in the input rather than on the padding around it. */
  padding: 0.3rem 0.4rem 0.3rem 0.95rem;
  margin-bottom: 1.75rem;
  box-shadow:
    0 1px 2px rgba(42, 39, 35, 0.04),
    0 10px 28px -14px rgba(42, 39, 35, 0.18);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* The Queue screen's section chips sit right under the bar and take over
   its gap to the page below. */
.chat-box.has-sections {
  margin-bottom: 0.6rem;
}

/* One row that swipes, never a block of rows: with a dozen lists a
   wrapping row would push the page half a screen down. It runs to the
   screen's edges, so a button cut off at the side says there is more. */
.capture-sections {
  display: flex;
  gap: 0.4rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  margin: 0 -1rem 1.5rem;
  padding: 0 1rem;
}

.capture-sections::-webkit-scrollbar {
  display: none;
}

/* relative: holds the hidden radio inside the row, which would otherwise
   sit outside its scrolling and widen the whole page. */
.section-chip {
  position: relative;
  flex: none;
  white-space: nowrap;
}

.section-chip input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.section-chip span {
  display: inline-block;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink-soft);
  font-size: 0.8rem;
  padding: 0.35rem 0.8rem;
  cursor: pointer;
}

.section-chip input:checked + span {
  background: var(--moss-light);
  border-color: var(--moss);
  color: var(--moss);
}

.section-chip input:focus-visible + span {
  outline: 2px solid var(--moss);
  outline-offset: 2px;
}

/* The rest of a well-known title, grey after what was typed on the Queue
   screen (titles.js): drawn over the field, lined up with its text. Only
   the grey takes a tap. */
.chat-box[data-titles] {
  position: relative;
}

.title-ghost {
  position: absolute;
  box-sizing: border-box;
  overflow: hidden;
  white-space: pre;
  text-overflow: ellipsis;
  font-size: 1rem;
  pointer-events: none;
}

.title-ghost .typed {
  visibility: hidden;
}

.title-ghost .rest {
  color: var(--faint);
  pointer-events: auto;
  cursor: pointer;
}

.chat-box:focus-within {
  border-color: var(--moss);
  box-shadow:
    0 0 0 3px var(--moss-light),
    0 10px 28px -14px rgba(42, 39, 35, 0.18);
}

.chat-box input {
  flex: 1;
  min-width: 0;
  padding: 0.6rem 0;
  border: none;
  outline: none;
  background: transparent;
  font-family: inherit;
  /* 16px, not smaller: iOS zooms the whole page into any field under that
     the moment it is tapped, and leaves it zoomed after sending. The same
     goes for every other text field below. */
  font-size: 1rem;
  color: var(--ink);
}

.chat-box input::placeholder {
  color: var(--faint);
}

.chat-box button {
  flex: none;
  width: 36px;
  height: 36px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--ink);
  color: var(--stone);
  font-family: inherit;
  font-size: 0.9rem;
  cursor: pointer;
}

/* Sent and waiting on a reply (capture.js). The button pulses rather than
   spins: slow, quiet, and still readable as "working". */
.chat-box[aria-busy="true"] input {
  color: var(--ink-soft);
}

.chat-box[aria-busy="true"] button {
  cursor: progress;
  animation: sending 1.2s ease-in-out infinite;
}

@keyframes sending {
  50% { opacity: 0.35; }
}

@media (prefers-reduced-motion: reduce) {
  .chat-box[aria-busy="true"] button {
    animation: none;
    opacity: 0.5;
  }
}

section {
  margin-bottom: 1.75rem;
}

/* Section labels. Small, spaced and uppercase so they read as furniture
   rather than competing with the item titles underneath them. */
h2 {
  font-family: "IBM Plex Sans", sans-serif;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--label);
  margin: 0 0.3rem 0.7rem;
}

/* The focus card carries facts and forms, so it stays a card rather than
   taking the pill shape the list stones use. */
.item-card {
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 18px;
  padding: 1.15rem 1.2rem;
  /* Two shadows, both very light: a tight one to seat the card on the
     background, and a wide soft one for depth. A single heavy shadow is
     what makes a page look like a template. */
  box-shadow:
    0 1px 2px rgba(42, 39, 35, 0.04),
    0 8px 24px -12px rgba(42, 39, 35, 0.13);
}

.pending-card {
  border-color: var(--clay);
}

.category {
  display: inline-block;
  font-size: 0.7rem;
  color: var(--ink-soft);
  margin-bottom: 0.15rem;
}

.title {
  font-size: 0.95rem;
  font-weight: 500;
  line-height: 1.35;
  margin: 0.15rem 0;
}

.due {
  font-size: 0.7rem;
  color: var(--ink-soft);
  margin: 0;
}

/* Inside a line of other details it takes that line's size. */
.focus-meta .due,
.stone-sub .due {
  font-size: inherit;
}

/* Clay is for what wants attention, and a date gone by does. */
.due.overdue {
  color: var(--clay);
}

.question {
  font-size: 0.8rem;
  color: var(--ink-soft);
  margin: 0.35rem 0 0;
}

/* ---- The focus card ----
   Task, then what it is, then what Keim knows about it. Clay is reserved
   for things wanting attention -- the pending border and this card's spine.
   A fact is context, not an alert, so it is quiet grey text and not the
   clay chip it used to be. */

.focus-card .title {
  font-size: 1.1rem;
  line-height: 1.3;
  margin: 0;
}

.focus-meta {
  font-size: 0.72rem;
  color: var(--ink-soft);
  margin: 0.3rem 0 0;
}

.focus-facts {
  list-style: none;
  margin: 0.85rem 0 0;
  padding: 0.7rem 0 0;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

/* Everything about editing a fact, shut by default. */
.notes-drawer {
  margin-top: 0.9rem;
  border-top: 1px solid var(--rule);
  padding-top: 0.7rem;
}

.notes-drawer > summary {
  list-style: none;
  cursor: pointer;
  padding: 0.4rem 0;
  font-size: 0.75rem;
  color: var(--ink-soft);
}

.notes-drawer > summary::-webkit-details-marker {
  display: none;
}

.notes-drawer > summary::before {
  content: "+ ";
}

.notes-drawer[open] > summary::before {
  content: "− ";
}

.notes-drawer[open] > summary {
  margin-bottom: 0.5rem;
}

.correcting {
  font-size: 0.68rem;
  color: var(--ink-soft);
  margin: 0.7rem 0 0;
}

/* Facts read as clay-tinted notes, as in the prototype's stone-note. */
.facts {
  list-style: none;
  margin: 0.7rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.fact-content {
  display: inline-block;
  font-size: 0.7rem;
  color: var(--clay);
  background: var(--clay-light);
  padding: 0.15rem 0.45rem;
  border-radius: 8px;
}

.fact-form {
  display: flex;
  gap: 0.35rem;
  margin-top: 0.3rem;
}

.fact-form input {
  flex: 1;
  min-width: 0;
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  font-family: inherit;
  font-size: 1rem;
  background: var(--stone);
  color: var(--ink);
  outline: none;
}

.fact-form input:focus {
  border-color: var(--moss);
}

.fact-form button {
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 0.75rem;
  cursor: pointer;
}

.add-fact {
  margin-top: 0.7rem;
}

.actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.9rem;
  flex-wrap: wrap;
}

.actions form {
  flex: 1;
}

.actions button {
  width: 100%;
  padding: 0.7rem;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  background: var(--card);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}

/* Scoped under .actions so these beat the generic `.actions button` rule
   above -- a bare `.complete` loses on specificity. */
.actions .complete {
  background: var(--moss);
  border-color: var(--moss);
  color: var(--on-moss);
}

.actions .skip {
  background: var(--card);
  color: var(--ink-soft);
}

.choices {
  margin-top: 0.9rem;
}

.choices form {
  flex: 1 1 8rem;
}

/* The exit from a pending question. Deliberately quiet -- a plain
   underlined text button, not another pill -- so it reads as "get rid of
   this" rather than competing with the real list choices above it. */
.dismiss-pending {
  margin-top: 0.7rem;
  text-align: right;
}

.dismiss-pending button {
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  font-size: 0.72rem;
  color: var(--ink-soft);
  text-decoration: underline;
  text-decoration-color: var(--hairline);
  cursor: pointer;
}

.dismiss-pending button:hover {
  color: var(--ink);
}

/* List rows are the prototype's stones: pill-shaped, flatter than a card. */
.item-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.item-row {
  background: var(--card);
  border: 1.5px solid var(--hairline);
  border-radius: 999px / 30px;
  padding: 0.85rem 1.3rem;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.item-row .category {
  order: 2;
  width: 100%;
  margin: 0;
  font-size: 0.72rem;
}

.item-row .title {
  order: 1;
  flex: 1;
  font-size: 0.875rem;
  margin: 0;
}

.item-row .due {
  order: 3;
  font-size: 0.72rem;
}

/* On the Lists screen: title with its date underneath, Remove at the side.
   Side by side, the date and Remove left a phone's title a third of the
   row and wrapped it over three lines. */
.list-row {
  align-items: center;
  flex-wrap: nowrap;
}

.list-row .row-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.list-row form {
  flex: none;
}

.empty {
  color: var(--ink-soft);
  font-size: 0.8rem;
  margin: 0.2rem 0.25rem;
}

/* ---- Bottom nav ---- */
/* Fixed to the bottom on a phone, matching the design's tab bar. The inner
   width tracks the body's column so it lines up on a desktop window too. */
.navbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  gap: 0.25rem;
  max-width: 430px;
  margin-inline: auto;
  padding: 0.6rem 0.75rem max(1.1rem, env(safe-area-inset-bottom));
  background: var(--stone);
  border-top: 1px solid var(--hairline);
  /* Above the task cards, which sit on their own layer (z-index 1) for
     the swipe. Without this, scrolling a card down to the bar drew it
     over the tabs. */
  z-index: 10;
}

/* The undo bar: dark, so it reads as a passing message rather than part
   of the page, and just above the tab bar. It floats over the foot of the
   page for a few seconds (app.js hides it after that), which is fine
   because the only thing it covers is the account line. */
.undo-bar {
  position: fixed;
  left: 1rem;
  right: 1rem;
  bottom: calc(4.9rem + env(safe-area-inset-bottom));
  z-index: 5;
  max-width: calc(430px - 2rem);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.35rem 0.4rem 0.35rem 0.95rem;
  background: var(--ink);
  color: var(--stone);
  border-radius: 14px;
  box-shadow: 0 10px 28px -10px rgba(42, 39, 35, 0.45);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.undo-bar.leaving {
  opacity: 0;
  transform: translateY(0.5rem);
  pointer-events: none;
}

.undo-label {
  flex: 1;
  min-width: 0;
  font-size: 0.8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.undo-bar form {
  flex: none;
  margin: 0;
}

.undo-bar button {
  min-height: 2.5rem;
  padding: 0 0.9rem;
  border: none;
  border-radius: 10px;
  background: transparent;
  color: var(--on-ink-accent);
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
  .undo-bar { transition: none; }
}

/* Chat reads oldest to newest, so its capture bar docks at the bottom with
   the nav, where the newest message is -- the usual messaging-app shape.
   Inside the fixed nav rather than sticky above it, so it can never drift
   off the nav's edge whatever height the nav ends up. */
.navbar.with-capture {
  flex-wrap: wrap;
}

.navbar.with-capture .chat-box {
  flex: 0 0 100%;
  margin: 0 0 0.6rem;
}

body:has(.navbar.with-capture) {
  padding-bottom: calc(10.5rem + env(safe-area-inset-bottom));
}


.navbtn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem;
  text-decoration: none;
  color: var(--ink-soft);
  font-size: 0.7rem;
}

.navbtn.active {
  color: var(--ink);
  font-weight: 500;
}

.navbtn .icon {
  font-size: 1.15rem;
  line-height: 1;
}

/* On a phone the account controls live at the foot of the page instead
   (partials/nav.ejs); the desktop rail below brings these back. */
.navbar .sign-out,
.navbar .sign-up-link,
.navbar .rail-link {
  display: none;
}

.account-foot {
  margin: 2.5rem 0.25rem 0;
  padding-top: 1rem;
  border-top: 1px solid var(--hairline);
  font-size: 0.75rem;
  color: var(--ink-soft);
}

.account-foot form {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.account-email {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-foot button {
  flex: none;
  min-height: 2.25rem;
  padding: 0 1rem;
  background: none;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  font-family: inherit;
  font-size: 0.75rem;
  color: var(--ink-soft);
  cursor: pointer;
}

.account-foot a {
  color: var(--moss);
}

/* Beside sign-out: somewhere you go now and then, not every day. */
.account-foot .history-link {
  display: inline-block;
  margin-bottom: 0.75rem;
  padding: 0.35rem 0;
}

/* ---- History screen ----
   A log to scan, so plain lines rather than the cards and stones of the
   screens where things get done. */
.history {
  list-style: none;
  margin: 0 0 1.6rem;
  padding: 0;
}

.history-row {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.6rem 0.25rem;
  border-bottom: 1px solid var(--hairline);
}

.history-row:last-child {
  border-bottom: none;
}

.history-time {
  flex: none;
  width: 4.2rem;
  font-size: 0.7rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.history-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.history-what {
  font-size: 0.85rem;
  overflow-wrap: anywhere;
}

.history-verb {
  font-weight: 600;
}

.history-detail {
  font-size: 0.72rem;
  color: var(--ink-soft);
}

.history-row form {
  flex: none;
  align-self: center;
}

.history-older {
  margin: 0 0.25rem;
  font-size: 0.8rem;
}

.history-older a {
  color: var(--moss);
}

/* A list's done screen: the way back to the list it belongs to. */
/* What the assistant was called for today, and the rows it touched: the
   calls that cost money, easy to pick out. */
.history-usage {
  font-size: 0.75rem;
  color: var(--ink-soft);
  margin: -0.5rem 0 1.25rem;
}

.history-detail.by-assistant {
  color: var(--clay);
}

/* To do / Done on Lists and Queue: two halves of one pill. */
.view-toggle {
  display: flex;
  gap: 0.25rem;
  padding: 0.2rem;
  margin: 0 0 1.25rem;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--card);
}

.view-toggle a {
  flex: 1;
  text-align: center;
  padding: 0.4rem 0;
  border-radius: 999px;
  font-size: 0.8rem;
  color: var(--ink-soft);
  text-decoration: none;
}

.view-toggle a.on {
  background: var(--moss-light);
  color: var(--moss);
}

.history-back {
  margin: 0 0.25rem 0.8rem;
  font-size: 0.8rem;
}

.history-back a {
  color: var(--moss);
  text-decoration: none;
  display: inline-block;
  padding: 0.3rem 0;
}

/* ---- Lists screen ---- */
.cat-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 0 0.25rem 0.6rem;
}

.cat-head h2 {
  font-family: Fraunces, Georgia, serif;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
  margin: 0;
}

.cat-count {
  font-size: 0.7rem;
  color: var(--ink-soft);
}

/* "12 done": a small link, padded out to something a thumb can hit. */
.cat-done {
  color: var(--moss);
  text-decoration: none;
  padding: 0.5rem 0 0.5rem 0.2rem;
}

/* ---- Notes screen ---- */
.review-banner {
  background: var(--clay-light);
  color: var(--ink);
  border-radius: 14px;
  padding: 0.8rem 0.95rem;
  font-size: 0.78rem;
  margin: 0 0 1.1rem;
}

.note-card {
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 14px;
  padding: 0.8rem 0.95rem;
  margin-bottom: 0.7rem;
}

.note-title {
  font-size: 0.85rem;
  font-weight: 500;
  margin: 0 0 0.35rem;
}

.note-body {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.75rem;
  color: var(--ink-soft);
  line-height: 1.5;
}

/* A note you can tap open to correct or forget. It reads as the plain line
   it always was; the padding is there to give a finger something to hit. */
.fact-edit > summary {
  list-style: none;
  cursor: pointer;
  padding: 0.45rem 0;
}

.fact-edit > summary::-webkit-details-marker { display: none; }

/* Open, the line heads the form under it, so it takes the ink colour. */
.fact-edit[open] > summary {
  color: var(--ink);
  font-weight: 500;
}

.fact-forget {
  margin: 0.45rem 0 0.35rem;
}

/* ---- Queue lists (Watch & read) ---- */
.queue-label {
  font-size: 0.7rem;
  color: var(--ink-soft);
  margin: 0 0.25rem 0.5rem;
}

.up-next {
  margin-bottom: 1rem;
}

/* Below every section, quiet: a tidy-up, not something to do every day. */
.sort-queue {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
  margin: 1.5rem 0.25rem 0;
}

.sort-queue /* A yes/no on the edit screen, sized for a thumb. */
.check-field {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.3rem;
  font-size: 1rem;
  color: var(--ink);
  cursor: pointer;
}

.check-field input {
  width: 1.2rem;
  height: 1.2rem;
  margin: 0;
  accent-color: var(--moss);
}

.field-hint {
  margin: 0;
}

/* The title sets order: 1, so an unordered form would sit in front of it. */
.item-row form {
  order: 4;
  margin: 0 0 0 auto;
}

.pill {
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 0.65rem;
  padding: 0.2rem 0.6rem;
  cursor: pointer;
}

.pill.on {
  background: var(--moss-light);
  border-color: var(--moss);
  color: var(--moss);
}

/* The row's own finish: the moss of the focus card's Done, in outline so
   a list of them doesn't shout. */
.pill.done {
  border-color: var(--moss);
  color: var(--moss);
}

/* Removing is the rarer thing to want, and it is the one press here that
   takes something away -- so it stays quiet until reached for, rather
   than sitting at the same weight as the action you came to the screen
   for. Colour on hover only; the border still gives it an edge to aim at
   on a touch screen, where there is no hover at all. */
.pill.remove {
  border-color: transparent;
  color: var(--ink-soft);
  opacity: 0.75;
}

.pill.remove:hover,
.pill.remove:focus-visible {
  border-color: var(--clay);
  color: var(--clay);
  opacity: 1;
}

/* ---- Add a list ---- */
.add-list {
  margin-top: 0.5rem;
}

.add-list > summary {
  list-style: none;
  cursor: pointer;
  border: 1.5px dashed var(--hairline);
  border-radius: 14px;
  padding: 0.8rem;
  text-align: center;
  font-size: 0.8rem;
  color: var(--ink-soft);
}

.add-list > summary::-webkit-details-marker { display: none; }
.add-list[open] > summary { margin-bottom: 0.9rem; }

.field-label {
  display: block;
  font-size: 0.7rem;
  color: var(--ink-soft);
  margin-bottom: 0.35rem;
}

.text-input {
  width: 100%;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 0.65rem 0.75rem;
  font-family: inherit;
  font-size: 1rem;
  color: var(--ink);
  margin-bottom: 1rem;
  outline: none;
}

.text-input:focus { border-color: var(--moss); }

.type-option {
  display: flex;
  gap: 0.65rem;
  align-items: flex-start;
  background: var(--card);
  border: 1.5px solid var(--hairline);
  border-radius: 14px;
  padding: 0.7rem 0.75rem;
  margin-bottom: 0.55rem;
  cursor: pointer;
}

.type-option:has(input:checked) { border-color: var(--moss); }
.type-option input { margin-top: 0.2rem; accent-color: var(--moss); }
.type-name { display: block; font-size: 0.8rem; font-weight: 500; }
.type-desc { display: block; font-size: 0.7rem; color: var(--ink-soft); line-height: 1.45; margin-top: 0.1rem; }

.create-list {
  width: 100%;
  background: var(--ink);
  color: var(--stone);
  border: none;
  border-radius: 14px;
  padding: 0.8rem;
  font-family: inherit;
  font-size: 0.85rem;
  margin-top: 0.5rem;
  cursor: pointer;
}

.form-error {
  background: var(--clay-light);
  color: var(--clay);
  border-radius: 12px;
  padding: 0.65rem 0.8rem;
  font-size: 0.78rem;
  margin: 0 0 1rem;
}

/* ---- Editing an item ---- */

/* A title you can tap to edit. It looks like the title it always was --
   the screens are for reading, and underlining every item on them would
   say otherwise. No callout, so a long press on a phone doesn't open a
   link preview in the middle of a swipe. */
.edit-link {
  color: inherit;
  text-decoration: none;
  -webkit-touch-callout: none;
}

.edit-link:hover,
.edit-link:focus-visible {
  text-decoration: underline;
  text-decoration-color: var(--hairline);
  text-underline-offset: 0.2em;
}

/* Same height as the title field. iOS draws a date input as a grey
   pill unless its native look is turned off; a select keeps its own, since
   the arrow is what says it opens. */
.edit-item input[type='date'],
.edit-item select {
  min-height: 2.9rem;
}

.edit-item input[type='date'] {
  -webkit-appearance: none;
  appearance: none;
}

.edit-item .check-field + .field-hint {
  margin: 0 0 1rem;
}

.edit-item input[type='date'] + .field-hint {
  margin: -0.65rem 0 1rem;
}

.field-hint {
  font-size: 0.7rem;
  color: var(--ink-soft);
}

.edit-actions {
  display: flex;
  gap: 0.6rem;
}

.edit-actions .create-list {
  flex: 1;
  margin-top: 0;
}

.edit-cancel {
  flex: 1;
  text-align: center;
  padding: 0.8rem;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  color: var(--ink);
  font-size: 0.85rem;
  text-decoration: none;
}

.edit-facts {
  margin-top: 1.6rem;
}

.edit-facts .focus-facts {
  margin-bottom: 0.4rem;
}

.edit-remove {
  margin-top: 1.6rem;
  text-align: center;
}

/* ---- Asking ---- */
.asked-question {
  font-family: Fraunces, Georgia, serif;
  font-size: 1.05rem;
  line-height: 1.35;
  color: var(--ink);
  margin: 0 0.25rem 1.1rem;
}

.report h2 {
  font-family: Fraunces, Georgia, serif;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
}

.report-answer {
  font-size: 0.9rem;
  margin: 0 0.25rem 0.7rem;
}

.capability-list {
  list-style: none;
  margin: 0.4rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.78rem;
  color: var(--ink-soft);
}

.rescue {
  margin-top: 1.25rem;
}

.rescue button {
  width: 100%;
  background: none;
  border: 1.5px dashed var(--hairline);
  border-radius: 14px;
  padding: 0.75rem;
  font-family: inherit;
  font-size: 0.78rem;
  color: var(--ink-soft);
  cursor: pointer;
}

/* ---- Renaming a subject ---- */
.rename {
  margin-top: 0.6rem;
}

.rename > summary {
  list-style: none;
  cursor: pointer;
  font-size: 0.7rem;
  color: var(--ink-soft);
}

.rename > summary::-webkit-details-marker { display: none; }
.rename[open] > summary { margin-bottom: 0.4rem; }

/* ---- Assistant reply ---- */
.reply-card {
  margin-bottom: 1rem;
}

.reply-text {
  font-size: 0.9rem;
  line-height: 1.5;
  margin: 0;
}

.reply-actions {
  list-style: none;
  margin: 0.7rem 0 0;
  padding: 0.7rem 0 0;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.75rem;
  color: var(--ink-soft);
}

.reply-actions strong {
  font-weight: 500;
  color: var(--ink);
}

/* ---- Signing in ----
   No capture bar, no nav, no fixed footer to clear -- so this one screen
   centres in the window rather than sitting under the app chrome. */
body.auth {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 100vh;
  padding: 2rem 1.25rem;
  max-width: 24rem;
}

.auth-header {
  display: block;
  text-align: center;
  margin-bottom: 1.75rem;
}

.auth-header h1 {
  font-family: Fraunces, Georgia, serif;
  font-size: 2.2rem;
  letter-spacing: -0.02em;
  margin: 0;
}

.auth-tagline {
  font-size: 0.78rem;
  color: var(--ink-soft);
  margin: 0.4rem 0 0;
}

.auth-card {
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 18px;
  padding: 1.5rem 1.35rem;
  box-shadow:
    0 1px 2px rgba(42, 39, 35, 0.04),
    0 12px 32px -16px rgba(42, 39, 35, 0.2);
}

.auth-card h2 {
  font-family: Fraunces, Georgia, serif;
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  margin: 0 0 1rem;
}

.auth-note {
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--moss-ink);
  background: var(--moss-light);
  border-radius: 12px;
  padding: 0.7rem 0.8rem;
  margin: 0 0 1rem;
}

.auth-form .field-label {
  margin-top: 0.85rem;
}

.auth-form .field-label:first-child {
  margin-top: 0;
}

.field-hint {
  font-size: 0.68rem;
  color: var(--ink-soft);
  line-height: 1.45;
  margin: 0.35rem 0 0;
}

.auth-alt {
  font-size: 0.75rem;
  color: var(--ink-soft);
  text-align: center;
  margin: 1rem 0 0;
}

.auth-alt a {
  color: var(--moss);
}

/* Signing out lives in the nav rail, so it does not need a screen. */
.sign-out {
  margin-top: auto;
  padding-top: 0.75rem;
}

.sign-out button {
  width: 100%;
  background: none;
  border: none;
  font-family: inherit;
  font-size: 0.7rem;
  color: var(--ink-soft);
  text-align: left;
  padding: 0.5rem 0.8rem;
  cursor: pointer;
  border-radius: 10px;
}

.sign-out button:hover {
  background: var(--wash);
}

/* ---- Chat ----
   Newest first, so the latest exchange sits directly under the capture bar
   at the top of the screen. That falls out of the bar living there in this
   design, and it means the transcript needs no scrolling script. */

.transcript {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.transcript-day {
  align-self: center;
  font-size: 0.63rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--label);
  margin: 0.7rem 0 0.2rem;
}

/* 84% of a phone, but capped to a readable measure once the column is wide
   -- a 700px-wide bubble holding four words looks broken. */
.bubble {
  max-width: min(84%, 32rem);
  padding: 0.7rem 0.9rem;
  border-radius: 16px;
}

/* You on the right in ink, Keim on the left on card. The flattened corner
   differs too, so a glance tells them apart without reading. */
.bubble.user {
  align-self: flex-end;
  background: var(--ink);
  color: var(--on-ink);
  border-bottom-right-radius: 5px;
}

.bubble.cairn {
  align-self: flex-start;
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-bottom-left-radius: 5px;
  box-shadow: 0 1px 2px rgba(42, 39, 35, 0.04);
}

.bubble-text {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.5;
  /* Report summaries arrive as bulleted lines, not one paragraph. */
  white-space: pre-wrap;
}

.bubble-actions {
  list-style: none;
  margin: 0.6rem 0 0;
  padding: 0.55rem 0 0;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.72rem;
  color: var(--ink-soft);
}

.bubble-actions strong {
  font-weight: 500;
  color: var(--ink);
}

.bubble-meta {
  display: block;
  margin-top: 0.4rem;
  font-size: 0.62rem;
  color: var(--ink-soft);
}

.bubble.user .bubble-meta {
  color: var(--on-ink-soft);
}

.chat-starters {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}

.chat-starters button {
  width: 100%;
  text-align: left;
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 14px;
  padding: 0.65rem 0.85rem;
  font-family: inherit;
  font-size: 0.8rem;
  color: var(--ink-soft);
  cursor: pointer;
}

/* ---- What Keim said, on a screen that is not Chat ---- */
.said {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  background: var(--moss-light);
  border-radius: 14px;
  padding: 0.7rem 0.85rem;
  margin: -0.9rem 0 1.5rem;
}

.said-text {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--moss-ink);
  white-space: pre-wrap;
}

.said-more {
  flex: none;
  font-size: 0.7rem;
  color: var(--moss);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}

/* ---- Stones: swipe, drag, keyboard ----
   The prototype's cairn stack. Three input modalities share one set of
   shapes; what changes between them is the affordance, not the layout.
   Everything gesture-related is gated on .stones-live, which stones.js
   sets -- a page without that file must not promise a swipe. */

.stack {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.stone-outer {
  position: relative;
  overflow: hidden;
  border-radius: 999px / 30px;
}

/* The focus card keeps its card shape; only the mask around it changes. */
.stone-outer.card-shape {
  border-radius: 18px;
}

.stone-outer.dragging {
  user-select: none;
}

/* Behind the stone, revealed as it slides off. Decoration for a gesture --
   aria-hidden in the markup, because the buttons are the real controls. */
.swipe-hint {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  align-items: center;
  font-size: 0.78rem;
  font-weight: 500;
  opacity: 0;
  transition: opacity 0.15s ease;
}

.swipe-hint.left {
  justify-content: flex-start;
  padding-left: 1.35rem;
  background: var(--hairline);
  color: var(--ink-soft);
}

.swipe-hint.right {
  justify-content: flex-end;
  padding-right: 1.35rem;
  background: var(--moss);
  color: var(--on-moss);
}

.stone-outer.sliding-right .swipe-hint.right,
.stone-outer.sliding-left .swipe-hint.left {
  opacity: 1;
}

.stone-outer.past-done .swipe-hint.right,
.stone-outer.past-skip .swipe-hint.left {
  font-weight: 600;
}

.stone-card {
  position: relative;
  z-index: 1;
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 999px / 30px;
  padding: 0.85rem 1.15rem;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  box-shadow:
    0 1px 2px rgba(42, 39, 35, 0.04),
    0 6px 18px -12px rgba(42, 39, 35, 0.14);
  /* Vertical scrolling still belongs to the page; only the horizontal
     axis is ours to capture. */
  touch-action: pan-y;
}

.focus-card {
  position: relative;
  z-index: 1;
  touch-action: pan-y;
  overflow: hidden;
}

/* The prototype marks the priority stone with a clay accent. On a card this
   wide it reads better as a spine than as a dot. */
.focus-card::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--clay);
}

.focus-card > * {
  position: relative;
}

.stone-body {
  flex: 1;
  min-width: 0;
}

.stone-title {
  display: block;
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.35;
}

.stone-sub {
  display: block;
  font-size: 0.75rem;
  color: var(--ink-soft);
  margin-top: 0.1rem;
}

.stone-actions {
  display: flex;
  gap: 0.4rem;
  flex-shrink: 0;
}

.stone-actions form {
  display: flex;
}

/* Always present, on every device. The swipe is the shortcut; these are
   the controls -- and the only thing a keyboard or a screen reader has. */
.stone-btn {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  border: 1px solid var(--hairline);
  background: var(--card);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 0.9rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}

.stone-btn.done {
  background: var(--moss);
  border-color: var(--moss);
  color: var(--on-moss);
}

.stone-btn:focus-visible,
.actions button:focus-visible,
.chat-box button:focus-visible,
.navbtn:focus-visible {
  outline: 2px solid var(--moss);
  outline-offset: 2px;
}

/* The legend is the only place the app claims a gesture exists, so it is
   hidden until the script that provides one has run. */
.stone-legend {
  display: none;
  font-size: 0.7rem;
  color: var(--ink-soft);
  text-align: center;
  margin: 0.6rem 0 0;
}

.stones-live .stone-legend {
  display: block;
}

.stone-legend .for-pointer {
  display: none;
}

.stone-legend kbd {
  font-family: inherit;
  font-size: 0.65rem;
  border: 1px solid var(--hairline);
  border-radius: 5px;
  background: var(--card);
  padding: 0.05rem 0.3rem;
}

/* A mouse gets a drag cursor and the keyboard hint; a touch screen gets
   neither, and is told to swipe instead. A tablet reports a coarse pointer
   and falls to the touch wording, which is right for it. */
@media (hover: hover) and (pointer: fine) {
  .stone-legend .for-touch {
    display: none;
  }

  .stone-legend .for-pointer {
    display: inline;
  }

  .stones-live .stone-card,
  .stones-live .focus-card {
    cursor: grab;
  }

  .stones-live .stone-outer.dragging .stone-card,
  .stones-live .stone-outer.dragging .focus-card {
    cursor: grabbing;
  }

  /* Text inside the focus card is still text, not a drag handle. */
  .stones-live .focus-card input,
  .stones-live .focus-card button {
    cursor: auto;
  }

  .stones-live .focus-card button {
    cursor: pointer;
  }
}

@media (prefers-reduced-motion: reduce) {
  .stone-card,
  .focus-card,
  .swipe-hint {
    transition: none !important;
  }
}

/* ---- Bigger screens ----
   The app was phone-shaped everywhere: a 430px column stranded in the
   middle of a monitor, under a tab bar that is a phone idiom. Two
   breakpoints, and the same markup throughout -- what changes is the
   column width, the type scale, and where the nav lives. */

/* Tablet: still touched, still a bottom tab bar, just more room. */
@media (min-width: 720px) {
  body {
    max-width: 620px;
    padding: 2.25rem 1.5rem 7rem;
  }

  .navbar {
    max-width: 620px;
    border-radius: 20px 20px 0 0;
  }

  header h1 {
    font-size: 2.1rem;
  }



  .stone-title,
  .title {
    font-size: 1rem;
  }
}

/* A finger, not a cursor: the small pills (Remove, Up next) get a target
   big enough to hit without zooming. */
@media (pointer: coarse) {
  .pill {
    min-height: 2rem;
    padding: 0.3rem 0.85rem;
    font-size: 0.72rem;
  }
}

/* Desktop: the tab bar becomes a left rail, and the content is centred in
   what is left rather than in the whole window. body is a single-column
   grid so every page centres without needing a wrapper element. */
@media (min-width: 1040px) {
  /* No tab bar under it here; centred on the column instead. */
  .undo-bar {
    bottom: 1.5rem;
    left: calc(232px + 3rem);
    right: 3rem;
    max-width: 480px;
  }

  body {
    display: grid;
    grid-template-columns: minmax(0, 720px);
    justify-content: center;
    max-width: none;
    padding: 3rem 3rem 3rem calc(232px + 3rem);
  }

  .navbar {
    top: 0;
    bottom: 0;
    right: auto;
    width: 232px;
    max-width: none;
    margin-inline: 0;
    flex-direction: column;
    justify-content: flex-start;
    align-items: stretch;
    gap: 0.2rem;
    padding: 2.5rem 1rem;
    border-top: none;
    border-right: 1px solid var(--hairline);
    border-radius: 0;
    background: transparent;
  }

  /* The rail runs top to bottom, so the capture bar cannot ride inside it:
     flex-basis 100% in a column means full HEIGHT, which stretched it into
     a white gutter down the left of the window. Out of the rail's flow and
     docked across the foot of the reading column instead, lined up with it
     by using the same left and right the body's padding sets. */
  .navbar.with-capture .chat-box {
    position: fixed;
    left: calc(232px + 3rem);
    right: 3rem;
    bottom: 1.75rem;
    flex: none;
    max-width: 720px;
    margin: 0 auto;
  }

  .navbtn {
    flex: none;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 0.7rem;
    padding: 0.6rem 0.8rem;
    border-radius: 12px;
    font-size: 0.85rem;
  }

  .navbtn .icon {
    font-size: 0.95rem;
    width: 1.1rem;
    text-align: center;
  }

  .navbtn:hover {
    background: var(--wash);
    color: var(--ink);
  }

  .navbtn.active {
    background: var(--card);
    box-shadow: 0 1px 2px rgba(42, 39, 35, 0.05);
  }

  header {
    margin-bottom: 1.5rem;
  }

  .account-foot {
    display: none;
  }

  .navbar .sign-out {
    display: block;
  }

  .navbar .sign-up-link {
    display: flex;
  }

  /* History, at the foot of the rail just above sign-out, in its type. */
  .navbar .rail-link {
    display: block;
    margin-top: auto;
    padding: 0.5rem 0.8rem;
    border-radius: 10px;
    font-size: 0.7rem;
    color: var(--ink-soft);
    text-decoration: none;
  }

  .navbar .rail-link:hover {
    background: var(--wash);
  }

  .navbar .rail-link.active {
    color: var(--ink);
    font-weight: 600;
  }

  .navbar .rail-link + .sign-out,
  .navbar .rail-link + .sign-up-link {
    margin-top: 0;
    padding-top: 0;
  }

  header h1 {
    font-size: 2.4rem;
  }
}

/* A mouse can hover, so stones answer to it. Touch screens get nothing
   here, which is right -- a sticky hover state on a phone is a bug. */
@media (hover: hover) and (pointer: fine) {
  .stone-outer:not(.dragging) .stone-card:hover {
    border-color: var(--card-edge-hover);
    box-shadow:
      0 1px 2px rgba(42, 39, 35, 0.05),
      0 10px 26px -12px rgba(42, 39, 35, 0.22);
  }

  .stone-btn:hover {
    border-color: var(--ink-soft);
  }

  .stone-btn.done:hover {
    background: var(--moss-deep);
    border-color: var(--moss-deep);
  }
}

/* The Watch pick. Today's focus card, labelled, so it reads as a
   suggestion for this list rather than a task. */
.pick-card .pick-label {
  margin: 0 0 0.35rem;
  font-size: 0.63rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Every section's pick, stacked at the top of the Queue screen. Tighter
   than Today's single focus card so four fit on a phone without a scroll. */
.picks {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-bottom: 1.6rem;
}

.picks .item-card {
  padding: 0.85rem 1rem;
}

.picks .actions {
  margin-top: 0.6rem;
}

.pick-card .pick-label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.pick-more {
  color: var(--moss);
  letter-spacing: 0.04em;
  text-decoration: none;
  /* A thumb-sized target without making the label row any taller. */
  padding: 0.7rem 0 0.7rem 1rem;
  margin: -0.7rem 0;
}

/* Clear of the top edge when "All n" jumps to it. */
.cat {
  scroll-margin-top: 1rem;
}

/* ---- Layout: Compact ----
   Same screens, tighter: less air between and inside the rows, so a long
   list fits on one screen. Only spacing moves -- the text stays the size
   it was, and every button keeps a thumb-sized target. */
:root[data-layout="compact"] section {
  margin-bottom: 1.1rem;
}
:root[data-layout="compact"] header {
  margin-bottom: 0.6rem;
}
:root[data-layout="compact"] .item-list {
  gap: 0.3rem;
}
:root[data-layout="compact"] .stack {
  gap: 0.3rem;
}
:root[data-layout="compact"] .item-row {
  padding: 0.5rem 1.1rem;
}
:root[data-layout="compact"] .stone-card {
  padding: 0.5rem 0.9rem;
}
:root[data-layout="compact"] .item-card {
  padding: 0.85rem 1rem;
}
:root[data-layout="compact"] h2 {
  margin-bottom: 0.45rem;
}

/* ---- Tips button ----
   Beside the date in every header. A small ringed "?", the one mark
   everybody already reads as "how does this work". */
header {
  gap: 0.75rem;
}
header .date {
  margin-left: auto;
}
.tips-btn {
  flex: none;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  background: var(--card);
  color: var(--ink-soft);
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
}
.tips-btn:hover,
.tips-btn:focus-visible {
  border-color: var(--moss);
  color: var(--moss);
}

/* History and Settings side by side at the foot of a phone's page. */
.foot-links {
  display: flex;
  gap: 1.25rem;
}

/* Two rail links now; only the first is pushed to the foot of the rail. */
.navbar .rail-link + .rail-link {
  margin-top: 0;
}

/* ---- Settings ---- */
.settings-group {
  margin-bottom: 1.75rem;
}

.choices {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* A whole card is the button: the name and what it means, together. */
.choice {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--card);
  border: 1.5px solid var(--card-edge);
  border-radius: 16px;
  padding: 0.8rem 1rem;
  font-family: inherit;
  color: var(--ink);
  cursor: pointer;
}
.choice[aria-pressed="true"] {
  border-color: var(--moss);
  background: var(--moss-light);
}
.choice:disabled {
  cursor: default;
}
.choice:disabled:not([aria-pressed="true"]) {
  opacity: 0.55;
}
.choice-name {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
}
.choice[aria-pressed="true"] .choice-name::after {
  content: " ✓";
  color: var(--moss);
}
.choice-blurb {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

/* Three short words: one pill in thirds, like To do / Done. */
.segmented {
  display: flex;
  padding: 0.2rem;
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 999px;
}
.segmented button {
  flex: 1;
  min-height: 2.5rem;
  border: none;
  border-radius: 999px;
  background: none;
  font-family: inherit;
  font-size: 0.8rem;
  color: var(--ink-soft);
  cursor: pointer;
}
.segmented button[aria-pressed="true"] {
  background: var(--ink);
  color: var(--stone);
  font-weight: 600;
}

.settings-note {
  margin: 0.6rem 0.3rem 0;
  font-size: 0.72rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.settings-note a,
.settings-tips a,
.tip a {
  color: var(--moss);
}
.settings-tips {
  font-size: 0.8rem;
  margin: 0 0.3rem;
}

/* ---- Tips ---- */
.tips-lead {
  font-size: 0.9rem;
  line-height: 1.55;
  margin: 0 0.25rem 1.5rem;
}

.tip {
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 18px;
  padding: 1rem 1.15rem;
  margin-bottom: 0.75rem;
}
.tip h2 {
  font-family: Fraunces, Georgia, serif;
  font-size: 1rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  margin: 0 0 0.4rem;
}
.tip p {
  font-size: 0.8rem;
  line-height: 1.55;
  margin: 0.4rem 0 0;
}

/* Things to type, shown as what they are: little bits of the capture
   bar. */
.tip-says {
  list-style: none;
  margin: 0.6rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}
.tip-says li {
  font-size: 0.75rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  background: var(--moss-light);
  color: var(--moss-ink);
}

.tip-keys {
  margin: 0.5rem 0 0;
  padding-left: 1.1rem;
  font-size: 0.8rem;
  line-height: 1.7;
}
.tip kbd {
  font-family: inherit;
  font-size: 0.7rem;
  padding: 0.05rem 0.35rem;
  border: 1px solid var(--hairline);
  border-radius: 5px;
  background: var(--stone);
}

/* ---- Feedback and Admin ---- */
.feedback-body {
  resize: vertical;
  min-height: 9rem;
  line-height: 1.5;
}
.feedback-text {
  margin: 0.35rem 0 0;
  font-size: 0.85rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.link-box {
  font-size: 0.8rem;
  margin-bottom: 0;
}
.new-link {
  background: var(--moss-light);
  border: 1.5px solid var(--moss);
  border-radius: 18px;
  padding: 1rem;
}
.admin-list {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
}
.admin-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6rem 0.3rem;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.85rem;
  overflow-wrap: anywhere;
}
.admin-meta {
  display: block;
  margin: 0;
  font-size: 0.72rem;
  color: var(--ink-soft);
}
.admin-small {
  flex-shrink: 0;
  background: none;
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  padding: 0.35rem 0.8rem;
  font-family: inherit;
  font-size: 0.75rem;
  color: var(--ink);
  cursor: pointer;
}

/* The private Admin screen: a plain column, no tabs or capture bar. */
.admin-page {
  max-width: 40rem;
  margin: 0 auto;
  padding: 1.5rem 16px 3rem;
}
.admin-head {
  display: block;
  margin-bottom: 1.5rem;
}
.admin-head h1 {
  margin: 0 0 0.2rem;
}
.admin-nav,
.admin-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin-top: 0.75rem;
  font-size: 0.85rem;
}
.admin-nav a,
.admin-filters > a {
  color: var(--ink-soft);
  text-decoration: none;
  padding-bottom: 0.15rem;
  border-bottom: 2px solid transparent;
}
.admin-nav a[aria-current="page"],
.admin-filters > a[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--moss);
}
.admin-filters {
  margin: 0 0 0.75rem;
}
.admin-filters .text-input {
  flex: 1 1 12rem;
  margin: 0;
}
.admin-filters label {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.75rem;
  color: var(--ink-soft);
}
.admin-filters select {
  font: inherit;
  font-size: 0.8rem;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 6px;
  padding: 0.3rem 0.4rem;
}
.admin-badge {
  font-size: 0.7rem;
  color: var(--on-moss);
  background: var(--moss);
  border-radius: 999px;
  padding: 0.05rem 0.45rem;
}
.admin-sub {
  margin: 1.1rem 0 0.2rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink-soft);
}
.admin-pager {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 0.75rem;
  font-size: 0.85rem;
}
.admin-unread {
  border-left: 3px solid var(--moss);
}
.admin-list a {
  color: var(--ink);
}

/* ---- Weather ----
   A few quiet characters after the date: "68° ☀". Links to where the
   place is set. */
.weather-chip {
  margin-left: 0.5rem;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}
.weather-chip:hover {
  color: var(--ink);
}

/* ---- Location and two-step, in Settings ---- */
.inline-form {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}
.inline-form .text-input {
  flex: 1;
  min-width: 0;
}
.inline-form .create-list {
  flex: none;
  width: auto;
  margin: 0;
}
.code-input {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.15em;
}
.link-button {
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  color: var(--moss);
  text-decoration: underline;
  cursor: pointer;
}
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
/* Always black on white, whatever the theme: phone cameras read that best. */
.qr-box {
  width: 12rem;
  margin: 0.75rem 0;
  padding: 0.5rem;
  background: #fff;
  border-radius: 12px;
}
.qr-box svg {
  display: block;
  width: 100%;
  height: auto;
}
.totp-secret,
.recovery-codes {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.9rem;
  color: var(--ink);
}
.totp-secret {
  margin: 0.4rem 0.3rem 0;
  word-break: break-all;
}
.recovery-codes {
  display: grid;
  grid-template-columns: repeat(2, max-content);
  gap: 0.4rem 1.5rem;
  margin: 0.75rem 0.3rem;
  padding: 0;
  list-style: none;
}

/* Online admin: a code box beside the buttons that hand over an account. */
.admin-list li {
  flex-wrap: wrap;
}
.admin-list form {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}
.admin-code {
  width: 5.5rem;
  padding: 0.35rem 0.6rem;
  font-size: 0.8rem;
}

/* ---- Admin numbers ----
   Tiles, bar charts and cap meters. The charts are SVG drawn on the
   server (src/stats.js); colours come from here so themes carry over. */
.stat-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
}
.stat-tile {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.7rem 0.8rem;
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 14px;
}
.stat-num {
  font-family: 'Fraunces', serif;
  font-size: 1.4rem;
  font-weight: 500;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.stat-label {
  font-size: 0.7rem;
  color: var(--ink-soft);
}
@media (max-width: 22rem) {
  .stat-tiles {
    grid-template-columns: repeat(2, 1fr);
  }
}
.chart-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.75rem;
}
.chart {
  margin: 0;
  padding: 0.75rem 0.85rem 0.6rem;
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 14px;
}
.chart figcaption {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 0.5rem;
}
.chart-title {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink);
}
.chart-total {
  font-size: 0.8rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.bar-chart {
  display: block;
  width: 100%;
  height: 4.5rem;
}
.bar-chart rect {
  fill: var(--moss);
}
.bar-chart rect:hover {
  fill: var(--ink);
}
.bar-chart .axis {
  stroke: var(--hairline);
  stroke-width: 1;
}
.chart .admin-meta {
  margin-top: 0.35rem;
}
.cap-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.25rem 0.75rem;
  padding: 0.5rem 0.3rem;
  font-size: 0.85rem;
}
.cap-row meter {
  grid-column: 1 / -1;
  width: 100%;
  height: 0.5rem;
}
.admin-list li > span:first-child {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.admin-page .admin-meta a,
.admin-page .settings-note a {
  color: var(--ink);
}
.admin-back {
  margin: 0 0 1rem;
}
