/* ============================================================
   LFFO — Library
   A reading room: quiet surfaces, one gold accent per card, and
   motion that only ever runs on arrival or on intent.
   ============================================================ */

.lib-hero{padding-block:clamp(56px,8vw,96px)}
.lib-section{padding-top:clamp(34px,4.5vw,52px)}

/* ---------- Console — navy "engraved keyline" panel ----------
   Sharp square edges (no chamfer, no radius). A deep navy surface framed by a
   fine gold rule with a second gold hairline just inside it (::before) — the
   line-within-a-line of engraved stationery, on navy. A shadow holds its edge
   against the white results area. */
/* Cream-white console — a soft, smooth panel on the white page, held by a warm
   hairline and a quiet shadow. No navy, no gold keyline. */
.lib-console{
  background:linear-gradient(180deg,#fffdf9,var(--surface-2));
  border:1px solid var(--line);border-radius:0;
  padding:16px clamp(18px,2.2vw,24px);
  position:sticky;top:calc(var(--header-h,74px) + 10px);z-index:30;
  box-shadow:0 10px 24px -18px rgba(15,32,56,.20),0 1px 3px rgba(15,32,56,.05),inset 0 1px 0 rgba(255,255,255,.7);
  transition:top .42s var(--ease-lux),padding .3s var(--ease-lux),box-shadow .3s var(--ease-lux);
}
@media (max-width:900px){
  .lib-console{top:calc(var(--header-h,74px) + 6px)}
}
.lib-console::before{content:none}
.lib-console > *{position:relative;z-index:1}


/* ═══════════════════════════════════════════════════════════════════════
   THE FOLD — the console follows, and opens on approach
   ═══════════════════════════════════════════════════════════════════════
   The console rides down the page with the reader. Once it pins it folds to
   a slim bar carrying the essentials — how many results, which filters are
   applied, the sort and the clear — and the search and facets fold away.
   Moving the pointer onto it opens it again; moving away closes it.

   There is NO handle. That is the whole point of this version. The previous
   build had a "Filters" button sitting inside the console, and the CSS also
   opened the panel on :hover and :focus-within — so pressing the button, an
   act which necessarily satisfies :focus-within, opened the panel no matter
   what the click had toggled, and pressing it again changed a class nobody
   could see while hover held the panel open regardless. Three sources of
   truth for one piece of state, and the control read as dead. Removing the
   button removes the conflict: hover is now the only thing that opens it, so
   the state and the gesture can never disagree.

   Touch has no hover, so on a touch device tapping the folded console itself
   opens it and tapping anywhere outside closes it (.touch-open, set in JS).
   The target is the whole bar rather than a control inside it, which is why
   it cannot repeat the old failure.

   The fold is a grid 1fr→0fr height transition; the inner panel also lifts a
   few pixels and fades, so it reads as a panel arriving rather than a box
   being squashed. */
.lib-panel{
  display:grid;grid-template-rows:1fr;
  transition:grid-template-rows .34s var(--ease-lux),opacity .22s var(--ease);
}
.lib-panel-inner{
  overflow:hidden;min-height:0;
  transform:translateY(0);opacity:1;
  transition:transform .34s var(--ease-lux),opacity .24s var(--ease);
}

/* FOLDED — the default the moment it pins */
#libConsole.pinned{padding-top:10px;padding-bottom:10px;box-shadow:0 8px 20px -12px rgba(15,32,56,.22),0 1px 3px rgba(15,32,56,.05)}
#libConsole.pinned .lib-panel{grid-template-rows:0fr;opacity:0}
#libConsole.pinned .lib-panel-inner{transform:translateY(-6px);opacity:0}
#libConsole.pinned .lib-bar{
  margin-top:0;padding-top:0;border-top-color:transparent;
  transition:margin-top .3s var(--ease-lux),padding-top .3s var(--ease-lux),border-color .22s var(--ease);
}

/* OPEN — hover, keyboard focus, or a tap on touch. One rule, three triggers,
   and all three mean the same thing: the reader is addressing the console. */
#libConsole.pinned:hover,
#libConsole.pinned:focus-within,
#libConsole.pinned.touch-open{
  padding-top:clamp(14px,2vw,22px);padding-bottom:clamp(14px,2vw,22px);
  box-shadow:0 14px 30px -16px rgba(15,32,56,.26),0 2px 5px rgba(15,32,56,.06);
}
#libConsole.pinned:hover .lib-panel,
#libConsole.pinned:focus-within .lib-panel,
#libConsole.pinned.touch-open .lib-panel{grid-template-rows:1fr;opacity:1}
#libConsole.pinned:hover .lib-panel-inner,
#libConsole.pinned:focus-within .lib-panel-inner,
#libConsole.pinned.touch-open .lib-panel-inner{transform:translateY(0);opacity:1}
#libConsole.pinned:hover .lib-bar,
#libConsole.pinned:focus-within .lib-bar,
#libConsole.pinned.touch-open .lib-bar{margin-top:3px;padding-top:12px;border-top-color:rgba(201,163,78,.22)}

/* While folded, a gold hairline down the leading edge says the set on screen
   is filtered — the one piece of state the slim bar must never lose. */
#libConsole::after{
  content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:var(--gold-bright);
  transform:scaleX(0);transform-origin:left center;
  transition:transform .3s var(--ease-lux);
  pointer-events:none;
}
#libConsole.has-filters::after{transform:scaleX(1)}

/* A folded console that cannot be opened is a trap, so on a viewport too short
   to show the open panel comfortably it simply never pins. */
@media (max-height:520px){
  .lib-console{position:relative;top:auto}
  #libConsole.pinned .lib-panel{grid-template-rows:1fr;opacity:1}
  #libConsole.pinned .lib-panel-inner{transform:none;opacity:1}
}
@media (prefers-reduced-motion:reduce){
  .lib-panel,.lib-panel-inner,.lib-console,#libConsole::after{transition:none}
  #libConsole.pinned .lib-panel-inner{transform:none}
}

/* ═══ MOBILE — no scroll-fold; the console is a button-summoned bottom sheet ═══
   The scroll-driven fold stranded readers (a tap that closed it could not
   reopen it, and on Library it sat over the results). On narrow viewports the
   console instead sits inline and fully open; once the reader scrolls past it a
   floating "Filters" button (js) summons it back as a bottom sheet with an
   explicit backdrop and handle to dismiss. Nothing about it depends on scroll
   position, so it can never get stuck. */
@media (max-width:760px){
  .lib-console{position:static;top:auto;padding:13px 15px;
    box-shadow:0 6px 18px -10px rgba(15,32,56,.28),inset 0 1px 0 rgba(255,255,255,.7)}
  #libConsole.pinned{padding:13px 15px;box-shadow:0 6px 18px -10px rgba(15,32,56,.28)}
  #libConsole.pinned .lib-panel{grid-template-rows:1fr;opacity:1}
  #libConsole.pinned .lib-panel-inner{transform:none;opacity:1}
  #libConsole.pinned .lib-bar{margin-top:12px;padding-top:12px;border-top-color:var(--line)}
  #libConsole::after{display:none}

  body.fc-sheet-open{overflow:hidden}
  body.fc-sheet-open #libConsole{
    position:fixed;left:0;right:0;bottom:0;top:auto;z-index:200;margin:0;
    max-height:82vh;overflow-y:auto;-webkit-overflow-scrolling:touch;
    border-radius:18px 18px 0 0;border-bottom:none;padding:8px 18px 22px;
    box-shadow:0 -14px 44px rgba(8,17,33,.34);
    animation:fcSheetUp .32s var(--ease-lux);
  }
}

.lib-search-wrap{position:relative;display:flex;align-items:center}
.lib-search-icon{
  position:absolute;left:16px;color:var(--gold);font-size:1.15rem;pointer-events:none;
  transition:transform .25s var(--ease);
}
.lib-search{
  width:100%;font-family:var(--sans);font-size:1rem;color:var(--ink);
  padding:.72em 1em .72em 3em;border:1px solid var(--line);border-radius:0;
  background:var(--surface-2);transition:border-color .22s var(--ease),background .22s var(--ease),box-shadow .22s var(--ease);
}
.lib-search::placeholder{color:var(--ink-soft);opacity:.75}
.lib-search:focus{
  outline:none;background:var(--surface);border-color:var(--gold);
  box-shadow:0 0 0 4px rgba(201,163,78,.14);
}
.lib-search:focus + .lib-search-icon,
.lib-search-wrap:focus-within .lib-search-icon{transform:scale(1.08)}
.lib-search::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}

/* ---------- Facets ────────────────────────────────────────────────────────
   Two tiers. Category is the primary index — each chip carries the same colour
   its cards use, so filtering and results read as one system. Format is the
   quieter refine tier beneath a hairline. Chips WRAP at every width; the old
   horizontal-scroll strip hid Guidance and 'Members only' off the right edge on
   a phone, which is exactly what read as broken. Nothing is ever clipped now. */
.lib-facets{margin-top:13px;display:flex;flex-direction:column}
.lib-facet-row{
  display:flex;align-items:baseline;gap:18px;
  padding-block:11px;
}
.lib-facet-format{border-top:1px solid var(--line)}
.lib-facet-label{
  flex:0 0 auto;width:74px;padding-top:.5em;
  font-size:.68rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft);
}
.lib-chiprow{display:flex;gap:9px;flex-wrap:wrap;min-width:0;flex:1}
.lib-chip{
  position:relative;overflow:hidden;
  display:inline-flex;align-items:center;gap:.5em;
  padding:.52em 1.02em;border-radius:0;border:1px solid var(--line);
  background:var(--surface);cursor:pointer;white-space:nowrap;
  font-size:.85rem;font-weight:600;color:var(--ink-soft);line-height:1;
  transition:color .2s var(--ease),border-color .2s var(--ease),background .2s var(--ease),
             box-shadow .2s var(--ease),transform .12s var(--ease);
}
.lib-chip > *{position:relative;z-index:1}
.lib-chip i{font-size:1.02em;opacity:.75}
.lib-chip:hover{border-color:var(--gold);color:var(--navy)}
.lib-chip:hover i{opacity:1}
.lib-chip:active{transform:scale(.97)}
.lib-chip:focus-visible{outline:none;border-color:var(--gold);box-shadow:0 0 0 3px rgba(201,163,78,.2)}
/* Selected = subtle gold, not a solid gold fill: a faint warm tint, a gold
   keyline and gold text. The category dot keeps its own colour. */
.lib-chip.active{
  background:rgba(201,163,78,.12);border-color:var(--gold);color:var(--gold-deep);
  box-shadow:inset 0 0 0 1px rgba(201,163,78,.38);
}
.lib-chip.active i{opacity:1}

/* Members-only control — marked by a quiet, static gold keyline (a fine inner
   hairline plus a subtle warm fill), not a moving glow. The looping perimeter
   light has been removed entirely. */
.lib-chip-mem{position:relative}
.lib-chip-mem:hover{border-color:var(--gold);box-shadow:inset 0 0 0 1px rgba(201,163,78,.35)}

/* Category colour dot: 8px of the card accent, carried into the filter. On the
   active (navy) chip it keeps its colour and gains a faint ring so it reads as
   lit rather than flattened into the fill. */
.lib-dot{display:inline-block;width:9px;height:9px;border-radius:50%;background:var(--d,var(--gold-deep));flex:0 0 auto}
.lib-dot-all{background:conic-gradient(var(--leaf-green),var(--leaf-sky),var(--leaf-amber),var(--leaf-blue),var(--leaf-orange),var(--leaf-red),var(--leaf-green))}
.lib-chip.active .lib-dot{box-shadow:0 0 0 2px rgba(255,255,255,.28)}

.lib-chip-mem{border-color:var(--gold);color:var(--brown);background:linear-gradient(180deg,#fdf9f0,#f8f0dd)}
.lib-chip-mem i{font-size:.95em;color:var(--gold);opacity:1}
.lib-chip-mem.active{background:rgba(201,163,78,.2);border-color:var(--gold);color:var(--gold-deep);box-shadow:inset 0 0 0 1px var(--gold)}
.lib-chip-mem.active i{color:var(--navy)}

/* ---------- Result bar ---------- */
.lib-bar{
  display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  margin-top:3px;padding-top:12px;border-top:1px solid var(--line);
}
.lib-count{font-size:.8rem;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--ink-soft)}
.lib-count #libCount{color:var(--brown);font-weight:700;font-size:1.05rem}
.lib-bar-right{display:flex;align-items:center;gap:12px;flex-wrap:wrap}

/* Cards-per-page — a compact 20 / 50 / 100 segmented control living in the bar.
   Minimal footprint, sharp edges, gold only on the active choice. */
.lib-perpage{display:inline-flex;align-items:center;gap:8px}
.lib-pp-label{font-size:.68rem;text-transform:uppercase;letter-spacing:.09em;color:var(--ink-soft);font-weight:700}
.lib-pp-seg{display:inline-flex;border:1px solid var(--line);background:var(--surface)}
.lib-pp-btn{
  padding:.4em .66em;min-width:2.3em;font-family:var(--sans);font-size:.78rem;font-weight:600;line-height:1;
  color:var(--ink-soft);background:transparent;border:0;border-left:1px solid var(--line);cursor:pointer;
  transition:background .18s var(--ease),color .18s var(--ease);
}
.lib-pp-btn:first-child{border-left:0}
.lib-pp-btn:hover{color:var(--navy)}
.lib-pp-btn.is-active{background:rgba(201,163,78,.14);color:var(--gold-deep);box-shadow:inset 0 0 0 1px rgba(201,163,78,.4)}
.lib-pp-btn:focus-visible{outline:none;box-shadow:inset 0 0 0 2px rgba(201,163,78,.5)}
@media (max-width:600px){ .lib-pp-label{display:none} }
.lib-clear{
  display:inline-flex;align-items:center;gap:6px;cursor:pointer;background:none;border:none;
  font-size:.82rem;font-weight:600;color:var(--brown);padding:.4em .2em;
  transition:color .2s var(--ease);
}
.lib-clear:hover{color:var(--navy)}

/* ============================================================
   LIGHT CONSOLE — controls on the cream-white surface. The base .lib-search /
   .lib-chip / .lib-facet-label already carry the light (dark-ink) styling;
   only the search field, hovers, the active chip and a few accents are set
   here. Gold is kept to the active state and the focus ring — a quiet accent,
   not the surface.
   ============================================================ */
/* Search field — white, so it lifts off the cream panel */
#libConsole .lib-search{
  background:#fff;border-color:var(--line);color:var(--ink);border-radius:var(--radius);
}
#libConsole .lib-search::placeholder{color:var(--ink-soft);opacity:.8}
#libConsole .lib-search-icon{color:var(--brown)}
#libConsole .lib-search:focus{
  background:#fff;border-color:var(--gold);
  box-shadow:0 0 0 4px rgba(201,163,78,.14);
}
/* ── Search motion ───────────────────────────────────────────────────────
   Taking focus is a small event and it should look like one. The gold nib of
   the magnifier steps left and brightens, and a gold rule draws across the
   full width of the field from the left — the same left-origin wipe the
   buttons use, so the whole interactive layer answers in one language. Both
   are scaleX/translate on existing boxes: no layout, no repaint. */
.lib-search-wrap::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;
  background:var(--gold-bright);border-radius:2px;
  transform:scaleX(0);transform-origin:left center;
  transition:transform .46s var(--ease-lux);
  pointer-events:none;
}
.lib-search-wrap:focus-within::after{transform:scaleX(1)}
#libConsole .lib-search-wrap:focus-within .lib-search-icon{
  transform:translateX(-2px) scale(1.12);color:#f0dca8;
}
@media (prefers-reduced-motion:reduce){
  .lib-search-wrap::after{transition:none}
  #libConsole .lib-search-wrap:focus-within .lib-search-icon{transform:none}
}
/* Tier labels + the hairline between Category and Format */
#libConsole .lib-facet-label{color:var(--ink-soft)}
#libConsole .lib-facet-format{border-top-color:var(--line)}
/* Chips — white, dark ink; gold only when active */
#libConsole .lib-chip{
  background:#fff;border-color:var(--line);color:var(--ink-soft);border-radius:0;
}
#libConsole .lib-chip i{color:var(--brown);opacity:.8}
#libConsole .lib-chip:hover{border-color:var(--gold);color:var(--navy)}
#libConsole .lib-chip:hover i{color:var(--brown);opacity:1}
#libConsole .lib-chip:focus-visible{border-color:var(--gold);box-shadow:0 0 0 3px rgba(201,163,78,.2)}
/* Selected = subtle gold, not a solid gold fill (see the base rule). */
#libConsole .lib-chip.active{
  background:rgba(201,163,78,.12);
  border-color:var(--gold);color:var(--gold-deep);
  box-shadow:inset 0 0 0 1px rgba(201,163,78,.38);
}
#libConsole .lib-chip.active i{color:var(--gold-deep)}
#libConsole .lib-chip.active .lib-dot{box-shadow:none}
/* Members-only chip: faint gold at rest, a touch more gold when on — still no
   solid fill. */
#libConsole .lib-chip-mem{
  background:var(--gold-soft);border-color:rgba(201,163,78,.5);color:var(--brown);
}
#libConsole .lib-chip-mem i{color:var(--brown)}
#libConsole .lib-chip-mem.active{
  background:rgba(201,163,78,.2);border-color:var(--gold);color:var(--gold-deep);
  box-shadow:inset 0 0 0 1px var(--gold);
}
#libConsole .lib-chip-mem.active i{color:var(--gold-deep)}
/* Result bar */
#libConsole .lib-bar{border-top-color:var(--line)}
#libConsole .lib-count{color:var(--ink-soft)}
#libConsole .lib-count #libCount{color:var(--brown)}
#libConsole .lib-clear{color:var(--brown)}
#libConsole .lib-clear:hover{color:var(--navy)}
/* Sort select */
#libConsole .kh-select{
  background:#fff;border-color:var(--line);color:var(--ink);border-radius:var(--radius);
}
#libConsole .kh-select:hover,#libConsole .kh-select:focus{border-color:var(--gold)}
#libConsole .kh-select-chev{color:var(--brown)}
/* A native <option> is drawn by the OS in a light menu, so it keeps dark
   text on white regardless of the page's ground. */
#libConsole .kh-select option{color:#12243f;background:#fff}

/* ---------- Grid ---------- */
.lib-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:22px;
  margin-top:30px;
}
@media (max-width:1000px){ .lib-grid{grid-template-columns:repeat(2,1fr)} }
@media (max-width:640px){ .lib-grid{grid-template-columns:1fr;gap:16px} }

.lib-card{
  position:relative;display:flex;flex-direction:column;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);
  padding:24px 22px 20px;overflow:hidden;cursor:pointer;
  box-shadow:var(--edge-light),0 1px 2px rgba(15,32,56,.04);
  opacity:0;transform:translateY(16px);
  transition:opacity .5s var(--ease),transform .5s var(--ease),
             border-color .28s var(--ease),box-shadow .28s var(--ease);
  transition-delay:calc(var(--i,0) * 38ms);
}
.lib-card.in{opacity:1;transform:none}

/* The travelling category glow has been removed to reduce visual noise. A card
   now carries only its quiet leading colour edge (.lib-edge) and a clean lift. */

/* ── The set leaves before the next one arrives ──────────────────────────
   Applied to the grid for 170ms when a filter, a sort or the search changes.
   The whole current set steps back and dims AS ONE — no stagger on the way
   out, because a staggered exit reads as the page struggling, while a single
   flat withdrawal reads as an answer being cleared. The incoming set then
   staggers in, so the two directions are legibly different gestures.
   transition-delay is zeroed here or each card would wait out its own entry
   delay before agreeing to leave. */
.lib-grid.lib-leaving .lib-card{
  opacity:0;transform:translateY(-8px) scale(.985);
  transition:opacity .17s var(--ease),transform .17s var(--ease);
  transition-delay:0s !important;
  pointer-events:none;
}
@media (prefers-reduced-motion:reduce){
  .lib-grid.lib-leaving .lib-card{transition:none;opacity:1;transform:none}
}
.lib-card:hover,.lib-card:focus-visible{
  border-color:var(--gold-soft);box-shadow:var(--edge-light),0 10px 24px -14px rgba(15,32,56,.24);outline:none;
  transform:translateY(-4px);transition-delay:0s;
}
.lib-card:focus-visible{border-color:var(--gold);box-shadow:0 0 0 3px rgba(201,163,78,.18)}

/* One quiet accent per card — a gold hairline down the leading edge, drawn on
   rather than filled, so a dense grid stays calm. Colour lives in the tree, not
   the chrome. */
.lib-edge{
  position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--c,var(--gold));
  transform:scaleY(0);transform-origin:top;
  transition:transform .45s var(--ease);
}
.lib-card.in .lib-edge{transform:scaleY(1);transition-delay:calc(var(--i,0) * 38ms + 120ms)}
.lib-card:hover .lib-edge{width:4px}

.lib-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px}
.lib-cat{
  font-size:.68rem;font-weight:700;letter-spacing:.11em;text-transform:uppercase;
  color:var(--c,var(--gold-deep));
}
.lib-type{
  width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:var(--surface-2);color:var(--brown);font-size:.95rem;flex:0 0 auto;
  transition:background .25s var(--ease),color .25s var(--ease);
}
.lib-card:hover .lib-type{background:var(--gold);color:#12243f}

.lib-title{
  font-family:var(--serif);font-size:1.18rem;line-height:1.3;color:var(--navy);
  margin-bottom:9px;font-weight:600;
}
.lib-sum{font-size:.9rem;line-height:1.6;color:var(--ink-soft);flex:1}

.lib-foot{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:16px;padding-top:13px;border-top:1px solid var(--line);
  font-size:.8rem;
}
.lib-lock{display:inline-flex;align-items:center;gap:5px;color:var(--brown);font-weight:600}
.lib-lock i{color:var(--gold)}
.lib-go{
  display:inline-flex;align-items:center;gap:6px;margin-left:auto;
  color:var(--ink);font-weight:600;
}
.lib-go i{transition:transform .25s var(--ease)}
.lib-card:hover .lib-go i{transform:translateX(4px)}

/* ---------- Empty + more ---------- */
.lib-empty{text-align:center;padding:70px 20px;color:var(--ink-soft)}
.lib-empty i{font-size:2.6rem;color:var(--gold);opacity:.7;display:block;margin-bottom:14px}
.lib-empty h2{font-family:var(--serif);font-size:1.5rem;color:var(--navy);margin-bottom:8px}
.lib-more-wrap{display:flex;justify-content:center;margin-top:34px}

/* ---------- Contribute ---------- */
.lib-cta{background:var(--surface-2);border-top:1px solid var(--line)}
/* The Library's ask is a real boxed CTA, so it carries the leaf frame (see
   .cta-band in style.css). On this cream ground the gold rules read as an
   engraved plate rather than as a border. */
.lib-cta-inner{max-width:660px;margin-inline:auto;text-align:center;background:linear-gradient(180deg,#fffdf9,var(--surface))}
.lib-cta-inner h2{margin-top:10px}
.lib-cta-inner p{margin-top:14px;margin-bottom:26px;color:var(--ink-soft)}

/* ---------- Mobile console ─────────────────────────────────────────────────
   The console stays a real card on a phone rather than dissolving into the
   page. Each facet becomes label-over-cluster, and the chips wrap into tidy
   rows so every category and format is on screen at once — no sideways scroll,
   nothing masked off the edge. Tap targets grow to a comfortable 42px. */
@media (max-width:720px){
  .lib-console{padding:16px 15px 16px;border-radius:0;--cut:14px}
  .lib-search{font-size:.95rem;padding-block:.9em}
  .lib-facets{margin-top:14px}
  .lib-facet-row{flex-direction:column;align-items:stretch;gap:10px;padding-block:14px}
  .lib-facet-label{width:auto;padding-top:0}
  .lib-chiprow{gap:8px}
  .lib-chip{min-height:42px;padding-inline:.95em}
  .lib-bar{flex-direction:column;align-items:stretch;gap:12px}
  .lib-bar-left{justify-content:space-between}
  .lib-bar-right{justify-content:space-between}
  .lib-bar-right .kh-select-wrap{flex:1}
  .lib-bar-right .kh-select{width:100%;min-height:46px}
}
@media (max-width:400px){
  .lib-console{padding:14px 12px}
  .lib-chip{font-size:.82rem;padding-inline:.85em}
}

@media (prefers-reduced-motion:reduce){
  .lib-card{opacity:1;transform:none;transition:none;transition-delay:0s}
  .lib-edge{transform:scaleY(1);transition:none}
  .lib-card:hover{transform:none}
}

/* Library chips — light slick pass (subtler than the Knowledge Hub) */
#libConsole .lib-chip{transition:background .18s var(--ease),border-color .18s var(--ease),color .18s var(--ease),box-shadow .18s var(--ease),transform .12s var(--ease)}
#libConsole .lib-chip:hover{transform:translateY(-1px)}
#libConsole .lib-chip:active{transform:translateY(0) scale(.97)}
#libConsole .lib-chip.active{box-shadow:inset 0 0 0 1px rgba(201,163,78,.38)}

/* ---------- Active-filter chips (osklen: what's applied, at a glance) ----------
   Shows every applied filter as a small removable chip in the bar, so it stays
   visible even when the console is folded; each chip clears just its own filter. */
.lib-active{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.lib-active[hidden]{display:none}
.lib-achip{
  display:inline-flex;align-items:center;gap:6px;
  padding:.34em .34em .34em .72em;border-radius:var(--radius);
  background:rgba(201,163,78,.15);border:1px solid rgba(201,163,78,.5);
  color:var(--gold-bright);font-family:var(--sans);font-size:.75rem;font-weight:600;
  cursor:pointer;line-height:1;
  transition:background .18s var(--ease),border-color .18s var(--ease),transform .1s var(--ease);
}
.lib-achip i{font-size:.95em;width:1.35em;height:1.35em;display:inline-flex;align-items:center;justify-content:center;border-radius:4px;background:rgba(201,163,78,.18)}
.lib-achip:hover{background:rgba(201,163,78,.26);border-color:var(--gold-bright)}
.lib-achip:active{transform:scale(.96)}
.vh{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE FILTER — a slim bar that opens, not a wall that sits there
   ---------------------------------------------------------------------------
   Measured on a 390px viewport: the console rendered 537px tall. On an
   844px-high phone that is the entire first screen given to controls, with
   the first result pushed below the fold — the reader arrives at a library
   and is shown a form. Sixteen chips were laid out permanently open in case
   one of them was wanted.

   Collapsed by default now: the search field stays (it is the thing most
   people reach for) and everything else folds behind one control that carries
   the live count of what is active, so the state is never hidden — you can
   see you have two filters on without opening anything. Opening is a height
   transition on a measured max-height, not a jump, and the control keeps the
   site's mark language: an engraved hairline, Ember Border on press, corner
   sparks. No modal, no overlay, no scroll lock — the results stay on screen
   underneath while you choose, which is the whole point of filtering.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width:760px){
  .lib-console{position:static}
  .lib-panel-inner{padding:12px 12px 14px}
  .lib-search-wrap{margin-bottom:0}
  .lib-search{min-height:46px;font-size:.95rem}

  /* the control */
  .lib-fbar{
    display:flex;align-items:center;justify-content:space-between;gap:10px;
    margin-top:10px;
  }
  .lib-ftoggle{
    position:relative;overflow:hidden;flex:1 1 auto;
    display:inline-flex;align-items:center;justify-content:space-between;gap:.6em;
    min-height:44px;padding:.6em .95em;
    background:transparent;border:var(--hair) solid rgba(15,32,56,.34);border-radius:0;
    font-family:var(--sans);font-size:.84rem;font-weight:600;letter-spacing:.05em;
    text-transform:uppercase;color:var(--navy);cursor:pointer;
    transition:border-color .3s var(--ease-lux),box-shadow .34s var(--ease-lux),color .3s var(--ease-lux);
  }
  .lib-ftoggle::before,.lib-ftoggle::after{
    content:"";position:absolute;width:2px;height:2px;border-radius:50%;
    background:var(--gold-deep);opacity:.26;pointer-events:none;
    transition:opacity .3s var(--ease-lux),box-shadow .3s var(--ease-lux);
  }
  .lib-ftoggle::before{top:5px;left:5px}
  .lib-ftoggle::after{bottom:5px;right:5px}
  .lib-ftoggle:active,.lib-ftoggle[aria-expanded="true"]{
    border-color:var(--gold);
    box-shadow:0 0 0 var(--hair) var(--gold),0 0 6px rgba(201,163,78,.32);
  }
  .lib-ftoggle[aria-expanded="true"]::before,.lib-ftoggle[aria-expanded="true"]::after{
    opacity:1;box-shadow:0 0 5px var(--gold-deep)}
  .lib-ftoggle .lf-label{display:inline-flex;align-items:center;gap:.55em}
  /* live count of active facets — the state stays visible while collapsed */
  .lib-ftoggle .lf-n{
    display:none;min-width:19px;height:19px;padding:0 5px;
    align-items:center;justify-content:center;
    background:var(--gold);color:#241a09;font-size:.7rem;font-weight:700;letter-spacing:0;
  }
  .lib-ftoggle.has-n .lf-n{display:inline-flex}
  .lib-ftoggle .lf-chev{transition:transform .34s var(--ease-lux);font-size:1.05em;color:var(--gold-deep)}
  .lib-ftoggle[aria-expanded="true"] .lf-chev{transform:rotate(180deg)}

  /* the drawer */
  .lib-facets{
    overflow:hidden;max-height:0;opacity:0;
    transition:max-height .42s var(--ease-lux),opacity .3s var(--ease),margin .42s var(--ease-lux);
    margin-top:0;
  }
  .lib-facets.is-open{opacity:1;margin-top:14px}
  .lib-facet-row{margin-bottom:14px}
  .lib-facet-label{font-size:.68rem;letter-spacing:.14em;margin-bottom:7px}
  .lib-chiprow{gap:7px}
  .lib-chip{padding:.46em .8em;font-size:.83rem;min-height:36px}
  .lib-count{margin-top:12px;font-size:.85rem}
}
@media (max-width:760px) and (prefers-reduced-motion:reduce){
  .lib-facets{transition:none}
  .lib-ftoggle .lf-chev{transition:none}
}

/* === BEGIN generated: touch-life hover mirror (tools/mirror_hover.py) === */
/* Touch devices only. js/touch-life.js adds .tl-on to a component
   while it sits in the middle band of the screen, so scrolling is the
   gesture that a pointer cannot make. Do not edit by hand. */
.lib-card.tl-on{border-color:var(--gold-soft);box-shadow:var(--edge-light),0 10px 24px -14px rgba(15,32,56,.24);outline:none;
  transform:translateY(-4px);transition-delay:0s;}
.lib-card.tl-on .lib-edge{width:4px}
.lib-card.tl-on .lib-type{background:var(--gold);color:#12243f}
.lib-card.tl-on .lib-go i{transform:translateX(4px)}
@media (prefers-reduced-motion:reduce){.lib-card.tl-on{transform:none}}
/* === END generated: touch-life hover mirror === */
