:root {
  color: #2f302a;
  background: #f4efe5;
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-synthesis: none;
  line-height: 1.45;
  --paper: #fffdf8;
  --ink: #2f302a;
  --muted: #74746c;
  --line: #ded8ca;
  --green: #536d4d;
  --green-soft: #e4ecdf;
  --yellow-soft: #fbf1c9;
  --red: #9c443a;
  --blue: #3f5b72;
  --blue-soft: #e9eff4;
}

* { box-sizing: border-box; }

/* The hidden attribute has to beat the author rules that set a display, or it
   does nothing: .editor-grid is a grid, and the user agent's own [hidden] rule
   loses to any author declaration. The pack-size fields toggled by
   confezioneDetail() in main.ts are hidden this way. */
[hidden] { display: none !important; }

body {
  margin: 0;
  min-width: 320px;
  min-height: 100vh;
}

button, input { font: inherit; }
button { cursor: pointer; }

.app-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.8rem max(1rem, calc((100vw - 900px) / 2));
  background: rgba(244, 239, 229, 0.95);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(10px);
}

.brand { font-weight: 750; letter-spacing: 0.02em; }
.brand small { display: block; color: var(--muted); font-size: 0.72rem; font-weight: 500; }

.sync-pill {
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.28rem 0.65rem;
  color: var(--muted);
  background: var(--paper);
  font-size: 0.78rem;
}
.sync-pill.online { color: var(--green); background: var(--green-soft); }
.sync-pill.offline, .sync-pill.error { color: var(--red); background: #f8e8e5; }

.page {
  width: min(900px, 100%);
  margin: 0 auto;
  padding: 1.25rem 1rem 6rem;
  flex: 1;
}

.page-header { display: flex; justify-content: space-between; align-items: start; gap: 1rem; margin-bottom: 1rem; }
h1 { margin: 0; font-size: clamp(1.7rem, 5vw, 2.35rem); line-height: 1.1; }
h2 { margin: 1.5rem 0 0.6rem; font-size: 1.15rem; }
p { margin: 0.4rem 0; }
.muted { color: var(--muted); }
.small { font-size: 0.82rem; }

.nav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding: 0.45rem max(0.5rem, calc((100vw - 900px) / 2));
  background: rgba(255, 253, 248, 0.96);
  border-top: 1px solid var(--line);
  backdrop-filter: blur(10px);
}

.nav button {
  border: 0;
  background: transparent;
  color: var(--muted);
  padding: 0.6rem 0.35rem;
  border-radius: 0.7rem;
}
.nav button.active { color: var(--green); background: var(--green-soft); font-weight: 700; }

.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 1rem;
  padding: 1rem;
  box-shadow: 0 0.3rem 1rem rgba(85, 70, 40, 0.04);
}

.toolbar { display: flex; flex-wrap: wrap; gap: 0.55rem; align-items: center; }
.primary, .secondary, .danger {
  border-radius: 0.7rem;
  padding: 0.62rem 0.85rem;
  border: 1px solid transparent;
  font-weight: 650;
}
.primary { color: white; background: var(--green); }
.secondary { color: var(--ink); background: var(--paper); border-color: var(--line); }
.danger { color: var(--red); background: #f8e8e5; border-color: #edc5bf; }
button:disabled { opacity: 0.5; cursor: not-allowed; }
.week-nav { display: flex; gap: 0.4rem; align-items: center; flex-shrink: 0; }
.week-nav .secondary { min-width: 44px; min-height: 44px; font-size: 1.2rem; line-height: 1; padding: 0.5rem 0.7rem; }

.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.65rem; margin: 1rem 0; }
.stat strong { display: block; font-size: 1.55rem; color: var(--green); }
.stat span { color: var(--muted); font-size: 0.78rem; }

.list { display: grid; gap: 0.55rem; }
.list-row {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  min-height: 3.25rem;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  background: var(--paper);
}
.plan-row { align-items: center; flex-wrap: wrap; }
.list-row input[type="checkbox"] { width: 1.25rem; height: 1.25rem; accent-color: var(--green); flex: 0 0 auto; }
/* Keeps a da-comprare row (no checkbox) aligned with the ricorrente rows. */
.check-spacer { width: 1.25rem; flex: 0 0 auto; }
.row-main { min-width: 0; flex: 1; }
.row-title { font-weight: 650; }
.row-title { display: block; }
.row-meta { display: block; color: var(--muted); font-size: 0.78rem; }
/* Compact plan rows: name, meta and the Modifica toggle sit on one line; the
   name/meta pair wraps together only if it runs out of room. */
.plan-row .row-main { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.5rem; row-gap: 0; }
.plan-row .row-title, .plan-row .row-meta { display: inline; }
.bought .row-title, .bought .row-meta { color: var(--muted); text-decoration: line-through; }
.section-label { margin: 1.2rem 0 0.45rem; color: var(--green); font-size: 0.78rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; }
/* Collapsible aisle: the band is the <summary>, the rows are inside. */
.section-group { margin: 0; }
.section-group > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 0.4rem; min-height: 2.5rem; }
.section-group > summary::-webkit-details-marker { display: none; }
.section-group > summary::before { content: "▾"; font-size: 0.7em; opacity: 0.7; transition: transform 0.15s; }
.section-group:not([open]) > summary::before { transform: rotate(-90deg); }
.section-count { margin-left: auto; opacity: 0.6; font-weight: 700; }
.collapse-all { display: flex; justify-content: flex-end; margin: 0.2rem 0 -0.4rem; }
.collapse-all button { font-size: 0.8rem; }
/* The section colour extends past the header to its rows: a coloured left-edge
   contour on every row, and a faint background tint on the plain ones. Rows that
   carry their own state colour (due / queued / bought) keep it, and only take
   the contour. */
.section-group.has-colour .list-row { border-left-width: 5px; border-left-color: var(--section-colour); }
.section-group.has-colour .list-row:not(.due):not(.queued):not(.bought) {
  background: color-mix(in srgb, var(--section-colour) 16%, var(--paper));
  border-color: color-mix(in srgb, var(--section-colour) 40%, var(--line));
  border-left-color: var(--section-colour);
}
.section-subhead { margin: 0.85rem 0 0.3rem; color: var(--muted); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; }
.sections-manager { margin-top: 1rem; }
.section-rows { display: flex; flex-direction: column; gap: 0.35rem; margin: 0.6rem 0 0.9rem; }
.section-row { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; }
.section-row .toolbar { display: inline-flex; gap: 0.3rem; margin: 0; }
.section-row .toolbar button { padding: 0.25rem 0.6rem; font-size: 0.8rem; }
.move-toolbar { display: inline-flex; gap: 0.3rem; margin-top: 0.35rem; }
.move-toolbar button { padding: 0.25rem 0.7rem; }

.add-plan { display: grid; gap: 0.75rem; margin-bottom: 1rem; }
.add-plan h2 { margin: 0; }
.catalog-results { display: grid; gap: 0.4rem; max-height: 14rem; overflow: auto; }
.catalog-result {
  display: flex;
  justify-content: space-between;
  gap: 0.8rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 0.6rem;
  color: var(--ink);
  background: var(--paper);
  text-align: left;
}
.catalog-result small { color: var(--muted); }
.catalog-result.selected { border-color: var(--green); background: var(--green-soft); }
.chosen-item { padding: 0.6rem 0.7rem; border-radius: 0.6rem; background: var(--green-soft); }
.linklike { background: none; border: none; color: var(--green); padding: 0; margin-left: 0.4rem; font: inherit; text-decoration: underline; cursor: pointer; }
/* Closed, the editor is just its "Modifica" toggle, pinned to the row's right
   so each item is one line. Opened, the fields break to a full-width block
   below — but the toggle is pinned to the row itself (not to the details
   box, which is what reflows to make room for those fields), so opening it
   only rotates the arrow in place instead of relocating it under the title. */
.list-row.plan-row { position: relative; padding-right: 2.3rem; }
.plan-editor { flex: 0 0 auto; margin-left: auto; min-width: 0; }
.plan-editor[open] { flex: 1 1 100%; margin-top: 0.5rem; }
/* Just a chevron, no "Modifica" label — it rotates open. Padding keeps the tap
   target usable even though the glyph is small. */
.plan-editor > summary {
  position: absolute;
  top: 0.5rem;
  right: 0.05rem;
  color: var(--green);
  cursor: pointer;
  list-style: none;
  padding: 0.35rem 0.6rem;
  white-space: nowrap;
}
.plan-editor > summary::-webkit-details-marker { display: none; }
.plan-editor > summary::before { content: "▾"; display: inline-block; font-size: 0.9rem; transition: transform 0.15s; }
.plan-editor:not([open]) > summary::before { transform: rotate(-90deg); }
.plan-editor > .editor-grid { margin: 0.7rem 0 0 2.05rem; }
.editor-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.65rem; }
.editor-grid > label { min-width: 0; }
.editor-grid select, .editor-grid input { min-width: 0; max-width: 100%; }
.editor-wide { grid-column: 1 / -1; }

.menu-grid { display: grid; gap: 0.65rem; }
.menu-day { display: grid; grid-template-columns: 6.2rem 1fr; gap: 0.7rem; align-items: stretch; }
.menu-date { padding: 0.75rem 0.2rem; color: var(--muted); font-size: 0.82rem; }
.menu-entries { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; }
.meal-slot { display: grid; gap: 0.55rem; padding: 0.7rem; border: 1px solid var(--line); border-radius: 0.7rem; background: var(--paper); }
.meal-slot small { display: block; color: var(--muted); font-size: 0.72rem; margin-bottom: 0.25rem; }
.meal-slot.empty { color: var(--muted); }
.menu-note, .history-card { display: grid; gap: 0.75rem; margin-top: 1rem; }
.menu-note h2, .history-card h2 { margin: 0; }
.history-range { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.65rem; align-items: end; }
.history-range button { min-height: 2.65rem; }
.history-list { display: grid; gap: 0.45rem; }
.history-row { display: flex; align-items: center; justify-content: space-between; gap: 0.8rem; padding: 0.6rem 0.7rem; border-top: 1px solid var(--line); }
.history-row > div { min-width: 0; display: grid; }

.form-grid { display: grid; gap: 0.75rem; }
label { display: grid; gap: 0.3rem; color: var(--muted); font-size: 0.82rem; }
input[type="text"], input[type="url"], input[type="password"] {
  width: 100%;
  padding: 0.68rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 0.65rem;
  background: var(--paper);
  color: var(--ink);
}
input[type="search"], input[type="number"], select {
  width: 100%;
  padding: 0.68rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 0.65rem;
  background: var(--paper);
  color: var(--ink);
}
input[type="date"], textarea {
  width: 100%;
  padding: 0.68rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 0.65rem;
  background: var(--paper);
  color: var(--ink);
}
textarea { min-height: 5rem; resize: vertical; }
.error-box { margin-top: 0.8rem; padding: 0.7rem; border-radius: 0.65rem; color: var(--red); background: #f8e8e5; }
.empty { padding: 1rem; color: var(--muted); text-align: center; }

.badge { display: inline-block; margin-left: 0.4rem; margin-right: 0.3rem; padding: 0.1rem 0.5rem; border-radius: 999px; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.02em; vertical-align: middle; text-transform: uppercase; }
.badge-fisso { color: #6a5d2a; background: var(--yellow-soft); border: 1px solid #e6cf7a; }
/* Single-letter badge (R = ricorrente): a tight circle instead of a word. */
.badge-letter { width: 1.15rem; height: 1.15rem; padding: 0; display: inline-flex; align-items: center; justify-content: center; border-radius: 999px; }
.badge-occasionale { color: var(--green); background: var(--green-soft); border: 1px solid #b9cbb0; }
.badge-existing { color: var(--green); background: var(--green-soft); border: 1px solid #b9cbb0; text-transform: none; }
.nested-advanced { margin: 0.6rem 0; border-top: 1px dashed var(--line); padding-top: 0.5rem; }
.nested-advanced > summary { color: var(--muted); cursor: pointer; font-size: 0.78rem; font-weight: 700; }

.plan-row.due { background: var(--yellow-soft); border-color: #efd98a; }
.plan-row.due .row-meta { color: #6a5d2a; }

/* A row that exists only in the offline queue. Dashed, so "not on the server
   yet" reads at a glance, and blue rather than yellow so it cannot be confused
   with a dispensa row that is due for restocking. */
.plan-row.queued { border-style: dashed; border-color: #b6c3cf; background: var(--blue-soft); }
.plan-row.queued .row-meta { color: var(--blue); }
.badge-queued { color: var(--blue); background: var(--paper); border: 1px solid #b6c3cf; }
.card.notice { border-left: 3px solid var(--blue); }
.card.notice strong { display: block; color: var(--blue); font-size: 0.78rem; letter-spacing: 0.06em; text-transform: uppercase; }
.card.notice p { margin: 0.35rem 0 0; }
.list-note { margin-top: 1rem; }
.list-note details > summary { cursor: pointer; color: var(--green); font-size: 0.85rem; font-weight: 700; }
.list-note[open] summary { margin-bottom: 0.5rem; }
.new-item { margin-top: 0.6rem; border: 1px dashed var(--line); border-radius: 0.7rem; padding: 0.8rem; }
.new-item > summary { cursor: pointer; color: var(--green); font-weight: 700; }
.new-item[open] summary { margin-bottom: 0.6rem; }
.restock-form { margin-top: 0.9rem; padding-top: 0.8rem; border-top: 1px dashed var(--line); }
.restock-form h3 { margin: 0 0 0.3rem; font-size: 0.95rem; }
.restock-form .toolbar { margin-top: 0.6rem; }

@media (max-width: 520px) {
  .editor-grid { grid-template-columns: 1fr; }
  .editor-wide { grid-column: auto; }
  .plan-editor > .editor-grid { margin-left: 0; }
  .history-range { grid-template-columns: 1fr; }
}

@media (min-width: 700px) {
  .page { padding-top: 2rem; }
  .nav { position: static; order: -1; justify-content: center; grid-template-columns: repeat(3, auto); gap: 0.4rem; padding: 0.4rem max(1rem, calc((100vw - 900px) / 2)); border-top: 0; border-bottom: 1px solid var(--line); }
  .nav button { min-width: 8rem; }
}

/* Stuck operations (B3). Every rejected or ambiguous edit is listed with both
   ways out — retry and discard — because discard alone means losing the edit. */
.card.attention { border-left: 3px solid var(--red); }
.card.attention > strong { display: block; color: var(--red); font-size: 0.78rem; letter-spacing: 0.06em; text-transform: uppercase; }
.attention-list { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.7rem; }
.attention-list li { display: flex; flex-direction: column; gap: 0.25rem; padding-top: 0.6rem; border-top: 1px solid var(--line); }
.attention-list li:first-child { padding-top: 0; border-top: 0; }
.attention-op { font-weight: 650; }
.attention-why { color: var(--muted); font-size: 0.82rem; overflow-wrap: anywhere; }
.attention-list .toolbar { display: inline-flex; gap: 0.4rem; margin: 0.2rem 0 0; }
.attention-detail { color: var(--muted); font-size: 0.72rem; font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; overflow-wrap: anywhere; }

/* Today must be unmissable on the Menù page (BaseCarbonio.md §4.2), and the
   marker is a written word as well as a tint — no meaning by colour alone. */
.menu-day.today .meal-slot { border-color: var(--green); }
.menu-day.today .menu-date { color: var(--green); font-weight: 700; }
.today-flag { display: block; margin-top: 0.15rem; color: var(--green); font-size: 0.68rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; }
/* Ricette is reserved in the navigation (§4.6) until its contract exists. */
.nav button.reserved { color: var(--muted); opacity: 0.55; }

/* Coloured section bands (BaseCarbonio.md §4.4). The name is always written in
   the band, so the colour is never the only thing carrying the meaning; the
   text colour is computed for contrast in main.ts, never chosen. */
.section-label.banded {
  margin: 1.2rem 0 0.5rem;
  padding: 0.4rem 0.7rem;
  border-radius: 0.55rem;
  color: inherit;
}
.section-chip { padding: 0.2rem 0.5rem; border-radius: 0.4rem; }
.swatches { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; margin-top: 0.35rem; flex: 1 0 100%; }
.swatch {
  width: 1.6rem;
  height: 1.6rem;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 0.4rem;
  font-size: 0.7rem;
  color: var(--muted);
}
.swatch.chosen { border-color: var(--ink); box-shadow: 0 0 0 2px var(--paper) inset; }
.swatch-none { background: var(--paper); }
.swatch-picker { width: 2.2rem; height: 1.6rem; padding: 0; border: 1px solid var(--line); border-radius: 0.4rem; background: var(--paper); }

/* Store switcher (BaseCarbonio.md §4.1): thumb-height, and rendered only when a
   second shop actually has items in the plan. */
.store-switcher { display: flex; gap: 0.4rem; margin: 0 0 1rem; overflow-x: auto; }
.store-switcher button {
  flex: 1 0 auto;
  min-height: 2.75rem;
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 0.7rem;
  background: var(--paper);
  color: var(--muted);
  font-weight: 650;
}
.store-switcher button.active { color: var(--green); background: var(--green-soft); border-color: #b9cbb0; }
.store-manage-row { border: 1px solid var(--line); border-radius: 0.7rem; padding: 0.6rem 0.7rem; margin-bottom: 0.7rem; }
.store-manage-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; flex-wrap: wrap; }
.store-section-order { display: grid; gap: 0.35rem; margin-top: 0.5rem; }
.store-section-row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }

/* Organizza: one row per catalog item, with where it belongs rather than what
   this week's list says about it. */
.organizza-row { flex-wrap: wrap; align-items: flex-start; }
.organizza-controls { flex: 1 0 100%; margin-top: 0.4rem; gap: 0.35rem; }
.organizza-controls button { padding: 0.35rem 0.7rem; }
.organizza-controls select { flex: 1 1 6rem; width: auto; padding: 0.4rem 0.5rem; }
.organizza-controls .store-input { flex: 1 1 5rem; min-width: 0; width: auto; padding: 0.4rem 0.5rem; }
