/* The grocery list (public/js/grocery.js), on both pages: the round basket
   button at the bottom right and the list that pops out of it (Mari's
   mockup, 2026-10-19). Colours, sizes, spacing and text styles come from
   tokens.css (System v2: Grocery button, Grocery item, Grocery add row,
   Grocery list panel). Buttons, the checkbox and the spinner come from
   recipe-form.css, the date picker from month-calendar.css. */

/* Room under the calendar / the meals, so the button never covers the last
   meal's "+ Add item" */
.gl-room main{ padding-bottom:calc(56px + 2 * var(--space-24)); }  /* the 56px button and its 24px margins */
/* The toast (bottom centre) keeps clear of the button: narrower on the
   desktop page, above it on the phone page */
.gl-desktop #toast{ max-width:calc(100% - 208px); }
.gl-mobile #toast{ bottom:calc(88px + env(safe-area-inset-bottom)); }

/* ---------- The button ---------- */
/* Grocery button: 56px brown circle, a 22px basket (× while open) */
.gl-fab{
  position:fixed;
  right:var(--space-24);
  bottom:var(--space-24);
  z-index:19;               /* under the Recipes drawer (20), which covers it */
  width:56px;
  height:56px;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:0;
  border:none;
  border-radius:50%;
  background:var(--action-primary);
  color:var(--text-inverse);
  box-shadow:var(--shadow-float);
  cursor:pointer;
  transition:background .12s;
}
.gl-fab:hover{ background:var(--action-hover); }
.gl-fab-icon{ display:flex; }
.gl-fab-icon .icon{ width:22px; height:22px; }
/* Meals changed since the list was made */
.gl-dot{
  position:absolute;
  top:2px;
  right:2px;
  width:14px;
  height:14px;
  border:2px solid var(--surface-panel);
  border-radius:50%;
  background:var(--text-primary);
}
.gl-mobile .gl-fab{ right:var(--space-16); bottom:calc(var(--space-16) + env(safe-area-inset-bottom)); z-index:25; }

/* ---------- The list ---------- */
/* Grows out of the button (scale + fade); a plain fade when the device asks
   for less motion. Closed, it can't be seen, clicked or tabbed to. */
.gl-panel{
  position:fixed;
  top:var(--gl-top, 96px);
  right:var(--space-24);
  bottom:92px;              /* just above the button */
  z-index:19;
  width:min(480px, calc(100vw - 48px));
  display:flex;
  flex-direction:column;
  background:var(--surface-panel);
  border:1px solid var(--border-default);
  border-radius:var(--radius-slot);
  box-shadow:var(--shadow-float);
  color:var(--text-primary);
  transform-origin:calc(100% - 28px) calc(100% + 40px);  /* the button's middle */
  transform:scale(.15);
  opacity:0;
  visibility:hidden;
  transition:transform .25s ease, opacity .25s ease, visibility 0s linear .25s;
}
.gl-panel.open{
  transform:none;
  opacity:1;
  visibility:visible;
  transition:transform .25s ease, opacity .25s ease;
}
@media (prefers-reduced-motion: reduce){
  .gl-panel, .gl-panel.open{ transform:none; }
}
.gl-mobile .gl-panel{
  top:calc(var(--space-12) + env(safe-area-inset-top));
  left:var(--space-12);
  right:var(--space-12);
  bottom:calc(84px + env(safe-area-inset-bottom));
  width:auto;
  z-index:25;               /* over the sticky header, under the pop-ups */
  transform-origin:calc(100% - 32px) calc(100% + 44px);
}

/* The header stays at the top while the items scroll: the title, then
   "Dates" with the field and Make / Update list */
.gl-head{
  flex:none;
  padding:var(--space-20) var(--space-24) var(--space-16);
  border-bottom:1px solid var(--border-default);
}
.gl-mobile .gl-head{ padding:var(--space-16) var(--space-16) var(--space-16); }
.gl-head h2{ margin:0 0 var(--space-16); font:var(--type-heading-small-semibold); outline:none; }
.gl-label{ display:block; margin-bottom:var(--space-8); font:var(--type-body-semibold); }

/* Dates: a Date field that opens a month calendar (public/js/month-calendar.js),
   like Plan meals */
.gl-row{ display:flex; align-items:center; gap:var(--space-8); }
.gl-dates{ position:relative; flex:1; min-width:0; }
.gl-row .btn-primary{ height:var(--size-control-form); }
.gl-dates-btn{
  width:100%;
  height:var(--size-control-form);
  display:flex;
  align-items:center;
  gap:var(--space-8);
  padding:0 var(--space-12);
  border:1px solid var(--border-default);
  border-radius:var(--radius-control);
  background:var(--surface-panel);
  font:var(--type-body);
  color:var(--text-primary);
  text-align:left;
  cursor:pointer;
}
.gl-dates-btn:hover{ border-color:var(--border-default); }
.gl-dates-btn[aria-expanded="true"]{ border-color:var(--text-secondary); }
.gl-dates-text{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.gl-dates-btn .icon{ color:var(--text-primary); }
.gl-cal{
  position:absolute;
  left:0;
  top:calc(100% + var(--space-4));
  z-index:5;
  width:304px;
  max-width:100%;
  padding:var(--space-12);
  background:var(--surface-panel);
  border-radius:var(--radius-control);
  box-shadow:var(--shadow-float);  /* no border on dropdown lists (Mari, 2026-10-22) */
}

/* What the list was made from (or "Meals changed…"), under the dates */
.gl-status{ margin:var(--space-8) 0 0; font:var(--type-support); color:var(--text-secondary); }
.gl-status:empty{ display:none; }
/* "Meals changed…": Support style like the rest (Mari, 2026-10-22; was ink
   semibold), with a dot in front like the one on the grocery button */
.gl-status.is-stale::before{
  content:"";
  display:inline-block;
  width:8px;
  height:8px;
  margin-right:var(--space-8);
  border-radius:50%;
  background:var(--text-primary);
  vertical-align:1px;
}

/* The items, by group (a real scroll container: an item being added scrolls
   into view and keeps its cursor; see grocery.js) */
.gl-body{ flex:1; min-height:0; overflow-y:auto; padding:var(--space-4) var(--space-24) var(--space-20); scroll-padding:var(--space-8) 0 var(--space-20); }
/* On the phone the rows run edge to edge (for swipe to delete), so the list
   rounds its own bottom corners or the rows would square off the panel's */
.gl-mobile .gl-body{ padding:var(--space-4) var(--space-16) var(--space-20); border-radius:0 0 calc(var(--radius-slot) - 1px) calc(var(--radius-slot) - 1px); }
/* "Hide recipe name", above the groups (Mari, 2026-10-19) */
.gl-option{ display:inline-flex; align-items:center; gap:var(--space-8); margin-top:var(--space-16); font:var(--type-body); cursor:pointer; }
.gl-empty{ margin:var(--space-20) 0 0; font:var(--type-body); color:var(--text-secondary); }
.gl-group h3{ margin:var(--space-20) 0 var(--space-8); font:var(--type-body-semibold); }
/* A group with nothing in it yet is greyed, like Reminders' "Others" */
.gl-group.is-empty h3{ color:var(--text-secondary); opacity:.6; }
.gl-group ul{ margin:0; padding:0; list-style:none; }
/* Grocery item: checkbox, the name (recipes under it), the amount, × */
.gl-item{ position:relative; border-bottom:1px solid var(--border-default); }
.gl-item:last-child{ border-bottom:none; }
.gl-item-row{ position:relative; z-index:1; display:flex; align-items:flex-start; background:var(--surface-panel); }
/* Only the checkbox ticks (Mari, 2026-10-19); its clickable area is a bit
   bigger than the box. The name and amount next to it are for editing. */
.gl-tick{ flex:none; display:flex; padding:var(--space-12) var(--space-12) var(--space-8) 0; cursor:pointer; }
.gl-main{ flex:1; min-width:0; display:flex; align-items:flex-start; gap:var(--space-12); padding:var(--space-8) 0; cursor:text; }
.gl-text{ flex:1; min-width:0; display:flex; flex-direction:column; gap:var(--space-4); }
.gl-name{ font:var(--type-body); overflow-wrap:anywhere; }
.gl-from{ font:var(--type-support); color:var(--text-secondary); }
.gl-amount{ flex:none; max-width:45%; font:var(--type-body); color:var(--text-secondary); text-align:right; }
/* Ticked: the whole row greys (System v2) and the name and amount are struck
   through (Mari kept that, 2026-10-22) */
.gl-item.is-checked :is(.gl-name, .gl-from, .gl-amount){ color:var(--text-secondary); }
.gl-item.is-checked :is(.gl-name, .gl-amount){ text-decoration:line-through; }
/* Being edited: the name and amount become boxes, like the "Add item" row */
.gl-item-row.is-editing{ align-items:center; gap:var(--space-8); padding:var(--space-4) 0; }
.gl-item-row.is-editing .gl-tick{ padding:0 var(--space-4) 0 0; }

/* Removing an item (Mari, 2026-10-19). Desktop page: a × at the right of
   every row, faint (25% ink) until the mouse is on it; a 32px button around
   an 18px ×, so it's easy to hit (Mari's screenshot). */
.gl-x{
  flex:none;
  display:flex;
  align-items:center;
  justify-content:center;
  width:32px;
  height:32px;
  margin:2px -7px 0 6px;   /* optical, not spacing: the 18px × lines up with the edge (−7 = (18 − 32) / 2) and sits on the name's line */
  padding:0;
  border:none;
  border-radius:var(--radius-base);
  background:none;
  color:color-mix(in srgb, var(--text-primary) 25%, transparent);
  cursor:pointer;
}
.gl-x .icon{ width:18px; height:18px; }
.gl-x:hover, .gl-x:focus-visible{ color:var(--text-primary); }
.gl-item-row.is-editing .gl-x{ margin-top:0; }
/* Phone page: swiping the row left uncovers a dark delete button with a
   white × (like Reminders). The row reaches the panel's edges so the
   button sits flush. */
.gl-mobile .gl-item{ margin:0 calc(-1 * var(--space-16)); overflow:hidden; }
.gl-mobile .gl-item-row{ padding:0 var(--space-16); transition:transform .2s ease; }
.gl-mobile .gl-item-row.is-editing{ padding:var(--space-4) var(--space-16); }
.gl-mobile .gl-item.is-dragging .gl-item-row{ transition:none; }
.gl-mobile .gl-item.is-swiped .gl-item-row{ transform:translateX(-72px); }
.gl-mobile .gl-tick{ margin-left:calc(-1 * var(--space-8)); padding-left:var(--space-8); padding-right:var(--space-16); }  /* easier to hit with a finger */
.gl-del{
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  width:72px;              /* DEL_W in grocery.js */
  display:flex;
  align-items:center;
  justify-content:center;
  padding:0;
  border:none;
  background:var(--text-primary);
  color:var(--text-inverse);
}
.gl-del .icon{ width:22px; height:22px; }

/* Recipes that add nothing yet: a warning note like the drawer's */
.gl-note{
  position:relative;
  margin-top:var(--space-16);
  padding:var(--space-12) var(--space-44) var(--space-12) var(--space-16);
  border:1px solid var(--feedback-warning-border);
  border-radius:var(--radius-card);
  background:var(--feedback-warning-surface);
  font:var(--type-body);
}
.gl-note p{ margin:0; }
/* × to close it, top right */
.gl-note .gl-note-close{
  position:absolute;
  top:var(--space-8);
  right:var(--space-8);
  width:28px;
  height:28px;
  display:flex;
  align-items:center;
  justify-content:center;
  border-radius:var(--radius-base);
  color:var(--text-secondary);
}
.gl-note .gl-note-close:hover{ background:color-mix(in srgb, var(--text-primary) 6%, transparent); color:var(--text-primary); text-decoration:none; }
.gl-note ul{ margin:var(--space-8) 0 0; padding-left:var(--space-20); }
.gl-note button{
  padding:0;
  border:none;
  background:none;
  font:inherit;
  color:var(--feedback-warning-link);
  text-align:inherit;
  text-underline-offset:2px;
  cursor:pointer;
}
.gl-note button:hover{ text-decoration:underline; }
/* Each recipe name ends with a small ↗: it opens the recipe (Mari, 2026-10-22) */
.gl-note li button{ display:inline-flex; align-items:center; gap:var(--space-4); }
.gl-note li button .icon{ width:14px; height:14px; }
.gl-foot-note{ margin:var(--space-20) 0 0; font:var(--type-support); color:var(--text-secondary); }

/* Grocery add row: the last row of every group (Mari, 2026-10-19, like
   Apple's Reminders). A dashed box where the checkbox would be and a light
   "Add item"; clicked, it becomes a name box and an Amount box. */
.gl-add-row{ display:flex; align-items:center; gap:var(--space-12); min-height:38px; }
.gl-ring{
  flex:none;
  width:16px;
  height:16px;
  border:1.5px dashed var(--text-secondary);
  border-radius:var(--radius-base);
  opacity:.55;
}
.gl-add-btn{
  flex:1;
  min-width:0;
  display:flex;
  align-items:center;
  gap:var(--space-12);
  align-self:stretch;
  padding:0;
  border:none;
  background:none;
  font:var(--type-body);
  color:var(--text-secondary);
  text-align:left;
  cursor:text;
}
/* the hint is lighter than other muted text (Mari, 2026-10-19), like a placeholder */
.gl-add-hint{ color:var(--text-secondary); opacity:.6; }
.gl-add-btn:hover .gl-add-hint{ opacity:1; }
.gl-add-btn:hover .gl-ring{ opacity:1; }
/* Clicked: a name box and an amount box (Mari's mockup, 2026-10-19). The
   amount box ends where the amounts do. */
.gl-add-row.is-adding{ gap:var(--space-8); padding:var(--space-4) 0; }
.gl-add-input, .gl-add-amount{
  min-width:0;
  height:34px;
  padding:0 var(--space-12);
  border:1px solid var(--border-default);
  border-radius:var(--radius-control);
  outline:none;
  background:var(--surface-panel);
  font:var(--type-body);
  color:var(--text-primary);
}
.gl-add-input{ flex:1; }
.gl-add-amount{ flex:none; width:120px; }
.gl-add-input:focus, .gl-add-amount:focus{ border-color:var(--text-secondary); }
.gl-add-amount::placeholder{ font:var(--type-support); color:var(--text-secondary); }
.gl-mobile .gl-add-amount{ width:96px; }
/* Phones zoom into text boxes under 16px; keep the page still (and the hint
   the same size, so nothing jumps when it becomes a text box) */
.gl-mobile .gl-add-input, .gl-mobile .gl-add-amount, .gl-mobile .gl-add-btn{ font:var(--type-heading-small); }
