/* ============================================================
   Camping Planner — Eagle Ridge
   Self-contained, offline-first. System fonts (no CDN).
   ============================================================ */
:root {
  --bg:        #0f1512;
  --bg-2:      #141b17;
  --surface:   #18211c;
  --surface-2: #1e2822;
  --border:    #26332b;
  --border-2:  #33463a;
  --text:      #e8efe9;
  --text-dim:  #a7bcb0;  /* ~9:1 on --bg */
  --text-mute: #82948a;  /* ~5.7:1 on --bg (was #6b7d71 ≈ 4.1:1, under AA) */

  --pine:      #4ea777;   /* primary accent */
  --pine-deep: #2f7d55;
  --ember:     #e8a24a;   /* warm accent */

  /* assignee colours */
  --woods:      #5aa9e6;  --woods-bg:    rgba(90,169,230,.14);
  --motawehs:   #57c98a;  --motawehs-bg: rgba(87,201,138,.14);
  --both:       #c58bef;  --both-bg:     rgba(197,139,239,.14);

  --ok:     #57c98a;
  --warn:   #e8a24a;
  --danger: #ef8f8f;   /* destructive-action hover only (delete); errors/warnings use --warn */
  --font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;
  --radius: 12px;    /* cards / containers */
  --radius-sm: 8px;  /* buttons / controls */
  --radius-xs: 6px;  /* inputs / small */
  --radius-pill: 999px;
  --shadow: 0 1px 0 rgba(255,255,255,.02), 0 8px 24px rgba(0,0,0,.35);

  /* the app is dark-only; without this, browsers render native controls (select
     popups, scrollbars, spinners) in light mode regardless of our own styling */
  color-scheme: dark;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  color: var(--text);
  background:
    radial-gradient(1200px 600px at 80% -10%, rgba(78,167,119,.10), transparent 60%),
    var(--bg);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* ---------- Top bar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  background: rgba(15,21,18,.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.topbar-inner {
  max-width: 1080px; margin: 0 auto;
  padding: 12px 20px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  flex-wrap: wrap;
}
.brand { display: flex; align-items: center; gap: 12px; }
.brand-mark { font-size: 26px; line-height: 1; }
.brand-text h1 { font-size: 17px; font-weight: 650; letter-spacing: -.01em; }
.brand-text p { font-size: 12.5px; color: var(--text-dim); }
.topbar-actions { display: flex; align-items: center; gap: 8px; }

.btn {
  font: inherit; font-size: 13.5px; font-weight: 550;
  color: var(--text); background: var(--surface-2);
  border: 1px solid var(--border-2); border-radius: var(--radius-sm);
  padding: 8px 13px; cursor: pointer;
  transition: border-color .15s, background .15s, transform .05s;
}
.btn:hover { border-color: var(--pine); }
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--pine-deep); border-color: var(--pine); color: #eafff2; }
.btn-primary:hover { background: var(--pine); }
.btn-ghost { background: transparent; color: var(--text-dim); }

.net-badge { display: inline-flex; align-items: center; color: var(--ok); margin-right: 2px; }
.net-badge.offline { color: var(--warn); }
.net-badge.syncing { color: var(--woods); }
.net-ic { width: 17px; height: 17px; }

/* ---------- Inline line icons ---------- */
.ic { width: 15px; height: 15px; flex: none; display: inline-block; vertical-align: -2px; }
.cat-ic { width: 16px; height: 16px; color: var(--text-dim); opacity: .95; }
.slot-ic { color: var(--ember); }
.note-ic { width: 15px; height: 15px; color: var(--ember); margin-top: 1px; }

/* ---------- Tabs ---------- */
.tabs {
  max-width: 1080px; margin: 0 auto;
  padding: 0 12px; display: flex; gap: 2px; overflow-x: auto;
}
.tab {
  font: inherit; font-size: 14px; font-weight: 550;
  color: var(--text-dim); background: none; border: none;
  padding: 11px 15px; cursor: pointer; white-space: nowrap;
  border-bottom: 2px solid transparent;
  display: flex; align-items: center; gap: 7px;
}
.tab:hover { color: var(--text); }
.tab.is-active { color: var(--text); border-bottom-color: var(--pine); }
.tab-ic { opacity: .8; }
.tab.is-active .tab-ic { opacity: 1; color: var(--pine); }

/* ---------- Layout ---------- */
.container { max-width: 1080px; margin: 0 auto; padding: 18px 20px 60px; }

.notes {
  background: linear-gradient(180deg, var(--surface), var(--bg-2));
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 14px 16px; margin-bottom: 16px;
}
.notes-summary {
  cursor: pointer; list-style: none; font-size: 13px; font-weight: 600; color: var(--text);
  display: flex; align-items: center; justify-content: space-between;
}
.notes-summary::-webkit-details-marker { display: none; }
.notes-summary::after { content: "▾"; color: var(--text-mute); font-size: 11px; }
.notes[open] .notes-summary::after { content: "▴"; }
.notes[open] .notes-summary { margin-bottom: 10px; }
#site-notes { display: grid; gap: 6px; }
.notes .note { display: flex; gap: 9px; font-size: 13px; color: var(--text-dim); align-items: flex-start; }
.notes .note strong { color: var(--text); font-weight: 600; }

/* ---------- Toolbar / filters ---------- */
.toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin-bottom: 14px;
}
.filters { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.filters label { font-size: 12px; color: var(--text-mute); display: flex; flex-direction: column; gap: 4px; }
.toolbar-2 { display: flex; align-items: center; gap: 16px; }
.check-inline { flex-direction: row; align-items: center; gap: 7px; color: var(--text-dim); font-size: 13px; }
select, input[type="text"], input[type="number"], input[type="password"], textarea {
  font: inherit; font-size: 13.5px; color: var(--text);
  background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: var(--radius-sm); padding: 7px 9px;
  color-scheme: dark;
}
select:focus, input:focus { outline: none; border-color: var(--pine); }

.progress { font-size: 13px; color: var(--text-dim); display: flex; gap: 16px; flex-wrap: wrap; }
.progress b { color: var(--text); }

/* ---------- Panels ---------- */
.panel { display: none; }
.panel.is-active { display: block; }

.cat-group { margin-bottom: 22px; }
.cat-head {
  display: flex; align-items: center; gap: 8px;
  margin: 0 2px 8px; padding: 4px 2px 6px;
  border-bottom: 1px solid var(--border); cursor: pointer; user-select: none;
}
.cat-head h3 { font-size: 14px; font-weight: 650; letter-spacing: .01em; }
.cat-head .count { font-size: 12px; color: var(--text-mute); }
.cat-caret { display: inline-flex; color: var(--text-mute); transition: transform .18s; }
.cat-caret svg { width: 14px; height: 14px; }
.cat-group.collapsed .cat-caret { transform: rotate(-90deg); }
.cat-group.collapsed .table-wrap { display: none; }

/* ---------- Tables ---------- */
/* Chrome kept minimal: no boxed card, hairline row rules, quiet hover.
   Numbers are right-aligned tabular figures so they stack and scan cleanly. */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; font-variant-numeric: tabular-nums; }
thead th {
  text-align: left; font-weight: 600; font-size: 11px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-mute);
  padding: 8px 12px 9px; border-bottom: 1px solid var(--border-2); white-space: nowrap;
}
thead th.num { text-align: right; padding-right: 16px; }
tbody td { padding: 9px 12px; border-bottom: 1px solid rgba(255,255,255,.045); vertical-align: middle; }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: rgba(120,180,140,.045); }
/* done / N/A / already-have = deactivated. Strike + dim only the item text and
   its leading marker; the Who avatars, chips, qty and notes stay fully legible. */
tbody tr.done td[data-label=""], tbody tr.na td[data-label=""], tbody tr.covered td[data-label=""] { opacity: .5; }
tbody tr.covered td:first-child { box-shadow: inset 3px 0 0 var(--pine); } /* green = you already have it */
tbody tr.done .item-name, tbody tr.na .item-name, tbody tr.covered .item-name { text-decoration: line-through; color: var(--text-mute); }
.item-name { font-weight: 600; color: var(--text); }
.muted { color: var(--text-mute); }
td.num, th.num { text-align: right; }
td.notes-cell { color: var(--text-dim); font-size: 12.5px; min-width: 160px; }
tbody td[data-label="Item"] { min-width: 200px; }   /* keep the item name column prominent */
/* header icons */
.th-in { display: inline-flex; align-items: center; gap: 5px; }
.hi { width: 12px; height: 12px; flex: none; opacity: .55; }
.tl-field label .hi { width: 11px; height: 11px; }

/* assignee pill = a styled <select> */
.assignee {
  font: inherit; font-size: 12px; font-weight: 600;
  border-radius: var(--radius-pill); padding: 4px 10px; cursor: pointer;
  border: 1px solid transparent; -webkit-appearance: none; appearance: none;
  text-align: center;
}
.assignee.Woods    { color: var(--woods);    background: var(--woods-bg);    border-color: rgba(90,169,230,.35); }
.assignee.Motawehs { color: var(--motawehs); background: var(--motawehs-bg); border-color: rgba(87,201,138,.35); }
.assignee.Both     { color: var(--both);     background: var(--both-bg);     border-color: rgba(197,139,239,.35); }
.assignee.blank    { color: var(--text-mute); background: var(--surface-2);   border-color: var(--border-2); }

/* "Who" avatar: colour-coded initial for fast identity; native select overlaid for editing */
.who { position: relative; display: inline-flex; align-items: center; border-radius: var(--radius-pill); }
.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 50%;
  font-size: 12px; font-weight: 700; border: 1px solid transparent; user-select: none;
}
/* Party avatars are coloured inline (style="...") from the board's own party.color —
   there's no fixed family palette any more, since a board can have any parties. */
/* unassigned draws a little attention (amber), since it still needs an owner */
.avatar.av-blank    { color: var(--ember);    background: #241f16; border-color: rgba(232,162,74,.45); }
.avatar.av-everyone { color: var(--text-dim); background: var(--surface-2); border-color: var(--border-2); font-size: 9.5px; }
.assignee-sel { position: absolute; inset: 0; width: 100%; opacity: 0; cursor: pointer; }
/* keyboard focus is visible even though the select itself is transparent */
.who:focus-within { outline: 2px solid var(--pine); outline-offset: 2px; }

/* editable chips (Sharing / Get / Split) */
.chip {
  font: inherit; font-size: 11.5px; font-weight: 600;
  border-radius: var(--radius-pill); padding: 4px 12px; cursor: pointer;
  border: 1px solid var(--border-2); background: var(--surface-2); color: var(--text-dim);
  -webkit-appearance: none; appearance: none; text-align: center;
}
.chip:focus { outline: none; border-color: var(--pine); }
/* Colour comes from the data: only "Buy" needs action, so only it pops.
   Have / N/A (nothing to do) recede; Borrow is a quiet middle. */
.chip.get-Have   { color: var(--text-dim);  background: var(--surface-2);     border-color: var(--border-2); }
.chip.get-Buy    { color: var(--ember);     background: rgba(232,162,74,.18); border-color: rgba(232,162,74,.45); font-weight: 700; }
.chip.get-Borrow { color: var(--woods);     background: rgba(90,169,230,.10); border-color: rgba(90,169,230,.28); }
.chip.get-NA     { color: var(--text-mute); background: transparent;          border-color: var(--border); }
/* the Split chip's colour used to be per-family CSS classes; party ids are now
   arbitrary, so it keeps the neutral .chip look (a proper per-party chip palette
   is Phase 3's job). */

/* chip with a leading value icon */
.chip-wrap { display: inline-flex; align-items: center; gap: 6px; }
.chip-ic { width: 13px; height: 13px; color: var(--text-mute); }
.chip-wrap.get-Buy    .chip-ic { color: var(--ember); }
.chip-wrap.get-Borrow .chip-ic { color: var(--woods); }

/* meal-type dropdown (drives the icon beside it) — a chip pill, loosely colour-matched
   to the coffee/sun/moon/cookie icon it selects; Other stays neutral like its fork icon. */
.chip.mealtype-Breakfast { color: var(--ember);    background: rgba(232,162,74,.14);  border-color: rgba(232,162,74,.35); }
.chip.mealtype-Lunch     { color: var(--woods);    background: rgba(90,169,230,.10);  border-color: rgba(90,169,230,.28); }
.chip.mealtype-Dinner    { color: var(--both);     background: rgba(197,139,239,.10); border-color: rgba(197,139,239,.28); }
.chip.mealtype-Snack     { color: var(--motawehs); background: rgba(87,201,138,.10);  border-color: rgba(87,201,138,.28); }
.chip.mealtype-Other     { color: var(--text-mute);background: transparent;           border-color: var(--border); }

/* "already have it" marker on a covered shopping row */
.cov-x { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; color: var(--ok); }
.cov-x .ic { width: 15px; height: 15px; }

.check { width: 18px; height: 18px; accent-color: var(--pine); cursor: pointer; }
/* N/A items show an ✗ instead of a checkbox (considered, not getting it) */
.na-x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 4px; flex: none;
  border: 1px solid var(--border-2); color: var(--text-mute);
  font-size: 12px; font-weight: 700; line-height: 1; user-select: none;
}
.tag { font-size: 11px; padding: 3px 9px; border-radius: var(--radius-pill); background: var(--surface-2); color: var(--text-dim); border: 1px solid var(--border-2); }

.cell-edit {
  width: 100%; background: transparent; border: 1px solid transparent;
  border-radius: var(--radius-xs); padding: 5px 7px; color: var(--text); font: inherit; font-size: 13px;
  line-height: 1.45;
}
.cell-edit:hover { border-color: var(--border-2); }
.cell-edit:focus { border-color: var(--pine); background: var(--surface-2); outline: none; }
textarea.cell-edit {
  display: block; resize: none; overflow: hidden;
  white-space: pre-wrap; overflow-wrap: anywhere; min-height: 30px;
}
/* clamped to two lines for breathing room; expands while focused for editing */
textarea.cell-clamp { height: 2.9em; overflow: hidden; }
textarea.cell-clamp.editing { height: auto; max-height: 260px; overflow-y: auto; }
.cell-edit.item-edit { font-weight: 600; color: var(--text); font-size: 14px; }
tbody tr.done .cell-edit.item-edit, tbody tr.na .cell-edit.item-edit, tbody tr.covered .cell-edit.item-edit { text-decoration: line-through; color: var(--text-mute); }
input.num-input { width: 52px; text-align: right; padding: 6px 2px; font-variant-numeric: tabular-nums; }

/* row action buttons (duplicate / delete): secondary, progressively revealed on hover */
.row-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--radius-sm);
  background: transparent; border: 1px solid var(--border); color: var(--text-mute);
  cursor: pointer; opacity: 0;
  transition: opacity .15s, color .15s, border-color .15s, background .15s, transform .05s;
}
tbody tr:hover .row-btn, .tl-meal:hover .row-btn, .row-btn:focus-visible { opacity: 1; }
.row-btn:active { transform: scale(.93); }
.row-btn svg { display: block; }
.del-btn:hover { color: var(--danger); border-color: rgba(239,143,143,.55); background: rgba(239,143,143,.12); }
.dup-btn:hover { color: var(--pine); border-color: var(--pine); background: rgba(78,167,119,.10); }
td.act { width: 84px; text-align: right; white-space: nowrap; }
td.act .row-btn + .row-btn { margin-left: 4px; }
/* mobile-only "tap to edit" chevron */
.exp-btn {
  display: none; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--radius-sm);
  background: transparent; border: 1px solid var(--border); color: var(--text-mute);
  cursor: pointer; transition: transform .15s, color .15s, border-color .15s;
}
.exp-btn:hover { color: var(--text); border-color: var(--border-2); }

/* per-table add button (in each group header) */
.mini-add {
  margin-left: auto; font: inherit; font-size: 12px; font-weight: 600;
  color: var(--pine); background: transparent; border: 1px solid var(--border-2);
  border-radius: var(--radius-sm); padding: 5px 11px; cursor: pointer; white-space: nowrap;
  transition: border-color .15s, background .15s;
}
.mini-add:hover { border-color: var(--pine); background: rgba(78,167,119,.10); }
/* invisible UI: the per-section "+ Add" only shows on hover/focus of its section
   (pointer devices); on touch (hover:none) it stays visible since there's no hover. */
@media (hover: hover) {
  .mini-add { opacity: 0; transition: opacity .14s ease, border-color .15s, background .15s; }
  .cat-group:hover .mini-add, .cat-group:focus-within .mini-add,
  .tl-day:hover .mini-add,   .tl-day:focus-within .mini-add { opacity: 1; }
}

/* add-row button */
.add-row { padding: 10px 2px 2px; }
.add-btn {
  font: inherit; font-size: 13px; font-weight: 550; color: var(--text-dim);
  background: transparent; border: 1px dashed var(--border-2); border-radius: var(--radius);
  padding: 10px 14px; cursor: pointer; width: 100%;
  transition: border-color .15s, color .15s;
}
.add-btn:hover { color: var(--text); border-color: var(--pine); }

/* ---------- Meals timeline ---------- */
.timeline { margin-top: 4px; }
.tl-day { position: relative; padding-left: 26px; }
.tl-day::before { content: ""; position: absolute; left: 6px; top: 16px; bottom: 0; width: 2px; background: var(--border); }
.tl-day:last-child::before { display: none; }
.tl-daymark { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.tl-dot { position: absolute; left: 0; top: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--pine); border: 3px solid var(--bg); box-sizing: content-box; }
.tl-daymark h3 { font-size: 14px; font-weight: 650; letter-spacing: .01em; }
.tl-daymark .mini-add { margin-left: auto; }
.tl-meals { display: flex; flex-direction: column; gap: 10px; margin-bottom: 22px; }
.tl-meal { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; transition: border-color .15s; }
.tl-meal:hover { border-color: var(--border-2); }
.tl-meal.done .check { opacity: .6; }
.tl-meal.done .tl-dish { text-decoration: line-through; color: var(--text-mute); }
.tl-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tl-slot { width: 112px; flex: 0 0 112px; font-size: 11px; text-transform: uppercase; letter-spacing: .05em; font-weight: 600; color: var(--text-mute); }
.tl-dish { flex: 1 1 150px; min-width: 130px; font-size: 15px; }
.tl-actions { display: inline-flex; margin-left: auto; }
.tl-actions .row-btn + .row-btn { margin-left: 4px; }
.tl-body { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 8px 16px; margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border); }
.tl-field { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tl-field label { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-mute); }
.tl-field .cell-edit { font-size: 13px; }
.tl-num { max-width: 120px; }
.tl-num .num-input { text-align: left; width: 60px; }

/* ---------- Summary (bento) ---------- */
.bento { display: grid; grid-template-columns: repeat(6, 1fr); gap: 14px; }
.b-workload { grid-column: span 4; }
.b-est { grid-column: span 2; }
.b-cell { grid-column: span 2; }
.b-cost { grid-column: span 6; }
.b-est .big.money { margin-top: 6px; }
.b-cost .cost-rows { display: flex; gap: 28px; flex-wrap: wrap; margin-top: 4px; }
.b-cost .split-row { border: none; padding: 4px 0; }
@media (max-width: 720px) {
  .bento { grid-template-columns: 1fr 1fr; }
  .b-workload, .b-cost { grid-column: span 2; }
  .b-est, .b-cell { grid-column: span 1; }
}
.mini-bar { height: 6px; border-radius: 4px; background: var(--surface-2); overflow: hidden; margin-top: 12px; }
.mini-bar > span { display: block; height: 100%; background: var(--pine); border-radius: 4px; transition: width .3s; }
.mini-pct { font-size: 11px; color: var(--text-mute); margin-top: 6px; }
.card .big .of { font-size: 16px; color: var(--text-dim); font-weight: 500; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px; margin-bottom: 20px; }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; }
.card h4 { font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-mute); margin-bottom: 10px; }
.card .big { font-size: 26px; font-weight: 700; letter-spacing: -.02em; }
.card .big.money::before { content: "$"; font-size: 16px; color: var(--text-dim); vertical-align: 8px; margin-right: 1px; }
.split-row { display: flex; align-items: center; justify-content: space-between; padding: 6px 0; font-size: 13.5px; border-bottom: 1px dashed var(--border); }
.split-row:last-child { border-bottom: none; }
.dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 7px; vertical-align: middle; }
/* dot/bar segment colours are now set inline (style="background:...") from party.color */

.bar { height: 10px; border-radius: var(--radius-xs); background: var(--surface-2); overflow: hidden; display: flex; margin-top: 10px; }
.bar span { display: block; height: 100%; }

/* ---------- Activity / audit log ---------- */
.audit { margin-top: 14px; }
.audit-head { display: flex; align-items: center; gap: 8px; margin-bottom: 2px; }
.audit-head h4 { margin: 0; }
.audit-title-ic { color: var(--text-mute); }
#audit-refresh { margin-left: auto; }
.audit-list { list-style: none; margin: 6px 0 0; padding: 0; max-height: 460px; overflow-y: auto; }
.audit-empty { color: var(--text-mute); font-size: 13px; padding: 10px 2px; line-height: 1.5; }
.audit-item { display: flex; gap: 11px; padding: 9px 2px; border-top: 1px solid var(--border); align-items: flex-start; }
.audit-item:first-child { border-top: none; }
.audit-ic { flex: none; width: 26px; height: 26px; border-radius: var(--radius-pill); display: inline-flex; align-items: center; justify-content: center; background: var(--surface-2); color: var(--text-dim); margin-top: 1px; }
.audit-ic .ic { width: 14px; height: 14px; }
.act-create .audit-ic { color: var(--ok); }
.act-delete .audit-ic { color: var(--ember); }
.act-restore .audit-ic { color: var(--woods); }
.act-reset .audit-ic, .act-seed .audit-ic { color: var(--text-mute); }
.audit-body { min-width: 0; flex: 1; }
.audit-text { font-size: 13.5px; color: var(--text-dim); line-height: 1.4; }
.audit-text b { color: var(--text); font-weight: 600; }
.audit-kind { display: inline-block; font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-mute); background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-xs); padding: 1px 6px; margin-right: 7px; vertical-align: 1px; }
.audit-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; font-size: 11.5px; color: var(--text-mute); margin-top: 3px; }
.audit-time { color: var(--text-dim); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.audit-rel { color: var(--text-mute); white-space: nowrap; }
.audit-dev { color: var(--text-dim); white-space: nowrap; }

.legend { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12.5px; color: var(--text-dim); margin-top: 10px; }
.legend span { display: flex; align-items: center; }

/* ---------- Footer ---------- */
.foot {
  max-width: 1080px; margin: 0 auto; padding: 20px;
  display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  color: var(--text-mute); font-size: 12px; border-top: 1px solid var(--border);
}

/* ---------- Mobile: compact cards ---------- */
@media (max-width: 720px) {
  body { overflow-x: hidden; }
  .container { padding: 12px 12px 64px; }

  /* header */
  .topbar-inner { padding: 10px 12px; gap: 10px; }
  .brand-mark { font-size: 22px; }
  .brand-text h1 { font-size: 16px; }
  .brand-text p { font-size: 11px; line-height: 1.35; }
  /* Share / Export / Install / kebab all stay reachable on mobile (the kebab holds
     Edit trip details + Manage people, which have no other entry point) — they wrap
     to their own row under the brand if they don't fit alongside it. */
  .topbar-actions { gap: 6px; flex-wrap: wrap; row-gap: 8px; }
  .btn { padding: 9px 13px; font-size: 13px; }
  .tabs { padding: 0 8px; }
  .tab { padding: 11px 12px; font-size: 14px; }
  .hide-sm { display: none; }
  .dup-btn { display: none; }

  .notes .note { font-size: 12px; }
  /* Who | Category on row 1; Outstanding + count share row 2 */
  .toolbar { flex-direction: column; align-items: stretch; gap: 10px; }
  .filters { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
  .filters label { font-size: 11px; gap: 5px; }
  .filters select { width: 100%; padding: 9px 10px; }
  .toolbar-2 { justify-content: space-between; width: 100%; }

  /* tables become tight spreadsheet rows; Sharing/Get/Notes live behind a tap */
  thead { display: none; }
  table, tbody { display: block; width: 100%; }
  .table-wrap { overflow: visible; }
  /* category headers stick under the top bar as you scroll */
  .cat-head { position: sticky; top: var(--stick-top, 54px); z-index: 6; background: var(--bg); margin-bottom: 4px; padding: 9px 4px; }
  tbody tr {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 6px 10px; padding: 9px 12px; border-bottom: 1px solid var(--border);
  }
  tbody td { display: flex; align-items: center; padding: 0; border: none; min-width: 0; }
  tbody td::before { display: none; }
  /* swipe: cells slide with the gesture, row tints green (pack) / red (delete) */
  tbody tr { transition: background .15s; }
  tbody tr td { transform: translateX(var(--sx, 0px)); }
  tbody tr:not(.sw-active) td { transition: transform .2s ease; }

  /* collapsed row: checkbox · item (grows) · qty · who · chevron */
  tbody td[data-label=""] { order: 1; flex: 0 0 auto; }
  tbody td[data-label="Item"] { order: 2; flex: 1 1 auto; min-width: 60px; }
  tbody td[data-label="Item"] .cell-edit { font-size: 15px; font-weight: 600; }
  tbody td[data-label="Qty"] { order: 3; flex: 0 0 auto; }
  tbody td[data-label="Who"],
  tbody td[data-label="Who cooks"],
  tbody td[data-label="Who buys"] { order: 4; flex: 0 0 auto; }
  tbody td.act { order: 5; flex: 0 0 auto; width: auto; }

  /* collapsed shows only the chevron; dup/delete hidden until expanded */
  .exp-btn { display: inline-flex; }
  td.act .row-btn { display: none; }
  tbody tr.expanded .exp-btn { transform: rotate(180deg); }
  tbody tr.expanded td.act .del-btn { display: inline-flex; }

  /* detail cells: hidden until the row is expanded */
  tbody td[data-label="Est $"], tbody td[data-label="Actual $"],
  tbody td[data-label="Sharing"], tbody td[data-label="Get"],
  tbody td[data-label="Split"], tbody td.notes-cell { display: none; }
  tbody tr.expanded td[data-label="Est $"],
  tbody tr.expanded td[data-label="Actual $"],
  tbody tr.expanded td[data-label="Sharing"],
  tbody tr.expanded td[data-label="Get"],
  tbody tr.expanded td[data-label="Split"],
  tbody tr.expanded td.notes-cell {
    display: flex; order: 8; flex: 1 1 100%; align-items: center; gap: 10px; padding: 3px 0 3px 28px;
  }
  tbody tr.expanded td[data-label="Est $"]::before,
  tbody tr.expanded td[data-label="Actual $"]::before,
  tbody tr.expanded td[data-label="Sharing"]::before,
  tbody tr.expanded td[data-label="Get"]::before,
  tbody tr.expanded td[data-label="Split"]::before,
  tbody tr.expanded td.notes-cell::before {
    display: inline-block; content: attr(data-label);
    flex: 0 0 72px; font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-mute);
  }
  tbody tr.expanded td.notes-cell { align-items: flex-start; }
  tbody tr.expanded td.notes-cell .cell-edit { flex: 1 1 auto; width: auto; }
  /* divider between the collapsed row and its first detail field */
  tbody tr.expanded td[data-label="Sharing"],
  tbody tr.expanded td[data-label="Est $"] { margin-top: 6px; padding-top: 9px; border-top: 1px dashed var(--border); }

  input.num-input { width: 44px; padding: 4px 2px; text-align: right; }
  .chip { font-size: 12px; padding: 4px 11px; }
  .assignee { font-size: 11px; padding: 4px 10px; }
  .check, .na-x, .cov-x { width: 21px; height: 21px; }
  .avatar { width: 24px; height: 24px; font-size: 11px; }
  .stack .avatar + .avatar { margin-left: -7px; }
  .row-btn { width: 28px; height: 28px; opacity: 1; }
  .mini-add { padding: 6px 12px; font-size: 12.5px; }
  .add-btn { font-size: 14px; padding: 13px; }

  /* summary bento */
  .bento { grid-template-columns: 1fr 1fr; }
  .b-workload, .b-cost { grid-column: span 2; }
  .b-est, .b-cell { grid-column: span 1; }

  /* meals timeline (compact) */
  .tl-day { padding-left: 22px; }
  .tl-meal { position: relative; padding: 10px 12px; }
  .tl-head { gap: 6px 8px; }
  .tl-slot { width: auto; font-size: 10px; }
  .tl-dish { flex: 1 1 100%; order: 3; font-size: 15px; }
  .tl-actions { position: absolute; top: 10px; right: 12px; }
  .tl-body { grid-template-columns: 1fr; gap: 6px; margin-top: 8px; padding-top: 8px; }
  .tl-field label { font-size: 9.5px; }
  .tl-field .cell-edit { font-size: 12.5px; }
  .tl-field:has(.cell-edit:placeholder-shown) { display: none; }

  /* toast full-width */
  .toast { left: 12px; right: 12px; bottom: 14px; transform: translateY(20px); max-width: none; }
  .toast.show { transform: translateY(0); }
}

/* ---------- Toast (undo) ---------- */
.toast {
  position: fixed; left: 50%; bottom: 24px;
  transform: translateX(-50%) translateY(20px);
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border-2); border-radius: var(--radius);
  padding: 12px 16px; display: flex; align-items: center; gap: 16px;
  box-shadow: 0 12px 34px rgba(0,0,0,.5); font-size: 14px; z-index: 100;
  max-width: calc(100vw - 28px);
  opacity: 0; pointer-events: none;
  transition: opacity .18s ease, transform .18s ease;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); pointer-events: auto; }
.toast-msg { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.toast-action {
  font: inherit; font-size: 13px; font-weight: 700; color: var(--pine);
  background: transparent; border: none; cursor: pointer; padding: 2px 4px; white-space: nowrap; flex: none;
}
.toast-action:hover { text-decoration: underline; }
@media (max-width: 720px) {
  .toast { left: 12px; right: 12px; bottom: 14px; transform: translateY(20px); max-width: none; }
  .toast.show { transform: translateY(0); }
}

/* ---------- Sync banner ---------- */
.sync-banner { display: none; margin: 0 0 12px; padding: 8px 12px; border-radius: var(--radius-sm); font-size: 12.5px; font-weight: 600; text-align: center; }
.sync-banner.show { display: flex; align-items: center; justify-content: center; gap: 8px; }
.banner-ic { width: 16px; height: 16px; }
.sync-banner.offline { background: rgba(232,162,74,.14); color: var(--ember); border: 1px solid rgba(232,162,74,.3); }
.sync-banner.syncing { background: rgba(90,169,230,.12); color: var(--woods); border: 1px solid rgba(90,169,230,.28); }

/* ---------- Empty state ---------- */
.empty { text-align: center; padding: 44px 20px; color: var(--text-dim); }
.empty-emoji { font-size: 30px; margin-bottom: 10px; opacity: .9; }
.empty p { margin-bottom: 14px; font-size: 14px; }

/* ---------- Overflow menu (popover) ---------- */
.menu-wrap { position: relative; }
.popover {
  position: absolute; right: 0; top: calc(100% + 6px);
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: var(--radius);
  padding: 6px; min-width: 168px; box-shadow: var(--shadow); z-index: 30;
  display: flex; flex-direction: column; gap: 2px;
}
.popover[hidden] { display: none; }
.pop-item {
  text-align: left; font: inherit; font-size: 13.5px; color: var(--text);
  background: transparent; border: none; border-radius: var(--radius-sm); padding: 8px 10px; cursor: pointer;
}
.pop-item:hover { background: var(--surface); }

/* ---------- Accessibility ---------- */
:focus-visible { outline: 2px solid var(--pine); outline-offset: 2px; }
.tab:focus-visible, .btn:focus-visible, .row-btn:focus-visible,
.mini-add:focus-visible, .add-btn:focus-visible { outline: 2px solid var(--pine); outline-offset: 2px; }

/* ---------- Motion ---------- */
@keyframes fadeUp { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.cat-group, .tl-day, .bento > * { animation: fadeUp .3s cubic-bezier(.2,.7,.3,1) both; }
.cat-group:nth-child(2), .tl-day:nth-child(2), .bento > *:nth-child(2) { animation-delay: .04s; }
.cat-group:nth-child(3), .tl-day:nth-child(3), .bento > *:nth-child(3) { animation-delay: .08s; }
.cat-group:nth-child(4), .tl-day:nth-child(4), .bento > *:nth-child(4) { animation-delay: .12s; }
.cat-group:nth-child(5), .tl-day:nth-child(5), .bento > *:nth-child(5) { animation-delay: .16s; }
.cat-group:nth-child(n+6), .tl-day:nth-child(n+6) { animation-delay: .2s; }
.net-badge.syncing { animation: pulse 1s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}

/* ---------- Print ---------- */
@media print {
  :root { --bg: #fff; --text: #111; --text-dim: #333; --text-mute: #555; --surface: #fff; --surface-2: #fff; --border: #bbb; --border-2: #999; }
  body { background: #fff; color: #000; font-size: 11px; }
  .topbar-actions, .toolbar, .net-badge, .foot { display: none !important; }
  .topbar { position: static; backdrop-filter: none; }
  .tabs { display: none; }
  .panel { display: block !important; page-break-before: always; }
  .panel:first-of-type { page-break-before: avoid; }
  .table-wrap { overflow: visible; border: none; }
  thead th { position: static; color: #000; }
  .assignee { border: 1px solid #999 !important; color: #000 !important; background: #fff !important; }
  .notes { border: 1px solid #999; }
  a { color: #000; text-decoration: none; }
}

/* ---------- Board header edit ---------- */
.btn-icon { padding: 6px 9px; font-size: 15px; margin-left: 4px; }
.board-edit-form {
  max-width: 1080px; margin: 0 auto; padding: 0 20px 12px;
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px;
}
.board-edit-form[hidden] { display: none; }
.board-edit-form label { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: var(--text-dim); flex: 1 1 200px; }
.board-edit-form label.board-edit-nights-label { flex: 0 0 90px; }
.board-edit-form input {
  font: inherit; font-size: 14px; color: var(--text); background: var(--surface-2);
  border: 1px solid var(--border-2); border-radius: var(--radius-xs); padding: 7px 10px;
}
.board-edit-form input:focus { outline: none; border-color: var(--pine); }
#board-edit-nights { width: 100%; }
.board-edit-actions { display: flex; gap: 8px; }

/* Kebab menu items that require edit access (dimmed, not blocked — clicking still
   surfaces the "enter the passcode" hint via toast, matching hasEditAccess() gating). */
body.read-only .menu-edit-action { opacity: .55; }

/* ---------- Manage people panel ---------- */
.parties-panel { max-width: 1080px; margin: 0 auto; padding: 0 20px 14px; }
.parties-panel[hidden] { display: none; }
.parties-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.party-row {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 8px 10px;
}
.party-row .party-name {
  flex: 1 1 auto; min-width: 0; font: inherit; font-size: 14px; color: var(--text);
  background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: var(--radius-xs); padding: 7px 10px;
}
.party-row .party-name:focus { outline: none; border-color: var(--pine); }
.swatches { display: flex; gap: 6px; flex: none; }
.swatch {
  width: 22px; height: 22px; border-radius: 50%; border: 2px solid transparent;
  cursor: pointer; padding: 0; transition: border-color .15s, transform .05s;
}
.swatch:hover { transform: scale(1.1); }
.swatch:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }
.swatch.is-active { border-color: var(--text); box-shadow: 0 0 0 2px var(--bg); }
.parties-add-btn { margin-bottom: 10px; }

/* ---------- Passcode panel ---------- */
.passcode-panel {
  background: linear-gradient(180deg, var(--surface), var(--bg-2));
  border: 1px solid rgba(232,162,74,.35); border-radius: var(--radius);
  padding: 14px 16px; margin-bottom: 16px;
}
.passcode-msg { font-size: 13px; color: var(--text-dim); margin-bottom: 10px; }
.passcode-form { display: flex; gap: 8px; flex-wrap: wrap; }
.passcode-form input {
  font: inherit; font-size: 14px; color: var(--text); background: var(--surface-2);
  border: 1px solid var(--border-2); border-radius: var(--radius-xs); padding: 8px 10px; flex: 1 1 160px;
}
.passcode-form input:focus { outline: none; border-color: var(--pine); }
.passcode-error { color: var(--warn); font-size: 12.5px; margin-top: 8px; }

/* ---------- Save-this-link notice: a slim, full-bleed ember bar above the top
   bar (first child of body). Shown once per device per planner until copied
   or dismissed. Not sticky, so it scrolls away with the rest of the page. ---------- */
.savelink-bar {
  background: linear-gradient(180deg, rgba(232,162,74,.16), rgba(232,162,74,.05));
  border-bottom: 1px solid rgba(232,162,74,.3);
}
.savelink-bar[hidden] { display: none; }
.savelink-bar-inner {
  max-width: 1080px; margin: 0 auto; padding: 9px 20px;
  display: flex; align-items: center; gap: 10px;
}
.savelink-ic { color: var(--ember); flex: none; }
.savelink-msg {
  flex: 1 1 auto; min-width: 0; font-size: 12.5px; color: var(--text-dim);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 3px 9px;
}
.savelink-msg b { color: var(--ember); font-weight: 650; }
.savelink-copy-link {
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--ember);
  background: none; border: none; padding: 2px; cursor: pointer;
}
.savelink-copy-link:hover { text-decoration: underline; }
.savelink-dismiss-btn {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--radius-xs);
  background: transparent; border: none; color: var(--text-mute);
  font-size: 16px; line-height: 1; cursor: pointer; transition: background .15s, color .15s;
}
.savelink-dismiss-btn:hover { background: rgba(255,255,255,.1); color: var(--text); }

/* ---------- Expiry warning banner (quiet, shown under 30 days, dismissible) ---------- */
.expiry-banner { display: none; align-items: center; justify-content: space-between; gap: 10px;
  margin: 0 0 12px; padding: 8px 12px; border-radius: var(--radius-sm); font-size: 12.5px; font-weight: 600;
  background: rgba(232,162,74,.14); color: var(--ember); border: 1px solid rgba(232,162,74,.3); }
.expiry-banner.show { display: flex; }

/* ---------- iOS "add to home screen" hint (quiet, one-time, dismissible) ---------- */
.ios-hint { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: 0 0 12px; padding: 8px 12px; border-radius: var(--radius-sm); font-size: 12.5px; font-weight: 600;
  background: rgba(78,167,119,.14); color: var(--pine); border: 1px solid rgba(78,167,119,.3); }
.ios-hint[hidden] { display: none; }

/* shared quiet "x" dismiss control used by the expiry / iOS-install banners
   (the save-link bar's dismiss has its own .savelink-dismiss-btn, styled the
   same way, since it sits on a different, full-bleed background) */
.expiry-dismiss, .ios-hint-dismiss {
  font: inherit; background: none; border: none; color: inherit; cursor: pointer;
  font-size: 16px; line-height: 1; padding: 0 2px; flex: none;
  border-radius: var(--radius-xs); transition: background .15s, color .15s;
}
.expiry-dismiss:hover, .ios-hint-dismiss:hover { background: rgba(255,255,255,.12); color: var(--text); }

/* ---------- Share modal (top-bar Share button) ---------- */
.share-modal { position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center; padding: 20px; }
.share-modal[hidden] { display: none; }
.share-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.55); }
.share-dialog {
  position: relative; width: 100%; max-width: 440px;
  background: linear-gradient(180deg, var(--surface), var(--bg-2));
  border: 1px solid var(--border-2); border-radius: var(--radius);
  padding: 20px; box-shadow: var(--shadow);
}
.share-heading { font-size: 16px; font-weight: 650; letter-spacing: -.01em; margin-bottom: 4px; }
.share-desc { font-size: 13px; color: var(--text-dim); margin-bottom: 14px; }
/* QR needs a light background + dark modules + quiet-zone margin to scan reliably,
   so it sits on its own white panel regardless of the app's dark theme. */
.share-qr-wrap { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-bottom: 16px; }
.share-qr-wrap[hidden] { display: none; }
.share-qr-panel {
  background: #fff; border-radius: var(--radius-sm); padding: 10px;
  display: inline-flex; box-shadow: var(--shadow);
}
.share-qr-img { display: block; width: 160px; height: 160px; }
.share-qr-caption { font-size: 12px; color: var(--text-mute); }
.share-url-row { display: flex; gap: 8px; }
.share-url {
  flex: 1; font: inherit; font-size: 13px; color: var(--text); background: var(--surface-2);
  border: 1px solid var(--border-2); border-radius: var(--radius-xs); padding: 8px 10px; min-width: 0;
}
.share-url:focus { outline: none; border-color: var(--pine); }
.share-actions { display: flex; justify-content: flex-end; margin-top: 14px; }

/* ---------- Solo mode: hide multi-party-only UI when board.parties.length === 1 ---------- */
/* !important beats the mobile "expanded row" display:flex override for these cells. */
body.solo-party td.split-col,
body.solo-party th.split-col,
body.solo-party .b-cost,
body.solo-party .b-workload {
  display: none !important;
}

/* ---------- Read-only mode: edits are visible but inert ---------- */
body.read-only .cell-edit,
body.read-only .assignee-sel,
body.read-only .chip,
body.read-only .check,
body.read-only .add-btn,
body.read-only .mini-add,
body.read-only .del-btn,
body.read-only .dup-btn,
body.read-only #btn-edit-board {
  pointer-events: none; opacity: .55;
}
