/* ========================================
   BASE STYLES
   ======================================== */
/* THEME: Minimalist Black & White
   - Clean black/white color scheme
   - Subtle grey borders (#e0e0e0) on cards
   - Cards for content grouping with consistent padding
   - Links for navigation (underline on hover)
   - Buttons only for form submissions
   - No heavy buttons or CTAs
   - Consistent spacing using design tokens
   ======================================== */
:root {
  --topic-gap: 15px;
  
  /* Design System Tokens */
  /* Colors - slightly warmed up grays */
  --card-border: #e8e8e8;
  --card-background: #ffffff;
  --hover-background: #fafafa;
  --divider: #f0f0f0;
  --border-color: #f0f0f0;
  --text-primary: #1a1a1a;
  --text-secondary: #555;
  --text-muted: #888;
  --text-faint: #bbb;
  --accent-color: #000;
  --accent-blue: #007bff;
  --accent-blue-hover: #0056b3;
  
  /* Button colors */
  --btn-primary: #000;
  --btn-primary-hover: #333;
  --btn-danger: #c00;
  --btn-danger-hover: #a00;
  --btn-success: #1a7f37;
  /* The third state. Danger and success were tokens; amber was written as
     #c60 wherever a page needed "not fine, not broken". */
  --btn-warning: #c60;
  /* The wash behind a cell that passed or failed a check — a DMARC row, a
     diagnostics line. Written as literal greens and reds in the one page that
     had them, which made a report the only page whose colours did not move
     with the palette. */
  --pass-background: #d4edda;
  --fail-background: #f8d7da;
  --warn-background: #fff7ed;
  --warn-text: #7c2d12;
  --console-background: #1a1a1a;
  --console-text: #e0e0e0;
  --pass-border: #c3e6cb;
  --warn-wash: #fff3cd;
  --warn-border: #ffc107;
  --warn-ink: #856404;
  --ok-wash: #f0fff0;
  --ok-border: #a3d9a5;
  --banner-wash: #fff8e1;
  --banner-border: #f1d68c;
  --banner-ink: #5b4a00;
  --btn-success-hover: #156b2d;
  
  /* Spacing - consistent scale */
  --spacing-xs: 4px;
  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  --spacing-xl: 32px;
  --item-padding: 16px;
  
  /* Borders */
  --border-radius: 6px;
  --border-width: 1px;
  
  /* Shadows */
  --shadow-sm: none;
  --shadow-md: 0 4px 6px rgba(0,0,0,0.04), 0 2px 4px rgba(0,0,0,0.06);
  
  /* Typography */
  --line-height: 1.6;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  
  /* Transitions */
  --transition-fast: 0.15s ease;
}

html, body {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
  font-family: "Nunito Sans", serif;
  font-size: 14px;
  box-sizing: border-box;
  overflow-x: hidden;
}

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

/* Links - minimalist style with hover underline */
a {
  color: #000;
  text-decoration: none;
  font-size: 0.9em;
  font-weight: bold;
  transition: opacity var(--transition-fast);
}

a:hover {
  text-decoration: underline;
}

/* A visited link is the same colour as an unvisited one — but this rule must
   not outrank the components.
 
   It used to read `a:visited:not(.btn)`. That is one element, one pseudo-class
   and one class: 0-2-1, which beats any two-class selector — so .pill.on,
   .mail-tag.on, .ar-chip.on and every other "selected filter" drawn as white
   text on a dark fill turned black-on-black the moment it had been clicked,
   which for the selected one is always. It was found and patched five separate
   times, on five different classes, because each fix was to the class rather
   than to this.
 
   Without the :not() it is 0-1-1, which loses to any two-class selector and
   still wins over a bare one. a.btn does not need the exclusion: it carries
   `color: #fff !important` and has since before this rule existed. The
   exclusion was belt over braces, and the belt was the thing catching. */
a:visited {
  color: #000;
}

/* External links - same color as other links for consistency */
a[target="_blank"],
a[rel*="noopener"] {
  color: var(--text-primary);
}

a[target="_blank"]:visited,
a[rel*="noopener"]:visited {
  color: var(--text-primary);
}

/* Buttons - slim, consistent padding */
button {
  display: inline-block;
  background: var(--btn-primary);
  color: #fff;
  border: 1px solid var(--btn-primary);
  border-radius: var(--border-radius);
  padding: 6px 12px;
  cursor: pointer;
  font-size: 14px;
  line-height: 1.4;
  text-decoration: none;
  transition: all var(--transition-fast);
}

button:hover {
  background: var(--btn-primary-hover);
  border-color: var(--btn-primary-hover);
}

/* Buttons that are controls rather than buttons: a word you click, no fill.
   These exist because a destructive or secondary action in a list row should
   not look like a call to action.

   They have to neutralise the background here and not only the colour. The rule
   above sets a dark fill on every button:hover, and a class that declares only
   `color` inherits it — so "Issue token" and "Remove" went dark text on a dark
   background the moment you pointed at them. Every one of these got it wrong
   separately, so it is fixed once, in one place. */
.agent-act,
.agent-remove,
.run-del,
.db-act,
.db-remove {
  background: none;
  border: 0;
  padding: 0;
  font-size: 13px;
  line-height: inherit;
}

.agent-act:hover,
.agent-remove:hover,
.run-del:hover,
.db-act:hover,
.db-remove:hover {
  background: none;
  border-color: transparent;
  text-decoration: underline;
}

/* .btn class for links styled as buttons */
a.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--btn-primary);
  color: #fff !important;
  border: 1px solid var(--btn-primary);
  border-radius: var(--border-radius);
  padding: 6px 12px;
  cursor: pointer;
  font-size: 14px;
  font-weight: normal;
  line-height: 1.4;
  text-decoration: none;
  transition: all var(--transition-fast);
  height: 36px;
  box-sizing: border-box;
}

a.btn:hover {
  background: var(--btn-primary-hover);
  border-color: var(--btn-primary-hover);
  color: #fff !important;
  text-decoration: none;
}

/* Button variants */
.btn-link {
  background: transparent;
  color: var(--text-primary);
  border: none;
  padding: 8px 12px;
  text-decoration: none;
  display: inline-block;
}
.btn-link:hover {
  background: var(--hover-background);
}
.btn-success:hover {
  background: var(--btn-success-hover);
  border-color: var(--btn-success-hover);
}

/* Search bar - unified across all pages */
.search-bar {
  display: flex;
  gap: 8px;
  margin-bottom: 20px;
}
.search-bar input {
  flex: 1;
  padding: 8px 12px;
  font-size: 14px;
  border: 1px solid var(--card-border, #e0e0e0);
  border-radius: var(--border-radius, 6px);
  min-width: 0;
}
.search-bar input:focus {
  outline: none;
  border-color: var(--text-muted, #999);
}
.search-bar button {
  flex-shrink: 0;
}

input, textarea, select, button {
  font-family: inherit;
  font-size: inherit;
}

input {
  width: 100%;
  padding: 10px;
  border-radius: 5px;
  border: 1px solid #e0e0e0;
  box-sizing: border-box;
}

/* A checkbox is not a text field. The rule above is written for one — full
   width, 10px of padding, a border — and a checkbox inherited all three, so it
   rendered as a box tens of pixels wide with its tick floating somewhere in the
   middle and its label stranded far to the right. Every page that wanted one
   worked around it instead of fixing it: the agents page replaced its
   checkboxes with styled chips, and the tasks form still shows a gap wide
   enough to read as a layout bug.

   Sizing them here fixes it everywhere at once, and lets a plain
   <label><input type=checkbox> text</label> line up the way it should. */
input[type="checkbox"],
input[type="radio"] {
  width: auto;
  flex: none;
  padding: 0;
  margin: 0;
  border: 0;
  vertical-align: middle;
}

select {
  padding: 5px;
  border-radius: 5px;
  background: white;
}

textarea:focus, input:focus {
  outline: none;
}

code {
  background: #f9f9f9;
  padding: 2px 5px;
  border-radius: 3px;
  font-size: 0.9em;
}

pre {
  background: #f9f9f9;
  padding: 15px;
  border-radius: 5px;
  overflow-x: auto;
}

pre code {
  padding: 0;
  background: none;
  border-radius: 0;
  font-size: inherit;
  white-space: pre-wrap;
}

table {
  width: 100%;
}

table, td, th {
  text-align: left;
}

th {
  border-bottom: 1px solid darkgrey;
}

td {
  border-bottom: 1px solid darkgrey;
  padding: 5px 25px 5px 0;
}

/* ========================================
   MICRO DIALOG
   ======================================== */
/* ========================================
   HEADER & NAVIGATION
   ======================================== */
/* ========================================
   HEADER & NAVIGATION
   ======================================== */
#head {
  background: white;
  width: 100%;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 40px;
  border-bottom: 1px solid #e0e0e0;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  box-sizing: border-box;
}

#menu-toggle {
  display: none;
  position: absolute;
  left: 15px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px;
  width: 36px;
  height: 34px;
  flex-direction: column;
  justify-content: space-between;
  align-items: stretch;
  box-sizing: border-box;
}

#menu-toggle span {
  display: block;
  height: 2px;
  width: 20px;
  background: var(--text-primary);
  border-radius: 1px;
}

#menu-toggle:hover {
  background: var(--hover-background);
  border-radius: var(--border-radius);
}

#brand {
  flex: 0 0 auto;
}

#brand a {
  color: black;
  font-weight: bold;
  text-decoration: none;
  font-size: 1.2em;
}

#nav-overlay {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 150;
}

#nav-container {
  position: fixed;
  left: 0;
  top: 50px;
  width: 220px;
  height: calc(100vh - 50px);
  padding: 12px 25px 25px;
  background: white;
  border-right: 1px solid #e0e0e0;
  z-index: 200;
  display: flex;
  flex-direction: column;
}

#nav {
  display: flex;
  flex-direction: column;
  gap: 5px;
  flex: 1;
  min-height: 0; /* let overflow-y:auto scroll instead of pushing .nav-bottom off-screen */
  overflow-y: auto;
  position: relative;
}

#nav a {
  color: var(--text-primary);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
  padding: 10px 14px;
  border-radius: var(--border-radius);
  display: flex;
  align-items: center;
  transition: all var(--transition-fast);
}

/* Hover only where there is a pointer that can hover. A touch device keeps
   :hover on whatever was tapped last, so on a phone the item you came from
   stayed lit as though it were still selected — and since nothing set .active,
   that stale hover was the only highlight the sidebar had. */
@media (hover: hover) and (pointer: fine) {
  #nav a:hover {
    background: var(--hover-background);
    color: var(--text-primary);
  }
}

/* Where you actually are. Distinct from hover on purpose: hover is the
   pointer's opinion and this is the page's fact, so they must not look
   identical or "selected" and "under the cursor" become the same signal. */
#nav a.active {
  background: var(--active-background, var(--hover-background));
  font-weight: var(--font-weight-semibold);
  box-shadow: inset 3px 0 0 var(--accent-color, currentColor);
}

#nav img {
  height: 24px;
  width: 24px;
  margin-right: 16px;
  filter: brightness(0);
}

#nav .label {
  font-size: 1.1em;
}
/* A pinned group inside the scrolling part of the nav. The divider above it
   separates what the product is (agents, tools, services) from what this
   reader uses, which are different kinds of thing and were previously the same
   undifferentiated list. */
.nav-group {
  display: flex;
  flex-direction: column;
  gap: 5px;
  border-top: 1px solid var(--divider, #f0f0f0);
  margin-top: 10px;
  padding-top: 10px;
}

.nav-heading {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-muted, #999);
  padding: 0 14px 2px;
}

.nav-bottom {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-top: 1px solid var(--divider, #f0f0f0);
  padding-top: 10px;
  margin-top: auto;
  flex-shrink: 0;
}

.nav-bottom a {
  color: var(--text-primary);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
  padding: 6px 14px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 12px;
  transition: background-color 0.15s ease;
  font-size: 0.95em;
}

.nav-bottom a:hover {
  background-color: #f5f5f5;
}

.nav-bottom img {
  height: 20px;
  width: 20px;
}
/* The account, as one control. See navBottom.

   It was a caption plus four destinations, which put Log out on the same
   footing as Inbox and made a five-item product look like a ten-item
   dashboard. */
.nav-me { position: relative }

.nav-me-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px;
  border-radius: 8px;
  cursor: pointer;
  list-style: none; /* the default disclosure triangle, which we draw ourselves */
  font-size: 0.95em;
  font-weight: var(--font-weight-medium);
  color: var(--text-primary);
}

.nav-me-btn::-webkit-details-marker { display: none }
.nav-me-btn:hover,
.nav-me[open] .nav-me-btn { background-color: #f5f5f5 }

.nav-me-av {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--btn-primary, #111);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

#nav-username {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Points up, because the menu opens upward. Turns over when it is open. */
.nav-me-chev {
  flex: 0 0 auto;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 5px solid var(--text-muted, #999);
}

.nav-me[open] .nav-me-chev {
  border-bottom: 0;
  border-top: 5px solid var(--text-muted, #999);
}

.nav-me-menu {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 6px;
  right: 6px;
  background: var(--card-background, #fff);
  border: 1px solid var(--card-border, #e8e8e8);
  border-radius: 10px;
  padding: 5px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .1);
  z-index: 20;
}

.nav-me-menu a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: 6px;
  text-decoration: none;
  color: var(--text-primary);
  font-size: 0.92em;
}

.nav-me-menu a:hover { background-color: #f5f5f5 }
.nav-me-menu img { height: 17px; width: 17px }

/* Credit balance, pinned above the account links so the number is in view on
   every page. Empty and low are coloured because "0 credits" in the same grey
   as everything else is a number nobody reads. */
/* Top-up prompt. Same shape as .verify-banner — one row on a desktop, wrapping
   to stacked lines on a phone, with the action last. */
.credits-banner {
  background: #fff8e1;
  border: 1px solid #f1d68c;
  border-radius: 6px;
  padding: 10px 14px;
  margin: 0 0 14px;
  font-size: 14px;
  color: #5b4a00;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.connect-banner {
  background: #f4f8ff;
  border-color: #c9dcf5;
  color: #1c3d63;
}

.credits-banner a {
  margin-left: auto;
  background: #000;
  color: #fff;
  text-decoration: none;
  padding: 6px 14px;
  border-radius: 6px;
  white-space: nowrap;
}
@media only screen and (max-width: 600px) {
  .connect-banner {
  background: #f4f8ff;
  border-color: #c9dcf5;
  color: #1c3d63;
}

.credits-banner a { margin-left: 0; }
}

/* The right-hand cluster: mail, credit balance, Tools. One flex row so the
   items measure themselves instead of being nudged apart by hand — the old
   absolute offsets needed a new magic number per item and could not look
   backwards to know what was showing. */
#head-right {
  position: absolute;
  right: 15px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 14px;
}

/* The header's inbox link. Hidden on desktop, where the sidebar carries Inbox;
   on a phone the sidebar is behind a hamburger, so this is the way to reach it.
   It carried a count once, from a different source than the one on Home, and
   the two disagreed with each other and with the list. */
#head-inbox {
  display: none;
  position: relative;
  text-decoration: none;
  color: #555;
  line-height: 0;
}
#head-inbox svg {
  vertical-align: middle;
}

/* Credit balance in the top bar, beside Tools. The only place it appears: it
   was in the sidebar too for a moment, and the same number twice on one screen
   reads as a mistake. The top bar is fixed, always visible, and the same on
   every viewport. */
#head-wallet {
  display: flex;
  align-items: center;
  text-decoration: none;
  color: #555;
  line-height: 1;
  white-space: nowrap;
}
#head-wallet svg { vertical-align: middle; }
#head-wallet-badge {
  margin-left: 5px;
  font-size: 13px;
  font-weight: 600;
  color: #555;
  vertical-align: middle;
  font-variant-numeric: tabular-nums;
}
#head-wallet.low, #head-wallet.low #head-wallet-badge { color: #a86400; }
#head-wallet.empty, #head-wallet.empty #head-wallet-badge { color: #b3261e; }

#nav-logged-out {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

#nav-logged-out button {
  width: 100%;
  padding: 12px;
  font-size: 1em;
}

/* ========================================
   LAYOUT
   ======================================== */
/* ========================================
   LAYOUT
   ======================================== */
#container {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - 50px);
  margin-top: 50px;
}

#content {
  flex: 1;
  max-width: 1400px;
  margin: 0 auto;
  padding: 20px 40px;
  text-align: left;
  width: 100%;
  box-sizing: border-box;
}

#page-title {
  margin-top: 0;
  margin-bottom: 15px;
  font-size: 1.5em;
}

#footer {
  text-align: center;
  padding: 30px 20px;
  color: var(--text-muted);
  font-size: 14px;
  border-top: 1px solid var(--divider);
  margin-top: 20px;
}

#footer a {
  color: var(--text-secondary);
  text-decoration: none;
}

#footer a:hover {
  text-decoration: underline;
}

/* Scroll offset for anchor links to account for fixed header */
.anchor {
  scroll-margin-top: 60px;
  margin: 50px 0;
}

#main {
  max-width: 900px;
  justify-items: center;
  text-align: center;
  padding: 25px;
  margin: 0 auto;
  margin-top: 75px;
}

/* ========================================
   HOME PAGE
   ======================================== */

/* Hide the customize-link on the home page but keep the title */
body.page-home #page-title ~ #customize-link {
  display: none;
}

#home-date {
  color: #888;
  margin: 0 0 16px;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* Says what the block underneath is. The cards read as a dashboard somebody
   arranged; they are the tools answering live, and two words are the whole
   difference between those two readings. Quiet, because a label that competes
   with what it labels is worse than none. */
.home-section {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 30px 0 12px;
  color: var(--text-muted, #888);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: var(--font-weight-semibold, 600);
}

/* The rule is what makes it a section rather than a caption. Two words in
   small caps sitting over a list read as a label on the thing below; a line
   across the rest of the width reads as a break between two things, which is
   what Home needed — it is a stack of unrelated blocks and nothing separated
   them. */
.home-section::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--divider, #f0f0f0);
}

.home-section small { font-size: 11px; white-space: nowrap }

/* What is waiting, said once, in the section it is about. It was a suggestion
   chip under the chat box that spent a model call to read your own mail. */
#home-date-text {
  white-space: nowrap;
}
#home-date-weather {
  font-size: 13px;
  color: #999;
}
#home-date-actions {
  margin-left: auto;
  font-size: 13px;
}
/* Two columns on desktop; the media queries below flip it to one.
   
   display:flex was missing here and only here. .home-left carries flex:1 and
   .home-right a fixed 370px with flex-shrink:0, which need a flex parent to
   mean anything — without one they are two blocks, so the right column dropped
   under the left and home became a single stack at every width. Both media
   queries set flex-direction:column on this element, which is what gave it
   away: nothing sets a direction on something that was never a flex container. */
#home {
  display: flex;
  gap: 20px;
  height: 100%;
}

/* Pinned apps: a quick-launch strip at the top of home, below the chips. */
#home-apps {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 16px;
}
.home-app {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  background: #fff;
  font-size: 13px;
  color: #333;
  text-decoration: none;
}
.home-app:hover {
  border-color: #bbb;
}

.card-tooltip {
  display: inline-block;
  position: relative;
  width: 16px;
  height: 16px;
  line-height: 16px;
  text-align: center;
  font-size: 11px;
  font-weight: 600;
  font-style: normal;
  color: #bbb;
  border: 1px solid #ddd;
  border-radius: 50%;
  cursor: pointer;
  vertical-align: middle;
  margin-left: 4px;
  float: right;
}
.card-tooltip:hover {
  color: #666;
  border-color: #aaa;
}
.card-tooltip::after {
  content: attr(data-tip);
  position: absolute;
  right: 0;
  top: 100%;
  margin-top: 6px;
  background: #333;
  color: #fff;
  font-size: 12px;
  font-weight: 400;
  padding: 6px 10px;
  border-radius: 4px;
  white-space: nowrap;
  z-index: 10;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
}
.card-tooltip:hover::after,
.card-tooltip.show::after {
  opacity: 1;
}

#home-chat-form {
  display: flex;
  gap: 10px;
  width: 100%;
}

#home-chat-form input {
  flex: 1;
  min-width: 0;
}

#home-chat-form button {
  white-space: nowrap;
  flex-shrink: 0;
}

#home:after {
  content: ".";
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}

#home h1 {
  margin-top: 0;
}

.home-left, .home-right {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* How old the thing on a card is. Only the stream carries it — the forecast and
   the prices are how things are now, and a time against them would be the time
   we asked rather than the time anything happened. */
.card-when {
  font-size: 0.75em;
  font-weight: var(--font-weight-normal, 400);
  color: var(--text-muted, #999);
  margin-left: 8px;
  white-space: nowrap;
}

.home-left {
  flex: 1;
  min-width: 0;
}

.home-right {
  width: 370px;
  flex-shrink: 0;
}

.home-left .card, .home-right .card {
  margin: 0;
  float: none;
  min-width: 350px;
  max-width: none;  /* Allow cards to expand in home columns */
}

/* Home page: cards have borders, but content inside does not */
#home .card .headline,
#mu-chat .card .headline,
#mu-overview .card .headline {
  border: none;
  border-bottom: 1px solid var(--border-color, #f0f0f0);
  border-radius: 0;
  padding: 12px 0;
  margin-bottom: 0;
  background: transparent;
}

#home .card .headline:last-of-type,
#mu-chat .card .headline:last-of-type,
#mu-overview .card .headline:last-of-type {
  border-bottom: none;
  padding-bottom: 0;
}

#home .card .headline:first-of-type,
#mu-chat .card .headline:first-of-type,
#mu-overview .card .headline:first-of-type {
  padding-top: 0;
}

#home .card .item,
#home .card .post-item,
#home .card .thumbnail,
#mu-chat .card .item,
#mu-chat .card .post-item,
#mu-chat .card .thumbnail,
#mu-overview .card .item,
#mu-overview .card .post-item,
#mu-overview .card .thumbnail {
  border: none;
  padding: 0;
  background: transparent;
}

/* Switch to a single column when there's not enough room for two + sidebar */
@media only screen and (max-width: 1100px) {
  #home, .home-row {
    flex-direction: column;
  }

  .home-right {
    width: 100%;
  }
}

/* Home: the inline agent spans the full column (not the 760px reading cap it
   uses on the landing page), and when its input pins on scroll it clears the
   fixed 50px header instead of hiding behind it. */
#home-agent #mu-chat { max-width: none; }
#home-agent #mu-chat-form { top: 58px; }
/* ========================================
   CARDS & BLOCKS
   ======================================== */
/* Reduce card min-width on smaller screens */
@media only screen and (max-width: 900px) {
  .card {
    max-width: 100%;
  }
}

.card h4 {
  margin-top: 0;
  margin-bottom: var(--spacing-sm);
  font-size: 1em;
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
}

.card form {
  margin-bottom: 0;
}

.block {
  width: 220px;
  height: auto;
  display: block;
  text-align: center;
  text-decoration: none;
  border: var(--border-width) solid var(--card-border);
  border-radius: var(--border-radius);
  padding: 10px;
  background: var(--card-background);
  transition: background var(--transition-fast);
}

.block:hover {
  background: var(--hover-background);
}

/* ========================================
   CHAT PAGE
   ======================================== */
body:has(#messages) #content {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 70px);
  padding-bottom: 20px;
  overflow: hidden;
}

body:has(#messages) #footer,
body:has(#messages) #chat-back-link {
  display: none;
}

#topic-selector {
  flex-shrink: 0;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid #e0e0e0;
  position: relative;
}

#chat-clear {
  position: absolute;
  top: 5px;
  right: 0;
  color: #999;
  text-decoration: none;
  font-size: 13px;
}

#chat-clear:hover {
  color: #555;
}
#topic-selector .head {
  padding: 5px 0;
  font-size: 14px;
  text-decoration: none;
  color: #333;
  transition: color 0.2s;
  cursor: pointer;
}

#topic-selector .head.home-link {
  font-size: 16px;
  padding: 4px 12px 4px 0;
  text-decoration: none !important;
}

#topic-selector .head:hover {
  color: #000;
  text-decoration: underline;
}

#topic-selector .head.active {
  color: #000;
  text-decoration: underline;
  font-weight: bold;
}

#topic-summary {
  flex-shrink: 0;
  margin-bottom: 10px;
}
/* The conversation fills whatever the room page has left after the sign-in
   notice and the message box. It used to be a fixed calc() that budgeted for a
   topic bar above it; that bar is gone, so growing into the flex column is
   both simpler and correct whatever else is on the page. */
#messages {
  flex: 1 1 0;
  min-height: 200px;
  border: 1px solid #ddd;
  border-radius: 5px;
  padding: 15px;
  text-align: left;
  overflow-y: auto;
}

/* A notice sits in the same flex column as the conversation, so it has to be
   told not to stretch or shrink — otherwise it is sized by the flex algorithm
   and spills out of the content area. */
.notice {
  flex: 0 0 auto;
  border: 1px solid #e0e0e0;
  border-radius: 5px;
  padding: 12px 15px;
  margin-bottom: 12px;
  background: #fafafa;
}

.notice p {
  margin: 6px 0 0 0;
  font-size: 14px;
  color: #555;
}

/* .link is display:block globally, which is right for a card's one call to
   action but wrong for a sentence of them separated by middots. */
.notice .link,
.rooms .row .link {
  display: inline;
  margin-top: 0;
}

.rooms h3 {
  margin: 24px 0 8px;
}

.rooms .row {
  padding: 8px 0;
  border-bottom: 1px solid #eee;
}

.rooms .row .muted {
  color: #888;
  font-size: 13px;
}
#messages p {
  margin-top: 8px;
  margin-bottom: 12px;
  line-height: 1.5;
}

#messages ul, #messages ol {
  margin: 10px 0;
  padding-left: 25px;
}

#messages li {
  margin-bottom: 8px;
  line-height: 1.5;
}

/* A heading inside a message is a heading inside a paragraph of speech, not
   the top of a page: it marks a section of an answer and should not be bigger
   than the room's own furniture. h4 is here because the renderer caps at it —
   see renderMarkdown in mu.js. */
#messages h1, #messages h2, #messages h3, #messages h4 {
  margin-top: 20px;
  margin-bottom: 12px;
  font-size: 15px;
}

#messages code {
  margin: 10px 0;
}

/* The rest of what an answer is written in. A model writes fenced code, quotes
   what it was asked about and rules off between sections, and none of the three
   had a rule — so they arrived as unstyled browser defaults in the middle of a
   conversation. */
#messages pre {
  margin: 10px 0;
  padding: 10px 12px;
  background: var(--hover-background, #f5f5f5);
  border-radius: var(--border-radius, 6px);
  overflow-x: auto;
}

#messages pre code { margin: 0; background: none; padding: 0 }

#messages blockquote {
  margin: 10px 0;
  padding-left: 12px;
  border-left: 2px solid var(--border-color, #f0f0f0);
  color: var(--text-secondary, #555);
}

#messages hr {
  border: 0;
  border-top: 1px solid var(--border-color, #f0f0f0);
  margin: 14px 0;
}

.message {
  margin-bottom: var(--spacing-lg);
  width: 100%;
  display: block;
}

.you {
  font-size: 0.85em;
  font-weight: bold;
  color: var(--text-primary);
  display: block;
  margin-bottom: var(--spacing-xs);
}

.llm, .ai, .micro, .system {
  font-size: 0.85em;
  font-weight: bold;
  color: var(--text-primary);
  display: block;
  margin-bottom: var(--spacing-xs);
}
@keyframes loading-dots {
  0%, 20% { content: '.'; }
  40% { content: '..'; }
  60%, 100% { content: '...'; }
}

.context-message {
  font-size: small;
  color: #999;
  font-style: italic;
  text-align: center;
  padding: 8px 0;
  margin: 10px 0;
  border-top: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
}

.summary-toggle {
  color: var(--text-secondary);
  font-size: 12px;
  text-decoration: none;
  cursor: pointer;
}

.summary-toggle:hover {
  text-decoration: underline;
}

.summary-content {
  margin-top: 8px;
  font-style: normal;
  line-height: 1.4;
}
.summary-meta {
  display: block;
  margin-top: 4px;
  color: #777;
  font-size: 12px;
  font-weight: 400;
}
#summary-toggle-icon {
  color: #666;
  font-size: 12px;
}
.summary-item {
  padding: 12px 0;
  border-bottom: 1px solid #eee;
}

.summary-item:last-child {
  border-bottom: none;
}

.summary-item .category {
  display: inline-block;
  margin-bottom: 8px;
}

.summary-item p {
  margin: 0;
  color: #555;
  font-size: 14px;
  line-height: 1.5;
}

.summary-item .link {
  display: block;
  margin-top: 8px;
}

.topic-summary {
  margin: 8px 0 0;
  color: #555;
  font-size: 14px;
  line-height: 1.5;
}

#topics {
  margin-bottom: 10px;
  padding-bottom: 5px;
  border-bottom: 1px solid #e0e0e0;
  display: flex;
  gap: var(--topic-gap);
  flex-wrap: wrap;
}

#prompt {
  flex: 1;
  padding: 10px;
  margin: 0;
  box-sizing: border-box;
}

#chat-users {
  font-size: 13px;
  color: #666;
  padding: 0 0 8px;
  border-bottom: 1px solid #eee;
  margin-bottom: 8px;
}

#chat-form {
  width: 100%;
  margin: 15px 0 0 0;
  display: flex;
  gap: 10px;
  align-items: center;
}

#chat-form button {
  padding: 10px 20px;
  margin: 0;
  width: auto;
  flex-shrink: 0;
}

.modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-content {
  background: white;
  padding: 30px;
  border-radius: 10px;
  max-width: 800px;
  max-height: 80vh;
  overflow-y: auto;
  position: relative;
  margin: 20px;
}
#summaries-content .message {
  margin-bottom: 20px;
}

#summary {
  border-bottom: 1px solid darkgrey;
  margin-bottom: 20px;
}

#summary p {
  margin-bottom: 20px;
}

.head {
  display: inline-block;
  color: var(--accent-color) !important;
  font-size: 10px !important;
  font-weight: bold !important;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: transparent;
  padding: 0;
  border: none;
  text-decoration: none;
  margin-right: 8px;
  transition: color var(--transition-fast);
}

.head:hover {
  text-decoration: underline;
}

.head.active {
  text-decoration: underline;
}

/* ========================================
   BLOG PAGE
   ======================================== */
/* Reading width for the /blog page. Scoped away from .card because the home
   card reuses this id — an id beats .home-left .card on specificity, so
   without :not(.card) the card sits narrower than its neighbours. The
   equivalent #news and #video caps were deleted outright: those pages have no
   element with that id, so the rules only ever hit the home cards. */
#blog:not(.card) {
  max-width: 900px;
}

#blog {
  position: relative;
}

#blog h2 {
  margin-top: 15px;
}

#blog-form {
  max-width: 100%;
}

#blog-form input, #blog-form textarea {
  width: 100%;
  box-sizing: border-box;
}

#post-form-container {
  margin-bottom: 30px;
  padding: 20px;
  border: 1px solid #e0e0e0;
  border-radius: 10px;
  background: #fafafa;
  max-width: 100%;
}

#post-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

#post-form input,
#post-form textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 10px;
  font-size: 14px;
  border: 1px solid #e0e0e0;
  border-radius: 5px;
}

#post-form textarea {
  resize: vertical;
}

#post-form button {
  padding: 10px 20px;
  font-size: 14px;
  background-color: #333;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  align-self: flex-start;
}

.profile-app-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}
.profile-app-icon svg {
  width: 20px;
  height: 20px;
  max-width: 20px;
  max-height: 20px;
}
.post-item {
  position: relative;
  border: var(--border-width) solid var(--card-border);
  border-radius: var(--border-radius);
  padding: var(--item-padding);
  background: var(--card-background);
  margin-bottom: var(--spacing-md);
}
.post-item h3 {
  margin-top: 0;
  margin-bottom: 8px;
}

.post-item h3 a {
  text-decoration: none;
  color: inherit;
}

.post-item > div {
  margin-bottom: 10px;
  font-size: 0.9em;
}

.post-item .info {
  color: var(--text-secondary);
  font-size: 0.8em;
  margin-top: var(--spacing-sm);
  margin-bottom: 0;
}

.post-item .info a {
  color: var(--text-secondary);
  text-decoration: none;
}

.post-item .info a:hover {
  text-decoration: underline;
}

.keep-reading {
  display: inline-block;
  font-size: 0.85em;
  font-weight: 500;
  color: var(--accent-color);
  text-decoration: none;
  margin-top: 4px;
}

.keep-reading:hover {
  text-decoration: underline;
}

.post-tags {
  margin-top: 8px;
  font-size: small;
}

.post-content {
  display: none !important;
  border: 1px solid darkgrey;
  border-radius: 5px;
  padding: 15px;
  max-width: 800px;
  overflow: auto;
  margin-bottom: 20px;
  margin-top: 20px;
}

.post-content img {
  max-width: inherit;
}
.post-show:focus + .post-content {
  display: block !important;
}

/* ========================================
   MODERATION PAGE
   ======================================== */
#moderation .info-banner {
  font-size: small;
  color: #999;
  font-style: italic;
  padding: 8px 0;
  margin: 10px 0;
  border-top: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
}

.flagged-item {
  background: #fff3cd;
  padding: 15px;
  border-radius: 5px;
  margin-bottom: 20px;
}

.flagged-item h3 {
  margin: 10px 0;
}

.flagged-item .info {
  color: #666;
  font-size: small;
  margin-top: 10px;
}

.flagged-item .content-type-badge {
  background: #666;
  color: white;
  padding: 2px 8px;
  border-radius: 3px;
  font-size: 12px;
  text-transform: uppercase;
}

.flagged-item .actions {
  margin-top: 15px;
  display: flex;
  gap: 10px;
}

.flagged-item .actions form {
  display: inline;
}

.flagged-item .actions button {
  padding: 8px 16px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-size: 14px;
}

.flagged-item .btn-approve {
  background: var(--btn-success);
  border-color: var(--btn-success);
  color: white;
}

.flagged-item .btn-approve:hover {
  background: var(--btn-success-hover);
  border-color: var(--btn-success-hover);
}

.flagged-item .btn-delete {
  background: var(--btn-danger);
  border-color: var(--btn-danger);
  color: white;
}

.flagged-item .btn-delete:hover {
  background: var(--btn-danger-hover);
  border-color: var(--btn-danger-hover);
}

/* ========================================
   NEWS PAGE
   ======================================== */
#news h1 {
  margin-top: 15px;
}

.headline {
  position: relative;
  border: var(--border-width) solid var(--card-border);
  border-radius: var(--border-radius);
  padding: var(--item-padding);
  background: var(--card-background);
  margin-bottom: var(--spacing-md);
}

.headline a {
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
  color: var(--text-primary);
  transition: color var(--transition-fast);
}

.headline a:hover {
  color: var(--accent-color);
  text-decoration: none;
}

.headline .title {
  display: block;
  font-size: 1em;
  line-height: 1.4;
  margin: var(--spacing-sm) 0 0 0;
}

.headline .description {
  display: block;
  color: var(--text-secondary);
  font-size: 0.875em;
  line-height: var(--line-height);
  margin-bottom: var(--spacing-xs);
}

.headline .summary {
  font-size: 0.75em;
  margin-top: var(--spacing-sm);
  color: var(--text-muted);
}

.headline .summary a {
  color: var(--text-muted);
  text-decoration: none;
  transition: color var(--transition-fast);
}

.headline .summary a:hover {
  color: var(--accent-color);
  text-decoration: none;
}

.news {
  position: relative;
  border: var(--border-width) solid var(--card-border);
  border-radius: var(--border-radius);
  padding: var(--item-padding);
  background: var(--card-background);
  margin-bottom: var(--spacing-md);
}

.news a {
  text-decoration: none;
  color: var(--text-primary);
}

.news .cover {
  max-width: 200px;
  width: 100%;
  max-height: 300px;
  object-fit: cover;
  border-radius: var(--border-radius);
  margin-bottom: var(--spacing-sm);
}

.news .cover[src=""],
.news .cover:not([src]) {
  display: none;
}

.news .blurb {
  display: block;
}

.news .title {
  display: block;
  font-weight: bold;
  font-size: 1em;
  margin-bottom: 0;
}

.news .description {
  display: block;
  color: var(--text-secondary);
  font-size: 0.9em;
  margin-bottom: var(--spacing-xs);
}

.news .summary {
  font-size: 0.8em;
  margin-top: var(--spacing-sm);
  color: var(--text-secondary);
}

.news .summary a {
  color: var(--text-secondary);
  text-decoration: none;
}

.news .summary a:hover {
  text-decoration: underline;
}

/* News Article View */
#news-article h1 {
  margin-top: 0;
  margin-bottom: 15px;
  font-size: 1.8em;
}

#news-article .article-meta {
  color: var(--text-secondary);
  margin-bottom: 20px;
  font-size: 0.9em;
}

#news-article .article-image {
  max-width: 100%;
  max-height: 300px;
  width: auto;
  height: auto;
  object-fit: cover;
  border-radius: var(--border-radius);
  margin-bottom: 20px;
}

#news-article .article-summary {
  background-color: #f5f5f5;
  padding: 20px;
  border-radius: var(--border-radius);
  margin-bottom: 20px;
}

#news-article .article-summary h3 {
  margin-top: 0;
}

#news-article .article-summary > div {
  line-height: 1.6;
}

#news-article .article-description {
  margin-bottom: 20px;
  line-height: 1.6;
}

#news-article .article-actions {
  margin-top: 20px;
  color: var(--text-secondary);
  font-size: 14px;
}

#news-article .article-actions a {
  color: var(--text-secondary);
}

#news-article .article-back {
  margin-top: 30px;
}

#news-article .article-back a {
  color: var(--text-secondary);
  text-decoration: none;
}

/* Reader content styling */
.reader-content {
  line-height: 1.7;
  font-size: 15px;
  color: var(--text-primary);
}

.reader-content p {
  margin: 0 0 16px;
}

.reader-content h1, .reader-content h2, .reader-content h3,
.reader-content h4, .reader-content h5, .reader-content h6 {
  margin: 24px 0 12px;
  line-height: 1.3;
}

.reader-content h1 { font-size: 1.6em; }
.reader-content h2 { font-size: 1.35em; }
.reader-content h3 { font-size: 1.15em; }

.reader-content ul, .reader-content ol {
  margin: 0 0 16px;
  padding-left: 24px;
}

.reader-content li {
  margin-bottom: 6px;
}

.reader-content blockquote {
  margin: 16px 0;
  padding: 12px 20px;
  border-left: 3px solid var(--border-color, #ddd);
  color: var(--text-secondary);
  background: var(--bg-secondary, #f8f8f8);
  border-radius: 4px;
}

.reader-content pre {
  margin: 16px 0;
  padding: 14px;
  background: var(--bg-secondary, #f5f5f5);
  border-radius: 6px;
  overflow-x: auto;
  font-size: 13px;
  line-height: 1.5;
}

.reader-content code {
  font-size: 0.9em;
  padding: 2px 5px;
  background: var(--bg-secondary, #f5f5f5);
  border-radius: 3px;
}

.reader-content pre code {
  padding: 0;
  background: none;
}

.reader-content a {
  color: var(--link-color, #1a73e8);
  text-decoration: underline;
}

.reader-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 16px 0;
  font-size: 14px;
}

.reader-content th, .reader-content td {
  padding: 8px 12px;
  border: 1px solid var(--border-color, #ddd);
  text-align: left;
}

.reader-content th {
  background: var(--bg-secondary, #f5f5f5);
  font-weight: 600;
}

.reader-content hr {
  border: none;
  border-top: 1px solid var(--border-color, #ddd);
  margin: 24px 0;
}

.reader-content figure {
  margin: 16px 0;
}

.reader-content figcaption {
  font-size: 13px;
  color: var(--text-secondary);
  margin-top: 6px;
}

/* Video info styling */
.thumbnail .info {
  font-size: 0.8em;
  margin-top: var(--spacing-sm);
  color: var(--text-secondary);
}

.thumbnail .info a {
  font-size: 1em; /* Inherit parent's 0.8em, don't compound with base a's 0.9em */
}

/* ========================================
   VIDEO PAGE
   ======================================== */
#video {
}

.thumbnail a {
  text-decoration: none;
  color: var(--text-primary);
}

.thumbnail img {
  max-width: 320px;
  width: 100%;
  border-radius: var(--border-radius);
  margin-bottom: var(--spacing-sm);
}

.thumbnail h3 {
  margin: var(--spacing-sm) 0;
  font-size: 1em;
}

#video img {
  width: 100%;
  border-radius: 5px;
}

#video-search {
  display: flex;
  gap: 8px;
  margin-bottom: 20px;
}

#video-search input {
  flex: 1;
  min-width: 0;
}

#video-search button {
  flex-shrink: 0;
}

/* ========================================
   NEWS
   ======================================== */
#news-search {
  display: flex;
  gap: 8px;
  margin-bottom: 20px;
}

#news-search input {
  flex: 1;
  min-width: 0;
}

#news-search button {
  flex-shrink: 0;
}
/* Legacy markets card styles (for /markets page) */
#markets, #prayer, #video {
  max-width: 100%;
  float: none;
  margin-right: 0;
}

.item {
  border: var(--border-width) solid var(--card-border);
  border-radius: var(--border-radius);
  padding: var(--item-padding);
  background: var(--card-background);
  margin-bottom: var(--spacing-md);
}
.market-symbol {
  font-size: 0.75em;
  color: var(--text-muted);
  font-weight: var(--font-weight-medium);
  letter-spacing: 0.02em;
}

.market-price {
  font-size: 0.75em;
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

/* ========================================
   AUTH PAGES
   ======================================== */
#login, #signup {
  max-width: 400px;
  margin: 0 auto;
}

#login input, #signup input {
  margin-bottom: 10px;
  width: 100%;
}

#login button, #signup button {
  width: 100%;
}

/* ========================================
   UTILITY CLASSES
   ======================================== */
.small {
  font-size: 0.8em;
  line-height: 1.4em;
  color: #666;
  font-weight: normal;
  display: block;
}

.text {
  display: block;
  font-size: 0.8em;
  margin-top: 10px;
}

.right {
  text-align: right;
}

/* A call to action reads as one.
   It was muted grey at 500, which is the weight and colour of furniture — so
   "Make one of your own →", the one thing a paragraph is asking you to do,
   was the least legible text in it. */
.link {
  display: block;
  font-weight: var(--font-weight-semibold, 600);
  text-decoration: none;
  margin-top: 12px;
  color: var(--text-primary, #111);
  font-size: 13px;
}

.link:hover {
  color: var(--accent-color, #000);
  text-decoration: none;
}

/* A link inside a sentence. See app.TextLink: .link is display:block, so used
   in prose it breaks the line where it sits. */
.link-text {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.link-text:hover {
  color: var(--accent-color, #000);
}

.category,
.highlight,
a.category,
a.highlight {
  display: inline-block;
  color: var(--text-secondary) !important;
  font-size: 10px !important;
  font-weight: bold !important;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: transparent;
  padding: 0;
  border: none;
  text-decoration: none;
}

.category-header {
  margin-bottom: 8px;
}

.category-header .category {
  margin-bottom: 0;
}

.cover {
  width: 200px;
  height: auto;
  min-height: 100px;
  max-height: 300px;
  object-fit: cover;
  margin-right: 10px;
  margin-bottom: 10px;
  display: inline-block;
  border-radius: 3px;
  background: #1a1a1a;
}

.cover[src=""],
.cover:not([src]) {
  display: none;
}

.blurb {
  display: inline-block;
  vertical-align: top;
  max-width: 600px;
}

.blurb .text {
  font-size: 0.9em;
}

.title {
  font-size: 1.2em;
  font-weight: bold;
  display: block;
}

.description, .description a {
  font-size: 1em;
  font-weight: normal;
  white-space: pre-wrap;
}

.description iframe {
  display: none;
}

.verse {
  white-space: pre-wrap;
  margin-bottom: 0;
  font-size: 0.9em;
  overflow-y: scroll;
  max-height: 200px;
}
.video {
  margin-bottom: var(--spacing-lg);
  position: relative;
  padding-bottom: 56.25%;
  height: 0;
}

/* ========================================
   MOBILE RESPONSIVE
   ======================================== */
/* Desktop: account for sidebar */
@media only screen and (min-width: 901px) {
  #nav-container ~ #content {
    padding-left: 240px; /* Account for fixed sidebar */
  }

  /* The hamburger is a mobile-only control by default; on desktop it becomes
     a collapse toggle, since the sidebar is always present rather than an
     overlay. Same button, different meaning per viewport. */
  #menu-toggle {
    display: flex;
  }

  #nav-container {
    transition: transform 0.18s ease;
  }
  #nav-container ~ #content {
    transition: padding-left 0.18s ease;
  }

  /* Collapsed: slide the sidebar off-canvas and reclaim its gutter. The
     selector carries body.nav-collapsed so it outranks the padding rule
     above rather than relying on source order. */
  body.nav-collapsed #nav-container {
    transform: translateX(-100%);
  }
  body.nav-collapsed #nav-container ~ #content {
    padding-left: 40px;
  }
}

/* Respect a user who has asked for less motion. */
@media (prefers-reduced-motion: reduce) {
  #nav-container,
  #nav-container ~ #content {
    transition: none;
  }
}

/* Pricing plans. These were inline styles, which no media query could override
   — inline always beats the stylesheet — so they stayed 240px wide on a phone. */
.plans {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0 0 24px;
}
.plan {
  flex: 1 1 200px;
  min-width: 200px;
  max-width: 240px;
  text-align: center;
}
@media only screen and (max-width: 600px) {
  .plans { flex-direction: column; align-items: stretch; }
  /* flex-basis sizes the height once stacked, so reset it to fit content. */
  .plan { flex: 0 0 auto; max-width: none; min-width: 0; width: 100%; }
}

/* Tablet/Mobile: hamburger menu with slide-out sidebar */
@media only screen and (max-width: 900px) {
  body {
    overflow-x: hidden;
  }
  
  /* Show hamburger menu button */
  #menu-toggle {
    display: flex;
  }

  #head {
    padding: 6px 15px;
    border-bottom: 1px solid #ddd;
    justify-content: center;
    position: fixed;
    height: 44px;
    box-sizing: border-box;
  }

  
  #brand a {
    font-size: 1em;
  }
  
  /* Sidebar hidden by default on mobile */
  #nav-container {
    position: fixed;
    left: -280px;
    top: 0;
    width: 260px;
    height: 100vh;
    /* dvh tracks the *currently visible* height as Safari's toolbar collapses,
       so the drawer's bottom always lands at the real bottom of the screen —
       svh (small) left a gap and vh (large) hid the bottom under the toolbar,
       which is why reachability changed "depending on the screen". */
    height: 100dvh;
    padding: 48px 20px calc(40px + env(safe-area-inset-bottom, 0px)) 20px;
    background: white;
    border-right: 1px solid #e0e0e0;
    z-index: 200;
    transition: left 0.3s ease;
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    /* Scroll the WHOLE sidebar on mobile. Relying on an inner #nav scroll plus
       a bottom-pinned .nav-bottom left Account/Logout behind the browser
       toolbar on short viewports; scrolling the container reaches everything. */
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }

  #nav {
    flex: 0 0 auto;
    overflow-y: visible;
    min-height: 0;
  }
  
  /* Show sidebar when menu is open */
  body.menu-open #nav-container {
    left: 0;
  }
  
  /* Show overlay when menu is open */
  body.menu-open #nav-overlay {
    display: block;
  }
  
  #nav {
    flex-direction: column;
    gap: 3px;
  }

  #nav a {
    padding: 8px 14px;
    flex-direction: row;
  }

  #nav img {
    margin-right: 14px;
    height: 22px;
    width: 22px;
  }

  .nav-divider {
    margin: 3px 0;
  }

  /* Starter query chips - slightly smaller on mobile */
  .starter-chip {
    font-size: 12px;
    padding: 5px 12px;
  }

  /* Follows the nav rather than being pinned to the bottom of the drawer.
     margin-top:auto was right when the sidebar held nineteen services and
     filled the screen; with eight entries it strands Account and Logout below
     a 280px hole, which is what made the open menu look broken rather than
     short. The border still separates them, and the container scrolls when a
     viewport is small enough to need it. */
  .nav-bottom {
    border-top: 1px solid var(--divider, #f0f0f0);
    padding-top: 10px;
    margin-top: 10px;
    gap: 1px;
  }

  .nav-bottom a {
    padding: 6px 14px;
  }
  
  #container {
    display: flex;
    flex-direction: column;
    min-height: calc(100vh - 44px);
    min-height: calc(100svh - 44px);
    padding-top: 44px;
    margin-top: 0;
  }
  
  #content {
    margin-left: 0;
    padding: 15px;
    max-width: 100%;
  }
  
  #page-title {
    text-align: center;
    font-size: 1.2em;
    margin-top: 0;
    margin-bottom: 8px;
    padding-top: 0;
  }
  
  #footer {
    padding: 20px 15px;
    margin-bottom: 0; /* No bottom bar anymore */
  }
  
  #main {
    max-width: 100%;
    padding: 15px;
    margin-top: 75px;
  }
  
  /* Blog styles */
  #blog .info {
    text-align: center;
  }
  #blog .post-item .info {
    text-align: left;
  }
  #blog .post-tags {
    text-align: center;
    margin-top: 8px;
    font-size: small;
  }
  #blog > div:first-child {
    text-align: center;
  }
  
  /* Topic selectors */
  .anchor {
    margin: 30px 0;
  }
  #topics, #topic-selector {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .topic-tabs, #topics {
    gap: 4px;
    flex-wrap: nowrap;
  }
  #topic-selector .head, #topics .head {
    font-size: 12px;
    white-space: nowrap;
    padding: 5px 0;
  }
  #chat-clear {
    position: static;
    display: block;
    text-align: right;
    margin-top: 4px;
  }
  
  /* Chat page adjustments */
  #messages {
    flex: 1 1 0;
    overflow-y: auto;
    min-height: 0;
    padding-bottom: 0;
    max-height: calc(100svh - 200px);
    -webkit-overflow-scrolling: touch;
  }
  #messages ~ #chat-form {
    margin-bottom: 0;
    flex-shrink: 0;
  }
  #chat-form {
    flex: 0 0 auto;
    background: white;
    padding-top: 10px;
    padding-bottom: 15px; /* Safe area for PWA/mobile */
    margin: 0;
  }
  
  /* Cards and content */
  .post-show {
    margin-top: 10px;
  }
  .card, #prayer, #video {
    float: none;
    display: block;
    width: 100%;
    min-width: auto;
    max-width: 100%;
    box-sizing: border-box;
  }
  #video-search {
    display: flex;
    max-width: 100%;
  }
  
  /* Home page layout — flatten columns on mobile for unified card ordering */
  #home, .home-row {
    display: flex;
    flex-direction: column;
    gap: 8px;
    height: auto;
  }
  .home-left, .home-right {
    display: contents;
  }
  #home-date {
    justify-content: center;
  }

  /* Compact cards on mobile */
  .home-left .card, .home-right .card {
    padding: 12px;
    margin-bottom: 0;
    width: 100%;
    min-width: auto;
  }

  /* The corner mark tracks the card's padding, which is smaller here. */
  .home-left .card-corner, .home-right .card-corner {
    right: 38px;
  }

  .home-left .card h3 {
    font-size: 14px;
    margin-bottom: 8px;
  }

  .home-left .card-link {
    font-size: 12px;
  }

  /* One column, in the order the server sent: the stream newest first, then
     what is fixed. There was a hand-written order per card id here — a list
     that had to be kept in step with cards.json, and was not: a card with no
     rule defaulted to order:0 and jumped to the top, which is what happened
     when Images was added and again each time the reminder card was renamed.
     display:contents flattens both columns into this grid in DOM order, and
     DOM order is now a decision rather than a file. */

  .cover {
    display: block;
  }
  
  /* Buttons on mobile: 36px is a thumb, not a design.
     
     It was min-height alone, which grows the box and leaves the label at the
     top of it — fine on a filled .btn where the fill shows you the target, and
     wrong on a borderless text button, where all you see is a word with
     twenty-two pixels of nothing under it. That is the gap in the agent card
     before Remove, and the same gap under the inbox's delete cross.
     
     Centring the label inside the target fixes it without giving the target
     back: the button is still 36px to a thumb and looks like its own height to
     an eye. */
  button, a.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 36px;
    padding: 6px 12px;
  }
  
  /* Prevent iOS zoom on input focus */
  input, textarea, select {
    font-size: 16px;
  }
  
  input[type="text"],
  input[type="email"],
  input[type="password"],
  textarea {
    -webkit-appearance: none;
    appearance: none;
  }
}

/* ========================================
   MAIL/MESSAGING
   ======================================== */
.thread-preview {
  padding: var(--item-padding);
  border-bottom: var(--border-width) solid var(--divider);
  position: relative;
  cursor: pointer;
  transition: background var(--transition-fast);
}

.thread-preview:hover {
  background: var(--hover-background);
}

.thread-preview .delete-btn {
  position: absolute;
  top: 15px;
  right: 15px;
  color: #ccc;
  text-decoration: none;
  font-size: 24px;
  line-height: 1;
}

/* Desktop: hide delete button, show on hover */
@media (min-width: 769px) {
  .thread-preview .delete-btn {
    display: none;
  }
  
  .thread-preview:hover .delete-btn {
    display: block;
  }
}

/* Mobile: always show delete button */
@media (max-width: 768px) {
  .thread-preview .delete-btn {
    display: block;
  }
}

/* Thread message card */
.thread-message {
  border: var(--border-width) solid var(--card-border);
  border-radius: var(--border-radius);
  padding: var(--item-padding);
  margin-bottom: var(--spacing-md);
  background: var(--card-background);
  max-width: 100%;
}

/* Reduce thread message padding on smaller screens */
@media only screen and (max-width: 900px) {
  .thread-message {
    padding: 10px;
  }
  
  .thread-message textarea,
  .thread-message input {
    max-width: 100%;
    box-sizing: border-box;
  }
}

.thread-message-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.thread-message-header-text {
  flex: 1;
  min-width: 0;
}

.thread-message-author {
  color: #333;
  font-size: 14px;
  font-weight: bold;
}

.thread-message-time {
  color: #999;
  font-size: 13px;
}

.thread-message-delete {
  color: #ccc;
  font-size: 24px;
  text-decoration: none;
  line-height: 1;
  padding: 0 5px;
  flex-shrink: 0;
}

.thread-message-body {
  line-height: 1.6;
  word-wrap: break-word;
  overflow-wrap: break-word;
  color: #333;
  max-width: 100%;
  overflow-x: auto;
}
/* Links */
.mail-link {
  color: var(--text-primary);
  text-decoration: none;
}

.mail-link:hover {
  text-decoration: underline;
}

.mail-link-muted {
  color: #666;
  text-decoration: none;
}

.mail-link-muted:hover {
  color: #333;
}

/* Contenteditable placeholder styling */
[contenteditable][placeholder]:empty:before {
  content: attr(placeholder);
  color: #999;
  cursor: text;
}

[contenteditable]:focus {
  outline: none;
}

/* Status indicator */
#status-indicator {
  /* placeholder */
}
.d-inline { display: inline; }
.d-flex { display: flex; }

/* Flex utilities */
.flex-column { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.gap-2 { gap: 8px; }
.gap-3 { gap: 10px; }
.gap-4 { gap: 15px; }
.text-center { text-align: center; }
/* The type scale and the greys, in one place.
   These are what pages were writing by hand: font-size:13px and color:#888
   between them account for a sixth of every inline style in the product. The
   inline versions are also worse than the class, not merely more verbose — a
   literal #888 does not follow --text-muted, so a page that hard-codes it is a
   page that will not follow the palette anywhere it moves.
   Sizes are named for what they are used for rather than numbered, and the
   scale is deliberately short: four sizes is a scale, nine is a habit. */
.text-2xs { font-size: 11px; }
.text-xs  { font-size: 12px; }
.text-sm  { font-size: 13px; }
.text-base { font-size: 14px; }

.text-error { color: var(--btn-danger); }
.text-success { color: var(--btn-success); }
.text-muted { color: var(--text-muted, #888); }
.text-secondary { color: var(--text-secondary, #666); }
/* Font style */
.italic { font-style: italic; }

/* Whitespace */
.whitespace-pre-wrap { white-space: pre-wrap; }
/* Width */
.w-full { width: 100%; }
.max-w-xl { max-width: 750px; }

/* Margins */
/* The shapes pages were writing by hand.
   Every one of these was measured off the inline styles in the product rather
   than guessed at: .row alone (display:flex + align-items:center + gap:8px)
   accounted for over a hundred of them, written out longhand each time. The
   set is deliberately small and deliberately named for what it does — the
   layer this replaced was a Tailwind-shaped vocabulary of a hundred classes
   the app never learned, which is why it was all dead. */

/* Layout */
.row { display: flex; align-items: center; gap: 8px; }
.row-top { display: flex; align-items: flex-start; gap: 8px; }
.col { display: flex; flex-direction: column; gap: 8px; }
.between { justify-content: space-between; }
.grow { flex: 1; min-width: 0; }
.fixed-w { flex: none; }
.min-w-0 { min-width: 0; }
.scroll-x { overflow-x: auto; }

/* Display */
.d-block { display: block; }
.d-inline-block { display: inline-block; }
.d-none { display: none; }

/* Type */
.medium { font-weight: 500; }
.semibold { font-weight: 600; }
.bold { font-weight: 700; }
.nowrap { white-space: nowrap; }
.text-left { text-align: left; }
.no-underline { text-decoration: none; }
.font-inherit { font-family: inherit; font-size: inherit; }

/* Surface */
.bg-soft { background: var(--hover-background, #f5f5f5); }
.bg-white { background: var(--card-background, #fff); }
.bg-black { background: var(--accent-color, #000); }
.text-white { color: #fff; }
.no-border { border: none; }
.rounded-lg { border-radius: 8px; }
.clickable { cursor: pointer; }
.p-tight { padding: 4px 8px; }

/* A small outlined action in a table row — Ban, Grant, Verify on /admin/users.
   The colour is the only thing that varies, so it is a modifier rather than
   four near-identical rules. */
.mini-btn {
  font-size: 12px;
  padding: 2px 8px;
  border-radius: var(--border-radius, 6px);
  border: var(--border-width, 1px) solid var(--card-border, #ddd);
  background: var(--card-background, #fff);
  color: var(--text-secondary, #555);
  cursor: pointer;
  font-family: inherit;
}
.mini-btn.danger { border-color: var(--btn-danger, #c00); color: var(--btn-danger, #c00); }
.mini-btn.good { border-color: var(--btn-success, #22c55e); color: var(--btn-success, #22c55e); }
.mini-btn.info { border-color: var(--link-color, #06b); color: var(--link-color, #06b); }

/* A count on a label — unread, flagged, over quota. */
.count-badge {
  background: var(--accent-color, #000);
  color: #fff;
  padding: 1px 6px;
  border-radius: 8px;
  font-size: 11px;
}
.count-badge.info { background: var(--link-color, #06b); }
.count-badge.good { background: var(--btn-success, #22c55e); }
.count-badge.quiet { background: var(--text-secondary, #555); }

/* A row that needs to shout — a banned account, a failed job. */
.row-danger { background: var(--btn-danger, #c00); color: #fff; }
.row-danger a { color: #fff; }

/* A few widths, for a table column that should not grow with its content. */
.w-60 { width: 60px; }
.w-100 { width: 100px; }
.inline-row { display: inline-flex; gap: 2px; align-items: center; }

/* A grid of thumbnails that reflows: images, apps, tiles. */
.thumb-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
  margin-top: 8px;
}

/* A one-line message about what just happened, above the thing it is about.
   Three states, and they were being written as literal greens, reds and ambers
   in five different files. */
.notice {
  font-size: 13px;
  margin: 0 0 8px;
  padding: 8px;
  border-radius: var(--border-radius, 6px);
}
.notice.ok { color: var(--btn-success, #0a7d33); }
.notice.bad { color: var(--btn-danger, #b00); }
.notice.warn { background: var(--warn-background, #fff7ed); color: var(--warn-text, #7c2d12); }

/* An action laid over the corner of an image. */
.overlay-btn {
  position: absolute;
  bottom: 6px;
  right: 6px;
  font-size: 11px;
  padding: 3px 8px;
  border: none;
  border-radius: var(--border-radius, 6px);
  background: rgba(0, 0, 0, .6);
  color: #fff;
  cursor: pointer;
}
.relative { position: relative; }

/* A picture that fills its column. */
.img-full { width: 100%; border-radius: var(--border-radius, 6px); display: block; }
.thumb-sm { width: 80px; height: 45px; object-fit: cover; border-radius: 3px; flex: none; }

/* Fixed field widths, for a form whose inputs should not all be one length. */
.w-160 { width: 160px; }
.w-260 { width: 260px; }
.w-640 { max-width: 640px; }
.w-760 { max-width: 760px; }

/* A row separated from the next by a hairline and nothing else. .feed-row is
   the roomier version; this is for a dense list. */
.thin-row { padding: 6px 0; border-bottom: var(--border-width, 1px) solid var(--divider, #f0f0f0); }
.thin-row.row-pad { padding: 8px 0; }

/* A bordered area holding something rendered — a preview, an embed. */
.frame {
  width: 100%;
  min-height: 120px;
  border: var(--border-width, 1px) solid var(--card-border, #eee);
  border-radius: var(--border-radius, 6px);
  background: var(--card-background, #fff);
}

.inherit-color { color: inherit; }
.link-colour { color: var(--link-color, #0066cc); }
.lead-15 { font-size: 15px; }
.indent { padding-left: 18px; }
.my-2 { margin-top: 8px; margin-bottom: 8px; }
.mr-2 { margin-right: 8px; }

/* A terminal: dark, monospaced, and scrolling on its own. */
.console {
  background: var(--console-background, #1a1a1a);
  color: var(--console-text, #e0e0e0);
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  padding: 16px;
  border: none;
}
.console-input {
  flex: 1;
  background: transparent;
  border: none;
  color: var(--console-text, #e0e0e0);
  font-family: inherit;
  font-size: 13px;
  outline: none;
  padding: 6px 0;
}
.console-btn {
  background: #333;
  color: var(--console-text, #e0e0e0);
  border: none;
  border-radius: var(--border-radius, 6px);
  padding: 4px 12px;
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
}

/* A round initial standing in for a face. */
.avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--hover-background, #f5f5f5);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  flex: none;
}
.avatar.filled { color: #fff; font-size: 12px; font-weight: 700; }

/* A chat bubble: square where it meets its avatar, round everywhere else. */
.bubble {
  margin-top: 3px;
  padding: 8px 10px;
  border-radius: 0 12px 12px 12px;
  font-size: 14px;
  line-height: 1.5;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}

/* A cell that must not grow: truncate rather than push the table wide. */
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fixed-table { width: 100%; table-layout: fixed; }
.w-90 { width: 90px; }
.w-110 { width: 110px; }
.w-130 { width: 130px; }

/* Raw text in a table cell — a header, a stack trace. */
.raw {
  background: var(--hover-background, #f9f9f9);
  padding: 8px;
  word-break: break-all;
  white-space: pre-wrap;
  font-size: 12px;
}
.wrap-anywhere { word-break: break-word; white-space: pre-wrap; }
.tall-scroll { max-height: 60vh; overflow-y: auto; }
.baseline-row { display: flex; align-items: baseline; gap: 8px; }
.text-faint { color: var(--text-faint, #bbb); }
.line-32 { line-height: 32px; }
.lh-15 { line-height: 1.5; }
.pre-line { white-space: pre-line; line-height: 1.6; }
.align-top { vertical-align: top; }
.top-rule { padding-top: 14px; border-top: var(--border-width, 1px) solid var(--card-border, #eee); }
.border-bad { border-color: var(--btn-danger, #e0a3a3); }
.my-1 { margin-top: 4px; margin-bottom: 4px; }
.ml-1 { margin-left: 4px; }

/* The prayer times table: the next one is the only row that matters, so it is
   the only row set in the text colour. */
.pr-row td { padding: 4px 0; color: var(--text-secondary, #666); font-weight: 400; }
.pr-row.pr-next td { color: var(--text-primary, #111); font-weight: 600; }

/* A panel saying something worked — a token just issued, a setting saved.
   Green wash, green border, and it holds the thing you are meant to copy. */
.success-panel {
  margin: 15px 0;
  padding: 15px;
  background: var(--pass-background, #d4edda);
  border: var(--border-width, 1px) solid var(--pass-border, #c3e6cb);
  border-radius: var(--border-radius, 6px);
  overflow: hidden;
}
.success-panel pre {
  background: var(--card-background, #fff);
  padding: 10px;
  border: var(--border-width, 1px) solid var(--pass-border, #c3e6cb);
  border-radius: var(--border-radius, 6px);
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

/* A strip across the top of a page asking for something — verify your address,
   finish setting up. Amber, and it sits above what it is about. */
.banner {
  padding: 12px 16px;
  background: var(--warn-wash, #fff3cd);
  border: var(--border-width, 1px) solid var(--warn-border, #ffc107);
  border-radius: var(--border-radius, 6px);
  margin-bottom: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.banner-text { font-size: 14px; color: var(--warn-ink, #856404); }

/* A build log: dark, monospaced, scrolling, and it starts hidden. */
.build-log {
  background: #1e1e1e;
  color: #d4d4d4;
  padding: 16px;
  border-radius: var(--border-radius, 6px);
  min-height: 200px;
  max-height: 500px;
  overflow-y: auto;
  font-size: 13px;
  line-height: 1.6;
  white-space: pre-wrap;
}
.log-ok { color: #6a9955; }
.log-bad { color: #f44747; }

/* A card whose left edge says how it went. */
.edge { border-left: 4px solid var(--card-border, #e8e8e8); }
.edge.good { border-left-color: var(--btn-success, #27ae60); }

/* A menu that drops from the corner of the thing that opens it. */
.dropdown {
  display: none;
  position: absolute;
  right: 0;
  top: 24px;
  background: var(--card-background, #fff);
  border: var(--border-width, 1px) solid var(--card-border, #e0e0e0);
  border-radius: var(--border-radius, 6px);
  box-shadow: var(--shadow-sm, 0 2px 8px rgba(0,0,0,0.1));
  z-index: 100;
  min-width: 130px;
  padding: 4px 0;
}
.corner { position: absolute; top: 10px; right: 10px; }
.corner-x { text-decoration: none; font-size: 18px; color: var(--text-muted, #888); line-height: 1; }

/* A form narrow enough to read in one column, centred. */
.form-col { max-width: 520px; margin: 0 auto; }
.hr-soft { margin: 30px 0; border: none; border-top: var(--border-width, 1px) solid var(--card-border, #eee); }

/* A card that reports something is fine. */
.card-ok { background: var(--ok-wash, #f0fff0); border-color: var(--ok-border, #a3d9a5); }

/* A field showing a value you may read and not change. */
.form-input.readonly { border-color: var(--divider, #eee); background: var(--hover-background, #fafafa); color: var(--text-secondary, #666); }

.text-1em { font-size: 1em; }
.text-08 { font-size: 0.8em; }
.text-18 { font-size: 18px; }
.break-all { word-break: break-all; }
.pad-row { padding: 12px 16px; }
.fill { height: 100%; width: 100%; }
.w-320 { max-width: 320px; }
.w-440 { max-width: 440px; }
.w-820 { max-width: 820px; }
.centered { margin: 0 auto; }
.mt-half { margin-top: 6px; }
.mt-14 { margin-top: 14px; }
.mt-24 { margin-top: 24px; }
.mt-2em { margin-top: 2em; }
.pull-up { margin-top: -8px; }
.text-22 { font-size: 22px; }
.text-24 { font-size: 24px; }
.text-28 { font-size: 28px; }
.cell-right { padding: 6px 8px; text-align: right; }
.raw-sm { white-space: pre-wrap; word-break: break-all; font-size: 0.8em; }
.push-right { margin-left: auto; }
.span-all { grid-column: 1 / -1; }
.icon-24 { width: 24px; height: 24px; vertical-align: bottom; margin-right: 6px; }
/* An iframe filling the box it was given. */
.fill-abs { position: absolute; top: 0; left: 0; right: 0; width: 100%; height: 100%; border: none; }

/* Sign in with Google. Not a .btn: it carries a mark and has to read as
   somebody else's control, which is what the outline is for. */
.oauth-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: var(--border-width, 1px) solid var(--card-border, #ddd);
  border-radius: var(--border-radius, 6px);
  padding: 10px 12px;
  text-decoration: none;
  color: var(--text-primary, #111);
  font-weight: 600;
  margin: 0 0 14px;
}
.oauth-btn.inline { display: inline-flex; justify-content: flex-start; padding: 8px 14px; margin: 8px 0 0; }

/* A button that is a link: no chrome, just the label. */
.plain-btn {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  cursor: pointer;
  color: var(--text-secondary, #555);
}
.plain-btn.danger { color: var(--btn-danger, #c00); }
.plain-btn.faint { color: var(--text-faint, #bbb); font-size: 18px; line-height: 1; }

/* The strip across the top of the app asking for one thing. Amber, one line,
   and the action is pushed to the right of it. */
.app-banner {
  background: var(--banner-wash, #fff8e1);
  border: var(--border-width, 1px) solid var(--banner-border, #f1d68c);
  border-radius: var(--border-radius, 6px);
  padding: 10px 14px;
  margin: 0 0 14px;
  font-size: 14px;
  color: var(--banner-ink, #5b4a00);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.app-banner a { color: var(--banner-ink, #5b4a00); }

/* A small round tick beside a name. */
.verified {
  display: inline-block;
  vertical-align: middle;
  width: 16px;
  height: 16px;
  background: var(--btn-success, #22c55e);
  color: #fff;
  border-radius: 50%;
  text-align: center;
  line-height: 16px;
  font-size: 11px;
  font-weight: 700;
}

/* A step in a run: what the agent did, quoted off to one side. */
.step-quote { border-left: 3px solid var(--link-color, #007bff); margin-bottom: 8px; opacity: .8; }
.step-toggle { cursor: pointer; color: var(--text-secondary, #555); font-size: 13px; list-style: none; padding: 4px 0; }
.step-out {
  margin: 6px 0 0;
  font-size: 12px;
  color: var(--text-secondary, #444);
  white-space: pre-wrap;
  background: var(--hover-background, #f9f9f9);
  border-radius: var(--border-radius, 6px);
  padding: 8px;
  max-height: 200px;
  overflow-y: auto;
  font-family: inherit;
}

.status-warn { color: #ff9800; }
.page-head { padding-bottom: 20px; border-bottom: 2px solid #333; }
.w-230 { width: 230px; }
.gap-xs { gap: 4px; }
.pl-1 { padding-left: 6px; }
.collapse { border-collapse: collapse; }
.corner-tr { position: absolute; top: 0; right: 0; }
.frame.frame-tall { min-height: 200px; }

/* One line in a dropdown. */
.menu-item, a.menu-item, a.menu-item:visited {
  display: block;
  padding: 8px 16px;
  font-size: 13px;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  color: var(--text-secondary, #555);
}
.menu-item:hover { background: var(--hover-background, #f5f5f5); }
.menu-item.danger, a.menu-item.danger, a.menu-item.danger:visited { color: var(--btn-danger, #c00); }

/* A row that is a choice: a saved place, a connected calendar. */
.pick-row-box {
  display: flex;
  align-items: center;
  gap: 12px;
  border: var(--border-width, 1px) solid var(--card-border, #eee);
  border-radius: var(--border-radius, 6px);
  padding: 10px 14px;
}
.pick-row-box.soft { background: var(--hover-background, #fafafa); }

/* Something somebody else said, quoted into a page. */
.quote {
  border-left: 3px solid var(--card-border, #ccc);
  margin: 8px 0;
  padding: 8px 12px;
  background: var(--hover-background, #fafafa);
  border-radius: 0 var(--border-radius, 6px) var(--border-radius, 6px) 0;
}

/* A block of preformatted output inside prose — a header dump, a raw body. */
.pre-block {
  background: var(--hover-background, #f5f5f5);
  padding: 10px;
  border-radius: var(--border-radius, 6px);
  overflow-x: auto;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 12px;
}
.warn-block {
  background: var(--warn-wash, #fff3cd);
  padding: 10px;
  border-radius: var(--border-radius, 6px);
  margin-bottom: 10px;
  border-left: 4px solid var(--warn-border, #ffc107);
}

.thumb-grid.wide { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
.text-gold { color: #b7791f; }
.cell { padding: 6px 8px; }
.cell.nested { padding-left: 24px; }
.sep { margin: 0 8px; color: var(--card-border, #ddd); }
.underlined { color: var(--link-color, #0066cc); text-decoration: underline; }

/* A map, drawn into a fixed box. z-index 0 so the tiles' own stacking does not
   climb over the page around them. */
.map-box {
  height: 280px;
  margin: 1rem 0;
  border-radius: var(--border-radius, 6px);
  overflow: hidden;
  position: relative;
  z-index: 0;
}

/* A narrow number field in a table row. */
.num-field {
  width: 64px;
  font-size: 12px;
  padding: 2px 4px;
  border: var(--border-width, 1px) solid var(--card-border, #ddd);
  border-radius: var(--border-radius, 6px);
}

/* A row of filter pills over a list. Named once because /apps, /mail, /inbox
   and /archive were each drawing the same strip. */
.app-filters { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 16px; }

/* A bordered box that is not a card: a row in a list, a nested panel. The card
   is the page's unit; this is the thing inside one. */
.tile {
  border: var(--border-width, 1px) solid var(--card-border, #eee);
  border-radius: var(--border-radius, 6px);
  padding: 12px;
}
.tile-row { position: relative; display: flex; gap: 12px; align-items: flex-start; }

/* A small dark label on a light row — a count, a state, a price. */
.badge-dark {
  background: var(--accent-color, #000);
  color: #fff;
  padding: 2px 8px;
  border-radius: var(--border-radius, 6px);
  font-size: 11px;
}

/* The secondary button: same shape as .btn, drawn as an outline. */
.btn-plain, a.btn-plain, a.btn-plain:visited {
  background: var(--card-background, #fff);
  color: var(--text-primary, #111);
  border: var(--border-width, 1px) solid var(--card-border, #e0e0e0);
}
.btn-plain:hover { border-color: var(--text-muted, #bbb); }
button.btn-plain { padding: 6px 12px; font: inherit; cursor: pointer; color: var(--text-secondary, #666); }

/* Amber, for a state that is neither fine nor an error. --btn-danger and
   --btn-success already exist; this was the missing third. */
.text-warn { color: var(--btn-warning, #c60); }

.w-auto { width: auto; }
.align-middle { vertical-align: middle; }
.gap-1 { gap: 6px; }
.my-3 { margin-top: 12px; margin-bottom: 12px; }
.mt-px { margin-top: 2px; }
/* A column narrower than the page, for a form nobody should have to track
   across 720px. */
.col-narrow { max-width: 600px; }

/* A textarea for prose you type: full width, growable, in the page's own face
   rather than the browser's monospace default. */
.form-area {
  width: 100%;
  box-sizing: border-box;
  padding: 10px;
  border: var(--border-width, 1px) solid var(--card-border, #ddd);
  border-radius: var(--border-radius, 6px);
  font: inherit;
  font-size: 14px;
  resize: vertical;
}

/* Text this instance did not write — a post, a link somebody pasted, a mail
   preview. One unbroken token has nowhere to wrap and drags the page sideways
   on a phone; the same reason .card carries overflow-wrap. */
.breakable { overflow-wrap: break-word; word-break: break-word; }

/* A row in a feed: separated by a rule rather than boxed. */
.feed-row { padding: 12px 0; border-bottom: var(--border-width, 1px) solid var(--divider, #f0f0f0); }

/* A quiet panel: a note, an empty state, a summary under a list. */
.panel {
  margin: 16px 0;
  padding: 12px;
  background: var(--hover-background, #f9f9f9);
  border-radius: var(--border-radius, 6px);
  text-align: center;
}

/* A card that is a link — a preview of somewhere else. */
.link-card {
  display: block;
  border: var(--border-width, 1px) solid var(--card-border, #e1e1e1);
  border-radius: var(--border-radius, 6px);
  margin-top: 8px;
  text-decoration: none;
  color: inherit;
  overflow: hidden;
}
.link-card-pad { padding: 12px; }

/* The social feed. These were inline on every post; they are page furniture,
   so they live with the rest of it. */
.so-head { align-items: baseline; padding-right: 20px; }
.so-name { color: var(--text-primary, #000); font-weight: 700; }
.so-image { width: 100%; max-height: 200px; object-fit: cover; display: block; }
.so-pad { padding: 10px 12px; }
.so-body { font-size: 15px; line-height: 1.5; }
.so-title { line-height: 1.3; }
.so-sub { margin-bottom: 2px; }
.so-desc { line-height: 1.4; }
.so-url { color: var(--link-color, #06c); word-break: break-all; }
.so-rule { border-bottom: 2px solid var(--card-border, #eee); }
.my-4 { margin-top: 16px; margin-bottom: 16px; }
.border-box { box-sizing: border-box; }
.mb-2 { margin-bottom: 8px; }

.m-0 { margin: 0; }
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 5px; }
.mt-2 { margin-top: 8px; }
.mt-3 { margin-top: 10px; }
.mt-4 { margin-top: 15px; }
.mt-5 { margin-top: 20px; }
.mt-6 { margin-top: 30px; }
.mb-1 { margin-bottom: 5px; }
.mb-3 { margin-bottom: 10px; }
.mb-4 { margin-bottom: 15px; }
.mb-5 { margin-bottom: 20px; }
.mb-6 { margin-bottom: 30px; }
.ml-3 { margin-left: 10px; }
.ml-4 { margin-left: 15px; }
.p-2 { padding: 8px; }
.p-3 { padding: 10px; }
.p-4 { padding: 15px; }
.p-5 { padding: 20px; }
/* Background */
.bg-light { background: #f9f9f9; }
/* Borders */
.border { border: 1px solid var(--card-border, #e0e0e0); }
.border-b { border-bottom: 1px solid var(--divider, #f0f0f0); }
.border-t { border-top: 1px solid var(--divider, #f0f0f0); }
.center-card { max-width: 400px; margin: 50px auto; text-align: center; }
.center-card-md { max-width: 500px; margin: 50px auto; text-align: center; }

/* Form elements */
/* The text field. Pages were drawing it by hand —
   width:100%;box-sizing:border-box;padding:8px;border:1px solid #ccc;
   border-radius:4px — which is this rule with a different radius and a border
   that does not follow the palette. Tokenised, so it moves with everything
   else; pair it with .w-full where the field should fill its row. */
.form-input {
  padding: 10px;
  border: var(--border-width, 1px) solid var(--card-border, #ccc);
  border-radius: var(--border-radius, 6px);
  box-sizing: border-box;
  font: inherit;
}

.form-input::placeholder {
  color: var(--text-muted, #aaa);
}

/* A field you paste code or a long body into: monospaced and tall enough to
   see the shape of what is in it. */
.mono { font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace); }

/* A field label above its input. */
.field-label { font-weight: 500; }

.mono-tall {
  min-height: 300px;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
}

/* Message/alert boxes */
.alert {
  padding: 10px;
  border-radius: 4px;
  margin-bottom: 15px;
}
/* Progress bar */
.progress {
  background: #eee;
  height: 6px;
  border-radius: 3px;
  margin: 10px 0;
}
/* Stats table (for wallet, admin, etc) */
.stats-table {
  width: 100%;
  font-size: 14px;
}

.stats-table td:last-child {
  text-align: right;
}

/* Data table with borders */
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  margin-bottom: 32px;
}

.data-table th,
.data-table td {
  padding: 10px 12px;
  border-bottom: 1px solid #eee;
}

.data-table th {
  text-align: left;
}

/* A table with a rule round every cell, for a report you read across as much
   as down — a DMARC digest, a diagnostics dump. .data-table is the other kind:
   rows separated, no vertical rules, for a list you scan down. Both were being
   drawn cell by cell with padding:8px;border:1px solid #ddd on every th and td.
   .tight makes the cells narrow enough for a dense report. */
.grid-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.grid-table th,
.grid-table td {
  padding: 8px;
  border: var(--border-width, 1px) solid var(--card-border, #ddd);
  text-align: left;
}
.grid-table th { background: var(--hover-background, #f5f5f5); }
.grid-table.tight th,
.grid-table.tight td { padding: 4px 8px; }
/* A cell that passed or failed a check. */
.cell-pass { background: var(--pass-background, #d4edda); }
.cell-fail { background: var(--fail-background, #f8d7da); }

/* A table whose rows are separated by a hairline and nothing else. */
.rule-table { width: 100%; border-collapse: collapse; font-size: 13px; margin: 8px 0; }
.rule-table th,
.rule-table td { padding: 4px 8px; text-align: left; }
.rule-table th { border-bottom: var(--border-width, 1px) solid var(--card-border, #eee); }

/* Output you did not write: a tool's answer, a raw report. Preformatted,
   scrollable, and it must not push the page sideways. */
.output {
  white-space: pre-wrap;
  word-break: break-all;
  background: var(--hover-background, #f5f5f5);
  padding: 10px;
  margin-top: 6px;
  font-size: 12px;
  max-height: 400px;
  overflow-y: auto;
  border-radius: var(--border-radius, 6px);
}

.data-table td:last-child,
.data-table th:last-child {
  text-align: right;
}

.data-table tbody tr:nth-child(odd) {
  background: var(--hover-background);
}

/* A button that reads as a link. For a row action — Share, Remove, Delete —
   where a filled button would shout, and where the thing being acted on is the
   row rather than the page. */
/* A button that sits inside a sentence, so it has to look like the links
   beside it — .link-text above. It was --text-secondary at a fixed 13px with
   no underline, which inside prose is a slightly grey word: "the secret was
   shown once and is stored hashed — replace it to get a new one" had no
   visible control in it at all.

   Size and colour inherit, so it matches whatever sentence it lands in rather
   than being 13px in a 15px line. */
.link-button {
  background: none;
  border: 0;
  padding: 0;
  font-size: inherit;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  font-family: inherit;
}

.link-button:hover {
  /* background and border, not only colour: `button:hover` above is a more
     specific selector than `.link-button`, so the dark fill it sets outranks
     the `background: none` here and every Delete, Remove and Share in a table
     row went dark-on-dark under the pointer. Same trap the .agent-act group
     documents; this class was the one that got missed. */
  background: none;
  border-color: transparent;
  color: var(--text-primary);
  text-decoration: underline;
}

/* The pin: a star you fill in. One control for "keep this where I can reach
   it" — a service in the sidebar on /services, an app at the top of home on
   /apps. It lived in the /services page's own style block until the second
   page needed it, which is the moment a control stops belonging to a page. */
.pin-btn {
  background: none;
  border: 0;
  padding: 4px;
  width: auto;
  cursor: pointer;
  color: #d0d0d0;
  display: flex;
  align-items: center;
  border-radius: 6px;
}

.pin-btn svg { fill: none; }

.pin-btn:hover {
  color: #888;
  background: #f5f5f5;
  border-color: transparent;
}

.pin-btn.pinned { color: #c79a2e; }
.pin-btn.pinned svg { fill: currentColor; }
.pin-btn.pinned:hover { color: #a87f1f; }

/* The line under the heading on /login and /signup.
   The landing makes a specific promise — one endpoint, every tool — and the
   forms used to be a username, a password and the word "Signup", which could
   belong to any product. Someone who came for tools for agents should still be
   able to see what they are signing up for at the moment they do it. */
.auth-lede {
  max-width: 30rem;
  margin: 0 auto 18px;
  text-align: center;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-secondary, #666);
}

.auth-foot {
  text-align: center;
  margin-top: 6px;
  font-size: 13px;
}

.link-button.danger {
  color: var(--btn-danger);
}

/* Button styles */
/* Button variants */
a.btn-primary, .btn-primary {
  background: var(--btn-primary, #000);
  color: #fff !important;
  border-color: var(--btn-primary, #000);
}

a.btn-primary:hover, .btn-primary:hover {
  background: var(--btn-primary-hover, #333);
  border-color: var(--btn-primary-hover, #333);
  color: #fff !important;
}
a.btn-secondary, .btn-secondary {
  background: var(--hover-background, #eee);
  color: var(--text-primary, #333) !important;
  border-color: var(--hover-background, #eee);
}

a.btn-secondary:hover, .btn-secondary:hover {
  background: #ddd;
  text-decoration: none;
}

/* Iframe container with aspect ratio */
.iframe-container {
  position: relative;
  padding-bottom: 56.25%;
  height: 0;
  overflow: hidden;
  max-width: 100%;
  margin: 15px 0;
}

.iframe-container iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
/* Additional utilities */
.rounded {
  border-radius: var(--border-radius, 6px);
}
.my-5 { margin-top: 20px; margin-bottom: 20px; }
.mx-2 { margin-left: 8px; margin-right: 8px; }

/* Blog form styles */
.blog-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.blog-form input,
.blog-form textarea,
.blog-form select {
  padding: 10px;
  font-size: 14px;
  border: 1px solid #ccc;
  border-radius: 5px;
  box-sizing: border-box;
}

.blog-form textarea {
  font-family: 'Nunito Sans', serif;
  resize: vertical;
  min-height: 150px;
}

.blog-form select {
  background-color: white;
  cursor: pointer;
}

.blog-form-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.blog-form-actions {
  display: flex;
  gap: 10px;
}

.blog-form-hint {
  font-size: 12px;
  color: #666;
}

/* Badge variant for private */
.badge-private {
  background-color: #d9534f;
  color: white;
}

/* Code/pre blocks */
.code-block {
  background: #f5f5f5;
  padding: 15px;
  border-radius: 5px;
  overflow-x: auto;
  font-size: 12px;
  line-height: 1.5;
}

.code-block-sm {
  background: #f5f5f5;
  padding: 10px;
  border-radius: 3px;
  overflow-x: auto;
  font-size: 11px;
  line-height: 1.4;
}

/* Mail compose form */
.mail-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.mail-form input,
.mail-form textarea {
  padding: 10px;
  font-size: 14px;
  border: 1px solid #ccc;
  border-radius: 5px;
  box-sizing: border-box;
}

.mail-form textarea {
  font-family: 'Nunito Sans', serif;
  resize: vertical;
  min-height: 200px;
}

.mail-reply-box {
  padding: 15px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-family: 'Nunito Sans', serif;
  font-size: inherit;
  min-height: 100px;
  outline: none;
  background: white;
}

.mr-1 { margin-right: 4px; }
.py-2 {
  padding-top: 8px;
  padding-bottom: 8px;
}
.pt-3 { padding-top: 10px; }
.ml-2 {
  margin-left: 8px;
}

/* Mail thread preview */
.mail-thread-item {
  margin-bottom: 4px;
}

.mail-thread-subject {
  font-size: 16px;
  font-weight: bold;
}

.mail-thread-meta {
  color: #666;
  font-size: 14px;
  margin-bottom: 4px;
}

.mail-thread-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* Filtered mail: what you can do about it, under what it is.
   Separated by a rule so the buttons read as a footer to the card rather than
   as part of the message — they had no rule at all, which is why they stacked
   wherever they happened to be written. */
.spam-actions {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(128, 128, 128, .18);
}

.mail-thread-preview {
  color: #999;
  font-size: 13px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mail-thread-time {
  color: #888;
  font-size: 12px;
  margin-left: 10px;
  flex-shrink: 0;
}
/* Unread indicator */
.unread-dot {
  color: var(--text-primary);
  font-weight: bold;
}

/* ========================================
   CARD SYSTEM
   Reusable card components for all data types
   ======================================== */

/* Base card */
.card {
  max-width: 750px;
  box-sizing: border-box;
  display: block;
  position: relative;
  overflow-wrap: anywhere;
  min-width: 0;
  border: 1px solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
  padding: 16px;
  margin-bottom: 12px;
  padding-bottom: var(--spacing-lg);
  background: var(--card-background, #fff);
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.15s;
}
.card:hover {
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}

/* Card elements */
.card-title {
  font-weight: 600;
  font-size: 15px;
  color: var(--text-primary, #1a1a1a);
  text-decoration: none;
  display: block;
  margin-bottom: 6px;
}
.card-title:hover {
  color: var(--accent-color, #000);
}
.card-desc, .card-preview {
  font-size: 14px;
  color: var(--text-secondary, #555);
  line-height: 1.5;
  margin-bottom: 8px;
}
.card-meta {
  font-size: 12px;
  color: var(--text-muted, #888);
}
.card-tags .tag {
  padding: 2px 8px;
  background: var(--tag-background, #f0f0f0);
  border-radius: 10px;
  font-size: 11px;
  color: var(--text-secondary, #666);
}
.card-content {
  font-size: 14px;
  color: var(--text-secondary, #555);
  line-height: 1.5;
  white-space: pre-wrap;
}
.card-video .card-body {
  padding: 12px;
}
.card-grid .card {
  margin-bottom: 0;
  max-width: none;
}
.card-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.card-list .card {
  margin-bottom: 0;
}
.card-row .card {
  margin-bottom: 0;
}

/* ========================================
   PAGE LAYOUT
   Standard page structure components
   ======================================== */

.page-action {
  margin-bottom: 16px;
}

.page-filters {
  margin-bottom: 16px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

.page-filters .tag {
  padding: 4px 12px;
  background: var(--tag-background, #f0f0f0);
  border-radius: 20px;
  text-decoration: none;
  color: var(--text-secondary, #333);
  font-size: 13px;
}

.page-filters .tag.active {
  background: var(--accent-color, #000);
  color: white;
}

.page-filters .tag.clear {
  background: var(--hover-background, #ddd);
}
.mail-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--card-border, #e0e0e0);
  margin-bottom: 20px;
}
.mail-tab {
  padding: 10px 20px;
  text-decoration: none;
  color: var(--text-muted, #666);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.mail-tab:hover {
  color: var(--text-primary, #333);
}
.mail-tab.active {
  color: var(--text-primary, #333);
  border-bottom-color: var(--text-primary, #333);
}

/* Note editor */
.note-editor {
  max-width: 600px;
}
.note-editor input[type="text"] {
  width: 100%;
  padding: 8px 0;
  border: none;
  border-bottom: 1px solid #eee;
  font-size: 18px;
  font-weight: 500;
  margin-bottom: 8px;
  outline: none;
}
.note-editor input[type="text"]:focus {
  border-bottom-color: var(--accent-color, #000);
}
.note-editor input[type="text"]::placeholder {
  color: #aaa;
  font-weight: normal;
}
.note-editor textarea {
  width: 100%;
  min-height: 200px;
  padding: 8px 0;
  border: none;
  font-size: 15px;
  font-family: inherit;
  line-height: 1.6;
  resize: none;
  outline: none;
}
.note-editor textarea::placeholder {
  color: #aaa;
}
.note-actions {
  display: flex;
  gap: 15px;
  align-items: center;
  padding-top: 16px;
  border-top: 1px solid #eee;
  margin-top: 16px;
}
.note-actions a {
  color: #666;
  text-decoration: none;
  font-size: 14px;
}
.note-actions .delete-link {
  color: #c00;
}
#autosave-status {
  font-size: 13px;
  margin-left: auto;
}
.error {
  color: #c00;
  padding: 10px;
  background: #fee;
  border-radius: 6px;
  margin-bottom: 15px;
}

/* Form groups */
.form-group {
  margin-bottom: 15px;
}
.form-group label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}
.form-group input[type="text"],
.form-group textarea {
  width: 100%;
  padding: 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  box-sizing: border-box;
  font-family: inherit;
  font-size: 16px;
}
.form-group textarea {
  min-height: 120px;
}
.hint {
  font-size: 13px;
  color: #666;
  margin-top: 5px;
}
/* Card actions */
.card .actions {
  margin-top: 10px;
}
.card .actions a {
  margin-right: 15px;
  font-size: 13px;
}
.card .actions a.delete {
  color: #c00;
}
/* Code editor / preview */
/* Video thumbnails */
.thumbnail {
  position: relative;
  border: var(--border-width) solid var(--card-border);
  border-radius: var(--border-radius);
  padding: var(--item-padding);
  background: var(--card-background);
  margin-bottom: 20px;
}

/* Recent searches */
.recent-searches {
  margin-bottom: 20px;
}
.recent-searches h3 {
  margin-bottom: 10px;
  white-space: normal;
}
.recent-search-item {
  display: inline-block;
  margin: 5px 10px 5px 0;
  padding: 5px 10px;
  background-color: #f0f0f0;
  border-radius: 5px;
  text-decoration: none;
  color: #333;
  cursor: pointer;
  white-space: nowrap;
}
.recent-search-item:hover {
  background-color: #e0e0e0;
}
.recent-search-item.active,
.recent-search-item.active:visited {
  background-color: #333;
  color: white;
}
.recent-search-item.active .recent-search-close {
  color: #ccc;
}
.recent-search-item.active .recent-search-close:hover,
.recent-search-item.active:visited .recent-search-close:hover {
  color: white;
}
.recent-search-label {
  margin-right: 8px;
}
.recent-search-close {
  display: inline-block;
  padding: 0 6px;
  color: #666;
  cursor: pointer;
  font-weight: bold;
}
.recent-search-close:hover {
  color: #000;
}
#send-section input[type="number"] {
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.btn-success {
  background: #22c55e;
  border-color: var(--btn-success);
  color: white;
}

/* =============================================
   Admin Styles
   ============================================= */

.admin-links {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 400px;
}
.admin-links a {
  padding: 12px 16px;
  background: var(--card-background, #fff);
  border: 1px solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
  text-decoration: none;
  color: var(--text-primary, #333);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.admin-links a:hover {
  background: var(--hover-background, #fafafa);
}
.admin-links .count {
  color: var(--text-muted, #888);
  font-size: 14px;
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
}
.admin-table th {
  text-align: left;
  padding: 10px;
  border-bottom: 2px solid #ddd;
}
.admin-table td {
  padding: 10px;
  border-bottom: 1px solid #eee;
}
.admin-table .center {
  text-align: center;
}
@media only screen and (max-width: 600px) {
  .admin-table {
    font-size: 0.85em;
  }
  .admin-table th, .admin-table td {
    padding: 5px 3px;
  }
  .admin-table .created-col {
    display: none;
  }
  .admin-table .delete-btn {
    padding: 3px 6px !important;
    font-size: 0.8em !important;
  }
}

/* Blocklist */
.blocklist-section {
  margin: 20px 0;
}
.blacklist-table {
  width: 100%;
  border-collapse: collapse;
  margin: 10px 0;
}
.blacklist-table th {
  text-align: left;
  padding: 10px;
  border-bottom: 2px solid #ddd;
}
.blacklist-table td {
  padding: 10px;
  border-bottom: 1px solid #eee;
}
.block-form {
  margin: 20px 0;
  padding: 15px;
  background: #f9f9f9;
  border-radius: 5px;
}
.block-form form {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.block-form input[type="text"] {
  padding: 8px;
  width: 300px;
  max-width: 100%;
  border: 1px solid #ccc;
  border-radius: 5px;
  font-size: 14px;
  flex: 1;
  min-width: 200px;
}

/* Email log table */
.email-log {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.email-log th {
  text-align: left;
  padding: 8px;
  border-bottom: 2px solid #ddd;
}
.email-log td {
  padding: 8px;
  border-bottom: 1px solid #eee;
  vertical-align: top;
}
.email-log .dir-in {
  color: #22c55e;
}
.email-log .dir-out {
  color: #3b82f6;
}
.email-log .dir-int {
  color: #666;
}
.email-log .subject {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.email-log .addr {
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: monospace;
  font-size: 12px;
}
@media (max-width: 600px) {
  .email-log {
    font-size: 12px;
  }
  .email-log th, .email-log td {
    padding: 6px 4px;
  }
  .email-log .hide-mobile {
    display: none;
  }
  .email-log .subject {
    max-width: 120px;
  }
  .email-log .addr {
    max-width: 80px;
    font-size: 11px;
  }
}

/* =============================================
   Agent Styles
   ============================================= */

/* =============================================
   Status Page Styles
   ============================================= */

.status-page {
  max-width: 600px;
}
.status-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 30px;
}
.status-ok {
  color: #4caf50;
}
.status-error {
  color: #f44336;
}
.status-section {
  margin-bottom: 30px;
}
.status-section h3 {
  border-bottom: 1px solid #eee;
  padding-bottom: 10px;
  margin-bottom: 15px;
}
.status-item {
  display: flex;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid #f5f5f5;
}
.status-item:last-child {
  border-bottom: none;
}
.status-name {
  font-weight: 500;
}
.status-value {
  display: flex;
  align-items: center;
  gap: 8px;
}
.status-icon {
  font-size: 16px;
}
.status-details {
  color: #666;
  font-size: 13px;
}
.system-info {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 15px;
}
.system-info-item {
  background: #f9f9f9;
  padding: 15px;
  border-radius: 8px;
}
.system-info-label {
  font-size: 12px;
  color: #666;
  text-transform: uppercase;
}
.system-info-value {
  font-size: 18px;
  font-weight: 600;
  margin-top: 5px;
}
.preview-frame {
  width: 100%;
  height: 400px;
  border: none;
  border-radius: 4px;
  margin-top: 20px;
  display: block;
}
.history {
  margin-top: 15px;
  font-size: 13px;
  color: #666;
}
.history ul {
  margin: 5px 0 0 20px;
  padding: 0;
}
.history li {
  margin: 3px 0;
}
.code-toggle {
  margin-top: 15px;
}
.code-toggle summary {
  cursor: pointer;
  color: #666;
  font-size: 13px;
}
.code-editor {
  font-family: monospace;
  font-size: 12px;
  min-height: 300px;
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  margin-top: 10px;
  box-sizing: border-box;
}

.app-frame {
  width: 100%;
  height: 500px;
  border: 1px solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
  background: white;
}
.widget-btn.add {
  background: var(--btn-primary, #000);
  color: white;
}
.widget-btn.remove {
  background: #eee;
  color: #333;
}
/* =============================================
   Docs Styles
   ============================================= */

.docs-content img {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  margin: 10px 0;
}
/* =============================================
   Video Player Embed
   ============================================= */

.video-player-body {
  margin: 0;
  padding: 0;
  background: #000;
  overflow: hidden;
  height: 100vh;   /* fallback */
  height: 100dvh;  /* mobile-safe: excludes the browser toolbars so the bar stays on-screen */
  display: flex;
  flex-direction: column;
}
.video-embed {
  position: relative;
  width: 100%;
  flex: 1;
  min-height: 0;
}
.video-embed iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: none;
}
.video-embed.audio-only iframe {
  clip-path: inset(100%);
  pointer-events: none;
}
.video-bar {
  height: 48px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 16px;
  background: #111;
}
.video-bar button {
  background: rgba(255,255,255,0.1);
  color: #fff;
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 6px;
  padding: 8px 16px;
  font-size: 14px;
  cursor: pointer;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.video-bar button:active {
  background: rgba(255,255,255,0.25);
}
.video-bar #playBtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 50%;
  font-size: 16px;
  line-height: 1;
}
.video-bar span {
  color: rgba(255,255,255,0.6);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
.audio-vis {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #000;
  align-items: center;
  justify-content: center;
  gap: 6px;
  z-index: 10;
}
.audio-vis span {
  display: inline-block;
  width: 8px;
  background: #fff;
  border-radius: 4px;
  animation: audiovis 1s ease-in-out infinite alternate;
}
.audio-vis span:nth-child(1){ height:20px; animation-delay:0s; }
.audio-vis span:nth-child(2){ height:35px; animation-delay:.2s; }
.audio-vis span:nth-child(3){ height:50px; animation-delay:.4s; }
.audio-vis span:nth-child(4){ height:35px; animation-delay:.6s; }
.audio-vis span:nth-child(5){ height:20px; animation-delay:.8s; }
@keyframes audiovis {
  from { transform: scaleY(1); }
  to   { transform: scaleY(3); }
}
@media (max-width: 700px) {
  .pricing-grid {
    grid-template-columns: 1fr;
  }
}
.pricing-grid .card {
  margin-bottom: 0;
}
/* Toast notifications */
.mu-toast {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  padding: 12px 40px 12px 16px;
  border-radius: 8px;
  font-size: 14px;
  z-index: 10000;
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  animation: toastIn 0.3s ease;
  max-width: 90%;
}
.mu-toast-close {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  cursor: pointer;
  font-size: 18px;
  opacity: 0.7;
}

.mu-toast-close:hover {
  opacity: 1;
}

.mu-toast-hide {
  animation: toastOut 0.3s ease forwards;
}

@keyframes toastIn {
  from { opacity: 0; transform: translateX(-50%) translateY(-20px); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

@keyframes toastOut {
  from { opacity: 1; transform: translateX(-50%) translateY(0); }
  to { opacity: 0; transform: translateX(-50%) translateY(-20px); }
}

/* ========================================
   MARKETS PAGE
   ======================================== */
.markets-page {
  max-width: 750px;
}

.markets-page .description {
  margin-bottom: 20px;
  color: var(--text-muted);
  font-size: 0.85em;
}

.markets-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.fx-form {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.fx-form input {
  width: auto;
  display: inline-block;
  margin: 0;
}

.fx-amount {
  max-width: 110px;
}

/* Wider than the text box it replaced, because a select spends part of its
   width on the arrow and 80px cropped five-letter codes behind it. */
.fx-code {
  max-width: 110px;
}

.fx-date {
  max-width: 160px;
}

.fx-in {
  color: var(--text-secondary);
}

.fx-result {
  margin-bottom: 20px;
}

.fx-answer {
  font-size: 1.8em;
  font-weight: 700;
  line-height: 1.2;
}

.markets-tab {
  display: inline-block;
  color: var(--accent-color) !important;
  font-size: 10px !important;
  font-weight: bold !important;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: transparent;
  padding: 0;
  border: none;
  text-decoration: none;
  margin-right: 8px;
  transition: color var(--transition-fast);
}

.markets-tab:hover {
  text-decoration: underline;
}

.markets-tab.active {
  text-decoration: underline;
}
.market-card .market-symbol {
  font-size: 0.85em;
  font-weight: var(--font-weight-bold);
  color: var(--text-primary);
  letter-spacing: 0.05em;
}
.market-card .market-price {
  font-size: 0.9em;
  font-weight: var(--font-weight-semibold);
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* Markets table */
.markets-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 20px;
  font-size: 0.9em;
}

.markets-table th {
  text-align: left;
  padding: 8px 12px;
  font-size: 0.75em;
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  border-bottom: var(--border-width) solid var(--border-color);
}

.markets-table td {
  padding: 10px 12px;
  border-bottom: var(--border-width) solid var(--border-color);
  font-variant-numeric: tabular-nums;
}

.markets-table tr:last-child td {
  border-bottom: none;
}

.markets-symbol {
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.05em;
}

/* The company behind a ticker, where there is one. Secondary to the symbol —
   it explains the row, it is not the row. */
.markets-name {
  font-weight: var(--font-weight-normal);
  letter-spacing: normal;
  color: var(--text-muted);
  font-size: 0.85em;
}

.markets-price {
  font-weight: var(--font-weight-semibold);
}

.markets-change {
  font-weight: var(--font-weight-semibold);
}

.markets-change-up {
  color: var(--success-color, #28a745);
}

.markets-change-down {
  color: var(--error-color, #dc3545);
}

.markets-change-neutral {
  color: var(--text-muted);
}

.markets-chart-link {
  font-size: 0.8em;
  color: var(--accent-color) !important;
  text-decoration: none;
  white-space: nowrap;
}

.markets-chart-link:hover {
  text-decoration: underline;
}

.markets-footer {
  margin-top: 20px;
  padding-top: 12px;
  border-top: 1px solid var(--border-color);
  color: var(--text-muted);
  font-size: 0.8em;
}

.markets-source {
  margin-bottom: 5px;
}

.markets-note {
  margin-top: 5px;
  font-style: italic;
}

@media (max-width: 768px) {
  .markets-grid {
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: 12px;
  }
  .markets-table {
    font-size: 0.8em;
  }
  .markets-table th,
  .markets-table td {
    padding: 8px 6px;
  }
}

/* Places page */
.places-page {
  max-width: 100%;
}
.places-location-row {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 0;
}

.places-location-row input[type="text"] {
  flex: 1;
  min-width: 180px;
  margin-bottom: 0;
}

.places-options-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.places-options-row select {
  flex: 1;
  min-width: 140px;
  margin-bottom: 0;
}

.places-actions-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 12px;
}

.places-actions-row button {
  flex: 1;
}

.places-forms {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-bottom: 16px;
}

@media (max-width: 768px) {
  .places-forms {
    grid-template-columns: 1fr;
  }
  .places-location-row {
    flex-direction: column;
    align-items: stretch;
  }
  .places-location-row input[type="text"] {
    min-width: unset;
    margin-bottom: 8px;
  }
  .places-options-row {
    flex-direction: column;
  }
  .places-options-row select {
    min-width: unset;
  }
}

.places-forms .card {
  margin: 0;
}

.places-forms input,
.places-forms select {
  width: 100%;
  margin-bottom: 8px;
}

.places-results {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
  margin-top: 16px;
}

.place-card {
  margin: 0;
}

.place-card h4 {
  margin: 0 0 6px 0;
  font-size: 1em;
}

.place-category {
  display: inline-block;
  background: var(--accent-color);
  color: #fff;
  font-size: 0.75em;
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 6px;
  vertical-align: middle;
  text-transform: capitalize;
}

.place-address {
  font-size: 0.85em;
  margin: 4px 0 0;
}

.cost-badge {
  display: inline-block;
  background: var(--text-secondary);
  color: #fff;
  font-size: 0.7em;
  padding: 1px 5px;
  border-radius: 3px;
  margin-left: 4px;
  vertical-align: middle;
}

/* Places city grid */
.city-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 20px;
}

.city-link {
  display: inline-block;
  padding: 6px 12px;
  background: var(--bg-secondary, #f5f5f5);
  border-radius: var(--border-radius, 6px);
  text-decoration: none;
  color: inherit;
  font-size: 0.9em;
  border: 1px solid var(--border-color, #ddd);
  transition: background 0.15s;
}

.city-link:hover,
.city-link:visited:hover {
  background: var(--accent-color);
  color: #fff;
  border-color: var(--accent-color);
}

.places-form-desc {
  margin-top: 0;
  font-size: 0.85em;
}

.type-filter-btn {
  margin: 5px;
}
.weather-current {
  display: inline-block;
  margin-bottom: 20px;
  min-width: 180px;
}

.weather-temp {
  font-size: 3em;
  font-weight: 700;
  line-height: 1;
}

.weather-desc {
  font-size: 1.1em;
  color: var(--text-secondary);
  margin-top: 4px;
}
@media (max-width: 600px) {
  .weather-controls {
    flex-direction: column;
    align-items: stretch;
  }

  .weather-search-form {
    width: 100%;
  }
}

/* =============================================
   Admin Mobile Styles
   ============================================= */

/* Deploy controls */
#deploy-controls {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

/* Spam filter settings table */
.spam-settings table {
  width: 100%;
}
.spam-settings td {
  padding: 8px 6px;
  vertical-align: middle;
}
.spam-section {
  margin-top: 24px;
}

/* Blacklist tables - action column */
.blacklist-table td.text-center,
.blacklist-table th.text-center {
  white-space: nowrap;
}

@media (max-width: 600px) {
  /* Block forms: stack input and button vertically with margin */
  .block-form form {
    flex-direction: column;
  }
  .block-form input[type="text"] {
    width: 100%;
    min-width: 0;
  }
  .block-form button {
    align-self: flex-start;
    margin-top: 4px;
  }

  /* Spam filter settings: stack each row */
  .spam-settings table,
  .spam-settings thead,
  .spam-settings tbody,
  .spam-settings tr,
  .spam-settings td {
    display: block;
    width: 100%;
  }
  .spam-settings tr {
    padding: 10px 0;
    border-bottom: 1px solid #eee;
  }
  .spam-settings td {
    padding: 2px 0;
  }
  .spam-settings td form {
    margin-top: 4px;
  }
  .spam-settings td input[type="number"] {
    width: 60px;
  }

  /* Blacklist / spam tables: allow horizontal scroll */
  .blacklist-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .blacklist-table th,
  .blacklist-table td {
    padding: 8px 6px;
  }

  /* Deploy controls: full-width buttons */
  #deploy-controls {
    flex-direction: column;
  }
  #deploy-controls button {
    width: 100%;
  }

  /* Status page: system info single column */
  .system-info {
    grid-template-columns: 1fr;
  }
}

/* ============================================
   DISPLAY / KIOSK MODE
   Activated via ?mode=display on /home
   Hides nav, header, footer for wall-mounted displays
   ============================================ */
body.display-mode #head,
body.display-mode #nav-container,
body.display-mode #nav-overlay,
body.display-mode #footer,
body.display-mode #menu-toggle,
body.display-mode #page-title,
body.display-mode #head-inbox {
  display: none !important;
}

body.display-mode #container {
  margin: 0;
  padding: 0;
  max-width: 100%;
}

body.display-mode #content {
  margin: 0;
  padding: 16px;
  max-width: 100%;
}

body.display-mode #home {
  gap: 16px;
}

body.display-mode .card {
  font-size: 15px;
}

body.display-mode .card h4 {
  font-size: 16px;
}
@keyframes typingBounce {
  0%, 60%, 100% { opacity: 0.3; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-4px); }
}

/* Console prompt mobile optimisation */
#console-prompt {
  max-width: 100%;
  box-sizing: border-box;
}
#console-input {
  min-height: 44px;
}
#console-response {
  overflow-x: auto;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}
#console-response pre {
  overflow-x: auto;
  max-width: 100%;
}
@media (max-width: 480px) {
  #console-prompt {
    padding-top: 12px !important;
  }
  #console-input {
    font-size: 15px !important;
    padding: 12px 40px 12px 12px !important;
  }
  #console-response {
    padding: 12px !important;
    font-size: 14px;
  }
}

/* Endpoint reference with a sticky index rail (/mcp, /api). On desktop the
   index sits to the left and follows the scroll; on mobile it is hidden and the
   cards stack normally. */
#content:has(.ep-layout) { max-width: none; }
#content:has(.ep-layout) .card { max-width: none; }

.ep-layout { display: flex; gap: 32px; align-items: flex-start; }
.ep-main { flex: 1 1 auto; min-width: 0; }
/* Clear any top overlay so an anchored card's header isn't hidden. */
.ep-main .card { scroll-margin-top: 80px; position: relative; }
.ep-nav {
  position: sticky; top: 16px; flex: 0 0 240px;
  max-height: calc(100vh - 32px); overflow-y: auto;
  font-size: 13px; padding-right: 14px; border-right: 1px solid #ececec;
}
.ep-nav-title { font-weight: 600; color: #999; text-transform: uppercase;
  letter-spacing: .05em; font-size: 11px; margin: 4px 0 8px 8px; }
.ep-nav a { display: flex; align-items: baseline; gap: 8px;
  padding: 5px 8px; color: #555; text-decoration: none; border-radius: 5px;
  line-height: 1.35; }
.ep-nav a:hover { background: #f4f4f5; color: #111; }
.ep-nav .ep-path { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ep-nav .ep-price { margin-left: auto; padding-left: 6px; color: #6b7280;
  font-variant-numeric: tabular-nums; font-size: 12px; }
.ep-nav .ep-method { flex: 0 0 auto; min-width: 32px; color: #9ca3af;
  font-size: 10px; font-weight: 700; letter-spacing: .03em; }

/* Per-endpoint price badge, top-right of each card — visible on mobile too,
   where the index rail is hidden. Neutral, not shouty. */
.tool-price { position: absolute; top: 14px; right: 14px; z-index: 1;
  font-size: 12px; color: #6b7280; background: #f4f4f5; border: 1px solid #e5e7eb;
  border-radius:6px; padding: 3px 10px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tool-price b { color: #111; font-weight: 600; }
.tool-price span { color: #9ca3af; }
/* Agent page: match the standard content width so it's as wide as every other page. */
#content:has(.chat-layout) { max-width: 1400px; }

@media (max-width: 900px) {
  .ep-layout { display: block; }
  .ep-nav { display: none; }
}
/* Keep the card title clear of the top-right price badge on narrow cards. */
.ep-main .card .card-title { padding-right: 96px; }

/* A small marker in a card's top-right corner — the next prayer on the Prayer
   card. .card is already position:relative. Empty until filled, so it takes no
   space when there is nothing to show. */
/* The next prayer, in the corner of its card.
   It shares that corner with the title's "?", which floats right — so the two
   sat on top of each other and the time read as nonsense under a circle. The
   offset is the card's own padding plus the circle (16px and a border either
   side) plus a gap, so it lands to the left of it rather than under it.
   Only the prayer card uses this, which is why the offset can assume the "?"
   is there: it always is. */
.card-corner {
  position: absolute;
  top: 14px;
  right: calc(var(--item-padding, 16px) + 26px);
  z-index: 1;
  font-size: 12px;
  color: #6b7280;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.card-corner:empty { display: none; }

/* ========================================
   PRAYER PAGE — reflection main, prayer times aside
   ======================================== */
/* Prayer times are a short, glanceable table; at full width the rows stretched
   across the page and the verse — the reason most people open the page — was
   pushed below the fold. Reminder content leads, prayer times sit beside it.
   The aside comes first in the DOM so that on a phone, where the columns
   stack, the times are what you land on. */
.prayer-layout { display: flex; gap: 28px; align-items: flex-start; }
.prayer-main { flex: 1 1 auto; min-width: 0; order: 1; }
.prayer-side { flex: 0 0 300px; order: 2; position: sticky; top: 16px; }
.prayer-side .card { max-width: none; margin-bottom: var(--spacing-md); }
.prayer-side table { font-variant-numeric: tabular-nums; }

@media only screen and (max-width: 900px) {
  .prayer-layout { display: block; }
  .prayer-side { position: static; }
}
/* A soft navigation is fast but not instant, so say something is happening
   without moving anything: the old content dims for as long as the next page
   takes. A spinner would be a bigger lie about the wait than this is. */
#content[data-loading] { opacity: .55; transition: opacity .12s ease-in; }

/* --- Shared primitives ----------------------------------------------------

   The shapes that were being redrawn once per page. See
   internal/app/primitives.go for why these are here rather than in another
   <style> block: the tokens above were never the missing piece, a component
   small enough to reach for was.

   Everything below is written in tokens, so the palette reaches the pages that
   use it — which is the only thing that makes it a palette. */

/* Square-ish, like every other control.

   This was 999px, and so was every shape hand-drawn to look like it — the
   notification button, the app tabs, the mail tag filter, the token scope
   chips. Meanwhile buttons, inputs, cards and .btn are all --border-radius,
   which is 6px. Two shape languages on one page, and the lozenge one turned up
   wherever somebody built a control that was not a <button>. One radius now:
   anything that wants to look like a control gets the control's shape. */
.pill {
  display: inline-block;
  border: var(--border-width, 1px) solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
  padding: 2px 9px;
  font-size: 11px;
  line-height: 1.55;
  color: var(--text-muted, #888);
  white-space: nowrap;
  flex: none;
}

a.pill:visited { color: var(--text-muted, #888) }

/* A pill that does something is a touch larger, because it has to be hit with
   a thumb. Buttons carry font:inherit because a <button> otherwise arrives
   with the browser's own face and is the one control on the page in a
   different typeface. */
a.pill,
a.pill:visited,
button.pill {
  font: inherit;
  font-size: 12px;
  padding: 3px 11px;
  background: none;
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--transition-fast, .15s ease), color var(--transition-fast, .15s ease);
}

a.pill:hover,
button.pill:hover {
  border-color: #ddd;
  color: var(--text-primary, #1a1a1a);
}

/* :visited spelled out, or the global a:visited:not(.btn) — 0-2-1 — outranks
   .pill.on at 0-2-0 and the selected pill goes black on black the moment it has
   been clicked, which for the selected one is always. Third time this rule has
   caught something; anything drawing a filled control needs its visited state
   named here rather than left to specificity. */
.pill.on,
.pill.on:visited,
.pill.on:hover {
  background: var(--accent-color, #000);
  border-color: var(--accent-color, #000);
  color: #fff;
}

/* Destructive, and only on hover: a Delete sitting permanently in red reads as
   an alarm about the page rather than a thing you may do to it. */
.pill-danger:hover {
  border-color: #e6b3b3;
  color: var(--btn-danger, #c00);
}

.actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-sm, 8px);
  margin: 0 0 var(--spacing-md, 16px);
  padding-bottom: 10px;
  border-bottom: var(--border-width, 1px) solid var(--divider, #f0f0f0);
  font-size: 13px;
}

.actions-back { min-width: 0 }
.actions-back p { margin: 0 }
.actions-set { display: flex; align-items: center; gap: 6px; flex: none }
.actions-set form { display: inline; margin: 0 }

/* --- Inbox ----------------------------------------------------------------

   Four <style> blocks lived in inbox/ — one per file — with sixty-two literal
   colours between them and not one token. That is why /inbox looked like a
   different site: not because it was styled badly, because it was styled
   separately.

   The pill shapes it drew four ways are gone; it uses .pill above. What is left
   here is the part that is genuinely only true of a mailbox. */

.ib { max-width: 760px }

/* The address is the one thing on the page that makes this an agentic inbox
   rather than a list, so it sits above everything and is selectable. */
.ib-addr {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 var(--spacing-md, 16px);
  padding-bottom: 14px;
  border-bottom: var(--border-width, 1px) solid var(--divider, #f0f0f0);
}

.ib-addr code {
  font-size: 13px;
  background: var(--hover-background, #fafafa);
  border: var(--border-width, 1px) solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
  padding: 3px 8px;
}

.ib-addr-note { font-size: 12px; color: var(--text-muted, #888) }
.ib-boxes { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 14px }
.ib-empty { font-size: 14px; color: var(--text-muted, #888); line-height: var(--line-height, 1.6) }

/* A row is the link plus the thing that deletes it. The rule under the row
   moved here, because it belongs to the pair rather than to the link. */
/* The whole row is the target, so the whole row lights up.
   
   Hovering used to underline the subject and nothing else, which says "this
   word is a link" when the thing you are pointing at is a conversation. Every
   mail client highlights the row, because that is the shape of what a click
   selects — and here a row is a link plus a delete cross, so an underline on
   one word of it described a third of the target.
   
   The bleed is padding plus a matching negative margin, so the highlight
   reaches past the text without moving anything. */
.ib-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 0 10px;
  margin: 0 -10px;
  border-radius: var(--border-radius, 6px);
  border-bottom: var(--border-width, 1px) solid var(--divider, #f0f0f0);
}

.ib-item:hover { background: var(--hover-background, #fafafa) }

/* And no underline, which is where the row was actually getting one.
   
   Removing the rule that underlined .ib-subject did nothing visible, because
   the row is an <a> and the global a:hover underlines it — and text-decoration
   inherits, so the whole row lit up: the sender, the subject, the snippet and
   the timestamp. That is what made hovering look like the text was the link
   rather than the row. */
.ib-row:hover { text-decoration: none }

.ib-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex: 1;
  min-width: 0;
  padding: 11px 0;
  text-decoration: none;
  color: inherit;
}

/* Hidden until the row is under the pointer, so twenty crosses are not the
   loudest thing on the page. Not hidden from the keyboard: :focus-within
   brings it back, or it would be a control nothing but a mouse could reach.
   Always shown where there is no pointer to hover with — see the media query
   at the bottom of this file. */
.ib-del { display: flex; align-items: center; flex: none }

.ib-del-go {
  font: inherit;
  font-size: 17px;
  line-height: 1;
  padding: 2px 6px;
  border: none;
  background: none;
  color: var(--text-muted, #888);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--transition-fast, .15s ease), color var(--transition-fast, .15s ease);
}

.ib-item:hover .ib-del-go,
.ib-del-go:focus { opacity: 1 }
.ib-del-go:hover { color: var(--btn-danger, #c00) }


/* Unread is what makes this a mailbox rather than a log: a rule down the left
   and a heavier subject, so the eye finds the two that need answering without
   reading the twenty that do not. */
.ib-row.unseen { border-left: 2px solid var(--accent-color, #000); padding-left: 9px; margin-left: -11px }
/* No pointer to hover with, so the cross is simply there. */
@media (hover: none) { .ib-del-go { opacity: 1 } }

/* On a phone a row is two lines and the cross belongs beside the first of
   them. .ib-item aligns on the baseline, which is right when the row is one
   line and drifts down the card when it is two — so on a narrow screen the
   cross is pinned to the top and nudged to sit on the name's line. */
@media (max-width: 640px) {
  .ib-item { align-items: flex-start }
  .ib-del { padding-top: 12px }
}
.ib-row.unseen .ib-who,
.ib-row.unseen .ib-subject { font-weight: var(--font-weight-bold, 700) }
.ib-row.unseen .ib-snip { color: var(--text-secondary, #555) }

.ib-who {
  flex: 0 0 130px;
  font-size: 13px;
  font-weight: var(--font-weight-medium, 500);
  color: var(--text-primary, #1a1a1a);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ib-mid { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 8px; overflow: hidden }

/* The labels and the subject, together. One box so a phone can stack the
   preview under them without breaking them apart — see the media query. */
.ib-line { display: flex; align-items: baseline; gap: 8px; flex: none; max-width: 60%; min-width: 0; overflow: hidden }

/* An explicit weight, because the row is a link and `a` is bold app-wide.
   Anything inside a link that does not declare a weight inherits that, so the
   subject was bold on every row and .ib-row.unseen had nothing left to say —
   read or unread, the page looked the same, which is the one distinction a
   mailbox exists to draw. .ib-who declares 500 and escaped it; this did not.
   TestAStatefulWeightHasABaseWeight now holds it for every such pair. */
.ib-subject {
  font-size: 14px;
  font-weight: var(--font-weight-normal, 400);
  color: var(--text-primary, #1a1a1a);
  white-space: nowrap;
  flex: none;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ib-snip { font-size: 13px; color: var(--text-muted, #888); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.ib-when { flex: none; font-size: 11px; color: var(--text-muted, #888); white-space: nowrap }

/* A conversation, read. */
.ib-head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px }
.ib-title { font-size: 20px; margin: 0 0 6px }
.ib-started { font-size: 12px; color: var(--text-muted, #888) }
.ib-parties { font-size: 13px; color: var(--text-muted, #888); margin: 0 0 20px }
.ib-trimmed { font-size: 12px; color: var(--text-muted, #888); margin: 0 0 18px }

.ib-note {
  margin-top: var(--spacing-lg, 24px);
  padding-top: 14px;
  border-top: var(--border-width, 1px) solid var(--divider, #f0f0f0);
  font-size: 13px;
  color: var(--text-muted, #888);
}

/* A rule between messages, not a quote bar beside them.
   Each message carried a 2px left border and 16px of margin, which reads as a
   blockquote — the mark for "somebody else said this" — on every message in
   the thread including your own. A thread is a stack of messages and what
   separates them is a line across, the way every mail client draws it: the
   eye needs to know where one ends, not that all of them are quotations. */
.ib-msg { padding: 16px 0; border-top: var(--border-width, 1px) solid var(--divider, #f0f0f0) }
.ib-msg:first-child { border-top: none; padding-top: 0 }
.ib-msg:last-child { padding-bottom: 0 }
.ib-from { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px }
.ib-who-l { font-size: 13px; font-weight: var(--font-weight-medium, 500); color: var(--text-primary, #1a1a1a) }
.ib-at { margin-left: auto; flex: none; font-size: 11px; color: var(--text-muted, #888); white-space: nowrap }
.ib-body { font-size: 14px; line-height: var(--line-height, 1.6) }
.ib-body p:first-child { margin-top: 0 }
.ib-body p:last-child { margin-bottom: 0 }
.ib-typed { white-space: pre-wrap }
.ib-ran { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px }
.ib-failed { font-size: 12px; color: var(--btn-danger, #c00) }

/* The instruction box: telling the agent what to do about what you are
   reading. See inbox/act.go. */
.ib-ask { margin-top: 22px; padding-top: var(--spacing-md, 16px); border-top: var(--border-width, 1px) solid var(--divider, #f0f0f0) }

.ib-ask textarea {
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: 14px;
  padding: 9px 11px;
  border: var(--border-width, 1px) solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
  resize: vertical;
}

.ib-ask textarea:focus { outline: none; border-color: #bbb }
.ib-ask-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; align-items: center }

/* Ask and Send are the plain `button` at the top of this file — the same one
   every form on the site submits with. They were redeclared here at 13px with
   a 999px radius, which is why the inbox looked like a different product from
   the page next to it: it had its own button. */
.ib-ask-note { font-size: 12px; color: var(--text-muted, #888); margin: 9px 0 0 }
.ib-ask-problem { font-size: 13px; color: var(--btn-danger, #c00); margin: 0 0 9px }

/* A run in flight. The button reports that it is working and stops taking
   presses — a POST that redirects on completion looks identical to one that
   did nothing, which is how the same instruction got sent twice. */
.ib-ask button[type=submit][disabled] {
  background: var(--text-muted, #888);
  border-color: var(--text-muted, #888);
  cursor: default;
}

/* Replying, on a mail conversation. See inbox/conversation.go. */
.ib-reply {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 20px;
}

/* Reply is an a.btn like every other call to action on the site. It was drawn
   here instead, as a black pill with color:#fff — and `a:visited { color: #000 }`
   above outranks a plain class, so it went black-on-black once used. a.btn
   carries color:#fff !important for exactly that reason. */
.ib-reply-who { font-size: 12px; color: var(--text-muted, #888) }

/* The inbox on Home. Same conversations, narrower column. */
/* The inbox on Home.
   
   In a card, like everything else on that screen. It was the one block not in
   one — naked rows between bordered cards, which is most of why it read as
   unfinished rather than as a section. */
.inbox-peek {
  border: var(--border-width, 1px) solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
  background: var(--card-background, #fff);
  padding: 4px var(--item-padding, 16px) 12px;
  margin: 0;
}

.peek-row {
  display: block;
  padding: 11px 0;
  text-decoration: none;
  color: inherit;
  border-bottom: var(--border-width, 1px) solid var(--divider, #f0f0f0);
}

.peek-row:last-of-type { border-bottom: 0 }
/* The row, not the title — see .ib-item. */
.peek-row { padding-left: 10px; padding-right: 10px; margin: 0 -10px;
  border-radius: var(--border-radius, 6px) }
.peek-row:hover { background: var(--hover-background, #fafafa); text-decoration: none }
.peek-row.unseen .peek-title { font-weight: var(--font-weight-bold, 700) }
.peek-row.unseen .peek-line { color: var(--text-secondary, #555) }
.peek-head { display: flex; align-items: baseline; gap: 10px }

.peek-title {
  font-size: 14px;
  font-weight: var(--font-weight-medium, 500);
  color: var(--text-primary, #1a1a1a);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.peek-when { font-size: 11px; color: var(--text-muted, #888); margin-left: auto; white-space: nowrap; flex: none }
.peek-line { display: block; font-size: 13px; color: var(--text-muted, #888); margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.peek-who { color: var(--text-secondary, #555); font-weight: var(--font-weight-medium, 500) }

/* The channel, last on the line the eye reads last. It was a pill, which made
   it the loudest thing in the block and usually said "Mail" three times. */
.peek-via { color: var(--text-muted, #888) }
.peek-via::before { content: " · " }

.peek-more { display: inline-block; margin-top: 12px; font-size: 13px; color: var(--text-secondary, #555); text-decoration: none }
.peek-more:hover { color: var(--text-primary, #1a1a1a) }

/* On a phone a row is two lines, not one squeezed into 390px: the name and the
   time on top, the subject and the preview under it — which is what every mail
   client on a phone does, and for the same reason. The preview used to be
   hidden entirely here, so a mobile inbox was a list of subjects with no way to
   tell what any of them said. */
@media (max-width: 640px) {
  .ib-row { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; padding: 12px 0 }
  .ib-who { flex: none; grid-column: 1; font-size: 13px }
  .ib-when { grid-column: 2; grid-row: 1; font-size: 11px }
  .ib-mid { grid-column: 1 / -1; flex-direction: column; align-items: flex-start; gap: 2px }
  /* The labels stay beside the subject; only the preview drops below. There
     was an order:3 here pushing the pills past the preview, which put a
     label — the thing you read to decide whether to read the row — at the
     bottom of the row it labels. */
  .ib-line { max-width: 100%; flex-wrap: wrap; row-gap: 2px }
  .ib-subject { white-space: normal; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical }
  .ib-snip { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-height: 1.45 }
  .ib-addr { gap: 6px }
  .ib-addr-note { font-size: 11px }
}

/* Composing one, with the agent drafting. See inbox/compose.go. */
.ib-from-line { font-size: 13px; color: var(--text-muted, #888); margin: 0 0 14px }
.ib-from-line code { font-size: 13px; background: var(--hover-background, #fafafa); border: var(--border-width, 1px) solid var(--card-border, #e8e8e8); border-radius: var(--border-radius, 6px); padding: 2px 7px }
.ib-compose { display: flex; flex-direction: column; gap: 8px }

.ib-field {
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: 14px;
  padding: 9px 11px;
  border: var(--border-width, 1px) solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
}

textarea.ib-field { resize: vertical; line-height: var(--line-height, 1.6) }
.ib-field:focus { outline: none; border-color: #bbb }

/* Under the message rather than beside it, because it is a way of filling the
   boxes above and reads in the order it is used. */
.ib-draft {
  margin-top: 6px;
  padding: 12px;
  background: var(--hover-background, #fafafa);
  border: var(--border-width, 1px) solid var(--divider, #f0f0f0);
  border-radius: var(--border-radius, 6px);
}

.ib-draft .ib-field { background: var(--card-background, #fff) }

.ib-compose .ib-ask-note { margin: 0 }
.ib-compose-link { margin-left: auto }
.ib-sent { font-size: 13px; color: var(--btn-success, #1a7f37); margin: 0 0 12px }

/* One tool, at an address of its own. See internal/api/tool_page.go. */
.tool-page { max-width: 760px }
.tool-name { font-size: 24px; margin: 0 0 6px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace }
.tool-lead { font-size: 15px; color: var(--text-secondary, #555); margin: 0 0 var(--spacing-md, 16px); line-height: var(--line-height, 1.6) }
.tool-cost, .tool-from { font-size: 13px; color: var(--text-secondary, #555); margin: 0 0 8px }
.tool-h { font-size: 13px; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted, #888); margin: var(--spacing-lg, 24px) 0 10px; font-weight: var(--font-weight-semibold, 600) }
.tool-note { font-size: 13px; color: var(--text-muted, #888); margin: 0 0 10px }
.tool-args { width: 100%; border-collapse: collapse; font-size: 13px }
.tool-args th { text-align: left; font-weight: var(--font-weight-medium, 500); color: var(--text-muted, #888); padding: 4px 8px 6px; border-bottom: var(--border-width, 1px) solid var(--card-border, #e8e8e8) }
.tool-args td { padding: 7px 8px; border-bottom: var(--border-width, 1px) solid var(--divider, #f0f0f0); vertical-align: top }
.tool-args code { font-size: 13px }
.tool-req { color: var(--btn-danger, #c00); margin-left: 2px }

.tool-call {
  background: var(--hover-background, #fafafa);
  border: var(--border-width, 1px) solid var(--divider, #f0f0f0);
  border-radius: var(--border-radius, 6px);
  padding: 10px 12px;
  font-size: 12px;
  overflow-x: auto;
  margin: 0 0 8px;
}

/* A service, derived from its Spec. See internal/api/service_page.go. */
.svc-page { max-width: 760px }
.svc-lead { font-size: 15px; color: var(--text-secondary, #555); margin: 0 0 var(--spacing-md, 16px); line-height: var(--line-height, 1.6) }

/* The card, at the size the page has room for. It is the answer somebody came
   for; everything under it is about how to ask for more. */
.svc-card {
  border: var(--border-width, 1px) solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
  padding: var(--item-padding, 16px);
  margin: 0 0 var(--spacing-lg, 24px);
  background: var(--card-background, #fff);
}

.svc-h { font-size: 13px; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted, #888); margin: var(--spacing-lg, 24px) 0 10px; font-weight: var(--font-weight-semibold, 600) }
.svc-tools { display: flex; flex-direction: column }

.svc-tool {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 11px 0;
  border-bottom: var(--border-width, 1px) solid var(--divider, #f0f0f0);
  text-decoration: none;
  color: inherit;
}

.svc-tool:hover .svc-tool-name { text-decoration: underline }
.svc-tool-name { flex: 0 0 auto; font-size: 13px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--text-primary, #1a1a1a) }
.svc-tool-desc { flex: 1; min-width: 0; font-size: 13px; color: var(--text-muted, #888); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.svc-price, .svc-free { flex: none; font-size: 11px; color: var(--text-muted, #888); white-space: nowrap }
.svc-doors { font-size: 13px; color: var(--text-muted, #888); margin: var(--spacing-lg, 24px) 0 0; line-height: var(--line-height, 1.6) }

/* The way out to the service's own page, from its reference. */
.svc-open { margin: 0 0 var(--spacing-lg, 24px) }

/* Try it: the declared parameters as inputs, on a method card. The call goes
   through /api/v1 like any other. See internal/api/service_ref.go. */
.try {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 12px 0 0;
  padding: 12px 0 0;
  border-top: var(--border-width, 1px) solid var(--divider, #f0f0f0);
}

.try-field { display: flex; align-items: center; gap: 10px }
.try-field > span {
  flex: 0 0 130px;
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--text-muted, #888);
}

.try-field input, .try-field select {
  flex: 1;
  min-width: 0;
  font: inherit;
  font-size: 13px;
  padding: 6px 8px;
  border: var(--border-width, 1px) solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
  background: var(--card-background, #fff);
  color: var(--text-primary, #1a1a1a);
}

.try-actions { display: flex; align-items: center; gap: 12px }
.try-actions .card-meta { margin: 0 }
.try-out { margin: 0; max-height: 320px; overflow: auto; white-space: pre-wrap }

@media (max-width: 640px) {
  .try-field { flex-wrap: wrap; gap: 4px }
  .try-field > span { flex: 1 0 100% }
}

@media (max-width: 640px) {
  .svc-tool { flex-wrap: wrap; gap: 2px 10px }
  .svc-tool-desc { flex: 1 0 100%; white-space: normal }
}

/* Somewhere to go for a person, on a service page whose card needs a session.
   See askTheAgent in internal/api/service_page.go. */
.svc-ask {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0 0 var(--spacing-lg, 24px);
  padding: 12px 14px;
  background: var(--hover-background, #fafafa);
  border: var(--border-width, 1px) solid var(--divider, #f0f0f0);
  border-radius: var(--border-radius, 6px);
}

.svc-ask-lead { flex: 1 0 100%; font-size: 13px; color: var(--text-secondary, #555); margin-bottom: 2px }

/* The hazards card: what has shaken, and how hard. Was a <style> block in
   service/hazards, shared by the card and a page that no longer exists. */
.hq { padding: 8px 0; border-bottom: var(--border-width, 1px) solid var(--divider, #f0f0f0); font-size: 15px; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap }
.hq:last-of-type { border-bottom: 0 }
.hmag { font-variant-numeric: tabular-nums; font-weight: var(--font-weight-semibold, 600); min-width: 3.4em }
.hago { color: var(--text-muted, #888); font-size: 13px; margin-left: auto }
.hmuted { color: var(--text-muted, #888); font-size: 14px; margin: 0 }
.hmore { margin: 12px 0 0; font-size: 14px }
/* The forecast, rendered here rather than in a browser, for somebody whose
   place this instance knows. See service/weather. */
.wx-now { display: flex; align-items: baseline; gap: 8px }
.wx-none { font-size: 13px; color: var(--text-muted, #888); line-height: 1.55; margin: 0 }
.wx-temp { font-size: 22px; font-weight: var(--font-weight-semibold, 600); color: var(--text-primary, #1a1a1a) }
.wx-desc { color: var(--text-secondary, #555) }
.wx-where { font-size: 12px; color: var(--text-muted, #888); margin-top: 2px }
.wx-days { display: flex; gap: 12px; margin-top: 6px; font-size: 12px; color: var(--text-muted, #888) }
.wx-day { white-space: nowrap }

/* The flights card, rendered here for somebody whose place we know. */
.fl-line-row { display: flex; justify-content: space-between; gap: 8px; font-size: 13px; padding: 2px 0 }
.fl-alt { color: var(--text-muted, #888); white-space: nowrap }
.fl-more, .fl-none { display: block; margin-top: 6px; font-size: 13px; color: var(--text-muted, #888); text-decoration: none }

/* --- Sections, fields and buttons ------------------------------------------

   The shapes a settings page is made of, defined once. See
   internal/app/form.go for why these arrived with a page rather than before
   one. Everything is in tokens. */

.note {
  font-size: 13px;
  color: var(--text-muted, #888);
  line-height: var(--line-height, 1.6);
  margin: 6px 0 0;
}

.notice-ok, .notice-bad {
  font-size: 13px;
  padding: 10px 14px;
  border-radius: var(--border-radius, 6px);
  border: var(--border-width, 1px) solid;
  margin: 0 0 var(--spacing-md, 16px);
}

.notice-ok { background: #f2faf4; border-color: #cfe8d6; color: var(--btn-success, #1a7f37) }
.notice-bad { background: #fdf4f4; border-color: #e8cfcf; color: var(--btn-danger, #c00) }

.form { display: flex; flex-direction: column; gap: 10px; margin: 8px 0 0 }
.form-inline { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px }
.form-inline .form-actions { margin: 0 }
.form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px }

.field {
  font: inherit;
  font-size: 14px;
  padding: 8px 11px;
  border: var(--border-width, 1px) solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
  background: var(--card-background, #fff);
  color: var(--text-primary, #1a1a1a);
  max-width: 320px;
  box-sizing: border-box;
}

.field:focus { outline: none; border-color: #bbb }
.field-wide { max-width: 100%; width: 100% }
textarea.field { resize: vertical; line-height: var(--line-height, 1.6); width: 100%; max-width: 100% }
select.field { max-width: 220px }

.field-label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 12px;
  color: var(--text-muted, #888);
}

/* One button, three volumes. The product drew 232 <button> elements against 26
   uses of .btn, so most of them arrived with the browser's own face on. */
.btn {
  display: inline-block;
  font: inherit;
  font-size: 13px;
  line-height: 1.5;
  padding: 7px 18px;
  border-radius:6px;
  border: var(--border-width, 1px) solid var(--btn-primary, #000);
  background: var(--btn-primary, #000);
  color: #fff;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--transition-fast, .15s ease), border-color var(--transition-fast, .15s ease);
}

.btn:hover { background: var(--btn-primary-hover, #333); border-color: var(--btn-primary-hover, #333); color: #fff }

.btn-quiet {
  background: none;
  border-color: var(--card-border, #e8e8e8);
  color: var(--text-secondary, #555);
}

.btn-quiet:hover { background: none; border-color: #ddd; color: var(--text-primary, #1a1a1a) }

.btn-danger {
  background: none;
  border-color: var(--card-border, #e8e8e8);
  color: var(--text-secondary, #555);
}
.btn-danger:hover {
  background: none;
  border-color: #e6b3b3;
  color: var(--btn-danger, #c00);
}

.links { display: flex; flex-direction: column; gap: 7px; font-size: 14px }
.links a { text-decoration: none }

/* The balance, on /account. */
.balance-figure { font-size: 28px; margin: 4px 0 2px }
.balance-figure span { color: var(--text-muted, #888); font-size: 14px }
.balance-links { margin: 10px 0 0; font-size: 14px }
/* The saved coordinates, under the form.
   margin-left:4px was written for a span sitting after something on the same
   line. It is appended after a <form>, which is a block, so it landed hard
   against the Save button with four pixels of left margin and nothing above
   it. It is a caption for the form, so it is a line of its own with room. */
.place-at {
  display: block;
  font-size: 12px;
  color: var(--text-muted, #888);
  margin: 10px 0 0;
}
.signout { margin: 12px 0 0 }

/* About, Privacy and Status at the foot of /account. A line rather than a
   card: they have to be reachable — the footer is not rendered once you are
   signed in — and giving them a titled card put a marketing nav at the same
   weight as the balance. */
.account-legal {
  margin: 24px 0 0;
  font-size: 13px;
  color: var(--text-muted, #888);
}
.account-legal a { font-weight: var(--font-weight-normal, 400); color: var(--text-muted, #888) }
.account-legal a:hover { color: var(--text-primary, #111) }
.link-code code { font-size: 18px; font-weight: var(--font-weight-bold, 700); background: var(--hover-background, #fafafa); border: var(--border-width, 1px) solid var(--card-border, #e8e8e8); border-radius: var(--border-radius, 6px); padding: 4px 12px }

/* Addresses this account has proved, on /account. */
.addr-list { font-size: 14px; margin: 4px 0 0; padding-left: 18px }
.addr-list li { margin: 0 0 4px }
.addr-drop { display: inline; margin: 0 }
.addr-drop .form-actions { display: inline-flex }
.addr-drop .btn { border: 0; background: none; padding: 0 0 0 8px; font-size: 13px }

/* The tile preview on /tiles: a grid of images and no map library, because the
   page is the demonstration and the app somebody builds brings its own. */
.tiles-page { max-width: 760px }
.tiles-styles { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 14px }

.tiles-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0;
  border: var(--border-width, 1px) solid var(--card-border, #e8e8e8);
  border-radius: var(--border-radius, 6px);
  overflow: hidden;
  margin: 0 0 var(--spacing-lg, 24px);
  background: var(--hover-background, #fafafa);
}

.tiles-img, .tiles-blank { display: block; width: 100%; aspect-ratio: 1 / 1 }
.tiles-blank { background: var(--divider, #f0f0f0) }

/* Who a message was from and who it was sent to, in full, under the name.
   The addresses were nowhere: the sender was truncated into a 130px column and
   the recipient was never recorded. See inbox/conversation.go. */
.ib-addrs {
  font-size: 12px;
  color: var(--text-muted, #888);
  margin: 0 0 8px;
  overflow-wrap: anywhere;
  line-height: 1.5;
}

.ib-addr-k { text-transform: uppercase; letter-spacing: .06em; font-size: 10px; margin-right: 3px }
.ib-addr-sep { margin: 0 8px; opacity: .5 }

/* A sender you can read, with the whole address on hover. */
.ib-who[title] { cursor: help }

/* The two addresses at the top of the inbox: yours, and the agent's. It showed
   one and composed as the other. See inbox/page.go. */
.ib-addr-one { display: inline-flex; align-items: baseline; gap: 6px }
.ib-addr-one .ib-addr-k {
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: 10px;
  color: var(--text-muted, #888);
}

/* One text column, one width. See app.Column.

   Pages chose their own — 600, 640, 680, 700, 720, 760, 820 — so the text
   changed width as you walked between them, and /privacy centred itself on top
   of that, which moved it sideways as well. */
.page-col { max-width: 720px }
