/* Atlas dashboard — "instrument panel" design language.
   Palette: deep ink / paper neutrals, an ocean-teal primary accent
   (navigation/charting), a brass secondary (instrument-dial warmth),
   and semantic good/warn colors kept separate from the accent so status
   always reads distinctly from decoration. */

:root {
  --ink: #12181c;
  --paper: #f3f5f4;
  --paper-raised: #ffffff;
  --ink-raised: #1a2226;

  --text: #1c2426;
  --text-muted: #5b6b6e;
  --border: #dde3e1;

  --ocean: #1f7a76;
  --ocean-strong: #145653;
  --brass: #b98a3d;

  --good: #3f8f5f;
  --good-bg: #e7f3ec;
  --warn: #c15b2e;
  --warn-bg: #fbe9e0;
  --danger: #c23b3b;
  --danger-bg: #fbe6e6;
  --neutral-bg: #eef1f0;

  --shadow: 0 1px 2px rgba(18, 24, 28, 0.06), 0 4px 16px rgba(18, 24, 28, 0.05);
  --radius: 14px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #0e1417;
    --paper: #12181c;
    --paper-raised: #1a2226;
    --ink-raised: #202a2e;

    --text: #e7ece9;
    --text-muted: #8ea0a0;
    --border: #263133;

    --ocean: #4fb3ac;
    --ocean-strong: #6fc9c2;
    --brass: #d8ab5f;

    --good: #6bc492;
    --good-bg: #16261d;
    --warn: #e08a5b;
    --warn-bg: #2c1d15;
    --danger: #e35b5b;
    --danger-bg: #2c1616;
    --neutral-bg: #1a2226;

    --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 20px rgba(0, 0, 0, 0.35);
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--text);
}

body {
  font-family: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom) 0;
}

.mono, .num {
  font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;
  font-variant-numeric: tabular-nums;
}

.wrap {
  max-width: 900px;
  margin: 0 auto;
  padding: 20px 16px 48px;
}

/* Top bar */
.topbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 4px 20px;
}

.wordmark {
  font-family: "Fraunces", Georgia, serif;
  font-weight: 600;
  font-optical-sizing: auto;
  font-size: 26px;
  letter-spacing: -0.01em;
  color: var(--text);
}

.wordmark span {
  color: var(--ocean-strong);
}

.updated {
  font-size: 12px;
  color: var(--text-muted);
  text-align: right;
}

/* Card grid */
.grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}

@media (min-width: 640px) {
  .grid { grid-template-columns: repeat(2, 1fr); }
  .grid .span-2 { grid-column: span 2; }
}

.card {
  background: var(--paper-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* Grid items default to min-width: auto, which protects unwrapped
     content's full width — a single long line anywhere inside (a mail
     subject, an event title) would otherwise force the whole grid, and
     with it the page's layout viewport, wider than the phone screen,
     which is what forces a pinch-zoom-out on load. */
  min-width: 0;
}

.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.eyebrow {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.card-primary {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.card-sub {
  font-size: 13px;
  color: var(--text-muted);
}

/* Rows within a card */
.rows {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.sub-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-top: 6px;
}

.sub-label:first-child { margin-top: 0; }

/* Today timeline — Apple Calendar-style day view, split into two side-by-
   side halves so each covers fewer hours per pixel of height — thick
   blocks instead of long thin slivers for the same event durations. */
.timeline {
  display: flex;
  gap: 18px;
  min-height: 520px;
}

.timeline-half {
  display: flex;
  gap: 8px;
  flex: 1;
  min-width: 0;
}

.timeline-half:first-child {
  padding-right: 18px;
  border-right: 1px solid var(--border);
}

/* Below this width there isn't room for two side-by-side AM/PM columns —
   stack them instead of letting the second half get clipped off-screen. */
@media (max-width: 640px) {
  .timeline {
    flex-direction: column;
    gap: 0;
    min-height: unset;
  }

  .timeline-half {
    min-height: 640px;
  }

  .timeline-half:first-child {
    padding-right: 0;
    padding-bottom: 18px;
    margin-bottom: 18px;
    border-right: none;
    border-bottom: 1px solid var(--border);
  }

  /* On mobile the calendar reads better as the last thing you scroll to
     rather than the first thing blocking the rest of the dashboard — grid
     items respect `order` the same way flex items do, so this alone moves
     it without touching any other card's position (default order: 0 keeps
     everything else in its normal document order, which sorts before 999).
     Desktop's 2-column layout is untouched since this is mobile-only.
     Finances sits at 998 specifically so it lands immediately before the
     calendar rather than just "somewhere before it." */
  #card-finances {
    order: 998;
  }

  #card-today {
    order: 999;
  }
}

.timeline-gutter {
  position: relative;
  width: 52px;
  flex-shrink: 0;
}

.timeline-hour-label {
  position: absolute;
  transform: translateY(-50%);
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
}

.timeline-track {
  position: relative;
  flex: 1;
  border-top: 1px solid var(--border);
}

.timeline-hour-line {
  position: absolute;
  left: 0;
  right: 0;
  border-top: 1px solid var(--border);
}

.timeline-lanes {
  position: absolute;
  inset: 0;
}

.timeline-event {
  position: absolute;
  border-left: 4px solid;
  border-radius: 7px;
  padding: 5px 10px;
  overflow: hidden;
  box-sizing: border-box;
}

.timeline-event-title {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.timeline-event-time {
  font-size: 11px;
  color: var(--text-muted);
}

.timeline-empty-note {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 12px;
  font-style: italic;
  color: var(--text-muted);
  white-space: nowrap;
}

.row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 13.5px;
}

.row-label {
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.row {
  min-width: 0;
}

.row-meta {
  color: var(--text-muted);
  font-size: 12px;
  flex-shrink: 0;
}

/* Homework completion checkboxes — .row-main groups the checkbox with the
   label so the pair acts as one flex item against .row-meta, matching
   .row's existing two-child space-between layout. */
.row-main {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  cursor: pointer;
}

.row-check {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  accent-color: var(--ocean-strong);
  cursor: pointer;
}

.row-label-done {
  text-decoration: line-through;
  color: var(--text-muted);
}

.completed-section {
  margin-top: 6px;
}

.completed-section summary {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  cursor: pointer;
  list-style: none;
}

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

.completed-section summary::before {
  content: "▸ ";
}

.completed-section[open] summary::before {
  content: "▾ ";
}

.completed-section .row {
  margin-top: 8px;
}

/* Status chips */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.chip-good { background: var(--good-bg); color: var(--good); }
.chip-warn { background: var(--warn-bg); color: var(--warn); }
.chip-neutral { background: var(--neutral-bg); color: var(--text-muted); }

.chip-group {
  display: flex;
  align-items: center;
  gap: 6px;
}

.journal-link {
  font-size: 12px;
  font-weight: 600;
  color: var(--ocean-strong);
  text-decoration: none;
  white-space: nowrap;
}

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

.journal-note {
  margin-top: 6px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 13.5px;
  color: var(--text);
  line-height: 1.5;
}

.journal-note-date {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 4px;
}

/* Card header: headline spend on the left, the total-budget wheel on the
   right, in line with each other rather than the wheel stacked below. */
.finance-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}

.finance-amount {
  min-width: 0;
}

/* Total-budget wheel — a single circular gauge for the headline number.
   Ring fills clockwise from 12 o'clock up to 100% in the ocean accent.
   Past 100% the ring turns red and a brighter arc is drawn on top of it,
   starting again from 12 o'clock, sized to how far past 100% we are —
   the same "second lap" language Apple's Activity rings use for an
   exceeded goal. */
.wheel-tile {
  display: flex;
  align-items: center;
  gap: 10px;
}

.wheel-track {
  fill: none;
  stroke: var(--neutral-bg);
}

.wheel-fill {
  fill: none;
  stroke: var(--ocean);
  stroke-linecap: round;
  transition: stroke-dashoffset 0.4s ease;
}

.wheel-fill-overlay {
  fill: none;
  stroke: var(--danger);
  stroke-linecap: round;
  transition: stroke-dashoffset 0.4s ease;
}

.wheel-pct {
  font-family: "IBM Plex Mono", monospace;
  font-size: 15px;
  font-weight: 500;
  fill: var(--text);
  text-anchor: middle;
  dominant-baseline: central;
}

.wheel-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.wheel-name {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text);
}

.wheel-amount {
  font-size: 12px;
  color: var(--text);
}

.wheel-subnote {
  font-size: 11.5px;
  color: var(--text-muted);
  margin-top: 1px;
}

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

/* Per-category breakdown — linear bars. A row per category so the full
   name has room instead of truncating in a cramped small wheel. Over
   budget turns the bar and percentage red; the percentage itself switches
   from "% of budget used" to "% over budget" once past 100%, since that's
   the more useful number at that point. */
.meter-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.meter-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.meter-labels {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}

.meter-name {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text);
}

.meter-pct {
  font-size: 12px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.meter-pct.danger {
  color: var(--danger);
  font-weight: 600;
}

.meter-track {
  height: 6px;
  border-radius: 999px;
  background: var(--neutral-bg);
  overflow: hidden;
}

.meter-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--ocean);
  transition: width 0.4s ease;
}

.meter-fill.danger {
  background: var(--danger);
}

.meter-amount {
  font-size: 12px;
  color: var(--text-muted);
}

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

/* Market sentiment gauge — a marker on a bearish/neutral/bullish track,
   colored with the same semantic danger/neutral/good tokens used
   elsewhere rather than a new accent color. */
.sentiment-wrap {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.sentiment-gauge {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.sentiment-track {
  position: relative;
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(to right, var(--danger), var(--neutral-bg), var(--good));
}

.sentiment-marker {
  position: absolute;
  top: 50%;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--text-muted);
  border: 2px solid var(--paper-raised);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transform: translate(-50%, -50%);
}

.sentiment-marker.bearish { left: 10%; background: var(--danger); }
.sentiment-marker.neutral { left: 50%; background: var(--text-muted); }
.sentiment-marker.bullish { left: 90%; background: var(--good); }

.sentiment-labels {
  display: flex;
  justify-content: space-between;
  font-size: 10.5px;
  color: var(--text-muted);
}

.sentiment-reasoning {
  font-size: 12.5px;
  color: var(--text);
  line-height: 1.4;
}

.sentiment-date {
  font-size: 11px;
  color: var(--text-muted);
}

/* Empty / loading states */
.empty {
  color: var(--text-muted);
  font-size: 13px;
  font-style: italic;
}

.error-banner {
  background: var(--warn-bg);
  color: var(--warn);
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 13px;
  margin-bottom: 14px;
}

/* Token gate */
.gate {
  max-width: 340px;
  margin: 20vh auto;
  text-align: center;
  padding: 0 20px;
}

.gate input {
  width: 100%;
  font-family: "IBM Plex Mono", monospace;
  font-size: 14px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--paper-raised);
  color: var(--text);
  margin: 14px 0;
}

.gate button {
  width: 100%;
  font-family: "IBM Plex Sans", sans-serif;
  font-weight: 600;
  font-size: 14px;
  padding: 10px 12px;
  border-radius: 10px;
  border: none;
  background: var(--ocean);
  color: var(--paper-raised);
  cursor: pointer;
}

.gate button:focus-visible,
input:focus-visible {
  outline: 2px solid var(--ocean);
  outline-offset: 2px;
}
