/* Botanical Box — professional instrument. No external assets.
   ====================================================================
   DESIGN SYSTEM: adopted verbatim from the Bountiful Herbs web app
   (the reference web app/base.css), fetched 2026-08-09. Its own
   art-direction note reads:

       "Botanical Apothecary -> dark, rich, warm. Dark green-black
        backgrounds, warm gold/amber accent, sage green secondary.
        Cormorant Garamond (display) + DM Sans (body) -- elegant herbal
        apothecary meets clinical."

   Adopted rather than approximated, deliberately. the clinician's brief is
   that the box should look like the web app; sharing the actual tokens
   is the only way the two stay the same product as either changes. The
   box's own semantic names (--accent, --panel, --traditional ...) are
   kept and MAPPED onto the web app's tokens, so the 400 lines below
   needed no edits and the safety surfaces keep their meanings.

   DARK IS PRIMARY, light is the alternate — same as the web app
   (`color-scheme: dark light`, meta-theme-color #0e1714).

   FONTS: the web app loads Cormorant Garamond and DM Sans from Google.
   THE BOX IS OFFLINE AND MUST NOT. Both are SIL Open Font Licence, so
   the woff2 files should ship in server/static/fonts/ and be declared
   with @font-face here. Until they do, the stacks below fall back to
   system faces of the same character. TODO before ship.
   ==================================================================== */
:root {
  color-scheme: dark light;

  /* ---- the web app's tokens, verbatim ---- */
  --color-bg:             #080d08;
  --color-surface:        #0f160f;
  --color-surface-2:      #151e15;
  --color-surface-3:      #1a251a;
  --color-surface-offset: #1e2a1e;
  --color-divider:        #2d3a2d;
  --color-border:         #3a4d3a;
  --color-text:           #ede8d8;
  --color-text-muted:     #9caf88;
  --color-text-faint:     #5e7a52;
  --color-text-inverse:   #080d08;
  --color-primary:        #c8a45e;   /* warm gold */
  --color-primary-hover:  #d4b36e;
  --color-primary-highlight: rgba(200, 164, 94, .12);
  --color-secondary:      #6b8f71;   /* sage */
  --color-secondary-highlight: rgba(107, 143, 113, .12);
  --color-warning:        #d4944a;   /* amber */
  --color-warning-highlight: rgba(212, 148, 74, .12);
  --color-error:          #d4644a;   /* terracotta */
  --color-error-highlight: rgba(212, 100, 74, .12);
  --color-success:        #7ab648;
  --shadow-glow:          0 0 20px rgba(200, 164, 94, .15);

  /* ---- the box's semantic names, mapped onto them ---- */
  --bg: var(--color-bg);
  --panel: var(--color-surface);
  --field: var(--color-surface-2);        /* inputs, selects */
  --ink: var(--color-text);
  --muted: var(--color-text-muted);
  --line: var(--color-border);
  --accent: var(--color-primary);
  --accent-soft: var(--color-primary-highlight);
  --on-accent: var(--color-text-inverse); /* text ON a gold fill */
  --chip-bg: var(--color-surface-2);
  --chip-line: var(--color-border);
  /* Provenance keeps its meanings: settled / modified / novel. */
  --traditional: var(--color-secondary);
  --adapted: var(--color-warning);
  --composed: var(--color-error);
  --tierb: var(--color-error);
  --serif: "Cormorant Garamond", Garamond, Georgia, "Iowan Old Style", serif;
  --sans: "DM Sans", -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
}

/* LIGHT MODE — the web app's alternate, same token names. */
:root[data-theme="light"] {
  --color-bg:             #f4f1e8;
  --color-surface:        #fbf9f2;
  --color-surface-2:      #ffffff;
  --color-surface-3:      #f8f5ec;
  --color-surface-offset: #ebe7db;
  --color-divider:        #d0cab9;
  --color-border:         #c2bba8;
  --color-text:           #1a2016;
  --color-text-muted:     #4a5e42;
  --color-text-faint:     #8a9a80;
  --color-text-inverse:   #f4f1e8;
  --color-primary:        #8a6d2a;
  --color-primary-hover:  #725a20;
  --color-primary-highlight: rgba(138, 109, 42, .1);
  --color-secondary:      #4a7050;
  --color-secondary-highlight: rgba(74, 112, 80, .1);
  --color-warning:        #b87a30;
  --color-warning-highlight: rgba(184, 122, 48, .1);
  --color-error:          #b84830;
  --color-error-highlight: rgba(184, 72, 48, .1);
  --color-success:        #4a8828;
  --shadow-glow:          0 0 20px rgba(138, 109, 42, .1);
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  font: 15px/1.5 var(--sans);
  color: var(--ink);
  background: var(--bg);
  display: flex; flex-direction: column;
}

header {
  display: flex; align-items: center; gap: 1.5rem;
  padding: .6rem 1.2rem;
  background: var(--panel);
  border-bottom: 2px solid var(--accent);
}
.brand { display: flex; align-items: center; gap: .6rem; }
.brand .mark { color: var(--accent); display: flex; flex: none; }
.brand .mark svg { width: 1.75rem; height: 1.75rem; display: block; }
/* The web app draws this leaf as a faint watermark behind empty cards, so
   its path elements carry opacity .3/.2 inline. As a logo it has to
   actually read. Override here rather than editing the path data, which is
   the identity and must stay byte-identical to the reference web app. */
.leaf-body { opacity: .9; }
.leaf-vein { opacity: .55; }
.brand .name {
  font-family: var(--serif); letter-spacing: .18em; font-weight: 700;
  line-height: 1.05; display: flex; flex-direction: column; gap: .16rem;
}
.brand .name-2 {
  font-family: var(--sans); font-weight: 500; font-size: .58rem;
  letter-spacing: .3em; color: var(--accent); text-transform: uppercase;
}
.brand .sub { color: var(--muted); font-size: .78rem; align-self: center; }
nav#tabs { display: flex; gap: .25rem; margin-left: auto; }
nav#tabs button {
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  padding: .35rem 1.1rem; cursor: pointer; font: inherit;
  text-transform: uppercase; font-size: .78rem; letter-spacing: .12em;
}
nav#tabs button.active { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.status { font-size: .75rem; color: var(--muted); max-width: 28rem; text-align: right; }
/* A degraded box must never read like a healthy one — in the header or
   anywhere else. Same rule that keeps a WARN from being styled like a PASS. */
.status.degraded { color: var(--warn-ink); font-weight: 500; }

/* WORKSPACE = records (main) + Herbert (#herbert-dock). Direction is set
   per mode below: row on consult/browse, column on formulate. */
#workspace { flex: 1; display: flex; min-height: 0; overflow: hidden; }
main { flex: 1; overflow: hidden; display: flex; min-width: 0; min-height: 0; }
.mode { display: none; flex: 1; min-height: 0; min-width: 0; }
.mode.active { display: flex; }
footer {
  padding: .4rem 1.2rem; font-size: .72rem; color: var(--muted);
  border-top: 1px solid var(--line); background: var(--panel);
}

/* ---------- HERBERT — the persistent dock ----------
   One component, three shapes. The shape is chosen by body[data-mode],
   which app.js sets in setMode(); body[data-dock] handles collapse. There
   is deliberately no separate "consult pane" any more — Consult IS Herbert
   at full width, which is why #consult no longer exists in the markup. */

#herbert-dock {
  display: flex; flex-direction: column;
  min-height: 0; min-width: 0;
  background: var(--panel);
}
#dock-head {
  display: flex; align-items: center; gap: .55rem;
  padding: .45rem .8rem;
  border-bottom: 1px solid var(--line);
  background: var(--field);
}
/* Herbert's portrait. Rendered a little larger than the old leaf glyph so the
   character actually reads, and rounded so the artwork's bright background
   does not sit as a hard square against the apothecary greens. */
.dock-mark {
  flex: none; display: block;
  width: 2rem; height: 2rem;
  border-radius: 6px; object-fit: cover;
  border: 1px solid var(--line);
}
.dock-id { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; }
.dock-name {
  font-family: var(--serif); font-weight: 700;
  letter-spacing: .1em; font-size: .95rem;
}
/* What Herbert can see right now. Truncates rather than wrapping so the
   head bar never changes height and shoves the chat around. */
.dock-context {
  font-size: .68rem; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#dock-toggle {
  margin-left: auto; flex: none;
  border: 1px solid var(--line); background: var(--bg); color: var(--muted);
  width: 1.5rem; height: 1.5rem; line-height: 1; cursor: pointer;
  font: inherit; font-size: .9rem;
}
#dock-toggle:hover { color: var(--accent); border-color: var(--accent); }
#dock-body { flex: 1; display: flex; flex-direction: column; min-height: 0; }

/* CONSULT — Herbert is the whole workspace. */
body[data-mode="consult"] main { display: none; }
/* CONSULT — Herbert hugs his content instead of stretching to fill the
   viewport. `flex: 0 1 auto` + `margin: auto` sizes the panel to what is
   actually in it and centres it; `max-height: 100%` lets a long conversation
   grow until it hits the viewport and then scroll inside #chat. Before this
   the panel was full-height from the first paint, so an empty conversation
   put a screen of nothing between Herbert's name and the ask bar. */
body[data-mode="consult"] #herbert-dock {
  flex: 0 1 auto; margin: auto;
  max-height: 100%; width: 100%; max-width: 62rem;
  border: 1px solid var(--line);
}

/* BROWSE — right rail. Monograph prose is a vertical column, so it gives up
   this width cheaply, and in exchange Herbert can see the open record. */
body[data-mode="browse"] #herbert-dock {
  width: 30%; min-width: 21rem; max-width: 34rem; flex: none;
  border-left: 1px solid var(--line);
}

/* FORMULATE — bottom console. The builder table needs the horizontal axis
   for parts / percent / amount / ceiling, so Herbert takes height instead
   of width. This is the one face where a right rail actively hurts. */
body[data-mode="formulate"] #workspace { flex-direction: column; }
body[data-mode="formulate"] #herbert-dock {
  height: 34%; min-height: 11rem; flex: none;
  border-top: 1px solid var(--line);
}

/* COLLAPSED — head strip only. In browse it becomes a vertical tab so it
   costs a couple of rem rather than a whole column. */
body[data-dock="collapsed"] #dock-body { display: none; }
body[data-dock="collapsed"] #herbert-dock { flex: none; }
body[data-mode="browse"][data-dock="collapsed"] #herbert-dock {
  width: 2.6rem; min-width: 0;
}
body[data-mode="browse"][data-dock="collapsed"] #dock-head {
  flex-direction: column; padding: .5rem .3rem; gap: .5rem;
}
body[data-mode="browse"][data-dock="collapsed"] .dock-id { display: none; }
body[data-mode="browse"][data-dock="collapsed"] #dock-toggle { margin-left: 0; }
body[data-mode="formulate"][data-dock="collapsed"] #herbert-dock {
  height: auto; min-height: 0;
}

/* ---------- CHAT ---------- */
/* `1 1 auto` rather than `1`: the basis is the content, so #chat does not
   demand height it has nothing to put in. It still fills and scrolls in the
   fixed-size rail and console. */
#chat { flex: 1 1 auto; overflow-y: auto; padding: 1rem 1.2rem;
        display: flex; flex-direction: column; }
/* Content sits just above the ask bar instead of stranding it at the bottom
   of a screen of empty space. `margin-top:auto` on the first child eats the
   slack when the conversation is short and does nothing once it fills up, so
   scrolling still behaves normally. */
#chat > :first-child { margin-top: auto; }
/* GUARD VERDICTS. Same contract as the safety panel: a serious finding is
   never styled like a caution, and neither is dismissible. */
.guard {
  margin-top: .6rem; padding: .5rem .7rem;
  font-size: .82rem; line-height: 1.45;
  border-left: 3px solid var(--amber-line);
  background: var(--amber-bg); color: var(--warn-ink);
}
.guard-serious {
  border-left-color: var(--block);
  background: var(--block-bg);
  color: var(--block);
  font-weight: 500;
}
.guard b { display: block; margin-bottom: .15rem; letter-spacing: .02em; }

/* SOURCES, FOLDED. Every citation is still present and still clickable; it
   just no longer buries the answer under a screen of records. */
.records-none {
  margin-top: .7rem; padding-top: .5rem;
  border-top: 1px solid var(--line);
  font-size: .74rem; color: var(--muted);
}
details.records { margin-top: .7rem; border-top: 1px solid var(--line); }
details.records > summary {
  cursor: pointer; padding: .45rem 0;
  font-size: .72rem; text-transform: uppercase; letter-spacing: .12em;
  color: var(--muted); list-style: none;
}
details.records > summary::-webkit-details-marker { display: none; }
details.records > summary::before { content: "▸ "; color: var(--accent); }
details.records[open] > summary::before { content: "▾ "; }
details.records > summary:hover { color: var(--accent); }

/* AN EXCHANGE — a question and its answer, deleted as one unit.
   The × only appears on hover or keyboard focus: a delete control sitting
   permanently beside every answer is visual noise, but it must never be
   reachable only by mouse. */
.exchange { position: relative; }
.exchange + .exchange {
  margin-top: 1.1rem; padding-top: 1.1rem;
  border-top: 1px solid var(--line);
}
.exchange-del {
  position: absolute; top: .1rem; right: 0;
  width: 1.35rem; height: 1.35rem; padding: 0; line-height: 1;
  border: 1px solid transparent; background: transparent;
  color: var(--muted); font: inherit; font-size: 1rem;
  cursor: pointer; opacity: 0; transition: opacity .12s ease;
}
.exchange:hover .exchange-del,
.exchange-del:focus-visible { opacity: 1; }
.exchange-del:hover, .exchange-del:focus-visible {
  color: var(--block); border-color: var(--block); outline: none;
}
.exchange-pdf {
  position: absolute; top: .2rem; right: 1.5rem;
  padding: 0 .25rem; height: 1.2rem; line-height: 1.15rem;
  border: 1px solid transparent; background: transparent;
  color: var(--muted); font: inherit; font-size: .58rem; font-weight: 700;
  letter-spacing: .06em; cursor: pointer; opacity: 0; transition: opacity .12s ease;
}
.exchange:hover .exchange-pdf, .exchange-pdf:focus-visible { opacity: 1; }
.exchange-pdf:hover, .exchange-pdf:focus-visible {
  color: var(--accent); border-color: var(--accent); outline: none;
}
#chat-save {
  margin-left: auto; flex: none;
  border: 1px solid var(--line); background: var(--bg); color: var(--muted);
  padding: .1rem .5rem; cursor: pointer; font: inherit; font-size: .7rem;
  text-transform: uppercase; letter-spacing: .1em;
}
#chat-save:hover { color: var(--accent); border-color: var(--accent); }
#chat-save.hidden { display: none; }
#chat-clear {
  flex: none; margin-left: .4rem;
  border: 1px solid var(--line); background: var(--bg); color: var(--muted);
  padding: .1rem .5rem; cursor: pointer; font: inherit; font-size: .7rem;
  text-transform: uppercase; letter-spacing: .1em;
}
#chat-clear:hover { color: var(--accent); border-color: var(--accent); }
#chat-clear.hidden { display: none; }
/* the toggle keeps its place at the far right once Clear appears */
#chat-clear + #dock-toggle { margin-left: .4rem; }

/* Floating "Added to formula" confirmation, over any face (the clinician 2026-08-13). */
#toast {
  position: fixed; left: 50%; bottom: 1.5rem; transform: translate(-50%, 1.5rem);
  z-index: 60; display: flex; align-items: center; gap: .8rem;
  background: var(--ink); color: var(--bg); padding: .55rem 1rem;
  border-radius: 6px; box-shadow: 0 6px 24px rgba(0, 0, 0, .35);
  font-size: .9rem; opacity: 0; pointer-events: none; max-width: 90vw;
  transition: opacity .18s ease, transform .18s ease;
}
#toast.show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.toast-act {
  border: 1px solid rgba(255, 255, 255, .4); background: transparent;
  color: inherit; padding: .15rem .55rem; border-radius: 4px; cursor: pointer;
  font: inherit; font-size: .8rem;
}
.toast-act:hover { background: rgba(255, 255, 255, .15); }

.msg { margin: .8rem 0; }
.msg.system { color: var(--muted); font-size: .9rem; }
.examples { margin-top: .5rem; display: flex; flex-wrap: wrap; gap: .4rem; }
.example {
  border: 1px dashed var(--chip-line); background: var(--panel);
  padding: .25rem .6rem; cursor: pointer; font-size: .8rem; color: var(--accent);
}
.msg.user {
  background: var(--accent-soft); border-left: 3px solid var(--accent);
  padding: .5rem .8rem; font-weight: 600;
}
.msg.assistant .gen {
  background: var(--panel); border: 1px solid var(--line);
  padding: .7rem .9rem; margin-bottom: .6rem; white-space: pre-wrap;
}
.gen-label, .retr-label {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .12em;
  color: var(--muted); display: block; margin-bottom: .35rem;
}
.card {
  background: var(--panel); border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  padding: .55rem .8rem; margin: .45rem 0;
}
.card h4 { margin: 0 0 .15rem; font-family: var(--serif); font-style: italic; font-size: 1rem; }
.card .kv { font-size: .85rem; margin: .12rem 0; }
.card .kv b { font-weight: 600; color: var(--muted); font-size: .75rem;
  text-transform: uppercase; letter-spacing: .08em; }
blockquote {
  margin: .3rem 0; padding: .4rem .7rem; font-family: var(--serif);
  background: var(--bg); border-left: 3px solid var(--chip-line); font-size: .92rem;
}
#ask-form { display: flex; gap: .5rem; padding: .8rem 1.2rem; border-top: 1px solid var(--line); background: var(--panel); }
#ask-form input { flex: 1; padding: .55rem .8rem; border: 1px solid var(--line); font: inherit; }
#ask-form button, #f-apply, #ff-apply {
  background: var(--accent); color: var(--on-accent); border: 0; padding: .55rem 1.4rem;
  cursor: pointer; font: inherit; letter-spacing: .06em;
}

/* ---------- chips & badges ---------- */
.chip {
  display: inline-block; border: 1px solid var(--chip-line);
  background: var(--chip-bg); color: var(--accent);
  font-size: .72rem; font-family: var(--mono);
  padding: .05rem .45rem; margin: .1rem .2rem .1rem 0;
  cursor: pointer; border-radius: 2px; max-width: 22rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  vertical-align: middle;
}
.chip:hover { background: var(--accent); color: var(--on-accent); }
.cite-ref {
  border: 0; background: none; color: var(--accent); cursor: pointer;
  font-weight: 700; padding: 0 .1rem; font: inherit;
}
.badge {
  display: inline-block; font-size: .66rem; font-weight: 700;
  letter-spacing: .1em; padding: .1rem .5rem; border-radius: 2px;
  text-transform: uppercase; margin-left: .35rem; vertical-align: middle;
}
.badge.tier-TRADITIONAL { background: var(--traditional); color: var(--on-accent); }
.badge.tier-ADAPTED { background: var(--adapted); color: var(--on-accent); }
.badge.tier-COMPOSED { background: var(--composed); color: var(--on-accent); }
.badge.tier-B { background: transparent; color: var(--tierb); border: 1px solid var(--tierb); }
.badge.formulable { background: transparent; color: var(--traditional); border: 1px solid var(--traditional); }

/* ---------- BROWSE ---------- */
/* ================= BROWSE — the web app's layout =================
   Filters across the top, cards below, Herbert keeping the right rail.
   Ported from the reference web app and mapped onto the box's own
   token names so light mode and the safety colours keep working. */

#browse { gap: 0; }
#browse-main { flex: 1; min-width: 0; overflow-y: auto; padding: 1.1rem 1.2rem; }

.filter-panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px; padding: 1rem 1.1rem; margin-bottom: 1rem;
}
.filter-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: .9rem;
}
.filter-group label {
  display: block; font-size: .68rem; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .1em; margin-bottom: .35rem;
}
.filter-group select, .filter-group input[type="text"] {
  width: 100%; padding: .45rem .6rem; font: inherit; font-size: .85rem;
  background: var(--field); color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px;
}
.filter-group select:focus, .filter-group input[type="text"]:focus {
  outline: none; border-color: var(--accent);
}
.filter-footer {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-top: .9rem; padding-top: .8rem;
  border-top: 1px solid var(--line); flex-wrap: wrap;
}
.filter-checkbox {
  display: flex; align-items: center; gap: .45rem;
  font-size: .84rem; color: var(--muted); cursor: pointer;
}
.filter-checkbox input { accent-color: var(--accent); }
.filter-buttons { display: flex; gap: .5rem; }

.herbs-toolbar {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; margin-bottom: .8rem; flex-wrap: wrap;
}
.herbs-count { font-size: .85rem; color: var(--muted); }

/* ---- the card ---- */
.herbs-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: .9rem;
}
.herb-card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px; overflow: hidden; cursor: pointer;
  transition: transform .15s ease, border-color .15s ease;
}
.herb-card:hover, .herb-card:focus-visible {
  transform: translateY(-2px); border-color: var(--accent); outline: none;
}
/* Fallback when a monograph has no photograph — about half of them, since
   the photo set covers 513 herbs and the store holds 3,022 records across 13
   sources. The web app does exactly the same. */
/* The 513 Bountiful Herbs photographs. Open-licensed, but CC-BY and CC-BY-SA
   among them require attribution — static/img/herbs/CREDITS.md ships with
   them and must remain reachable. */
.herb-card-img {
  width: 100%; height: 108px; object-fit: cover; display: block;
  background: var(--field); border-bottom: 1px solid var(--line);
}
.herb-card-placeholder {
  height: 108px; background: var(--field);
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  color: var(--accent);
}
.herb-card-placeholder svg { width: 40px; height: 40px; opacity: .35; }
.herb-card-body { padding: .7rem .8rem .8rem; min-width: 0; }
.herb-card-name {
  font-family: var(--serif); font-size: 1.02rem; font-weight: 700;
  line-height: 1.2; color: var(--ink); margin-bottom: .15rem;
}
.herb-card-latin {
  font-size: .72rem; font-style: italic; color: var(--muted);
  margin-bottom: .45rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.herb-card-badges { display: flex; flex-wrap: wrap; gap: .3rem; }
.herb-card-safety { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .45rem; }
.herb-card-source {
  margin-top: .5rem; font-size: .66rem; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.badge {
  display: inline-flex; align-items: center; padding: 2px .5rem;
  border-radius: 999px; font-size: .68rem; font-weight: 500;
  line-height: 1.5; white-space: nowrap;
}
.badge-action {
  background: var(--pass-bg); color: var(--pass);
  border: 1px solid var(--pass);
}
/* What the clinician filtered on, so a result explains why it is here. */
.badge-matched {
  background: var(--accent-soft); color: var(--accent);
  border: 1px solid var(--accent);
}
.safety-icon { font-size: .68rem; color: var(--muted); }
.safety-icon.caution { color: var(--warn-ink); }

.empty-state { text-align: center; padding: 3rem 1rem; color: var(--muted); }
.empty-state h3 {
  font-family: var(--serif); font-size: 1.15rem; color: var(--ink);
  margin: 0 0 .5rem;
}
.empty-state p { font-size: .88rem; max-width: 44ch; margin: 0 auto; }
/* The old filter RAIL (#facet-panel) was removed on 2026-08-10 when Browse
   was rebuilt to the web app's layout: filters across the top, cards below.
   Its CSS is deleted rather than left orphaned — dead rules that still know
   how to draw a removed component are how a removed component comes back. */
#f-apply { width: 100%; margin-top: .6rem; }
#browse-results { flex: 1; overflow-y: auto; padding: 1rem 1.2rem; }
.hint { color: var(--muted); font-size: .85rem; }
.result-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr)); gap: .6rem; }
.result-card { cursor: pointer; }
.result-card:hover { border-left-color: var(--adapted); }

/* ---------- FORMULATE ---------- */
#formulate { flex-direction: column; }
.banner {
  padding: .5rem 1.2rem; font-size: .82rem;
  background: var(--color-warning-highlight); border-bottom: 1px solid var(--adapted); color: var(--color-warning);
}
#formula-filters { display: flex; gap: .5rem; padding: .7rem 1.2rem; background: var(--panel); border-bottom: 1px solid var(--line); }
#formula-filters input, #formula-filters select { padding: .45rem; border: 1px solid var(--line); font: inherit; background: var(--field); }
#formula-filters input { width: 16rem; }
.split { flex: 1; display: flex; min-height: 0; }
#formula-list { width: 26rem; overflow-y: auto; padding: .8rem; border-right: 1px solid var(--line); }
#formula-view { flex: 1; overflow-y: auto; padding: 1rem 1.4rem; }
#formula-view h2 { font-family: var(--serif); margin: .2rem 0 .4rem; }
.verbatim {
  font-family: var(--serif); font-size: .95rem; white-space: pre-wrap;
  background: var(--panel); border: 1px solid var(--line); padding: .9rem 1.1rem;
}
.verbatim-note { font-size: .74rem; color: var(--muted); margin: .2rem 0 .8rem; }
table.ingredients { border-collapse: collapse; width: 100%; background: var(--panel); }
table.ingredients th, table.ingredients td {
  border: 1px solid var(--line); padding: .35rem .6rem; text-align: left; font-size: .88rem;
}
table.ingredients th { background: var(--accent-soft); font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; }
.warn-box {
  border: 1px solid var(--composed); background: var(--color-error-highlight); color: var(--composed);
  padding: .6rem .9rem; margin: .6rem 0; font-size: .88rem;
}
.diff-box {
  border: 1px solid var(--adapted); background: var(--color-warning-highlight);
  padding: .6rem .9rem; margin: .6rem 0; font-size: .88rem;
}
.diff-box h4, .warn-box h4 { margin: 0 0 .3rem; font-size: .72rem; text-transform: uppercase; letter-spacing: .1em; }

/* ---------- modal ---------- */
#modal {
  position: fixed; inset: 0; background: rgba(8, 13, 8, .72);
  display: flex; align-items: center; justify-content: center; z-index: 50;
}
#modal.hidden { display: none; }
#modal-card {
  background: var(--panel); max-width: 46rem; width: 92%; max-height: 82vh;
  overflow-y: auto; padding: 1.2rem 1.5rem; position: relative;
  border-top: 4px solid var(--accent); box-shadow: 0 12px 40px rgba(0,0,0,.6);
}
#modal-close {
  position: absolute; top: .4rem; right: .6rem; border: 0; background: none;
  font-size: 1.5rem; cursor: pointer; color: var(--muted);
}
.passage { font-family: var(--serif); white-space: pre-wrap; font-size: .95rem; }
.source-line { font-size: .78rem; color: var(--muted); margin: .3rem 0 .8rem; font-family: var(--mono); }
.section-label { font-size: .7rem; text-transform: uppercase; letter-spacing: .12em; color: var(--muted); margin: .9rem 0 .25rem; }

/* =====================================================================
   SAFETY + HONESTY SURFACES
   Everything below is here because a clinician must not be able to miss
   it. No colour alone carries meaning: every state also has a word, a
   border and a position in the flow.
   ===================================================================== */

/* Safety palette, mapped onto the same design system. These were light-mode
   hexes and would have been unreadable on the dark canvas. The MEANINGS are
   unchanged: amber = caution, block = serious, pass = the only calm state,
   unsourced = visibly not a cited answer. */
:root {
  --amber: var(--color-warning);
  --amber-bg: var(--color-warning-highlight);
  --amber-line: var(--color-warning);
  --warn-ink: var(--color-warning);
  --pass: var(--color-secondary);
  --pass-bg: var(--color-secondary-highlight);
  --block: var(--color-error);
  --block-bg: var(--color-error-highlight);
  --unsourced-line: var(--color-text-faint);
  --unsourced-bg: var(--color-surface-2);
}

/* ---------- persistent disclaimer (never dismissible) ---------- */
.disclaimer {
  display: flex; gap: .5rem; align-items: baseline;
  padding: .45rem 1.2rem;
  background: var(--color-warning-highlight);
  border-bottom: 1px solid var(--amber-line);
  color: var(--warn-ink);
  font-size: .82rem;
}
.disclaimer .disclaimer-mark { color: var(--amber); }

/* ---------- loud degrade banner (retrieval not at full strength) ---------- */
.banner-degraded {
  padding: .5rem 1.2rem; font-size: .8rem;
  background: var(--amber-bg); color: var(--warn-ink);
  border-bottom: 2px solid var(--amber-line);
  font-family: var(--mono);
}
.banner-degraded.hidden { display: none; }

/* ---------- CONSULT: coverage / prose honesty ---------- */
.coverage {
  font-size: .8rem; padding: .45rem .8rem; margin-bottom: .5rem;
  border-left: 4px solid var(--line); background: var(--panel);
}
.coverage b { text-transform: uppercase; letter-spacing: .1em; font-size: .7rem; }
.coverage.state-grounded { border-left-color: var(--pass); background: var(--pass-bg); }
.coverage.state-weak { border-left-color: var(--amber-line); background: var(--amber-bg); color: var(--warn-ink); }
.coverage.state-off_corpus,
.coverage.state-no_corpus_match {
  border-left-color: var(--block); background: var(--block-bg); color: var(--block);
  font-weight: 600;
}
/* Citation styling WITHHELD: the prose is visibly not a sourced answer. */
.msg.assistant .gen.unsourced {
  background: var(--unsourced-bg);
  border: 1px dashed var(--unsourced-line);
  border-left: 4px solid var(--unsourced-line);
  color: var(--muted); font-style: italic;
}
.msg.assistant .gen.caution {
  border-left: 4px solid var(--amber-line); background: var(--color-warning-highlight);
}
.unsourced-ref {          /* what a [n] looks like when it may not be a link */
  font-family: var(--mono); color: var(--unsourced-line);
  text-decoration: line-through;
}
.gen-label.unsourced-label { color: var(--block); font-weight: 700; }
.retrieval-line {
  font-size: .7rem; font-family: var(--mono); color: var(--muted);
  margin: .2rem 0 .5rem;
}
.retrieval-line.degraded { color: var(--block); font-weight: 700; }

/* ---------- deterministic conversion (apothecary.py) ---------- */
.conversion {
  border: 2px solid var(--accent); background: var(--panel);
  padding: .6rem .9rem; margin: .5rem 0;
}
.conversion .metric {
  font-family: var(--mono); font-size: 1.25rem; font-weight: 700;
  color: var(--accent); display: block;
}
.conversion .computed-by {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--muted);
}
.conversion .as-written { font-family: var(--serif); font-size: .9rem; }
#converter { border-top: 1px solid var(--line); background: var(--panel); padding: .5rem 1.2rem; }
#converter summary { font-size: .75rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); cursor: pointer; }
#convert-form { display: flex; gap: .5rem; margin-top: .5rem; }
#convert-form input { flex: 1; padding: .45rem; border: 1px solid var(--line); font: inherit; }
#convert-form select { padding: .45rem; border: 1px solid var(--line); font: inherit; background: var(--field); }
#convert-form button { background: var(--accent); color: var(--on-accent); border: 0; padding: .45rem 1.1rem; cursor: pointer; font: inherit; }
#convert-out:not(:empty) { margin-top: .5rem; }

/* ---------- FORMULATE: the safety panel ---------- */
#safety-tool {
  display: flex; gap: 0; border-bottom: 1px solid var(--line);
  background: var(--bg); max-height: 60vh;
}
#builder {
  width: 22rem; padding: .8rem 1rem; border-right: 1px solid var(--line);
  background: var(--panel); overflow-y: auto;
}
#builder-rows { display: flex; flex-direction: column; gap: .3rem; }
.builder-row { display: flex; gap: .3rem; }
.builder-row input.herb { flex: 1; padding: .35rem; border: 1px solid var(--line); font: inherit; }
.builder-row input.parts { width: 4.2rem; padding: .35rem; border: 1px solid var(--line); font: inherit; }
.builder-row button { border: 1px solid var(--line); background: var(--bg); cursor: pointer; }
#builder-controls { margin-top: .6rem; display: flex; flex-direction: column; gap: .4rem; }
#builder-controls label { font-size: .74rem; color: var(--muted); }
#builder-controls input, #builder-controls select {
  width: 100%; padding: .35rem; border: 1px solid var(--line); font: inherit; background: var(--field);
}
#builder-check, #builder-compose {
  background: var(--accent); color: var(--on-accent); border: 0; padding: .5rem 1rem;
  cursor: pointer; font: inherit; letter-spacing: .06em;
}
#builder-compose { background: var(--muted); }
#safety-panel { flex: 1; overflow-y: auto; padding: .9rem 1.2rem; }

/* Verdict header. A WARN is never styled like a PASS: different colour,
   different border weight, different word, and PASS is the only one that
   is allowed to look calm. */
.verdict {
  display: flex; align-items: baseline; gap: .6rem;
  padding: .6rem .9rem; margin-bottom: .7rem; border: 2px solid var(--line);
}
.verdict .word {
  font-weight: 800; letter-spacing: .18em; text-transform: uppercase;
  font-size: 1rem;
}
.verdict.pass { border-color: var(--pass); background: var(--pass-bg); color: var(--pass); }
.verdict.warn {
  border: 3px solid var(--amber-line); background: var(--amber-bg);
  color: var(--warn-ink); border-left-width: 12px;
}
.verdict.block {
  border: 3px solid var(--block); background: var(--block-bg);
  color: var(--block); border-left-width: 12px;
}
.verdict .sub { font-size: .78rem; }

/* The whole-formula ceiling line. */
.ceiling-line {
  border: 1px solid var(--accent); background: var(--panel);
  padding: .6rem .9rem; margin: .5rem 0;
}
.ceiling-line .value {
  font-family: var(--mono); font-size: 1.3rem; font-weight: 700; color: var(--accent);
}
.ceiling-line.no-ceiling { border-color: var(--amber-line); background: var(--amber-bg); color: var(--warn-ink); }
.ceiling-line .binding { font-family: var(--serif); font-style: italic; }
.ceiling-rule { font-size: .72rem; color: var(--muted); margin-top: .3rem; }

/* NON-DISMISSIBLE amber banner, one per unbounded ingredient. */
.amber-banner {
  border: 2px solid var(--amber-line); border-left-width: 12px;
  background: var(--amber-bg); color: var(--warn-ink);
  padding: .55rem .9rem; margin: .4rem 0;
}
.amber-banner .label {
  display: block; font-weight: 800; letter-spacing: .04em;
  text-transform: none; font-size: .95rem;
}
.amber-banner .no-dismiss {
  font-size: .66rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--amber); display: block; margin-top: .25rem;
}
.amber-banner .who { font-family: var(--serif); font-style: italic; }

/* cannot_compare: both preparations, side by side, no conversion. */
.cannot-compare {
  border: 2px solid var(--amber-line); background: var(--field);
  padding: .55rem .9rem; margin: .4rem 0;
}
.cannot-compare .sides { display: flex; gap: .8rem; flex-wrap: wrap; margin: .35rem 0; }
.cannot-compare .side {
  flex: 1 1 12rem; border: 1px solid var(--line); background: var(--bg);
  padding: .4rem .6rem; font-size: .85rem;
}
.cannot-compare .side h5 {
  margin: 0 0 .2rem; font-size: .66rem; text-transform: uppercase;
  letter-spacing: .1em; color: var(--muted);
}
.cannot-compare .no-conversion {
  display: block; font-weight: 800; color: var(--block);
  text-transform: uppercase; letter-spacing: .08em; font-size: .74rem;
  margin-top: .3rem;
}

/* headroom table; the binding row is flagged in three ways. */
table.headroom { border-collapse: collapse; width: 100%; background: var(--panel); margin: .4rem 0; }
table.headroom th, table.headroom td {
  border: 1px solid var(--line); padding: .3rem .55rem; font-size: .84rem; text-align: left;
}
table.headroom th { background: var(--accent-soft); font-size: .68rem; text-transform: uppercase; letter-spacing: .08em; }
table.headroom tr.binding { background: var(--amber-bg); font-weight: 700; }
table.headroom tr.binding td:first-child { border-left: 6px solid var(--amber-line); }
table.headroom .flag {
  font-size: .64rem; letter-spacing: .08em; text-transform: uppercase;
  background: var(--amber); color: var(--on-accent); padding: .05rem .4rem; border-radius: 2px;
}

/* every results[] entry */
table.results { border-collapse: collapse; width: 100%; background: var(--panel); }
table.results th, table.results td {
  border: 1px solid var(--line); padding: .3rem .55rem; font-size: .82rem;
  text-align: left; vertical-align: top;
}
table.results th { background: var(--accent-soft); font-size: .68rem; text-transform: uppercase; letter-spacing: .08em; }
table.results td.status { font-weight: 800; letter-spacing: .1em; text-transform: uppercase; font-size: .7rem; white-space: nowrap; }
table.results tr.pass td.status { color: var(--pass); }
table.results tr.warn td.status { color: var(--warn-ink); background: var(--amber-bg); }
table.results tr.block td.status { color: var(--on-accent); background: var(--block); }

.provenance {
  font-size: .74rem; color: var(--muted); font-family: var(--mono);
  border-top: 1px solid var(--line); margin-top: .8rem; padding-top: .4rem;
}
.fail-closed {
  border: 3px solid var(--block); border-left-width: 12px;
  background: var(--block-bg); color: var(--block);
  padding: .6rem .9rem; margin: .5rem 0; font-size: .88rem;
}
.fail-closed b { text-transform: uppercase; letter-spacing: .1em; font-size: .7rem; }


/* ---------- FORMULATE: the editable builder (wired 2026-08-10) ---------- */

/* The middle column between #builder and #safety-panel. */
#builder-work {
  flex: 1 1 22rem; min-width: 18rem; padding: .8rem 1rem;
  border-right: 1px solid var(--line); overflow-y: auto; background: var(--bg);
}

/* Add-a-herb search + autocomplete. */
#herb-search-wrap { position: relative; }
#herb-search {
  width: 100%; padding: .4rem .5rem; border: 1px solid var(--line);
  font: inherit; background: var(--field); color: var(--ink);
}
#herb-suggest {
  position: absolute; z-index: 30; left: 0; right: 0; top: 100%;
  background: var(--panel); border: 1px solid var(--line);
  box-shadow: var(--shadow-glow); max-height: 18rem; overflow-y: auto;
}
#herb-suggest.hidden { display: none; }
.suggest-item {
  display: block; width: 100%; text-align: left; border: 0;
  border-bottom: 1px solid var(--line); background: transparent; color: var(--ink);
  padding: .4rem .55rem; cursor: pointer; font: inherit;
}
.suggest-item:hover, .suggest-item:focus { background: var(--accent-soft); }
.suggest-name { font-family: var(--serif); font-weight: 600; }
.suggest-latin { color: var(--muted); font-style: italic; font-size: .85rem; }
.suggest-refused { display: block; color: var(--block); font-size: .74rem; }
.suggest-empty { padding: .5rem .6rem; color: var(--muted); font-size: .85rem; }

/* The add result line: a soft note, a hard refusal, or a brief confirmation.
   Nothing here is a safety judgement made in the browser — every word comes
   from the engine's /api/builder/add response. */
#add-refusal:not(:empty) { margin: .4rem 0; }
.add-refusal {
  border: 2px solid var(--amber-line); border-left-width: 10px;
  background: var(--amber-bg); color: var(--warn-ink);
  padding: .45rem .7rem; font-size: .85rem;
}
.add-refusal.hard { border-color: var(--block); background: var(--block-bg); color: var(--block); }
.add-refusal b { text-transform: none; }
.refusal-suggest { margin-top: .3rem; display: flex; flex-wrap: wrap; gap: .3rem; }
.add-ok {
  border: 1px solid var(--secondary); background: var(--color-secondary-highlight);
  color: var(--ink); padding: .4rem .7rem; font-size: .85rem;
}

/* THE INGREDIENT TABLE. Override the legacy .builder-row{display:flex} so the
   new real table renders as a table. Every cell holds engine output. */
#builder-rows .builder-table { border-collapse: collapse; width: 100%; background: var(--panel); }
#builder-rows .builder-table th, #builder-rows .builder-table td {
  border: 1px solid var(--line); padding: .3rem .4rem; font-size: .84rem;
  text-align: left; vertical-align: top;
}
#builder-rows .builder-table th {
  background: var(--accent-soft); font-size: .66rem; text-transform: uppercase;
  letter-spacing: .08em; color: var(--muted);
}
#builder-rows .builder-row { display: table-row; }
#builder-rows .row-herb { min-width: 9rem; }
.row-name { font-family: var(--serif); font-weight: 600; }
.row-note { font-size: .72rem; color: var(--muted); margin-top: .15rem; }
#builder-rows input.num {
  width: 4.6rem; padding: .3rem; border: 1px solid var(--line);
  font: inherit; background: var(--field); color: var(--ink); text-align: right;
}
#builder-rows .unit { font-size: .72rem; color: var(--muted); }
.row-remove {
  border: 1px solid var(--line); background: var(--bg); color: var(--muted);
  cursor: pointer; width: 1.6rem; height: 1.6rem; line-height: 1; font-size: 1rem;
}
.row-remove:hover { color: var(--block); border-color: var(--block); }

.badge.tier-none {
  background: var(--field); color: var(--muted); border: 1px solid var(--line);
}

.derived-line {
  margin: .5rem 0; padding: .4rem .6rem; background: var(--panel);
  border: 1px solid var(--line); font-size: .85rem;
}
.derived-line b { color: var(--accent); font-family: var(--mono); }

.export-bar { display: flex; gap: .5rem; margin-top: .5rem; }
.export-bar button {
  background: var(--accent); color: var(--on-accent); border: 0;
  padding: .45rem 1rem; cursor: pointer; font: inherit; letter-spacing: .05em;
}
.export-bar button.secondary { background: var(--field); color: var(--ink); border: 1px solid var(--line); }

/* MY LIBRARY. */
.library-mode {
  padding: .5rem .8rem; border: 1px solid var(--line); background: var(--panel);
  font-size: .85rem; margin-bottom: .6rem;
}
.library-mode.ok { border-color: var(--secondary); color: var(--ink); }
.library-mode.warn { border-color: var(--amber-line); background: var(--amber-bg); color: var(--warn-ink); }
#library-controls { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: .5rem; }
#library-controls button {
  background: var(--accent); color: var(--on-accent); border: 0;
  padding: .45rem 1rem; cursor: pointer; font: inherit;
}
#library-list { display: flex; flex-direction: column; gap: .35rem; }
.library-item {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  border: 1px solid var(--line); background: var(--panel); padding: .45rem .7rem;
}
.library-item .lib-name { font-family: var(--serif); font-weight: 600; flex: 1 1 12rem; }
.library-item .lib-meta { color: var(--muted); font-size: .78rem; font-family: var(--mono); }
.library-item .lib-actions { display: flex; gap: .35rem; }
.library-item button { border: 1px solid var(--line); background: var(--field); color: var(--ink); cursor: pointer; padding: .3rem .7rem; font: inherit; }
.library-item button.lib-load { background: var(--accent); color: var(--on-accent); border: 0; }


/* Formulate sub-faces. index.html carries .fmode / .fmode.active and
   #formulate-tabs, but the stylesheet never defined them, so all three
   panes rendered stacked. Mirror the .mode contract: only the active pane
   shows. (Pre-existing gap, surfaced when the builder was first wired.) */
#formulate.mode.active { flex-direction: column; }
#formulate .banner { flex: 0 0 auto; }
#formulate-tabs {
  display: flex; gap: .3rem; padding: .5rem 1rem 0;
  border-bottom: 1px solid var(--line); flex: 0 0 auto;
}
#formulate-tabs button {
  background: var(--field); color: var(--muted);
  border: 1px solid var(--line); border-bottom: 0; padding: .4rem 1.1rem;
  cursor: pointer; font: inherit; letter-spacing: .03em;
}
#formulate-tabs button.active { background: var(--panel); color: var(--ink); }
.fmode { display: none; flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.fmode.active { display: block; }
#fmode-library, #fmode-sources { padding: .8rem 1rem; }

/* The import file-input is triggered from the "Import a formula file…"
   button; there is no global .hidden{display:none}, so suppress it here. */
#lib-file { display: none; }


/* ================= FORMULATE builder — redesign 2026-08-10 =================
   Modelled on the reference web app: clean, clinical, professional.
   Single column, a named script, the herb table, directions, and a safety
   note only when a herb carries a real concern. */
#fmode-builder { padding: 1rem 1.2rem 2rem; }
#prep-tabs { display: flex; gap: .4rem; max-width: 52rem; margin: 0 auto 1.2rem; }
#prep-tabs button {
  flex: 1; background: var(--field); color: var(--muted);
  border: 1px solid var(--line); padding: .6rem 1rem; cursor: pointer;
  font: inherit; letter-spacing: .03em; border-radius: 3px;
}
#prep-tabs button.active {
  background: var(--accent); color: var(--on-accent);
  border-color: var(--accent); font-weight: 600;
}

#script-card { max-width: 52rem; margin: 0 auto; }
.script-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem;
}
.formula-name {
  flex: 1 1 18rem; background: transparent; border: 0;
  border-bottom: 1px dotted var(--line); color: var(--ink);
  font-family: var(--serif); font-size: 1.9rem; padding: .2rem 0;
}
.formula-name::placeholder { color: var(--muted); font-style: italic; opacity: .7; }
.script-actions { display: flex; gap: .4rem; flex-wrap: wrap; }
.script-actions button {
  background: var(--field); color: var(--ink); border: 1px solid var(--line);
  padding: .4rem .9rem; cursor: pointer; font: inherit; border-radius: 3px;
}
.script-actions button:hover { border-color: var(--accent); }
.script-actions .danger:hover { border-color: var(--block); color: var(--block); }

#herb-search-wrap { position: relative; margin-bottom: .4rem; }
#herb-search {
  width: 100%; padding: .7rem .9rem; border: 1px solid var(--line);
  background: var(--field); color: var(--ink); font: inherit; border-radius: 4px;
}
#herb-suggest {
  position: absolute; z-index: 40; left: 0; right: 0; top: 100%;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 0 0 4px 4px; box-shadow: var(--shadow-glow);
  max-height: 20rem; overflow-y: auto;
}
#herb-suggest.hidden { display: none; }
.suggest-item {
  display: flex; justify-content: space-between; align-items: baseline;
  width: 100%; text-align: left; border: 0; border-bottom: 1px solid var(--line);
  background: transparent; color: var(--ink); padding: .5rem .8rem;
  cursor: pointer; font: inherit;
}
.suggest-item:hover { background: var(--accent-soft); }
.suggest-name { font-family: var(--serif); font-size: 1.05rem; }
.suggest-latin { color: var(--muted); font-style: italic; font-size: .85rem; }
.suggest-empty { padding: .6rem .8rem; color: var(--muted); }

#add-refusal:not(:empty) { margin: .4rem 0; }
.add-note {
  border-left: 3px solid var(--amber-line); background: var(--amber-bg);
  color: var(--warn-ink); padding: .4rem .7rem; font-size: .9rem;
}
.add-note .link-add {
  background: none; border: 0; color: var(--accent); cursor: pointer;
  text-decoration: underline; font: inherit; padding: 0;
}
.add-ok {
  border-left: 3px solid var(--secondary);
  background: var(--color-secondary-highlight); color: var(--ink);
  padding: .4rem .7rem; font-size: .9rem;
}

#builder-settings {
  display: flex; gap: 1.2rem; align-items: flex-end; flex-wrap: wrap;
  background: var(--panel); border: 1px solid var(--line); border-radius: 4px;
  padding: .8rem 1rem; margin: .6rem 0 .4rem;
}
#builder-settings label {
  display: flex; flex-direction: column; gap: .25rem; font-size: .68rem;
  text-transform: uppercase; letter-spacing: .06em; color: var(--muted);
}
#builder-settings input, #builder-settings select {
  padding: .4rem .5rem; border: 1px solid var(--line); background: var(--field);
  color: var(--ink); font: inherit; text-transform: none; letter-spacing: normal;
}
#builder-settings input[type=number] { width: 6rem; }
.settings-info {
  flex: 1 1 12rem; margin: 0; color: var(--muted); font-size: .82rem;
  text-transform: none; letter-spacing: normal; align-self: center;
}

.rx-table { border-collapse: collapse; width: 100%; margin: .6rem 0 1rem; }
.rx-table th, .rx-table td {
  padding: .5rem .5rem; text-align: right; border-bottom: 1px solid var(--line);
  font-size: .92rem;
}
.rx-table th:first-child, .rx-table td:first-child { text-align: left; }
.rx-table thead th {
  color: var(--muted); font-size: .68rem; text-transform: uppercase;
  letter-spacing: .07em; border-bottom: 1.5px solid var(--line);
}
.rx-common { font-family: var(--serif); font-size: 1.05rem; }
.rx-latin { color: var(--muted); font-style: italic; font-size: .82rem; }
.rx-menstruum { color: var(--muted); font-size: .85rem; }
.rx-table input.num {
  width: 4.6rem; padding: .3rem; border: 1px solid var(--line);
  background: var(--field); color: var(--ink); font: inherit;
  text-align: right; border-radius: 3px;
}
.rx-remove {
  border: 0; background: none; color: var(--muted); cursor: pointer;
  font-size: 1.2rem; line-height: 1; padding: 0 .3rem;
}
.rx-remove:hover { color: var(--block); }
.rx-total td {
  border-top: 1.5px solid var(--line); border-bottom: 0; font-weight: 700;
  color: var(--accent);
}
.rx-total td:first-child { color: var(--ink); }

.builder-empty { text-align: center; color: var(--muted); padding: 2.5rem 1rem; }
.builder-empty .empty-mark svg { width: 46px; height: 46px; opacity: .45; color: var(--accent); }
.builder-empty h3 { font-family: var(--serif); color: var(--ink); margin: .6rem 0 .2rem; font-weight: 500; }
.builder-empty p { margin: 0; font-size: .9rem; }

#builder-safety:not(:empty) { margin: 1rem 0; }
.safety-block { border: 1px solid var(--line); border-radius: 4px; overflow: hidden; }
.safety-title {
  background: var(--field); color: var(--muted); font-size: .7rem;
  text-transform: uppercase; letter-spacing: .08em; padding: .35rem .8rem;
}
.safety-line {
  display: flex; gap: .8rem; align-items: baseline; padding: .5rem .8rem;
  border-top: 1px solid var(--line); font-size: .9rem;
}
.safety-line .safety-what { flex: 1; }
.safety-line .safety-who { font-family: var(--serif); font-style: italic; color: var(--ink); }
.safety-line.red { border-left: 4px solid var(--block); }
.safety-line.red .safety-what { color: var(--block); font-weight: 600; }
.safety-line.amber { border-left: 4px solid var(--amber-line); }
.safety-line.amber .safety-what { color: var(--warn-ink); }
.safety-line.info { border-left: 4px solid var(--accent); }
.safety-line.info .safety-what { color: var(--accent); font-weight: 600; }

/* Essential-oil blend ceiling — limiting-reagent result for the whole blend. */
.eo-ceiling {
  margin: .5rem 0; padding: .6rem .8rem; font-size: .86rem;
  border: 1px solid var(--line); border-left: 4px solid var(--accent);
  background: var(--accent-soft); color: var(--ink); border-radius: 4px;
}
.eo-ceiling.over {
  border-left-color: var(--block); background: var(--amber-bg);
  color: var(--warn-ink);
}
.eo-ceiling .eo-ceiling-label {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .08em;
  font-weight: 700; color: var(--accent); margin-right: .4rem;
}
.eo-ceiling.over .eo-ceiling-label { color: var(--block); }

/* Herbal-formula → essential-oil conversion warning. */
.eo-convert {
  margin: .5rem 0; padding: .6rem .8rem; font-size: .86rem;
  border: 1px solid var(--block); border-left: 4px solid var(--block);
  background: var(--amber-bg); color: var(--warn-ink); border-radius: 4px;
}
.eo-convert-label {
  display: inline-block; font-size: .66rem; text-transform: uppercase;
  letter-spacing: .08em; font-weight: 700; color: var(--block);
  margin-right: .4rem;
}

/* Single-oil route banner in the monograph modal: topical-only vs internal. */
.eo-route {
  margin: .8rem 0; padding: .7rem .9rem; font-size: .9rem; border-radius: 4px;
  border: 1px solid var(--amber-line); border-left: 4px solid var(--amber-line);
  background: var(--amber-bg); color: var(--warn-ink);
}
.eo-route.danger { border-color: var(--block); border-left-color: var(--block); }
.eo-route.ok {
  border-color: var(--accent); border-left-color: var(--accent);
  background: var(--accent-soft); color: var(--ink);
}
.eo-route-label {
  display: inline-block; font-size: .66rem; text-transform: uppercase;
  letter-spacing: .08em; font-weight: 700; margin-right: .4rem;
}
.eo-route-basis, .eo-route-cautions {
  margin-top: .35rem; font-size: .82rem; color: var(--ink);
}
.eo-route-cautions { font-style: italic; }

.section-label {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--muted); margin: 1.3rem 0 .4rem;
}
#dosage-section .dosage-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: .7rem;
}
#dosage-section label, #script-people label {
  display: flex; flex-direction: column; gap: .25rem; font-size: .68rem;
  text-transform: uppercase; letter-spacing: .06em; color: var(--muted);
}
#dosage-section input, #script-people input, #builder-notes {
  padding: .5rem; border: 1px solid var(--line); background: var(--field);
  color: var(--ink); font: inherit; text-transform: none; letter-spacing: normal;
  border-radius: 3px;
}
#script-people {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: .7rem; margin-top: 1rem;
}
#builder-notes { width: 100%; }


/* ---------- Browse: token multi-select filters + 3-state badges (2026-08-10) */
.token-group { position: relative; }
.token-input {
  width: 100%; padding: .4rem .5rem; border: 1px solid var(--line);
  background: var(--field); color: var(--ink); font: inherit; border-radius: 3px;
}
.token-chips { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .35rem; }
.token-chip {
  display: inline-flex; align-items: center; gap: .3rem; font-size: .8rem;
  background: var(--accent-soft); color: var(--ink); border: 1px solid var(--accent);
  border-radius: 12px; padding: .12rem .3rem .12rem .6rem;
}
.token-x {
  border: 0; background: none; color: var(--muted); cursor: pointer;
  font-size: 1rem; line-height: 1; padding: 0 .15rem;
}
.token-x:hover { color: var(--block); }
.filter-toggles { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; }

/* Three-state safety badges on cards, matching the web app. */
.herb-card-safety { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .35rem; }
.safety-icon {
  font-size: .68rem; letter-spacing: .02em; padding: .1rem .4rem; border-radius: 3px;
  border: 1px solid; white-space: nowrap;
}
.safety-icon.amber { color: var(--warn-ink); border-color: var(--amber-line); background: var(--amber-bg); }
.safety-icon.red { color: var(--block); border-color: var(--block); background: var(--block-bg); }


/* Clear-all: a rectangle matching Apply (2026-08-11), not a wrapped square. */
#f-apply, #f-reset { border-radius: 3px; }
#f-reset {
  background: var(--field); color: var(--ink); border: 1px solid var(--line);
  padding: .55rem 1.1rem; cursor: pointer; font: inherit; letter-spacing: .04em;
  white-space: nowrap;
}
#f-reset:hover { border-color: var(--accent); }


/* Refreshable example questions (2026-08-11). */
.examples-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .8rem; flex-wrap: wrap;
}
.examples-refresh {
  background: none; border: 1px solid var(--line); color: var(--muted);
  border-radius: 3px; padding: .2rem .55rem; font-size: .72rem; cursor: pointer;
  white-space: nowrap;
}
.examples-refresh:hover { color: var(--accent); border-color: var(--accent); }


/* Formula "For / indication" subtitle field (2026-08-11). */
.script-title { flex: 1 1 18rem; display: flex; flex-direction: column; gap: .15rem; }
.script-title .formula-name { flex: none; width: 100%; }
.formula-for {
  background: transparent; border: 0; border-bottom: 1px dotted var(--line);
  color: var(--muted); font-family: var(--serif); font-style: italic;
  font-size: .98rem; padding: .1rem 0;
}
.formula-for::placeholder { color: var(--muted); opacity: .6; }


/* Ask Herbert for a formula (#16) — options → auto-fill builder (2026-08-11). */
#formulate-assist { margin-bottom: .5rem; }
#assist-bar { display: flex; gap: .5rem; }
#assist-need {
  flex: 1; padding: .6rem .85rem; border: 1px solid var(--accent);
  background: var(--field); color: var(--ink); font: inherit; border-radius: 4px;
}
#assist-go {
  background: var(--accent); color: var(--on-accent); border: 0;
  padding: .6rem 1.1rem; cursor: pointer; font: inherit; border-radius: 4px;
  white-space: nowrap;
}
#assist-results:not(:empty) {
  margin-top: .5rem; display: flex; flex-direction: column; gap: .3rem;
}
.assist-note { font-size: .82rem; color: var(--muted); margin-bottom: .2rem; }
.assist-option {
  display: flex; align-items: baseline; gap: .6rem; width: 100%;
  text-align: left; border: 1px solid var(--line); background: var(--panel);
  color: var(--ink); padding: .5rem .7rem; cursor: pointer; font: inherit;
  border-radius: 3px;
}
.assist-option:hover { border-color: var(--accent); background: var(--accent-soft); }
.custom-formulate { margin-top: .6rem; }
.assist-option-custom {
  border: 1px solid var(--accent); border-left: 4px solid var(--accent);
  background: var(--accent-soft);
}
.assist-option-custom .assist-name { color: var(--accent); font-weight: 700; }
.assist-name { font-family: var(--serif); font-size: 1.02rem; flex: 1; }
.assist-trad { font-size: .72rem; color: var(--muted); text-transform: capitalize; }
.assist-src { font-size: .7rem; color: var(--muted); font-family: var(--mono); }
.or-divider {
  display: flex; align-items: center; text-align: center; color: var(--muted);
  font-size: .7rem; text-transform: uppercase; letter-spacing: .08em;
  margin: .7rem 0; gap: .6rem;
}
.or-divider::before, .or-divider::after {
  content: ""; flex: 1; border-top: 1px solid var(--line);
}


/* Monograph modal redesign (2026-08-11) — professional, comprehensive,
   printable; the raw-JSON dump is gone, replaced by clean labelled fields. */
.mono h3 { font-family: var(--serif); font-size: 1.5rem; margin: 0 0 .1rem; font-weight: 600; }
.mono .source-line { color: var(--muted); font-size: .8rem; margin-bottom: .5rem; }
.mono .card-actions { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin: .3rem 0 1rem; }
.mono-print-btn {
  background: var(--accent); color: var(--on-accent); border: 0;
  padding: .4rem 1rem; border-radius: 3px; cursor: pointer; font: inherit;
  letter-spacing: .04em;
}
.mono-print-btn:hover { background: var(--accent-hover, var(--accent)); }
.mono .section-label {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--accent); margin: 1.1rem 0 .35rem;
  border-top: 1px solid var(--line); padding-top: .7rem;
}
.mono-names { display: flex; flex-wrap: wrap; gap: .5rem; }
.mono-fields {
  display: grid; grid-template-columns: max-content 1fr; gap: .25rem .9rem;
  font-size: .88rem; margin: .2rem 0;
}
.mono-field { display: contents; }
.mono-fk { color: var(--muted); text-transform: capitalize; }
.mono-fv { color: var(--ink); }

/* Plant-part badge on Browse cards (dandelion root vs leaf). #37 */
.badge-part{
  background:#eef4ec;color:#3a5a40;border:1px solid #cfe0c8;
  text-transform:capitalize;
}

/* Monograph "Source texts" accordion — numbered passages, folded like the
   Consult answer's Sources (the clinician 2026-08-11). */
.mono-sources { margin-top: 14px; }
.mono-source { padding: 8px 0; border-top: 1px solid var(--color-border, #e5e2da); }
.mono-source:first-child { border-top: none; }
.mono-source-h { font-size: 0.9em; color: var(--color-text-muted, #6b675f); margin-bottom: 4px; }
.mono-source-n { font-family: var(--mono, monospace); font-weight: 700; color: var(--color-text, #333); }
.mono-source-loc { color: var(--color-text-faint, #9a958c); }
.mono-source blockquote { margin: 4px 0 6px; padding-left: 10px; border-left: 3px solid var(--color-border, #e5e2da); }

/* Primary "fill this formula" chip in a Consult answer (the clinician 2026-08-11). */
.chip.chip-primary {
  background: var(--color-accent, #3a5a40);
  color: #fff; border-color: var(--color-accent, #3a5a40); font-weight: 600;
}
.chip.chip-primary:hover { filter: brightness(1.08); }

/* "Formulate these" clickable picks shown in a Consult formula answer. */
.formulate-picks { margin: 10px 0; display: flex; flex-direction: column; gap: 6px; }
.formulate-picks-h { font-size: 0.9em; color: var(--color-text-muted, #6b675f); }

/* "treats: …" line on a formula pick (the clinician 2026-08-11). */
.assist-treats { display:block; font-size:0.82em; color: var(--color-text-muted,#6b675f); margin-top:2px; }

/* TCM amounts-uncertain disclaimer (the clinician 2026-08-12) — a caution, shown
   in the builder safety panel and on the formula record. */
.amounts-warning {
  display: flex; gap: 8px; align-items: flex-start;
  background: #fdf3e3; border: 1px solid #e6c98a; border-left: 4px solid #d19a3e;
  color: #6b4e1e; border-radius: 6px; padding: 9px 12px; margin: 10px 0;
  font-size: 0.9em; line-height: 1.4;
}
.amounts-warning-icon { font-size: 1.05em; line-height: 1; }

/* Documented preparation form note + caution (the clinician 2026-08-12). */
.prep-documented { display:flex; flex-direction:column; gap:2px; margin-left:auto; align-items:flex-end; }
.prep-doc-label { font-size:0.82em; color: var(--color-text-muted,#6b675f); }
.prep-doc-caution { font-size:0.82em; color:#8a5a1e; max-width:420px; text-align:right; }

/* Essential Oil tab disabled when a documented herbal formula is loaded — an
   EO must be built by hand or loaded from a known EO formula (the clinician). */
#prep-tabs button.disabled, #prep-tabs button:disabled {
  opacity: 0.4; cursor: not-allowed;
}


/* ======================================================================
   VISUAL REFINEMENT LAYER — 2026-08-13
   Appended at the end of style.css so it wins on source order. Nothing
   above is removed; this only elevates. Two goals:
     (1) ship the fonts the design was always meant to use, and
     (2) add the depth, warmth and motion that a $2,000 clinical
         instrument should have — without touching a single id the app
         binds to.
   The box is offline: fonts are local woff2 in /static/fonts/, no network.
   ====================================================================== */

/* ---- 1. THE FONTS (SIL OFL, bundled) ------------------------------- */
@font-face{font-family:"Cormorant Garamond";font-style:normal;font-weight:400;font-display:swap;src:url("/static/fonts/cormorant-garamond-400.woff2") format("woff2");}
@font-face{font-family:"Cormorant Garamond";font-style:normal;font-weight:500;font-display:swap;src:url("/static/fonts/cormorant-garamond-500.woff2") format("woff2");}
@font-face{font-family:"Cormorant Garamond";font-style:normal;font-weight:600;font-display:swap;src:url("/static/fonts/cormorant-garamond-600.woff2") format("woff2");}
@font-face{font-family:"Cormorant Garamond";font-style:normal;font-weight:700;font-display:swap;src:url("/static/fonts/cormorant-garamond-700.woff2") format("woff2");}
@font-face{font-family:"Cormorant Garamond";font-style:italic;font-weight:400;font-display:swap;src:url("/static/fonts/cormorant-garamond-italic-400.woff2") format("woff2");}
@font-face{font-family:"DM Sans";font-style:normal;font-weight:400;font-display:swap;src:url("/static/fonts/dm-sans-400.woff2") format("woff2");}
@font-face{font-family:"DM Sans";font-style:normal;font-weight:500;font-display:swap;src:url("/static/fonts/dm-sans-500.woff2") format("woff2");}
@font-face{font-family:"DM Sans";font-style:normal;font-weight:700;font-display:swap;src:url("/static/fonts/dm-sans-700.woff2") format("woff2");}

/* ---- 2. REFINEMENT TOKENS ----------------------------------------- */
:root{
  --r-sm: 8px; --r-md: 12px; --r-lg: 16px;
  --ease: cubic-bezier(.2,.7,.2,1);
  --lift: 0 10px 30px -12px rgba(0,0,0,.65);
  --ring: 0 0 0 3px var(--color-primary-highlight);
  --gold-grad: linear-gradient(180deg, var(--color-primary-hover), var(--color-primary));
}

/* ---- 3. AMBIENT CANVAS -------------------------------------------- */
/* Flat black reads cheap. Two very soft apothecary glows and a vignette
   give the surface depth without ever competing with content. */
body{
  background:
    radial-gradient(1100px 620px at 8% -10%, rgba(200,164,94,.07), transparent 60%),
    radial-gradient(1000px 720px at 100% -6%, rgba(107,143,113,.06), transparent 55%),
    radial-gradient(1200px 900px at 50% 120%, rgba(107,143,113,.05), transparent 60%),
    var(--color-bg);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
:root[data-theme="light"] body{
  background:
    radial-gradient(1100px 620px at 8% -10%, rgba(138,109,42,.06), transparent 60%),
    radial-gradient(1000px 720px at 100% -6%, rgba(74,112,80,.05), transparent 55%),
    var(--color-bg);
}

::selection{ background: rgba(200,164,94,.30); color: var(--color-text); }
*::-webkit-scrollbar{ width:11px; height:11px; }
*::-webkit-scrollbar-thumb{
  background: var(--color-surface-offset); border-radius:8px;
  border:3px solid transparent; background-clip:padding-box;
}
*::-webkit-scrollbar-thumb:hover{ background: var(--color-border); }
*::-webkit-scrollbar-track{ background: transparent; }

/* Global, gentle motion + a real focus ring everywhere. */
a, button, input, select, textarea, .herb-card, .example, .chip,
nav#tabs button, #formulate-tabs button, #prep-tabs button, .assist-option{
  transition: color .16s var(--ease), background-color .16s var(--ease),
              border-color .16s var(--ease), box-shadow .16s var(--ease),
              transform .14s var(--ease), filter .16s var(--ease);
}
:focus-visible{ outline: none; box-shadow: var(--ring); border-radius: 6px; }

/* ---- 4. FIELDS — kill every white default box ---------------------- */
input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]),
select, textarea{
  background: var(--field); color: var(--ink);
  border:1px solid var(--color-divider); border-radius: var(--r-sm);
}
input:focus, select:focus, textarea:focus{
  outline:none; border-color: var(--accent); box-shadow: var(--ring);
}
::placeholder{ color: var(--color-text-faint); opacity:1; }
/* the two intentionally-bare script fields keep their dotted underline */
.formula-name, .formula-for{
  background: transparent; border:0; border-bottom:1px dotted var(--line);
  border-radius:0; box-shadow:none;
}
.formula-name:focus, .formula-for:focus{
  box-shadow:none; border-bottom:1px solid var(--accent);
}

/* ---- 5. PRIMARY BUTTONS — warm gold, subtle depth, hover lift ------ */
#ask-form button, #f-apply, #ff-apply, #assist-go, #builder-check,
#library-controls button, .library-item button.lib-load, .mono-print-btn,
#convert-form button, .export-bar button:not(.secondary){
  background: var(--gold-grad); color: var(--on-accent); border:0;
  border-radius: var(--r-sm); font-weight:600; letter-spacing:.03em;
  box-shadow: 0 2px 12px -4px rgba(200,164,94,.5);
}
#ask-form button:hover, #f-apply:hover, #ff-apply:hover, #assist-go:hover,
#builder-check:hover, #library-controls button:hover,
.library-item button.lib-load:hover, .mono-print-btn:hover,
#convert-form button:hover, .export-bar button:not(.secondary):hover{
  filter: brightness(1.06);
  box-shadow: 0 6px 20px -5px rgba(200,164,94,.62);
  transform: translateY(-1px);
}
#ask-form button:active, #f-apply:active, #assist-go:active{ transform: translateY(0); }

/* Secondary / ghost buttons — quiet until hovered. */
.script-actions button, #f-reset, .export-bar button.secondary,
.examples-refresh, #chat-save, #chat-clear{
  border-radius: var(--r-sm);
}
.script-actions button:hover, #f-reset:hover{
  border-color: var(--accent); color: var(--accent);
}

/* ---- 6. HEADER — quiet elevation, pill nav ------------------------- */
header{
  padding:.7rem 1.4rem;
  background: linear-gradient(180deg, #101710, #0b110b);
  box-shadow: 0 10px 30px -20px rgba(0,0,0,.9);
  position: relative; z-index: 5;
}
.brand .mark svg{ filter: drop-shadow(0 0 10px rgba(200,164,94,.35)); }
nav#tabs{ gap:.35rem; }
nav#tabs button{
  border-radius: 999px; border-color: var(--color-divider);
  background: rgba(255,255,255,.02); color: var(--color-text-muted);
  padding:.4rem 1.2rem;
}
nav#tabs button:hover{ color: var(--accent); border-color: var(--accent); background: var(--color-primary-highlight); }
nav#tabs button.active{
  background: var(--gold-grad); color: var(--on-accent); border-color: var(--accent);
  box-shadow: 0 4px 16px -4px rgba(200,164,94,.55);
}

/* ---- 7. CONSULT — Herbert as a premium panel ---------------------- */
body[data-mode="consult"] #herbert-dock{
  border-radius: var(--r-lg); border-color: var(--color-divider);
  box-shadow: 0 30px 70px -30px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,.03);
  overflow: hidden;
}
#dock-head{ background: linear-gradient(180deg, rgba(107,143,113,.10), rgba(15,22,15,.6)); }
.dock-mark{
  width:2.35rem; height:2.35rem; border-radius:50%; border:0;
  box-shadow: 0 0 0 2px var(--accent), 0 0 16px -3px rgba(200,164,94,.55);
}
.dock-name{ font-size:1.02rem; }

/* the question — a warmer, rounded prompt block */
.msg.user{
  background: linear-gradient(180deg, var(--color-primary-highlight), rgba(200,164,94,.03));
  border-left:3px solid var(--accent); border-radius: 0 var(--r-sm) var(--r-sm) 0;
  padding:.6rem .95rem;
}
/* the answer — a comfortable reading measure and rhythm */
.msg.assistant{ line-height:1.64; }
.msg.assistant p{ margin:.6rem 0; }
.msg.assistant strong{ color: var(--color-text); }
.msg.assistant em{ color: var(--color-text); }

/* citations — a small gold pill, not a raw bracket */
.cite-ref{
  font-size:.74em; font-weight:700; color: var(--accent);
  border:1px solid var(--color-primary-highlight);
  background: rgba(200,164,94,.06);
  border-radius:6px; padding:0 .3em; margin:0 .05em; line-height:1.4;
  vertical-align: baseline;
}
.cite-ref:hover{ background: var(--accent); color: var(--on-accent); border-color: var(--accent); }

/* the custom-formulate CTA — the one place a gold call-to-action belongs */
.assist-option-custom{
  display:flex; flex-direction:column; align-items:flex-start; gap:.2rem;
  background: linear-gradient(180deg, rgba(200,164,94,.14), rgba(200,164,94,.05));
  border:1px solid var(--accent); border-left:4px solid var(--accent);
  border-radius: var(--r-sm); padding:.7rem .9rem;
  box-shadow: 0 4px 18px -8px rgba(200,164,94,.45);
}
.assist-option-custom .assist-name{ flex:none; }
.assist-option-custom .assist-src{ font-size:.78rem; text-align:left; }
.assist-option-custom:hover{
  filter: brightness(1.05); transform: translateY(-1px);
  box-shadow: 0 8px 24px -8px rgba(200,164,94,.6);
}
.assist-option-custom .assist-name::before{ content:"\2726  "; }

/* sources fold — a touch more presence */
details.records > summary{ font-weight:600; }

/* ask bar — the input should feel like the hero control it is */
#ask-form{ background: linear-gradient(180deg, rgba(15,22,15,.4), var(--panel)); }
#ask-form input{ border-radius: var(--r-sm); padding:.65rem .9rem; }

/* ---- 8. BROWSE — cards with depth ---------------------------------- */
.filter-panel{
  border-color: var(--color-divider);
  box-shadow: 0 12px 30px -22px rgba(0,0,0,.7);
}
.herbs-grid{ gap: 1rem; }
.herb-card{
  border-color: var(--color-divider); border-radius: var(--r-md);
  box-shadow: 0 1px 2px rgba(0,0,0,.35);
}
.herb-card:hover, .herb-card:focus-visible{
  transform: translateY(-4px); border-color: var(--accent); outline:none;
  box-shadow: 0 18px 40px -16px rgba(0,0,0,.7), 0 0 22px -6px rgba(200,164,94,.28);
}
.herb-card-img{ height:132px; }
.herb-card-placeholder{
  height:132px;
  background: radial-gradient(circle at 50% 38%, var(--color-surface-3), var(--field));
}
.herb-card-placeholder svg{ width:54px; height:54px; opacity:.42; }
.herb-card-name{ font-size:1.08rem; }

/* ---- 9. FORMULATE — refined tabs ---------------------------------- */
#prep-tabs button.active, #formulate-tabs button.active{
  box-shadow: inset 0 2px 0 var(--accent);
}
#prep-tabs button.active{
  background: var(--gold-grad); box-shadow: 0 4px 16px -6px rgba(200,164,94,.5);
}
#builder-settings, #script-card .rx-table, .safety-block{ border-radius: var(--r-md); }

/* ---- 10. DISCLAIMER — keep the meaning, soften the edge ----------- */
.disclaimer{ backdrop-filter: saturate(1.1); }

/* ---- 11. MODAL — lift it off the page ----------------------------- */
#modal-card{ border-radius: var(--r-lg); box-shadow: 0 40px 90px -30px rgba(0,0,0,.85); }

/* Answer tradition tag — replaces book citations (2026-08-14). A quiet sage
   pill under Herbert's prose naming which tradition(s) it drew on. */
.answer-tradition{ display:flex; gap:.4rem; flex-wrap:wrap; margin:.6rem 0 .2rem; }
.trad-pill{
  font-family: var(--sans); font-size:.68rem; letter-spacing:.06em;
  text-transform:uppercase; color: var(--color-secondary);
  border:1px solid var(--color-secondary); border-radius:999px;
  padding:.12rem .7rem; background: var(--color-secondary-highlight);
}
.herb-card-source{ color: var(--color-secondary); font-weight:500; letter-spacing:.03em; }


/* ======================================================================
   VISUAL REFINEMENT LAYER v2 — 2026-08-14
   The award-winning pass: tactile texture, a confident type scale,
   choreographed motion, and the small tactile cues (image zoom, shimmer,
   botanical flourishes) that separate a competent dark theme from one that
   feels crafted. Built on top of the v1 layer; nothing removed.
   ====================================================================== */

/* ---- 1. TACTILE GRAIN --------------------------------------------- */
/* A whisper of paper grain over everything — the difference between "flat
   dark" and "printed apothecary page". Fixed, non-interactive, barely there. */
body::after{
  content:""; position:fixed; inset:0; z-index:9998; pointer-events:none;
  opacity:.035; mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- 2. TYPE SCALE + RHYTHM --------------------------------------- */
.brand .name{ font-size:1.18rem; letter-spacing:.2em; }
.dock-name{ font-size:1.1rem; letter-spacing:.12em; }
.msg.assistant{ font-size:1.02rem; line-height:1.7; }
.msg.assistant p:first-child{ font-size:1.06rem; }
.herb-card-name{ font-size:1.14rem; letter-spacing:.005em; }
.mono h3{ font-size:1.7rem !important; letter-spacing:.01em; }
.empty-state h3, .builder-empty h3{ font-size:1.4rem; letter-spacing:.01em; }
.section-label, .filter-group label, #builder-settings label,
#dosage-section label, #script-people label{ letter-spacing:.14em; }

/* ---- 3. CHOREOGRAPHED ENTRANCE ------------------------------------ */
@keyframes riseIn{ from{ opacity:0; transform:translateY(12px);} to{ opacity:1; transform:none;} }
@keyframes fadeIn{ from{ opacity:0;} to{ opacity:1;} }
.herb-card{ animation:riseIn .5s var(--ease) backwards; }
.herbs-grid .herb-card:nth-child(1){animation-delay:.02s}
.herbs-grid .herb-card:nth-child(2){animation-delay:.05s}
.herbs-grid .herb-card:nth-child(3){animation-delay:.08s}
.herbs-grid .herb-card:nth-child(4){animation-delay:.11s}
.herbs-grid .herb-card:nth-child(5){animation-delay:.14s}
.herbs-grid .herb-card:nth-child(6){animation-delay:.17s}
.herbs-grid .herb-card:nth-child(7){animation-delay:.20s}
.herbs-grid .herb-card:nth-child(8){animation-delay:.23s}
.herbs-grid .herb-card:nth-child(n+9){animation-delay:.26s}
.exchange{ animation:riseIn .45s var(--ease) backwards; }
.assist-option, .formulate-picks{ animation:fadeIn .4s var(--ease) backwards; }
@media (prefers-reduced-motion: reduce){
  *{ animation:none !important; }
}

/* ---- 4. CARD IMAGE HOVER-ZOOM ------------------------------------- */
.herb-card{ overflow:hidden; }
.herb-card-img{ transition:transform .5s var(--ease); will-change:transform; }
.herb-card:hover .herb-card-img{ transform:scale(1.06); }
/* a soft gradient scrim at the image foot so any caption/badges read */
.herb-card-body{ position:relative; }

/* ---- 5. LOADING SHIMMER ------------------------------------------- */
#browse-results > .hint,
#chat .msg.assistant > .hint{
  position:relative; overflow:hidden;
}
#browse-results > .hint::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(100deg, transparent 20%, rgba(200,164,94,.08) 50%, transparent 80%);
  transform:translateX(-100%); animation:shimmer 1.3s infinite;
}
@keyframes shimmer{ to{ transform:translateX(100%);} }

/* ---- 6. BOTANICAL DIVIDER ---------------------------------------- */
.or-divider::before, .or-divider::after{
  border-top:1px solid var(--color-divider);
}
.or-divider span{ color:var(--color-text-faint); }
.or-divider span::before{ content:"\2767  "; color:var(--accent); }  /* rotated floral heart bullet */
.or-divider span::after{ content:"  \2767"; color:var(--accent); }

/* ---- 7. TRADITION PILL — a small jewel --------------------------- */
.trad-pill{
  background:linear-gradient(180deg, rgba(107,143,113,.16), rgba(107,143,113,.06));
  box-shadow:0 1px 0 rgba(255,255,255,.03), inset 0 0 0 1px rgba(107,143,113,.25);
  border:0;
}
.herb-card-source{ display:flex; align-items:center; gap:.35rem; }
.herb-card-source::before{
  content:""; width:.4rem; height:.4rem; border-radius:50%;
  background:var(--color-secondary); flex:none; opacity:.8;
}

/* ---- 8. QUESTION BLOCK — a spoken prompt -------------------------- */
.msg.user{
  position:relative; font-family:var(--serif); font-size:1.15rem;
  font-weight:600; letter-spacing:.005em; padding-left:1.1rem;
}
.msg.user::before{
  content:"\201C"; position:absolute; left:.15rem; top:-.15rem;
  font-family:var(--serif); font-size:1.6rem; color:var(--accent); opacity:.5;
}

/* ---- 9. HEADER HAIRLINE ------------------------------------------ */
header{ border-bottom:1px solid var(--accent);
  box-shadow:0 1px 0 rgba(200,164,94,.25), 0 12px 34px -22px rgba(0,0,0,.9); }
.brand .sub{ font-style:italic; font-family:var(--serif); font-size:.92rem;
  color:var(--color-text-faint); letter-spacing:.01em; }

/* ---- 10. EMPTY STATE — a pressed leaf ---------------------------- */
.empty-state{ padding:4rem 1rem; }
.empty-state::before{
  content:""; display:block; width:56px; height:56px; margin:0 auto 1rem;
  background:var(--accent); opacity:.25;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='M32 8c-8 4-20 16-20 32 8-4 16-12 20-24 4 12 12 20 20 24C52 24 40 12 32 8z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='M32 8c-8 4-20 16-20 32 8-4 16-12 20-24 4 12 12 20 20 24C52 24 40 12 32 8z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* ---- 11. SCRIPT NAME — a confident serif ------------------------- */
.formula-name{ font-size:2.1rem; letter-spacing:.01em; }

/* ---- 12. REFINED SCROLL FEEL ------------------------------------- */
html{ scroll-behavior:smooth; }
#chat, #browse-main, #browse-results, .fmode{ scrollbar-width:thin; }

/* ===== CONVERSATION HISTORY PANEL (2026-08-16 review) ================= */
#dock-body{ position: relative; }
#history-panel{
  position:absolute; inset:0; z-index:20; display:flex; flex-direction:column;
  background:var(--panel, #0b110b); overflow:hidden;
}
#history-panel.hidden{ display:none; }
.history-head{
  display:flex; align-items:center; justify-content:space-between;
  padding:.65rem .95rem; border-bottom:1px solid var(--color-divider);
  font-family:var(--serif, serif); letter-spacing:.02em;
  color:var(--color-text-muted);
}
#history-close{
  background:none; border:0; color:var(--color-text-muted);
  font-size:1.25rem; line-height:1; cursor:pointer; padding:0 .2rem;
}
#history-close:hover{ color:var(--accent); }
#history-list{ overflow:auto; padding:.6rem; }
.history-item{
  display:flex; flex-direction:column; align-items:flex-start; gap:.15rem;
  width:100%; text-align:left; cursor:pointer; margin:0 0 .45rem;
  background:rgba(255,255,255,.02); border:1px solid var(--color-divider);
  border-radius:10px; padding:.6rem .75rem;
  transition:border-color .15s, transform .12s;
}
.history-item:hover{ border-color:var(--accent); transform:translateY(-1px); }
.history-title{ font-weight:600; color:var(--color-text); line-height:1.3; }
.history-meta{ font-size:.76rem; color:var(--color-text-faint); letter-spacing:.02em; }
#chat-history, #chat-new{ font-size:.82rem; }
.add-fix{ margin-top:.5rem; }
.fix-btn{
  background:var(--gold-grad, #c8a45e); color:var(--on-accent, #1a1206);
  border:0; border-radius:8px; padding:.4rem .8rem; font-weight:600;
  cursor:pointer;
}
.fix-btn:hover{ filter:brightness(1.06); }

/* ===== FORMULARY: independent column scroll (2026-08-16 review) =========
   The pane itself must not scroll; the list (left) and the detail (right)
   each scroll on their own. #fmode-sources was display:block, so .split had
   no bounded height and the whole pane scrolled as one. */
#fmode-sources.active{ display:flex; flex-direction:column; overflow:hidden; }
#fmode-sources #formula-filters{ flex:0 0 auto; }
#fmode-sources .split{ flex:1 1 auto; min-height:0; }
#formula-list, #formula-view{ overflow-y:auto; min-height:0; }
.q-none{ color:var(--color-text-faint, #8a988a); font-style:italic; }

/* Common names on the browse card (2026-08-17 review) */
.herb-card-common{
  font-size:.8rem; color:var(--color-text-muted); margin-top:.1rem;
  line-height:1.35;
}
/* ======================================================================
   UI v3 — INSTRUMENT GRADE (2026-08-17)
   Research-driven elevation: a real 4-level surface system, a tokenized
   motion language, editorial type finishing, apothecary-label framing,
   clinical table discipline, and accessibility as craft. Appended last so
   it wins on source order; nothing above is removed.
   ====================================================================== */

/* ---- 0. TOKENS ----------------------------------------------------- */
:root{
  /* four green-tinted surfaces, each a step lighter — elevation = light */
  --s0:#0b110b; --s1:#111a12; --s2:#18241a; --s3:#1f2d21;
  /* ink scale — warm, WCAG-safe on every surface it sits on */
  --ink-hi:#e8e4d8; --ink-mid:#a8a599; --ink-low:#7d8a7d;
  /* the only red in the instrument — it always means danger */
  --danger:#c96a5a;
  /* motion */
  --t-fast:120ms; --t-med:200ms; --t-slow:320ms;
  --eo:cubic-bezier(.22,1,.36,1);
  --eio:cubic-bezier(.65,0,.35,1);
  --spring:var(--eo); --spring-t:300ms;
  /* fluid display scale */
  --disp-lg:clamp(1.9rem, 1.4rem + 1.6vw, 2.7rem);
  --disp:clamp(1.45rem, 1.2rem + .8vw, 1.85rem);
}
@supports (animation-timing-function: linear(0,1)){
  :root{
    --spring:linear(0,.0087 .96%,.0339 1.93%,.1288 3.89%,.2712 5.9%,.4406 7.94%,
      .6142 10%,.776 12.1%,.9127 14.24%,1.019 16.42%,1.0954 18.66%,1.1424 20.98%,
      1.1633 23.4%,1.1618 26%,1.1194 31.7%,1.0655 38.28%,1.0247 45.15%,
      1.0006 52.79%,.9903 61.62%,.9932 74.4%,1);
    --spring-t:520ms;
  }
}

/* ---- 1. CANVAS: vignette + calmer glows ---------------------------- */
body::before{
  content:""; position:fixed; inset:0; z-index:9997; pointer-events:none;
  background:radial-gradient(120% 92% at 50% 0%, transparent 62%,
    rgba(0,0,0,.32) 100%);
}
::selection{ background:rgba(200,164,94,.32); color:var(--ink-hi); }

/* ---- 2. FOCUS RING — two-tone, survives images --------------------- */
:focus-visible{
  outline:2px solid var(--accent); outline-offset:2px;
  box-shadow:0 0 0 5px rgba(11,17,11,.9);
}

/* ---- 3. PRESS STATES + HOVER ECONOMY ------------------------------- */
button, .chip, .example, .assist-option, nav#tabs button{
  transition: color var(--t-fast) var(--eo), background-color var(--t-fast) var(--eo),
    border-color var(--t-fast) var(--eo), box-shadow var(--t-fast) var(--eo),
    transform var(--t-fast) var(--eo), filter var(--t-fast) var(--eo);
}
button:active, .chip:active, .example:active{ transform:scale(.97); }
.herb-card:active{ transform:translateY(-2px) scale(.99); }
/* daily-use surfaces get colour shifts, not lifts */
nav#tabs button:hover{ transform:none; }
.rx-row:hover td{ background:var(--s2); }

/* ---- 4. HEADER + NAV ----------------------------------------------- */
header{ background:linear-gradient(180deg, var(--s1), var(--s0)); }
nav#tabs button{ background:rgba(255,255,255,.02); }
nav#tabs button.active{
  box-shadow:0 4px 16px -4px rgba(200,164,94,.5),
    inset 0 1px 0 rgba(255,255,255,.25);
}

/* the standing safety note — always present, now composed, not shouted */
.disclaimer{
  background:var(--s1);
  border-bottom:1px solid rgba(200,164,94,.22);
  color:var(--ink-mid);
  font-size:.8rem; letter-spacing:.015em;
  padding:.4rem 1.4rem;
}
.disclaimer .disclaimer-mark{ color:var(--accent); opacity:.85; }

/* ---- 5. HERBERT DOCK — no more name/button collisions --------------- */
#dock-head{ gap:.55rem; flex-wrap:nowrap; }
#dock-head .dock-id{ flex:0 1 auto; min-width:0; overflow:hidden; }
.dock-name{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#chat-history, #chat-new, #chat-save, #chat-clear{
  flex:none; font-size:.72rem; letter-spacing:.08em; text-transform:uppercase;
  background:rgba(255,255,255,.03); border:1px solid var(--color-divider);
  color:var(--ink-mid); border-radius:999px; padding:.28rem .7rem;
}
#chat-history:hover, #chat-new:hover, #chat-save:hover, #chat-clear:hover{
  color:var(--accent); border-color:var(--accent);
}
/* when the dock is narrow, the name yields before the controls do */
body[data-mode="browse"] .dock-name{ max-width:9ch; }
@media (max-width:1180px){
  body[data-mode="browse"] .dock-id{ display:none; }
}

/* ---- 6. CONSULT: an editorial reading room -------------------------- */
.msg.assistant .gen{ max-width:66ch; }
.msg.assistant .gen p{ line-height:1.68; }
.msg.assistant .gen{ text-wrap:pretty; }
.msg.user{ text-wrap:balance; }
/* example prompts: quiet solid chips, not dashed drafts */
.example{
  border:1px solid var(--color-divider) !important;
  border-style:solid !important;
  background:var(--s1); color:var(--ink-mid); border-radius:999px;
}
.example:hover{ color:var(--accent); border-color:var(--accent) !important;
  background:var(--s2); }
.examples-head span{
  font-size:.6875rem; font-weight:600; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-low);
}
/* the custom-formulate CTA settles in with the spring */
.custom-formulate .assist-option-custom{
  animation:ctaIn var(--spring-t) var(--spring) backwards;
}
@keyframes ctaIn{ from{ opacity:0; transform:scale(.96) translateY(6px);} }

/* ---- 7. TOAST — above the ask bar, never on it ---------------------- */
#toast{
  bottom:5.2rem !important;
  background:var(--s3); border:1px solid rgba(200,164,94,.3);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),
    0 18px 44px -12px rgba(0,0,0,.6);
  border-radius:12px;
}
#toast.show{ animation:toastIn var(--spring-t) var(--spring); }
@keyframes toastIn{ from{ opacity:0; transform:translate(-50%, 8px) scale(.97);} }

/* ---- 8. BROWSE: cards as specimen labels ---------------------------- */
.filter-panel{
  background:var(--s1);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04);
}
.filter-panel label, .filter-group label{
  font-size:.6875rem; letter-spacing:.14em; color:var(--ink-low);
}
.herb-card{
  background:var(--s1); border-color:rgba(255,255,255,.06);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04);
}
.herb-card:hover, .herb-card:focus-visible{
  background:var(--s2); transform:translateY(-3px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06),
    0 18px 40px -18px rgba(0,0,0,.7), 0 0 20px -8px rgba(200,164,94,.25);
}
/* unified plate treatment: warm grade + foot vignette so mixed photos cohere */
.herb-card-img{
  filter:sepia(.12) saturate(.92) contrast(1.04);
  transition:transform .5s var(--eo), filter .4s var(--eo);
}
.herb-card:hover .herb-card-img{ transform:scale(1.04); filter:sepia(.06) saturate(1) contrast(1.05); }
.herb-card-body{ position:relative; }
.herb-card-body::before{
  content:""; position:absolute; left:0; right:0; top:-26px; height:26px;
  background:linear-gradient(180deg, transparent, rgba(11,17,11,.5));
  pointer-events:none;
}
/* corner ticks — quiet by default, ceremonial on attention */
.herb-card::after{
  content:""; position:absolute; inset:6px; pointer-events:none; opacity:0;
  transition:opacity var(--t-med) var(--eo);
  background:
    linear-gradient(var(--accent), var(--accent)) left top / 8px 1px,
    linear-gradient(var(--accent), var(--accent)) left top / 1px 8px,
    linear-gradient(var(--accent), var(--accent)) right top / 8px 1px,
    linear-gradient(var(--accent), var(--accent)) right top / 1px 8px,
    linear-gradient(var(--accent), var(--accent)) left bottom / 8px 1px,
    linear-gradient(var(--accent), var(--accent)) left bottom / 1px 8px,
    linear-gradient(var(--accent), var(--accent)) right bottom / 8px 1px,
    linear-gradient(var(--accent), var(--accent)) right bottom / 1px 8px;
  background-repeat:no-repeat;
}
.herb-card:hover::after, .herb-card:focus-visible::after{ opacity:.45; }
.herb-card-common{ color:var(--ink-mid); }
.herb-card-latin{ color:var(--ink-mid); }
/* badge discipline: actions neutral, parts quieter, safety reserved */
.badge-action{ background:var(--s2); border:1px solid rgba(255,255,255,.07);
  color:var(--ink-mid); }
.badge-part{ background:transparent; border:1px solid rgba(107,143,113,.4);
  color:var(--color-secondary, #8fae95); }
.safety-icon.red{ color:var(--danger); border-color:var(--danger); }
.herb-card-placeholder{ background:radial-gradient(circle at 50% 38%, var(--s2), var(--s1)); }

/* ---- 9. FORMULATE: the workbench ------------------------------------ */
/* sub-tabs become a quiet segmented control, consistent with the pill nav */
#formulate-tabs{ gap:.35rem; padding:.5rem 1rem 0; border-bottom:1px solid var(--color-divider); }
#formulate-tabs button{
  border:1px solid transparent; border-radius:999px 999px 0 0;
  background:transparent; color:var(--ink-mid);
  padding:.45rem 1.1rem; letter-spacing:.02em;
}
#formulate-tabs button:hover{ color:var(--accent); }
#formulate-tabs button.active{
  background:var(--s1); color:var(--ink-hi);
  border-color:var(--color-divider); border-bottom-color:var(--s1);
  box-shadow:inset 0 2px 0 var(--accent);
}
/* prep tabs: one row of even pills */
#prep-tabs button{ border-radius:999px; padding:.5rem 1.2rem; }
/* the script card carries the apothecary label frame */
#script-card{
  background:var(--s1); border:1px solid rgba(200,164,94,.26);
  border-radius:14px; position:relative;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
}
#script-card::before{
  content:""; position:absolute; inset:5px; pointer-events:none;
  border:1px solid rgba(200,164,94,.12); border-radius:10px;
}
/* builder table: clinical spec — hairlines, tabular numerals, calm header */
.rx-table th{
  font:600 .6875rem/1 "DM Sans", sans-serif; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-low);
  background:transparent; border-bottom:1px solid rgba(255,255,255,.09);
  padding:.55rem .6rem;
}
.rx-table td{
  border-bottom:1px solid rgba(255,255,255,.05);
  padding:.35rem .6rem; height:40px;
  transition:background-color var(--t-fast) var(--eo);
}
.rx-table input.num{
  font-variant-numeric:tabular-nums lining-nums; text-align:right;
}
.rx-table td:nth-child(2), .rx-table td:nth-child(3), .rx-table td:nth-child(4){
  text-align:right; font-variant-numeric:tabular-nums lining-nums;
}
.rx-remove{ opacity:.4; transition:opacity var(--t-fast) var(--eo),
  color var(--t-fast) var(--eo); }
.rx-row:hover .rx-remove{ opacity:1; color:var(--danger); }
/* safety panel: tiered, the red reserved */
.safety-block, #builder-safety > div{ border-radius:12px; }
#builder-safety .danger, .safety-danger{ border-left:3px solid var(--danger); }

/* ---- 10. FORMULARY: reading the record ------------------------------ */
#formula-list .result-card{
  background:var(--s1); border:1px solid rgba(255,255,255,.06);
  border-radius:10px;
  transition:background-color var(--t-fast) var(--eo),
    border-color var(--t-fast) var(--eo);
}
#formula-list .result-card:hover{ background:var(--s2); border-color:rgba(200,164,94,.35); }
/* the bright header row goes calm */
table.ingredients th, table.doses th{
  background:var(--s2) !important; color:var(--ink-low) !important;
  font:600 .6875rem/1 "DM Sans", sans-serif; letter-spacing:.12em;
  text-transform:uppercase; border-bottom:1px solid rgba(255,255,255,.09);
  padding:.55rem .6rem;
}
table.ingredients td, table.doses td{
  border-bottom:1px solid rgba(255,255,255,.05); padding:.45rem .6rem;
}
table.ingredients tr:hover td{ background:var(--s2); }
table.ingredients td:nth-child(4), table.ingredients td:nth-child(5){
  text-align:right; font-variant-numeric:tabular-nums lining-nums;
}
.q-none{ color:var(--ink-low); }
.amounts-warning{
  background:rgba(200,164,94,.07); border:1px solid rgba(200,164,94,.28);
  border-left-width:3px; color:var(--ink-mid); border-radius:8px;
}
#formula-view h2{ font-size:var(--disp); font-weight:600; text-wrap:balance; }

/* ---- 11. MODAL: lifted on surface-3 with the label frame ------------ */
#modal-card{
  background:var(--s3); border:1px solid rgba(200,164,94,.3);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),
    0 24px 60px -12px rgba(0,0,0,.6);
  animation:modalIn var(--spring-t) var(--spring);
}
@keyframes modalIn{ from{ opacity:0; transform:scale(.96) translateY(8px);} }
#modal-card .mono h3{ font-size:var(--disp); font-weight:600; text-wrap:balance; }
#modal-card .mono{ line-height:1.65; }
#modal-card .mono blockquote{ max-width:66ch; }
.safety-chip{
  display:inline-block; font:600 .6875rem/1.5 "DM Sans", sans-serif;
  letter-spacing:.06em; text-transform:uppercase;
  border:1px solid var(--color-secondary); color:var(--color-secondary);
  background:rgba(107,143,113,.1); border-radius:999px; padding:2px 9px;
  margin:2px 4px 2px 0;
}
.safety-chip.warn{ border-color:var(--accent); color:var(--accent);
  background:rgba(200,164,94,.09); }
.safety-chip.ok{ border-color:var(--color-secondary); }

/* ---- 12. EMPTY STATES: the instrument speaks ------------------------ */
#browse-results > .hint, #library-list > .hint, #formula-view > .hint,
.builder-empty, .empty-state p{
  font-family:var(--serif, "Cormorant Garamond", serif);
  font-style:italic; font-size:1.08rem; color:var(--ink-mid);
}

/* ---- 13. SECTION LABELS: gradient-rule ends (engraved plate) -------- */
.section-label{
  display:flex; align-items:center; gap:.75rem;
  font-size:.6875rem; letter-spacing:.14em; color:var(--ink-low);
}
.section-label::after{
  content:""; flex:1; height:1px;
  background:linear-gradient(90deg, rgba(200,164,94,.35), transparent);
}

/* ---- 14. VIEW TRANSITIONS ------------------------------------------- */
::view-transition-old(root){ animation:160ms var(--eo) both vtOut; }
::view-transition-new(root){ animation:220ms var(--eo) 40ms both vtIn; }
@keyframes vtOut{ to{ opacity:0; transform:translateY(-4px);} }
@keyframes vtIn{ from{ opacity:0; transform:translateY(6px);} }

/* ---- 15. ENTRANCES: cap the cascade --------------------------------- */
.herbs-grid .herb-card:nth-child(n+9){ animation-delay:.24s; }
.herb-card{ animation-duration:.4s; }

/* ---- 16. REDUCED MOTION --------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  #toast.show, #modal-card, .custom-formulate .assist-option-custom{
    animation:none !important;
  }
  .herb-card:hover .herb-card-img{ transform:none; }
}

/* ---- 17. NARROW WIDTHS ---------------------------------------------- */
@media (max-width:1100px){
  .msg.assistant .gen{ max-width:100%; }
}

/* ======================================================================
   v3.1 — FORMULATE COMPOSITION + GOLD TOAST (2026-08-17b review)
   ====================================================================== */

/* 1. TOAST: gold ground, black lettering (was too dark to read) */
#toast{
  background:linear-gradient(180deg, #dcbc7d, #c8a45e) !important;
  border:1px solid #8a6f3a !important;
  color:#1a1408 !important;
  box-shadow:0 18px 44px -12px rgba(0,0,0,.55);
  font-weight:600;
}
#toast button, #toast [data-toast-act]{
  background:rgba(0,0,0,.14); color:#1a1408;
  border:1px solid rgba(0,0,0,.35); border-radius:8px; font-weight:600;
}
#toast button:hover{ background:rgba(0,0,0,.24); }

/* 2. THE SCRIPT TITLE is an editorial heading, never a boxed field.
   (The generic input rule out-specifies the class rule, so these carry
   !important deliberately.) */
#script-card .formula-name, #script-card .formula-for{
  background:transparent !important; border:0 !important;
  border-bottom:1px dotted rgba(200,164,94,.4) !important;
  border-radius:0 !important; box-shadow:none !important;
  padding:.1rem 0 .25rem !important;
}
.formula-name{
  font-size:var(--disp) !important; font-weight:500 !important;
  color:var(--ink-hi) !important; letter-spacing:-.01em;
}
.formula-name::placeholder{ color:rgba(232,228,216,.4); }
.formula-for{
  font-family:var(--serif, "Cormorant Garamond", serif) !important;
  font-style:italic; font-size:1.05rem !important; color:var(--ink-mid) !important;
}
#script-card .formula-name:focus, #script-card .formula-for:focus{
  border-bottom:1px solid var(--accent) !important;
  outline:none !important; box-shadow:none !important;
}
.script-head{ align-items:flex-end; gap:1rem; }
.script-title{ gap:.35rem; }

/* 3. SAVE is the primary act; the rest are quiet */
#builder-save{
  background:var(--gold-grad, linear-gradient(180deg,#d9b877,#c8a45e));
  color:#1a1408; border:0; font-weight:600; letter-spacing:.03em;
  box-shadow:0 2px 12px -4px rgba(200,164,94,.5);
}
#builder-save:hover{ filter:brightness(1.06); transform:translateY(-1px); }
#builder-print, #builder-pdf, #builder-clear{
  background:rgba(255,255,255,.03); color:var(--ink-mid);
  border:1px solid var(--color-divider);
}
#builder-print:hover, #builder-pdf:hover{ color:var(--accent); border-color:var(--accent); }
#builder-clear:hover{ color:var(--danger); border-color:var(--danger); }

/* 4. ONE calm input family — assist bar and herb search match */
#assist-bar input, #herb-search{
  background:var(--s2) !important;
  border:1px solid rgba(200,164,94,.28) !important;
  box-shadow:none !important; border-radius:10px !important;
  padding:.6rem .9rem !important;
}
#assist-bar input:focus, #herb-search:focus{
  border-color:var(--accent) !important;
  box-shadow:0 0 0 3px rgba(200,164,94,.18) !important;
}

/* 5. Number cells: consistent compact boxes, tabular digits */
.rx-table input.num{
  background:var(--s2); border:1px solid rgba(255,255,255,.08);
  border-radius:8px; padding:.3rem .5rem; width:5.2ch; min-width:4.5ch;
}
.rx-table input.num:focus{
  border-color:var(--accent); box-shadow:0 0 0 3px rgba(200,164,94,.15);
}

/* 6. Sub-tab active state without the pale corner artifact */
#formulate-tabs button.active{
  background:var(--s1); border-bottom-color:transparent;
}

/* v3.2 — numbered herb lists in Herbert's answers (2026-08-18 review) */
.msg.assistant .gen ol{
  margin:.5rem 0 .5rem 1.4rem; padding:0;
  display:flex; flex-direction:column; gap:.45rem;
}
.msg.assistant .gen ol li{ line-height:1.6; padding-left:.25rem; }
.msg.assistant .gen ol li::marker{
  color:var(--accent); font-weight:600;
  font-variant-numeric:tabular-nums;
}
.msg.assistant .gen strong{ color:var(--ink-hi); font-weight:600; }

/* ---- streaming consult (2026-08-19): live typing view ---- */
.gen-live{white-space:pre-wrap;line-height:1.62;color:var(--ink-hi,#e8e4d8)}
.gen-live::after{content:"";display:inline-block;width:.55em;height:1.05em;
  margin-left:2px;vertical-align:text-bottom;background:var(--gold,#c8a45e);
  border-radius:1px;animation:bh-caret 1s steps(1) infinite}
@keyframes bh-caret{0%,55%{opacity:1}56%,100%{opacity:0}}
@media (prefers-reduced-motion: reduce){.gen-live::after{animation:none}}

/* ---- museum plate: the monograph hero (2026-08-19) ---- */
.mono-plate{margin:0 0 16px;padding:10px 10px 0;background:
  linear-gradient(180deg,#141d15,#101710);border:1px solid #2a3a2c;
  border-radius:10px;box-shadow:inset 0 0 0 1px rgba(220,188,125,.07),
  0 10px 30px rgba(0,0,0,.35)}
.mono-plate img,.mono-plate canvas{display:block;width:100%;height:auto;
  max-height:340px;object-fit:cover;border-radius:6px;
  filter:saturate(.92) contrast(1.02)}
.mono-plate figcaption{display:flex;flex-wrap:wrap;align-items:baseline;
  gap:4px 14px;padding:9px 6px 10px}
.mono-plate-latin{font-style:italic;font-family:Georgia,'Times New Roman',serif;
  font-size:1.02rem;color:var(--ink-hi,#e8e4d8);letter-spacing:.01em}
.mono-plate-common{font-size:.82rem;color:var(--ink-mid,#b9b4a4);
  text-transform:none;letter-spacing:.02em}
@media (max-width:640px){.mono-plate img,.mono-plate canvas{max-height:220px}}

/* ---- botanical loader: a sprig unfurls while Herbert thinks ---- */
.bh-loader{display:flex;align-items:center;gap:12px;color:#8faf7e;
  padding:4px 0 2px}
.bh-loader .bh-stem{stroke-dasharray:130;stroke-dashoffset:130;
  animation:bh-grow 2.6s cubic-bezier(.22,1,.36,1) infinite}
.bh-loader .bh-leaf{opacity:0;transform-box:fill-box;
  transform-origin:bottom left;animation:bh-unfurl 2.6s ease infinite}
.bh-loader .bh-bud{transform-box:fill-box;transform-origin:center}
.bh-loader .l1{animation-delay:.55s}
.bh-loader .l2{animation-delay:.95s}
.bh-loader .l3{animation-delay:1.35s}
.bh-loader .bh-bud{opacity:0;animation:bh-bloom 2.6s ease infinite;
  animation-delay:1.7s;fill:#dcbc7d}
.bh-loader-t{font-size:.82rem;color:var(--ink-low,#8a8574);
  letter-spacing:.04em}
@keyframes bh-grow{0%{stroke-dashoffset:130}55%,88%{stroke-dashoffset:0}
  100%{stroke-dashoffset:0;opacity:0}}
@keyframes bh-unfurl{0%{opacity:0;transform:scale(.4)}
  18%{opacity:.9;transform:scale(1)}88%{opacity:.9}100%{opacity:0}}
@keyframes bh-bloom{0%{opacity:0;transform:scale(.3)}
  18%{opacity:1;transform:scale(1)}88%{opacity:1}100%{opacity:0}}
@media (prefers-reduced-motion: reduce){
  .bh-loader .bh-stem{animation:none;stroke-dashoffset:0}
  .bh-loader .bh-leaf,.bh-loader .bh-bud{animation:none;opacity:.9}}

/* ---- sound toggle ---- */
.sound-toggle{background:none;border:1px solid #2a3a2c;color:var(--ink-low,#8a8574);
  font-size:.68rem;letter-spacing:.08em;text-transform:uppercase;
  padding:4px 10px;border-radius:99px;cursor:pointer;
  transition:color .2s,border-color .2s}
.sound-toggle:hover{color:var(--ink-mid,#b9b4a4);border-color:#3a4f3c}
.sound-toggle.on{color:#dcbc7d;border-color:#5a4f33}
