:root {
  --bg: #fafaf8;
  --text: #1f2430;
  --muted: #6b7280;
  --border: #e3e1db;
  --accent: #5B8DEF;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
}

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

/* Layout: a fixed left sidebar + main content, side by side. Below
   640px the sidebar collapses into a plain top block (flex-direction
   switches to column) rather than trying to keep a real sidebar on a
   phone-width screen. */
.app-layout { display: flex; align-items: flex-start; min-height: 100vh; }

.sidebar {
  flex: 0 0 190px;
  width: 190px;
  box-sizing: border-box;
  padding: 16px 12px;
  border-right: 1px solid var(--border);
  background: #fff;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.sidebar .brand { display: block; font-weight: 700; color: var(--text); margin-bottom: 16px; padding: 0 8px; }

.nav-group { margin-bottom: 14px; }
.nav-group.nav-footer { margin-top: auto; margin-bottom: 0; padding-top: 14px; border-top: 1px solid var(--border); }

.nav-parent {
  display: block;
  padding: 6px 8px;
  border-radius: 6px;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text);
}
.nav-parent:hover { background: var(--bg); text-decoration: none; }
.nav-parent.active { background: #eef3ff; color: var(--accent); }

.nav-child {
  display: block;
  padding: 5px 8px 5px 22px;
  font-size: 0.88rem;
  color: var(--muted);
}
.nav-child:hover { text-decoration: none; color: var(--accent); }
.nav-child.active { color: var(--accent); font-weight: 600; }

main { flex: 1; min-width: 0; max-width: 900px; padding: 16px; }
main.no-sidebar { max-width: 900px; margin: 0 auto; }

/* The month grid is the one page that benefits from real laptop-width
   screen space -- more width means each day cell can grow too, instead
   of the calendar being squeezed into the same 900px column that suits
   a single-column form or list. Other pages keep the narrower cap since
   a wide single column of text/forms is harder to read, not easier. */
main.cal-page { max-width: 1240px; }

@media (max-width: 640px) {
  .app-layout { flex-direction: column; }
  .sidebar {
    width: 100%;
    min-height: auto;
    border-right: none;
    border-bottom: 1px solid var(--border);
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    padding: 10px 12px;
  }
  .sidebar .brand { width: 100%; margin-bottom: 2px; padding: 4px 8px; }
  .nav-group { display: flex; align-items: center; flex-wrap: wrap; margin-bottom: 0; }
  .nav-group.nav-footer { margin-top: 0; padding-top: 0; padding-left: 8px; border-top: none; border-left: 1px solid var(--border); }
  .nav-parent, .nav-child { padding: 4px 6px; display: inline-block; }
  .nav-child { padding-left: 6px; }
}

.flashes { margin-bottom: 12px; }
.flash { padding: 8px 12px; border-radius: 6px; margin-bottom: 8px; font-size: 0.9rem; }
.flash-ok { background: #e3f5e6; color: #1b6b2c; }
.flash-error { background: #fbe4e4; color: #a12727; }

h1 { font-size: 1.4rem; }

/* Login */
.login-box { max-width: 320px; margin: 60px auto; text-align: center; }
.login-box form { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; text-align: left; }

label { display: flex; flex-direction: column; gap: 4px; font-size: 0.9rem; color: var(--muted); }
input, select, textarea, button {
  font: inherit;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
}
button {
  background: var(--accent);
  color: #fff;
  border: none;
  cursor: pointer;
  margin-top: 8px;
}
button:hover { opacity: 0.9; }

/* Calendar */
.cal-header { display: flex; align-items: center; justify-content: center; gap: 16px; }
.cal-header h1 { margin: 0; min-width: 200px; text-align: center; }
.day-header h1 { font-size: 1.2rem; min-width: unset; }
.nav-arrow { font-size: 1.4rem; padding: 4px 10px; }

.legend { display: flex; gap: 16px; justify-content: center; margin: 12px 0; flex-wrap: wrap; }
.legend-item { display: flex; align-items: center; gap: 6px; font-size: 0.85rem; color: var(--muted); }
.swatch { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }

.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  margin-top: 12px;
}
.cal-dow { text-align: center; font-size: 0.75rem; color: var(--muted); font-weight: 600; padding-bottom: 4px; }

/* Redesigned for clarity: one plain white card per day, a single colored
   left-border accent for "whose day" instead of a colored background wash
   (previously the same fact got repeated in the background tint, the
   border, and the text color all at once), and secondary info (event,
   exchange, note) kept to compact single lines below rather than a mix of
   emoji icons, a filled pill, and a duplicate day/night text row. */
.cal-day {
  position: relative;
  display: block;
  height: 136px; /* bigger on desktop/laptop widths so a typical busy day (a
    couple events, an exchange time, a note) actually fits and shows instead
    of getting clipped by/hidden behind the overflow-clip safety net below --
    see the @media (max-width: 640px) block for the smaller phone height */
  min-width: 0; /* grid items default to min-width:auto, which some browsers compute
    using the popover's min-width even though it's position:absolute -- without this,
    whichever column happens to have an open/wide popover stretches that whole column */
  background: #fff;
  border: 1px solid var(--border);
  border-left: 4px solid #ddd;
  border-radius: 6px;
  padding: 8px 9px;
  color: var(--text);
  cursor: pointer; /* clicking anywhere on the cell opens the day view, see calendar.html's script */
}
.cal-day.outside { opacity: 0.35; }
.cal-day.no-data { opacity: 0.4; }
.cal-day.today { outline: 2px solid var(--accent); outline-offset: -1px; }

/* Fills the cell's padding box and clips -- the safety net that keeps any
   combination of custody name + night suffix + event + exchange/note from
   ever pushing past the cell's fixed height. A sibling of .cal-day-popover
   (not a parent), so this clipping never cuts the popover off, which needs
   to float below the cell's own bounds to show full detail. */
.cal-day-content { height: 100%; overflow: hidden; }
.cal-day-num {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  margin-bottom: 3px;
}
.cal-day.today .cal-day-num { color: var(--accent); }
.cal-day-num:hover { text-decoration: underline; }

/* The quick "who has Owen" picker -- looks like plain bold text, but is a
   real <select> so a tap/click there changes the day's custody
   immediately without opening the day view. calendar.html's click
   handler excludes .cal-day-parent-form so interacting with it doesn't
   also navigate to the day view. */
.cal-day-parent-form { display: flex; align-items: baseline; flex-wrap: wrap; gap: 3px; max-width: 100%; }
.cal-day-parent-select {
  font: inherit;
  font-size: 0.84rem;
  font-weight: 700;
  border: none;
  background: transparent;
  padding: 0;
  margin: 0;
  appearance: none;
  -webkit-appearance: none;
  max-width: 100%;
  cursor: pointer;
}

/* Only rendered when the overnight parent differs from the daytime one
   (see day_night_parents() in app.py) -- most days have no exchange_time
   and so are the same person day and night. Folded onto the same line as
   the picker ("Lisa → Mat") instead of a whole separate icon+text row.
   Read-only here (unlike the day picker): "night" is derived from the
   day's exchange_time, not its own stored field, so changing it belongs
   on the day view where the actual time gets set.

   Styled as the PRIMARY name on a split day -- bigger/bolder than the day
   picker next to it, and it's night_color (not day_color) that the cell's
   left-border match now too (see calendar.html) -- because Mat wants "the
   color of the day" to reflect who has Owen at the *end* of the day, not
   the start. .has-split on the form (calendar.html) shrinks the picker
   down to a secondary label in the same move -- see below. */
.cal-day-night-suffix { font-size: 0.84rem; font-weight: 700; white-space: nowrap; }
.cal-day-parent-form.has-split .cal-day-parent-select { font-size: 0.74rem; font-weight: 600; }

/* A tiny superscript mark, not a bordered pill -- present but not
   competing for attention with the custody name it sits next to. */
.cal-day-swap-mark { font-size: 0.74rem; color: var(--muted); }

.cal-day-event-text {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.74rem;
  font-weight: 600;
  margin-top: 4px;
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.cal-day-event-text:hover { text-decoration: underline; }
.cal-day-event-dot { width: 5px; height: 5px; border-radius: 50%; flex: 0 0 auto; }

/* Exchange time/note and the day note each get their own real line now
   that the taller cell has room for them -- ellipsized (not wrapped) if
   a single line still isn't enough, since wrapping would silently blow
   past the cell's fixed height (this happened before, see the commit
   history). The full, un-truncated text is always in .cal-day-popover
   on hover, and one tap away on the day view either way. */
.cal-day-info {
  display: block;
  margin-top: 3px;
  font-size: 0.72rem;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.cal-day-exchange { color: var(--accent); font-weight: 600; }

.cal-day-popover {
  position: absolute;
  top: calc(100% + 4px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  min-width: 150px;
  max-width: 220px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.1s ease;
  text-align: left;
  cursor: default;
}
.cal-day:hover .cal-day-popover {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
.popover-line { font-size: 0.75rem; color: var(--text); overflow-wrap: anywhere; margin: 3px 0; }
.popover-line:first-child { margin-top: 0; }
.popover-line:last-child { margin-bottom: 0; }
.exchange-line { color: var(--accent); font-weight: 600; }
.popover-sub { color: var(--muted); font-size: 0.7rem; margin-top: -1px; }

@media (max-width: 640px) {
  .cal-grid { gap: 2px; }
  .cal-day { height: 72px; padding: 4px; font-size: 0.8rem; }
  .cal-day-parent-select, .cal-day-event-text { font-size: 0.62rem; }
  .cal-day-night-suffix { font-size: 0.66rem; }
  .cal-day-parent-form.has-split .cal-day-parent-select { font-size: 0.56rem; }
  .cal-day-info { font-size: 0.58rem; }
}

/* Day detail */
.back-link { display: inline-block; margin-bottom: 8px; font-size: 0.9rem; }

.timeline-wrap { margin: 16px 0; }
.timeline-bar {
  position: relative;
  height: 28px;
  border-radius: 6px;
  overflow: hidden;
  background: #eee;
  border: 1px solid var(--border);
}
.timeline-segment { position: absolute; top: 0; bottom: 0; }
.timeline-marker {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  background: var(--text);
  transform: translateX(-1px);
}
.timeline-ticks {
  position: relative;
  height: 16px;
  margin-top: 2px;
}
.timeline-ticks span {
  position: absolute;
  transform: translateX(-50%);
  font-size: 0.65rem;
  color: var(--muted);
}
.timeline-ticks span:first-child { transform: translateX(0); }
.timeline-ticks span:last-child { transform: translateX(-100%); }
.timeline-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 10px;
  font-size: 0.85rem;
}
.timeline-legend .legend-item { display: flex; align-items: center; gap: 5px; }
.pattern-hint { color: var(--muted); font-size: 0.9rem; }
.day-form fieldset { border: 1px solid var(--border); border-radius: 8px; padding: 10px 14px; margin: 12px 0; }
.day-form fieldset label { flex-direction: row; align-items: center; gap: 6px; margin: 6px 0; color: var(--text); }
.day-form legend { color: var(--muted); font-size: 0.85rem; padding: 0 6px; }
.note-label .hint { color: var(--muted); font-weight: 400; }

.exchange-banner {
  background: #eef3ff;
  border: 1px solid var(--accent);
  color: var(--accent);
  border-radius: 8px;
  padding: 8px 12px;
  font-weight: 600;
  font-size: 0.9rem;
  margin: 10px 0;
}
.transition-hint { margin-top: 0; }
.day-form fieldset input[type="text"],
.day-form fieldset input[type="time"] { flex: 1; min-width: 0; }
.meta { color: var(--muted); font-size: 0.8rem; }

/* Pattern grid */
.pattern-form { margin-top: 12px; }
.pattern-settings { display: flex; gap: 24px; flex-wrap: wrap; margin-bottom: 8px; }
.hint { color: var(--muted); font-size: 0.8rem; }
/* overflow-x here (not just min-width:0 below) is a deliberate belt-and-
   suspenders pair: min-width:0 on the grid items is what actually lets the
   7 columns shrink to fit most of the time, but three stacked inputs per
   cell (select + transition time + note, added for the default-schedule
   transition feature) can still be too much for a really narrow phone --
   overflow-x here contains that scroll to the grid itself rather than
   letting it push the *page body* into horizontal scroll, which actually
   happened during testing before this was added. */
.pattern-week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; margin-bottom: 16px; overflow-x: auto; }
.pattern-cell { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.pattern-cell-dow { font-size: 0.75rem; color: var(--muted); font-weight: 600; text-align: center; }
.pattern-transition, .pattern-note { font-size: 0.75rem; min-width: 0; }

@media (max-width: 640px) {
  .pattern-week { grid-template-columns: repeat(7, 1fr); }
  .pattern-cell select, .pattern-cell input { font-size: 0.7rem; padding: 4px; }
}

.account-form { max-width: 320px; display: flex; flex-direction: column; gap: 12px; margin-top: 8px; }

/* Events */
.event-form {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px;
  margin: 12px 0 20px;
}
.event-form label { min-width: 140px; flex: 1; }
.event-form button { align-self: flex-end; }
.event-form .checkbox-label {
  flex-direction: row;
  align-items: center;
  gap: 6px;
  min-width: auto;
  flex: 0 0 auto;
  color: var(--text);
}
.event-form .checkbox-label input { width: auto; padding: 0; }
.event-form .note-field { flex-basis: 100%; }
.time-fields:not([hidden]) { display: flex; gap: 12px; flex: 1 1 100%; }
.time-fields label { min-width: 120px; }

.event-list { list-style: none; padding: 0; margin: 0; }
.event-list li { padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
.event-list .event-row { display: flex; align-items: center; gap: 8px; }
.event-list .hint { margin-left: auto; }
.event-note { margin: 4px 0 0 20px; color: var(--muted); font-size: 0.82rem; overflow-wrap: anywhere; }

.add-event { margin-top: 16px; }
.add-event summary { cursor: pointer; color: var(--accent); font-size: 0.9rem; }
.add-event .event-form { margin-top: 10px; }

.delete-form { margin-top: 20px; }
button.danger { background: #c0392b; }

/* Finances */
.manage-link { font-size: 0.8rem; font-weight: 400; margin-left: 10px; }

.charge-list { list-style: none; padding: 0; margin: 0; }
.charge-row { padding: 8px 0; border-bottom: 1px solid var(--border); }
/* .charge-form and .charge-delete-form are two separate <form> elements
   (Save submits the edit, the × submits a delete) -- display:contents
   makes each form "disappear" for layout purposes while keeping its own
   submit behavior, so their fields flow directly into .charge-row-main's
   single flex-wrap row instead of nesting a wrapping row inside a
   wrapping row. Save and the × themselves live outside both forms in
   .charge-actions (each still points at its form via the button's
   form="" attribute) so that group is always ONE flex item -- two
   independent items can end up wrapping onto different lines from each
   other, but one item can't split from itself, which is what keeps the
   two buttons on the same line as each other no matter how the rest of
   the row wraps. */
.charge-row-main { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.charge-form, .charge-delete-form { display: contents; }
.charge-label { flex: 1 1 140px; font-size: 0.9rem; }
.charge-amount-wrap { display: flex; align-items: center; gap: 2px; font-size: 0.9rem; }
.charge-amount { width: 70px; }
.charge-paid-by { font-weight: 600; }
.charge-reimbursement { font-size: 0.85rem; color: var(--muted); }
.charge-note { flex: 1 1 120px; min-width: 100px; }
.charge-actions { display: flex; gap: 4px; flex: 0 0 auto; }
.charge-actions button { padding: 4px 10px; font-size: 0.8rem; margin: 0; }
.charge-owed-hint { margin: 4px 0 0; font-size: 0.8rem; color: var(--muted); }
.charge-owed-hint strong { color: var(--text); }

.charge-totals {
  text-align: right;
  font-size: 0.9rem;
  color: var(--muted);
  padding: 10px 0;
}
.charge-totals strong { color: var(--text); font-size: 1.05rem; }
.charge-totals.owed strong { color: #c0392b; }
.charge-totals.ahead strong { color: #1b6b2c; }

@media (max-width: 640px) {
  .charge-row-main { gap: 6px; }
  .charge-label { flex-basis: 100%; }
}
