/* ------------------------------------------------------------------ *
 * flush.css  ...  the ONE stylesheet.
 *
 * Mycelia grew to eight stylesheets and 186 selectors defined in three
 * or more files, and the result stopped reading as one design. This app
 * starts with one file and stays that way. If you are about to add a
 * second stylesheet, edit this one instead.
 *
 * Order: tokens, reset, layout, nav, primitives, screens, sheet, toast.
 * ------------------------------------------------------------------ */

/* ---------- tokens ---------- */
:root {
  color-scheme: light dark;

  /* Brand. Warm and earthy, deliberately nothing like Mycelia's cosmic
     teal and violet, so the two apps never read as the same product. */
  --moss:      #2f6b46;
  --moss-lift: #3d8759;
  --amber:     #b8781a;
  --rust:      #a5613a;
  --danger:    #b3402f;

  --grad: linear-gradient(135deg, #2f6b46 0%, #43855a 55%, #7a9a44 100%);

  /* Light is the default, per the house preference for light first. */
  --bg:      #f4f1e9;
  --bg-2:    #ebe6da;
  --surface: #fffdf7;
  --surface-2:#f7f3ea;
  --ink:     #1f1c17;
  --ink-mut: #6b6459;
  --ink-dim: #8b8478;
  --line:    #e0d9c9;
  --line-2:  #cec5b1;
  --edge-hi: rgba(255,255,255,.9);
  --edge-lo: rgba(31,28,23,.05);
  --shadow:  0 1px 2px rgba(31,28,23,.05), 0 8px 24px -12px rgba(31,28,23,.18);
  --shadow-lift: 0 2px 4px rgba(31,28,23,.06), 0 18px 40px -18px rgba(31,28,23,.28);
  --on-brand:#ffffff;

  --r-sm: 8px;  --r: 14px;  --r-lg: 20px;  --r-xl: 26px;
  --hit: 44px;
  --scale: 1;
  --maxw: 720px;

  --ease: cubic-bezier(.22,.75,.3,1);
}

:root[data-theme="dark"], :root[data-theme="auto"] {
  /* placeholder so the selector exists; real dark values below */
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:      #17140f;
    --bg-2:    #1e1a14;
    --surface: #221e17;
    --surface-2:#2a2519;
    --ink:     #f2ece0;
    --ink-mut: #b0a897;
    --ink-dim: #8b8375;
    --line:    #362f24;
    --line-2:  #473e2f;
    --edge-hi: rgba(255,255,255,.06);
    --edge-lo: rgba(0,0,0,.3);
    --shadow:  0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.7);
    --shadow-lift: 0 2px 4px rgba(0,0,0,.45), 0 18px 40px -18px rgba(0,0,0,.8);
    --moss-lift: #55a271;
    --amber: #d9982f;
  }
}
/* Explicit choice always wins over the system preference, both ways. */
:root[data-theme="dark"] {
  --bg:      #17140f;
  --bg-2:    #1e1a14;
  --surface: #221e17;
  --surface-2:#2a2519;
  --ink:     #f2ece0;
  --ink-mut: #b0a897;
  --ink-dim: #8b8375;
  --line:    #362f24;
  --line-2:  #473e2f;
  --edge-hi: rgba(255,255,255,.06);
  --edge-lo: rgba(0,0,0,.3);
  --shadow:  0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.7);
  --shadow-lift: 0 2px 4px rgba(0,0,0,.45), 0 18px 40px -18px rgba(0,0,0,.8);
  --moss-lift: #55a271;
  --amber: #d9982f;
}

/* ---------- reset ---------- */
/* A base rule like .layer{display:grid} outranks the UA [hidden] rule, which
   is how overlay layers end up visible on load. This is the global fix. */
[hidden] { display: none !important; }

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  font-size: calc(16px * var(--scale));
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}
img { max-width: 100%; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -.015em; }
p { margin: 0; }
a { color: var(--moss-lift); }

::selection { background: color-mix(in srgb, var(--moss) 26%, transparent); }
:focus-visible { outline: 2px solid var(--moss-lift); outline-offset: 2px; border-radius: 6px; }
input, textarea, select { caret-color: var(--moss-lift); }

.skip {
  position: fixed; left: 8px; top: -60px; z-index: 200;
  background: var(--moss); color: #fff; padding: 10px 16px; border-radius: var(--r-sm);
  text-decoration: none; transition: top .16s var(--ease);
}
.skip:focus { top: 8px; }

/* Every counter, timestamp and stat, so numbers stop jittering as they change. */
.num, .stat-v, .kv b, .co-row b, .g-day, .rb-v { font-variant-numeric: tabular-nums; }

/* ---------- layout ---------- */
#app {
  min-height: 100dvh;
  display: grid;
  grid-template-rows: 1fr auto;
}
#screen {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0 0 24px;
}
.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: max(18px, env(safe-area-inset-top)) 18px 8px;
}

/* Screen reveal.
   Content is VISIBLE by default and the animation is added on top. Mycelia had
   this the other way round, with .wrap>* starting at opacity 0 and fill-mode
   both, which meant that if the animation clock never started the whole screen
   stayed invisible. The failure mode here is a missing animation, never a
   missing screen. .animating is added by render() and removed once it is done. */
@media (prefers-reduced-motion: no-preference) {
  #screen.animating .wrap > * { animation: rise .4s var(--ease) backwards; }
  #screen.animating .wrap > *:nth-child(1) { animation-delay: .01s; }
  #screen.animating .wrap > *:nth-child(2) { animation-delay: .05s; }
  #screen.animating .wrap > *:nth-child(3) { animation-delay: .09s; }
  #screen.animating .wrap > *:nth-child(4) { animation-delay: .13s; }
  #screen.animating .wrap > *:nth-child(n+5) { animation-delay: .16s; }
}
@keyframes rise { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }

/* ---------- nav ---------- */
#nav {
  display: flex;
  border-top: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  padding-bottom: env(safe-area-inset-bottom);
  position: sticky; bottom: 0; z-index: 20;
}
#nav button {
  flex: 1;
  min-height: var(--hit);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  background: none; border: 0; padding: 8px 2px;
  color: var(--ink-dim);
  font-size: calc(10.5px * var(--scale)); font-weight: 650; letter-spacing: .02em;
  transition: color .14s var(--ease);
}
#nav button svg { width: 22px; height: 22px; }
#nav button.on { color: var(--moss-lift); }
#nav button.on svg { stroke-width: 2.1; }

@media (min-width: 860px) {
  #app { grid-template-rows: none; grid-template-columns: 232px 1fr; }
  #nav {
    position: sticky; top: 0; bottom: auto; order: -1;
    flex-direction: column; justify-content: flex-start; gap: 3px;
    height: 100dvh; padding: 20px 12px;
    border-top: 0; border-right: 1px solid var(--line);
  }
  #nav button { flex: 0 0 auto; flex-direction: row; justify-content: flex-start; gap: 12px; padding: 11px 13px; border-radius: var(--r); font-size: calc(14.5px * var(--scale)); }
  #nav button.on { background: color-mix(in srgb, var(--moss) 12%, transparent); }
  #nav .navbrand { display: flex; align-items: center; gap: 9px; padding: 4px 13px 18px; font-weight: 800; font-size: calc(19px * var(--scale)); letter-spacing: -.02em; }
  #screen { height: 100dvh; }
}
#nav .navbrand { display: none; }

/* ---------- primitives ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  padding: 16px;
  margin-bottom: 14px;
}
/* One shared edge treatment: light catches the top, it sits down onto the page.
   Two lines, and it is the difference between a surface and a grey rectangle. */
.card, .tile, .sheet-inner, .stat, .listrow {
  box-shadow: var(--shadow), inset 0 1px 0 var(--edge-hi), inset 0 -1px 0 var(--edge-lo);
}
.card.lift { box-shadow: var(--shadow-lift), inset 0 1px 0 var(--edge-hi), inset 0 -1px 0 var(--edge-lo); }

.h-top { margin-bottom: 16px; }
.htitle { font-size: calc(27px * var(--scale)); font-weight: 800; letter-spacing: -.03em; line-height: 1.15; }
.hsub { color: var(--ink-mut); font-size: calc(14.5px * var(--scale)); margin-top: 4px; }
.section-label {
  display: flex; align-items: center; gap: 7px;
  font-size: calc(11.5px * var(--scale)); font-weight: 750; letter-spacing: .075em; text-transform: uppercase;
  color: var(--ink-mut); opacity: .86;
  margin: 22px 0 10px;
}
.section-label:first-child { margin-top: 0; }

.btn {
  min-height: var(--hit);
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 0 18px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--surface);
  font-size: calc(15px * var(--scale)); font-weight: 650;
  transition: transform .1s var(--ease), filter .14s var(--ease);
}
.btn:active { transform: scale(.975); }
.btn-primary { background: var(--grad); background-size: cover; border-color: transparent; color: var(--on-brand); }
.btn-primary:hover { filter: brightness(1.06); }
.btn-block { width: 100%; }
.btn-lg { min-height: 54px; font-size: calc(16px * var(--scale)); }
.btn-quiet { background: transparent; border-color: transparent; color: var(--ink-mut); }
.btn-danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 35%, transparent); background: transparent; }
.btn-sm { min-height: 36px; padding: 0 13px; font-size: calc(13.5px * var(--scale)); }

.seg {
  display: flex; gap: 3px; padding: 3px;
  background: var(--bg-2); border-radius: 999px; margin-bottom: 16px;
  overflow-x: auto; scrollbar-width: none; touch-action: pan-x pan-y;
}
.seg::-webkit-scrollbar { display: none; }
.seg button {
  flex: 1 0 auto; min-height: 38px; padding: 0 15px;
  border: 0; background: none; border-radius: 999px; white-space: nowrap;
  color: var(--ink-mut); font-size: calc(13.5px * var(--scale)); font-weight: 650;
}
.seg button.on { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }
/* A tab strip wider than the screen with no edge treatment reads as if those
   are all the tabs there are. The fade is added by JS only when it actually
   overflows, and removed once you reach the end, so it never lies. */
.seg.can-scroll { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 30px), transparent 100%); mask-image: linear-gradient(to right, #000 calc(100% - 30px), transparent 100%); }
.seg.can-scroll.at-end { -webkit-mask-image: none; mask-image: none; }

.field { margin-bottom: 12px; }
.field label { display: block; font-size: calc(13px * var(--scale)); font-weight: 650; color: var(--ink-mut); margin-bottom: 6px; }
.field label span { font-weight: 500; opacity: .8; }
.inp {
  width: 100%; min-height: var(--hit); padding: 10px 13px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r);
  font-size: calc(15.5px * var(--scale));
}
textarea.inp { min-height: 84px; resize: vertical; line-height: 1.5; }
select.inp { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--ink-mut) 50%), linear-gradient(135deg, var(--ink-mut) 50%, transparent 50%); background-position: right 18px center, right 13px center; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 36px; }

.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 999px;
  font-size: calc(11.5px * var(--scale)); font-weight: 700; letter-spacing: .01em;
  background: var(--bg-2); color: var(--ink-mut);
}
.pill.moss { background: color-mix(in srgb, var(--moss) 15%, transparent); color: var(--moss-lift); }
.pill.amber { background: color-mix(in srgb, var(--amber) 18%, transparent); color: var(--amber); }
.pill.rust { background: color-mix(in srgb, var(--rust) 16%, transparent); color: var(--rust); }
.pill.danger { background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); }

.empty {
  text-align: center; padding: 34px 20px; color: var(--ink-mut);
  border: 1px dashed var(--line-2); border-radius: var(--r-lg); background: var(--surface-2);
}
.empty svg { margin: 0 auto 10px; color: var(--ink-dim); }
.empty b { display: block; color: var(--ink); font-size: calc(16px * var(--scale)); margin-bottom: 5px; }

.note {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 12px 14px; border-radius: var(--r);
  background: color-mix(in srgb, var(--amber) 11%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--amber) 30%, transparent);
  font-size: calc(13.5px * var(--scale)); line-height: 1.5;
  margin-bottom: 14px;
}
.note svg { flex: 0 0 auto; color: var(--amber); margin-top: 1px; }
.note.danger { background: color-mix(in srgb, var(--danger) 10%, var(--surface)); border-color: color-mix(in srgb, var(--danger) 32%, transparent); }
.note.danger svg { color: var(--danger); }
.note b { display: block; }

/* Dividers inset to where the text starts. A full bleed rule is a table
   border, an inset one is a list. */
.divide > * + * { border-top: 1px solid var(--line); }
.divide.inset > * + * { position: relative; border-top: 0; }
.divide.inset > * + *::before { content: ''; position: absolute; left: 56px; right: 0; top: 0; height: 1px; background: var(--line); }

/* ---------- tiles ---------- */
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; margin-bottom: 14px; }
.tile {
  text-align: left; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 14px; min-height: 96px;
  display: flex; flex-direction: column; gap: 4px;
}
.tile .tic { width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center; margin-bottom: 6px; color: #fff; flex: 0 0 auto; }
/* Icon tints all walk one brand ramp. Four unrelated default hues side by side
   is not a palette, it is four defaults. */
.tg-1 { background: linear-gradient(140deg, #2f6b46, #44875b); }
.tg-2 { background: linear-gradient(140deg, #44875b, #7a9a44); }
.tg-3 { background: linear-gradient(140deg, #b8781a, #d09a34); }
.tg-4 { background: linear-gradient(140deg, #a5613a, #bd7a4c); }
.tg-5 { background: linear-gradient(140deg, #6b6459, #8b8478); }
.tile .tt { font-weight: 700; font-size: calc(14.5px * var(--scale)); line-height: 1.25; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tile .td { font-size: calc(12.5px * var(--scale)); color: var(--ink-mut); line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* ---------- list rows ---------- */
.listrow {
  width: 100%; text-align: left;
  display: flex; align-items: center; gap: 12px;
  min-height: 58px; padding: 11px 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  margin-bottom: 8px;
}
.listrow .lr-ic { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; flex: 0 0 auto; color: #fff; }
.listrow .lr-b { flex: 1; min-width: 0; }
.listrow .lr-t { font-weight: 650; font-size: calc(14.5px * var(--scale)); line-height: 1.3; }
.listrow .lr-s { font-size: calc(12.5px * var(--scale)); color: var(--ink-mut); line-height: 1.35; margin-top: 1px; }
.listrow .lr-v { font-size: calc(13.5px * var(--scale)); color: var(--ink-mut); flex: 0 0 auto; }
.listrow .lr-x { color: var(--ink-dim); flex: 0 0 auto; }

/* group of rows that reads as one card */
.group { border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; background: var(--surface); box-shadow: var(--shadow), inset 0 1px 0 var(--edge-hi); margin-bottom: 14px; }
.group .listrow { border: 0; border-radius: 0; margin: 0; box-shadow: none; background: none; }
.group .listrow + .listrow { position: relative; }
.group .listrow + .listrow::before { content: ''; position: absolute; left: 58px; right: 0; top: 0; height: 1px; background: var(--line); }
.group .listrow:not(:has(.lr-ic)) + .listrow:not(:has(.lr-ic))::before { left: 14px; }

/* ---------- today ---------- */
.greet { font-size: calc(15px * var(--scale)); color: var(--ink-mut); }
.today-card {
  background: var(--grad); color: var(--on-brand);
  border-radius: var(--r-xl); padding: 20px; margin-bottom: 16px;
  box-shadow: var(--shadow-lift);
  border: 0;
}
.today-card .tc-k { font-size: calc(11.5px * var(--scale)); font-weight: 750; letter-spacing: .08em; text-transform: uppercase; opacity: .8; }
.today-card .tc-t { font-size: calc(20px * var(--scale)); font-weight: 800; letter-spacing: -.02em; margin: 6px 0 6px; line-height: 1.2; }
.today-card .tc-d { font-size: calc(14.5px * var(--scale)); opacity: .93; line-height: 1.5; }
.today-card .btn { margin-top: 14px; background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.3); color: #fff; backdrop-filter: blur(6px); }
.today-card.calm { background: var(--surface); color: var(--ink); border: 1px solid var(--line); box-shadow: var(--shadow), inset 0 1px 0 var(--edge-hi); }
.today-card.calm .tc-k { color: var(--moss-lift); opacity: 1; }
.today-card.calm .tc-d { color: var(--ink-mut); }

/* ---------- grow card ---------- */
.g-card { display: block; width: 100%; text-align: left; }
.g-head { display: flex; align-items: center; gap: 11px; margin-bottom: 12px; }
.g-mono { width: 42px; height: 42px; border-radius: 13px; display: grid; place-items: center; color: #fff; font-weight: 800; font-size: calc(15px * var(--scale)); letter-spacing: -.02em; flex: 0 0 auto; }
.g-n { flex: 1; min-width: 0; }
.g-nm { font-weight: 700; font-size: calc(16px * var(--scale)); line-height: 1.25; }
.g-sp { font-size: calc(12.5px * var(--scale)); color: var(--ink-mut); }
.g-day { font-size: calc(12.5px * var(--scale)); color: var(--ink-mut); font-weight: 650; flex: 0 0 auto; }

.g-rail { display: flex; gap: 4px; margin-bottom: 9px; }
.g-rail i { flex: 1; height: 5px; border-radius: 3px; background: var(--bg-2); }
.g-rail i.on { background: var(--grad); }
.g-stage { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.g-stage b { font-size: calc(14px * var(--scale)); }
.g-next { font-size: calc(13.5px * var(--scale)); color: var(--ink-mut); line-height: 1.5; }

/* ---------- stats ---------- */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 9px; margin-bottom: 14px; }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 12px 13px; }
.stat-v { font-size: calc(21px * var(--scale)); font-weight: 800; letter-spacing: -.025em; line-height: 1.1; }
.stat-k { font-size: calc(11.5px * var(--scale)); color: var(--ink-mut); margin-top: 3px; }

/* yield bars */
/* stretch, NOT flex-end. With flex-end each column is content-sized, so
   .yb-track has no height and the bars' percentage heights resolve against
   zero, which renders every flush as the same flat line. */
.ybars { display: flex; align-items: stretch; gap: 7px; height: 150px; padding: 18px 0 0; }
.yb { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.yb-track { flex: 1; width: 100%; display: flex; align-items: flex-end; }
.yb-bar { width: 100%; border-radius: 7px 7px 3px 3px; background: var(--grad); min-height: 6px; position: relative; }
.yb-bar span { position: absolute; top: -19px; left: 0; right: 0; text-align: center; font-size: calc(11px * var(--scale)); font-weight: 700; color: var(--ink-mut); font-variant-numeric: tabular-nums; }
.yb-l { font-size: calc(10.5px * var(--scale)); color: var(--ink-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }

/* ---------- journal ---------- */
.j-entry { display: flex; gap: 12px; padding: 12px 0; }
.j-rail { width: 26px; flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; }
.j-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--moss-lift); margin-top: 5px; box-shadow: 0 0 0 3px color-mix(in srgb, var(--moss) 16%, transparent); }
.j-line { flex: 1; width: 2px; background: var(--line); margin-top: 5px; border-radius: 2px; }
.j-b { flex: 1; min-width: 0; padding-bottom: 4px; }
.j-when { font-size: calc(11.5px * var(--scale)); color: var(--ink-dim); font-weight: 650; }
.j-txt { font-size: calc(14px * var(--scale)); line-height: 1.5; margin-top: 2px; white-space: pre-wrap; word-break: break-word; }

/* ---------- calculators ---------- */
.calc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); gap: 10px; margin-bottom: 14px; }
.calc-out {
  margin-top: 14px; padding: 14px; border-radius: var(--r);
  background: color-mix(in srgb, var(--moss) 9%, var(--surface-2));
  border: 1px solid color-mix(in srgb, var(--moss) 22%, transparent);
}
.calc-out.is-err { background: color-mix(in srgb, var(--danger) 9%, var(--surface-2)); border-color: color-mix(in srgb, var(--danger) 28%, transparent); }
.co-plain { font-size: calc(14px * var(--scale)); line-height: 1.55; margin-bottom: 10px; }
.calc-out.is-err .co-plain { margin-bottom: 0; }
.co-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 7px 0; font-size: calc(14px * var(--scale)); }
.co-row + .co-row { border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }
.co-row span { color: var(--ink-mut); }
.co-row b { font-size: calc(15.5px * var(--scale)); }

/* ---------- reference content ---------- */
.doc { font-size: calc(15px * var(--scale)); line-height: 1.62; }
.doc h3 { font-size: calc(17px * var(--scale)); margin: 20px 0 8px; letter-spacing: -.02em; }
.doc h3:first-child { margin-top: 0; }
.doc p { margin-bottom: 12px; color: var(--ink); }
.doc .lead { color: var(--ink-mut); }
.steps { counter-reset: s; list-style: none; padding: 0; margin: 0 0 14px; }
.steps li { counter-increment: s; position: relative; padding: 0 0 14px 40px; font-size: calc(14.5px * var(--scale)); line-height: 1.55; }
.steps li::before {
  content: counter(s); position: absolute; left: 0; top: 0;
  width: 26px; height: 26px; border-radius: 50%;
  background: color-mix(in srgb, var(--moss) 14%, transparent); color: var(--moss-lift);
  display: grid; place-items: center; font-size: calc(12.5px * var(--scale)); font-weight: 750;
  font-variant-numeric: tabular-nums;
}
.steps li:not(:last-child)::after { content: ''; position: absolute; left: 13px; top: 30px; bottom: 6px; width: 1px; background: var(--line); }
/* A button inside a paragraph of prose must sit on its own line. Inline-flex
   makes it flow mid-sentence, which is where "anything in a jar. [Open]" came from. */
.steps li .btn { display: flex; width: fit-content; margin-top: 9px; }
.bullets { list-style: none; padding: 0; margin: 0 0 14px; }
.bullets li { position: relative; padding: 0 0 8px 20px; font-size: calc(14.5px * var(--scale)); line-height: 1.5; }
.bullets li::before { content: ''; position: absolute; left: 4px; top: 9px; width: 6px; height: 6px; border-radius: 50%; background: var(--moss-lift); }

.kv { display: flex; justify-content: space-between; gap: 14px; padding: 9px 0; font-size: calc(14px * var(--scale)); }
.kv + .kv { border-top: 1px solid var(--line); }
.kv span { color: var(--ink-mut); min-width: 0; }
/* A value must never break mid-quantity. "500" on one line and "g" on the next
   is how a recipe starts looking like a bug. */
.kv b { text-align: right; white-space: nowrap; flex: 0 0 auto; }
.kv b.wrapv { white-space: normal; }

.swatches { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; margin-bottom: 14px; }
.sw { border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; background: var(--surface); }
.sw-c { height: 52px; }
.sw-b { padding: 9px 11px; }
.sw-t { font-weight: 700; font-size: calc(13.5px * var(--scale)); }
.sw-d { font-size: calc(12px * var(--scale)); color: var(--ink-mut); line-height: 1.4; margin-top: 2px; }

/* search results */
.sr-type { font-size: calc(10.5px * var(--scale)); font-weight: 750; letter-spacing: .07em; text-transform: uppercase; color: var(--moss-lift); }

/* ---------- sheet ---------- */
#sheet-layer { position: fixed; inset: 0; z-index: 100; display: flex; align-items: flex-end; justify-content: center; }
#sheet-scrim { position: absolute; inset: 0; background: rgba(20,17,12,.5); backdrop-filter: blur(3px); animation: fade .2s var(--ease); }
#sheet {
  position: relative; width: 100%; max-width: 560px;
  max-height: 92dvh; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); border-bottom: 0;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  box-shadow: 0 -8px 50px -12px rgba(0,0,0,.4);
  animation: up .26s var(--ease);
}
@keyframes fade { from { opacity: 0; } }
@keyframes up { from { transform: translateY(18px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { #sheet, #sheet-scrim { animation: none; } }
@media (min-width: 620px) {
  #sheet-layer { align-items: center; }
  #sheet { border-radius: var(--r-xl); border-bottom: 1px solid var(--line); }
}
.sheet-h { padding: 18px 18px 12px; border-bottom: 1px solid var(--line); position: relative; flex: 0 0 auto; }
.sheet-h h3 { font-size: calc(19px * var(--scale)); padding-right: 44px; }
.sheet-h p { font-size: calc(13.5px * var(--scale)); color: var(--ink-mut); margin-top: 3px; padding-right: 44px; }
.sheet-x { position: absolute; right: 12px; top: 13px; width: var(--hit); height: var(--hit); border-radius: 50%; border: 0; background: var(--bg-2); display: grid; place-items: center; color: var(--ink-mut); }
.sheet-b { padding: 16px 18px calc(18px + env(safe-area-inset-bottom)); overflow-y: auto; flex: 1; }
.sheet-b > .btn-block { margin-top: 8px; }

/* ---------- toast ---------- */
#toast {
  position: fixed; left: 50%; bottom: calc(84px + env(safe-area-inset-bottom)); transform: translateX(-50%);
  z-index: 150; max-width: min(440px, calc(100vw - 32px));
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-radius: 999px;
  background: var(--ink); color: var(--bg);
  font-size: calc(14px * var(--scale)); font-weight: 600;
  box-shadow: 0 10px 34px -8px rgba(0,0,0,.5);
  animation: up .22s var(--ease);
}
#toast .t-ok { color: #7fd6a0; }
#toast .t-warn { color: #ffc86b; }
#toast .t-err { color: #ff9c8c; }
#toast button { background: none; border: 0; color: var(--bg); font-weight: 750; text-decoration: underline; padding: 0 0 0 4px; }
@media (min-width: 860px) { #toast { bottom: 24px; } }

/* ---------- misc ---------- */
.row { display: flex; gap: 10px; }
.row > * { flex: 1; }
.mt { margin-top: 14px; }
.mb0 { margin-bottom: 0; }
.center { text-align: center; }
.muted { color: var(--ink-mut); }
.sm { font-size: calc(13px * var(--scale)); }
.brandmark { display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: 9px; background: var(--grad); color: #fff; flex: 0 0 auto; }
