/* Self-hosted so that no request — and no visitor IP — reaches Google. One variable file per
   family and subset covers every weight the app uses. */
@font-face { font-family:'DM Sans'; font-style:normal; font-weight:100 1000; font-display:swap; src:url('fonts/dm-sans-latin-ext.woff2') format('woff2'); unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family:'DM Sans'; font-style:normal; font-weight:100 1000; font-display:swap; src:url('fonts/dm-sans-latin.woff2') format('woff2'); unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family:'Space Grotesk'; font-style:normal; font-weight:300 700; font-display:swap; src:url('fonts/space-grotesk-latin-ext.woff2') format('woff2'); unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family:'Space Grotesk'; font-style:normal; font-weight:300 700; font-display:swap; src:url('fonts/space-grotesk-latin.woff2') format('woff2'); unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
/* Tomato and basil on flour-white — a kitchen rather than Libri's bound book or Tracktivity's cool
   green. --tomato is the colour anything interactive is drawn in; --basil is reserved for things that
   are done — an item in the basket, a step finished — so that green on this page always means "that
   part is taken care of". --saffron marks money. */
:root { --ink:#2a1f1b; --muted:#85766f; --paper:#fbf6f1; --card:#fffdfb; --line:#eedfd5; --tomato:#c2412d; --tomato-soft:#fbe7e1; --basil:#4f7d3a; --basil-soft:#e6f0de; --saffron:#d79a22; --saffron-soft:#fbf0d9; }
* { box-sizing:border-box; }
/* Defensive: user-select inherits, so any future none on an ancestor would silently take away the
   long-press "paste" menu inside text fields. */
input,textarea { user-select:text; -webkit-user-select:text; }
/* Beats any display rule below: .login-shell sets display:flex, which otherwise outranks the
   browser's own [hidden] { display:none } and leaves the signed-out panel showing under every tab. */
[hidden] { display:none !important; }
/* Android browsers "boost" text they take for body copy, which silently overrides small sizes. */
html { -webkit-text-size-adjust:100%; text-size-adjust:100%; }
/* A sideways drag would otherwise engage the browser's own swipe-to-go-back gesture, which nudges the
   whole page and drops fixed elements like the tab bar for a few frames. */
html,body { overscroll-behavior-x:none; }
/* The document does not scroll; the body inside it does. Browsers hang their own furniture — Samsung
   Internet's floating "scroll to top" button among it — off whatever the root scroller is, and in an
   installed app that button lands on top of the tab bar. Not being the root scroller leaves it
   nothing to attach to. See Libri's commit of the same name for the whole story. */
html { height:100%; overflow:hidden; }
body { height:100%; overflow-x:hidden; overflow-y:auto; }
.shell { overflow-x:clip; }
/* Only transform and opacity are animated: those two the compositor handles on its own. */
@keyframes card-in-right { from { opacity:0; transform:translate3d(22%,0,0); } to { opacity:1; transform:none; } }
@keyframes card-in-left { from { opacity:0; transform:translate3d(-22%,0,0); } to { opacity:1; transform:none; } }
@keyframes pop-in { from { opacity:0; transform:translate3d(0,10px,0) scale(.98); } to { opacity:1; transform:none; } }
.view.card-right,.view.card-left { backface-visibility:hidden; will-change:transform, opacity; }
.view.card-right { animation:card-in-right .24s cubic-bezier(.16,.84,.36,1); }
.view.card-left { animation:card-in-left .24s cubic-bezier(.16,.84,.36,1); }
@media (prefers-reduced-motion: reduce) { .view.card-right,.view.card-left,.pick-card { animation:none !important; } }
body { margin:0; background:radial-gradient(circle at 100% 0%, #fbe1d8 0, transparent 36%), radial-gradient(circle at 0% 100%, #eef3e4 0, transparent 30%), var(--paper); background-attachment:fixed; color:var(--ink); font-family:'DM Sans', sans-serif; }
button,input,select,textarea { font:inherit; }
button { cursor:pointer; }
.shell,.login-shell { width:min(100% - 32px, 680px); margin:0 auto; }
.topbar { display:flex; align-items:center; justify-content:space-between; padding:28px 0 18px; gap:10px; }
h1,h2 { font-family:'Space Grotesk', sans-serif; margin:0; letter-spacing:0; }
h1 { font-size:clamp(1.7rem, 6vw, 2.3rem); }
h2 { font-size:1.55rem; }
.kicker,.eyebrow { color:var(--tomato); font-size:.68rem; font-weight:700; letter-spacing:.14em; margin:0 0 7px; text-transform:uppercase; }
.muted { color:var(--muted); }
.icon-button,.small-button { border:0; background:transparent; color:var(--muted); }
.icon-button { font-size:1.35rem; padding:8px; }
.topbar-actions { align-items:center; display:flex; gap:2px; position:relative; }
.menu { background:var(--card); border:1px solid var(--line); border-radius:6px; box-shadow:0 12px 28px rgba(42,31,27,.16); display:flex; flex-direction:column; overflow:hidden; padding:5px; position:absolute; right:0; top:calc(100% + 6px); width:max-content; min-width:190px; z-index:40; }
/* nowrap plus a max-content menu keeps every label on one line, whatever the phone's width.
   Absolute px, not rem: immune to a scaled root font size on the phone. */
.menu-item { background:transparent; border:0; border-radius:4px; color:var(--ink); font-size:11px; letter-spacing:.02em; padding:8px 11px; text-align:left; white-space:nowrap; width:100%; }
.menu-item:hover { background:var(--paper); }
.menu-item.danger { color:#b3382f; }
.menu-caption { color:var(--muted); display:block; font-size:.85em; letter-spacing:.08em; text-transform:uppercase; }
.menu-value { display:block; font-weight:600; margin-top:2px; }
.menu-value:after { content:' ▸'; color:var(--muted); }
.menu-divider { background:var(--line); height:1px; margin:4px 6px; }
.switch-row { align-items:center; cursor:pointer; display:flex; gap:14px; justify-content:space-between; }
.switch-row input { accent-color:var(--basil); cursor:pointer; flex:none; height:20px; margin:0; width:34px; }
.switch-row.busy { opacity:.5; pointer-events:none; }
.section-heading,.view-title { align-items:end; display:flex; gap:12px; justify-content:space-between; }
.section-heading { margin:26px 0 12px; }
.section-heading span { color:var(--muted); font-size:.78rem; }
.view { padding-bottom:100px; }
.view-title { margin:2px 0 18px; }
#view-legal { padding-bottom:40px; }
.intro { margin:-8px 0 18px; }

/* ---- search, chips, segmented controls ---- */
.searchbar { display:flex; gap:8px; }
.searchbar input { background:var(--card); border:1px solid var(--line); border-radius:6px; color:var(--ink); flex:1; min-width:0; padding:12px 13px; }
.searchbar input:focus-visible,.field input:focus-visible,.field textarea:focus-visible,.field select:focus-visible,.ghost-button:focus-visible,.chip:focus-visible,.ingredient-row input:focus-visible,.step-edit textarea:focus-visible { outline:2px solid var(--tomato); outline-offset:2px; }
/* Scrolls sideways rather than wrapping: a household's categories and a phone's width do not fit on
   one line, and a row that grows taller pushes everything below it down every time one is added. */
.chips { display:flex; gap:7px; margin:14px 0 4px; overflow-x:auto; padding-bottom:4px; scrollbar-width:none; }
.chips::-webkit-scrollbar { display:none; }
/* In a dialog the chips wrap instead: there it is a choice being made, and every option should be in
   sight while making it. */
.chips.wrap { flex-wrap:wrap; overflow:visible; margin:0; }
.chip { background:var(--card); border:1px solid var(--line); border-radius:999px; color:var(--muted); flex:none; font-size:.8rem; padding:7px 13px; }
.chip.active { background:var(--tomato); border-color:var(--tomato); color:#fff; font-weight:700; }
.chip.add { border-style:dashed; color:var(--tomato); }
.chip .chip-count { opacity:.7; margin-left:5px; }
.segmented { background:var(--card); border:1px solid var(--line); border-radius:6px; display:flex; overflow:hidden; }
.segmented button { background:transparent; border:0; color:var(--muted); flex:1; font-size:.82rem; padding:9px 6px; }
.segmented button.active { background:var(--tomato); color:#fff; font-weight:700; }

/* ---- photos ----
   Every photo sits in a fixed frame so a page of mismatched pictures still lines up. A recipe with no
   photo gets its initials on a soft tomato ground rather than a broken-image glyph: the grid is read
   by shape, and a hole in it reads as a fault. */
.photo { align-items:center; aspect-ratio:4/3; background:var(--tomato-soft); border-radius:6px; color:var(--tomato); display:flex; flex:none; font-family:'Space Grotesk', sans-serif; font-weight:700; justify-content:center; overflow:hidden; position:relative; }
.photo img { display:block; height:100%; object-fit:cover; width:100%; }
.photo .initials { font-size:1.15rem; letter-spacing:.04em; opacity:.7; }
.photo.square { aspect-ratio:1; }

/* ---- the recipe grid ---- */
.recipe-grid { display:grid; gap:14px 12px; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr)); }
.recipe-card { background:var(--card); border:1px solid var(--line); border-radius:9px; color:var(--ink); display:flex; flex-direction:column; overflow:hidden; padding:0; text-align:left; }
.recipe-card .photo { border-radius:0; width:100%; }
.recipe-card-copy { display:flex; flex-direction:column; gap:4px; padding:10px 11px 12px; }
.recipe-card strong { font-size:.9rem; font-weight:600; line-height:1.25; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
.recipe-card small { color:var(--muted); font-size:.74rem; }
.price { color:#8f6312; font-variant-numeric:tabular-nums; font-weight:700; }

/* ---- rows: history, the calendar day, the recipe picker ---- */
.row-list { display:flex; flex-direction:column; gap:8px; }
.row { align-items:center; background:var(--card); border:1px solid var(--line); border-radius:8px; color:var(--ink); display:flex; gap:12px; padding:10px 12px; text-align:left; width:100%; }
.row .photo { width:58px; }
.row-copy { display:flex; flex:1; flex-direction:column; gap:3px; min-width:0; }
.row-copy strong { font-size:.94rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.row-copy small { color:var(--muted); font-size:.77rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.row .arrow { color:var(--muted); font-size:1.2rem; margin-left:auto; }
.row-actions { display:flex; flex:none; gap:6px; }
.meter { background:var(--line); border-radius:3px; height:5px; margin-top:4px; overflow:hidden; }
.meter i { background:var(--basil); border-radius:3px; display:block; height:100%; }
.pill { background:var(--tomato-soft); border-radius:999px; color:var(--tomato); display:inline-block; font-size:.68rem; font-weight:700; letter-spacing:.05em; padding:4px 9px; text-transform:uppercase; white-space:nowrap; }
.pill.cooked { background:var(--basil-soft); color:var(--basil); }
.pill.dropped { background:#eee9e6; color:var(--muted); }
.pill.repeat { background:var(--saffron-soft); color:#8f6312; }
.pill-row { display:flex; flex-wrap:wrap; gap:6px; }

/* ---- today ---- */
.panel { background:var(--card); border:1px solid var(--line); border-radius:12px; padding:16px; }
.panel + .panel { margin-top:12px; }
.panel h3 { font-family:'Space Grotesk', sans-serif; font-size:1rem; margin:0 0 10px; }
.pick-panel { background:linear-gradient(160deg, #fff 0%, var(--tomato-soft) 140%); }
.pick-button { align-items:center; background:var(--tomato); border:0; border-radius:10px; box-shadow:0 6px 18px rgba(194,65,45,.28); color:#fff; display:flex; font-family:'Space Grotesk', sans-serif; font-size:1.15rem; font-weight:700; gap:10px; justify-content:center; margin-top:14px; min-height:58px; width:100%; }
.pick-button span { font-size:1.4rem; }
.pick-button:active { transform:translateY(1px); }
.pick-card { animation:pop-in .22s cubic-bezier(.16,.84,.36,1); margin-top:14px; }
.pick-card.steady { animation:none; }
.pick-card .photo { border-radius:9px; width:100%; }
.pick-card h3 { font-size:1.35rem; margin:12px 0 4px; }
.pick-meta { color:var(--muted); display:flex; flex-wrap:wrap; font-size:.82rem; gap:4px 12px; margin-bottom:10px; }
.pick-actions { display:flex; gap:9px; margin-top:14px; }
.pick-actions > button { flex:1; min-height:48px; }
.pick-tally { color:var(--muted); font-size:.76rem; margin:10px 0 0; text-align:center; }

/* ---- an ingredient list, read-only ---- */
.ingredient-list { list-style:none; margin:0; padding:0; }
.ingredient-list li { align-items:baseline; border-bottom:1px dashed var(--line); display:flex; font-size:.9rem; gap:10px; padding:7px 0; }
.ingredient-list li:last-child { border-bottom:0; }
.ingredient-list .qty { color:var(--muted); flex:none; font-size:.82rem; min-width:62px; }
.ingredient-list .name { flex:1; min-width:0; }
.ingredient-list .price { flex:none; font-size:.82rem; font-weight:600; }
.total-line { align-items:baseline; border-top:2px solid var(--ink); display:flex; font-weight:700; justify-content:space-between; margin-top:4px; padding-top:8px; }
.total-line .price { font-family:'Space Grotesk', sans-serif; font-size:1.1rem; }
.total-line small { color:var(--muted); font-size:.72rem; font-weight:400; }

/* ---- the method, read-only ---- */
.method { counter-reset:step; list-style:none; margin:0; padding:0; }
.method li { counter-increment:step; display:flex; font-size:.92rem; gap:12px; line-height:1.55; margin:0 0 12px; white-space:pre-wrap; }
.method li:before { align-items:center; background:var(--tomato-soft); border-radius:50%; color:var(--tomato); content:counter(step); display:flex; flex:none; font-family:'Space Grotesk', sans-serif; font-size:.8rem; font-weight:700; height:26px; justify-content:center; width:26px; }
.prose { font-size:.92rem; line-height:1.6; margin:0; overflow-wrap:anywhere; white-space:pre-wrap; }

/* ---- one recipe, opened ---- */
/* The pictures scroll sideways and snap, one to a screen: it is how a phone already shows a set of
   photos, so it needs no explaining and no controls of its own. */
.gallery { border-radius:10px; display:flex; gap:8px; margin:-4px 0 14px; overflow-x:auto; scroll-snap-type:x mandatory; scrollbar-width:none; }
.gallery::-webkit-scrollbar { display:none; }
.gallery .photo { scroll-snap-align:center; width:100%; }
.gallery-count { color:var(--muted); font-size:.72rem; margin:-8px 0 12px; text-align:center; }
.recipe-head h3 { font-size:1.35rem; line-height:1.25; margin:0 0 6px; }
.recipe-notes { background:var(--paper); border-left:3px solid var(--tomato); border-radius:0 5px 5px 0; font-size:.88rem; line-height:1.55; margin:12px 0; overflow-wrap:anywhere; padding:10px 12px; white-space:pre-wrap; }
.sheet-section { color:var(--muted); font-size:.7rem; font-weight:700; letter-spacing:.1em; margin:18px 0 8px; text-transform:uppercase; }

/* ---- cooking: the shopping list ---- */
.cook-head { margin-bottom:14px; }
.cook-head h2 { font-size:1.45rem; line-height:1.2; }
.cook-summary { align-items:center; display:flex; gap:10px; justify-content:space-between; margin:14px 0 10px; }
.cook-summary strong { font-family:'Space Grotesk', sans-serif; font-size:1.25rem; }
.cook-summary small { color:var(--muted); display:block; font-size:.74rem; }
.shop-list { display:flex; flex-direction:column; gap:7px; }
/* The row is the target, not a small checkbox inside it: this is used one-handed, in a shop, with a
   basket in the other hand. */
.shop-item { align-items:center; background:var(--card); border:1px solid var(--line); border-radius:9px; display:flex; gap:12px; min-height:56px; padding:6px 8px 6px 12px; transition:background .15s, opacity .15s; }
.shop-tick { align-items:center; background:transparent; border:0; color:var(--ink); display:flex; flex:1; gap:12px; min-width:0; padding:6px 0; text-align:left; }
.tick-box { align-items:center; border:2px solid var(--line); border-radius:50%; color:transparent; display:flex; flex:none; font-size:.85rem; font-weight:700; height:26px; justify-content:center; transition:.15s; width:26px; }
.shop-copy { display:flex; flex:1; flex-direction:column; gap:1px; min-width:0; }
.shop-copy strong { font-size:.95rem; font-weight:600; overflow-wrap:anywhere; }
.shop-copy small { color:var(--muted); font-size:.78rem; }
.shop-item .price { flex:none; font-size:.85rem; }
.skip-button { background:transparent; border:1px solid var(--line); border-radius:5px; color:var(--muted); flex:none; font-size:.68rem; letter-spacing:.03em; padding:6px 7px; white-space:nowrap; }
.shop-item.got { background:var(--basil-soft); border-color:#cfe0c2; }
.shop-item.got .tick-box { background:var(--basil); border-color:var(--basil); color:#fff; }
.shop-item.got .shop-copy strong { color:#3b5e2b; }
.shop-item.skipped { opacity:.55; }
.shop-item.skipped .shop-copy strong,.shop-item.skipped .price { text-decoration:line-through; }
.shop-item.skipped .skip-button { background:var(--ink); border-color:var(--ink); color:#fff; }
.shop-item.readonly .shop-tick,.shop-item.readonly .skip-button { pointer-events:none; }

/* ---- cooking: the method ---- */
.step-list { display:flex; flex-direction:column; gap:10px; }
.step-card { background:var(--card); border:1px solid var(--line); border-radius:10px; display:flex; gap:12px; padding:14px; transition:opacity .2s, background .2s; }
.step-number { align-items:center; background:var(--tomato); border-radius:50%; color:#fff; display:flex; flex:none; font-family:'Space Grotesk', sans-serif; font-weight:700; height:30px; justify-content:center; width:30px; }
.step-body { display:flex; flex:1; flex-direction:column; gap:10px; min-width:0; }
.step-body p { font-size:.98rem; line-height:1.6; margin:0; overflow-wrap:anywhere; white-space:pre-wrap; }
.step-done { align-self:flex-start; background:transparent; border:1px solid var(--basil); border-radius:5px; color:var(--basil); font-size:.8rem; font-weight:700; padding:7px 13px; }
/* Greyed rather than hidden or moved: a finished step stays where it was, so the eye does not lose
   its place, and the one being worked on is simply the first one still in colour. */
.step-card.done { background:transparent; opacity:.45; }
.step-card.done .step-number { background:var(--basil); }
.step-card.done .step-body p { text-decoration:line-through; text-decoration-color:rgba(42,31,27,.35); }
.step-card.done .step-done { background:var(--basil); color:#fff; }
.step-card.current { border-color:var(--tomato); box-shadow:0 4px 16px rgba(194,65,45,.12); }
.cook-finish { background:var(--basil-soft); border:1px solid #cfe0c2; border-radius:10px; color:#3b5e2b; margin-top:14px; padding:14px; text-align:center; }
.cook-finish p { margin:0 0 10px; }
.cook-footer { display:flex; flex-wrap:wrap; gap:9px; justify-content:space-between; margin-top:22px; }

/* ---- the calendar ---- */
.month-bar { align-items:center; display:flex; gap:8px; justify-content:space-between; margin-bottom:12px; }
.month-bar h2 { font-size:1.3rem; }
.month-nav { display:flex; gap:6px; }
.month-nav button { background:var(--card); border:1px solid var(--line); border-radius:6px; color:var(--ink); font-size:.85rem; min-width:38px; padding:8px 10px; }
.calendar { display:grid; gap:4px; grid-template-columns:repeat(7, minmax(0, 1fr)); }
.calendar .weekday { color:var(--muted); font-size:.66rem; font-weight:700; letter-spacing:.08em; padding:2px 0 4px; text-align:center; text-transform:uppercase; }
.day { align-items:stretch; background:var(--card); border:1px solid var(--line); border-radius:7px; color:var(--ink); display:flex; flex-direction:column; gap:3px; min-height:62px; overflow:hidden; padding:5px 4px; text-align:left; }
.day .day-number { font-size:.78rem; font-weight:600; padding-left:2px; }
.day.outside { background:transparent; border-color:transparent; color:#c4b8b1; }
.day.today .day-number { align-items:center; background:var(--tomato); border-radius:999px; color:#fff; display:inline-flex; justify-content:center; min-width:22px; padding:1px 6px; width:max-content; }
.day.selected { border-color:var(--tomato); box-shadow:inset 0 0 0 1px var(--tomato); }
.day .meal-tag { background:var(--saffron-soft); border-radius:3px; color:#7a540f; font-size:.6rem; line-height:1.3; overflow:hidden; padding:1px 4px; text-overflow:ellipsis; white-space:nowrap; }
.day .meal-more { color:var(--muted); font-size:.6rem; padding-left:3px; }
.day-panel { margin-top:16px; }
.day-panel .section-heading { margin-top:0; }

/* ---- the recipe editor ---- */
.photo-strip { display:flex; flex-wrap:wrap; gap:8px; }
.photo-thumb { position:relative; width:76px; }
.photo-thumb .photo { width:76px; }
.photo-thumb button { align-items:center; background:rgba(42,31,27,.75); border:0; border-radius:50%; color:#fff; display:flex; font-size:.85rem; height:22px; justify-content:center; padding:0; position:absolute; right:4px; top:4px; width:22px; }
.photo-thumb .first { background:var(--tomato); border-radius:3px; bottom:4px; color:#fff; font-size:.55rem; font-weight:700; left:4px; letter-spacing:.05em; padding:2px 4px; position:absolute; text-transform:uppercase; }
.photo-add { align-items:center; aspect-ratio:4/3; background:var(--card); border:1.5px dashed var(--line); border-radius:6px; color:var(--tomato); display:flex; flex-direction:column; font-size:.68rem; gap:2px; justify-content:center; width:76px; }
.photo-add span { font-size:1.2rem; line-height:1; }
.ingredient-editor { display:flex; flex-direction:column; gap:7px; }
/* Name gets the room, quantity and price are short by nature. On a phone the three would be too
   cramped on one line, so the name takes a line of its own there. */
.ingredient-row { display:grid; gap:6px; grid-template-columns:1fr 92px 80px 30px; }
.ingredient-row input { background:var(--card); border:1px solid var(--line); border-radius:5px; color:var(--ink); min-width:0; padding:10px 9px; width:100%; }
.ingredient-row .remove,.step-edit .remove { background:transparent; border:0; color:var(--muted); font-size:1.1rem; padding:0; }
@media (max-width: 460px) {
  .ingredient-row { grid-template-columns:1fr 80px 30px; }
  .ingredient-row .ingredient-name { grid-column:1 / -1; }
}
.add-row { align-self:flex-start; background:transparent; border:1px dashed var(--line); border-radius:5px; color:var(--tomato); font-size:.82rem; font-weight:600; margin-top:2px; padding:8px 12px; }
.editor-total { color:var(--muted); font-size:.8rem; margin-top:6px; text-align:right; }
.step-editor { display:flex; flex-direction:column; gap:8px; }
.step-edit { align-items:flex-start; display:flex; gap:8px; }
.step-edit .step-number { font-size:.8rem; height:26px; margin-top:8px; width:26px; }
.step-edit textarea { background:var(--card); border:1px solid var(--line); border-radius:5px; color:var(--ink); flex:1; font-family:inherit; font-size:.92rem; min-width:0; padding:9px; resize:vertical; }
.step-tools { display:flex; flex:none; flex-direction:column; }
.step-tools button { background:transparent; border:0; color:var(--muted); font-size:.85rem; padding:3px 4px; }
.step-tools button:disabled { opacity:.3; }
.method-mode { margin-bottom:10px; }
.new-category { display:flex; gap:7px; margin-top:8px; }
.new-category input { background:var(--card); border:1px solid var(--line); border-radius:5px; color:var(--ink); flex:1; min-width:0; padding:8px 10px; }

/* ---- imprint and privacy ---- */
.back-button { background:transparent; border:0; color:inherit; font:inherit; letter-spacing:inherit; margin:0; padding:0; text-transform:inherit; }
.imprint-button { background:transparent; border:0; color:var(--muted); font-size:.78rem; padding:8px 4px; white-space:nowrap; }
.legal-block { background:var(--card); border:1px solid var(--line); border-radius:8px; padding:16px 18px; }
.legal-facts { display:grid; gap:2px 16px; grid-template-columns:auto 1fr; margin:0 0 14px; }
.legal-facts dt { color:var(--muted); font-size:.76rem; letter-spacing:.06em; text-transform:uppercase; }
.legal-facts dd { margin:0 0 8px; }
.legal-block a,.legal-body a { color:var(--tomato); }
.legal-details { background:var(--card); border:1px solid var(--line); border-radius:8px; margin-top:12px; }
.legal-details summary { cursor:pointer; font-family:'Space Grotesk', sans-serif; font-size:1.05rem; font-weight:600; list-style:none; padding:15px 18px; }
.legal-details summary::-webkit-details-marker { display:none; }
.legal-details summary:after { color:var(--muted); content:'▾'; float:right; transition:transform .2s; }
.legal-details[open] summary:after { transform:rotate(180deg); }
.legal-body { border-top:1px solid var(--line); padding:4px 18px 18px; }
.legal-body h3 { font-family:'Space Grotesk', sans-serif; font-size:.95rem; margin:18px 0 6px; }
.legal-body p,.legal-body li { color:#4a3d38; font-size:.88rem; line-height:1.55; margin:6px 0; }
.legal-body ul { margin:6px 0; padding-left:20px; }

/* ---- tab bar ----
   Opaque, not translucent: translate3d and will-change keep it on its own compositor layer, so it is
   not repainted — and briefly dropped — while a card animates past. */
.tabbar { background:var(--paper); border-top:1px solid var(--line); bottom:0; display:flex; justify-content:space-around; left:50%; max-width:680px; padding:11px 0 max(11px, env(safe-area-inset-bottom)); position:fixed; transform:translate3d(-50%,0,0); width:100%; will-change:transform; z-index:3; }
.tabbar button { background:none; border:0; color:var(--muted); display:flex; flex-direction:column; font-size:.72rem; gap:4px; padding:3px 12px; }
.tabbar button span { font-size:1.25rem; line-height:1; }
.tabbar button.active { color:var(--tomato); font-weight:700; }
.tabbar button em { font-style:normal; }

/* ---- buttons, dialogs, the rest of the furniture ---- */
.primary-button { background:var(--tomato); border:0; border-radius:5px; color:#fff; font-weight:700; padding:10px 18px; white-space:nowrap; }
.primary-button.basil { background:var(--basil); }
.primary-button:disabled,.update-button:disabled,.tiny-button:disabled { opacity:.55; cursor:default; }
.ghost-button { background:transparent; border:1px solid var(--line); border-radius:5px; color:var(--ink); font-weight:500; padding:10px 14px; }
.tiny-button { background:var(--card); border:1px solid var(--line); border-radius:5px; color:var(--ink); font-size:.8rem; padding:7px 10px; white-space:nowrap; }
.tiny-button.go { background:var(--tomato); border-color:var(--tomato); color:#fff; font-weight:700; }
.danger-button { background:#b3564d; }
.link-button { background:none; border:0; color:var(--tomato); font-weight:700; padding:0; text-decoration:underline; }
.danger { color:#b3564d; }
.empty-state { color:var(--muted); padding:30px 10px; text-align:center; }
.empty-state .link-button { margin-top:8px; }
.modal-overlay { align-items:center; background:rgba(42,31,27,.46); bottom:0; display:flex; justify-content:center; left:0; opacity:0; padding:20px; position:fixed; right:0; top:0; transition:opacity .16s; z-index:10; }
.modal-overlay.open { opacity:1; }
.modal { background:var(--paper); border-radius:12px; box-shadow:0 18px 44px rgba(42,31,27,.26); max-height:calc(100vh - 40px); max-width:480px; overflow-y:auto; padding:22px; transform:translateY(8px); transition:transform .16s; width:100%; }
.modal.wide { max-width:560px; }
/* vh on a phone is measured with the browser's toolbars hidden, so a dialog sized in it is taller
   than what can be seen and its last row — the buttons — sits under the address bar. dvh is the
   height there really is. */
@supports (max-height: 100dvh) { .modal { max-height:calc(100dvh - 40px); } }
.modal-overlay.open .modal { transform:none; }
.modal h3 { font-family:'Space Grotesk', sans-serif; font-size:1.2rem; margin:0 0 10px; }
.modal-copy { color:var(--muted); font-size:.9rem; line-height:1.45; margin:0 0 18px; }
/* Wrapping is not cosmetic: a flex row that justifies to the end overflows towards the start, and
   overflow in that direction cannot be scrolled to — on a narrow phone the leftmost button, which is
   Delete, was simply gone in Libri before this. */
.modal-actions { display:flex; flex-wrap:wrap; gap:9px; justify-content:flex-end; margin-top:20px; }
.modal-actions .spacer { flex:1 1 0; min-width:0; }
@media (max-width: 460px) {
  .modal-overlay { padding:12px; }
  .modal { padding:18px; }
  .modal-actions { flex-direction:column-reverse; }
  .modal-actions .spacer { display:none; }
  .modal-actions > button { padding:12px 14px; width:100%; }
}
.field { display:flex; flex-direction:column; gap:8px; margin-bottom:16px; }
.field > span { color:var(--muted); font-size:.72rem; font-weight:700; letter-spacing:.09em; text-transform:uppercase; }
.field input,.field textarea,.field select { background:var(--card); border:1px solid var(--line); border-radius:5px; color:var(--ink); padding:11px; width:100%; }
.field textarea { font-family:inherit; font-size:.95rem; resize:vertical; }
.field select { appearance:none; background-image:linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position:calc(100% - 17px) 50%, calc(100% - 12px) 50%; background-repeat:no-repeat; background-size:5px 5px, 5px 5px; padding-right:34px; }
.field-row { display:flex; gap:9px; }
.field-row > .field { flex:1; min-width:0; }
@media (max-width: 360px) { .field-row { flex-direction:column; gap:0; } }
.picker-list { display:flex; flex-direction:column; gap:7px; max-height:38vh; overflow-y:auto; }
.picker-list .row { cursor:pointer; }
.picker-list .row.chosen { border-color:var(--tomato); box-shadow:inset 0 0 0 1px var(--tomato); }
.picker-list .row .photo { width:44px; }

/* ---- signed out, and the two banners ---- */
.login-shell { align-items:flex-start; display:flex; flex-direction:column; justify-content:center; min-height:100vh; padding:30px 0; }
.login-mark { align-items:center; background:var(--tomato); border-radius:50%; color:#fff; display:flex; font-size:2rem; height:64px; justify-content:center; margin-bottom:26px; width:64px; }
.login-shell h1 { font-size:clamp(2.2rem, 11vw, 4.5rem); max-width:520px; }
.login-shell > .muted { margin:10px 0 30px; }
.login-actions { display:flex; gap:9px; margin-top:4px; }
.login-actions .primary-button { align-items:center; display:flex; flex:1; justify-content:center; min-height:48px; text-decoration:none; }
.login-switch { color:var(--muted); font-size:.85rem; margin:14px 0 0; }
.build-badge { color:var(--muted); font-size:.6rem; letter-spacing:.04em; margin:0; opacity:.7; pointer-events:none; position:fixed; right:12px; top:max(calc(env(safe-area-inset-top) + 6px), 6px); z-index:2; }
.update-banner { align-items:center; background:var(--ink); border-radius:6px; color:var(--paper); display:flex; font-size:.85rem; gap:12px; left:50%; max-width:calc(100% - 32px); padding:10px 12px; position:fixed; top:12px; transform:translateX(-50%); width:680px; z-index:6; }
.update-banner span { flex:1; }
.update-button { background:var(--saffron); border:0; border-radius:5px; color:var(--ink); font-weight:700; padding:8px 14px; }
#toast { background:var(--ink); border-radius:5px; bottom:85px; color:#fff; left:50%; max-width:calc(100% - 32px); opacity:0; padding:12px 16px; pointer-events:none; position:fixed; transform:translate(-50%, 15px); transition:.2s; z-index:20; }
#toast.show { opacity:1; transform:translate(-50%,0); }

@media (max-width:520px) {
  .shell,.login-shell { width:min(100% - 24px, 680px); }
  .recipe-grid { gap:10px; grid-template-columns:repeat(2, minmax(0, 1fr)); }
  .primary-button { min-height:46px; }
  .day { min-height:52px; padding:4px 3px; }
  .day .meal-tag { font-size:.56rem; }
  .tabbar button { padding:3px 8px; }
}

/* ---- servings on the pick ---- */
.servings-row { align-items:center; display:flex; flex-wrap:wrap; gap:8px 12px; margin:4px 0 2px; }
.servings-row > span { color:var(--muted); font-size:.7rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase; }
.stepper { align-items:center; background:var(--card); border:1px solid var(--line); border-radius:8px; display:flex; overflow:hidden; }
/* 40px targets: this is changed with a thumb, often more than once in a row. */
.stepper button { background:transparent; border:0; color:var(--tomato); font-size:1.25rem; font-weight:700; height:40px; line-height:1; width:40px; }
.stepper button:disabled { color:var(--line); cursor:default; }
.stepper input { border:0; border-left:1px solid var(--line); border-right:1px solid var(--line); color:var(--ink); font-family:'Space Grotesk', sans-serif; font-size:1.05rem; font-weight:700; height:40px; text-align:center; width:48px; }
.stepper input:focus-visible { outline:2px solid var(--tomato); outline-offset:-2px; }
.servings-reset { font-size:.78rem; }
.servings-note { font-size:.8rem; margin:4px 0 0; }
