 .risk-card{border-left:4px solid var(--green)}.risk-card.medium{border-left-color:#d3a928;background:#fff9df}.risk-card.high{border-left-color:#d45b4d;background:#fff0ec}.risk-card.low{border-left-color:#4caa72;background:#f0fbf3}.dot-plot{display:grid;gap:10px;padding:12px 4px}.dot-point{position:relative;height:28px;border-bottom:1px solid var(--line)}.dot-point::before{content:'';position:absolute;left:0;right:0;top:13px;border-top:1px dashed var(--line)}.dot-marker{position:absolute;left:var(--risk);top:7px;width:13px;height:13px;border-radius:50%;transform:translateX(-50%);border:3px solid var(--white);box-shadow:0 0 0 1px currentColor}.dot-marker.low{color:#4caa72;background:#4caa72}.dot-marker.medium{color:#d3a928;background:#d3a928}.dot-marker.high{color:#d45b4d;background:#d45b4d}.dot-label{display:block;padding-top:18px;color:var(--muted);font:10px 'DM Mono',monospace}
.trend-panel canvas{height:240px!important;max-height:240px}
 .pagination{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px;color:var(--muted);font:500 10px 'DM Mono',monospace}.pagination button{border:1px solid var(--line);background:var(--white);color:var(--ink);padding:7px 10px;font:inherit;cursor:pointer}.pagination button:disabled{opacity:.4;cursor:default}
@import url('https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Manrope:wght@400;500;600;700;800&display=swap');
:root{--ink:#172b29;--muted:#72817c;--line:#dbe5df;--paper:#f5f6f1;--white:#fff;--mint:#d9f1e0;--green:#176b52;--lime:#b9eb72;--coral:#e87857;--shadow:0 14px 40px rgba(33,62,52,.08);font-family:Manrope, sans-serif;color:var(--ink);background:var(--paper)}*{box-sizing:border-box}body{margin:0;min-width:320px}.topbar{height:70px;padding:0 5vw;display:flex;align-items:center;justify-content:space-between;background:var(--white);border-bottom:1px solid var(--line)}.brand{display:flex;align-items:center;gap:12px;font-size:15px;font-weight:800;letter-spacing:-.02em}.brand-mark{display:grid;place-items:center;width:29px;height:29px;background:var(--ink);color:var(--lime);border-radius:50%;font:500 10px 'DM Mono',monospace}.topbar-status{font-size:11px;color:var(--muted);letter-spacing:.03em}.status-dot,.rail-dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:#6dbf7a;margin-right:7px}.divider{height:13px;border-left:1px solid var(--line);margin:0 12px}.shell{max-width:1600px;margin:auto;padding:0 5vw}.hero{min-height:245px;display:flex;justify-content:space-between;align-items:end;padding:48px 0 42px}.eyebrow{margin:0 0 12px;color:var(--green);font:500 10px 'DM Mono',monospace;letter-spacing:.12em}.hero h1{margin:0;font-size:clamp(38px,5vw,72px);line-height:.99;letter-spacing:-.07em}.hero h1 em{font-family:Georgia,serif;font-weight:400;color:var(--coral);letter-spacing:-.06em}.hero-copy{max-width:400px;margin:21px 0 0;color:var(--muted);font-size:14px;line-height:1.7}.hero-note{display:flex;gap:14px;align-items:start;padding-bottom:6px;color:var(--muted);font-size:12px;line-height:1.55}.note-number{font:500 11px 'DM Mono',monospace;color:var(--coral)}.workspace{display:grid;grid-template-columns:230px 1fr;gap:24px;padding-bottom:48px}.recipe-rail{min-height:620px;border-right:1px solid var(--line);padding:24px 24px 24px 0}.rail-heading{display:flex;align-items:center;justify-content:space-between;color:var(--muted);font:500 10px 'DM Mono',monospace;letter-spacing:.1em}.icon-button{border:0;background:var(--ink);color:var(--lime);height:28px;width:28px;border-radius:50%;font-size:21px;line-height:1;cursor:pointer}.recipe-list{margin-top:28px}.recipe-item{display:flex;align-items:center;gap:10px;width:100%;padding:12px 0;border:0;border-bottom:1px solid #e6ece7;background:none;text-align:left;color:var(--muted);cursor:pointer}.recipe-item.active{color:var(--ink);font-weight:700}.recipe-index{font:500 10px 'DM Mono',monospace;color:var(--coral)}.rail-foot{position:sticky;top:20px;margin-top:70px;color:var(--green);font-size:11px;line-height:1.7}.rail-foot small{color:var(--muted)}.dashboard{min-width:0}.empty-dashboard{min-height:620px;display:grid;place-content:center;text-align:center;max-width:490px;margin:auto}.empty-symbol{margin:0 auto 24px;display:grid;place-items:center;width:58px;height:58px;border:1px solid var(--green);border-radius:50%;color:var(--green);font-size:30px;font-weight:300}.empty-dashboard h2{margin:0;font-size:27px;letter-spacing:-.05em}.empty-dashboard p{color:var(--muted);font-size:13px;line-height:1.7}.primary-button{border:0;background:var(--ink);color:white;padding:13px 17px;font:600 12px Manrope,sans-serif;cursor:pointer}.primary-button span{color:var(--lime);font-size:16px;margin-left:16px}.dashboard-head{display:flex;justify-content:space-between;align-items:start;padding:26px 0 26px;border-bottom:1px solid var(--line)}.dashboard-head h2{font-size:30px;letter-spacing:-.06em;margin:0}.dashboard-head p{color:var(--muted);font-size:12px;margin:8px 0 0}.head-actions{display:flex;gap:8px}.ghost-button{border:1px solid var(--line);background:var(--white);padding:10px 12px;color:var(--ink);font:600 11px Manrope;cursor:pointer}.metric-row{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;margin:28px 0;background:var(--line);border:1px solid var(--line)}.metric{padding:18px;background:var(--white)}.metric-label{color:var(--muted);font:500 10px 'DM Mono',monospace;text-transform:uppercase}.metric-value{font-size:27px;font-weight:700;letter-spacing:-.05em;margin-top:10px}.metric-value.accent{color:var(--coral)}.metric-sub{font-size:10px;color:var(--muted);margin-top:5px}.viz-grid{display:grid;grid-template-columns:1.45fr 1fr;gap:18px}.panel{background:var(--white);border:1px solid var(--line);padding:21px;min-width:0}.panel-title{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.panel-title h3{font-size:14px;margin:0}.panel-title span{color:var(--muted);font:10px 'DM Mono',monospace}.chart{height:220px;display:flex;align-items:end;gap:7px;border-bottom:1px solid var(--line);padding:0 4px}.bar-wrap{height:100%;flex:1;display:flex;flex-direction:column;justify-content:end;align-items:center;gap:7px;cursor:pointer}.bar{width:min(30px,70%);background:var(--mint);border-top:3px solid var(--green);min-height:4px;transition:background .2s}.bar-wrap:hover .bar{background:var(--lime)}.bar-label{font:9px 'DM Mono',monospace;color:var(--muted);white-space:nowrap}.table-list{display:grid;gap:2px}.table-row{display:grid;grid-template-columns:1fr 65px 55px;gap:8px;align-items:center;padding:10px 0;border-bottom:1px solid #edf1ed;font-size:11px;cursor:pointer}.table-row:hover{background:#f7faf5}.table-row strong{font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.table-row span{color:var(--muted);text-align:right}.risk-pill{color:var(--coral)!important;font:500 10px 'DM Mono',monospace}.ingredient-strip{margin-top:18px}.ingredient-list{display:flex;gap:8px;flex-wrap:wrap}.ingredient-chip{padding:9px 11px;background:var(--mint);font-size:11px;color:var(--green)}.preview-banner{margin-top:18px;padding:11px 14px;background:#fff8e9;color:#836632;font-size:11px}.modal{position:fixed;inset:0;background:rgba(17,40,34,.42);display:grid;place-items:center;padding:20px;z-index:3}.modal.hidden{display:none}.modal-card{background:var(--paper);width:min(800px,100%);max-height:90vh;overflow:auto;padding:28px;box-shadow:var(--shadow)}.modal-head{display:flex;justify-content:space-between}.modal-head h2{margin:0;font-size:28px;letter-spacing:-.06em}.close-button{border:0;background:none;font-size:28px;color:var(--muted);cursor:pointer}.field-label{display:block;margin-top:25px;color:var(--muted);font:10px 'DM Mono',monospace;text-transform:uppercase}.text-input{display:block;width:100%;margin-top:8px;padding:12px 13px;border:1px solid var(--line);background:var(--white);color:var(--ink);font:13px Manrope;outline-color:var(--green)}.taxonomy-head{display:flex;justify-content:space-between;gap:20px;align-items:end;margin-top:28px}.taxonomy-head p:last-child{font-size:11px;color:var(--muted);margin:0;max-width:400px}.search-input{max-width:220px;margin:0}.taxonomy-tree{margin-top:14px;background:var(--white);border:1px solid var(--line);padding:12px;max-height:330px;overflow:auto}.tree-node{border-bottom:1px solid #f0f3ef;padding:5px 0}.tree-node label{display:flex;gap:9px;align-items:center;padding:5px;cursor:pointer;font-size:12px}.tree-node label:hover{background:var(--mint)}.tree-node input{accent-color:var(--green)}.tree-node small{margin-left:auto;color:#9aa8a1;font:9px 'DM Mono',monospace}.tree-children{margin-left:20px}.selection-footer{display:flex;justify-content:space-between;align-items:center;margin-top:18px;font-size:11px;color:var(--muted)}@media(max-width:850px){.topbar{padding:0 20px}.topbar-status{display:none}.shell{padding:0 20px}.hero{display:block;padding:42px 0 35px}.hero-note{margin-top:25px}.workspace{grid-template-columns:1fr;gap:0}.recipe-rail{min-height:0;border-right:0;border-bottom:1px solid var(--line);padding:0 0 18px}.rail-foot{display:none}.recipe-list{display:flex;gap:10px;margin-top:14px;overflow:auto}.recipe-item{min-width:150px;border:1px solid var(--line);padding:11px}.metric-row{grid-template-columns:repeat(3,1fr)}.viz-grid{grid-template-columns:1fr}.dashboard-head{display:block}.head-actions{margin-top:18px}.taxonomy-head{display:block}.search-input{max-width:none;margin-top:12px}}
.filter-group{margin-top:22px}.filter-group-head{display:flex;justify-content:space-between;align-items:center;color:var(--muted);font:10px 'DM Mono',monospace;text-transform:uppercase}.select-all{display:flex;align-items:center;gap:6px;text-transform:none;font:600 11px Manrope;color:var(--ink);cursor:pointer}.select-all input{accent-color:var(--green)}.check-list{margin-top:8px;background:var(--white);border:1px solid var(--line);padding:6px 4px;max-height:160px;overflow:auto}.check-row{display:flex;align-items:center;gap:9px;padding:6px 8px;cursor:pointer;font-size:12px}.check-row:hover{background:var(--mint)}.check-row input{accent-color:var(--green)}.active-filters{display:flex;flex-wrap:wrap;gap:8px;padding:14px 0 0}.filter-chip{display:inline-flex;align-items:center;gap:7px;padding:7px 6px 7px 11px;background:var(--mint);color:var(--green);font-size:11px}.filter-chip button{border:0;background:none;color:var(--green);font-size:14px;line-height:1;cursor:pointer;padding:0 2px}.ingredient-strip summary{cursor:pointer;list-style:none}.ingredient-strip summary::-webkit-details-marker{display:none}.ingredient-strip summary::after{content:'▾';margin-left:8px;color:var(--muted)}.ingredient-strip[open] summary::after{content:'▴'}

/* --- Authentication --- */
.current-user { font-weight: 600; }
.logout-button { padding: .25rem .75rem; font-size: .8rem; }
.topbar-right { display: flex; align-items: center; gap: 18px; }
.topbar-account { display: flex; align-items: center; gap: 10px; font-size: 12px; }
.topbar-account .ghost-button.active { background: var(--ink); border-color: var(--ink); color: var(--white); }
@media (max-width: 850px) { .topbar-right { gap: 0; } }
.auth-body { min-height: 100vh; }
.auth-shell { display: grid; grid-template-columns: 1.1fr .9fr; gap: 4rem; align-items: center; max-width: 1100px; margin: 0 auto; padding: 4rem 2rem; }
.auth-intro h1 { font-size: clamp(2.2rem, 4vw, 3.4rem); line-height: 1.05; margin: .5rem 0 1rem; }
.auth-card { background: #fff; border: 1px solid #e4e4df; border-radius: 18px; padding: 2rem; box-shadow: 0 18px 40px rgba(23, 107, 82, .08); }
.auth-tabs { display: flex; gap: .5rem; margin-bottom: 1.5rem; }
.auth-tab { flex: 1; padding: .6rem 1rem; border: 1px solid #e4e4df; border-radius: 999px; background: transparent; cursor: pointer; font: inherit; }
.auth-tab.active { background: #176b52; border-color: #176b52; color: #fff; }
.auth-form { display: flex; flex-direction: column; gap: 1rem; }
.auth-form .primary-button { margin-top: .5rem; justify-content: center; }
.field-hint { display: block; margin-top: .3rem; color: #76766f; font-size: .78rem; }
.auth-error { margin-top: 1rem; min-height: 1.2rem; color: #b23b2c; font-size: .88rem; }
@media (max-width: 860px) { .auth-shell { grid-template-columns: 1fr; gap: 2rem; padding: 2rem 1.25rem; } }

/* Collapsible taxonomy */
.tree-row { display: flex; gap: 8px; align-items: center; padding: 5px; font-size: 12px; cursor: pointer; user-select: none; }
.tree-row:hover { background: var(--mint); }
.tree-row input { accent-color: var(--green); cursor: pointer; }
.tree-row small { margin-left: auto; color: #9aa8a1; font: 9px 'DM Mono', monospace; white-space: nowrap; }
.tree-row small b { color: var(--green); font-weight: 600; }
.tree-caret { width: 12px; flex: none; color: var(--muted); font-size: 10px; text-align: center; }
.tree-row.branch .tree-name { font-weight: 600; }

/* Blocking overlay while a request is in flight */
.busy-overlay { position: fixed; inset: 0; z-index: 10; display: grid; place-items: center; background: rgba(245, 246, 241, .72); cursor: progress; }
.busy-overlay.hidden { display: none; }
/* Blocks clicks at once, but only becomes visible if the wait is noticeable. */
.busy-overlay > .busy-card, .busy-overlay { animation: busy-fade .2s .25s both; }
@keyframes busy-fade { from { opacity: 0; } to { opacity: 1; } }
.busy-card { background: var(--white); box-shadow: var(--shadow); border: 1px solid var(--line); padding: 24px 30px; text-align: center; min-width: 260px; }
.busy-card p { margin: 14px 0 4px; font-size: 13px; }
.busy-card small { color: var(--muted); font: 10px 'DM Mono', monospace; }
.busy-spinner { width: 28px; height: 28px; margin: 0 auto; border: 3px solid var(--mint); border-top-color: var(--green); border-radius: 50%; animation: busy-spin .8s linear infinite; }
@keyframes busy-spin { to { transform: rotate(360deg); } }

/* Share / paste */
.rail-actions { display: flex; gap: 8px; align-items: center; }
.rail-link { border: 1px solid var(--line); background: var(--white); color: var(--ink); font: 600 10px Manrope, sans-serif; padding: 6px 9px; cursor: pointer; letter-spacing: 0; }
.rail-link:hover { background: var(--mint); }
.share-card { width: min(560px, 100%); }
.share-help { color: var(--muted); font-size: 13px; line-height: 1.6; }
.share-code { font: 15px 'DM Mono', monospace; letter-spacing: .04em; }
.share-status { min-height: 1.2em; font-size: 12px; color: var(--green); }
.share-status.error { color: #b23b2c; }

/* Login: one form at a time. There was no generic .hidden rule, so the
   "hidden" register form was always on screen next to the sign-in form. */
.hidden { display: none !important; }
.auth-title { margin: 0 0 1.25rem; font-size: 1.6rem; letter-spacing: -.04em; }
.auth-switch { margin: .25rem 0 0; font-size: .85rem; color: #76766f; text-align: center; }
.link-button { border: 0; background: none; padding: 0; color: #176b52; font: inherit; font-weight: 600; text-decoration: underline; cursor: pointer; }

/* Windowed lists (see mountVirtualList in app.js): fixed-height rows inside a
   scrollable box; only the rows in view exist in the DOM. */
.vlist { position: relative; overflow-y: auto; overscroll-behavior: contain; }
.vlist-sizer { position: relative; width: 100%; }
.vlist-rows { position: absolute; top: 0; left: 0; right: 0; will-change: transform; }
.panel-list { height: calc(7 * 44px); }
.panel-list .table-row { box-sizing: border-box; height: 44px; padding: 0 10px; gap: 14px; grid-template-columns: minmax(0, 1fr) auto auto; border-bottom: 1px solid #edf1ed; }
.panel-list .table-row span { white-space: nowrap; }
.ingredient-list { height: calc(8 * 34px); margin-top: 4px; border-top: 1px solid var(--line); }
.ingredient-row { box-sizing: border-box; height: 34px; padding: 0 10px; display: flex; align-items: center; font-size: 12px; color: var(--green); border-bottom: 1px solid #edf1ed; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.check-list.vlist { height: calc(6 * 34px); max-height: none; padding: 0; }
.check-list .check-row { box-sizing: border-box; height: 34px; padding: 0 8px; overflow: hidden; }
.check-row span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filter-chip em { font-style: normal; opacity: .7; }
.filter-note { margin: 18px 0 0; color: var(--muted); font-size: 11px; line-height: 1.6; }

/* Recipe list: each row is the recipe button plus a small remove button. */
.recipe-row { display: flex; align-items: center; border-bottom: 1px solid #e6ece7; }
.recipe-row .recipe-item { flex: 1; min-width: 0; border-bottom: 0; }
.delete-recipe { border: 0; background: none; color: var(--muted); font-size: 18px; line-height: 1; padding: 4px 6px; cursor: pointer; }
.delete-recipe:hover { color: #b23b2c; }

/* Three metric cards: stack them once three across no longer fits the figures. */
@media (max-width: 760px) { .metric-row { grid-template-columns: 1fr; } }

/* Narrow screens: the action buttons wrap and the recipe rail may shrink (its list scrolls sideways). */
.head-actions { flex-wrap: wrap; }
.recipe-rail { min-width: 0; }

/* Editor lists and dashboard loading/error states */
.list-note { margin: 0; padding: 14px 12px; color: var(--muted); font-size: 12px; }
.check-row.unavailable { color: var(--muted); background: #fbf4e6; }
.check-row.unavailable span { font-style: italic; }
.check-row em { margin-left: auto; padding-left: 10px; font-style: normal; font-size: 10px; color: #836632; white-space: nowrap; }
.filter-status { min-height: 1.4em; margin: 14px 0 0; }
.filter-status.error { color: #b23b2c; }
.metrics-state { min-height: 280px; display: grid; place-content: center; justify-items: center; gap: 10px; text-align: center; color: var(--muted); font-size: 13px; padding: 30px 0; }
.metrics-state p { margin: 14px 0 0; color: var(--ink); max-width: 420px; line-height: 1.6; }
.metrics-state small { font: 10px 'DM Mono', monospace; min-height: 1.2em; }
.table-row:focus-visible, .check-row:focus-within, .ghost-button:focus-visible, .primary-button:focus-visible { outline: 2px solid var(--green); outline-offset: -2px; }
