/* ============================================================
   TableSet Desk — the mobile shell.

   A phone is not a small desk. On a 390 px screen the page sits at
   ~40% scale, where a caret is unusable — so on mobile the document
   is edited through a card list and *read* as paper, with an explicit
   Edit / Preview switch between the two.

   This file styles that second view only. It never restyles the desk:
   the desk stays laid out underneath at full size, because the PDF
   writer measures those very sheets. Mobile surfaces sit on top of it.

   Everything here is inert until <body class="mobile">.
   ============================================================ */

:root {
  --m-nav-h:   52px;
  --m-seg-h:   50px;
  --m-bar-h:   62px;
  /* The phone shell keeps its own names, but they are now aliases of
     the shared chrome tokens rather than a second palette. One theme
     switch moves both shells, and the two cannot drift. */
  --m-card:    var(--lift-2);
  --m-card-2:  var(--chrome);
  --m-line:    var(--chrome-line-2);
  --m-field:   var(--field);
  /* Two soft vertical washes: the surface the cards sit on, and the
     Edit/Preview switch above them. Literals rather than aliases
     because no chrome token is a gradient pair. */
  --m-grad-a:  #efe9e2;
  --m-grad-b:  #e8e0d8;
  --m-seg-a:   #f4efe8;
  --m-seg-b:   #ede7df;
  --m-safe-b:  env(safe-area-inset-bottom, 0px);
}

/* The four gradient stops are the only phone tokens that are not
   aliases, so they are the only ones needing a dark counterpart. This
   override lives here rather than in desk.css on purpose: it has the
   same specificity as the `:root` above, and this file is loaded after
   desk.css, so a dark block over there would lose the cascade and the
   phone would keep a pale surface behind dark cards. */
[data-theme="dark"] {
  --m-grad-a:  #161514;
  --m-grad-b:  #100f0e;
  --m-seg-a:   #211f1d;
  --m-seg-b:   #1a1817;
}

/* The mobile shell is absent from the DOM flow until it is switched on. */
.m-nav, .m-seg, .m-surface, .m-bar, .m-pvmode, .m-scrim, .m-sheet { display: none; }

body.mobile .m-nav,
body.mobile .m-seg,
body.mobile .m-bar { display: flex; }

/* The desk keeps its full-size layout (the PDF writer measures it) but is
   covered by the edit surface. In preview it is revealed and refitted. */
body.mobile .toolbar,
body.mobile .statusbar,
body.mobile .ruler-slot,
body.mobile .drawer { display: none !important; }

body.mobile .desk {
  top: calc(var(--m-nav-h) + var(--m-seg-h) + var(--m-pv, 0px));
  bottom: calc(var(--m-bar-h) + var(--m-safe-b));
  left: 0; right: 0;
  background: linear-gradient(180deg, var(--m-grad-a), var(--m-grad-b));
}
/* Preview owns the pinch. `pan-x pan-y` leaves one-finger scrolling to
   the browser and hands us the two-finger gesture, so zooming the page
   does not zoom the toolbar with it. Only in Preview: Edit is cards and
   Reading is reflowed text, and neither has anything to magnify. */
body.mobile.m-preview .desk { touch-action: pan-x pan-y; }

body.mobile .stack-wrap { padding: 14px 0 34px; }
body.mobile .inserters,
body.mobile .row-grip,
body.mobile .col-grip,
body.mobile .stock-mark, body.mobile .cellar-door, body.mobile .ed-only,
body.mobile .col-labels,
body.mobile .sec-grip { display: none !important; }
body.mobile .page { box-shadow: 0 3px 14px rgba(60, 40, 30, .17), 0 0 0 1px rgba(0,0,0,.07); }

/* ════════════════ TOP NAV ════════════════ */
.m-nav {
  position: fixed; top: 0; left: 0; right: 0; height: var(--m-nav-h);
  z-index: 40; align-items: center; gap: 2px;
  padding: 0 6px 0 4px;
  background: var(--chrome);
  border-bottom: 1px solid var(--chrome-line);
}
.m-title {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px;
  border: 0; background: transparent; padding: 8px 6px; border-radius: 4px;
  text-align: left; font-family: var(--font-ui); color: var(--ink);
  -webkit-tap-highlight-color: transparent;
}
.m-title:active { background: rgba(0,0,0,.05); }
.m-title svg { width: 22px; height: 22px; flex: 0 0 auto; color: var(--accent-ink); }
.m-title-text {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 16px; font-weight: 600; letter-spacing: .1px;
}
.m-icon {
  flex: 0 0 auto; width: 38px; height: 38px; border: 0; border-radius: 50%;
  background: transparent; color: var(--ink-soft);
  display: inline-flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
}
.m-icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.m-icon:active { background: rgba(0,0,0,.07); color: var(--accent-ink); }
.m-icon[disabled] { opacity: .3; }
.m-icon[disabled]:active { background: transparent; color: var(--ink-soft); }

/* ════════════════ EDIT / PREVIEW SWITCH ════════════════ */
.m-seg {
  position: fixed; top: var(--m-nav-h); left: 0; right: 0; height: var(--m-seg-h);
  z-index: 39; align-items: center; justify-content: center;
  background: var(--chrome);
  border-bottom: 1px solid var(--chrome-line-2);
}
.m-seg-track {
  display: flex; padding: 3px; gap: 2px;
  background: var(--chrome-2); border-radius: 999px;
}
.m-seg-track button {
  border: 0; background: transparent; border-radius: 999px;
  padding: 7px 20px; font-family: var(--font-ui); font-size: 15px;
  color: var(--ink-soft); display: inline-flex; align-items: center; gap: 7px;
  transition: background .16s ease, color .16s ease;
  -webkit-tap-highlight-color: transparent;
}
.m-seg-track button svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.m-seg-track button[aria-selected="true"] {
  background: var(--lift-2); color: var(--accent-ink); font-weight: 600;
  box-shadow: 0 1px 3px rgba(0,0,0,.12);
}

/* Sheet / Reading sub-switch — preview mode only */
body.mobile.m-preview { --m-pv: 46px; }
body.mobile.m-preview .m-pvmode { display: flex; }
.m-pvmode {
  position: fixed; top: calc(var(--m-nav-h) + var(--m-seg-h)); left: 0; right: 0;
  height: 46px; z-index: 38; align-items: center; justify-content: center;
  background: linear-gradient(180deg, var(--m-grad-a), var(--m-grad-a));
  border-bottom: 1px solid rgba(0,0,0,.06);
}
.m-pvmode .m-seg-track { background: var(--m-track); }
.m-pvmode .m-seg-track button { padding: 6px 18px; font-size: 14px; }

/* ════════════════ SURFACES ════════════════ */
.m-surface {
  position: fixed; left: 0; right: 0;
  top: calc(var(--m-nav-h) + var(--m-seg-h));
  bottom: calc(var(--m-bar-h) + var(--m-safe-b));
  z-index: 30; overflow-y: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  background: linear-gradient(180deg, var(--m-seg-a), var(--m-seg-b));
}
body.mobile.m-edit #mEdit { display: block; }
body.mobile.m-read #mRead { display: block; }
body.mobile.m-read { --m-pv: 46px; }
body.mobile.m-read .m-pvmode { display: flex; }
body.mobile.m-read #mRead { top: calc(var(--m-nav-h) + var(--m-seg-h) + 46px); }

/* ──────── section chip strip ──────── */
.m-chips {
  display: flex; gap: 7px; overflow-x: auto; scrollbar-width: none;
  padding: 11px 14px 10px; scroll-behavior: smooth;
}
.m-chips::-webkit-scrollbar { display: none; }
.m-chip {
  flex: 0 0 auto; border: 1px solid var(--m-line); background: var(--m-card);
  color: var(--ink); border-radius: 999px; padding: 0 14px; height: 33px;
  font-family: var(--font-ui); font-size: 14px; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 6px;
  transition: background .14s ease, color .14s ease, border-color .14s ease;
  -webkit-tap-highlight-color: transparent;
}
.m-chip-count { font-size: 11.5px; opacity: .62; font-variant-numeric: tabular-nums; }
.m-chip.active { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.m-chip.active .m-chip-count { opacity: .8; }

/* ──────── section cards ──────── */
.m-cards { padding: 2px 14px 0; }
.m-card {
  background: var(--m-card); border: 1px solid var(--m-line);
  border-radius: var(--r-m); margin-bottom: 14px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(60,40,30,.05);
}
.m-card-head { display: flex; align-items: center; gap: 2px; padding: 9px 10px 9px 4px; }

/* ──────── section reorder ────────
   The grip is the only surface that drags, so it is the only surface
   that gives up touch-action. Everything else in the card keeps its
   scroll, which is why a phone can carry this gesture at all. */
.m-sec-grip {
  flex: 0 0 auto; width: 32px; height: 44px; border: 0; background: transparent;
  color: #b9ada0; border-radius: 6px; touch-action: none; cursor: grab;
  display: inline-flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
}
.m-sec-grip .grip-dots { width: 17px; height: 17px; fill: currentColor; stroke: none; }
.m-sec-grip:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; color: var(--accent-ink); }

/* While a section is held, every card shuts to its head — the list
   collapses to titles so the drop target is visible without scrolling. */
body.m-reordering .m-card .m-rows,
body.m-reordering .m-card .m-legend,
body.m-reordering .m-card .m-add-pair { display: none; }
body.m-reordering .m-card { transition: transform .16s cubic-bezier(.22,.61,.36,1); }
body.m-reordering .m-chev { transform: rotate(0deg); }
body.m-reordering .m-chips,
body.m-reordering .m-add-section,
body.m-reordering .m-hint { opacity: .35; transition: opacity .16s ease; }
body.m-reordering * { -webkit-user-select: none; user-select: none; }

/* The held card is a clone that follows the finger; the original stays
   in flow, invisible, so the slots the others shift between stay put. */
.m-card-src { visibility: hidden; }
.m-drag-chip {
  position: fixed; z-index: 90; margin: 0; pointer-events: none;
  transition: none; transform: scale(1.025);
  box-shadow: 0 10px 24px rgba(60,40,30,.22), 0 2px 6px rgba(60,40,30,.14);
  border-color: var(--accent-line);
}
.m-drag-chip .m-sec-grip { color: var(--accent-ink); }
@media (prefers-reduced-motion: reduce) {
  body.m-reordering .m-card { transition: none; }
  .m-drag-chip { transform: none; }
}
.m-chev {
  flex: 0 0 auto; width: 30px; height: 30px; border: 0; background: transparent;
  color: var(--ink-faint); display: inline-flex; align-items: center; justify-content: center;
  transition: transform .18s ease; -webkit-tap-highlight-color: transparent;
}
.m-chev svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.m-chev { transform: rotate(90deg); }
.m-card.collapsed .m-chev { transform: rotate(0deg); }
.m-card.collapsed .m-rows, .m-card.collapsed .m-add { display: none; }

.m-sec-title {
  flex: 1 1 auto; min-width: 0; border: 0; background: transparent;
  font-family: var(--font-ui); font-size: 19px; font-weight: 600; color: var(--ink);
  padding: 4px 6px; border-radius: 4px; outline: none;
  width: 100%; text-overflow: ellipsis;
}
.m-sec-title:focus { background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-line); }
.m-sec-count {
  flex: 0 0 auto; font-size: 11.5px; color: var(--ink-faint);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.m-sec-del {
  flex: 0 0 auto; width: 34px; height: 34px; border: 0; background: transparent;
  color: var(--ink-faint); border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
}
.m-sec-del svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
.m-sec-del.armed {
  width: auto; padding: 0 11px; background: var(--accent); color: var(--on-accent);
  font-family: var(--font-ui); font-size: 13px; font-weight: 600;
}

/* "Starts a new page", in the section head with the other structural
   controls. Off it is as quiet as the trash can beside it; on, it fills
   with the accent, because a break that is set and invisible is the one
   state worth shouting about. Absent entirely on the first section. */
.m-sec-brk {
  flex: 0 0 auto; width: 32px; height: 34px; border: 0; background: transparent;
  color: var(--ink-faint); border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
}
.m-sec-brk svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
.m-sec-brk.on { background: var(--accent-soft); color: var(--accent-ink); }

.m-rows { border-top: 1px solid var(--m-line); }
.m-row {
  display: flex; align-items: baseline; gap: 12px; width: 100%;
  padding: 13px 14px; border: 0; background: transparent; text-align: left;
  border-bottom: 1px solid var(--chrome-line-2); font-family: var(--font-ui);
  -webkit-tap-highlight-color: transparent;
}
.m-row:last-child { border-bottom: 0; }
.m-row:active { background: var(--accent-soft); }
.m-row-main { flex: 1 1 auto; min-width: 0; }
.m-row-name {
  font-size: 16px; color: var(--ink); line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.m-row-name.placeholder { color: var(--ink-faint); font-style: italic; }
/* 86'd on the phone reads the same as it reads on the sheet: struck
   through at full ink, no badge and no greying. */
.m-row.sold-out .m-row-name,
.m-row.sold-out .m-row-detail,
.m-row.sold-out .m-row-price {
  text-decoration: line-through;
  text-decoration-color: currentColor;
  text-decoration-thickness: 1px;
}
.m-row-detail {
  margin-top: 2px; font-size: 13px; color: var(--ink-soft); line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.m-row-prices {
  flex: 0 0 auto; display: flex; gap: 10px; align-items: baseline;
  font-variant-numeric: tabular-nums;
}
.m-row-prices > div { min-width: 38px; text-align: right; }
.m-row-price { font-size: 15px; color: var(--ink); }
.m-row-price.empty { color: var(--chrome-line); }

/* The price columns are named once per section, not once per wine — eleven
   repetitions of "GLASS  BOTTLE" is noise, and the numbers align anyway. */
.m-legend {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 0 14px 6px; border-bottom: 1px solid var(--m-line);
  font-family: var(--font-ui-2); font-size: 9.5px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--ink-faint);
}
.m-legend > span { min-width: 38px; text-align: right; }

/* ──────── flight, as a phone divider ────────
   Not a card. A wine card opens a sheet because a wine has ten fields
   behind it; a flight has two, so both are on the divider and the tap
   target is the field itself. Chrome burgundy is fine here — this is
   the app, not the sheet that prints. */
.m-flight {
  display: flex; flex-direction: column; gap: 2px;
  padding: 9px 14px 8px; background: color-mix(in srgb, var(--accent-ink) 3.5%, transparent);
  border-top: 1px solid var(--m-line); border-bottom: 1px solid var(--m-line);
}
.m-flight-name {
  flex: 1 1 auto; min-width: 0; border: 0; background: transparent;
  font-family: var(--font-ui); font-size: 14.5px; font-style: italic;
  font-weight: 600; letter-spacing: .3px; color: var(--accent-ink);
  padding: 3px 0; -webkit-appearance: none;
}
.m-flight-name::placeholder { color: var(--ink-faint); font-weight: 400; }
.m-flight-price {
  flex: 0 0 66px; width: 66px; text-align: right;
  border: 0; background: transparent; padding: 3px 0;
  font-family: var(--font-ui); font-size: 14.5px; font-style: italic;
  font-variant-numeric: tabular-nums; color: var(--accent-ink);
}
.m-flight-price::placeholder { color: var(--ink-faint); }
.m-flight-name:focus, .m-flight-price:focus { outline: none; }
.m-flight-del {
  flex: 0 0 auto; width: 30px; height: 30px; border: 0; border-radius: var(--r-m);
  background: transparent; color: var(--ink-faint);
  display: grid; place-items: center;
  -webkit-tap-highlight-color: transparent;
}
.m-flight-del svg {
  width: 15px; height: 15px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round;
}
.m-flight-del:active { background: color-mix(in srgb, var(--accent-ink) 10%, transparent); color: var(--accent-ink); }

.m-flight-top { display: flex; align-items: center; gap: 8px; }
/* v0.62: what the set is, and how many wines it holds. */
.m-flight-sub { display: flex; align-items: center; gap: 10px; }
.m-flight-pours {
  flex: 1 1 auto; min-width: 0; border: 0; background: transparent; padding: 3px 0;
  font-family: var(--font-ui); font-size: 13.5px; font-style: italic; color: var(--ink-soft);
  -webkit-appearance: none;
}
.m-flight-pours::placeholder { color: var(--ink-faint); }
.m-flight-pours:focus { outline: none; }
.m-flight-step { display: inline-flex; align-items: center; gap: 6px; flex: none;
  font-family: var(--font-ui-2); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--accent-ink); }
.m-flight-step button {
  width: 30px; height: 30px; border: 0; border-radius: 3px; padding: 0;
  background: var(--lift); color: var(--accent-ink); font-size: 16px;
  box-shadow: 0 0 0 1px var(--m-line);
}
.m-flight-step button:disabled { opacity: .35; }
/* A wine in a set carries the set's bar down its left edge, as the
   desk's bracket does in the margin. */
.m-row.in-set { box-shadow: inset 3px 0 0 color-mix(in srgb, var(--accent-ink) 32%, transparent); }

.m-add-pair { display: flex; border-top: 1px dashed var(--m-line); }
.m-add-pair .m-add { border-top: 0; }
/* Was italic. Italic is not free here: the desk toolbar uses it for one
   thing only, the current value of a menu — Template By the Glass, Font
   Garamond, Page Letter, Border None. This is an action, and the pair
   is already ranked without it: 40% of the width against 60%, and a
   .02 accent wash against .043. The width and the wash stay. */
.m-add-pair .m-add-flight {
  flex: 0 0 40%; border-left: 1px dashed var(--m-line);
  background: color-mix(in srgb, var(--accent-ink) 2%, transparent);
}

.m-add {
  display: block; width: 100%; padding: 12px; border: 0;
  border-top: 1px dashed var(--m-line); background: color-mix(in srgb, var(--accent-ink) 4.5%, transparent);
  color: var(--accent-ink); font-family: var(--font-ui); font-size: 14.5px; font-weight: 600;
  -webkit-tap-highlight-color: transparent;
}
.m-add:active { background: color-mix(in srgb, var(--accent-ink) 10%, transparent); }

.m-add-section {
  display: block; width: calc(100% - 28px); margin: 2px 14px 0;
  padding: 15px; border: 1px dashed var(--chrome-line); border-radius: var(--r-m);
  background: transparent; color: var(--accent-ink);
  font-family: var(--font-ui); font-size: 15px; font-weight: 600;
  -webkit-tap-highlight-color: transparent;
}
.m-add-section:active { background: color-mix(in srgb, var(--accent-ink) 6%, transparent); }
.m-hint {
  margin: 16px 14px 26px; text-align: center;
  font-family: var(--font-ui); font-size: 12.5px; color: var(--ink-faint); line-height: 1.5;
}
/* Centred here, unlike the rooms: the hint above it is centred and the
   phone's cards have no single left edge to hang from. The hint's
   bottom margin is given up to it, so the surface ends no lower than
   it did. */
.m-credit {
  margin: -18px 14px 26px; text-align: center;
  font-family: var(--font-ui-2); font-size: 9.5px;
  letter-spacing: .04em; color: var(--ink-faint);
  user-select: none;
}

/* ──────── reading view ──────── */
.m-read-doc { padding: 26px 22px 40px; max-width: 620px; margin: 0 auto; }
.m-read-title {
  margin: 0; text-align: center; font-size: 27px; font-weight: 600;
  line-height: 1.2; color: var(--ink); letter-spacing: .2px;
}
.m-read-sub {
  margin: 7px 0 0; text-align: center; font-size: 14px;
  color: var(--ink-soft); font-style: italic;
}
.m-read-sec {
  margin: 34px 0 0; font-size: 19px; font-weight: 600; color: var(--accent-ink);
  letter-spacing: .3px; padding-bottom: 7px; border-bottom: 1px solid var(--accent-line);
}
/* In the reading view a flight is a subheading between the section rule
   and the wines — one step down from .m-read-sec, italic, in ink. */
.m-read-flight {
  display: flex; align-items: baseline; gap: 12px;
  margin: 20px 0 -2px; font-size: 15px; font-weight: 600;
  font-style: italic; color: var(--ink); letter-spacing: .2px;
}
.m-read-flight span { flex: 1 1 auto; min-width: 0; }
.m-read-flight em {
  flex: 0 0 auto; font-style: italic; font-weight: 400;
  font-variant-numeric: tabular-nums; color: var(--ink-soft);
}
.m-read-row { display: flex; align-items: baseline; gap: 14px; padding: 13px 0 12px; border-bottom: 1px solid rgba(0,0,0,.06); }
.m-read-row:last-child { border-bottom: 0; }
.m-read-main { flex: 1 1 auto; min-width: 0; }
.m-read-name { font-size: 16.5px; line-height: 1.4; color: var(--ink); }
.m-read-detail { margin-top: 3px; font-size: 13.5px; line-height: 1.45; color: var(--ink-soft); }
.m-read-row.sold-out .m-read-name,
.m-read-row.sold-out .m-read-detail,
.m-read-row.sold-out .m-read-prices div {
  text-decoration: line-through;
  text-decoration-color: currentColor;
  text-decoration-thickness: 1px;
}
/* The little GLASS / BOTTLE captions are furniture, not the offer.
   Striking them makes the column heading look cancelled as well. */
.m-read-row.sold-out .m-read-prices b { text-decoration: none; }
.m-read-prices {
  flex: 0 0 auto; display: flex; gap: 13px; align-items: baseline;
  font-variant-numeric: tabular-nums;
}
.m-read-prices div { font-size: 16px; color: var(--ink); line-height: 1.3; text-align: right; }
.m-read-prices b {
  display: block; font-family: var(--font-ui-2); font-weight: 500;
  font-size: 9px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-faint); margin-bottom: 1px;
}
.m-read-foot {
  margin: 40px 0 0; text-align: center; font-size: 12px;
  color: var(--ink-faint); font-style: italic; line-height: 1.6;
}

/* ════════════════ BOTTOM BAR ════════════════ */
.m-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  height: calc(var(--m-bar-h) + var(--m-safe-b));
  padding-bottom: var(--m-safe-b);
  background: var(--chrome); border-top: 1px solid var(--chrome-line);
}
.m-bar-inner { display: flex; width: min(100%, 560px); margin: 0 auto; height: var(--m-bar-h); }
.m-bar-btn {
  flex: 1 1 0; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 3px; border: 0; background: transparent;
  color: var(--ink-soft); font-family: var(--font-ui);
  -webkit-tap-highlight-color: transparent;
}
.m-bar-btn svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.m-bar-btn span { font-size: 11px; letter-spacing: .02em; }
.m-bar-btn:active { color: var(--accent-ink); }
/* Deliberately not accented. All four items in this bar open a sheet;
   none of them is a place you can be. A single permanently red item in
   a four-up bottom bar reads as the current tab, so the bar always
   looked as though Export were the screen you were on. */
.m-bar-btn.primary { color: var(--ink-soft); }

/* ════════════════ BOTTOM SHEETS ════════════════ */
.m-scrim {
  position: fixed; inset: 0; z-index: 60; background: rgba(34, 28, 24, .42);
  backdrop-filter: blur(2px); opacity: 0; pointer-events: none;
  transition: opacity .22s ease;
}
body.mobile .m-scrim { display: block; }
body.mobile .m-scrim.open { opacity: 1; pointer-events: auto; }

.m-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 61;
  width: min(100%, 620px); margin: 0 auto;
  max-height: 88vh; max-height: 88dvh;
  background: var(--m-card);
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  box-shadow: 0 -10px 36px rgba(50, 30, 24, .24);
  transform: translateY(100%); visibility: hidden; pointer-events: none;
  transition: transform .26s cubic-bezier(.32,.72,0,1), visibility .26s;
  flex-direction: column;
}
body.mobile .m-sheet { display: flex; }
body.mobile .m-sheet.open { transform: translateY(0); visibility: visible; pointer-events: auto; }
@media (prefers-reduced-motion: reduce) {
  .m-sheet { transition: visibility .01s; }
  .m-scrim { transition: none; }
}

.m-grip { width: 38px; height: 4px; border-radius: 999px; background: var(--chrome-line); margin: 9px auto 0; flex: 0 0 auto; }
.m-sheet-head {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--m-line);
}
.m-sheet-head h2 {
  margin: 0; font-family: var(--font-ui); font-size: 20px; font-weight: 400;
  color: var(--accent-ink); letter-spacing: 0;
}
.m-sheet-x {
  flex: 0 0 auto; width: 34px; height: 34px; border: 0; background: transparent;
  color: var(--ink-soft); border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
}
.m-sheet-x svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.m-sheet-body {
  flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain; padding: 16px 16px 20px;
}
.m-sheet-foot {
  flex: 0 0 auto; padding: 11px 16px calc(11px + var(--m-safe-b));
  border-top: 1px solid var(--m-line); background: var(--m-card-2);
}
.m-done {
  display: block; width: 100%; padding: 14px; border: 0; border-radius: var(--r-m);
  background: var(--accent); color: var(--on-accent);
  font-family: var(--font-ui); font-size: 16px; font-weight: 600;
  -webkit-tap-highlight-color: transparent;
}
.m-done:active { background: color-mix(in srgb, var(--accent) 82%, #000); }

/* ──────── sheet form furniture ──────── */
.m-group { margin-bottom: 20px; }
.m-group:last-child { margin-bottom: 4px; }
.m-group-label {
  display: block; margin: 0 0 3px; font-family: var(--font-ui-2);
  font-size: 10.5px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent-ink);
}
.m-group-note { margin: 0 0 10px; font-size: 12.5px; color: var(--ink-soft); line-height: 1.45; }

.m-field { margin-bottom: 13px; }
.m-field:last-child { margin-bottom: 0; }
.m-field label {
  display: block; margin-bottom: 4px; font-family: var(--font-ui-2);
  font-size: 10.5px; font-weight: 500; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-soft);
}
.m-field input, .m-field textarea {
  display: block; width: 100%; padding: 12px 13px;
  border: 1px solid var(--m-line); border-radius: var(--r-m); background: var(--m-field);
  font-family: var(--font-ui); font-size: 16px; color: var(--ink);
  -webkit-appearance: none; appearance: none;
}
.m-field input:focus, .m-field textarea:focus {
  outline: none; border-color: var(--accent-line);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-ink) 10%, transparent);
}
.m-field textarea { resize: vertical; min-height: 78px; line-height: 1.5; }
.m-field-row { display: flex; gap: 11px; }
.m-field-row .m-field { flex: 1 1 0; min-width: 0; }

/* choice grid — templates, fonts, sizes, spacing, page setup */
.m-choices { display: grid; gap: 9px; }
.m-choices.cols-2 { grid-template-columns: 1fr 1fr; }
.m-choices.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.m-choice {
  display: block; text-align: left; padding: 12px 13px;
  border: 1px solid var(--m-line); border-radius: var(--r-m); background: var(--m-field);
  font-family: var(--font-ui); color: var(--ink);
  -webkit-tap-highlight-color: transparent;
  transition: border-color .14s ease, background .14s ease;
}
.m-choice-name { display: block; font-size: 15.5px; font-weight: 600; line-height: 1.3; }
.m-choice-note { display: block; margin-top: 3px; font-size: 12px; color: var(--ink-soft); line-height: 1.4; }
.m-choice[aria-pressed="true"] {
  border-color: var(--accent); background: var(--accent-soft);
}
.m-choice[aria-pressed="true"] .m-choice-name { color: var(--accent-ink); }
.m-choices.cols-3 .m-choice { text-align: center; padding: 13px 6px; }
.m-choices.cols-3 .m-choice-name { font-size: 15px; }

/* ──────── wine library search inside the sheet ──────── */
.m-lib {
  margin: -2px 0 18px; padding: 13px; border-radius: var(--r-m);
  background: var(--accent-soft); border: 1px solid var(--accent-line);
}
.m-lib-head {
  display: flex; align-items: center; gap: 7px; margin-bottom: 9px;
  font-family: var(--font-ui-2); font-size: 10.5px; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--accent-ink);
}
.m-lib-head svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.m-lib input {
  display: block; width: 100%; padding: 12px 13px;
  border: 1px solid var(--accent-line); border-radius: var(--r-m); background: var(--field);
  font-family: var(--font-ui); font-size: 16px; color: var(--ink);
  -webkit-appearance: none; appearance: none;
}
.m-lib input:focus { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-ink) 13%, transparent); }
/* Keep the native search clear button in the palette instead of system blue. */
.m-lib input::-webkit-search-cancel-button {
  -webkit-appearance: none; appearance: none;
  width: 17px; height: 17px; border-radius: 50%; background: var(--chrome-line);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 7l10 10M17 7L7 17' stroke='black' stroke-width='3.4' stroke-linecap='round'/%3E%3C/svg%3E") center/13px no-repeat,
          linear-gradient(#000, #000);
  -webkit-mask-composite: xor;
}

/* A chip strip that scrolls should look like it scrolls. */
.m-chips { mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 26px), transparent 100%); }

/* Sheets without a sticky footer end at the screen edge otherwise. */
#mExportSheet .m-sheet-body,
#mWinesSheet .m-sheet-body,
#mMoreSheet .m-sheet-body { padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px)); }
.m-lib-hits { margin-top: 9px; display: none; }
.m-lib-hits.show { display: block; }
.m-lib-hit {
  display: block; width: 100%; text-align: left; padding: 11px 12px;
  border: 1px solid var(--accent-line); border-radius: var(--r-m); background: var(--lift);
  margin-bottom: 7px; font-family: var(--font-ui);
  -webkit-tap-highlight-color: transparent;
}
.m-lib-hit:last-child { margin-bottom: 0; }
.m-lib-hit:active { background: var(--accent-soft); }
.m-lib-hit-name { display: block; font-size: 15px; color: var(--ink); line-height: 1.3; }
.m-lib-hit-meta { display: block; margin-top: 2px; font-size: 12px; color: var(--ink-soft); line-height: 1.35; }
.m-lib-empty { margin: 9px 0 0; font-size: 12.5px; color: var(--ink-soft); font-style: italic; }

/* Which shelf answered. Only drawn when both did, so it is a divider
   rather than a label — set small and quiet, because the wine names
   under it are the thing being read. `:first-child` covers the house
   group, which sits at the top of the list with nothing above it. */
.m-lib-group {
  margin: 12px 0 6px; font-family: var(--font-ui-2);
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-faint);
}
.m-lib-group:first-child { margin-top: 4px; }

/* ──────── list-style rows (export, more) ──────── */
.m-list-item {
  display: flex; align-items: center; gap: 13px; width: 100%;
  padding: 14px 13px; margin-bottom: 9px; text-align: left;
  border: 1px solid var(--m-line); border-radius: var(--r-m); background: var(--m-field);
  font-family: var(--font-ui); color: var(--ink);
  -webkit-tap-highlight-color: transparent;
}
.m-list-item:last-child { margin-bottom: 0; }
.m-list-item:active { background: var(--accent-soft); border-color: var(--accent-line); }
.m-list-item > svg { flex: 0 0 auto; width: 21px; height: 21px; color: var(--accent-ink); fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.m-list-text { flex: 1 1 auto; min-width: 0; }
.m-list-title { display: block; font-size: 15.5px; font-weight: 600; line-height: 1.3; }
.m-list-note { display: block; margin-top: 2px; font-size: 12.5px; color: var(--ink-soft); line-height: 1.4; }
.m-list-item[disabled] { opacity: .45; }

/* inline emphasis toggles in the wine sheet */
.m-marks { display: flex; gap: 8px; }
.m-mark {
  flex: 1 1 0; height: 44px; border: 1px solid var(--m-line); border-radius: var(--r-m);
  background: var(--m-field); color: var(--ink); font-size: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
}
.m-mark[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-ink); }
/* The 86'd button wears the rule it applies, the way Bold and Italic
   beside it are set in their own weight and slant. Matched to the
   hairline the sheet actually prints rather than left to the browser's
   heavier default, so the button is a preview and not an approximation. */
.m-mark s {
  text-decoration: line-through;
  text-decoration-color: currentColor;
  text-decoration-thickness: 1px;
}

/* Keep the toast clear of the bottom bar, and the busy card centred. */
body.mobile .toast { bottom: calc(var(--m-bar-h) + var(--m-safe-b) + 14px); max-width: 88vw; text-align: center; }

/* A phone in landscape gets the desk back — there is room for a caret. */
@media (min-width: 761px) { body.mobile { /* never reached: shell is width-driven */ } }

/* ---------------- The house on a phone ----------------
   A logo is the only thing in this app a person supplies rather than
   types, so the sheet has to show what was supplied. The thumbnail sits
   on a checkerboard because a transparent PNG is the file that prints
   best, and on a white card it would look like a white rectangle. */
.m-house-thumb {
  display: flex; align-items: center; justify-content: center;
  height: 84px; margin: 0 0 8px; padding: 8px;
  border: 1px solid var(--chrome-line); border-radius: var(--r-m);
  background-color: var(--field);
  background-image:
    linear-gradient(45deg, rgba(128,128,128,.14) 25%, transparent 25%, transparent 75%, rgba(128,128,128,.14) 75%),
    linear-gradient(45deg, rgba(128,128,128,.14) 25%, transparent 25%, transparent 75%, rgba(128,128,128,.14) 75%);
  background-size: 14px 14px;
  background-position: 0 0, 7px 7px;
}
.m-house-thumb img { max-width: 100%; max-height: 68px; object-fit: contain; }

.m-house-acts { display: flex; gap: 8px; margin: 0 0 10px; }
.m-mini {
  flex: 1; min-height: 40px; padding: 0 10px;
  font: inherit; font-size: 13px;
  color: var(--ink); background: var(--lift);
  border: 1px solid var(--chrome-line); border-radius: var(--r-m);
}
.m-mini:active { background: var(--field); }
.m-mini.is-danger { color: var(--accent); }

.m-house-add {
  display: block; width: 100%; min-height: 56px; margin: 0 0 8px;
  font: inherit; font-size: 14px; color: var(--ink-soft);
  background: var(--field);
  border: 1px dashed var(--chrome-line-2); border-radius: var(--r-m);
}
.m-house-add:active { background: var(--lift); color: var(--ink); }

/* A caption for one grid inside a group, where the group label is
   already spent on the larger heading. */
.m-sub {
  margin: 12px 0 6px;
  font-family: var(--font-ui-2); font-size: 10.5px;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-faint);
}
.m-sub:first-child { margin-top: 0; }

/* ——— The cellar's mark, on a phone card ———
   The same two states as the sheet, in the only margin a phone row
   has: the strip to the left of the name. Four pixels. It sits on the
   first line rather than centred, because a two-line row is a long
   name and the mark belongs to the name. */
.m-row { position: relative; }
.m-row[data-stock] { padding-left: 20px; }
.m-row[data-stock]::before {
  content: ''; position: absolute; left: 8px; top: 18px;
  width: 5px; height: 5px; border-radius: 50%; box-sizing: border-box;
  border: 1px solid var(--accent-line); background: transparent;
}
.m-row[data-stock="out"]::before { background: var(--accent-line); }

/* THE PASS on the phone: the card is the screen, not a card on it.
   A dialog with margins around it on a 375px field wastes the only
   thing that matters here, which is the size of the two buttons. */
body.mobile .pass { padding: 0; }
body.mobile .pass-sheet {
  width: 100%; height: 100%; max-height: none;
  border-radius: 0; box-shadow: none;
}
/* The name reads at the top, the dial sits where the thumb already
   is. Centring the whole group put the two buttons in the middle of
   the field, which is the one place a hand holding a phone is not. */
body.mobile .pass-body {
  flex: 1 1 auto;
  display: flex; flex-direction: column; justify-content: flex-start;
  padding: 7vh 20px 26px;
}
body.mobile .pass-dial { margin-top: auto; margin-bottom: 9vh; }
body.mobile .pass-sheet.is-end .pass-body { padding-top: 7vh; }
body.mobile .pass-step { width: 84px; height: 84px; font-size: 32px; }
body.mobile .pass-n { font-size: 64px; }
body.mobile .pass-wine { font-size: 25px; }
body.mobile .pass-skip, body.mobile .pass-go { padding: 20px 10px; }



/* The Cellar's band on the phone: its own group, directly above
   Availability — the observation beside the judgement, never inside
   it. v0.59. */
.m-group-cellar .cellar-band { margin: 0; }
.m-group-cellar .cb-go { padding: 10px 12px; }

/* v0.63 — long names wrap, on the cards and in the fields. A truncated
   wine name on the phone is the same fault as a truncated name on the
   sheet: the one word that tells two bottles apart is the one cut off. */
.m-row-name, .m-row-detail { display: block; white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }
.m-grow {
  display: block; resize: none; overflow: hidden; box-sizing: border-box;
  line-height: 1.3; min-height: 0; margin: 0; overflow-wrap: anywhere;
}
.m-sec-title.m-grow { line-height: 1.25; }
.m-row-price { white-space: nowrap; }
.m-field textarea.m-grow { min-height: 0; resize: none; line-height: 1.35; }

/* v0.74.1 — the way back from the desk on a phone. */
.m-back-phone {
  position: fixed; z-index: 9000; left: 50%; bottom: calc(40px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 18px 0 14px;
  border: 1px solid var(--accent-ink); border-radius: 3px;
  background: var(--accent-ink); color: var(--on-accent, #fff);
  font-family: var(--font-ui-2); font-weight: 600; font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  box-shadow: 0 6px 18px -6px rgba(40, 20, 10, .45);
  cursor: pointer;
}
.m-back-phone[hidden] { display: none; }
.m-back-phone svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.4; }

/* v0.92: one way out of a list. The shelf icon and the chalice sat side
   by side and only one of them left the list; now the chalice, with a
   back arrow, is that one control. The title beside it opens page setup. */
.m-home {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 1px;
  height: 40px; padding: 0 6px 0 4px; border: 0; border-radius: 4px;
  background: transparent; color: var(--accent-ink);
  -webkit-tap-highlight-color: transparent;
}
.m-home:active { background: rgba(0,0,0,.06); }
.m-home-arrow { font-size: 24px; line-height: 1; color: var(--ink-soft); margin-top: -2px; }
.m-home .m-brand { width: 22px; height: 22px; }
.m-home + .m-title { padding-left: 4px; }

/* ═══════════ ONE KIND OF WAY BACK (v0.111) ═══════════
   Everywhere else a bordered chip with ‹ goes back to the place it
   names; here the same ‹ beside the list's title used to mean the
   opposite. The way out now says where it goes, in the same chip. */
.m-home {
  height: 34px; padding: 0 10px 0 7px; gap: 5px;
  border: 1px solid var(--chrome-line-2); border-radius: 3px;
  background: var(--lift); color: var(--ink);
  font-family: var(--font-ui); font-size: 15px; white-space: nowrap;
}
.m-home-arrow { font-size: 17px; color: var(--ink-faint); margin-top: -1px; }
.m-home-ic { width: 15px; height: 15px; flex: none; fill: none; stroke: var(--accent-ink); stroke-width: 1.3; }
.m-home + .m-title { padding-left: 8px; }
[data-theme="dark"] .m-home { background: transparent; }
/* v0.143: the row a wine in Inventory opened the list at. */
.m-row.is-found { animation: m-found 1.8s ease-out; }
@keyframes m-found {
  0%, 30% { box-shadow: inset 0 0 0 2px var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
  100% { box-shadow: inset 0 0 0 2px transparent; background: transparent; }
}
@media (prefers-reduced-motion: reduce) { .m-row.is-found { animation: none; outline: 2px solid var(--accent); } }

/* ════════════════ v0.173: the cloud notice on the phone ════════════════
   "Changed on another device" for the open list, or "Signed out". The
   phone has no status bar, so it sits at the top of the Edit scroll and
   sticks there while the cards scroll under it. Content, not chrome. */
.m-cloud {
  position: sticky; top: 0; z-index: 4;
  margin: 10px 14px 0; padding: 9px 10px 9px 12px;
  border: 1px solid var(--accent-line); border-radius: 3px;
  background: var(--m-card); box-shadow: 0 2px 10px rgba(0, 0, 0, .06);
}
.m-cloud[hidden] { display: none; }
.m-cloud .cl-strip { gap: 8px; }
.m-cloud .cl-said { flex: 1 1 100%; font-size: 10.5px; margin: 0 0 2px; }
.m-cloud .cl-act { min-height: 38px; padding: 0 14px; font-size: 15px; }
