/* Personal Dashboard - Stylesheet
 * A polished, calm, "glanceable at 7am" aesthetic
 */

/* CSS Custom Properties - Design System */
:root {
  /* Light theme (default) */
  --bg-primary: #F6F7F9;
  --bg-card: #FFFFFF;
  --text-primary: #1A202C;
  --text-muted: #64748B;
  --border-color: #E2E8F0;

  /* Accent */
  --accent: #14B8A6;
  --accent-hover: #0D9488;

  /* Status */
  --status-up: #22C55E;
  --status-down: #EF4444;
  --status-warning: #F59E0B;

  /* Delta indicators (prices: up is bad, down is good) */
  --delta-increase: #EF4444;
  --delta-decrease: #22C55E;

  /* Spacing */
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;

  /* Border radius */
  --drop-target-bg: rgba(20, 184, 166, 0.08);
  --drop-target-border: var(--accent);
  --palette-bg: #F0F1F4;

  --radius-sm: 6px;
  --radius-md: 12px;
  --radius-lg: 16px;

  /* Shadows */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);

  /* Typography */
  --font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;

  /* Transitions */
  --transition-fast: 150ms ease;
  --transition-normal: 250ms ease;

  /* Tooltips: inverted from the page, so they read as a label floating
     over it rather than another card. */
  --tooltip-bg: #1A202C;
  --tooltip-text: #FFFFFF;
}

/* Dark theme */
[data-theme="dark"] {
  --drop-target-bg: rgba(20, 184, 166, 0.16);
  --palette-bg: #161B22;
  --bg-primary: #0F1420;
  --bg-card: #1A2130;
  --text-primary: #E8ECF4;
  --text-muted: #8B96A8;
  --border-color: #2A3348;
  --tooltip-bg: #E8ECF4;
  --tooltip-text: #1A202C;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -2px rgba(0, 0, 0, 0.2);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -4px rgba(0, 0, 0, 0.2);
}

/* Reset */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* The hidden attribute must actually hide. The browser rule for it is
   display:none, which loses to any class that sets display -- .btn sets
   flex -- so a hidden button was still on screen and still clickable. */
[hidden] {
  display: none !important;
}

/* Base styles */
html {
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  font-family: var(--font-family);
  font-size: var(--font-size-base);
  line-height: 1.5;
  color: var(--text-primary);
  background-color: var(--bg-primary);
  min-height: 100vh;
}

/* Typography */
h1, h2, h3, h4, h5, h6 {
  font-weight: 600;
  line-height: 1.25;
}

a {
  color: var(--accent);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* Focus styles for accessibility */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Header */
.header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border-color);
  padding: var(--space-md) var(--space-lg);
  display: flex;
  align-items: center;
  gap: var(--space-lg);
}

.header__title {
  font-size: var(--font-size-lg);
  font-weight: 600;
  color: var(--text-primary);
}

/* Search Results Dropdown */
.search-results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  max-height: 400px;
  overflow-y: auto;
  z-index: 200;
  margin-top: var(--space-xs);
}

.search-results__empty {
  padding: var(--space-md);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--font-size-sm);
}

.search-results__group {
  padding: var(--space-sm) 0;
}

.search-results__group:not(:last-child) {
  border-bottom: 1px solid var(--border-color);
}

.search-results__header {
  padding: var(--space-xs) var(--space-md);
  font-size: var(--font-size-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

.search-results__item {
  display: block;
  padding: var(--space-sm) var(--space-md);
  text-decoration: none;
  color: var(--text-primary);
  cursor: pointer;
  transition: background-color var(--transition-fast);
}

.search-results__item:hover {
  background: var(--bg-primary);
}

.search-results__title {
  display: block;
  font-weight: 500;
  font-size: var(--font-size-sm);
}

.search-results__snippet {
  display: block;
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  margin-top: 2px;
}

/* Highlight animation for todo scroll-to */
.highlight {
  animation: highlight-pulse 2s ease-out;
}

@keyframes highlight-pulse {
  0% { background-color: var(--accent); }
  100% { background-color: transparent; }
}

.header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* Search input */
.search-input {
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--bg-primary);
  color: var(--text-primary);
  font-size: var(--font-size-sm);
  transition: border-color var(--transition-fast);
}

.search-input:focus {
  border-color: var(--accent);
  outline: none;
}

/* Card grid */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-lg);
  padding: var(--space-lg);
  max-width: 1400px;
  margin: 0 auto;
}

/* A card may span up to the full grid width. --card-span is set inline per
   card; the fallback keeps a card one column wide if it is ever missing. */
.card {
  grid-column: span min(var(--card-span, 1), 3);
}

@media (max-width: 1199px) {
  .card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  /* Spans clamp to the columns that exist, or a wide card overflows the grid
     instead of wrapping. */
  .card {
    grid-column: span min(var(--card-span, 1), 2);
  }
}

@media (max-width: 699px) {
  .card-grid {
    grid-template-columns: 1fr;
  }
  .card {
    grid-column: span 1;
  }
}

/* Widgets sit inside a card and must never widen it. min-width: 0 is the
   load-bearing declaration: grid and flex children default to min-width: auto
   and will otherwise push past their track. */
.widget {
  min-width: 0;
  max-width: 100%;
}

.widget__body > * {
  min-width: 0;
  max-width: 100%;
}

/* Wide content inside a widget scrolls itself rather than the page. */
.widget__body table,
.widget__body pre {
  display: block;
  overflow-x: auto;
}

/* A card holding more than one widget separates them. */
.card .widget + .widget {
  border-top: 1px solid var(--border-color);
}

.widget-footer {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-align: right;
  padding: var(--space-sm) var(--space-md);
}

.markets-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.markets-item {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  background: var(--bg-primary);
  border-radius: var(--radius-sm);
}

.markets-name {
  flex: 1;
  min-width: 0;
  color: var(--text-muted);
  font-size: var(--font-size-sm);
}

.markets-value {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.markets-change {
  font-size: var(--font-size-xs);
  font-variant-numeric: tabular-nums;
}

/* Card */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: box-shadow var(--transition-fast), transform var(--transition-fast);
}

.card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}

.card__header {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md);
  border-bottom: 1px solid var(--border-color);
}

.card__icon {
  width: 20px;
  height: 20px;
  color: var(--accent);
}

.card__title {
  font-size: var(--font-size-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  flex: 1;
}

.card__timestamp {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
}

.card__body {
  padding: var(--space-md);
}

.card__error {
  padding: var(--space-sm) var(--space-md);
  background: rgba(239, 68, 68, 0.1);
  color: var(--status-down);
  font-size: var(--font-size-sm);
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.card__stale {
  padding: var(--space-sm) var(--space-md);
  background: rgba(245, 158, 11, 0.1);
  color: var(--status-warning);
  font-size: var(--font-size-sm);
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border: none;
  border-radius: var(--radius-sm);
  font-size: var(--font-size-sm);
  font-weight: 500;
  cursor: pointer;
  transition: all var(--transition-fast);
}

.btn--primary {
  background: var(--accent);
  color: white;
}

.btn--primary:hover {
  background: var(--accent-hover);
}

.btn--ghost {
  background: transparent;
  color: var(--text-muted);
}

.btn--ghost:hover {
  background: var(--border-color);
  color: var(--text-primary);
}

.btn--icon {
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: var(--radius-sm);
}

/* Tooltips
   A name for an icon-only control, shown beneath it on hover and on keyboard
   focus. Not the browser's title attribute: that takes a second to appear,
   never shows for the keyboard, and cannot be styled. The text is in
   data-tooltip, beside an aria-label carrying the same words — the accessible
   name comes from the label, and a pseudo-element is no part of it. */
[data-tooltip] {
  position: relative;
}

[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  top: calc(100% + var(--space-xs));
  left: 50%;
  transform: translate(-50%, -4px);
  padding: var(--space-xs) var(--space-sm);
  background: var(--tooltip-bg);
  color: var(--tooltip-text);
  font-size: var(--font-size-xs);
  font-weight: 500;
  line-height: 1.3;
  white-space: nowrap;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  z-index: 300;
  /* Hiding: fade out, then stop being rendered once the fade is done. */
  transition: opacity var(--transition-fast), transform var(--transition-fast),
              visibility 0s linear 150ms;
}

[data-tooltip]:hover::after,
[data-tooltip]:focus-visible::after {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  /* Showing: a short pause first, so a pointer crossing the row on its way
     somewhere else does not set every label flickering. */
  transition-delay: 250ms;
}

/* The last icon sits at the page edge, where a centred label would be cut
   off; it hangs left from the icon's right edge instead. */
.header__actions > [data-tooltip]:last-child::after {
  left: auto;
  right: 0;
  transform: translate(0, -4px);
}

.header__actions > [data-tooltip]:last-child:hover::after,
.header__actions > [data-tooltip]:last-child:focus-visible::after {
  transform: translate(0, 0);
}

/* A touch screen has no hover, only a tap that the browser reports as one and
   leaves in place — so the label would appear on the tap and stay until the
   next. Nothing to show it on, so nothing shown. */
@media (hover: none) {
  [data-tooltip]::after {
    display: none;
  }
}

/* Mobile: Larger touch targets (44px minimum per WCAG) */
@media (max-width: 699px) {
  .btn--icon {
    width: 44px;
    height: 44px;
  }

  .btn--small {
    min-height: 44px;
    padding: var(--space-sm) var(--space-md);
  }
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Status indicators */
.status-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}

.status-dot--up {
  background: var(--status-up);
  box-shadow: 0 0 6px var(--status-up);
}

.status-dot--down {
  background: var(--status-down);
  box-shadow: 0 0 6px var(--status-down);
}

/* Delta indicators */
.delta {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: var(--font-size-xs);
  font-weight: 500;
}

.delta--up {
  color: var(--delta-increase);
}

.delta--down {
  color: var(--delta-decrease);
}

/* Number formatting */
.number {
  font-variant-numeric: tabular-nums;
}

.number--large {
  font-size: var(--font-size-xl);
  font-weight: 600;
}

/* Badge */
.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 10px;
  font-size: var(--font-size-xs);
  font-weight: 600;
  background: var(--accent);
  color: white;
}

.badge--highlight {
  background: var(--status-down);
}

/* Form elements */
.form-group {
  margin-bottom: var(--space-md);
}

.form-label {
  display: block;
  margin-bottom: var(--space-xs);
  font-size: var(--font-size-sm);
  font-weight: 500;
  color: var(--text-primary);
}

.form-input {
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-primary);
  color: var(--text-primary);
  font-size: var(--font-size-base);
  transition: border-color var(--transition-fast);
}

.form-input:focus {
  border-color: var(--accent);
  outline: none;
}

.form-input--error {
  border-color: var(--status-down);
}

.form-error {
  margin-top: var(--space-xs);
  font-size: var(--font-size-sm);
  color: var(--status-down);
}

/* Checkbox */
.checkbox {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  cursor: pointer;
}

.checkbox input {
  width: 18px;
  height: 18px;
  accent-color: var(--accent);
}

/* Todo item */
/* Add-task row: stretch keeps the field and the Add button the same height */
.todo-add {
  display: flex;
  align-items: stretch;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}

.todo-input {
  flex: 1;
  min-width: 0;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-primary);
  color: var(--text-primary);
  font-size: var(--font-size-sm);
  font-family: inherit;
  transition: border-color var(--transition-fast);
}

.todo-input::placeholder {
  color: var(--text-muted);
}

.todo-input:focus {
  border-color: var(--accent);
  outline: none;
}

.todo-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-sm) 0;
  border-bottom: 1px solid var(--border-color);
}

.todo-item:last-child {
  border-bottom: none;
}

.todo-item--completed .todo-item__text {
  text-decoration: line-through;
  color: var(--text-muted);
}

.todo-item--pinned {
  background: rgba(20, 184, 166, 0.08);
  margin: 0 calc(-1 * var(--space-md));
  padding: var(--space-sm) var(--space-md);
  border-left: 3px solid var(--accent);
}

.todo-item--archived {
  background: rgba(128, 128, 128, 0.1);
  opacity: 0.7;
}

.todo-archive-toggle {
  display: flex;
  justify-content: flex-end;
  padding: var(--space-xs) 0;
  margin-bottom: var(--space-sm);
  border-bottom: 1px solid var(--border-color);
}

.todo-archive-label {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: 0.85rem;
  color: var(--text-muted);
  cursor: pointer;
}

.todo-archive-label input {
  cursor: pointer;
}

.todo-pin-indicator {
  font-size: 0.8rem;
  margin-right: var(--space-xs);
}

.btn--active {
  color: var(--accent);
}

.todo-item__text {
  flex: 1;
  word-wrap: break-word;
  overflow-wrap: break-word;
}

.todo-item__date {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
}

/* Todo text */
.todo-text {
  flex: 1;
  word-wrap: break-word;
  overflow-wrap: break-word;
  cursor: pointer;
}

.todo-text:hover {
  background: var(--bg-hover);
  border-radius: var(--radius-xs);
  padding: 2px 4px;
  margin: -2px -4px;
}

/* Todo actions */
.todo-actions {
  display: flex;
  gap: 2px;
  opacity: 0.5;
  transition: opacity var(--transition);
}

.todo-item:hover .todo-actions {
  opacity: 1;
}

/* Todo edit input */
.todo-edit-input {
  flex: 1;
  padding: var(--space-xs) var(--space-sm);
  border: 2px solid var(--accent);
  border-radius: var(--radius-sm);
  font-size: inherit;
  font-family: inherit;
  background: var(--bg-card);
  color: var(--text-primary);
}

.todo-edit-input:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(20, 184, 166, 0.2);
}

/* Completed todo styling */
.todo-item--completed .todo-text {
  text-decoration: line-through;
  color: var(--text-muted);
}

/* Todo checkbox */
.todo-checkbox {
  width: 18px;
  height: 18px;
  accent-color: var(--accent);
  margin-top: 2px;
  cursor: pointer;
}

/* Toast notifications */
.toast-container {
  position: fixed;
  bottom: var(--space-lg);
  right: var(--space-lg);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.toast {
  padding: var(--space-md);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  box-shadow: var(--shadow-lg);
  animation: toast-in 0.3s ease;
}

.toast--success {
  border-left: 3px solid var(--status-up);
}

.toast--error {
  border-left: 3px solid var(--status-down);
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Skeleton loading */
.skeleton {
  background: linear-gradient(90deg, var(--border-color) 25%, var(--bg-primary) 50%, var(--border-color) 75%);
  background-size: 200% 100%;
  animation: skeleton-loading 1.5s infinite;
  border-radius: var(--radius-sm);
}

@keyframes skeleton-loading {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

/* Modal/Dialog */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal {
  background: var(--bg-card);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  max-width: 500px;
  width: 90%;
  max-height: 90vh;
  overflow-y: auto;
}

.modal__header {
  padding: var(--space-md);
  border-bottom: 1px solid var(--border-color);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.modal__title {
  font-size: var(--font-size-lg);
  font-weight: 600;
}

.modal__body {
  padding: var(--space-md);
}

.modal__footer {
  padding: var(--space-md);
  border-top: 1px solid var(--border-color);
  display: flex;
  justify-content: flex-end;
  gap: var(--space-sm);
}

/* Empty state */
.empty-state {
  text-align: center;
  padding: var(--space-xl);
  color: var(--text-muted);
}

.empty-state__icon {
  width: 48px;
  height: 48px;
  margin: 0 auto var(--space-md);
  opacity: 0.5;
}

.empty-state__text {
  font-size: var(--font-size-sm);
}

/* Login/Setup page */
.auth-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-lg);
}

.auth-card {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--space-xl);
  width: 100%;
  max-width: 400px;
}

.auth-card__title {
  font-size: var(--font-size-xl);
  font-weight: 600;
  text-align: center;
  margin-bottom: var(--space-lg);
}

/* Utility classes */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.text-muted {
  color: var(--text-muted);
}

.text-sm {
  font-size: var(--font-size-sm);
}

.mt-sm { margin-top: var(--space-sm); }
.mt-md { margin-top: var(--space-md); }
.mb-sm { margin-bottom: var(--space-sm); }
.mb-md { margin-bottom: var(--space-md); }

/* Health card */
.health-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.health-item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  background: var(--bg-primary);
  border-radius: var(--radius-sm);
  border-left: 3px solid transparent;
}

.health-item--up {
  border-left-color: var(--status-up);
}

.health-item--down {
  border-left-color: var(--status-down);
}

.health-status {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: bold;
  color: white;
}

.health-status--up {
  background: var(--status-up);
  box-shadow: 0 0 6px var(--status-up);
}

.health-status--down {
  background: var(--status-down);
  box-shadow: 0 0 6px var(--status-down);
}

.health-up-indicator {
  font-size: var(--font-size-xs);
  color: var(--status-up);
  background: rgba(34, 197, 94, 0.1);
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  font-weight: 600;
}

.health-name {
  flex: 1;
  color: var(--text-primary);
  text-decoration: none;
  font-weight: 500;
}

.health-name:hover {
  color: var(--accent);
}

.health-error {
  font-size: var(--font-size-xs);
  color: var(--status-down);
  background: rgba(239, 68, 68, 0.1);
  padding: 2px 6px;
  border-radius: var(--radius-sm);
}

.health-down-since {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  margin-left: auto;
  white-space: nowrap;
}

/* 24h History Strip */
.health-history {
  display: flex;
  gap: 2px;
  margin-top: var(--space-xs);
  height: 16px;
  align-items: center;
}

.health-history-bar {
  flex: 1;
  min-width: 4px;
  max-width: 8px;
  height: 100%;
  border-radius: 2px;
  transition: transform 0.15s ease, opacity 0.15s ease;
  cursor: pointer;
}

.health-history-bar--up {
  background: var(--status-up);
}

.health-history-bar--down {
  background: var(--status-down);
}

.health-history-bar:hover {
  transform: scaleY(1.3);
  opacity: 0.8;
}

.health-history-empty {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  font-style: italic;
}

.loading-state {
  color: var(--text-muted);
  text-align: center;
  padding: var(--space-md);
}

/* Refresh button spinning animation */
.refreshing {
  animation: spin 1s linear infinite;
}

.refreshing svg {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

/* Fuel Prices card */
.fuel-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.fuel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: var(--space-sm);
  border-bottom: 1px solid var(--border-color);
  margin-bottom: var(--space-sm);
}

.fuel-effective {
  font-size: var(--font-size-sm);
  color: var(--text-muted);
  font-weight: 500;
}

.stale-indicator {
  font-size: var(--font-size-xs);
  color: var(--status-warning);
  cursor: help;
}

.fuel-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.fuel-item {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm);
  background: var(--bg-primary);
  border-radius: var(--radius-sm);
}

.fuel-name {
  font-size: var(--font-size-sm);
  color: var(--text-primary);
}

.fuel-price {
  font-size: var(--font-size-base);
  font-weight: 600;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.fuel-change {
  font-size: var(--font-size-xs);
  font-weight: 500;
  min-width: 60px;
  text-align: right;
}

.fuel-change.change--up {
  color: var(--delta-increase);
}

.fuel-change.change--down {
  color: var(--delta-decrease);
}

.fuel-footer {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-align: right;
  padding-top: var(--space-xs);
  border-top: 1px solid var(--border-color);
  margin-top: var(--space-sm);
}

/* Markets card */
.markets-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.stale-banner {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--font-size-xs);
  color: var(--status-warning);
  background: rgba(245, 158, 11, 0.1);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-sm);
}

.markets-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.market-item {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm);
  background: var(--bg-primary);
  border-radius: var(--radius-sm);
}

.market-item--error {
  opacity: 0.6;
}

.market-name {
  font-size: var(--font-size-sm);
  color: var(--text-primary);
}

.market-rate {
  font-size: var(--font-size-base);
  font-weight: 600;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.market-change {
  font-size: var(--font-size-xs);
  font-weight: 500;
  min-width: 70px;
  text-align: right;
}

.market-change.change--up {
  color: var(--delta-increase);
}

.market-change.change--down {
  color: var(--delta-decrease);
}

.markets-footer {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-align: right;
  padding-top: var(--space-xs);
  border-top: 1px solid var(--border-color);
  margin-top: var(--space-sm);
}

.health-footer {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-align: right;
  padding-top: var(--space-xs);
  border-top: 1px solid var(--border-color);
  margin-top: var(--space-sm);
}

/* Email card */
.email-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.mailbox-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.mailbox-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-sm) var(--space-md);
  background: var(--bg-primary);
  border-radius: var(--radius-sm);
  border-left: 3px solid var(--accent);
}

.mailbox-item--error {
  border-left-color: var(--status-down);
}

.mailbox-name {
  color: var(--text-primary);
  text-decoration: none;
  font-weight: 500;
}

.mailbox-name:hover {
  color: var(--accent);
}

.mailbox-count {
  font-size: var(--font-size-sm);
  padding: 2px 8px;
  background: var(--bg-secondary);
  border-radius: var(--radius-full);
  color: var(--text-muted);
}

.mailbox-count--unread {
  background: var(--accent);
  color: white;
  font-weight: 600;
}

.mailbox-error {
  font-size: var(--font-size-xs);
  color: var(--status-down);
  cursor: help;
}

.mailbox-checking {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  font-style: italic;
}

.email-footer {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-align: right;
  padding-top: var(--space-xs);
  border-top: 1px solid var(--border-color);
  margin-top: var(--space-sm);
}

.unread-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  background: var(--accent);
  color: white;
  font-size: 11px;
  font-weight: 600;
  border-radius: var(--radius-full);
  margin-left: var(--space-xs);
}


/* ============================================================
   Card builder
   ============================================================ */

.builder {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: var(--space-lg);
  padding: var(--space-lg);
  max-width: 1400px;
  margin: 0 auto;
  align-items: start;
}

@media (max-width: 899px) {
  .builder {
    grid-template-columns: 1fr;
    padding: var(--space-md);
  }

  /* The cards come first. Stacked, the palette is taller than a phone screen,
     so leaving it on top meant scrolling past every widget before reaching the
     thing you opened this page to arrange. */
  .builder__cards {
    order: 1;
  }

  .widget-palette {
    order: 2;
    /* Sticky earns nothing in a single column and only complicates scrolling. */
    position: static;
  }

  /* Compact: a phone cannot drag a palette item anyway, so the entry only has
     to name the widget and offer Add. The description goes. */
  .palette-item {
    align-items: center;
    gap: var(--space-sm);
  }

  .palette-item__body small {
    display: none;
  }

  .palette-item__add {
    min-height: 36px;
  }

  /* The header is five controls; on a phone they need two lines and a real
     touch target rather than being squeezed onto one. */
  .builder-card__header {
    gap: var(--space-sm);
  }

  .builder-card__name {
    flex: 1 1 100%;
    min-width: 0;
  }
}

.widget-palette {
  background: var(--palette-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  position: sticky;
  top: var(--space-lg);
}

.widget-palette__title {
  font-size: var(--font-size-base);
  margin: 0 0 var(--space-xs);
}

.palette-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-sm);
  margin-top: var(--space-sm);
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  cursor: grab;
}

.palette-item:active { cursor: grabbing; }
.palette-item__icon { color: var(--accent); flex-shrink: 0; }
.palette-item__body { min-width: 0; flex: 1; }

/* The click route into a card, for touch and keyboard where drag has none. */
.palette-item__add {
  flex-shrink: 0;
  align-self: center;
  padding: 2px var(--space-sm);
  font-size: var(--font-size-xs);
}

.card-choices {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.card-choice {
  justify-content: flex-start;
  text-align: left;
  border: 1px solid var(--border-color);
}

.builder__toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-bottom: var(--space-md);
  flex-wrap: wrap;
}

.builder-card {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-md);
}

.builder-card__header {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-md);
  border-bottom: 1px solid var(--border-color);
  flex-wrap: wrap;
}

.builder-card__name {
  flex: 1;
  min-width: 120px;
  font-weight: 600;
  padding: var(--space-xs) var(--space-sm);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-primary);
  font-family: inherit;
}

.builder-card__name:hover,
.builder-card__name:focus {
  border-color: var(--border-color);
  background: var(--bg-primary);
  outline: none;
}

/* min-height keeps an empty card a usable drop target. */
.builder-card__zone {
  padding: var(--space-md);
  min-height: 72px;
  transition: background var(--transition-fast);
}

.builder-card__zone.drag-over {
  background: var(--drop-target-bg);
  outline: 2px dashed var(--drop-target-border);
  outline-offset: -6px;
}

.builder-card__empty {
  margin: 0;
  text-align: center;
  padding: var(--space-sm);
}

.builder-widget {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  background: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-sm);
  cursor: grab;
}

.builder-widget:active { cursor: grabbing; }
.builder-widget__name { flex: 1; min-width: 0; }

/* The element being dragged. DragReorder has always added this class; until
   now nothing defined it. */
.dragging {
  opacity: 0.4;
}

/* Where the dragged item would land. */
.drop-placeholder {
  height: 3px;
  margin: var(--space-xs) 0;
  background: var(--accent);
  border-radius: 2px;
}

/* The lift on hover fights the drag image while a drag is in progress. */
body:has(.dragging) .card:hover {
  transform: none;
}


/* ============================================================
   Health and Email widgets
   ============================================================ */

.health-list, .email-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.health-item, .email-item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  background: var(--bg-primary);
  border-radius: var(--radius-sm);
  border-left: 3px solid transparent;
}

.health-item--down { border-left-color: var(--status-down); }

.health-status--up { color: var(--status-up); }
.health-status--down { color: var(--status-down); }

.health-name, .email-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.health-badge {
  font-size: var(--font-size-xs);
  font-weight: 600;
  padding: 2px var(--space-xs);
  border-radius: var(--radius-sm);
}

.health-badge--up { color: var(--status-up); background: rgba(34, 197, 94, 0.12); }
.health-badge--down { color: var(--status-down); background: rgba(239, 68, 68, 0.12); }

/* The bars shrink rather than pushing the card wider. */
.health-history {
  display: flex;
  gap: 1px;
  flex-shrink: 1;
  min-width: 0;
  overflow: hidden;
}

.health-bar {
  width: 4px;
  height: 16px;
  border-radius: 1px;
  flex-shrink: 0;
}

.health-bar--up { background: var(--status-up); }
.health-bar--down { background: var(--status-down); }

.email-item--error { border-left-color: var(--status-warning); }

.email-count {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

.email-count--unread {
  color: white;
  background: var(--accent);
  padding: 2px var(--space-sm);
  border-radius: var(--radius-sm);
}

.email-error {
  font-size: var(--font-size-xs);
  color: var(--status-warning);
}


/* ============================================================
   Managed record lists inside widget settings
   ============================================================ */

.record-manager {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  padding: var(--space-sm);
  background: var(--bg-primary);
}

.record-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin-bottom: var(--space-sm);
}

.record-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-xs) var(--space-sm);
  background: var(--bg-card);
  border-radius: var(--radius-sm);
}

/* Each cell shares the row and truncates rather than widening it. */
.record-cell {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--font-size-sm);
}

.record-cell:first-child { font-weight: 500; }
.record-cell:not(:first-child) { color: var(--text-muted); }

.record-actions {
  display: flex;
  gap: var(--space-xs);
  flex-shrink: 0;
}

.record-form {
  margin-top: var(--space-sm);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--border-color);
}

.record-form__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-sm);
}


/* ============================================================
   Web search bar and engine settings
   ============================================================ */

.header__search {
  display: flex;
  align-items: stretch;
  gap: var(--space-xs);
  flex: 1;
  max-width: 560px;
  margin: 0 auto;
}

.search-engine {
  flex-shrink: 0;
  padding: var(--space-sm);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text-primary);
  font-family: inherit;
  font-size: var(--font-size-sm);
  cursor: pointer;
}

/* The search input inside a widget, distinct from the header one. */
.widget-search {
  width: 100%;
  margin-bottom: var(--space-sm);
  font-size: var(--font-size-sm);
}

.engine-default {
  font-size: var(--font-size-xs);
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-xs);
  margin-left: var(--space-xs);
}

@media (max-width: 767px) {
  }


/* ============================================================
   Notes & To-Dos widget
   ============================================================ */

.notepad-bar {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}

.notepad-bar .widget-search {
  flex: 1;
  min-width: 0;
  margin-bottom: 0;
}

.notepad-new,
.notepad-mode {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  padding: 0;
  line-height: 1;
}

.notepad-new {
  font-size: var(--font-size-lg);
}

/* Ghost-styled, so the toggle reads as a setting for the field beside it rather
   than as a second thing to press. */
.notepad-mode {
  border: 1px solid var(--border-color);
  color: var(--text-muted);
}

.notepad-mode:hover {
  color: var(--accent);
}

@media (max-width: 599px) {
  .notepad-new,
  .notepad-mode {
    width: 44px;
    height: 44px;
  }

  /* Matches the buttons beside it, so the bar lines up and the field is as
     easy to hit as they are. */
  .notepad-bar .widget-search {
    min-height: 44px;
  }
}

/* A row is a fixed height so the list below can be sized in rows rather than
   pixels, and stays right whatever the font size is. */
.notepad-row {
  --notepad-row-h: 2.25rem;

  display: flex;
  align-items: center;
  gap: var(--space-sm);
  min-height: var(--notepad-row-h);
  padding: 0 var(--space-sm);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-primary);
}

/* Only the handle is a grab surface: the rest of the row is a checkbox and a
   button, which take the mousedown themselves. */
.notepad-drag {
  flex-shrink: 0;
  color: var(--text-muted);
  font-size: var(--font-size-sm);
  line-height: 1;
  cursor: grab;
  opacity: 0.5;
}

.notepad-row:hover .notepad-drag {
  opacity: 1;
}

.notepad-row.dragging {
  opacity: 0.5;
  cursor: grabbing;
}

.notepad-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* The card keeps its height however long the list grows. The count comes from
   the placement's own setting, so two placements can differ. */
.notepad-list--scrolling {
  max-height: calc(var(--notepad-visible, 6) * (2.25rem + var(--space-xs)));
  overflow-y: auto;
  padding-right: 2px;
}

.notepad-row--pinned {
  border-color: var(--accent);
}

.notepad-check {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
  cursor: pointer;
}

/* Keeps the headings of notes and tasks on the same left edge. */
.notepad-check-spacer {
  display: inline-block;
  flex-shrink: 0;
  width: 16px;
}

/* The heading is a button, not a div with a click handler, so it is reachable
   by keyboard and announced as something that does anything. */
.notepad-heading {
  flex: 1;
  min-width: 0;
  padding: 0;
  border: none;
  background: none;
  font-family: inherit;
  font-size: var(--font-size-sm);
  color: var(--text-primary);
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}

.notepad-heading:hover {
  color: var(--accent);
}

/* A completed task stays legible — struck through and dimmed, not hidden,
   because hiding it is a separate setting. */
.notepad-row--done .notepad-heading {
  text-decoration: line-through;
  color: var(--text-muted);
}

.notepad-marks {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

.notepad-mark {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  line-height: 1;
}

/* ---- the editor modal ---- */

/* A phone has no room for the footer's five buttons in a row, and the modal
   itself should use the whole screen rather than floating in the middle of it. */
@media (max-width: 599px) {
  .modal--wide {
    width: 100%;
    max-width: none;
    max-height: 100%;
    height: 100%;
    border-radius: 0;
  }

  .modal--wide .modal__footer {
    flex-wrap: wrap;
  }

  .modal--wide .modal__footer .btn {
    flex: 1 1 auto;
    min-height: 44px;
  }

  /* The spacer only makes sense while the buttons are on one line. */
  .notepad-editor__spacer {
    display: none;
  }

  .notepad-editor__body {
    min-height: 140px;
  }
}

/* Wider than the default 500px: this one holds a note body and images. */
.modal--wide {
  max-width: 640px;
}

.notepad-editor__title {
  width: 100%;
  padding: var(--space-sm);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-primary);
  font-family: inherit;
  font-size: var(--font-size-lg);
  font-weight: 600;
}

.notepad-editor__title:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--bg-primary);
}

.notepad-editor__body {
  display: block;
  width: 100%;
  min-height: 200px;
  padding: var(--space-sm);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: inherit;
  font-size: var(--font-size-sm);
  line-height: 1.6;
  resize: vertical;
}

.notepad-editor__body:focus {
  outline: none;
  border-color: var(--accent);
}

.notepad-editor__controls {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex-wrap: wrap;
  margin-top: var(--space-sm);
}

.notepad-editor__delete {
  color: var(--status-down);
}

/* Pushes Cancel and Save away from Delete, so the destructive one is not
   next to the one you reach for most. */
.notepad-editor__spacer {
  flex: 1;
}

.notepad-dropzone {
  position: relative;
}

.notepad-dropzone__overlay {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
  border: 2px dashed var(--accent);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--accent);
  font-weight: 500;
  pointer-events: none;
}

.notepad-dropzone--active .notepad-dropzone__overlay {
  display: flex;
}

.notepad-editor__images {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-top: var(--space-sm);
}

.notepad-editor__images:empty {
  margin-top: 0;
}

.notepad-image {
  position: relative;
  width: 110px;
}

.notepad-image img {
  display: block;
  width: 100%;
  height: 80px;
  object-fit: cover;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
}

.notepad-image__remove {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 20px;
  height: 20px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--bg-card);
  color: var(--text-primary);
  font-size: var(--font-size-sm);
  line-height: 1;
  cursor: pointer;
  opacity: 0.85;
}

.notepad-image__remove:hover {
  opacity: 1;
  color: var(--status-down);
}


/* ============================================================
   Lightbox and export chooser
   ============================================================ */

/* Deliberately not themed: a picture is judged against a dark ground in either
   theme, and this is the one surface in the app that is about the image rather
   than the interface. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-lg);
  background: rgba(0, 0, 0, 0.9);
}

/* The page behind must not scroll under the viewer, which on a phone is the
   difference between pinching an image and losing your place. */
body.lightbox-open {
  overflow: hidden;
}

.lightbox__image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: var(--radius-sm);
}

.lightbox__close,
.lightbox__nav {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  cursor: pointer;
  line-height: 1;
  transition: background-color var(--transition-fast);
}

.lightbox__close:hover,
.lightbox__nav:hover {
  background: rgba(255, 255, 255, 0.25);
}

/* 44px is the smallest comfortable touch target, so the controls are that size
   everywhere rather than shrinking on the screens that need them biggest. */
.lightbox__close {
  top: var(--space-md);
  right: var(--space-md);
  width: 44px;
  height: 44px;
  font-size: 1.75rem;
}

.lightbox__nav {
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  font-size: 2rem;
}

.lightbox__nav--prev { left: var(--space-md); }
.lightbox__nav--next { right: var(--space-md); }

.lightbox__count {
  position: absolute;
  bottom: var(--space-md);
  left: 50%;
  transform: translateX(-50%);
  padding: 4px var(--space-sm);
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-size: var(--font-size-xs);
}

/* On a phone the arrows would sit on top of the picture, so they move to the
   bottom corners where the thumbs already are. */
@media (max-width: 599px) {
  .lightbox {
    padding: var(--space-sm);
  }

  .lightbox__nav {
    top: auto;
    bottom: var(--space-md);
    transform: none;
  }

  .lightbox__count {
    bottom: calc(var(--space-md) + 52px);
  }
}

/* Thumbnails say they can be opened. */
.notepad-image img {
  cursor: zoom-in;
}

.export-choices {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.export-choice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-height: 44px;
  padding: var(--space-sm);
  border: 1px solid var(--border-color);
  text-align: left;
}


/* ============================================================
   Camera and location controls
   ============================================================ */

.notepad-editor__tools {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-top: var(--space-sm);
}

/* These are the controls a phone reaches for, so they get a real touch target
   and share the row evenly rather than sizing to their labels. */
.notepad-tool {
  flex: 1 1 auto;
  min-height: 44px;
  border: 1px solid var(--border-color);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}

.notepad-tool:disabled {
  opacity: 0.6;
  cursor: default;
}

.location {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-sm);
  margin-top: var(--space-sm);
  padding: var(--space-sm);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-primary);
  font-size: var(--font-size-sm);
}

/* The dot carries the quality of the fix, so a coarse network position is not
   mistaken for a GPS one at a glance. */
.location__dot {
  flex-shrink: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.location__dot--good { background: var(--status-up); }
.location__dot--fair { background: var(--status-warning); }
.location__dot--coarse { background: var(--status-down); }

.location__coords {
  color: var(--accent);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}

.location__coords:hover {
  text-decoration: underline;
}

.location__accuracy {
  color: var(--text-muted);
  font-size: var(--font-size-xs);
}

/* Takes the whole second line, so a permission hint reads as a sentence rather
   than being squeezed between the coordinates and the remove button. */
.location__note {
  flex-basis: 100%;
  color: var(--text-muted);
  font-size: var(--font-size-xs);
}


/* The grab surface for reordering cards. The rest of the header is form
   controls, which take the mousedown themselves, so a drag begun anywhere else
   never reaches the card. */
.builder-card__drag {
  flex-shrink: 0;
  padding: 0 var(--space-xs);
  color: var(--text-muted);
  cursor: grab;
  opacity: 0.5;
  user-select: none;
}

.builder-card:hover .builder-card__drag {
  opacity: 1;
}

.builder-card.dragging {
  opacity: 0.5;
}


/* Up and down, for touch, where HTML5 drag does not exist. Kept beside the
   delete button so every control that acts on the whole card is in one place. */
.builder-card__moves {
  display: flex;
  flex-shrink: 0;
  gap: 2px;
}

.builder-card__moves .btn {
  min-width: 36px;
  min-height: 36px;
  font-size: var(--font-size-xs);
}

.builder-card__moves .btn:disabled {
  opacity: 0.3;
  cursor: default;
}

@media (max-width: 899px) {
  /* A real touch target: on a phone these are the only way to reorder. */
  .builder-card__moves .btn {
    min-width: 44px;
    min-height: 44px;
  }

  /* Drag is a mouse gesture, so the handle is only clutter here. */
  .builder-card__drag {
    display: none;
  }
}


/* ============================================================
   Header on a narrow screen
   ============================================================ */

/* One row cannot hold a title, a search box and four buttons on a phone: the
   search squeezed to nothing and the buttons went off the right edge, reachable
   only by scrolling sideways. The search takes its own row instead, where it
   has the width it actually needs. */
@media (max-width: 767px) {
  .header {
    flex-wrap: wrap;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
  }

  .header__title {
    flex: 0 1 auto;
    min-width: 0;
    font-size: var(--font-size-base);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* Pushed hard right on the first row, so the buttons keep their place
     whatever the title is. */
  .header__actions {
    flex: 0 0 auto;
    margin-left: auto;
  }

  /* Ordered after the actions, which with wrapping puts it on the next line. */
  .header__search {
    order: 3;
    flex: 1 1 100%;
    width: auto;
    max-width: none;
    margin: 0;
  }

  /* The engine picker keeps its label readable without eating the input. */
  .search-engine {
    max-width: 40%;
  }
}



/* ============================================================
   The map mark on a located entry
   ============================================================ */

/* The location mark, in both note widgets. It reads as one of the row's marks
   until you touch it, then as the link it is. */
.mark-link {
  flex-shrink: 0;
  text-decoration: none;
  color: var(--text-muted);
  line-height: 1;
}

.mark-link:hover,
.mark-link:focus-visible {
  color: var(--accent);
}

/* Touch needs something to aim at, and the mark itself is a single glyph. The
   negative margin keeps the row its own height while the target grows. */
@media (max-width: 599px) {
  .mark-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    margin: -10px 0;
  }
}


/* ============================================================
   Notes & To-Dos row controls
   ============================================================ */

/* Held out of the way until the row is under the pointer. Faded rather than
   removed, so the row does not change width when they appear and the headings
   stay in a straight line. */
.notepad-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity var(--transition-fast);
}

.notepad-row:hover .notepad-actions,
.notepad-row:focus-within .notepad-actions {
  opacity: 1;
}

.notepad-actions .btn {
  width: 26px;
  height: 26px;
  padding: 0;
  font-size: var(--font-size-xs);
  line-height: 1;
}

/* A pinned entry says so through its own button, which is why the row no longer
   carries a separate pin mark. */
.notepad-row--pinned .notepad-actions [data-action="pin"] {
  opacity: 1;
  filter: none;
}

.notepad-row:not(.notepad-row--pinned) .notepad-actions [data-action="pin"] {
  filter: grayscale(1);
}

/* Touch has no hover, so the controls would never appear. They take a real
   target, and the two informational marks give up their space for it — the
   editor says the same thing when you open the entry. */
@media (hover: none), (max-width: 599px) {
  .notepad-actions {
    opacity: 1;
  }

  .notepad-actions .btn {
    width: 36px;
    height: 36px;
  }

  .notepad-marks .notepad-mark:not(.mark-link) {
    display: none;
  }
}

/* Recovery code
   ------------------------------------------------------------------------ */

/* Shown once, on setup and on the first login of a carried-over account, then
   never again. Monospace and widely spaced because it is meant to be copied
   onto paper by eye, and user-select makes it easy to take digitally instead. */
.recovery-code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: var(--font-size-lg);
  letter-spacing: 0.08em;
  text-align: center;
  word-break: break-all;
  padding: var(--space-md);
  margin-bottom: var(--space-md);
  border: 1px dashed var(--border-color);
  border-radius: var(--radius-md);
  background: var(--bg-primary);
  color: var(--text-primary);
  user-select: all;
}

/* Settings and admin pages
   ------------------------------------------------------------------------
   Promoted out of settings.html's inline <style> so the admin console can
   use the same chrome instead of duplicating eighty lines of it. Appended at
   the end of the file, which is the lowest-conflict edit available while
   another branch may be working further up. */
  .settings-page {
    max-width: 800px;
    margin: 0 auto;
    padding: var(--space-lg);
  }
  .settings-header {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
  }
  .tabs {
    display: flex;
    align-items: center;
    border-bottom: 1px solid var(--border-color);
    margin-bottom: var(--space-lg);
  }
  /* Pushed to the far end, away from the tabs it is not one of. */
  .tabs__action {
    margin-left: auto;
    margin-bottom: var(--space-xs);
    gap: var(--space-xs);
    border: 1px solid var(--border-color);
    white-space: nowrap;
  }
  @media (max-width: 767px) {
    .tabs {
        gap: var(--space-xs);
    }
    /* Icon only. The label is what would not fit beside the tabs, and
       losing it keeps everything on one row. */
    .tabs__action-label {
        display: none;
    }
    .tabs__action {
        width: 44px;
        min-height: 44px;
        padding: 0;
        justify-content: center;
    }
  }
  .tab {
    padding: var(--space-sm) var(--space-md);
    border: none;
    background: none;
    cursor: pointer;
    color: var(--text-muted);
    border-bottom: 2px solid transparent;
    transition: all var(--transition-fast);
  }
  .tab:hover {
    color: var(--text-primary);
  }
  .tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
  }
  .tab-content {
    display: none;
  }
  .tab-content.active {
    display: block;
  }
  .settings-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
  }
  .settings-item {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-md);
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
  }
  .settings-item__drag {
    cursor: grab;
    color: var(--text-muted);
  }
  .settings-item__name {
    flex: 1;
    /* A flex child will not shrink below its content without this, so a
       long address pushed the buttons clean off the row. */
    min-width: 0;
  }
  .settings-item__name small {
    /* An address has no spaces to break at, so it is allowed to break
       anywhere rather than setting the row's width. */
    overflow-wrap: anywhere;
  }
  .settings-item__actions {
    display: flex;
    flex-shrink: 0;
    gap: var(--space-xs);
  }

/* Admin console
   ------------------------------------------------------------------------ */

.admin-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  margin-bottom: var(--space-md);
}

.admin-heading {
  font-size: var(--font-size-lg);
  margin: 0;
}

/* A badge sits inline with the name it qualifies, so it must not inherit the
   line height of the row and push it taller. */
.settings-item__name .badge {
  margin-left: var(--space-xs);
  vertical-align: middle;
}
