/* --- style.css --- */
/* Two families, everywhere. Every font-family and font: shorthand in every
   stylesheet goes through these two - see tests/test_font_consistency.py,
   which fails on any family named directly. Onest carries the interface,
   Literata the titles and prices. */
:root{--font-sans:"Onest","Segoe UI",Arial,sans-serif;--font-serif:"Literata",Georgia,serif}
:root{--bg:#f5f1e8;--paper:#fffdf8;--ink:#1d2925;--muted:#66736e;--line:#ddd8cc;--accent:#256f5a;--accent2:#e8a84c;--good:#e4f4ec;--warn:#fff1cf;--bad:#fbe5e5}*{box-sizing:border-box}body{margin:0;font-family:var(--font-sans);background:var(--bg);color:var(--ink)}a{color:inherit}.wrap{max-width:1180px;margin:auto;padding:0 22px}.top{background:#173e34;color:white;padding:18px 0;box-shadow:0 2px 10px #0002}.nav{display:flex;align-items:center;gap:22px}.brand{font-weight:800;font-size:21px;text-decoration:none;margin-right:auto}.nav a{text-decoration:none;color:#f4fbf8}.hero{padding:54px 0 26px}.hero h1{font-size:44px;margin:0 0 10px;max-width:760px}.hero p{font-size:18px;color:var(--muted);margin:0}.search{display:flex;gap:10px;margin:28px 0}.search input{flex:1;padding:17px 18px;border:1px solid var(--line);border-radius:12px;font-size:17px;background:white}.btn{border:0;background:var(--accent);color:white;padding:13px 20px;border-radius:10px;font-weight:700;cursor:pointer;text-decoration:none;display:inline-block}.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:18px}.card{background:var(--paper);border:1px solid var(--line);border-radius:16px;padding:20px;box-shadow:0 8px 24px #2b3b350d}.book-card{display:grid;grid-template-columns:90px 1fr;gap:17px}.cover{width:90px;height:132px;border-radius:8px;background:linear-gradient(145deg,#274f69,#91b8af);display:flex;align-items:flex-end;padding:10px;color:white;font-weight:800}.muted{color:var(--muted)}.meta{font-size:14px;color:var(--muted);line-height:1.6}.price{font-size:25px;font-weight:800}.old{text-decoration:line-through;color:var(--muted);font-size:14px}.badges{display:flex;flex-wrap:wrap;gap:7px;margin:8px 0}.badge{font-size:12px;padding:5px 8px;border-radius:999px;background:#edf0ee}.badge.good{background:var(--good)}.badge.warn{background:var(--warn)}.badge.bad{background:var(--bad)}.offers{width:100%;border-collapse:collapse}.offers th,.offers td{text-align:left;padding:14px;border-bottom:1px solid var(--line);vertical-align:top}.offers th{font-size:13px;text-transform:uppercase;color:var(--muted)}.section{margin:26px 0}.detail-head{display:grid;grid-template-columns:160px 1fr;gap:26px}.detail-cover{height:235px;border-radius:14px;background:linear-gradient(145deg,#274f69,#91b8af);display:flex;align-items:flex-end;padding:18px;color:white;font-size:20px;font-weight:800}.rating{display:inline-flex;align-items:center;gap:8px;background:#fff6da;padding:9px 12px;border-radius:10px}.admin-card{margin-bottom:18px}.admin-card form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.admin-card label{font-size:13px;font-weight:700;color:var(--muted)}input,select,textarea{width:100%;padding:10px;border:1px solid var(--line);border-radius:8px;background:white}textarea{min-height:74px;resize:vertical}.full{grid-column:1/-1}.check{display:flex;align-items:center;gap:8px}.check input{width:auto}.shop-row{display:flex;justify-content:space-between;gap:16px;align-items:start}.footer{padding:40px 0;color:var(--muted)}@media(max-width:700px){.hero h1{font-size:33px}.search{flex-direction:column}.detail-head{grid-template-columns:1fr}.detail-cover{height:190px}.offers{display:block;overflow-x:auto}.admin-card form{grid-template-columns:1fr}.full{grid-column:auto}.nav{gap:12px;flex-wrap:wrap}}


.toolbar{display:flex;flex-wrap:wrap;gap:12px;margin:0 0 18px}.toolbar button{padding:11px 14px;border:1px solid var(--line);background:white;border-radius:10px;cursor:pointer;font-size:15px;color:var(--ink)}.toolbar button.active{background:#173e34;color:#fff;border-color:#173e34}.offers-wrap{overflow-x:auto}.offers{table-layout:fixed}.offers td.actions{text-align:right}.shop{display:flex;align-items:flex-start;gap:14px;min-width:220px}.shop-logo{width:54px;height:54px;object-fit:contain;border:1px solid var(--line);border-radius:14px;background:white;padding:7px;flex:none}.shop-name{font-size:18px;font-weight:800;margin:0 0 4px}.price-note{margin-top:10px}.offer-desc{font-size:14px;color:var(--muted);line-height:1.5}.tooltip{position:relative;cursor:help;border-bottom:1px dashed #6b7b76}.tooltip .tip{visibility:hidden;opacity:0;position:absolute;z-index:20;left:0;top:calc(100% + 10px);width:310px;background:#173e34;color:white;padding:12px 14px;border-radius:10px;box-shadow:0 10px 28px #0003;font-size:13px;line-height:1.45;transition:.15s}.tooltip .tip:before{content:"";position:absolute;left:18px;top:-6px;border-width:0 6px 6px;border-style:solid;border-color:transparent transparent #173e34}.tooltip:hover .tip,.tooltip:focus .tip,.tooltip:focus-within .tip{visibility:visible;opacity:1}

/* Cozy library visual direction */
:root{--bg:#f3ecdf;--paper:#fffaf1;--ink:#3b2f2a;--muted:#806f65;--line:#d9c8b5;--accent:#9a4f3f;--accent2:#6f7f59;--good:#e8efe0;--warn:#f3dfb8}
body{background:var(--bg);color:var(--ink)}
.top{background:#fffaf1;color:var(--ink);border-bottom:1px solid var(--line);box-shadow:none}.nav a{color:var(--muted)}.brand,.hero h1,.shop-name,.price{font-family:var(--font-serif)}.btn{background:var(--accent);border-radius:12px;box-shadow:0 5px 0 #70392e}.card{background:var(--paper);border-color:var(--line)}
.toolbar{background:#f9f1e4;border:1px solid var(--line);border-radius:18px;padding:16px 18px;margin-bottom:22px;box-shadow:0 12px 30px rgba(76,50,34,.08)}.toolbar button{border-radius:999px;background:var(--paper)}.toolbar button.active{background:var(--ink);border-color:var(--ink)}
.offer-list{display:grid;gap:14px}.offer-card{background:var(--paper);border:1px solid var(--line);border-radius:18px;box-shadow:0 12px 30px rgba(76,50,34,.08);display:grid;grid-template-columns:minmax(230px,1.25fr) minmax(150px,.65fr) minmax(300px,1.35fr) auto;gap:20px;align-items:center;padding:18px 20px;position:relative}.offer-card:before{content:"";position:absolute;left:0;top:18px;bottom:18px;width:5px;border-radius:0 5px 5px 0;background:#c28d57}.shop-logo{border-radius:50%}.badge.good{background:var(--good)}.badge.warn{background:var(--warn)}
@media(max-width:900px){.offer-card{grid-template-columns:1fr 1fr}.offer-programs{grid-column:1/3}.offer-action{grid-column:2;justify-self:end}}@media(max-width:650px){.offer-card{grid-template-columns:1fr}.offer-programs,.offer-action{grid-column:auto}.offer-action{justify-self:stretch}.offer-action .btn{width:100%}}

/* КнигоЦіна — warm, editorial storefront */
:root{--bg:#f7f2e9;--paper:#fffdf9;--ink:#211b18;--muted:#786f68;--line:#e8ded2;--accent:#a74434;--accent-dark:#843326;--accent-soft:#f5e5df;--good:#e9f4e6;--shadow:0 12px 35px rgba(61,42,29,.08);--red:#a74434;--green:#176d4f;--card:#fffaf3}
*{box-sizing:border-box}body{font-family:var(--font-sans);background:radial-gradient(circle at 85% 0,#fff7ed 0,transparent 34%),var(--bg);color:var(--ink);line-height:1.45}.wrap{max-width:1600px;padding-left:28px;padding-right:28px}/* backdrop-filter:blur(16px) removed - a real user-recorded DevTools trace
   showed ~2.7s of cumulative GPU-process work (CrGpuMain RunTask, up to
   80ms per task) spread across an entire scroll session, not localized to
   any one point on the page. blur() on a sticky/fixed element forces the
   GPU to recomposite a blurred sample of everything scrolling underneath
   it on every single frame for as long as it's stuck to the screen - i.e.
   the whole page, the whole time a user scrolls, regardless of what
   content happens to be passing underneath. The renderer main thread was
   already clean (confirmed in the same trace - nothing over ~24ms) by
   this point; this was the entire remaining cost. Near-opaque background
   keeps the same visual weight without needing to sample/blur anything. */
.top{position:sticky;top:0;z-index:50;padding:0;background:#fffdf9;border-bottom:1px solid rgba(168,139,115,.2)}.nav{min-height:72px}.brand{display:flex;align-items:center;gap:10px;font-family:var(--font-serif);font-size:22px;color:var(--ink)!important}.brand-mark{display:grid;place-items:center;width:34px;height:34px;border-radius:10px;background:var(--accent);color:white;font-size:19px;box-shadow:0 5px 12px rgba(167,68,52,.25)}.nav-links{display:flex;align-items:center;gap:7px}.nav-links a{padding:9px 13px;border-radius:9px;font-size:14px;font-weight:650;color:#5e554e}.nav-links a:hover{background:#f3ebe2;color:var(--accent)}
.hero{margin:34px 0 44px;padding:54px 64px 38px;border:1px solid #eadbc9;border-radius:28px;background:linear-gradient(118deg,rgba(255,253,248,.98),rgba(250,235,219,.92)),radial-gradient(circle at 90% 20%,#efc9b5,transparent 30%);box-shadow:var(--shadow);text-align:center;position:relative;overflow:hidden}.hero:after{content:"";position:absolute;width:260px;height:260px;border:1px solid rgba(167,68,52,.1);border-radius:50%;right:-110px;top:-150px}.hero-copy{position:relative;z-index:1}.eyebrow{display:block;color:var(--muted);font-size:12px;font-weight:800;letter-spacing:.13em;text-transform:uppercase}.hero h1{font-family:var(--font-serif);max-width:none;font-size:clamp(36px,5vw,58px);line-height:1.05;letter-spacing:-.035em;margin:11px 0 14px}.hero p{font-size:17px}.search{position:relative;z-index:2;max-width:780px;margin:30px auto 13px;padding:6px;background:#fff;border:1px solid #ded2c6;border-radius:15px;box-shadow:0 10px 30px rgba(55,35,22,.1);gap:0}.search-icon{display:grid;place-items:center;width:48px;font-size:26px;color:#9a8d82}.search input{border:0;padding:12px 6px;border-radius:0;outline:none}.search .btn{min-width:126px}.hero-note{font-size:12px;color:#968a80}.btn{background:linear-gradient(180deg,#b24f3f,var(--accent));border-radius:10px;box-shadow:0 4px 0 var(--accent-dark),0 8px 18px rgba(131,51,38,.16);transition:transform .16s,box-shadow .16s}.btn:hover{transform:translateY(-2px);box-shadow:0 6px 0 var(--accent-dark),0 11px 22px rgba(131,51,38,.2)}
.section-heading,.offers-heading{display:flex;align-items:end;justify-content:space-between;margin:0 0 20px}.section-heading h2,.offers-heading h2{font-family:var(--font-serif);font-size:29px;margin:3px 0 0}.section-heading h2 span{color:var(--accent)}.result-count{font-size:13px;color:var(--muted);padding:7px 11px;border:1px solid var(--line);border-radius:999px;background:rgba(255,255,255,.55)}.grid{grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:24px}.card{border:1px solid var(--line);box-shadow:var(--shadow)}.book-card{border-radius:18px;background:var(--paper)}.book-cover-wrap{aspect-ratio:4/4.5;padding:18px;background:linear-gradient(145deg,#f5eadc,#eee0cf)}.book-cover-wrap:after{display:none}.book-cover{width:auto;max-width:100%;height:100%;border-radius:8px;box-shadow:0 10px 22px rgba(52,34,22,.2)}.book-card-body{padding:18px 19px 19px}.book-title{font-family:var(--font-serif);font-size:1.14rem;min-height:3em}.book-title a{text-decoration:none}.book-author{font-size:.86rem;margin-top:5px}.book-isbn{font-size:.72rem;letter-spacing:.02em}.book-card .badges{min-height:26px;margin:11px 0 8px}.book-card .badge{background:#f2eee8;border:0;color:#554c46}.format-prices{display:grid;grid-template-columns:1fr auto;align-items:end;gap:12px}.paper-price{font-family:var(--font-serif);color:var(--accent);font-size:1.65rem}.price-label{font-family:var(--font-sans);color:#6d625a}.electronic-price{text-align:right}.book-meta-row{border-top:0;margin:14px 0;color:#756a62}.book-card .btn{display:flex;justify-content:center;gap:9px;padding:11px 14px}.empty-state{grid-column:1/-1;display:flex;flex-direction:column;align-items:center;gap:6px;padding:50px;text-align:center;color:var(--muted)}.empty-state strong{font-family:var(--font-serif);font-size:24px;color:var(--ink)}
.back-link{display:inline-block;margin:30px 0 16px;text-decoration:none;color:var(--accent);font-size:14px;font-weight:700}.detail-head.card{margin:0 0 35px;padding:34px;grid-template-columns:190px 1fr;align-items:center;border-radius:22px;background:var(--paper);text-align:left;overflow:visible}.detail-head.card:after{display:none}.detail-image,.detail-cover{width:190px;height:275px;object-fit:cover;border-radius:10px;box-shadow:0 14px 28px rgba(53,35,22,.18)}.detail-copy h1{font-family:var(--font-serif);font-size:clamp(30px,4vw,46px);margin:8px 0}.detail-copy .meta{font-size:16px;color:#655b54}.detail-copy .muted{margin:16px 0 0}.format-tabs{margin-top:20px}.format-tab{font-weight:700;border-color:var(--line);background:#f4f0eb}.format-tab.active{background:var(--accent);border-color:var(--accent);color:white}.offers-heading{margin-top:6px}.sort-button{border:1px solid var(--line);background:var(--paper);padding:10px 14px;border-radius:10px;color:var(--ink);cursor:pointer}.toolbar{padding:0;background:transparent;border:0;box-shadow:none;margin:0 0 14px}.toolbar button{font-size:13px;padding:9px 13px;background:var(--paper)}.toolbar button.active{background:var(--accent);border-color:var(--accent)}.offers-card{padding:0;overflow:hidden;border-radius:18px}.offers{table-layout:auto}.offers th{background:#f5eee5;padding:13px 18px}.offers td{padding:18px;vertical-align:middle}.offers tbody tr:last-child td{border-bottom:0}.offers tbody tr:hover{background:#fffaf3}.offers .price{font-family:var(--font-serif);color:var(--ink);white-space:nowrap}.offers .btn{box-shadow:none}.footer{display:flex;justify-content:space-between;border-top:1px solid var(--line);margin-top:55px}.footer strong{font-family:var(--font-serif);color:var(--ink)}
@media(max-width:800px){.wrap{padding-left:18px;padding-right:18px}.nav{min-height:64px}.nav-links a{display:none}.nav-links a:first-child{display:block}.hero{padding:38px 22px 27px;margin-top:20px}.hero h1{font-size:38px}.grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:15px}.detail-head.card{grid-template-columns:130px 1fr;padding:22px}.detail-image,.detail-cover{width:130px;height:190px}.offers-wrap{overflow-x:auto}.offers{min-width:720px}}
@media(max-width:540px){.wrap{padding-left:14px;padding-right:14px}.brand{font-size:19px}.hero h1{font-size:32px}.hero p{font-size:15px}.search{display:grid;grid-template-columns:40px 1fr}.search .btn{grid-column:1/-1;margin-top:6px;box-shadow:none}.grid{grid-template-columns:1fr}.book-cover-wrap{aspect-ratio:4/3.7}.detail-head.card{grid-template-columns:1fr;text-align:center}.detail-image,.detail-cover{margin:auto}.detail-copy .eyebrow{margin-top:6px}.format-tabs{justify-content:center}.section-heading,.offers-heading{align-items:flex-start}.result-count{display:none}.footer{flex-direction:column;gap:6px}}
.hero.detail-head{margin:34px 0;padding:34px;grid-template-columns:190px 1fr;align-items:center;border-radius:22px;background:var(--paper);text-align:left;overflow:visible}.hero.detail-head:after{display:none}.hero.detail-head h1{font-size:clamp(30px,4vw,46px);margin:7px 0 10px}.hero.detail-head .meta:first-child{color:var(--accent);font-size:12px;font-weight:800;letter-spacing:.13em;text-transform:uppercase}.hero.detail-head .muted{margin-top:14px}.hero.detail-head .detail-image{width:190px;height:275px}.hero.detail-head+.toolbar{margin-top:-12px}
@media(max-width:700px){.hero.detail-head{grid-template-columns:1fr;text-align:center}.hero.detail-head .detail-image{margin:auto;width:150px;height:218px}.hero.detail-head .format-tabs{justify-content:center}}
.book-cover{width:100%;height:100%;max-width:100%;object-fit:contain;box-shadow:none}
.book-page{padding-top:26px}.book-page .back-link{margin:0 0 17px}.book-summary{display:grid;grid-template-columns:180px minmax(0,1fr);gap:32px;padding:30px;margin:0 0 34px;border-radius:20px;background:var(--paper)}.book-summary-cover{width:180px;height:260px;display:flex;align-items:center;justify-content:center;border-radius:12px;background:#f4eadc;overflow:hidden}.book-summary-cover img{display:block;width:100%;height:100%;object-fit:contain}.book-summary-placeholder{display:grid;place-items:center;width:100%;height:100%;padding:20px;color:#8b7561;font-family:var(--font-serif);font-weight:700;text-align:center}.book-summary-copy{align-self:center}.book-summary-copy h1{font-family:var(--font-serif);font-size:clamp(22px,2.4vw,30px);line-height:1.15;margin:8px 0 9px}.book-summary-author{font-size:17px;color:#655b54;margin-bottom:8px}.book-summary-isbn{font-size:13px;color:#94877c}.book-summary-copy .format-tabs{margin-top:22px}.comparison-section{margin-top:25px}.comparison-header{display:flex;justify-content:space-between;align-items:end;margin-bottom:15px}.comparison-header h2{font-family:var(--font-serif);font-size:28px;margin:4px 0 0}.comparison-count{padding:7px 11px;border-radius:999px;background:#f1ece6;color:#756a62;font-size:12px}.edition-group{margin-bottom:24px}.edition-title{display:flex;align-items:center;gap:13px;margin:0 0 10px;font-size:14px}.edition-title:after{content:"";height:1px;flex:1;background:var(--line)}.offer-list-modern{overflow:hidden;border-radius:15px;background:var(--paper)}.offer-row-modern{display:grid;grid-template-columns:minmax(150px,1.1fr) minmax(120px,.8fr) minmax(220px,1.5fr) auto;align-items:center;gap:18px;padding:17px 18px;border-bottom:1px solid var(--line)}.offer-row-modern:last-child{border-bottom:0}.offer-row-modern:hover{background:#fff9f1}.offer-shop{font-size:15px}.offer-shop strong{display:block;margin-bottom:5px}.stock-pill{display:inline-flex;align-items:center;gap:5px;padding:4px 8px;border-radius:999px;background:var(--good);color:#4c8c55;font-size:11px;font-weight:700}.stock-pill:before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor}.stock-pill.out{background:#f4e8e5;color:#a65b51}.offer-price-main{font-family:var(--font-serif);font-size:22px;font-weight:800;white-space:nowrap}.offer-price-old{font-family:var(--font-sans);font-size:12px;font-weight:400;color:#9a8d82;text-decoration:line-through;margin-left:7px}.offer-programs-modern{display:flex;flex-wrap:wrap;gap:6px}.offer-programs-modern .badge{font-size:11px;padding:5px 8px}.offer-updated{font-size:11px;color:#9a8d82;margin-top:6px}.store-link{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:9px 13px;border-radius:9px;background:#eeeae4;color:#423a35;text-decoration:none;font-size:13px;font-weight:750;white-space:nowrap;transition:.15s}.store-link:hover{background:var(--accent);color:#fff}.book-filterbar{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 22px}.book-filterbar button{padding:8px 12px;border:1px solid var(--line);border-radius:999px;background:var(--paper);color:var(--ink);cursor:pointer;font-size:12px}.book-filterbar button.active{background:var(--accent);border-color:var(--accent);color:#fff}
@media(max-width:760px){.book-summary{grid-template-columns:120px 1fr;gap:20px;padding:20px}.book-summary-cover{width:120px;height:174px}.offer-row-modern{grid-template-columns:1fr auto}.offer-programs-modern{grid-column:1/-1}.offer-updated{display:none}}
@media(max-width:520px){.book-summary{grid-template-columns:1fr;text-align:center}.book-summary-cover{width:145px;height:210px;margin:auto}.book-summary-copy .format-tabs{justify-content:center}.comparison-header{align-items:start}.offer-row-modern{grid-template-columns:1fr}.offer-price-main{font-size:24px}.store-link{width:100%}}

/* Distinctive, Ukrainian-friendly typography */
body,input,button,select,textarea{font-family:var(--font-sans)}.brand,.hero h1,.section-heading h2,.offers-heading h2,.book-title,.paper-price,.empty-state strong,.detail-copy h1,.offers .price,.footer strong,.book-summary-copy h1,.comparison-header h2,.offer-price-main,.book-summary-placeholder{font-family:var(--font-serif)}.hero h1,.book-summary-copy h1{font-weight:700}.book-title{font-weight:700;letter-spacing:-.012em}.paper-price,.offer-price-main{font-weight:800}.eyebrow,.btn,.format-tab,.store-link{font-family:var(--font-sans)}.meta,.book-author,.book-isbn,.book-summary-isbn{font-feature-settings:"tnum" 1,"ss01" 1}

/* Never crop catalogue covers, including on hover. */
.book-cover-wrap{padding:18px;overflow:hidden}.book-cover,.book-card:hover .book-cover{display:block;width:100%;height:100%;max-width:100%;max-height:100%;object-fit:contain;object-position:center;transform:none!important;border-radius:8px}

/* Stable image geometry: no cascade difference between idle and hover. */
.book-card .book-cover-wrap{position:relative;padding:0}.book-card .book-cover,.book-card:hover .book-cover{position:absolute;inset:18px;width:calc(100% - 36px);height:calc(100% - 36px);max-width:none;max-height:none;object-fit:contain;object-position:50% 50%;transform:none!important;transition:none;border-radius:8px;box-shadow:none}

/* Whole-card navigation and equal visual treatment for both formats. */
.card-link{cursor:pointer}.card-link:focus-visible{outline:3px solid rgba(167,68,52,.35);outline-offset:4px}.format-prices{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;padding-top:12px}.format-price-item{min-width:0;padding:10px 11px;border:1px solid #eadfd3;border-radius:11px;background:#fffaf4}.format-price-item .price-label{display:block;min-height:2.4em;margin:0 0 5px;font-size:.7rem;line-height:1.2;color:#796d64}.format-price-item strong{display:block;font-family:var(--font-serif);font-size:1.12rem;line-height:1.15;color:var(--accent);white-space:nowrap}.format-price-item.unavailable strong{font-family:var(--font-sans);font-size:.74rem;line-height:1.35;color:#978b7f;white-space:normal}.paper-price,.electronic-price{font:inherit;color:inherit;text-align:left;margin:0}
@media(max-width:340px){.format-prices{grid-template-columns:1fr}.format-price-item .price-label{min-height:0}}

/* Backward-compatible price layout for a server process started before the markup update. */
.format-prices>.paper-price,.format-prices>.electronic-price{min-width:0;min-height:70px;padding:10px 11px;border:1px solid #eadfd3;border-radius:11px;background:#fffaf4;font-family:var(--font-sans);font-size:.7rem;line-height:1.2;color:#796d64;text-align:left}.format-prices>.paper-price .price-label{display:block;min-height:2.4em;margin:0 0 5px;font:inherit;color:inherit}.format-prices>.paper-price:not(.price-unavailable),.format-prices>.electronic-price strong{font-family:var(--font-serif);font-size:1.12rem;font-weight:800;line-height:1.15;color:var(--accent)}.format-prices>.paper-price:not(.price-unavailable) .price-label{font-family:var(--font-sans);font-size:.7rem;font-weight:600;color:#796d64}.format-prices>.electronic-price{display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-start;margin:0}.format-prices>.electronic-price strong{display:block;margin-top:5px}.format-prices>.price-unavailable{display:flex;flex-direction:column;justify-content:flex-end;font-size:.74rem;font-weight:700;line-height:1.35;color:#978b7f}
.format-prices>.price-unavailable{justify-content:flex-start!important}
.format-price-item.unavailable strong{font-family:var(--font-serif);font-size:0;font-weight:800;line-height:1.15;color:#978b7f;white-space:nowrap}.format-price-item.unavailable strong:after{content:"Немає";font-size:1.12rem}

/* Compact catalogue cards: the whole tile is the action. */
.book-card .btn{display:none!important}.book-card-body{flex:0 0 auto;padding:14px 16px 15px}.book-title{min-height:0;margin:0;font-size:1.08rem;line-height:1.25}.book-author{margin-top:3px;font-size:.82rem;line-height:1.3}.book-isbn{margin-top:3px;line-height:1.25}.book-card .badges{min-height:0;margin:8px 0 0}.format-prices{margin-top:9px!important;padding-top:9px!important;gap:8px}.format-price-item{min-height:66px;padding:9px 10px}.format-price-item .price-label{min-height:2.25em;margin-bottom:3px}.book-meta-row{margin:10px 0 0;padding-top:9px;border-top:1px solid rgba(92,67,44,.1);font-size:.72rem}.book-card{align-self:start}

/* Smaller covers and equal-height catalogue tiles. */
.grid{grid-template-columns:repeat(auto-fill,minmax(218px,1fr));align-items:stretch}.book-card{align-self:stretch;height:100%}.book-cover-wrap{aspect-ratio:4/3.45}.book-card-body{flex:1 1 auto}.book-title{min-height:2.5em}.book-card .badges{min-height:25px}.format-prices{grid-auto-rows:1fr}.format-price-item{height:100%}.book-meta-row{margin-top:auto}
@media(max-width:540px){.grid{grid-template-columns:1fr}.book-cover-wrap{aspect-ratio:4/3.2}.book-title{min-height:0}}

/* Book page: show paper and electronic prices together, without tabs. */
.book-format-prices{display:grid;grid-template-columns:repeat(2,minmax(0,190px));gap:10px;margin-top:20px}.book-format-price{display:flex;flex-direction:column;justify-content:center;min-height:76px;padding:11px 13px;border:1px solid #eadfd3;border-radius:12px;background:#fff8f0}.book-format-price span{font-size:.72rem;font-weight:650;color:#796d64}.book-format-price strong{margin-top:5px;font-family:var(--font-serif);font-size:1.25rem;line-height:1.15;color:var(--accent)}.book-format-price.unavailable strong{font-family:var(--font-sans);font-size:.78rem;color:#978b7f}.book-page .format-tabs{display:none}
@media(max-width:520px){.book-format-prices{grid-template-columns:repeat(2,minmax(0,1fr));text-align:left}.book-format-price{padding:10px}.book-format-price strong{font-size:1.05rem}}

/* Old running processes may still inject format-switching JS. Never hide editions. */
.book-page .edition-group{display:block!important}
.completion-note{margin:14px 0 4px;padding:10px 12px;border-radius:10px;background:#e8f4e6;color:#397043;font-size:.85rem;font-weight:750}
.import-duration{font-variant-numeric:tabular-nums;font-weight:700;color:var(--accent)}
.catalog-search{position:relative;z-index:5}.catalog-search .search{margin-bottom:14px}.search-filters{display:grid;grid-template-columns:repeat(auto-fit,minmax(145px,1fr));align-items:end;gap:9px;max-width:1180px;margin:0 auto;text-align:left}.search-filters>label{min-width:0;font-size:.7rem;font-weight:700;color:#786b62}.search-filters select,.search-filters input[type=number]{height:38px;margin-top:4px;padding:7px 9px;border:1px solid #ded2c6;border-radius:9px;background:#fff;font-size:.78rem}.search-filters .availability-check{display:flex;align-items:center;gap:6px;height:38px;padding:0 9px;border:1px solid #ded2c6;border-radius:9px;background:#fff;white-space:nowrap}.availability-check input{width:auto}.reset-filters{display:flex;align-items:center;height:38px;color:var(--accent);font-size:.75rem;font-weight:750;text-decoration:none;white-space:nowrap}
.filter-dropdown{position:relative;margin-top:4px}.filter-trigger{width:100%;height:38px;padding:7px 30px 7px 10px;border:1px solid #ded2c6;border-radius:9px;background:#fff;color:#5f544b;font:600 .76rem var(--font-sans);text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer}.filter-trigger:after{content:"⌄";position:absolute;right:10px;color:#9a8775}.filter-trigger.has-value{border-color:#b95842;background:#fff8f3;color:#9f3f2f}.filter-panel{display:none;position:absolute;z-index:30;top:calc(100% - 1px);left:0;width:max(100%,230px);padding:9px;border:1px solid #dfd2c5;border-radius:12px;background:#fffdf9;box-shadow:0 16px 38px rgba(65,45,30,.18)}.filter-dropdown.open .filter-panel{display:block}.filter-search{width:100%;height:34px!important;margin:0 0 7px!important;padding:7px 9px!important;border:1px solid #e2d7cc!important;border-radius:8px!important;font-size:.76rem!important}.filter-options{max-height:240px;overflow:auto}.filter-option{display:flex!important;align-items:center;gap:8px;padding:7px 6px;border-radius:7px;color:#554a42!important;font-size:.76rem!important;font-weight:500!important;cursor:pointer}.filter-option:hover{background:#f6ede4}.filter-option input{width:auto;margin:0;accent-color:#b64b37}.filter-option[hidden]{display:none!important}
@media(max-width:900px){.search-filters{grid-template-columns:repeat(3,1fr)}}@media(max-width:540px){.search-filters{grid-template-columns:repeat(2,1fr)}.search-filters .availability-check{grid-column:1/-1}.reset-filters{justify-content:center}}
.book-extra-meta{font-size:.76rem;color:#8a7765;margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.book-category-list{display:flex;flex-wrap:wrap;gap:7px;margin:14px 0 2px}.book-description{padding:24px;margin-top:18px}.book-description h2{margin-top:0}.book-description p{line-height:1.75;color:#5f544b;white-space:pre-line}.offer-edition-meta{font-size:.72rem;color:#88796c;margin-top:7px;line-height:1.35}
.book-summary-author a{color:inherit;text-decoration-color:rgba(178,72,54,.35);text-underline-offset:3px}.book-summary-author a:hover{color:var(--accent);text-decoration-color:currentColor}.book-series a{color:inherit;text-decoration-color:rgba(178,72,54,.35);text-underline-offset:3px}.book-series a:hover{color:var(--accent);text-decoration-color:currentColor}.book-category-list a.badge{text-decoration:none;transition:border-color .16s ease,background .16s ease,color .16s ease}.book-category-list a.badge:hover{border-color:var(--accent);background:#fff0e7;color:var(--accent)}
.book-summary{align-items:start;gap:26px;padding:26px}.book-summary-copy{align-self:start;min-width:0;padding-top:2px}.book-summary-copy h1{margin:0 0 2px}.book-summary-author{margin-bottom:0;margin-top:0}.book-category-list{margin:12px 0 0}.book-summary-about{margin-top:16px;padding-top:14px;border-top:1px solid var(--line)}.book-summary-about h2{margin:0 0 7px;font-family:var(--font-sans);font-size:.78rem;line-height:1.2;letter-spacing:.035em;text-transform:uppercase;color:#75685e}.book-summary-description{position:relative;color:#62574f;font-size:.9rem;line-height:1.55}.book-summary-about.is-collapsible:not(.is-expanded) .book-summary-description{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:3}.book-summary-about.is-collapsible:not(.is-expanded) .book-summary-description:after{content:"";position:absolute;right:0;bottom:0;width:92px;height:1.55em;background:linear-gradient(90deg,rgba(255,250,243,0),var(--paper) 70%)}.book-about-toggle{margin-top:8px;padding:0;border:0;background:transparent;color:var(--accent);font:750 .78rem var(--font-sans);cursor:pointer;text-underline-offset:3px}.book-about-toggle:hover{text-decoration:underline}.book-about-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:4px;border-radius:2px}
@media(max-width:760px){.book-summary{gap:18px;padding:20px}.book-summary-description{font-size:.84rem}.book-summary-about.is-collapsible:not(.is-expanded) .book-summary-description{-webkit-line-clamp:4}}
@media(max-width:520px){.book-summary-copy{text-align:left}.book-summary-about{text-align:left}.book-category-list{justify-content:center}}
.site-search{display:flex;min-width:220px;max-width:520px;flex:1;align-items:center;height:42px;margin:0 auto;border:1px solid #ded2c6;border-radius:12px;background:#fff;overflow:hidden;box-shadow:0 5px 16px rgba(55,35,22,.07)}.site-search-icon{display:grid;width:38px;flex:0 0 38px;place-items:center;color:#97887c;font-size:21px}.site-search input{min-width:0;height:100%;padding:0 5px;border:0;border-radius:0;background:transparent;font-size:.82rem;outline:none}.site-search button{align-self:stretch;padding:0 16px;border:0;background:var(--accent);color:#fff;font:750 .76rem var(--font-sans);cursor:pointer}.site-search button:hover{background:var(--accent-dark)}.nav .brand{margin-right:0;flex:none}.nav-links{flex:none}.advanced-search-submit{height:38px;padding:7px 14px;box-shadow:none}.search-hero{margin-top:18px!important}.search-hero .advanced-search{margin-top:0}.search-hero .catalog-search{margin:0}
.header-filters-button{display:inline-flex;height:42px;flex:none;align-items:center;gap:6px;padding:0 13px;border:1px solid #d9cbbd;border-radius:11px;background:#fffaf4;color:#594c43;font:750 .76rem var(--font-sans);cursor:pointer}.header-filters-button:hover,.header-filters-button[aria-expanded=true]{border-color:var(--accent);background:#fff0e9;color:var(--accent)}.header-filters-button span{font-size:1rem}.hero.search-hero{display:none;position:fixed;z-index:45;top:72px;left:50%;width:min(1184px,calc(100vw - 32px));max-height:calc(100vh - 90px);margin:0!important;padding:20px 24px 22px!important;transform:translateX(-50%);overflow:visible auto;border-radius:0 0 20px 20px;box-shadow:0 20px 45px rgba(56,37,24,.18);text-align:left}.hero.search-hero.filters-open{display:block}.search-hero .advanced-search>summary{display:none}.search-hero .search-filters{margin-top:0}
.work-edition.format-electronic{border-color:#c8d9ee;background:linear-gradient(120deg,#f5f9ff 0%,#edf5ff 100%);box-shadow:0 8px 24px rgba(48,91,150,.07)}.work-edition.format-electronic .edition-offers{background:rgba(255,255,255,.72)}.work-edition.format-electronic .edition-card-chips>span:last-child{border-color:#bfd3ed;background:#e3effd;color:#315f9d}.work-edition.format-electronic:target{outline-color:rgba(49,95,157,.25)}
@media(max-width:920px){.nav{gap:10px}.brand>span:last-child{display:none}.nav-links a{display:none}.site-search{max-width:none}.site-search button{padding:0 12px}.header-filters-button{padding:0 11px}.header-filters-button span{display:none}}
@media(max-width:540px){.top .wrap{padding-left:8px;padding-right:8px}.nav{min-height:62px;gap:6px}.brand-mark{width:30px;height:30px}.site-search{height:40px;min-width:0}.site-search-icon{display:none}.site-search input{padding-left:10px;font-size:.73rem}.site-search button{padding:0 8px;font-size:.68rem}.header-filters-button{width:40px;height:40px;justify-content:center;padding:0;font-size:0}.header-filters-button:before{content:'☷';font-size:1rem}.hero.search-hero{top:62px;width:calc(100vw - 16px);max-height:calc(100vh - 72px);padding:14px!important}.search-hero .search-filters{grid-template-columns:repeat(2,minmax(0,1fr))}}
.hero.search-hero{z-index:10;overflow:visible;padding:24px 64px 32px}.search-hero .search{margin-top:0}.search-hero:after{display:none}.search-hero .catalog-search{position:relative;z-index:2}.search-hero+.section-heading{position:relative;z-index:1}
@media(max-width:800px){.hero.search-hero{padding:24px 22px 28px}}@media(max-width:540px){.hero.search-hero{padding:18px 14px 24px}}
.book-card{content-visibility:auto;contain-intrinsic-size:260px 570px}.catalog-loading-head{display:flex;justify-content:space-between;gap:20px;margin:32px 0 18px}.catalog-loading-head span,.skeleton-card span,.skeleton-cover{display:block;background:linear-gradient(100deg,#eee5da 20%,#faf5ee 38%,#eee5da 56%);background-size:220% 100%;animation:catalog-shimmer 1.25s ease-in-out infinite}.catalog-loading-head span:first-child{width:min(340px,70%);height:31px;border-radius:9px}.catalog-loading-head span:last-child{width:90px;height:28px;border-radius:999px}.skeleton-card{pointer-events:none;overflow:hidden}.skeleton-cover{aspect-ratio:4/3.45}.skeleton-card .book-card-body{gap:11px}.skeleton-card .book-card-body span{height:13px;border-radius:6px}.skeleton-card .book-card-body span:first-child{width:88%;height:20px}.skeleton-card .book-card-body span:nth-child(2){width:62%}.skeleton-card .book-card-body span:last-child{width:100%;height:76px;margin-top:8px}.catalog-error{display:flex;flex-direction:column;align-items:center;gap:8px;padding:42px;margin:30px 0;text-align:center}.catalog-error .btn{margin-top:8px}@keyframes catalog-shimmer{to{background-position-x:-220%}}@media(prefers-reduced-motion:reduce){.catalog-loading-head span,.skeleton-card span,.skeleton-cover{animation:none}}
.load-more{display:flex;margin:28px auto 8px;min-width:220px;justify-content:center}.load-more:disabled{cursor:wait;opacity:.72}.filter-hint{min-height:0;margin:0 2px 7px;color:#8a796b;font-size:.67rem;line-height:1.35}.filter-hint:empty{display:none}.filter-hint.loading:before{content:"";display:inline-block;width:7px;height:7px;margin-right:6px;border:2px solid #ddcfc2;border-top-color:var(--accent);border-radius:50%;animation:filter-spin .7s linear infinite}@keyframes filter-spin{to{transform:rotate(360deg)}}

/* Compact catalogue-card information hierarchy. */
.book-card-body{padding:13px 15px 14px}.book-card-copy{min-width:0}.book-card-copy .book-title{min-height:0;font-size:1.03rem;line-height:1.22}.book-card-copy .book-author{margin-top:4px;font-size:.79rem}.book-card-copy .book-extra-meta{margin-top:3px;font-size:.7rem}.book-card .format-prices{margin-top:10px!important;padding-top:10px!important;gap:7px}.book-card .format-price-item{display:flex;min-height:58px;height:auto;flex-direction:column;align-items:center;justify-content:center;padding:8px 7px;text-align:center;background:#fffaf5;border-color:#eadfd4}.book-card .format-price-item .price-label{min-height:0;margin:0 0 4px;font-size:.63rem;font-weight:700;letter-spacing:.035em;text-transform:uppercase;color:#8a786a}.book-card .format-price-item strong{font-size:1rem;line-height:1.1;text-align:center}.book-card .format-price-item.unavailable strong{font-size:0}.book-card .format-price-item.unavailable strong:after{font-size:1rem}.book-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));margin-top:10px;padding-top:9px;border-top:1px solid rgba(92,67,44,.1)}.book-stats>span{display:flex;min-width:0;flex-direction:column;align-items:center;gap:1px;padding:0 5px;text-align:center}.book-stats>span+span{border-left:1px solid rgba(92,67,44,.1)}.book-stats strong{font-size:.86rem;line-height:1.15;color:#55483e;font-variant-numeric:tabular-nums}.book-stats small{max-width:100%;font-size:.61rem;line-height:1.2;color:#8a7c70;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.book-card .book-meta-row{display:none}
.book-card .book-card-body{display:grid;grid-template-rows:74px 78px 42px;align-content:start;height:221px;box-sizing:border-box}.book-card-copy{height:74px;overflow:hidden}.book-card .format-prices{height:78px;box-sizing:border-box}.book-card .format-price-item{box-sizing:border-box}.book-stats{height:42px;box-sizing:border-box;align-items:start}.book-card-copy .book-title,.book-card-copy .book-author,.book-card-copy .book-extra-meta{max-width:100%;overflow:hidden}.book-card-copy .book-author,.book-card-copy .book-extra-meta{white-space:nowrap;text-overflow:ellipsis}
@media(max-width:540px){.book-card .book-card-body{height:216px;grid-template-rows:69px 78px 42px}.book-card-copy{height:69px}}

/* Dense catalogue layout: essential comparison data only. */
.grid{grid-template-columns:repeat(auto-fill,minmax(178px,1fr));gap:16px}@media(min-width:1180px){.grid{grid-template-columns:repeat(auto-fill,minmax(178px,1fr))}}
.book-card{border-radius:15px}.book-card .book-cover-wrap{aspect-ratio:4/3.15}.book-card .book-cover,.book-card:hover .book-cover{inset:12px;width:calc(100% - 24px);height:calc(100% - 24px)}
.book-card .book-card-body{grid-template-rows:60px 62px 38px;height:183px;padding:11px 12px 12px}.book-card-copy{height:60px}.book-card-copy .book-title{font-size:.94rem;line-height:1.18}.book-card-copy .book-author{margin-top:4px;font-size:.74rem;line-height:1.25}.book-card .format-prices{height:62px;margin-top:7px!important;padding-top:7px!important;gap:6px}.book-card .format-price-item{min-height:47px;padding:6px 5px;border-radius:9px}.book-card .format-price-item .price-label{margin-bottom:3px;font-size:.6rem;letter-spacing:.025em}.book-card .format-price-item strong,.book-card .format-price-item.unavailable strong:after{font-size:.88rem}.book-stats{height:38px;margin-top:7px;padding-top:7px}.book-stats>span{padding:0 3px}.book-stats strong{font-size:.78rem}.book-stats small{font-size:.6rem}.book-card-copy .book-extra-meta{display:none}
@media(max-width:540px){.grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.book-card .book-card-body{grid-template-rows:60px 62px 38px;height:183px}.book-card-copy{height:60px}.book-card .book-cover-wrap{aspect-ratio:4/3.05}}
@media(max-width:360px){.grid{grid-template-columns:1fr}.book-card .book-cover-wrap{aspect-ratio:4/2.8}}

/* Retail-style card: portrait-first, calm surface, no dashboard-like boxes. */
.grid{grid-template-columns:repeat(auto-fill,minmax(184px,1fr));gap:12px}@media(min-width:1180px){.grid{grid-template-columns:repeat(auto-fill,minmax(184px,1fr))}}
.book-card{--book-card-surface:#f4eadc;overflow:hidden;border:1px solid #e5d8c8;border-radius:16px;background:var(--book-card-surface);box-shadow:0 8px 24px rgba(62,43,29,.075)}.book-card:hover{transform:translateY(-3px);box-shadow:0 14px 32px rgba(62,43,29,.12)}
.book-card .book-cover-wrap{aspect-ratio:2/3;background:transparent;border:0}.book-card .book-cover,.book-card:hover .book-cover{inset:8px;width:calc(100% - 16px);height:calc(100% - 16px);border-radius:10px;box-shadow:none}
.book-card .book-card-body{grid-template-rows:58px 58px 32px;height:170px;padding:11px 12px}.book-card-copy{height:58px}.book-card-copy .book-title{font-size:.95rem;line-height:1.18}.book-card-copy .book-author{margin-top:4px;font-size:.75rem;color:#7c736d}
.book-card .format-prices{height:58px;margin-top:5px!important;padding-top:8px!important;gap:0;border-top:1px solid #eee8e1}.book-card .format-price-item{min-height:49px;padding:3px 7px;border:0;border-radius:0;background:transparent}.book-card .format-price-item+ .format-price-item{border-left:1px solid #eee8e1}.book-card .format-price-item .price-label{margin-bottom:4px;font-size:.58rem;color:#8d837c}.book-card .format-price-item strong,.book-card .format-price-item.unavailable strong:after{font-size:.96rem}.book-card .format-price-item.unavailable strong:after{color:#9a918b}
.book-stats{height:32px;margin-top:5px;padding-top:7px;border-top:1px solid #eee8e1}.book-stats>span+span{border-left:0}.book-stats strong{font-size:.73rem}.book-stats small{font-size:.58rem;color:#938a83}.skeleton-cover{aspect-ratio:2/3}
@media(max-width:540px){.grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.book-card .book-cover-wrap{aspect-ratio:2/3}.book-card .book-card-body{grid-template-rows:58px 58px 32px;height:170px}}
@media(max-width:360px){.grid{grid-template-columns:1fr}.book-card .book-cover-wrap{aspect-ratio:2/3}}
.book-card .card-prices{display:flex;min-width:0;height:58px;margin-top:5px;padding:7px 3px 5px;flex-direction:column;justify-content:center;gap:5px;border-top:1px solid #e8ded3}.card-price-row{display:flex;min-width:0;align-items:baseline;justify-content:space-between;gap:7px;color:#776d66;font-size:.68rem;line-height:1.15}.card-price-row strong{flex:none;color:#30251f;font-family:var(--font-serif);font-size:.82rem;font-weight:800;white-space:nowrap}.card-price-row:nth-child(2) strong{color:#8f594a;font-size:.78rem;font-weight:700}.card-price-row strong.unavailable,.card-price-row:nth-child(2) strong.unavailable{color:#9a9089;font-family:var(--font-sans);font-size:.68rem;font-weight:600}.book-card .book-stats{display:none}.book-card .book-card-body{grid-template-rows:58px 58px;height:138px}
.book-cover-backdrop{display:none}.book-cover-wrap.wide-cover:before{display:none}.book-card .book-cover,.book-card:hover .book-cover{z-index:2}.book-cover-placeholder{position:relative;z-index:3}.book-card .book-card-body{padding-left:9px;padding-right:9px}.book-card .format-price-item{padding-left:4px;padding-right:4px}.book-stats>span{padding-left:1px;padding-right:1px}

.edition-group{margin-top:28px}.edition-heading{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;margin:0 4px 10px}.edition-heading h3{margin:2px 0 0}.edition-number{font-size:.75rem;text-transform:uppercase;letter-spacing:.08em;color:#a14332;font-weight:800}.edition-heading-meta{margin-top:5px;color:#807267;font-size:.86rem}.edition-heading-price{text-align:right;display:flex;flex-direction:column;white-space:nowrap}.edition-heading-price strong{font-family:var(--font-serif);font-size:1.35rem;color:#3a2b22}.edition-heading-price span{font-size:.78rem;color:#8b7d71}@media(max-width:650px){.edition-heading{align-items:flex-start;flex-direction:column}.edition-heading-price{text-align:left}}

/* Keep search usable on phones: it gets a full-width second header row
   instead of being squeezed between the brand and account actions. */
@media(max-width:700px){
  .top{padding:10px 0}
  .top .wrap.nav{display:grid;grid-template-columns:auto minmax(0,1fr) auto;grid-template-rows:auto auto;gap:8px;min-height:0}
  .nav .brand{grid-column:1;grid-row:1}
  .nav .site-search{grid-column:1/-1;grid-row:2;width:100%;max-width:none;min-width:0;height:44px}
  .nav-links{display:flex!important;grid-column:3!important;grid-row:1;justify-content:flex-end!important;gap:2px}
  .site-search .header-filters-button,.site-search .site-search-submit{width:42px;min-width:42px;height:40px}
}
@media(max-width:380px){.nav .brand{font-size:.9rem}.nav-icon{width:34px;height:34px}}

.mobile-search-toggle,
.mobile-search-close { display: none; }
@media(max-width:700px) {
  .top .wrap.nav { position: relative; display: flex; min-height:54px; gap:6px; }
  .nav .brand { grid-column:auto; grid-row:auto; }
  .mobile-search-toggle { display:grid; width:40px; height:40px; flex:0 0 40px; place-items:center; padding:0; border:1px solid #d9cbbd; border-radius:11px; background:#fffaf4; color:#594c43; cursor:pointer; }
  .nav .site-search { display:none; grid-column:auto; grid-row:auto; }
  .nav .site-search.is-mobile-open { position:absolute; z-index:90; inset:0; display:flex; width:100%; min-width:0; max-width:none; height:54px; margin:0; }
  .nav .site-search.is-mobile-open .header-filters-button,
  .nav .site-search.is-mobile-open .site-search-submit,
  .nav .site-search.is-mobile-open .mobile-search-close { flex:0 0 42px; width:42px; min-width:42px; height:54px; }
  .mobile-search-close { display:none; padding:0; border:0; border-left:1px solid #e4d8cc; border-radius:0 11px 11px 0; background:#fff; color:#594c43; font-size:1.45rem; cursor:pointer; }
  .nav .site-search.is-mobile-open .mobile-search-close { display:grid; place-items:center; }
  .nav-links { display:flex!important; grid-column:auto!important; grid-row:auto; margin-left:auto; justify-content:flex-end!important; gap:2px; }
}

/* --- header-search.css --- */
/* Header search suggestions and filter popover. */
.site-search{position:relative;overflow:visible}.site-search>input{align-self:stretch}.site-search>button{border-radius:0 11px 11px 0}.search-suggestions{position:absolute;z-index:80;top:calc(100% + 9px);left:0;width:100%;min-width:390px;overflow:hidden;border:1px solid #ded2c6;border-radius:14px;background:#fffdf9;box-shadow:0 18px 42px rgba(52,35,23,.2)}.search-suggestions[hidden]{display:none}.suggestion-item{display:grid;grid-template-columns:42px minmax(0,1fr) auto;align-items:center;gap:10px;padding:9px 11px;border-bottom:1px solid #eee5dc;color:#302720;text-decoration:none}.suggestion-item:hover,.suggestion-item.active{background:#f9eee6}.suggestion-cover{display:grid;width:42px;height:54px;place-items:center;overflow:hidden;border-radius:6px;background:#f1e7da}.suggestion-cover img{width:100%;height:100%;object-fit:contain}.suggestion-copy{display:flex;min-width:0;flex-direction:column}.suggestion-copy strong{overflow:hidden;color:#302720;font-family:var(--font-serif);font-size:.78rem;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.suggestion-copy small{overflow:hidden;margin-top:3px;color:#81746b;font-size:.68rem;text-overflow:ellipsis;white-space:nowrap}.suggestion-price{color:#27623f;font-family:var(--font-serif);font-size:.74rem;font-weight:800;white-space:nowrap}.suggestions-all{display:block;padding:11px;color:var(--accent);font-size:.75rem;font-weight:800;text-align:center;text-decoration:none}.suggestions-all:hover{background:#fff3eb}.suggestion-loading,.suggestion-empty{padding:18px;color:#84766c;font-size:.75rem;text-align:center}
.hero.search-hero{display:none;position:fixed;z-index:45;top:72px;left:50%;width:min(1184px,calc(100vw - 32px));max-height:calc(100vh - 90px);margin:0!important;padding:20px 24px 22px!important;transform:translateX(-50%);overflow:visible auto;border-radius:0 0 20px 20px;box-shadow:0 20px 45px rgba(56,37,24,.18);text-align:left}.hero.search-hero.filters-open{display:block}.search-hero .advanced-search>summary{display:none}.search-hero .advanced-search,.search-hero .catalog-search{margin:0}.filter-panel-heading{display:flex;align-items:center;justify-content:space-between;gap:20px;margin-bottom:18px;padding-bottom:14px;border-bottom:1px solid #eadfd3}.filter-panel-heading strong{display:block;font-family:var(--font-serif);font-size:1.08rem;color:#30241e}.filter-panel-heading span{display:block;margin-top:2px;color:#8a796d;font-size:.72rem}.filter-panel-heading-actions{display:flex;align-items:center;gap:13px}.filter-panel-heading-actions>a{color:var(--accent);font-size:.74rem;font-weight:750;text-decoration:none;white-space:nowrap}.filter-panel-heading-actions>a:hover{text-decoration:underline}.filter-panel-close{display:grid;width:34px;height:34px;padding:0;place-items:center;border:1px solid #ded2c6;border-radius:9px;background:#fff;color:#685b52;font-size:1.25rem;line-height:1;cursor:pointer}.filter-panel-close:hover{border-color:var(--accent);color:var(--accent)}.search-hero .search-filters{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:13px 12px;max-width:none;margin:0}.search-hero .search-filters>label{font-size:.72rem}.search-hero .search-filters>label:has([name=author]),.search-hero .search-filters>label:has([name=publisher]),.search-hero .search-filters>label:has([name=category]){grid-column:span 2;order:1}.search-hero .search-filters>label:has([name=format]),.search-hero .search-filters>label:has([name=binding]),.search-hero .search-filters>label:has([name=shop]),.search-hero .search-filters>label:has([name=year]),.search-hero .search-filters>label:has([name=language]){order:2}.search-hero .search-filters>label:has([name=min_price]),.search-hero .search-filters>label:has([name=max_price]),.search-hero .availability-check{order:3}.search-hero .advanced-search-submit{grid-column:span 2;order:3;align-self:end}.search-hero .filter-trigger,.search-hero .search-filters select,.search-hero .search-filters input[type=number]{height:42px;margin-top:5px;border-color:#d9cec2;border-radius:10px}.search-hero .availability-check{height:42px;margin-top:20px;justify-content:center}.search-hero .advanced-search-submit{height:42px;margin-top:20px}.search-hero .filter-panel{z-index:60;min-width:260px}.search-hero .filter-options{max-height:210px}
@media(max-width:900px){.search-hero .search-filters{grid-template-columns:repeat(3,minmax(0,1fr))}.search-hero .search-filters>label:has([name=author]),.search-hero .search-filters>label:has([name=publisher]),.search-hero .search-filters>label:has([name=category]),.search-hero .advanced-search-submit{grid-column:span 1}}
@media(max-width:540px){.search-suggestions{position:fixed;top:62px;left:8px;width:calc(100vw - 16px);min-width:0;max-height:calc(100vh - 72px);overflow:auto}.suggestion-item{grid-template-columns:36px minmax(0,1fr) auto}.suggestion-cover{width:36px;height:48px}.hero.search-hero{top:62px;width:calc(100vw - 16px);max-height:calc(100vh - 72px);padding:14px!important}.filter-panel-heading{align-items:flex-start;margin-bottom:13px;padding-bottom:11px}.filter-panel-heading span{display:none}.filter-panel-heading-actions>a{font-size:.68rem}.search-hero .search-filters{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 8px}.search-hero .search-filters>label:has([name=author]),.search-hero .search-filters>label:has([name=publisher]),.search-hero .search-filters>label:has([name=category]){grid-column:1/-1}.search-hero .availability-check{margin-top:18px}.search-hero .advanced-search-submit{grid-column:1/-1;margin-top:0}.search-hero .filter-panel{position:fixed;top:118px;left:12px;width:calc(100vw - 24px);max-height:calc(100vh - 130px);overflow:auto}}

/* --- postgres-ui.css --- */
/* PostgreSQL storefront compatibility layer. The visual baseline comes from
   the archived 2026-07-18 23:21 SQLite build (style.css/header-search.css). */
.pagination{display:flex;align-items:center;justify-content:center;gap:18px;margin:28px 0 48px}.pagination a{padding:10px 14px;border:1px solid #d9cbbd;border-radius:11px;background:#fffaf3;color:#a94737;font-weight:750;text-decoration:none}.pagination span{color:#81746a}
.nav{overflow:visible}.site-search{overflow:visible}.site-search .header-filters-button{height:42px;border-radius:11px;white-space:nowrap}.site-search-submit{height:42px}
.notice{margin:14px 0}
/* .card-quick-actions/.heart-button/.card-cart-button/.unified-book-card
   (and everything under it)/.book-grid/.collection-grid all moved to
   book-card.css 2026-07-22 (single source of truth for the card component). */
.collection-section{margin:34px 0 48px}.collection-section>header,.catalog-heading{display:flex;align-items:end;justify-content:space-between;gap:18px;margin:0 0 16px}.collection-section>header h2,.catalog-heading h1{margin:4px 0 0}.collection-section>header span,.result-count{color:#81746a}.collection-section>header>a{font-weight:750;color:#a94737}.welcome{display:none}
.book-summary{position:relative;display:grid;grid-template-columns:270px minmax(0,1fr);align-items:start;gap:30px;margin:28px 0;padding:28px;border-radius:24px;background:#fffaf3}.book-summary-cover{display:grid;height:390px;place-items:center}.book-summary-cover img{width:auto;max-width:100%;height:100%;object-fit:contain;border-radius:12px;box-shadow:0 12px 28px rgba(45,31,22,.18)}.book-summary-author{font-size:1.1rem;color:#77695e}.book-summary-author a{color:inherit;text-underline-offset:4px}.book-category-list{display:flex;gap:7px;flex-wrap:wrap;margin-top:14px}.book-category-list .badge{text-decoration:none}.book-summary-about{margin-top:18px;padding-top:15px;border-top:1px solid #e6dbce}.book-summary-about h2{margin:0 0 7px;font:800 .78rem var(--font-sans);letter-spacing:.05em;text-transform:uppercase}.book-summary-description{position:relative;color:#62574f;line-height:1.55}.book-summary-about.is-collapsible:not(.is-expanded) .book-summary-description{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:3}.book-about-toggle{margin-top:8px;padding:0;border:0;background:transparent;color:#a94737;font-weight:750;cursor:pointer}.book-summary-actions{margin-top:16px}.book-summary-actions form{margin:0}.wishlist-primary{display:inline-flex;align-items:center;gap:7px;padding:10px 14px;border:1px solid #d9cbbd;border-radius:11px;background:#fff;color:#5b4c41;font-weight:750;text-decoration:none;cursor:pointer}
.wishlist-primary.is-saved{color:#c73b2f;background:#fdeceb;border-color:rgba(199,59,47,.3)}
.wishlist-primary.is-saved .icon{fill:currentColor}
.admin-collections-panel{width:100%;margin-top:8px}
.admin-collections-toggle{display:inline-block;padding:8px 13px;border:1px dashed #c7ae86;border-radius:11px;background:#faf3e6;color:#805a29;font-size:.78rem;font-weight:750;cursor:pointer}
.admin-collections-body{display:flex;flex-direction:column;gap:10px;max-width:360px;margin-top:10px;padding:14px;border:1px solid #dfd2c5;border-radius:14px;background:#fffaf3}
.admin-collections-list{display:grid;gap:6px;margin:0;padding:0;list-style:none}
.admin-collections-list li{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:6px 0;border-bottom:1px solid #eee4d9;font-size:.82rem}
.admin-collections-list li:last-child{border-bottom:0}
.admin-collections-draft{color:#81746a;font-style:normal;font-size:.7rem}
.admin-collections-new{display:flex;gap:8px;padding-top:8px;border-top:1px solid #eee4d9}
.admin-collections-new input[type=text]{flex:1;min-width:0;padding:8px 10px;border:1px solid #dcd0c3;border-radius:9px}
.work-editions-head{display:flex;align-items:end;justify-content:space-between;gap:20px;margin:36px 2px 17px}.work-editions-head h2{margin:3px 0 0}.work-edition{display:grid;grid-template-columns:112px minmax(0,1fr);gap:18px;padding:16px;border:1px solid #e5d8ca;border-radius:20px;background:#fffaf3}.work-edition.format-electronic{border-color:#c8d9ee;background:linear-gradient(120deg,#f5f9ff,#edf5ff)}.work-edition+.work-edition{margin-top:14px}.work-edition-cover{display:grid;min-height:145px;place-items:center;align-self:start}.work-edition-cover img{width:auto;max-width:100%;height:145px;object-fit:contain;border-radius:8px;box-shadow:0 7px 15px rgba(45,31,22,.18)}.work-edition-content{min-width:0}.work-edition-heading{display:flex;align-items:start;justify-content:space-between;gap:16px}.work-edition-heading h3{margin:8px 0 5px;font-family:var(--font-serif)}.edition-card-chips{display:flex;gap:6px;flex-wrap:wrap}.edition-card-chips span{display:inline-flex;height:25px;align-items:center;padding:0 9px;border:1px solid #e4d6c7;border-radius:999px;background:#f4ebe1;font-size:.64rem;font-weight:750}.edition-card-chips .edition-language-chip{background:#e6f0e4;color:#3e6c42}.edition-heading-meta{color:#81746a;font-size:.78rem}.work-edition-price{text-align:right;white-space:nowrap}.work-edition-price strong{display:block;color:#a94737;font-family:var(--font-serif);font-size:1.35rem}.work-edition-price span{font-size:.7rem;color:#81746a}.edition-offers{margin-top:14px}.offer-row-modern{display:grid;grid-template-columns:minmax(155px,.8fr) minmax(105px,.45fr) minmax(220px,1.2fr) auto;align-items:center;gap:16px;padding:14px;border-top:1px solid #ece2d6;background:rgba(255,255,255,.58)}.offer-row-modern:first-child{border-radius:12px 12px 0 0;border-top:0}.offer-row-modern:last-child{border-radius:0 0 12px 12px}.offer-row-modern.unavailable{opacity:.72}.offer-shop{display:flex;flex-direction:column;align-items:flex-start;gap:5px}.stock-pill{padding:4px 8px;border-radius:999px;background:#e3f2e4;color:#2e7a4d;font-size:.68rem}.stock-pill.out{background:#eee9e3;color:#7b7067}.offer-price-main{font:800 1.2rem var(--font-serif)}.offer-price-old{margin-left:7px;color:#978b80;font:400 .72rem var(--font-sans);text-decoration:line-through}.offer-programs-modern{display:flex;gap:5px;flex-wrap:wrap}.offer-updated{margin-top:4px;color:#91857a;font-size:.65rem}.offer-actions{display:flex;align-items:center;gap:7px}.offer-actions form{margin:0}.offer-cart-button{display:grid;width:40px;height:40px;place-items:center;padding:0;border:1px solid #d9cbbd;border-radius:11px;background:#fff;color:#176d4f;font-size:1.2rem;text-decoration:none;cursor:pointer}.store-link{padding:10px 12px;border-radius:11px;background:#eee9e3;color:#352a23;font-weight:750;text-decoration:none;white-space:nowrap}
.filter-overlay[hidden]{display:none}.filter-overlay{position:fixed;z-index:80;inset:0;background:rgba(38,29,22,.28);backdrop-filter:blur(3px)}.filter-sheet{position:absolute;top:82px;left:50%;box-sizing:border-box;width:min(1180px,calc(100vw - 32px));max-height:calc(100vh - 100px);padding:22px;transform:translateX(-50%);overflow:visible auto;border:1px solid #dfd2c5;border-radius:20px;background:#fffaf3;box-shadow:0 24px 65px rgba(45,31,22,.22)}.filter-sheet>header{display:flex;justify-content:space-between}.filter-sheet>header h2{margin:4px 0}.filter-sheet>header p{margin:4px 0 16px;color:#7a6e65}.filter-sheet>header button{border:0;background:transparent;font-size:1.6rem}.filter-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}.facet{position:relative}.facet summary{display:flex;height:42px;box-sizing:border-box;align-items:center;justify-content:space-between;padding:0 12px;border:1px solid #ded2c6;border-radius:10px;background:#fff;cursor:pointer;list-style:none}.facet summary span{font-size:.68rem;color:#9a8775}.facet-popover{position:fixed;z-index:100;width:300px;padding:10px;border:1px solid #dfd2c5;border-radius:12px;background:#fffdf9;box-shadow:0 16px 38px rgba(65,45,30,.18)}.facet-popover>input{box-sizing:border-box;width:100%;height:38px;margin-bottom:8px}.facet-options{max-height:300px;overflow:auto}.facet-options label{display:flex;align-items:center;gap:8px;padding:8px;border-radius:8px}.facet-options label:hover{background:#f6ede4}.price-field{display:flex;flex-direction:column;gap:5px}.stock-check{display:flex;align-items:center;gap:8px}.filter-sheet>footer{display:flex;align-items:center;justify-content:flex-end;gap:15px;margin-top:18px}.filter-sheet>footer button{padding:11px 18px}.card-cart-dialog{width:min(560px,calc(100vw - 32px));padding:26px;border:1px solid #dfd2c5;border-radius:20px;background:#fffaf3;box-shadow:0 24px 65px rgba(45,31,22,.28)}.card-cart-dialog::backdrop{background:rgba(38,29,22,.42)}.dialog-close-row{display:flex;justify-content:flex-end}.dialog-close-row button{border:0;background:transparent;font-size:1.5rem}.cart-format-actions{display:grid;grid-template-columns:1fr 1fr;gap:10px}.cart-format-actions button{padding:13px}.cart-format-actions button:disabled{opacity:.4}
@media(max-width:1100px){.filter-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(max-width:900px){.offer-row-modern{grid-template-columns:1fr 120px}.offer-programs-modern,.offer-updated{grid-column:1}.offer-actions{grid-column:2;grid-row:1/3}.book-summary{grid-template-columns:210px minmax(0,1fr)}.book-summary-cover{height:320px}}@media(max-width:820px){.filter-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.nav-links{display:none}}@media(max-width:650px){.book-summary{grid-template-columns:1fr;padding:18px}.book-summary-cover{height:300px}.work-edition{grid-template-columns:76px minmax(0,1fr);gap:12px}.work-edition-cover img{height:110px}.work-edition-heading{display:block}.work-edition-price{margin-top:9px;text-align:left}.offer-row-modern{grid-template-columns:1fr}.offer-actions,.offer-programs-modern,.offer-updated{grid-column:1;grid-row:auto}}@media(max-width:600px){.site-search .header-filters-button{font-size:0;width:42px;padding:0}.site-search .header-filters-button span{font-size:1rem}.filter-grid{grid-template-columns:1fr}.filter-sheet{top:70px}}

.icon{display:block;width:21px;height:21px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.nav-links{display:flex;align-items:center;gap:7px}.nav-icon{position:relative;display:grid;width:42px;height:42px;place-items:center;border:1px solid transparent;border-radius:12px;color:#55483e}.nav-icon:hover{border-color:#dfd2c5;background:#f4ece2}.nav-icon>b{position:absolute;top:-5px;right:-5px;display:grid;min-width:19px;height:19px;place-items:center;padding:0 5px;border:2px solid #fffaf3;border-radius:999px;background:#ad4937;color:#fff;font-size:10px;line-height:1}.site-search-icon .icon{width:20px;height:20px}.header-filters-button{display:flex;align-items:center;gap:6px}.header-filters-button .icon{width:18px;height:18px}
body.filters-visible{overflow:auto}.filter-overlay{position:fixed;z-index:80;inset:66px 0 auto;display:flex;justify-content:center;padding:10px 18px;background:transparent;backdrop-filter:none;pointer-events:none}.filter-overlay[hidden]{display:none}.filter-sheet{position:static;width:min(1080px,calc(100vw - 36px));max-height:calc(100vh - 90px);margin:0;padding:16px 18px;transform:none;overflow:visible auto;border-radius:17px;box-shadow:0 18px 48px rgba(45,31,22,.2);pointer-events:auto}.filter-sheet>header p,.filter-sheet>header .eyebrow{display:none}.filter-sheet h2{font-size:1.25rem!important}.filter-grid{grid-template-columns:repeat(5,minmax(0,1fr));gap:9px;margin-top:9px}.facet summary,.price-field,.stock-check{min-height:44px!important;height:44px!important}.filter-sheet>footer{margin-top:12px}.facet-popover{max-height:330px}.facet-options{max-height:245px}
/* .card-quick-actions/.edition-card-price/.edition-price-format sizing
   moved to book-card.css 2026-07-22. .card-count was dead (not used by
   any current template). */
@media(max-width:1100px){.filter-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(max-width:700px){.filter-overlay{inset:62px 0 auto;padding:8px}.filter-sheet{width:calc(100vw - 16px);max-height:calc(100vh - 76px)}.filter-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.nav-links{gap:2px}.nav-icon{width:36px;height:36px}}

.wishlist-grid{align-items:start}.wishlist-card-wrap{min-width:0}.wishlist-settings{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:14px 5px 0;padding:13px;border:1px solid #dfd2c5;border-radius:14px;background:#fffaf3;font-size:.72rem}.wishlist-settings label:first-child{grid-column:1/-1;display:flex;align-items:center;justify-content:space-between}.wishlist-settings input[type=number]{width:105px;padding:7px;border:1px solid #ded2c6;border-radius:8px}.wishlist-settings button{padding:8px;border:0;border-radius:8px;background:#176d4f;color:#fff;font-weight:750}.wishlist-settings .link-danger{background:transparent;color:#a94737}
.cart-heading p{max-width:720px;color:#77695e}.cart-summary{display:flex;flex-direction:column;align-items:flex-end}.cart-summary strong{color:#176d4f;font:800 2rem var(--font-serif)}.cart-summary span,.cart-summary small{color:#81746a}.cart-layout{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:22px;align-items:start}.cart-main{display:grid;gap:17px}.cart-store,.cart-aside{border:1px solid #dfd2c5;border-radius:20px;background:#fffaf3}.cart-store>header{display:flex;align-items:end;justify-content:space-between;padding:18px 20px;border-bottom:1px solid #e8ddd1}.cart-store h2{margin:3px 0 0}.cart-store>header>strong{font:800 1.35rem var(--font-serif);color:#176d4f}.cart-product{display:grid;grid-template-columns:62px minmax(0,1fr) auto auto;align-items:center;gap:14px;padding:14px 20px;border-bottom:1px solid #eee4d9}.cart-product:last-child{border-bottom:0}.cart-product>img{width:58px;height:78px;object-fit:contain;border-radius:7px}.cart-product h3{margin:0;font-size:.9rem}.cart-product p,.cart-product span{margin:3px 0;color:#81746a;font-size:.72rem}.cart-product>strong{white-space:nowrap;color:#6e6156;font-weight:700;font-size:.86rem}.cart-product-actions{display:flex;flex-direction:column;align-items:flex-end;gap:6px;font-size:.7rem;font-weight:700}.cart-product-actions button{padding:0;border:0;background:transparent;color:#a94737}.cart-aside{position:sticky;top:82px;padding:22px}.cart-aside h2{margin:5px 0 20px}.cart-total-row{display:flex;justify-content:space-between;padding:14px 0;border-block:1px solid #e5d9cc}.cart-total-row strong{color:#6e6156;font-weight:700;font-size:.92rem}.single-store-option{display:flex;flex-direction:column;gap:4px;margin-top:18px;padding:13px;border-radius:12px;background:#edf4ed}.single-store-option small{color:#627366}.empty-state>a{display:inline-block;margin-top:8px;color:#a94737;font-weight:750}
.admin-links .panel{transition:.18s ease}.admin-links .panel:hover{transform:translateY(-3px);box-shadow:0 12px 30px rgba(54,38,25,.09)}
@media(max-width:1000px){.cart-layout{grid-template-columns:1fr}.cart-aside{position:static;order:-1}}@media(max-width:820px){.nav-links{display:flex;grid-column:1/-1;justify-content:flex-end}}@media(max-width:650px){.cart-product{grid-template-columns:48px 1fr auto;padding:12px}.cart-product>img{width:45px;height:64px}.cart-product-actions{grid-column:2/-1;flex-direction:row;justify-content:space-between}.wishlist-settings{grid-template-columns:1fr}}
.secondary-action{padding:10px 14px;border:1px solid #d8cabb;border-radius:11px;background:#fffaf3;color:#493d34;font-weight:750}.notification-item{position:relative}.notification-meta{display:flex;align-items:center;justify-content:space-between;color:#8c7d70;font-size:.72rem}.notification-meta b{padding:4px 8px;border-radius:999px;background:#e7f1e9;color:#246243}.notification-item h2{margin:9px 0 5px;font-size:1.15rem}.notification-item p{color:#74675d}.notification-item>a{color:#a94737;font-weight:750}.wishlist-primary .icon,.offer-cart-button .icon{width:19px;height:19px}

/* Search controls: compact icon actions with a calm, continuous field. */
.nav .site-search{max-width:820px;height:48px;border-radius:15px}.site-search>input{padding-inline:8px;font-size:.88rem}.site-search .header-filters-button,.site-search .site-search-submit{display:grid;width:48px;min-width:48px;height:40px;padding:0;place-items:center;border-left:1px solid #e4d8cc;border-radius:0;background:#fff;color:#69594c}.site-search .site-search-submit{margin-left:0;border-radius:0 11px 11px 0;background:#ad4937;color:#fff}.site-search .header-filters-button:hover{background:#f4ece2}.site-search .site-search-submit:hover{background:#963b2e}.site-search .icon{width:21px;height:21px}

/* The filter surface is one stable dropdown; option panels float without reflow. */
.filter-overlay{inset:72px 0 auto;padding-top:6px}.filter-sheet{width:min(1120px,calc(100vw - 32px));padding:14px 16px 16px;overflow:visible}.filter-sheet>header{align-items:center}.filter-sheet>header h2{margin:0!important;font:800 1.1rem var(--font-sans)!important}.filter-sheet>header button{display:grid;width:34px;height:34px;place-items:center;border-radius:9px;background:#f2e9df!important;color:#5d4f44}.filter-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:9px;margin-top:10px}.facet{min-width:0}.facet>summary{height:46px!important;min-height:46px!important;padding:0 12px!important;border-color:#ded2c6!important;border-radius:11px!important}.facet>summary strong{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.facet>summary span{flex:none}.facet-popover{box-sizing:border-box;width:320px;max-height:352px;padding:10px;overflow:hidden;border-radius:14px}.facet-popover>input{height:41px;padding:0 11px;border:1px solid #d8cabb;border-radius:9px}.facet-options{max-height:282px;padding-right:3px}.facet-options label{box-sizing:border-box;display:flex;min-height:40px;align-items:center;padding:7px 8px;line-height:1.25}.facet-options label[hidden]{display:none}.facet-options label input{flex:0 0 18px}.price-field,.stock-check{box-sizing:border-box;height:46px!important;min-height:46px!important;padding:5px 11px!important;border:1px solid #ded2c6!important;border-radius:11px!important;background:#fff!important}.price-field input{font-size:.8rem}.filter-sheet>footer{margin-top:11px;padding-top:11px;border-top:1px solid #eadfd4}.filter-sheet>footer button{padding:10px 15px;border:0;border-radius:10px;background:#ad4937;color:#fff;font-weight:800}

.cart-edition-picker{display:grid;gap:8px;margin-top:15px}.cart-edition-choice{display:flex;width:100%;align-items:center;gap:16px;padding:14px;border:1px solid #dcd0c3;border-radius:13px;background:#fff;color:#332921;text-align:left}.cart-edition-choice:hover{border-color:#8aac93;background:#f2f7f2}.cart-edition-choice.format-electronic{border-color:#c7d8ec;background:#f4f8ff}.cart-edition-cover{display:grid;width:52px;height:74px;flex:0 0 52px;place-items:center;overflow:hidden;border-radius:7px;background:#f1e7da}.cart-edition-cover img{width:100%;height:100%;object-fit:contain}.cart-edition-copy{display:flex;min-width:0;flex:1;flex-direction:column}.cart-edition-language{border-radius:999px;background:#efe4d3;color:#805a29;font-size:.68rem;font-weight:700;font-style:normal;padding:2px 7px;margin-left:4px;vertical-align:middle}.cart-edition-choice small{margin-top:3px;overflow:hidden;color:#81746a;text-overflow:ellipsis;white-space:nowrap}.cart-edition-choice b{flex:none;margin-left:16px;color:#176d4f}.cart-edition-choice.format-electronic b{color:#2c63ae}.ui-toast{position:fixed;z-index:300;right:24px;bottom:24px;padding:12px 16px;border-radius:12px;background:#263c32;color:#fff;box-shadow:0 14px 35px rgba(32,24,18,.25);opacity:0;transform:translateY(12px);pointer-events:none;transition:.18s ease}.ui-toast.is-visible{opacity:1;transform:none}

.work-edition-price-actions{display:flex;align-items:center;gap:11px}.edition-cart-button{display:grid;width:44px;height:44px;place-items:center;border:1px solid #cbdacb;border-radius:12px;background:#e7f1e9;color:#176d4f;cursor:pointer}.edition-cart-button:hover{background:#d9eadc}.edition-cart-button .icon{width:21px;height:21px}.work-edition.format-electronic .edition-cart-button{border-color:#c4d5eb;background:#e4effd;color:#2c63ae}.offer-actions{justify-content:flex-end}

.cart-editor{margin-bottom:18px;border:1px solid #dfd2c5;border-radius:18px;background:#fffaf3}.cart-editor>header{display:flex;align-items:center;justify-content:space-between;padding:15px 18px;border-bottom:1px solid #e8ddd1}.cart-editor h2{margin:0;font-size:1.1rem}.cart-editor>header span{color:#81746a;font-size:.72rem}.cart-editor>article{display:grid;grid-template-columns:48px minmax(0,1fr) auto auto;align-items:center;gap:12px;padding:10px 18px;border-bottom:1px solid #eee4d9}.cart-editor>article:last-child{border-bottom:0}.cart-editor img{width:43px;height:58px;object-fit:contain;border-radius:5px}.cart-editor article>div{display:flex;min-width:0;flex-direction:column}.cart-editor article>div strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cart-editor article>div span{color:#81746a;font-size:.7rem}.cart-editor form{display:flex;align-items:end;gap:6px}.cart-editor label{display:flex;flex-direction:column;gap:3px;color:#81746a;font-size:.65rem}.cart-editor input{width:64px;padding:7px;border:1px solid #d8cabb;border-radius:8px}.cart-editor button{padding:8px 10px;border:0;border-radius:8px;background:#eee5db;color:#493d34;font-weight:700}.cart-editor .link-danger{background:transparent;color:#a94737}.cart-plan-tabs{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px;margin-bottom:18px}.cart-plan-tabs button{display:grid;grid-template-columns:1fr auto;gap:3px 14px;padding:15px 18px;border:1px solid #dfd2c5;border-radius:15px;background:#fffaf3;color:#493d34;text-align:left}.cart-plan-tabs button.is-active{border-color:#83aa8f;background:#edf5ef;box-shadow:0 0 0 2px rgba(73,130,91,.08)}.cart-plan-tabs span{font-weight:800}.cart-plan-tabs strong{grid-row:1/3;grid-column:2;align-self:center;font:800 1.2rem var(--font-serif);color:#211a14}.cart-plan-tabs small{color:#81746a}.cart-plan-panel[hidden]{display:none}
@media(max-width:900px){.filter-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(max-width:700px){.nav .site-search{height:44px}.filter-overlay{inset:64px 0 auto}.filter-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.cart-plan-tabs{grid-template-columns:1fr}.cart-editor>article{grid-template-columns:42px 1fr}.cart-editor form{grid-column:2}.cart-editor>article>form:last-child{grid-column:2;justify-self:end;margin-top:-41px}}@media(max-width:430px){.filter-grid{grid-template-columns:1fr}.filter-sheet{max-height:calc(100vh - 72px);overflow:auto}.facet-popover{width:calc(100vw - 20px)}.site-search .header-filters-button,.site-search .site-search-submit{width:42px;min-width:42px}}

/* Stable multi-select feedback: choices stay aligned and the popover may
   escape the compact filter sheet without forcing a second scrollbar. */
.facet.has-selection>summary{border-color:#7da58a!important;background:#f1f7f2!important}
.facet.has-selection>summary span{color:#176d4f!important;font-weight:800}
.facet-options label:has(input:checked){background:#edf5ef;color:#176d4f;font-weight:700}
.facet-popover{overscroll-behavior:contain}
.facet-popover>input:focus{outline:3px solid rgba(44,99,174,.15);border-color:#6d8fbd}
.filter-sheet>footer a{padding:9px 4px;color:#6e5c4e;font-weight:700}

/* --- card-refresh.css --- */
/* Book detail page hero cover (.book-summary-cover*) and edition-list
   cover treatment (.work-edition-cover) - NOT the catalog card grid, see
   book-card.css for that (.unified-book-card etc. used to live here too,
   moved out 2026-07-22 during the CSS consolidation). */

/* The hero cover previously used a fixed 270x390 box with its own fill
   color - for a narrower-than-average cover this showed as a big empty
   colored rectangle around a much smaller image. No fixed height, no
   background: the image just renders at its own aspect ratio within the
   width cap, so the box is never bigger than the cover actually is. */
.book-summary-cover {
  display: block !important;
  width: 100% !important;
  height: auto !important;
  background: none !important;
  padding: 0 !important;
}
.book-summary-cover img {
  display: block !important;
  width: 100% !important;
  height: auto !important;
  max-width: 100%;
  object-fit: contain !important;
  object-position: center;
  margin: 0 auto !important;
}

/* Cover + goodreads badge stacked as one column, sized to the cover's own
   width (see .book-summary-cover above) - the badge previously sat
   absolutely over the top-right corner of the whole summary block, which
   overlapped long two-line titles. Normal flow under the cover instead. */
.book-summary-cover-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 270px;
  flex: 0 0 auto;
}
@media (max-width: 760px) {
  .book-summary-cover-wrap {
    width: 180px;
  }
}
@media (max-width: 520px) {
  .book-summary-cover-wrap {
    width: 160px;
  }
}

/* Placeholder for the hero cover specifically (book-card.css has its own
   copy of the shared .book-cover-placeholder/.placeholder-icon rules for
   catalog cards - duplicated on purpose rather than shared across files,
   so neither depends on the other still existing). */
.book-summary-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  height: 100%;
  padding: 14px;
  color: #a8937d;
  text-align: center;
}
.book-summary-placeholder .placeholder-icon {
  width: 34%;
  max-width: 46px;
  height: auto;
  opacity: 0.5;
}
.book-summary-placeholder.small .placeholder-icon {
  max-width: 30px;
}
.book-summary-placeholder small {
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.3;
}
.book-summary-placeholder[hidden] {
  display: none !important;
}

/* .work-edition and .offer-row-modern both set display:grid
   unconditionally (postgres-ui.css/style.css), which - being an author
   stylesheet - beats the browser's own default [hidden]{display:none}
   (a user-agent stylesheet rule, always overridden by any author rule
   regardless of specificity/order). That silently broke the offer-filter
   buttons on the book detail page: their JS toggles the `hidden` property
   correctly, but the row/edition stayed visually rendered anyway. */
.work-edition[hidden],
.offer-row-modern[hidden] {
  display: none !important;
}

.book-summary-ratings {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
}
.goodreads-badge,
.reader-rating-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 11px;
  border-radius: 999px;
  background: #fff6da;
  color: #6b5420;
  font-size: 0.82rem;
  font-weight: 700;
  white-space: nowrap;
}
.goodreads-badge b,
.reader-rating-badge b {
  font-family: var(--font-serif);
}
.goodreads-badge img {
  width: 14px;
  height: 14px;
}

/* Same never-crop rule as book-card.css's cover image, for the per-edition
   cover thumbnails in the book detail page's edition list. */
.work-edition-cover img {
  width: auto !important;
  height: 100% !important;
  max-width: 100%;
  object-fit: contain !important;
  object-position: center;
}

.edition-heading-meta {
  overflow-wrap: anywhere;
}
.work-edition > .edition-offers {
  grid-column: 1 / -1;
  margin-top: 0;
}

/* Wishlist page's own goodreads-rating chip (app/templates/user/wishlist.html)
   - a different, simpler layout than the catalog card's .card-rating-hero
   overlay, not part of the shared book-card component. */
.wishlist-ratings {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
}
.card-goodreads,
.card-reader-rating {
  color: #8a6d1f;
  font-size: 0.74rem;
  font-weight: 700;
  white-space: nowrap;
}
.card-goodreads {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.card-goodreads img {
  width: 12px;
  height: 12px;
}
.card-reader-rating { color: #76551e; }

/* --- ui-polish.css --- */
/* Search bar + filters: deliberate final layout, loaded after card-refresh.css
   so it wins the cascade cleanly rather than adding another patch on top of
   the accumulated rules in style.css/postgres-ui.css. */

/* --- Search bar: consistent height, evenly aligned icon/input/buttons ---
   Deliberately no overflow:hidden on the container: it was clipping both
   the search-suggestions dropdown (positioned below this box, so it was
   rendering into the DOM correctly but invisible on screen) and the
   input's focus ring. The input gets matching rounded corners directly
   instead, since it's the only child that could otherwise show a square
   corner poking out from under the container's own rounding. */
.nav .site-search {
  display: flex;
  align-items: stretch;
  height: 48px;
  border-radius: 14px;
}
.nav .site-search-icon {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}
.nav .site-search input {
  flex: 1 1 auto;
  min-width: 0;
  align-self: stretch;
  height: auto;
  padding-left: 16px;
  border-radius: 14px 0 0 14px;
}
.nav .site-search input:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--accent, #a74434);
}
.nav .site-search .header-filters-button,
.nav .site-search .site-search-submit {
  flex: 0 0 48px;
  width: 48px;
  height: auto;
  align-self: stretch;
  border-radius: 0;
  border-left: 1px solid #e4d8cc;
}
.nav .site-search .site-search-submit {
  border-left: 0;
  border-radius: 0 14px 14px 0;
}

/* --- Filter facet dropdowns: clearer states, smoother open/close --- */
.facet-popover {
  transform-origin: top left;
  animation: facet-pop-in 0.14s ease-out;
}
@keyframes facet-pop-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .facet-popover { animation: none; }
}

.facet > summary {
  transition: border-color 0.15s ease, background 0.15s ease;
}
.facet > summary::-webkit-details-marker {
  display: none;
}
.facet > summary:after {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  margin-left: 4px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  opacity: 0.55;
  transform: rotate(45deg);
  transition: transform 0.15s ease;
}
.facet[open] > summary:after {
  transform: rotate(-135deg);
}

.facet-options label {
  transition: background 0.12s ease;
  cursor: pointer;
}
.facet-options label:has(input:checked) {
  font-weight: 700;
}

/* A visible, easy target for clearing one facet's selection without
   reopening it and unchecking every box by hand. */
.facet-clear {
  display: none;
  padding: 6px 8px;
  margin-top: 2px;
  border: 0;
  background: transparent;
  color: var(--accent, #a74434);
  font-size: 0.72rem;
  font-weight: 700;
  cursor: pointer;
  text-align: left;
}
.facet.has-selection .facet-clear {
  display: block;
}

/* The filter sheet's own primary/secondary actions, distinguished clearly. */
.filter-sheet > footer > a {
  padding: 10px 6px;
  font-weight: 700;
}
.filter-sheet > footer > button {
  box-shadow: 0 3px 0 rgba(0, 0, 0, 0.12);
}
.filter-sheet > footer > button:active {
  transform: translateY(2px);
  box-shadow: none;
}

@media (max-width: 540px) {
  .nav .site-search .header-filters-button,
  .nav .site-search .site-search-submit {
    flex-basis: 42px;
    width: 42px;
  }
}

/* Price-range / availability filter fields: the label wraps its text label
   AND the input in a column, but a fixed 46px height (from the "Search
   controls" patch) can't fit both - and the global `input{border;background}`
   rule then gives the input its own visible box, which overflows out the
   bottom of the label looking like a second, unstyled field underneath.
   Fix: auto height sized to actual content, and the input styled to sit
   invisibly inside the label's own box instead of drawing a second one. */
.price-field,
.stock-check {
  height: auto !important;
  min-height: 64px !important;
  padding: 9px 13px !important;
}
.price-field {
  justify-content: center;
  gap: 4px;
}
.price-field > input {
  height: 22px;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  font-size: 0.86rem;
}
.stock-check {
  flex-direction: row;
  align-items: center;
  justify-content: flex-start !important;
  gap: 9px;
}
.stock-check input {
  width: auto !important;
}

/* Site-wide safety net: an unexpectedly long word (long URL-like author
   string, a title with no spaces, etc.) must wrap or ellipsize, never force
   a container wider than its column and never sit half-hidden with no
   indication there's more text. */
.notification-item h2,
.notification-item p,
.cart-product h3,
.cart-editor article > div strong,
.suggestion-copy strong,
.suggestion-copy small,
.library-list h2 {
  overflow-wrap: anywhere;
}

/* --- ui-polish-2.css --- */
/* Second UI polish pass: interactive feedback, bigger uncropped card covers,
   distinct header bubble colors, tighter filters, horizontally-scrolling
   homepage collections. Loaded last so it wins the cascade cleanly. */

/* --- Universal interactive feedback: every button/link-button/nav icon --- */
button,
.btn,
.nav-icon,
.header-filters-button,
.site-search-submit,
.card-cart-button,
.heart-button,
.edition-cart-button,
.store-link,
.link-button,
.wishlist-primary,
a.badge {
  transition: transform 0.12s ease, box-shadow 0.12s ease, background-color 0.12s ease,
    border-color 0.12s ease, color 0.12s ease, opacity 0.12s ease;
}
button:not(:disabled):hover,
.btn:hover,
.nav-icon:hover,
.card-cart-button:hover,
.heart-button:hover,
.edition-cart-button:hover,
.store-link:hover,
.wishlist-primary:hover {
  transform: translateY(-1px);
}
button:not(:disabled):active,
.btn:active,
.nav-icon:active,
.card-cart-button:active,
.heart-button:active,
.edition-cart-button:active,
.store-link:active,
.wishlist-primary:active {
  transform: translateY(1px);
  transition-duration: 0.05s;
}
a:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--accent, #a74434);
  outline-offset: 2px;
}

/* .heart-button styling moved to book-card.css 2026-07-22. */

/* --- Header bubbles: cart most prominent, then wishlist, then notifications --- */
.nav-icon {
  position: relative;
  display: flex !important;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  line-height: 0;
  /* Most nav icons are <a> tags with no native chrome to begin with; the
     notification bell is a real <button> (it opens a dropdown, not a link),
     so it needs its own reset or the browser's default button background/
     border/font/text-color show through, distinct from every other icon
     here. `color:inherit` alone isn't enough - style.css's `.nav-links a`
     rule (color:#5e554e) only ever matched <a> tags, so a plain button
     fell back to the ancestor's darker body ink instead of matching. */
  border: 0;
  background: transparent;
  padding: 0;
  color: #5e554e;
  font: inherit;
  cursor: pointer;
}
.nav-icon[aria-expanded="true"] {
  background: #efe4d3;
  border-radius: 999px;
}
.nav-icon .icon {
  display: block;
  width: 23px;
  height: 23px;
  margin: 0;
}
.nav-icon > b {
  border-width: 2px;
}
/* style.css's `.nav-icon > b { display:grid }` outranks the browser's own
   [hidden] rule (a class+element selector beats a bare attribute selector),
   so a badge holding "0" stayed visible even though the template already
   marks it hidden. Restore the hide. */
.nav-icon > b[hidden] {
  display: none !important;
}
.nav-icon[href*="/cart"] > b {
  background: #a74434;
}
.nav-icon[href*="/wishlist"] > b {
  background: #c78a2e;
}
.nav-icon[data-nav="notifications"] > b {
  background: #3a6ea5;
}

/* --- Discount tag: overlaid on the cover, top-left --- */
.card-discount-tag {
  position: absolute;
  z-index: 7;
  top: 18px;
  left: 18px;
  padding: 5px 10px;
  border-radius: 999px;
  background: #a74434;
  color: #fff;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  box-shadow: 0 4px 12px rgba(55, 39, 26, 0.2);
}

/* Book-card price row/counts/cover rules all moved to book-card.css
   2026-07-22 (single source of truth for the whole card component). */

/* Card cover fixes (empty-space gap, hover-crop bug) moved to
   book-card.css 2026-07-22, along with the reasoning behind each. */

/* --- Filters: compact, dropdown never wider than its button --- */
.filter-grid {
  gap: 8px;
}
.facet-popover {
  min-width: 0;
}
.facet-options label {
  padding: 6px 7px;
  font-size: 0.82rem;
}

/* The availability toggle gets a visibly different treatment from the
   facet dropdown buttons, so the filter row isn't a wall of identical-
   looking pills (price now has its own dedicated slider styling below). */
.stock-check {
  background: #eef6ee !important;
  border-color: #bfdcc2 !important;
}
.stock-check input[type="checkbox"] {
  accent-color: #2f7a45;
}

/* Homepage collection scroll-row (.scroll-row-wrap/.book-row-scroll/
   .scroll-arrow*) moved to book-card.css 2026-07-22. */

/* --- 404/500 error pages --- */
.error-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  max-width: 480px;
  margin: 60px auto;
  padding: 40px;
  text-align: center;
}
.error-code {
  font-family: var(--font-serif);
  font-size: 4rem;
  font-weight: 800;
  color: var(--accent, #a74434);
  opacity: 0.4;
  line-height: 1;
}
.error-page h1 {
  margin: 0;
}
.error-page p {
  color: var(--muted);
}
.error-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 10px;
}

/* --- Shops page: had no dedicated styling at all before (plain stacked
   list, generic .status pill inherited from jobs.css) --- */
.shop-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
  margin-top: 14px;
}
.shop-grid .panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 18px;
}
.shop-grid .panel-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.shop-grid .panel-title h2 {
  margin: 0;
  font-size: 1.05rem;
}
.shop-grid .status {
  padding: 4px 10px;
  border-radius: 999px;
  background: #eee9e3;
  color: var(--muted, #7b7067);
  font-size: 0.72rem;
  font-weight: 700;
  white-space: nowrap;
}
.shop-grid .status.ok {
  background: #dff1e5;
  color: #17663f;
}
.shop-grid .status.pending {
  background: #fbeee0;
  color: #8a5a1f;
  cursor: help;
}
.shop-grid a {
  color: var(--accent, #a74434);
  font-weight: 700;
  text-decoration: none;
}
.shop-grid a:hover {
  text-decoration: underline;
}
.shop-grid p {
  margin: 0;
  font-size: 0.85rem;
}
.shop-grid .shop-edit {
  margin-top: 6px;
  border-top: 1px solid var(--line);
  padding-top: 8px;
}
.shop-grid .shop-edit summary {
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--accent, #a74434);
}
.shop-edit-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}
.shop-edit-form label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.75rem;
  color: var(--muted, #7b7067);
  font-weight: 700;
}
.shop-edit-form input[type="text"],
.shop-edit-form input[type="url"],
.shop-edit-form input[type="number"],
.shop-edit-form select {
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font: inherit;
  font-weight: 400;
  color: var(--ink);
}
.delivery-method-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.delivery-method-list li {
  font-size: 0.82rem;
  color: var(--muted, #7b7067);
}
.delivery-method-table {
  width: 100%;
  margin-top: 8px;
  border-collapse: collapse;
  font-size: 0.78rem;
}
.delivery-method-table th,
.delivery-method-table td {
  padding: 5px 6px;
  border-bottom: 1px solid var(--line);
  text-align: left;
}
.delivery-method-table th {
  color: var(--muted, #7b7067);
  font-weight: 700;
}
.delivery-method-table button {
  border: 0;
  background: transparent;
  color: var(--accent, #a74434);
  cursor: pointer;
  font-weight: 700;
}
.delivery-method-form {
  margin-top: 10px;
  border-top: 1px dashed var(--line);
  padding-top: 8px;
}
.shop-edit-checkbox {
  flex-direction: row !important;
  align-items: center;
  gap: 6px !important;
}
.shop-edit-form button {
  align-self: flex-start;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

/* --- Search-as-you-type results: same visual language as the wishlist
   rows (rounded cover thumb, title/author stack, bold price) instead of
   the old dense single-line list. --- */
.suggestion-item {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line, #eee5dc);
  border-radius: 12px;
  color: #302720;
  text-decoration: none;
  transition: background-color 0.12s ease;
}
.suggestion-item:first-child {
  margin-top: 4px;
}
.suggestion-item:hover,
.suggestion-item.active {
  background: #f4eee4;
}
.suggestion-cover {
  display: grid;
  width: 56px;
  height: 78px;
  place-items: center;
  overflow: hidden;
  border-radius: 10px;
  background: linear-gradient(145deg, #efe4d3, #f7f1e7);
}
.suggestion-cover img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.suggestion-copy {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 3px;
}
.suggestion-copy strong {
  display: -webkit-box;
  overflow: hidden;
  color: #211a14;
  font-family: var(--font-serif);
  font-size: 0.86rem;
  line-height: 1.3;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}
.suggestion-copy small {
  overflow: hidden;
  color: var(--muted, #81746b);
  font-size: 0.74rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.suggestion-ratings {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  margin-top: 1px;
  color: #80611f;
  font-size: 0.7rem;
  font-weight: 700;
}
.suggestion-reader-rating,
.suggestion-goodreads-rating {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.suggestion-goodreads-rating img {
  width: 11px;
  height: 11px;
  margin-right: 3px;
}
.suggestion-price {
  flex: 0 0 auto;
  color: #211a14;
  font-family: var(--font-serif);
  font-size: 0.86rem;
  font-weight: 800;
  white-space: nowrap;
}
.suggestion-price.price-discounted {
  color: var(--red, #a74434);
}
.suggestion-item.out-of-stock {
  opacity: 0.55;
}
.suggestion-item.out-of-stock .suggestion-price {
  font-weight: 500;
}

/* .unified-book-card price color rule moved to book-card.css 2026-07-22. */
.offer-price-main {
  color: #211a14;
}
.offer-price-main.price-discounted {
  color: var(--red, #a74434);
}

/* --- Merge review: one duplicate-book candidate at a time, human decides --- */
.merge-review-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 10px;
}
.merge-review-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.merge-review-score {
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--muted);
  font-size: 0.78rem;
}
.merge-review-score strong {
  font-family: var(--font-serif);
  font-size: 1.3rem;
  color: var(--accent, #a74434);
}
.merge-review-score small {
  margin-left: auto;
  text-align: right;
}
.merge-review-pair {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
}
.merge-review-book {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  min-width: 0;
}
.merge-review-book img,
.merge-review-book .book-cover-placeholder {
  flex: 0 0 auto;
  width: 56px;
  height: 78px;
  border-radius: 8px;
  object-fit: contain;
  background: #f4eadc;
}
.merge-review-book h3 {
  margin: 0 0 3px;
  font-size: 0.92rem;
  line-height: 1.3;
}
.merge-review-book p {
  margin: 0 0 4px;
  color: var(--muted);
  font-size: 0.8rem;
}
.merge-review-book small {
  color: var(--muted);
  font-size: 0.7rem;
}
.merge-review-vs {
  color: var(--muted);
  font-weight: 800;
  font-size: 0.8rem;
  text-transform: uppercase;
}
.merge-review-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.merge-review-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.merge-review-actions button {
  border: 0;
  border-radius: 10px;
  padding: 9px 16px;
  font-weight: 750;
  cursor: pointer;
}
.merge-review-actions button[type="submit"]:not(.secondary) {
  background: var(--green, #176d4f);
  color: #fff;
}
.merge-review-actions .secondary {
  background: #eee5db;
  color: var(--ink);
}
@media (max-width: 700px) {
  .merge-review-pair {
    grid-template-columns: 1fr;
  }
  .merge-review-vs {
    display: none;
  }
}

/* --- Author alias review: explicit canonical name, never automatic --- */
.author-merge-review-list {
  display: grid;
  gap: 16px;
  margin-top: 10px;
}
.author-merge-review-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 16px 22px;
  align-items: start;
}
.author-merge-review-score {
  display: grid;
  gap: 2px;
  min-width: 76px;
  color: var(--muted);
  font-size: 0.72rem;
}
.author-merge-review-score strong {
  color: var(--accent, #a74434);
  font: 800 1.35rem var(--font-serif);
}
.author-merge-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: 14px;
  align-items: center;
}
.author-merge-pair > div {
  display: grid;
  gap: 4px;
  min-width: 0;
}
.author-merge-pair strong {
  overflow-wrap: anywhere;
}
.author-merge-pair small {
  color: var(--muted);
}
.author-merge-pair > span {
  color: var(--muted);
  font-weight: 800;
}
.author-merge-review-actions {
  display: flex;
  grid-column: 1 / -1;
  justify-content: space-between;
  gap: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.author-merge-review-actions form:first-child {
  display: flex;
  flex-direction: column;
  flex: 1;
  align-items: stretch;
  gap: 10px;
}
.author-merge-variants {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 8px;
  margin: 0;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
}
.author-merge-variants legend {
  padding: 0 4px;
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 700;
}
.author-merge-variants label {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 7px;
  border-radius: 8px;
  background: #fffaf3;
  cursor: pointer;
}
.author-merge-variants input {
  width: 17px;
  min-width: 17px;
  height: 17px;
  margin: 2px 0 0;
  accent-color: var(--green, #176d4f);
}
.author-merge-variants span {
  display: grid;
  gap: 2px;
  min-width: 0;
}
.author-merge-variants small {
  color: var(--muted);
}
.author-merge-variants small a {
  color: inherit;
  text-decoration: underline;
}
.author-merge-books {
  display: flex !important;
  flex-wrap: wrap;
  gap: 3px 7px;
  margin-top: 2px;
}
.author-merge-books a {
  max-width: 100%;
  color: var(--ink);
  font-size: 0.73rem;
  font-weight: 500;
  line-height: 1.3;
  overflow: hidden;
  text-decoration: underline;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.author-merge-review-actions label {
  display: grid;
  flex: 1;
  gap: 5px;
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 700;
}
.author-merge-review-actions input {
  min-width: 0;
  height: 40px;
  padding: 8px 11px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: #fff;
  color: var(--ink);
}
.author-merge-review-actions button {
  min-height: 40px;
  border: 0;
  border-radius: 9px;
  padding: 9px 14px;
  background: var(--green, #176d4f);
  color: #fff;
  font-weight: 750;
  cursor: pointer;
}
.author-merge-review-actions .secondary {
  background: #eee5db;
  color: var(--ink);
}
@media (max-width: 700px) {
  .author-merge-review-card,
  .author-merge-pair {
    grid-template-columns: 1fr;
  }
  .author-merge-pair > span {
    display: none;
  }
  .author-merge-review-actions,
  .author-merge-review-actions form:first-child {
    flex-direction: column;
    align-items: stretch;
  }
}

/* --- Wishlist: purpose-built management rows instead of browse cards ---
   This page is for managing saved books (price/availability alerts,
   removal), not browsing, so it gets its own compact row layout rather
   than reusing the catalog card grid. */
.wishlist-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 6px;
}
.wishlist-row {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 18px;
  padding: 16px 18px;
  border: 1px solid var(--line, #e8ded2);
  border-radius: 18px;
  background: var(--card, #fffaf3);
  box-shadow: 0 8px 22px rgba(52, 36, 21, 0.05);
}
.wishlist-row.is-discounted {
  border-color: #e8c3ab;
}
.wishlist-row-cover {
  display: grid;
  flex: 0 0 auto;
  width: 84px;
  height: 112px;
  place-items: center;
  overflow: hidden;
  border-radius: 12px;
  background: linear-gradient(145deg, #efe4d3, #f7f1e7);
}
.wishlist-row-cover img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.wishlist-row-copy {
  min-width: 0;
}
.wishlist-row-copy h3 {
  margin: 0 0 4px;
  font-size: 1rem;
  line-height: 1.3;
}
.wishlist-row-copy h3 a {
  color: inherit;
  text-decoration: none;
}
.wishlist-row-copy h3 a:hover {
  text-decoration: underline;
}
.wishlist-row-author {
  margin: 0;
  overflow: hidden;
  color: var(--muted);
  font-size: 0.84rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wishlist-row-meta {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 8px;
  color: var(--muted);
  font-size: 0.78rem;
}
.wishlist-row-counts {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.wishlist-row-counts .icon {
  width: 15px;
  height: 15px;
  vertical-align: -3px;
  margin-right: 2px;
}
.wishlist-row-price {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  min-width: 110px;
}
.wishlist-row-price .card-price-row strong {
  /* No color override here on purpose - inherit the same black/red/blue
     price-coloring rules book-card.css already applies everywhere else
     (home, search, book page), so a wishlist price isn't a different
     color just because of where it's shown. */
  font-family: var(--font-serif);
  font-size: 1.15rem;
}
.wishlist-row-price .card-discount-tag.static {
  position: static;
  margin-bottom: 4px;
  box-shadow: none;
}
.wishlist-row-actions {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}
.wishlist-notify {
  position: relative;
}
.wishlist-notify summary {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 700;
  white-space: nowrap;
  list-style: none;
  cursor: pointer;
}
.wishlist-notify summary::-webkit-details-marker {
  display: none;
}
.wishlist-notify summary .icon {
  width: 15px;
  height: 15px;
}
.wishlist-notify[open] summary {
  border-color: #7da58a;
  background: #f1f7f2;
  color: #176d4f;
}
.wishlist-notify-form {
  position: absolute;
  z-index: 20;
  top: calc(100% + 8px);
  right: 0;
  display: flex;
  flex-direction: column;
  width: 290px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 16px 38px rgba(65, 45, 30, 0.18);
}
.wishlist-notify-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.wishlist-notify-head strong {
  font-size: 0.92rem;
}
.wishlist-notify-head span {
  color: var(--muted);
  font-size: 0.72rem;
}
.wishlist-switch-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  font-size: 0.84rem;
}
.wishlist-switch {
  position: relative;
  display: inline-block;
  flex: 0 0 auto;
  width: 38px;
  height: 22px;
}
.wishlist-switch input {
  position: absolute;
  z-index: 1;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.wishlist-switch i {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: #e3d9c9;
  transition: background-color 0.15s ease;
}
.wishlist-switch i::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  transition: transform 0.15s ease;
}
.wishlist-switch input:checked + i {
  background: #2f7a45;
}
.wishlist-switch input:checked + i::before {
  transform: translateX(16px);
}
.wishlist-switch input:focus-visible + i {
  outline: 2px solid var(--accent, #a74434);
  outline-offset: 2px;
}
.wishlist-target {
  display: grid;
  gap: 5px;
  margin: 6px 0 14px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.76rem;
}
.wishlist-target input {
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
}
.wishlist-notify-save {
  border: 0;
  border-radius: 10px;
  padding: 10px 14px;
  background: var(--red, #a74434);
  color: #fff;
  font-weight: 700;
  cursor: pointer;
}
.wishlist-notify-danger {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
  text-align: center;
}
.wishlist-notify-danger .link-danger {
  border: 0;
  background: transparent;
  color: #a94737;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
}
@media (max-width: 760px) {
  .wishlist-row {
    grid-template-columns: 64px 1fr;
    grid-template-areas: "cover copy" "cover price" "actions actions";
    row-gap: 8px;
  }
  .wishlist-row-cover {
    grid-area: cover;
    width: 64px;
    height: 88px;
  }
  .wishlist-row-copy {
    grid-area: copy;
  }
  .wishlist-row-price {
    grid-area: price;
    align-items: flex-start;
  }
  .wishlist-row-actions {
    grid-area: actions;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
  .wishlist-notify-form {
    right: auto;
    left: 0;
    width: calc(100vw - 64px);
    max-width: 300px;
  }
}

/* --- Notification bell dropdown --- */
.notif-root {
  position: relative;
}
.notif-panel {
  position: absolute;
  z-index: 60;
  top: calc(100% + 10px);
  right: 0;
  display: flex;
  flex-direction: column;
  width: 380px;
  max-height: 70vh;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: #fff;
  box-shadow: 0 20px 50px rgba(65, 45, 30, 0.22);
}
.notif-panel[hidden] {
  display: none;
}
.notif-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}
.notif-panel-head strong {
  font-size: 0.95rem;
}
.notif-mark-all {
  border: 0;
  background: transparent;
  color: #3a6ea5;
  font-size: 0.74rem;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.notif-panel-list {
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  max-height: calc(70vh - 96px);
}
.notif-panel-foot {
  padding: 11px 16px;
  border-top: 1px solid var(--line);
  color: var(--red);
  font-size: 0.8rem;
  font-weight: 750;
  text-align: center;
}
.notif-empty {
  padding: 26px 16px;
  color: var(--muted);
  font-size: 0.85rem;
  text-align: center;
}
.notif-card {
  position: relative;
  display: flex;
  gap: 10px;
  padding: 13px 16px;
  border-bottom: 1px solid #f2ebe1;
  color: inherit;
  transition: background-color 0.12s ease;
}
.notif-card:last-child {
  border-bottom: 0;
}
.notif-card:hover {
  background: #fbf6ee;
}
.notif-card.is-unread {
  background: #f4f8fc;
}
.notif-card.is-unread:hover {
  background: #eef4fa;
}
.notif-dot {
  flex: 0 0 8px;
  width: 8px;
  height: 8px;
  margin-top: 6px;
  border-radius: 50%;
  background: #3a6ea5;
}
.notif-card-body {
  min-width: 0;
  flex: 1;
}
.notif-card-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.notif-card-top strong {
  font-size: 0.86rem;
  line-height: 1.3;
}
.notif-card-top time {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 0.68rem;
}
.notif-card p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.4;
}
/* Reuse the same card look on the full /me/notifications page, just wider
   and standalone (not clipped inside a fixed-height dropdown). */
.notif-card-page {
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
}
.notif-card-page.is-unread {
  background: #f4f8fc;
  border-color: #bcd3e8;
}
@media (max-width: 480px) {
  .notif-panel {
    position: fixed;
    top: 68px;
    right: 10px;
    left: 10px;
    width: auto;
  }
}

/* --- Shop logo next to each offer's store name on the book page --- */
.offer-shop-name {
  display: flex;
  align-items: center;
  gap: 8px;
}
.offer-shop-logo {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  border-radius: 5px;
  object-fit: contain;
  background: #fff;
}
.offer-shop strong {
  margin-bottom: 0 !important;
}

/* --- Profile dropdown panel --- */
.profile-panel-body {
  padding: 14px 16px;
}
.profile-panel-email {
  margin: 0 0 12px;
  color: var(--muted);
  font-size: 0.82rem;
}
.profile-panel-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-bottom: 14px;
}
.profile-panel-stats a {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 10px 6px;
  border: 1px solid var(--line);
  border-radius: 12px;
  text-align: center;
}
.profile-panel-stats a:hover {
  background: #fbf6ee;
}
.profile-panel-stats strong {
  font: 800 1.1rem var(--font-serif);
  white-space: nowrap;
}
.profile-panel-stats .profile-panel-stat-label {
  color: var(--muted);
  font: 600 0.68rem var(--font-sans);
  margin-left: 0.18em;
}
.profile-panel-links {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.profile-panel-links a,
.profile-panel-links form {
  margin: 0;
}
.profile-panel-links a,
.profile-panel-links .link-button {
  padding: 8px 4px;
  color: var(--ink);
  font-size: 0.84rem;
  font-weight: 700;
  text-align: left;
  background: none;
  border: 0;
  cursor: pointer;
}
.profile-panel-links .link-button {
  width: 100%;
  color: var(--red);
}
.profile-panel-links a:hover,
.profile-panel-links .link-button:hover {
  text-decoration: underline;
}
/* The legacy mobile rule `.nav-links a{display:none}` (plus a `:first-child`
   re-show) in style.css was meant for the top-level text nav, but the profile
   and notification popups live *inside* .nav-links - so on phones every panel
   link except the first vanished (the "Адміністрування" admin link and the
   "Повний профіль" footer among them). Restore panel links here; the higher
   specificity (.nav-*-root .*-panel a) beats the leaking `.nav-links a`. */
@media (max-width: 920px) {
  .nav-profile-root .profile-panel-links a,
  .nav-profile-root .profile-panel .notif-panel-foot,
  .nav-notifications-root .notif-panel a {
    display: block;
  }
}

/* --- Shared informational footer and its temporary pages --- */
.site-footer {
  margin-top: 56px;
  border-top: 1px solid #e3d7ca;
  background: rgba(255, 250, 243, 0.72);
}
.site-footer-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(15rem, 0.7fr);
  gap: 26px 48px;
  padding-top: 28px;
  padding-bottom: 22px;
}
.site-footer-intro p {
  max-width: 30rem;
  margin: 7px 0 0;
  color: #77695e;
  font-size: 0.82rem;
  line-height: 1.5;
}
.site-footer-brand {
  color: #211a14;
  font: 800 1.3rem var(--font-serif);
  text-decoration: none;
}
/* Two links, sitting next to each other. This was a 2-column 1fr grid, which
   put "Контакти" at the halfway mark of the column with a gulf between it and
   "Про EREADIAN" - the gap was the grid's, not a decision. */
.site-footer-links {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 9px 18px;
}
.site-footer-links a {
  color: #69594c;
  font-size: 0.8rem;
  text-decoration: none;
}
.site-footer-links a:hover {
  color: #a94737;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.site-footer-meta {
  display: flex;
  grid-column: 1 / -1;
  justify-content: space-between;
  gap: 14px;
  padding-top: 15px;
  border-top: 1px solid #eadfd4;
  color: #91857a;
  font-size: 0.7rem;
}
.site-footer-socials {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 4px;
}
/* The socials sit in the footer's link column now, in the row the two
   removed links left behind - so they span both of that column's tracks
   rather than being squeezed into one of them. */
.site-footer-links .site-footer-socials {
  flex-basis: 100%;
  margin-top: 10px;
}
.site-footer-socials a {
  display: grid;
  width: 32px;
  height: 32px;
  place-items: center;
  border: 1px solid #ddd0c2;
  border-radius: 50%;
  color: #5d4d42;
  font-size: 1rem;
  font-weight: 800;
  line-height: 1;
  text-decoration: none;
}
.site-footer-socials svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}
.site-footer-socials svg.icon-filled {
  fill: currentColor;
  stroke: none;
}
/* Instagram's icon has padding baked into its own shapes (an 18x18 rounded
   square inset within its 24x24 viewBox), so the shared 17px box gives it
   a natural margin. X, Facebook, and Threads are solid brand marks drawn
   edge-to-edge in their viewBox, so the same box size makes their actual
   silhouettes look inconsistent with each other's visual weight - Threads'
   loop crowds the circle border, Facebook's disc-with-cutout reads smaller
   than X's angular mark at the same nominal size. Sized individually so
   all four read as the same visual weight instead of the same box size. */
.site-footer-socials svg.icon-facebook {
  width: 19px;
  height: 19px;
}
.site-footer-socials svg.icon-threads {
  /* viewBox padded to -16..208 (base.html) so the loop no longer crowds/gets
     clipped by the circle - it now renders with a built-in margin, so it can
     take the same 17px box as the others without looking cramped. */
  width: 17px;
  height: 17px;
}
.site-footer-socials a:hover,
.site-footer-socials a:focus-visible {
  border-color: var(--accent, #a74434);
  color: var(--accent, #a74434);
}
.info-page {
  max-width: 48rem;
  margin: 46px auto 72px;
}
.info-page h1 {
  margin: 5px 0 12px;
}
.info-page > p {
  margin: 0;
  color: #77695e;
  line-height: 1.6;
}
.info-page-placeholder {
  display: grid;
  gap: 5px;
  margin-top: 26px;
  padding: 18px 20px;
  border: 1px solid #e3d7ca;
  border-radius: 16px;
  background: #fffaf3;
}
.info-page-placeholder span {
  color: #77695e;
  font-size: 0.86rem;
}
@media (max-width: 650px) {
  .site-footer {
    margin-top: 38px;
  }
  .site-footer-inner {
    grid-template-columns: 1fr;
    gap: 22px;
    padding-top: 23px;
  }
  .site-footer-meta {
    flex-direction: column;
    gap: 5px;
  }
  .info-page {
    margin: 30px 0 50px;
  }
}

/* --- Admin: built-in collection category filters --- */
.builtin-filter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  margin-top: 14px;
}
.builtin-filter {
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #fffdf8;
  overflow: hidden;
}
.builtin-filter summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px;
  font-weight: 700;
  cursor: pointer;
  list-style: none;
}
.builtin-filter summary::-webkit-details-marker {
  display: none;
}
.builtin-filter summary span {
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 600;
}
.builtin-filter form {
  padding: 0 14px 14px;
}
.builtin-filter-options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 4px 10px;
  max-height: 260px;
  overflow-y: auto;
  margin-bottom: 10px;
}
.builtin-filter-options label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8rem;
}
.builtin-book-exclusions {
  padding: 0 14px 14px;
  border-top: 1px solid var(--line);
}
.builtin-book-exclusions > label {
  display: grid;
  gap: 5px;
  margin-top: 12px;
  color: var(--muted);
  font-size: 0.78rem;
}
.builtin-book-exclusions input[type="search"] {
  min-width: 0;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
}
.builtin-book-exclusions .suggestion-list {
  position: relative;
  z-index: 5;
  margin-top: 4px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  overflow: hidden;
}
.builtin-book-exclusions .suggestion-item {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  color: #302720;
  text-align: left;
  font-size: 0.78rem;
  cursor: pointer;
}
.builtin-book-exclusions .suggestion-item.out-of-stock {
  opacity: 0.6;
}
.builtin-book-exclusions .suggestion-item:last-child {
  border-bottom: 0;
}
.builtin-book-exclusions .suggestion-item:hover {
  background: #f9eee6;
}
.builtin-book-exclusion-list {
  display: grid;
  gap: 8px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}
.builtin-book-exclusion-list li {
  display: grid;
  grid-template-columns: 30px 1fr auto;
  align-items: center;
  gap: 8px;
}
.builtin-book-exclusion-list li.muted {
  display: block;
  color: var(--muted);
  font-size: 0.78rem;
}
.builtin-book-exclusion-list img {
  width: 30px;
  height: 40px;
  border-radius: 4px;
  object-fit: cover;
}
.builtin-book-exclusion-list strong {
  display: block;
  overflow: hidden;
  font-size: 0.8rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.builtin-book-exclusion-list small {
  color: var(--muted);
  font-size: 0.7rem;
}

/* --- Collection admin editor (Stage 1 Task 4) --- */
.section-divider {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 28px 0 14px;
}
.danger-action {
  border: 1px solid #e2b8ae;
  border-radius: 11px;
  background: #fff5f2;
  color: var(--red);
  font-weight: 750;
  padding: 10px 14px;
}
.danger-action:hover {
  background: #fbe4de;
}
.collection-editor {
  position: relative;
}
.collection-editor-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}
.collection-status-badge {
  padding: 5px 10px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 750;
}
.collection-status-badge.is-published {
  background: #e6efe4;
  color: #356436;
}
.collection-status-badge.is-draft {
  background: #f1e9d8;
  color: #76551f;
}
.collection-editor-head form:last-child {
  margin-left: auto;
}
.collection-move-controls {
  display: flex;
  gap: 4px;
}
.collection-move-controls button {
  width: 30px;
  height: 30px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
  font-weight: 750;
}
.collection-move-controls button:disabled {
  opacity: 0.35;
  cursor: default;
}
.builtin-filter.is-disabled {
  opacity: 0.6;
}
.builtin-filter.is-disabled summary {
  text-decoration: line-through;
  text-decoration-color: var(--muted);
}
.collection-books-editor {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.collection-books-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}
.collection-add-book {
  margin-bottom: 12px;
}
.collection-add-book label {
  display: grid;
  gap: 5px;
  color: var(--muted);
  font-size: 0.78rem;
}
.collection-add-book input[type="search"] {
  min-width: 0;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
}
.collection-add-book .suggestion-list {
  position: relative;
  z-index: 5;
  margin-top: 4px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  overflow: hidden;
}
.collection-add-book .suggestion-item {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  /* jobs.css's ".collection-add-book button" rule sets color:#fff for the
     real "Зберегти"-style buttons in this panel - this suggestion button
     never overrode it, so it rendered white text on this rule's own
     transparent background (i.e. invisible against the white dropdown). */
  color: #302720;
  text-align: left;
  font-size: 0.78rem;
  cursor: pointer;
}
.collection-add-book .suggestion-item.out-of-stock {
  opacity: 0.6;
}
.collection-add-book .suggestion-item:last-child {
  border-bottom: 0;
}
.collection-add-book .suggestion-item:hover {
  background: #f9eee6;
}
.collection-book-list {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.collection-book-list li {
  display: grid;
  grid-template-columns: auto 30px 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
}
.collection-book-list img,
.book-cover-placeholder-sm {
  width: 30px;
  height: 40px;
  border-radius: 4px;
  background: #f1e7da;
  object-fit: cover;
}
.collection-book-list strong {
  display: block;
  overflow: hidden;
  font-size: 0.8rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.collection-book-list small {
  color: var(--muted);
  font-size: 0.7rem;
}

/* --- Breadcrumbs (category and author listings) --- */
.breadcrumbs {
  margin: 0 0 14px;
}
.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--muted, #786f68);
  font-size: 0.78rem;
}
/* The separator belongs to the trail, not to any crumb's text, so it is drawn
   rather than typed - a copied breadcrumb pastes as words, not as "a › b". */
.breadcrumbs li + li::before {
  content: "›";
  margin-right: 8px;
  color: #b8aa9c;
}
.breadcrumbs a {
  color: var(--muted, #786f68);
  text-decoration: none;
}
.breadcrumbs a:hover {
  color: var(--red, #a94737);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.breadcrumbs [aria-current="page"] {
  color: #4a4038;
  font-weight: 700;
}

/* --- Sort control (search results + collection pages) --- */
.catalog-heading-tools {
  display: flex;
  align-items: center;
  gap: 14px;
}
.sort-form {
  display: contents;
}
.sort-select-label {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 700;
}
.sort-select-label select {
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
/* Search told the reader it changed their query for them (wrong keyboard
   layout). Reads as a note, not an error. */
/* Specific enough to beat `.catalog-heading p`, which is what applies the
   single-line ellipsis this paragraph must not inherit. */
.catalog-heading p.search-correction {
  margin-top: 4px;
  color: var(--muted);
  font-size: 0.9rem;
  /* Its siblings in .catalog-heading are single-line labels that ellipsize;
     this one is a sentence and has to wrap or it gets cut mid-word. */
  overflow: visible;
  white-space: normal;
  text-overflow: clip;
}

@media (max-width: 680px) {
  .catalog-heading-tools {
    flex-wrap: wrap;
  }
  .search-results-heading {
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 14px;
  }
  .search-results-heading h1 {
    font-size: clamp(2rem, 9vw, 2.55rem);
    line-height: 1.04;
  }
  .search-results-heading h1 span {
    display: block;
    margin-top: 3px;
    color: var(--muted);
    font-family: var(--font-sans);
    font-size: 0.48em;
    font-weight: 650;
    line-height: 1.2;
  }
  .search-results-heading .catalog-heading-tools {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    width: 100%;
    gap: 8px;
  }
  .search-results-heading .sort-form {
    display: block;
  }
  .search-results-heading .sort-select-label {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 6px;
    font-size: 0.72rem;
    white-space: nowrap;
  }
  .search-results-heading .sort-select-label select {
    min-width: 0;
    width: 100%;
    padding: 8px 28px 8px 9px;
    font-size: 0.78rem;
  }
  .search-results-heading .result-count {
    align-self: center;
    padding: 8px 10px;
    font-size: 0.68rem;
    white-space: nowrap;
  }
}
.save-filtered-form {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: -8px 0 20px;
  padding: 10px 14px;
  border: 1px dashed var(--line);
  border-radius: 13px;
  background: #f7f1e6;
}
.save-filtered-label {
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.save-filtered-form input[type="text"] {
  padding: 8px 11px;
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  font-size: 0.85rem;
  width: 200px;
  max-width: 100%;
}
.save-filtered-form button {
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}

/* --- Wishlist ebook-tracking opt-in --- */
.wishlist-format-note {
  margin: 2px 0 6px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.76rem;
  line-height: 1.4;
}

/* --- Compact per-format price history: a small clickable sparkline card
   that opens a bigger <dialog> with the full chart (hotline.ua-style
   preview -> expand). Lives inside the book hero's sidebar (.book-price-panel
   below) rather than as its own full-width section. --- */
.price-chart-card {
  display: block;
  width: 100%;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 14px 9px;
  box-shadow: var(--shadow, 0 8px 22px rgba(61, 42, 29, 0.06));
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.price-chart-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 26px rgba(61, 42, 29, 0.1);
}
.price-chart-paper { color: var(--accent); }
.price-chart-ebook { color: var(--accent2, #6f7f59); }
.price-chart-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}
.price-chart-label {
  font-weight: 700;
  font-size: 0.82rem;
  color: var(--ink);
}
.price-chart-trend {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--muted);
  white-space: nowrap;
}
.price-chart-trend.trend-down { color: var(--green, #176d4f); }
.price-chart-trend.trend-up { color: var(--red, #a74434); }
.price-chart-svg {
  display: block;
  width: 100%;
  height: 32px;
}
.price-chart-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-top: 4px;
  font-size: 0.7rem;
  color: var(--muted);
}
.price-chart-range { font-weight: 700; color: var(--ink); }
.price-chart-expand-hint {
  color: var(--accent);
  font-weight: 700;
}

/* The expanded view - same content, bigger chart, in a native <dialog> */
.price-chart-dialog {
  width: min(560px, calc(100vw - 32px));
  padding: 22px 24px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--paper);
  box-shadow: 0 24px 65px rgba(45, 31, 22, 0.28);
}
.price-chart-dialog::backdrop {
  background: rgba(38, 29, 22, 0.42);
}
/* svg.price-chart-svg-dialog (not the plain descendant-combinator form)
   so this beats .book-price-panel .price-chart-svg on specificity - the
   dialog is a sibling of the compact card *inside* .book-price-panel, so
   that 30px compact-card override was tying on specificity with this rule
   and winning on cascade order alone, forcing the dialog chart down to
   the compact card's height. */
svg.price-chart-svg.price-chart-svg-dialog {
  height: 220px;
}
.price-chart-dialog .price-chart-head {
  margin-bottom: 12px;
}
.price-chart-dialog .price-chart-label {
  font-size: 1.05rem;
}
/* The dialog chart carries its own point markers/date-price labels drawn
   straight into the SVG (see price-chart-svg-dialog below) instead of a
   table underneath - so, unlike the compact sparkline, its viewBox is
   real pixels (DIALOG_WIDTH/HEIGHT in price_history_chart.py) rather than
   a stretched preserveAspectRatio="none" box, or the label text would
   distort along with the line. */
.price-chart-svg-dialog {
  overflow: visible;
}
.price-chart-point circle {
  fill: var(--paper);
  stroke: currentColor;
  stroke-width: 1.6;
  transition: r 0.12s ease;
}
.price-chart-point.is-labeled circle {
  fill: currentColor;
}
.price-chart-point:hover circle {
  r: 5;
}
.price-chart-point-label {
  font-size: 10px;
  font-weight: 700;
  fill: var(--ink);
  font-variant-numeric: tabular-nums;
  paint-order: stroke;
  stroke: var(--paper);
  stroke-width: 3px;
  stroke-linejoin: round;
}
.price-chart-hover-hint {
  margin: 6px 0 0;
  color: var(--muted);
  font-size: 0.72rem;
  text-align: center;
}
.price-chart-stale-note {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 0.7rem;
  text-align: center;
}
.price-chart-dialog-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 16px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.price-chart-dialog-stats > div {
  font-size: 0.8rem;
}

/* --- Cart: unavailable items, quantity stepper, icon-only actions --- */
.cart-editor > article.is-unavailable {
  opacity: 0.55;
}
.cart-editor > article.is-unavailable img {
  filter: grayscale(1);
}
.cart-qty-form {
  display: flex;
  align-items: center;
  gap: 5px;
}
.notif-row {
  position: relative;
}
.notif-row .notif-card {
  padding-right: 44px;
}
.notif-row form {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
}
.notif-delete {
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font-size: 1.2rem;
  cursor: pointer;
}
.notif-delete:hover {
  background: #fbeeeb;
  color: var(--red);
}
.cart-qty-form input[type="number"] {
  width: 40px;
  padding: 7px 2px;
  border: 0;
  background: transparent;
  text-align: center;
  font-weight: 700;
  -moz-appearance: textfield;
}
.cart-qty-form input[type="number"]::-webkit-outer-spin-button,
.cart-qty-form input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.qty-step {
  width: 30px;
  height: 30px;
  border: 0;
  border-radius: 50%;
  background: #fbf6ee;
  color: #493d34;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}
.qty-step:hover {
  background: #f0e8dd;
}
.cart-icon-btn {
  display: grid;
  width: 34px;
  height: 34px;
  place-items: center;
  border: 1px solid var(--line, #dfd2c5);
  border-radius: 50%;
  background: #fff;
  cursor: pointer;
}
.cart-icon-btn .icon {
  width: 17px;
  height: 17px;
}
.cart-remove-btn {
  color: #a94737;
  border-color: #ecd4cd;
}
.cart-remove-btn:hover {
  background: #fbeeeb;
}
.cart-wishlist-btn {
  color: #a94737;
}
.cart-wishlist-btn:hover {
  background: #fbeeeb;
}
@media (max-width: 700px) {
  .cart-editor > article {
    grid-template-columns: 42px 1fr auto auto;
  }
}

/* ============================================================
   Book page design-02 — "Широка шапка + панель нижче".
   Wide identity header (cover | copy | buy-box) full-width on top,
   with a shop-promocode band filling the middle; below it a tabbed
   panel: "Видання і ціни" (offers) / "Динаміка ціни" (price charts).
   ============================================================ */
/* Breadcrumb trail on the book page: Головна › Category › Author › Title. */
.breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  /* Sit centred in the gap between the header and the book block, rather
     than hugging the top menu. */
  margin: 20px 0 20px;
  font-size: 0.8rem;
  color: var(--muted);
}
.breadcrumbs a {
  color: var(--muted);
  text-decoration: none;
}
.breadcrumbs a:hover {
  color: var(--accent);
  text-decoration: underline;
}
.breadcrumbs .breadcrumbs-sep {
  opacity: 0.55;
}
.breadcrumbs .breadcrumbs-current {
  color: var(--ink);
  font-weight: 700;
  max-width: 40ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (max-width: 640px) {
  .breadcrumbs .breadcrumbs-current {
    max-width: 20ch;
  }
}

.book-hero-02 {
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr) 250px;
  align-items: start;
  gap: 28px;
}
/* Cover column: the wrap is 270px site-wide (card-refresh.css); pin it to
   the hero's 210px column here so it can't overflow into the copy. */
.book-hero-02 .book-summary-cover-wrap {
  width: 210px;
}
@media (max-width: 1050px) {
  .book-hero-02 {
    grid-template-columns: 210px minmax(0, 1fr);
  }
  .book-hero-02 .book-hero-buybox {
    grid-column: 1 / -1;
  }
}
@media (max-width: 640px) {
  .book-hero-02 {
    grid-template-columns: 1fr;
    gap: 18px;
    padding: 18px;
  }
  .book-hero-02 .book-summary-cover-wrap {
    width: min(200px, 60vw);
    margin: 0 auto;
  }
}

/* Right-hand buy box: price lead + wishlist CTA + admin controls. */
.book-hero-buybox {
  display: flex;
  flex-direction: column;
  gap: 14px;
  align-self: stretch;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: #fffaf3;
}
.buybox-price-lead {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.buybox-kind {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
}
.buybox-now {
  font-family: var(--font-serif);
  font-weight: 800;
  font-size: 2rem;
  line-height: 1;
  color: #211a14;
  font-variant-numeric: tabular-nums;
}
.buybox-now .buybox-cur {
  font-size: 1.3rem;
}
.buybox-now.buybox-now-ebook {
  color: #315f9d;
}
.buybox-ebook {
  margin-top: 6px;
  font-size: 0.86rem;
  font-weight: 750;
  color: #315f9d;
}
.buybox-none {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 1.2rem;
  color: var(--muted);
}
/* Primary buy CTA + wishlist heart, mirroring the mockup's action row. */
.buybox-actions {
  display: flex;
  gap: 10px;
  align-items: stretch;
}
.buybox-actions form {
  margin: 0;
  display: flex;
}
.buybox-actions form:first-child {
  flex: 1 1 auto;
}
.buybox-cart {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  height: 48px;
  padding: 0 18px;
  border: 0;
  border-radius: 12px;
  background: var(--accent, #a74434);
  color: #fff;
  font: 750 0.95rem var(--font-sans);
  cursor: pointer;
  transition: background 0.15s ease;
}
.buybox-cart:hover {
  background: var(--accent-dark, #843326);
}
.buybox-cart svg {
  width: 18px;
  height: 18px;
}
.buybox-heart {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 50px;
  height: 48px;
  flex: none;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #fff;
  color: var(--accent, #a74434);
  cursor: pointer;
}
.buybox-heart.is-saved {
  background: var(--accent-soft, #f5e5df);
}
.buybox-heart svg {
  width: 20px;
  height: 20px;
}
.book-hero-buybox .book-summary-actions {
  margin-top: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.book-hero-buybox .wishlist-primary {
  width: 100%;
  justify-content: center;
}
.buybox-admin {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 4px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}

/* Green kicker in the mockup -> the site's own accent as an eyebrow. */
.hero-kicker {
  font: 800 0.68rem var(--font-sans);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent, #a74434);
  margin-bottom: 4px;
}

/* Ratings row: reader-average + Goodreads pills, with the interactive
   5-star input sitting to their right (per the "stars to the top" ask). */
.hero-ratings {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 12px 0 2px;
  padding: 0;
  border: 0;
}
.hero-ratings .rb {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 800;
  font-size: 0.82rem;
  border-radius: 999px;
  padding: 6px 11px;
}
.hero-ratings .rb.reader {
  background: #fbeecf;
  color: #7a4d12;
}
.hero-ratings .rb.good {
  background: #efeadf;
  color: #5a4a2c;
}
.hero-ratings .rb.good .g {
  width: 15px;
  height: 15px;
  border-radius: 3px;
  background: #5a4a2c;
  color: #efeadf;
  display: grid;
  place-items: center;
  font-size: 0.64rem;
  font-weight: 800;
}
.hero-ratings .rb small {
  font-weight: 700;
  opacity: 0.75;
}
.hero-rate-input {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}
.hero-rate-input .star-rating-label {
  font-size: 0.76rem;
  color: var(--muted);
}
@media (max-width: 640px) {
  .hero-rate-input {
    margin-left: 0;
    flex-basis: 100%;
  }
}

/* Promo-code band filling the middle emptiness of the wide header. */
.book-hero-promos {
  margin-top: 18px;
  padding: 12px 14px;
  border: 1px dashed #d9c19a;
  border-radius: 14px;
  background: #fffdf5;
}
.book-hero-promos-title {
  display: block;
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: #8a6d2f;
  margin-bottom: 9px;
}
.book-hero-promos-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.book-hero-promos .promo-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border-radius: 999px;
  background: #f5edd8;
  border: 1px solid #e6d3a3;
  font-size: 0.78rem;
}
.book-hero-promos .promo-chip b {
  font-weight: 800;
  letter-spacing: 0.02em;
  color: #7a4d12;
}
.book-hero-promos .promo-chip .promo-chip-off {
  font-weight: 800;
  color: #176d4f;
}
.book-hero-promos .promo-chip em {
  font-style: normal;
  color: var(--muted);
  font-size: 0.72rem;
}
.book-hero-promos-note {
  margin: 9px 0 0;
  font-size: 0.72rem;
  color: var(--muted);
}

/* Tabbed panel below the hero. */
.work-tabs {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  margin: 26px 0 0;
  border-bottom: 1px solid var(--line);
}
.work-tab-btn {
  border: 0;
  background: none;
  padding: 11px 16px;
  font: inherit;
  font-weight: 750;
  font-size: 0.95rem;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.work-tab-btn:hover {
  color: var(--ink);
}
.work-tab-btn.is-active {
  color: var(--accent);
  border-bottom-color: currentColor;
}
.work-tab-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}
.work-tab-body {
  margin-top: 18px;
}
.work-tab-body[hidden] {
  display: none;
}
/* In the dynamics tab the charts lay out side-by-side full width. */
.book-price-panel-tab {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 16px;
}
.book-price-panel-tab .price-chart-card {
  flex: 1 1 320px;
}

/* --- Legacy: price history when it lived as a right-side hero panel
   (superseded by the design-02 dynamics tab; kept harmless) --- */
@media (min-width: 1051px) {
  .book-summary.has-price-panel {
    grid-template-columns: 270px minmax(0, 1fr) 205px;
  }
}
@media (max-width: 1050px) {
  .book-summary.has-price-panel {
    grid-template-columns: 270px minmax(0, 1fr);
  }
  .book-price-panel {
    grid-column: 1 / -1;
    flex-direction: row;
    flex-wrap: wrap;
  }
  .book-price-panel .price-chart-card {
    flex: 1 1 220px;
  }
}
@media (max-width: 760px) {
  .book-summary.has-price-panel {
    grid-template-columns: 180px minmax(0, 1fr);
  }
}
.book-price-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.book-price-panel .price-chart-card {
  padding: 10px 12px 9px;
}
.book-price-panel .price-chart-label {
  font-size: 0.74rem;
  line-height: 1.25;
}
.book-price-panel .price-chart-svg {
  height: 30px;
}
.price-chart-stats {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--line);
}
.price-chart-stats > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 0.72rem;
}
.price-chart-stats span {
  color: var(--muted);
}
.price-chart-stats strong {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.book-price-panel .price-chart-expand-hint {
  display: block;
  margin-top: 6px;
  color: var(--accent);
  font-weight: 700;
  font-size: 0.7rem;
}

/* --- Compact filter sheet rework: tighter facet rows, more columns per
   row, and a real dual-handle price slider replacing the old two plain
   number inputs. The existing cascade (postgres-ui.css) sets facet-row
   height with !important at several breakpoints, so matching !important
   here is the only reliable way to win regardless of load order. Facet
   *behavior* (search-as-you-type, popover open/close, live option
   fetch) is untouched - see initFacets()/initPriceSlider() in
   storefront.js - only sizing/layout changes. --- */
.filter-sheet .filter-grid {
  grid-template-columns: repeat(6, minmax(0, 1fr)) !important;
  gap: 8px !important;
}
.filter-sheet .facet > summary {
  height: 38px !important;
  min-height: 38px !important;
  padding: 0 10px !important;
  font-size: 0.82rem;
  border-radius: 9px !important;
}
.filter-sheet .facet > summary span {
  font-size: 0.66rem;
}
.filter-sheet .stock-check {
  height: 38px !important;
  min-height: 38px !important;
  padding: 0 10px !important;
  font-size: 0.82rem;
  border-radius: 9px !important;
}
.filter-sheet .facet-popover {
  padding: 8px !important;
}
.filter-sheet .facet-options label {
  min-height: 32px !important;
  padding: 5px 7px !important;
  font-size: 0.82rem;
}

/* The price control is used often enough to deserve always-visible real
   estate rather than a click-to-open popover like the other facets, so
   it spans two grid columns and shows the slider inline. */
.price-facet {
  display: flex;
  flex-direction: column;
  grid-column: span 2;
  justify-content: center;
  gap: 7px;
  min-height: 38px;
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: #fff;
}
.price-facet.has-selection {
  border-color: var(--accent);
}
.price-facet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.82rem;
}
.price-facet-head strong {
  font-weight: 700;
}
.price-facet-head span {
  color: var(--muted);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
}
.price-slider {
  position: relative;
  height: 16px;
  margin: 0 7px;
}
.price-slider-track {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 3px;
  transform: translateY(-50%);
  border-radius: 999px;
  background: var(--line);
}
.price-slider-range {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: 999px;
  background: var(--accent);
}
.price-thumb {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 16px;
  margin: 0;
  transform: translateY(-50%);
  background: transparent;
  appearance: none;
  -webkit-appearance: none;
  pointer-events: none;
}
.price-thumb::-webkit-slider-runnable-track {
  background: transparent;
}
.price-thumb::-moz-range-track {
  background: transparent;
}
.price-thumb::-webkit-slider-thumb {
  width: 15px;
  height: 15px;
  margin-top: 0;
  border: 2px solid var(--accent);
  border-radius: 50%;
  background: #fff;
  appearance: none;
  -webkit-appearance: none;
  pointer-events: auto;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}
.price-thumb::-moz-range-thumb {
  width: 15px;
  height: 15px;
  border: 2px solid var(--accent);
  border-radius: 50%;
  background: #fff;
  pointer-events: auto;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}
@media (max-width: 700px) {
  .filter-sheet .filter-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
  .price-facet {
    grid-column: 1 / -1;
  }
}

.cart-store-delivery {
  margin: 4px 0 0;
  color: #627366;
  font-size: 0.76rem;
}
.cart-store-delivery.muted {
  color: #a0948a;
  font-style: italic;
}
.cart-store-delivery-warning {
  margin: 4px 0 0;
  color: #9a5a28;
  font-size: 0.72rem;
  line-height: 1.3;
}
.cart-plan-tabs strong em {
  display: block;
  color: #81746a;
  font-size: 0.68rem;
  font-style: normal;
  font-weight: 600;
  text-align: right;
}
.cart-plan-tabs strong {
  min-width: 150px;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.cart-editor-link,
.cart-product-link {
  display: contents;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}
/* The link wrapper (display:contents) sits between .cart-editor article /
   .cart-product and their img/div - postgres-ui.css's ">" direct-child
   selectors for those no longer match through it (display:contents changes
   rendering, not DOM parentage, so ">" still requires literal parentage),
   so those rules are restated here scoped to the wrapper class instead. */
.cart-editor-link img {
  width: 43px;
  height: 58px;
  object-fit: contain;
  border-radius: 5px;
}
.cart-editor-link > div {
  display: flex;
  min-width: 0;
  flex-direction: column;
}
.cart-editor-link > div strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cart-editor-link > div span {
  color: #81746a;
  font-size: 0.7rem;
}
.cart-clear-form {
  margin-left: auto;
}

.cart-shop-form {
  min-width: 150px;
  flex-direction: column;
  justify-content: center;
  align-items: stretch !important;
}
.cart-shop-form select {
  max-width: 190px;
  padding: 7px 25px 7px 8px;
  border: 1px solid var(--line, #dfd2c5);
  border-radius: 8px;
  background: #fff;
  color: #493d34;
  font-size: 0.72rem;
}
.cart-shop-form small {
  color: #81746a;
  font-size: 0.62rem;
  line-height: 1.15;
  text-align: center;
}
@media (min-width: 701px) {
  .cart-shop-form {
    position: relative;
    align-self: center;
  }
  .cart-shop-form small {
    position: absolute;
    top: calc(100% + 5px);
    right: 0;
    left: 0;
  }
}
.offer-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.offer-cart-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  min-width: 44px;
  gap: 5px;
  padding: 0 10px;
}
.offer-cart-button span {
  font-size: 0.7rem;
  font-weight: 800;
}
@media (min-width: 701px) {
  .cart-editor > article {
    grid-template-columns: 48px minmax(0, 1fr) minmax(150px, 190px) auto auto;
  }
}
@media (max-width: 700px) {
  .cart-editor > article {
    grid-template-columns: 42px minmax(0, 1fr) auto auto;
  }
  .cart-editor > article .cart-shop-form {
    grid-column: 2 / -1;
    margin-top: -2px;
  }
  .cart-editor > article .cart-qty-form {
    grid-column: 2;
  }
  .cart-editor > article > form:last-child {
    grid-column: 4;
    grid-row: 1;
    margin-top: 0;
  }
}

#more-collections.is-loading {
  min-height: 7rem;
}
/* The transform/opacity reveal transition previously here was removed -
   reported live as a possible contributor to a scroll stutter right at
   this lazy-loaded boundary (the one thing structurally unique to this
   section vs. the eagerly-rendered ones above it, which have no reveal
   animation at all). Purely decorative, no functional downside to
   dropping it; sections now just appear as their images finish loading,
   like everything else on the page. */
.cart-clear-btn {
  padding: 6px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--accent, #a74434);
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
}
.cart-clear-btn:hover {
  background: rgba(167, 68, 52, 0.08);
}
.cart-product-link img {
  width: 58px;
  height: 78px;
  object-fit: contain;
  border-radius: 7px;
}
@media (max-width: 650px) {
  .cart-product-link img {
    width: 45px;
    height: 64px;
  }
}
.cart-store-pickup {
  margin: 2px 0 0;
  color: #a0948a;
  font-size: 0.7rem;
}
.cart-delivery-pref {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
  margin-bottom: 18px;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card, #fffaf3);
}
.cart-delivery-pref-field {
  display: flex;
  align-items: center;
  gap: 10px;
}
.cart-delivery-pref label {
  color: var(--muted, #7b7067);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
}
.cart-delivery-pref select {
  padding: 8px 32px 8px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
}
.cart-delivery-pref p {
  flex: 1 1 240px;
  margin: 0;
  color: #a0948a;
  font-size: 0.76rem;
  line-height: 1.4;
  text-align: right;
}
@media (max-width: 640px) {
  .cart-delivery-pref p {
    text-align: left;
  }
}

@media (max-width: 700px) {
  .nav .brand > span {
    display: block !important;
  }
  /* declutter the mobile header, but keep admins' direct access to the admin
     panel (the settings icon) - it only ever renders for is_admin, so regular
     users see nothing extra, and admins get the same one-tap access to
     Адміністрування they have on desktop (mirrored in the profile popup). */
  .nav-shop-link {
    display: none !important;
  }
  .nav .brand {
    font-size: 1.25rem;
    font-weight: 800;
    letter-spacing: -0.05em;
  }
  .mobile-search-toggle {
    order: 2;
    margin-left: auto;
  }
  .nav-links {
    order: 3;
    margin-left: 0 !important;
  }
  .collection-section {
    margin: 24px 0 34px;
  }
  .collection-section > header {
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
  }
  .collection-section > header h2 {
    font-size: clamp(1.3rem, 6vw, 1.7rem);
    line-height: 1.12;
  }
  .collection-section > header > a {
    flex: 0 0 auto;
    font-size: 0.76rem;
    white-space: nowrap;
  }
  .nav .header-filters-button::before {
    display: none;
    content: none;
  }
  .filter-overlay {
    padding: 6px;
  }
  .filter-sheet {
    width: calc(100vw - 12px);
    max-height: calc(100dvh - 72px);
    padding: 14px 12px 12px;
  }
  .filter-sheet > header h2 {
    font-size: 1.12rem !important;
  }
  .filter-sheet .filter-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 7px !important;
  }
  .filter-sheet .facet[data-facet="language"],
  .filter-sheet .stock-check,
  .price-facet {
    grid-column: 1 / -1;
  }
  .filter-sheet .stock-check {
    justify-content: flex-start;
  }
  .facet-popover {
    right: 6px !important;
    left: 6px !important;
    width: auto !important;
  }
  .facet-options label {
    color: var(--ink, #211b18) !important;
  }
  .filter-sheet .facet-popover > input[type="search"] {
    min-height: 44px;
    font-size: 16px !important;
  }
  .filter-sheet .facet-options label {
    display: grid !important;
    grid-template-columns: 22px minmax(0, 1fr);
    width: 100%;
    min-height: 44px !important;
    align-items: center;
    color: var(--ink, #211b18) !important;
    font-size: 0.9rem !important;
    line-height: 1.25;
    overflow: visible !important;
    white-space: normal !important;
  }
  .filter-sheet .facet-options input[type="checkbox"] {
    width: 22px !important;
    height: 22px !important;
    margin: 0;
  }
  .filter-sheet > footer {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 8px;
    margin-top: 9px;
    padding-top: 9px;
  }
  .filter-sheet > footer button {
    min-height: 42px;
    padding: 8px 10px;
  }
  .notif-panel,
  .profile-panel {
    max-height: calc(100dvh - 76px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .wishlist-notify[open] .wishlist-notify-form {
    position: fixed;
    z-index: 70;
    top: 70px;
    right: 10px;
    bottom: 10px;
    left: 10px;
    width: auto;
    max-width: none;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .cart-editor > header {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 3px 10px;
  }
  .cart-editor > header h2 {
    grid-column: 1;
    min-width: 0;
  }
  .cart-editor > header > span {
    grid-column: 1;
    margin: 0;
  }
  .cart-editor > header .cart-clear-form {
    grid-column: 2;
    grid-row: 1 / span 2;
    margin: 0;
    align-self: center;
  }
  .cart-delivery-pref {
    display: grid;
    gap: 10px;
    padding: 13px 14px;
  }
  .cart-delivery-pref-field {
    display: grid;
    gap: 6px;
  }
  .cart-delivery-pref select {
    width: 100%;
  }
  .cart-delivery-pref p {
    font-size: 0.72rem;
  }
}
.cart-store-totals {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}
.cart-store-totals strong {
  font: 800 1.35rem var(--font-serif);
  color: #211a14;
}
.cart-store-totals small {
  color: #81746a;
  font-size: 0.72rem;
  white-space: nowrap;
}

/* Keep store-order cards compact without sacrificing the information needed
   to compare delivery and item totals. */
.cart-store > header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 8px 16px;
  padding: 14px 18px;
}
.cart-store > header > div:first-child {
  min-width: 0;
}
.cart-store h2 {
  margin: 2px 0 0;
  font-size: clamp(1.15rem, 2.6vw, 1.45rem);
  line-height: 1.1;
}
.cart-store .eyebrow {
  font-size: 0.67rem;
}
.cart-store-delivery {
  max-width: 34rem;
  margin-top: 5px;
  font-size: 0.72rem;
  line-height: 1.3;
}
.cart-store-totals {
  min-width: 112px;
}
.cart-store-totals strong {
  font-size: 1.2rem;
  line-height: 1.1;
}
.cart-store-totals small {
  max-width: 15rem;
  font-size: 0.67rem;
  line-height: 1.25;
  text-align: right;
  white-space: normal;
}
.cart-product {
  grid-template-columns: 50px minmax(0, 1fr) auto auto;
  gap: 10px;
  padding: 11px 18px;
}
.cart-product-link img {
  width: 46px;
  height: 62px;
}
.cart-product h3 {
  font-size: 0.88rem;
  line-height: 1.2;
}
.cart-product p,
.cart-product span,
.cart-product-actions {
  font-size: 0.67rem;
  line-height: 1.25;
}
.cart-product-actions a {
  white-space: nowrap;
}
@media (max-width: 650px) {
  .cart-store > header {
    gap: 7px 10px;
    padding: 13px 14px;
  }
  .cart-store h2 {
    font-size: 1.2rem;
  }
  .cart-store-delivery {
    font-size: 0.68rem;
  }
  .cart-store-totals {
    min-width: 94px;
  }
  .cart-store-totals strong {
    font-size: 1.1rem;
  }
  .cart-store-totals small {
    max-width: 9.5rem;
    font-size: 0.62rem;
  }
  .cart-product {
    grid-template-columns: 42px minmax(0, 1fr) auto;
    gap: 8px;
    padding: 10px 14px;
  }
  .cart-product-link img {
    width: 40px;
    height: 55px;
  }
  .cart-product > strong {
    align-self: start;
    font-size: 0.98rem;
  }
  .cart-product-actions {
    grid-column: 2 / -1;
    margin-top: -3px;
  }
  .cart-product p {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
  }
}
/* The plan panels no longer carry a summary aside - each tab in the chooser
   above already states its own total - so the column it used to sit in would
   otherwise stay reserved and empty. */
.cart-layout {
  grid-template-columns: minmax(0, 1fr);
}
.single-store-option small {
  display: block;
}
.filter-sheet>footer button[data-clear-all-filters] {
  background: transparent !important;
  color: #6e5c4e !important;
  padding: 9px 4px !important;
}
.offer-filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 16px;
}
.offer-filter-empty {
  margin: -4px 0 18px;
  padding: 12px 14px;
  border: 1px dashed var(--line, #dfd2c5);
  border-radius: 10px;
  background: var(--card, #fffaf3);
  color: #6e5c4e;
  font-size: 0.9rem;
}
.offer-filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card, #fffaf3);
  color: var(--ink);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  cursor: pointer;
  transition: 0.15s ease;
}
.offer-filter-btn::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--line);
  transition: 0.15s ease;
}
.offer-filter-btn:hover {
  border-color: var(--accent, #a74434);
}
.offer-filter-btn.is-active {
  border-color: var(--accent, #a74434);
  background: var(--accent, #a74434);
  color: #fff;
}
.offer-filter-btn.is-active::before {
  background: #fff;
}

/* Card grid/scroll-row sizing (gap, column count, card width) all in
   book-card.css now. */

/* --- .panel base chrome: this class is used all over (admin dashboard,
   jobs pages, cart, shop cards, merge review...) but its actual box styling
   only ever existed in production.css, a stylesheet that isn't loaded by
   base.html - every ".panel" on the site has been rendering with no border,
   background, or padding at all this whole time (plain stacked text/links).
   Scoped overrides like .shop-grid .panel already added their own layout on
   top of this missing base, which is why they only half-worked. This is the
   one real fix; the admin stats/links dashboards below build on it. */
.panel {
  padding: 22px;
  border: 1px solid var(--line, #e8ded2);
  border-radius: 18px;
  background: var(--card, #fffaf3);
  box-shadow: 0 6px 18px rgba(52, 36, 21, 0.05);
}
.panel h2 {
  margin: 0 0 6px;
  font-size: 1.1rem;
}
.panel > p,
.panel > .muted {
  margin: 0;
  color: var(--muted, #786f68);
}

/* --- Admin dashboard: top-line stat tiles (.stats) and the link grid to
   each admin sub-page (.admin-links), e.g. app/templates/admin.html and
   admin_popularity.html. Same missing-base-class problem as .panel above -
   these rendered as a bare vertical list of numbers with no card chrome. --- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
  margin: 22px 0;
}
.stats article {
  padding: 18px 20px;
  border: 1px solid var(--line, #e8ded2);
  border-radius: 16px;
  background: var(--card, #fffaf3);
  box-shadow: 0 6px 18px rgba(52, 36, 21, 0.05);
}
.stats article strong {
  display: block;
  font-family: var(--font-serif);
  font-size: 1.9rem;
  line-height: 1.15;
  color: var(--ink, #211b18);
}
.stats article span {
  color: var(--muted, #786f68);
  font-size: 0.82rem;
}

.admin-links {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 16px;
  margin: 22px 0;
}
.admin-links .panel {
  display: block;
  cursor: pointer;
  text-decoration: none;
  transition: 0.18s ease;
}
.admin-links .panel h2 {
  text-decoration: none;
}
.admin-links .panel a {
  color: var(--accent, #a74434);
  text-decoration: underline;
}
.admin-links .panel:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 30px rgba(54, 38, 25, 0.09);
}
.admin-links .panel h2 {
  font-size: 1.05rem;
}
.admin-links .panel p {
  margin: 0;
  color: var(--muted, #786f68);
  font-size: 0.86rem;
}

/* Mobile search results need a fixed title row and a separate compact
   toolbar; otherwise a long query/filter label competes with the sort
   control for the same narrow line. */
.search-results-title > p {
  margin: 4px 0 0;
  color: var(--muted, #786f68);
  font-size: 0.82rem;
}
@media (max-width: 680px) {
  .search-results-heading {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
    margin-bottom: 16px;
  }
  .search-results-heading h1 {
    margin: 0;
    font-size: clamp(2rem, 9vw, 2.4rem);
    line-height: 1.02;
  }
  .search-results-title > p {
    overflow: hidden;
    font-size: 0.8rem;
    line-height: 1.3;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .search-results-heading .catalog-heading-tools {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    width: 100%;
    gap: 10px;
  }
  .search-results-heading .sort-form {
    min-width: 0;
  }
  .search-results-heading .sort-select-label {
    display: grid;
    grid-template-columns: 1fr;
    gap: 4px;
    min-width: 0;
    font-size: 0.68rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
  }
  .search-results-heading .sort-select-label select {
    width: 100%;
    min-width: 0;
    height: 40px;
    padding: 8px 30px 8px 10px;
    font-size: 0.82rem;
    letter-spacing: 0;
    text-transform: none;
  }
  .search-results-heading .result-count {
    align-self: end;
    padding: 11px 9px;
    font-size: 0.66rem;
    line-height: 1;
    white-space: nowrap;
  }
}

/* --- Empty-state primary CTA (cart/wishlist "Перейти до каталогу") ---
   Scoped ".empty-state .empty-state-cta" (0,0,2,0) deliberately, so it beats
   postgres-ui.css's ".empty-state>a{color:#a94737}" (0,0,1,1) - otherwise the
   button text renders red-on-red (invisible). The notifications empty-state
   still uses a bare <a> and keeps that red link styling. */
.empty-state .empty-state-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  padding: 12px 20px;
  border: 1px solid var(--accent, #a74434);
  border-radius: 12px;
  background: var(--accent, #a74434);
  color: #fff;
  font-weight: 750;
  text-decoration: none;
}
.empty-state .empty-state-cta:hover {
  background: var(--accent-dark, #843326);
  border-color: var(--accent-dark, #843326);
  color: #fff;
}
.empty-state .empty-state-cta:focus-visible {
  outline: 2px solid var(--accent, #a74434);
  outline-offset: 3px;
}

/* --- Sticky footer: keep <footer> pinned to the bottom on short pages
   (empty wishlist/cart) instead of floating mid-viewport with dead space
   below it. body becomes a flex column; the main content flexes to fill.
   CRITICAL: every direct flex child needs min-width:0. A flex item defaults to
   min-width:auto (= its content's min-content width), which would refuse to
   shrink below wide content (e.g. the book page's price-panel grid) and blow
   the layout out to 1600px on a phone, causing horizontal scroll. min-width:0
   lets each row shrink to the viewport so the children's own responsive rules
   take over. --- */
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
body > header,
body > main.wrap,
body > .site-footer {
  min-width: 0;
}
body > main.wrap {
  flex: 1 0 auto;
  /* width:100% pins the row to the body's width (the viewport). Without it the
     flex item sized itself to its content's min-content width - which the book
     page's price-panel grid pushes to ~1600px - blowing the layout out to
     1600px on a phone. With it, the row is the viewport width and the content
     inside falls back to its own responsive rules. */
  width: 100%;
}
body > .site-footer {
  flex-shrink: 0;
}

/* ============================================================
   Homepage hero carousel (#19) - replaced the numeric stats band.
   Auto-advancing image band, responsive aspect ratio, dots + arrows.
   Behaviour lives in storefront.js (initHomeCarousel).
   ============================================================ */
.home-carousel {
  position: relative;
  margin: 18px 0 30px;
  border-radius: 20px;
  overflow: hidden;
  background: #ece3d6;
  /* Softer shadow (was 0 14px 34px) + its own compositor layer via
     translateZ(0): when the sticky header sweeps over the band's lower edge,
     the compositor just composites the two layers instead of re-rasterizing
     the big blurred shadow every frame - which was the scroll hitch at the
     carousel edge. */
  box-shadow: 0 5px 14px rgba(45, 31, 22, 0.12);
  transform: translateZ(0);
  /* Hint the compositor to keep the band on its own layer during scroll so it
     translates rather than re-rasters (it's a big image element). */
  will-change: transform;
}
.home-carousel-viewport {
  overflow: hidden;
  /* The band's height is driven by the aspect ratio, which steps up (gets
     taller relative to width) as the screen narrows, so it stays a pleasing
     shape from the 1600px cap all the way down to phones instead of
     collapsing to a thin sliver or fighting a fixed max-height. No max-height
     cap (it conflicted with the ratio and cropped the art at wide widths). */
  aspect-ratio: 16 / 5;      /* ~500px at the 1600px cap */
}
@media (max-width: 1200px) {
  .home-carousel-viewport { aspect-ratio: 16 / 5.4; }
}
@media (max-width: 900px) {
  .home-carousel-viewport { aspect-ratio: 16 / 7; }
}
@media (max-width: 620px) {
  .home-carousel-viewport { aspect-ratio: 3 / 2; }
}
@media (max-width: 420px) {
  .home-carousel-viewport { aspect-ratio: 4 / 3; }
}
.home-carousel-track {
  display: flex;
  height: 100%;
  /* will-change is applied only while a transition is running (see the JS
     toggling .is-animating) - keeping it on permanently promoted a big
     always-live compositor layer that added to scroll cost. */
  transition: transform 0.55s cubic-bezier(0.4, 0.0, 0.2, 1);
}
.home-carousel.is-animating .home-carousel-track {
  will-change: transform;
}
.home-carousel.no-anim .home-carousel-track {
  transition: none;
}
.home-carousel-slide {
  position: relative;
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  display: block;
  text-decoration: none;
  color: #fff;
}
.home-carousel-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}
.home-carousel-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 40px 26px 22px;
  font-family: var(--font-serif);
  font-size: clamp(1rem, 2.4vw, 1.5rem);
  font-weight: 700;
  line-height: 1.2;
  color: #fff;
  background: linear-gradient(to top, rgba(20, 14, 8, 0.62), rgba(20, 14, 8, 0));
  pointer-events: none;
}
/* Arrows - hidden on touch/small screens where dots + swipe suffice. */
.home-carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 250, 243, 0.86);
  color: #2a211b;
  font-size: 1.7rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(45, 31, 22, 0.24);
  transition: background 0.15s ease, transform 0.15s ease;
}
.home-carousel-arrow:hover {
  background: #fff;
  /* Re-assert the centering transform on hover so the button can't inherit a
     stray lift (e.g. a generic .btn:hover translateY) and jump off-centre.
     Only the deliberate :active press below changes the transform. */
  transform: translateY(-50%);
}
.home-carousel-arrow:hover,
.home-carousel-arrow:focus,
.home-carousel-arrow:focus-visible,
.home-carousel-arrow:active {
  /* Never shift/scale on hover, focus or tap (a press-scale on touch reads as
     the arrow "moving"); only colour/shadow may change. */
  transform: translateY(-50%) !important;
}
.home-carousel-prev { left: 14px; }
.home-carousel-next { right: 14px; }
.home-carousel-dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 12px;
  z-index: 3;
  display: flex;
  justify-content: center;
  gap: 8px;
}
.home-carousel-dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.55);
  box-shadow: 0 0 0 1px rgba(45, 31, 22, 0.18);
  cursor: pointer;
  transition: width 0.2s ease, background 0.2s ease;
}
.home-carousel-dot.is-active {
  width: 26px;
  background: #fff;
}
.home-carousel-dot:focus-visible,
.home-carousel-arrow:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}
@media (max-width: 760px) {
  .home-carousel {
    border-radius: 16px;
    margin: 12px 0 24px;
  }
  .home-carousel-viewport {
    aspect-ratio: 3 / 2;
    max-height: none;
  }
  .home-carousel-arrow {
    display: none;
  }
  .home-carousel-caption {
    padding: 30px 16px 16px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .home-carousel-track {
    transition: none;
  }
}

/* --- Carousel admin editor (#19) --- */
.carousel-settings-form,
.carousel-add-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 14px;
}
.carousel-settings-form label,
.carousel-add-form label,
.carousel-slide-edit label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 0.82rem;
  font-weight: 600;
  color: #6b5d51;
}
.carousel-add-form label { flex: 1 1 240px; }
.carousel-settings-form .carousel-check {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}
.carousel-settings-form .carousel-check input { width: auto; }
.carousel-slide-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.carousel-slide-row {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr) auto;
  gap: 16px;
  align-items: start;
  padding: 14px;
  border: 1px solid var(--line, #e4dccd);
  border-radius: 14px;
  background: rgba(255, 253, 248, 0.7);
}
.carousel-slide-row.is-inactive { opacity: 0.55; }
.carousel-slide-thumb {
  width: 150px;
  aspect-ratio: 16 / 9;
  border-radius: 10px;
  overflow: hidden;
  background: #ece3d6;
}
.carousel-slide-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.carousel-slide-edit {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.carousel-slide-controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: stretch;
}
.carousel-slide-controls form { margin: 0; }
.carousel-slide-controls .danger-action {
  color: #b23b30;
}
@media (max-width: 760px) {
  .carousel-slide-row {
    grid-template-columns: 1fr;
  }
  .carousel-slide-thumb { width: 100%; }
}

/* --- Admin book/edition editor (#27) --- */
.admin-edit-link{display:inline-block;margin-bottom:10px;font-weight:700;font-size:.82rem;color:var(--accent,#a74434);text-decoration:none;border:1px solid var(--line,#e2dccd);border-radius:10px;padding:7px 12px;background:var(--paper,#fffdf8)}
.admin-edit-link:hover{border-color:var(--accent,#a74434)}
.admin-edit-form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px;margin-top:8px}
.admin-edit-form label{display:flex;flex-direction:column;gap:5px;font-size:.8rem;font-weight:600;color:#6b5d51}
.admin-edit-form .full{grid-column:1/-1}
.admin-edit-form input,.admin-edit-form select,.admin-edit-form textarea{padding:9px 11px;border:1px solid var(--line-strong,#d3cab6);border-radius:9px;background:#fff;font-size:.9rem;font-family:inherit}
.admin-edit-form textarea{resize:vertical}
.admin-edition-form{margin-top:14px}
.admin-edition-form h3{font-family:var(--font-serif);font-size:1rem;margin:0}
@media(max-width:640px){.admin-edit-form{grid-template-columns:1fr}}

/* ============================================================
   Per-shop promo codes on the book page (#promo). The promo-adjusted price
   reuses the discount styling; the code is a small tag; the toggle lets a
   visitor hide promo-adjusted prices (cookie-backed).
   ============================================================ */
/* The promo-adjusted price reads in the site's green "savings" colour. */
.offer-price-main.price-promo,
.offer-price-main.price-promo strong { color: #1f7a54; }
.offer-promo-codes { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }
/* Badge shows the code + discount %. Green while promo prices are active, grey
   when the visitor has toggled them off. */
.promo-code-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border: 1px solid #1f7a54;
  border-radius: 999px;
  background: #e7f4ec;
  color: #1f7a54;
  font-size: 0.72rem;
  font-weight: 750;
  letter-spacing: 0.02em;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.promo-code-badge em { font-style: normal; font-weight: 800; }
.work-editions.is-hiding-promo .promo-code-badge {
  background: #f1ece5 !important;
  border-color: #cdc3b6 !important;
  color: #8a7c70 !important;
}
/* Dual price: promo shown by default, base hidden; the toggle flips them. */
.is-hiding-promo [data-promo-price] { display: none; }
.is-hiding-promo [data-base-price] { display: block; }

/* Toggle: a pill button with an inner checkbox that fills green when on. */
.work-editions-head { display: flex; align-items: end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.promo-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px 7px 10px;
  border: 1px solid #cdbfae;
  border-radius: 999px;
  background: #fffaf4;
  color: #5c4f45;
  cursor: pointer;
  font: 650 0.8rem var(--font-sans);
}
.promo-toggle:hover { border-color: #1f7a54; }
.promo-toggle-box {
  position: relative;
  width: 17px;
  height: 17px;
  flex: none;
  border: 2px solid #b7ab9c;
  border-radius: 5px;
  background: #fff;
}
.promo-toggle[aria-pressed="true"] { border-color: #1f7a54; color: #1f7a54; background: #eaf5ee; }
.promo-toggle[aria-pressed="true"] .promo-toggle-box { background: #1f7a54; border-color: #1f7a54; }
.promo-toggle[aria-pressed="true"] .promo-toggle-box::after {
  content: "";
  position: absolute;
  left: 4px;
  top: 1px;
  width: 5px;
  height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
/* Admin shops page: dim a deactivated promo row */
.promo-inactive { opacity: 0.5; }

/* Book page: reader rating + 5-star input moved to the top of the identity
   block, laid out in one row (summary left, your stars to the right). */
.reader-rating.reader-rating-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 18px;
  margin: 12px 0 6px;
  padding: 0;
  border: 0;
  background: none;
}
.reader-rating-top .reader-rating-summary {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}
.reader-rating-top .reader-rating-summary strong { font-size: 0.9rem; }
.reader-rating-top .star-rating-form {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}

/* Mobile: bigger touch targets on the book page's rating stars + filter chips
   (were ~28px; ~44px is the comfortable tap size). */
@media (max-width: 600px) {
  .reader-rating-top .star-rating-star {
    min-width: 40px;
    min-height: 40px;
    padding: 5px;
    font-size: 1.75rem;
  }
  .offer-filter-bar .offer-filter-btn,
  .offer-filter-bar .promo-toggle {
    min-height: 40px;
  }
}

/* Admin shops page (mobile): let the delivery/promo-code tables scroll inside
   their panel instead of forcing horizontal page scroll on a phone. */
@media (max-width: 640px) {
  .shop-edit .delivery-method-table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }
}

/* ============================================================
   Catalogue burger menu (#5): a left slide-out drawer listing the
   whole catalogue grouped into curated two-level sections. Trigger
   sits at the far left of the header; groups are <details> so they
   expand/collapse (the two-level feel over otherwise-flat data).
   ============================================================ */
.catalog-menu-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-right: 6px;
  padding: 8px 12px;
  height: 42px;
  border: 1px solid var(--line, #e8ded2);
  border-radius: 12px;
  background: transparent;
  color: #55483e;
  font: 700 0.9rem var(--font-sans);
  cursor: pointer;
}
.catalog-menu-toggle:hover {
  border-color: #dfd2c5;
  background: #f4ece2;
}
.catalog-menu-toggle svg {
  width: 20px;
  height: 20px;
}
@media (max-width: 760px) {
  .catalog-menu-toggle {
    padding: 8px;
  }
  .catalog-menu-toggle-text {
    display: none;
  }
}

.catalog-drawer {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
}
.catalog-drawer[hidden] {
  display: none;
}
.catalog-drawer-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 14, 8, 0.45);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.catalog-drawer.is-open .catalog-drawer-backdrop {
  opacity: 1;
}
.catalog-drawer-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(360px, 88vw);
  height: 100%;
  padding: 18px 16px 26px;
  background: var(--paper, #fffdf9);
  box-shadow: 0 0 40px rgba(30, 20, 12, 0.28);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateX(-100%);
  transition: transform 0.22s ease;
}
.catalog-drawer.is-open .catalog-drawer-panel {
  transform: translateX(0);
}
.catalog-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.catalog-drawer-close {
  display: inline-flex;
  padding: 6px;
  border: 0;
  background: none;
  color: var(--muted);
  cursor: pointer;
}
.catalog-drawer-close svg {
  width: 22px;
  height: 22px;
}
.catalog-drawer-group {
  border-top: 1px solid var(--line);
}
.catalog-drawer-group > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 13px 4px;
  font: 800 0.95rem var(--font-sans);
  color: var(--ink);
  cursor: pointer;
  list-style: none;
}
.catalog-drawer-group > summary::-webkit-details-marker {
  display: none;
}
.catalog-drawer-chevron {
  width: 18px;
  height: 18px;
  color: var(--muted);
  transition: transform 0.18s ease;
  flex: none;
}
.catalog-drawer-group[open] > summary .catalog-drawer-chevron {
  transform: rotate(90deg);
}
.catalog-drawer-group ul {
  list-style: none;
  margin: 0 0 8px;
  padding: 0 0 4px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.catalog-drawer-group li a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 9px;
  color: #4a3f38;
  text-decoration: none;
  font-size: 0.88rem;
}
.catalog-drawer-group li a:hover {
  background: #f4ece2;
  color: var(--accent);
}
.catalog-drawer-count {
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
@media (prefers-reduced-motion: reduce) {
  .catalog-drawer-panel,
  .catalog-drawer-backdrop {
    transition: none;
  }
}

/* ============================================================
   Offer-row refinements (book page): freshness recency indicator +
   leaner mobile rows (icon-only cart/shop, colour-only availability &
   recency with tap tooltips).
   ============================================================ */
.stock-pill-dot { display: none; }
/* Availability colour: in-stock green (default pill), preorder/expected
   amber, out-of-stock red. */
.stock-pill.avail-preorder,
.stock-pill.avail-expected {
  background: #fbeecf;
  color: #8a6d2f;
}

/* Recency dot + label. */
.offer-updated .freshness {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.freshness-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: none;
  background: var(--muted);
}
.freshness-fresh .freshness-dot { background: #2e7a4d; }
.freshness-stale .freshness-dot { background: #c8871a; }
.freshness-old .freshness-dot { background: #b23b30; }

/* Store link: text + arrow on desktop. */
.store-link .store-link-arrow { font-weight: 700; }

/* Tap tooltip bubble (availability / recency on touch). */
.tap-tip {
  position: fixed;
  z-index: 120;
  max-width: 240px;
  padding: 7px 10px;
  border-radius: 8px;
  background: #241a12;
  color: #fff;
  font-size: 0.76rem;
  line-height: 1.3;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.28);
  pointer-events: none;
  opacity: 0;
  transform: translateY(2px);
  transition: opacity 0.12s ease, transform 0.12s ease;
}
.tap-tip.is-shown {
  opacity: 1;
  transform: translateY(0);
}

/* --- Mobile: strip the offer rows down to essentials --- */
@media (max-width: 640px) {
  /* Cart button -> icon only */
  .offer-actions .offer-cart-button span { display: none; }
  .offer-actions .offer-cart-button {
    width: 42px;
    padding: 0;
    justify-content: center;
  }
  /* Store link -> arrow only */
  .store-link .store-link-text { display: none; }
  .store-link {
    width: 42px;
    padding: 0;
    justify-content: center;
    font-size: 1.05rem;
  }
  /* Availability -> colour dot only, tappable for the label */
  .stock-pill {
    width: 14px;
    height: 14px;
    min-width: 0;
    padding: 0;
    border-radius: 50%;
    font-size: 0;
    gap: 0;
    cursor: pointer;
  }
  .stock-pill::before { display: none; }
  .stock-pill .stock-pill-text { display: none; }
  /* Recency -> colour dot only, tappable for the label. The legacy
     `.offer-updated{display:none}` (style.css, <=760px) hid the whole
     thing on mobile; re-show it here so the recency dot survives. */
  .offer-row-modern .offer-updated {
    display: flex;
    align-items: center;
    margin-top: 4px;
  }
  .offer-updated .freshness-text { display: none; }
  .offer-updated .freshness {
    cursor: pointer;
    padding: 4px;
    margin: -4px;
  }
  .freshness-dot {
    width: 12px;
    height: 12px;
  }
}

/* Remote worker schedule editor (#2, jobs/remote.html). */
.remote-schedule-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 10px;
}
.remote-schedule-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
}
.remote-schedule-row legend {
  padding: 0 6px;
  font-weight: 800;
  font-size: 0.9rem;
}
.remote-schedule-row .schedule-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.74rem;
  color: var(--muted);
}
.remote-schedule-row .schedule-field input {
  width: 130px;
}

/* Collection rail subtitle (admin subtitle_override / custom description). */
.collection-section-subtitle {
  margin: 2px 0 0;
  font-size: 0.86rem;
  color: var(--muted);
  line-height: 1.35;
}

/* Declutter the header on small screens: the catalogue burger now shares the
   top row with the brand, search toggle and account icons, so tighten sizes
   and gaps to give everything breathing room (no actions removed). */
@media (max-width: 600px) {
  .top .nav { gap: 4px; }
  .top .brand { font-size: 1.12rem; }
  .nav-links { gap: 1px; }
  .nav-links .nav-icon { width: 34px; height: 34px; }
  .catalog-menu-toggle {
    width: 38px;
    height: 38px;
    padding: 0;
    justify-content: center;
    margin-right: 2px;
  }
  .mobile-search-toggle { width: 38px; }
}

/* ============================================================
   Header 3-zone layout: burger + search on the LEFT, brand CENTERED,
   account icons on the RIGHT. Wishlist moved into the profile menu.
   ============================================================ */
/* Authoritative at all widths: overrides the legacy flex header in style.css
   (@media(max-width:700px){.top .wrap.nav{display:flex}} and friends), which
   assumed the old brand-left / icons-right structure. */
/* Desktop (>=601px): brand LEFT, then the burger, then a big search bar
   (Enter submits - no submit button), then the account icons on the right. */
.top .wrap.nav {
  display: flex !important;
  align-items: center;
  gap: 14px;
  min-height: 60px;
  grid-template-columns: none !important;
}
.top .wrap.nav .brand {
  order: 0;
  margin: 0 !important;
  flex: 0 0 auto;
}
.nav-zone.nav-left {
  order: 1;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.nav-zone.nav-left .site-search {
  flex: 1 1 auto;
  min-width: 0;
  max-width: none;
}
.top .wrap.nav .nav-links.nav-right {
  order: 2;
  margin: 0 !important;
  display: flex !important;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}
/* The separate search-toggle icon is only for narrow screens where the
   search bar collapses; on desktop the bar itself is visible so it's
   redundant. (<=700 matches the legacy breakpoint where .site-search hides.) */
@media (min-width: 701px) {
  .nav-left .mobile-search-toggle { display: none !important; }
}
/* Mobile (<=700px): burger + search icon on the left, brand centred, icons
   right - a compact 3-zone grid (matches where the search bar collapses). */
@media (max-width: 700px) {
  .top .wrap.nav {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) !important;
    gap: 8px;
  }
  /* Pin columns explicitly - the desktop `order` values would otherwise drive
     grid auto-placement and shove the brand into column 1. */
  .nav-zone.nav-left { grid-column: 1 !important; order: 0 !important; flex: 0 0 auto; justify-self: start; }
  .top .wrap.nav .brand { grid-column: 2 !important; order: 0 !important; justify-self: center; }
  .top .wrap.nav .nav-links.nav-right { grid-column: 3 !important; order: 0 !important; justify-self: end !important; }
}
/* Burger + search share one identical framed-button style. */
.catalog-menu-toggle,
.nav-left .mobile-search-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 42px;
  min-width: 42px;
  padding: 0 12px;
  border: 1px solid var(--line, #e8ded2) !important;
  border-radius: 12px !important;
  background: transparent !important;
  color: #55483e !important;
  cursor: pointer;
}
.catalog-menu-toggle:hover,
.nav-left .mobile-search-toggle:hover {
  border-color: #dfd2c5 !important;
  background: #f4ece2 !important;
}
.nav-left .mobile-search-toggle {
  padding: 0;
  width: 42px;
}
.catalog-menu-toggle svg,
.nav-left .mobile-search-toggle svg {
  width: 20px;
  height: 20px;
}
/* Right-hand account icons: identical square buttons + identical glyph size
   (the cart glyph otherwise reads a touch smaller than bell/profile). */
.nav-links.nav-right .nav-icon,
.nav-links.nav-right [data-notif-toggle] {
  width: 42px;
  height: 42px;
}
.nav-links.nav-right .nav-icon svg,
.nav-links.nav-right .nav-icon .icon,
.nav-links.nav-right [data-notif-toggle] svg,
.nav-links.nav-right [data-notif-toggle] .icon {
  width: 22px !important;
  height: 22px !important;
  /* These svgs are flex items inside the icon button; without flex:none they
     shrink (cart/shop rendered 16px wide while bell/profile stayed 22px). */
  flex: 0 0 auto !important;
  min-width: 22px;
  stroke-width: 1.85;
}
/* Wishlist link inside the profile menu (moved off the header). */
.profile-panel-links a {
  display: flex;
  align-items: center;
  gap: 8px;
}
.profile-panel-links a svg {
  width: 18px;
  height: 18px;
  flex: none;
}
.profile-panel-link-count {
  margin-left: auto;
  min-width: 20px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--accent-soft, #f5e5df);
  color: var(--accent, #a74434);
  font-size: 0.72rem;
  font-weight: 800;
  text-align: center;
}
@media (max-width: 600px) {
  /* The centred brand + two flanking zones still fit; keep the search a
     toggle (icon) on the left so the row stays uncrowded. */
  .top .nav { gap: 6px; }
}

/* Scroll performance: skip rendering/painting off-screen collection rails
   until they're near the viewport, so scrolling past rows of heavy cover
   images doesn't trigger their paint every frame. contain-intrinsic-size
   reserves an estimated height (then remembers the real one) to keep the
   scrollbar stable. */
.collection-section,
.budget-tabs-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 520px;
}

/* Budget tabs. These lived in jobs.css, which is a job-dashboard
   stylesheet that public pages stopped loading - and took the homepage's
   budget section's styling with it, leaving bare radio buttons stacked
   down the page. They belong beside .budget-tabs-section, which is here. */
.budget-tabs{border:0;margin:0;padding:0;min-width:0}
.budget-tab-input{position:absolute;opacity:0;width:1px;height:1px;overflow:hidden}
.budget-tab-label{display:inline-block;padding:9px 18px;margin:0 8px 14px 0;border:1px solid var(--line);border-radius:999px;cursor:pointer;font-weight:650;font-size:.88rem;color:var(--muted);background:var(--card)}
.budget-tab-input:checked + .budget-tab-label{background:var(--red);border-color:var(--red);color:#fff}
.budget-tab-input:focus-visible + .budget-tab-label{outline:2px solid var(--red);outline-offset:2px}
.budget-tab-panel{display:none}
.budget-tab-view-all{display:inline-block;margin-top:10px;font-weight:750;color:#a94737;text-decoration:none}
/* Thresholds are admin-configurable (arbitrary integers), so panels can't
   be matched to their radio by id/value in static CSS - :nth-of-type
   pairs the Nth radio (counted among <input> siblings) with the Nth panel
   (counted among <div> siblings) regardless of what number either one is
   actually labelled with. Both loops in _budget_tabs.html render tabs and
   panels under the same "if books" condition in the same order, so the
   Nth rendered radio and Nth rendered panel are always the same tab. */
.budget-tab-input:nth-of-type(1):checked ~ .budget-tab-panel:nth-of-type(1),
.budget-tab-input:nth-of-type(2):checked ~ .budget-tab-panel:nth-of-type(2),
.budget-tab-input:nth-of-type(3):checked ~ .budget-tab-panel:nth-of-type(3){display:block}


/* --- book-card.css --- */
/* ==========================================================================
   Book card - single source of truth.

   This replaces every book-card rule previously scattered across style.css
   (6+ layered historical redesigns of .book-card/.grid/.book-cover-wrap,
   never cleaned up), postgres-ui.css, card-refresh.css, ui-polish.css and
   ui-polish-2.css. Rebuilt 2026-07-22 from the actual live computed styles
   (Chrome DevTools Protocol getComputedStyle on a real rendered card), not
   from re-reading the old cascade, so this reproduces exactly what was
   really on screen - including several fixes made the same night:
     - align-self:flex-start (an old unscoped ".book-card{align-self:stretch}"
       rule was silently winning and stretching every card to match its row)
     - the cover image centered via position:absolute + transform, not the
       percentage-height-on-a-static-element approach that didn't reliably
       resolve pre-paint
     - cover margin (15px 15px 0) matches the body's own padding so the
       cover and the text block sit the same distance from the card border
     - explicit width/height attributes on <img> (see _book_card.html) so
       the browser reserves the right box before the image loads, avoiding
       a layout-settle glitch for lazy-loaded images inside a horizontally
       scrolling row

   Markup (app/templates/_book_card.html):
     <article class="unified-book-card [compact-book-card] format-paper|format-electronic">
       <a class="unified-card-cover">
         <img class="book-cover">                (or .book-cover-placeholder)
         <span class="card-discount-tag">        (optional)
         <span class="card-rating-hero">         (optional)
       </a>
       <div class="card-quick-actions">
         <button/a class="heart-button">
       </div>
       <div class="book-card-body">
         <div class="card-chip-row"><span class="card-chip ...">
         <div class="book-card-copy">
           <h3 class="book-title"><div class="book-author">
         <div class="card-footer">
           <div class="edition-card-price">
             <div><span class="card-price-row"><strong><s class="card-old-price">
             <button class="card-cart-button">
           <div class="card-compare-line">
   ========================================================================== */

/* --- Card container ---
   2026-07-22: adopted the denser proportions the "related/similar books"
   compact card had (smaller padding, taller 3/4 cover) as the main design
   for every context - it read as cleaner than the original, more padded
   version. Scaled up somewhat from the compact card's own numbers (which
   were tuned for a 6-per-row context), and kept the chip row + compare
   line visible here (the compact variant hid both to save space, but the
   main grid/scroll-row has the room and the info is useful). */
.unified-book-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  min-width: 0;
  height: auto;
  min-height: 0;
  padding: 12px 12px 14px;
  border: 1px solid var(--line, #e3d9c9);
  border-radius: 16px;
  background: var(--card, #fffaf3);
  /* Tighter blur (was 0 8px 22px) - big blur radii raster ~quadratically with
     radius, and a whole row of cards re-rasters as it scrolls into view, so a
     smaller shadow measurably cuts scroll paint cost for a near-identical look. */
  box-shadow: 0 5px 13px rgba(52, 36, 21, 0.07);
  box-sizing: border-box;
  overflow: visible;
  cursor: pointer;
  align-self: flex-start;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.unified-book-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 32px rgba(52, 36, 21, 0.1);
}
.unified-book-card:focus-visible {
  outline: 3px solid rgba(167, 68, 52, 0.35);
  outline-offset: 4px;
}

/* --- Cover frame: no background box (removed the green-tinted gradient),
   aspect-ratio-driven so it scales with the card's own width, margin
   matches the body's own side/top padding so cover and text line up. --- */
.unified-book-card .unified-card-cover {
  /* Must stay ".unified-book-card .unified-card-cover" (2 classes), not a
     bare ".unified-card-cover" - style.css has an old, still-present
     ".book-card .book-cover-wrap{aspect-ratio:2/3}" (2 classes too) that a
     1-class selector here would lose to regardless of file order. */
  position: relative;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 100%;
  margin: 0;
  aspect-ratio: 3 / 4;
  /* The frame carries the rounded corners + soft shadow so EVERY card reads as
     an identical-sized tile regardless of the cover's own aspect ratio. The
     image is contained (object-fit:contain below) so it's never cropped; the
     neutral matte fill below shows in the letterbox margin around covers whose
     ratio doesn't match the frame. */
  background: #f0e7db;
  border-radius: 13px;
  overflow: hidden;
  box-sizing: border-box;
  /* Tighter blur (was 0 8px 18px) for the same scroll-paint reason as the
     card body shadow above. */
  box-shadow: 0 5px 11px rgba(45, 31, 22, 0.16);
}

/* --- Cover image: absolute + transform-centered (not percentage-height on
   a static element - see file header) - fills the frame right up to its
   edge, object-fit:contain so it's never cropped at any aspect ratio. --- */
.unified-book-card .book-cover,
.unified-book-card:hover .book-cover,
.book-card:hover .book-cover {
  /* All three selectors matter, not just the plain one: style.css has an
     old ".book-card .book-cover, .book-card:hover .book-cover
     {transform:none!important;...}" rule. The :hover-qualified half is
     (0,0,3,0) specificity (:hover counts like a class) - HIGHER than a
     plain 2-class selector - so on hover specifically it would win outright
     regardless of !important or file order unless matched here too.
     !important throughout because the competing rule also uses it - without
     it, importance alone (checked before specificity) would let style.css's
     version win even at equal/lower specificity. */
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  transform: none !important;
  width: 100% !important;
  height: 100% !important;
  max-width: 100% !important;
  max-height: 100% !important;
  /* object-fit:contain, NOT cover - never crop the cover. The frame carries a
     neutral matte (#f0e7db) so the letterbox margin around covers that don't
     match the frame ratio reads as intentional padding rather than a bug (per
     product call: prefer a little empty space over a cropped cover). The cover
     keeps lightly rounded corners of its own. */
  object-fit: contain !important;
  object-position: center;
  border-radius: 6px;
  box-shadow: none;
}

/* --- Discount tag / Goodreads rating, overlaid on the cover corners --- */
.unified-book-card .card-discount-tag {
  position: absolute;
  z-index: 7;
  top: 10px;
  left: 10px;
  padding: 5px 10px;
  border-radius: 999px;
  background: var(--red, #a74434);
  color: #fff;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.01em;
  box-shadow: 0 4px 12px rgba(55, 39, 26, 0.2);
}
.unified-book-card .card-rating-stack {
  position: absolute;
  z-index: 6;
  bottom: 10px;
  right: 10px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}
.unified-book-card .card-rating-hero {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  border-radius: 999px;
  background: rgba(255, 250, 243, 0.94);
  color: #6b4b1f;
  font-size: 0.72rem;
  font-weight: 800;
  box-shadow: 0 4px 12px rgba(55, 39, 26, 0.14);
}
.unified-book-card .card-rating-goodreads img {
  width: 12px;
  height: 12px;
}

/* .heart-button is also used bare (no .unified-book-card ancestor) on the
   wishlist page's own card layout (app/templates/user/wishlist.html) - not
   scoped to the catalog card component, deliberately - stays the original
   38px size there; the card context sizes both buttons down below. */
.heart-button,
.card-cart-button {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border: 1px solid rgba(91, 69, 50, 0.17);
  border-radius: 12px;
  background: rgba(255, 250, 243, 0.94);
  color: #4c3b30;
  font-size: 1.35rem;
  box-shadow: 0 4px 12px rgba(55, 39, 26, 0.14);
  cursor: pointer;
}
.unified-book-card .heart-button,
.unified-book-card .card-cart-button {
  width: 36px;
  height: 36px;
  border-radius: 11px;
  font-size: 1.15rem;
  flex: 0 0 auto;
}
.unified-book-card .heart-button .icon,
.unified-book-card .card-cart-button .icon {
  width: 18px;
  height: 18px;
}
.heart-button:hover,
.heart-button:focus-visible {
  color: var(--red, #a74434);
}
.card-cart-button:hover,
.card-cart-button:focus-visible {
  color: #176d4f;
}
.heart-button .icon {
  transition: fill 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.heart-button:active .icon {
  transform: scale(0.88);
}
/* Filled red when the book is already saved. There were briefly two
   competing versions of this rule (postgres-ui.css: green, unused since
   ui-polish-2.css's red version loaded later with matching !important and
   actually won) - this is the one that was really on screen. */
.heart-button.is-saved {
  color: #c73b2f;
  background: #fdeceb;
  border-color: rgba(199, 59, 47, 0.3);
}
.heart-button.is-saved .icon {
  fill: currentColor;
}
/* Green check when the book is already in the cart - same treatment as
   the wishlist heart's is-saved state above, distinct color so the two
   states never read as the same thing at a glance. */
.card-cart-button.is-in-cart {
  color: #176d4f;
  background: #e9f4ee;
  border-color: rgba(23, 109, 79, 0.3);
}

/* --- Body: chip row, title/author, footer (price + compare line) --- */
.unified-book-card .book-card-body {
  /* Side padding matches the cover's own extra margin (10px) so text and
     cover line up at the same inset from the card border - same reasoning
     as the original "unify the padding" fix, just re-tuned to the smaller
     numbers here. */
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
  gap: 6px;
  padding: 8px 0 8px;
  box-sizing: border-box;
}

.unified-book-card .card-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 20px;
}
.unified-book-card .card-chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 8px;
  border-radius: 999px;
  font-size: 0.64rem;
  font-weight: 800;
  line-height: 1.4;
  white-space: nowrap;
}
.unified-book-card .card-chip-paper {
  background: #e6f0e4;
  color: #2e6b40;
}
.unified-book-card .card-chip-ebook {
  background: #e4effd;
  color: #2c63ae;
}
.unified-book-card .card-chip-unavailable {
  background: #eee9e3;
  color: var(--muted, #7b7067);
}
/* Why a search result is here when the title alone doesn't explain it -
   deliberately quieter than the format chips beside it, since it answers a
   question rather than describing the book. */
.unified-book-card .card-chip-match {
  background: transparent;
  border: 1px solid #ded4c8;
  color: var(--muted, #7b7067);
  font-weight: 600;
}

.unified-book-card .book-card-copy {
  /* min-height (not per-line-clamped-element height) so a short one-line
     title still sits tight against the author line - any reserved space
     for a hypothetical second title line shows up below the author line
     instead of between title and author, keeping the footer/price row at
     the same vertical position across every card in a row regardless of
     title length. */
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  height: auto;
  min-height: 3.9em;
  overflow: visible;
}
.unified-book-card .book-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  margin: 0;
  padding: 0;
  font-family: var(--font-serif);
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.3;
  text-overflow: ellipsis;
}
.unified-book-card .book-title a {
  color: inherit;
  text-decoration: none;
}
.unified-book-card .book-author {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
  margin-top: 4px;
  color: #75685d;
  font-size: 0.76rem;
  line-height: 1.3;
  white-space: normal;
  text-overflow: ellipsis;
}

.unified-book-card .card-footer {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: auto;
}
.unified-book-card .edition-card-price {
  display: grid;
  grid-template-columns: 38px minmax(76px, 1fr) 38px;
  align-items: center;
  flex: 0 0 auto;
  height: auto;
  min-height: 54px;
  gap: 10px;
  padding-top: 7px;
  border-top: 1px solid rgba(92, 67, 44, 0.16);
  box-sizing: border-box;
}
.unified-book-card .edition-card-price > div {
  display: flex;
  min-width: 0;
  flex-direction: column;
  align-items: center;
  overflow: hidden;
  text-align: center;
}
.unified-book-card .card-price-details {
  min-height: 45px;
  justify-content: center;
}
.unified-book-card .card-price-details.regular-prices {
  justify-content: center;
}
.unified-book-card .card-price-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 0 6px;
  min-width: 0;
  /* Reserves 2-line height on every card, not just the ones that actually
     wrap - without this, a discounted card whose old price wraps onto its
     own line (measured 29.1px) ends up 11px taller than a neighboring
     card whose price fits on one line (16.2px), breaking row alignment in
     both .book-grid and .book-row-scroll (cards use height:auto by
     design, see the .unified-book-card comment above, so nothing else
     equalizes them). Confirmed live via CDP on /collection/discount. */
  min-height: 30px;
}
.unified-book-card .card-price-details.has-discount .card-price-row {
  flex-direction: column;
  align-items: center;
  gap: 1px;
}
.unified-book-card .card-price-details.regular-prices .card-price-row {
  min-height: 0;
}
.unified-book-card .card-price-row strong,
.unified-book-card .edition-card-price small {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* Black by default (both paper and eBook-only cards), red only when
   discounted - a later, higher-specificity rule than the green/blue
   format-coded colors below had actually already replaced them; this
   reproduces the real winning behavior, not the superseded one. */
.unified-book-card .card-price-row strong {
  flex: 0 0 auto;
  min-width: 0;
  max-width: 100%;
  font-family: var(--font-sans);
  font-size: clamp(1.05rem, 1.3vw, 1.32rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: #211a14;
  word-break: normal;
}
.unified-book-card .card-price-row strong.price-discounted {
  color: var(--red, #a74434);
}
/* Ebook-only cards (no paper offer at all) show their single price in the
   same blue used for the ebook subtitle line/book page, instead of
   defaulting to the paper-price dark tone - discount red still wins if
   both apply, since a deal matters more than the format at a glance. */
.unified-book-card .card-price-row strong.ebook-price-tone-main {
  color: #315f9d;
}
.unified-book-card .card-price-row strong.ebook-price-tone-main.price-discounted {
  color: var(--red, #a74434);
}
.unified-book-card .edition-price-format {
  white-space: nowrap;
}
.unified-book-card .card-old-price {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  color: var(--muted, #8a7d70);
  font-size: 0.8rem;
  font-weight: 500;
  text-decoration: line-through;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.unified-book-card .ebook-price-tone {
  margin-top: 5px;
  color: #315f9d;
  font: 600 0.66rem var(--font-sans);
}
@media (max-width: 700px) {
  .unified-book-card .edition-card-price {
    grid-template-columns: 32px minmax(0, 1fr) 32px;
    min-height: 48px;
    gap: 4px;
  }
  .unified-book-card .heart-button,
  .unified-book-card .card-cart-button {
    width: 32px;
    height: 32px;
    border-radius: 10px;
  }
  .unified-book-card .card-price-row strong {
    font-size: 0.88rem;
  }
  .unified-book-card .ebook-price-tone {
    font-size: 0.58rem;
  }
  .unified-book-card .card-compare-line {
    padding-top: 6px;
    font-size: 0.64rem;
  }
}
@media (max-width: 600px) {
  .unified-book-card {
    padding: 10px 9px 12px;
  }
  .unified-book-card .unified-card-cover {
    /* Real book covers are ~2/3; a 4/5 frame is much wider than that, so
       object-fit:cover cropped the top/bottom heavily on phones. 2/3 matches
       the covers so almost nothing is cropped while tiles stay uniform. */
    aspect-ratio: 2 / 3;
  }
  .unified-book-card .book-card-body {
    gap: 5px;
    padding: 7px 0 6px;
  }
  .unified-book-card .card-chip-row {
    gap: 4px;
  }
  .unified-book-card .card-chip {
    padding: 3px 7px;
    font-size: 0.6rem;
  }
  .unified-book-card .book-title {
    font-size: 0.78rem;
  }
  .unified-book-card .book-author {
    font-size: 0.72rem;
  }
}
.unified-book-card .regular-prices .ebook-price-tone {
  margin-top: 2px;
}
.unified-book-card .edition-card-price .card-cart-button {
  justify-self: end;
}
.unified-book-card .edition-card-price .card-heart-form,
.unified-book-card .edition-card-price > .heart-button {
  justify-self: start;
}

.unified-book-card .card-compare-line {
  padding-top: 8px;
  border-top: 1px solid var(--line, #e8ded2);
  color: var(--muted, #8a7d70);
  font-size: 0.7rem;
  text-align: center;
}

/* --- Filter/results toolbars near the offer badges reuse .badge (see
   base site styles) - no card-specific override needed. --- */

/* --- Grid (search/collection results) and horizontal scroll row (home
   page curated collections) - two different layout containers for the
   same card component. --- */
.book-grid,
.collection-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
  align-items: start;
}
@media (max-width: 1100px) {
  .book-grid,
  .collection-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
@media (max-width: 820px) {
  .book-grid,
  .collection-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media (max-width: 600px) {
  .book-grid,
  .collection-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 370px) {
  .book-grid,
  .collection-grid {
    grid-template-columns: 1fr;
  }
}

.scroll-row-wrap {
  position: relative;
  width: 100%;
}
.book-row-scroll {
  display: flex;
  flex-wrap: nowrap;
  /* stretch, not flex-start: every card in the row takes the height of the
     tallest, so a card with a discount's extra struck-price line no longer
     renders shorter/taller than its neighbours. */
  align-items: stretch;
  width: 100%;
  gap: 12px;
  padding: 4px 4px 10px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-padding-left: 4px;
  /* a thin, unobtrusive scrollbar (was hidden) so the row's scrollability is
     discoverable and draggable. */
  scrollbar-width: thin;
  scrollbar-color: rgba(150, 120, 95, 0.4) transparent;
}
.book-row-scroll::-webkit-scrollbar {
  height: 7px;
}
.book-row-scroll::-webkit-scrollbar-thumb {
  background: rgba(150, 120, 95, 0.4);
  border-radius: 4px;
}
.book-row-scroll::-webkit-scrollbar-thumb:hover {
  background: rgba(150, 120, 95, 0.6);
}
.book-row-scroll::-webkit-scrollbar-track {
  background: transparent;
}
.book-row-scroll > * {
  flex: 0 0 210px;
  width: 210px;
  max-width: 210px;
  scroll-snap-align: start;
}
@media (max-width: 700px) {
  /* Size cards to the viewport so two fit cleanly with a visible sliver of
     the next one peeking in - that partial card is the affordance that tells a
     phone user the row scrolls horizontally (previously a fixed 190px let the
     2nd card get clipped at the edge with no intentional peek). clamp keeps
     them sane on very small and larger phones. */
  .book-row-scroll > * {
    flex-basis: clamp(140px, 42vw, 190px);
    width: clamp(140px, 42vw, 190px);
    max-width: 190px;
  }
}

.scroll-arrow {
  position: absolute;
  top: 50%;
  z-index: 5;
  display: grid;
  width: 44px;
  height: 44px;
  transform: translateY(-50%);
  place-items: center;
  border: 1px solid var(--line, #e8ded2);
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 8px 20px rgba(52, 36, 21, 0.22);
  color: #352a20;
  font-size: 1.5rem;
  font-weight: 700;
  cursor: pointer;
}
button.scroll-arrow:hover {
  /* No size/position change on hover - only colour + shadow - so the arrow
     never appears to "jump". The centering transform is re-asserted so no
     generic button:hover rule can lift it off-centre. */
  transform: translateY(-50%);
  border-color: #c9a173;
  box-shadow: 0 10px 24px rgba(52, 36, 21, 0.3);
}
button.scroll-arrow:hover,
button.scroll-arrow:focus,
button.scroll-arrow:focus-visible,
button.scroll-arrow:active {
  /* No shift/scale on hover, focus or tap - only colour/shadow change. */
  transform: translateY(-50%) !important;
}
.scroll-arrow-left {
  left: -8px;
}
.scroll-arrow-right {
  right: -8px;
}
.scroll-arrow[hidden] {
  display: none;
}
@media (max-width: 700px) {
  .scroll-arrow {
    display: none;
  }
}

/* --- Placeholder cover (no image_url, or the image failed to load - see
   onerror on <img class="book-cover"> in _book_card.html). Only used by
   the card component (the book detail page's own hero cover placeholder
   is .book-summary-placeholder, a separate rule in card-refresh.css). --- */
.unified-book-card .book-cover-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  height: 100%;
  padding: 14px;
  border-radius: 12px;
  color: #8d765e;
  font-size: 0.78rem;
  text-align: center;
}
.placeholder-icon {
  width: 34%;
  max-width: 46px;
  height: auto;
  opacity: 0.5;
}
.unified-book-card .book-cover-placeholder small {
  font-weight: 700;
  line-height: 1.3;
}
/* Author-stylesheet `display` rules always beat the browser's own
   [hidden]{display:none} (origin outranks specificity) - the onerror
   fallback only actually hides this once we say so explicitly, or a
   successfully-loaded cover and the placeholder both render at once. */
.unified-book-card .book-cover-placeholder[hidden] {
  display: none !important;
}

/* --- Compact variant (related/similar books on the book detail page,
   e.g. "Інші книжки автора" / "Схожі книги") - same markup/macro as the
   full card, every dimension shrinks together (cover, text, price)
   instead of only cropping the cover. --- */
.compact-book-grid {
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
}
@media (max-width: 1100px) {
  .compact-book-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
@media (max-width: 650px) {
  .compact-book-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media (max-width: 420px) {
  .compact-book-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* The "related/similar books" rows now use the exact same card design as
   the main grid/scroll-row (see the top of this file) - previously a
   separate, denser .compact-book-card override, folded away 2026-07-22
   once the main design adopted its proportions instead. Only the
   content-visibility opt-out still needs to be card-specific. */
.compact-book-card.unified-book-card {
  /* Long catalog grids use content-visibility:auto as a rendering-
     virtualization hint (see .unified-book-card above is NOT given this -
     it turned out to interfere with how far a grid track can shrink the
     card on narrow viewports, confirmed live: full-size card despite every
     layout property being correct, on mobile specifically). These compact
     rows only ever hold ~10 items - no virtualization benefit worth that
     risk, so it's opted out explicitly rather than left ambiguous. */
  content-visibility: visible;
  contain-intrinsic-size: auto;
}

/* Same opt-out for horizontally-scrolling home page collection rows
   (see style.css's .book-card{content-visibility:auto}). content-visibility
   skips layout for cards not yet scrolled into view and substitutes the
   contain-intrinsic-size placeholder box, which doesn't match this card's
   real (redesigned, smaller) size - so off-screen cards report a taller
   height than they actually render at until the user scrolls past them.
   Since a flex row's own height is driven by its tallest child, on- or
   off-screen, that wrong placeholder height was inflating the whole row -
   showing up as a big empty gap before the next home page section. These
   rows cap out around 30 items, so there's no real virtualization win
   worth that bug. */
.book-row-scroll .book-card {
  content-visibility: visible;
  contain-intrinsic-size: auto;
}

/* --- Loading skeleton: shown in place of #search-results while an AJAX
   search/filter/sort/page fetch is in flight (see storefront.js's
   loadResults) - a shimmering placeholder shaped like the real card so the
   grid doesn't visibly collapse/flash blank while the request is running.
   Built fresh against the current card proportions (12px padding, 3/4
   cover) rather than reusing style.css's older, now-unused .skeleton-card
   (which was sized for a since-replaced card design and never wired up to
   anything). */
.book-card-skeleton {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: 12px 12px 14px;
  border: 1px solid var(--line, #e3d9c9);
  border-radius: 16px;
  background: var(--card, #fffaf3);
  box-shadow: 0 8px 22px rgba(52, 36, 21, 0.06);
  box-sizing: border-box;
  pointer-events: none;
}
.skeleton-shimmer {
  display: block;
  background: linear-gradient(100deg, #eee5da 20%, #faf5ee 38%, #eee5da 56%);
  background-size: 220% 100%;
  animation: skeleton-shimmer 1.25s ease-in-out infinite;
}
.book-card-skeleton .skeleton-cover {
  width: 100%;
  aspect-ratio: 3 / 4;
  border-radius: 13px;
}
.book-card-skeleton .skeleton-line {
  height: 12px;
  margin-top: 10px;
  border-radius: 6px;
}
.book-card-skeleton .skeleton-line.title {
  width: 90%;
  height: 15px;
}
.book-card-skeleton .skeleton-line.author {
  width: 55%;
}
.book-card-skeleton .skeleton-line.price {
  width: 40%;
  height: 20px;
  margin-top: 14px;
}
@keyframes skeleton-shimmer {
  to {
    background-position-x: -220%;
  }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton-shimmer {
    animation: none;
  }
}

/* --- Login/register slide-over (base.html's [data-auth-panel],
   storefront.js's openAuthPanel/loadAuthPanel) --- */
.auth-panel[hidden] {
  display: none;
}
.auth-panel-backdrop {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(37, 28, 21, 0.35);
  backdrop-filter: blur(3px);
  animation: auth-fade-in 0.18s ease;
}
.auth-panel-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 201;
  display: flex;
  flex-direction: column;
  width: min(420px, 100vw);
  padding: 28px 26px;
  background: var(--card, #fffaf3);
  box-shadow: -18px 0 50px rgba(40, 25, 15, 0.22);
  overflow-y: auto;
  animation: auth-slide-in 0.22s ease;
}
@keyframes auth-fade-in {
  from { opacity: 0; }
}
@keyframes auth-slide-in {
  from { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) {
  .auth-panel-backdrop,
  .auth-panel-drawer {
    animation: none;
  }
}
.auth-panel-close {
  align-self: flex-end;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 11px;
  background: transparent;
  color: var(--muted, #8a7d70);
  font-size: 1.4rem;
  cursor: pointer;
}
.auth-panel-close:hover {
  background: #f3ede4;
}
.auth-panel-body {
  margin-top: 4px;
}
.auth-panel-body h2 {
  margin: 0 0 20px;
  font: 700 1.6rem var(--font-serif);
}
.auth-panel-body form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.auth-panel-body label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  color: var(--muted, #8a7d70);
  font-size: 0.85rem;
  font-weight: 650;
}
.auth-panel-body input:not([type="checkbox"]) {
  padding: 12px 14px;
  border: 1px solid var(--line, #e3d9c9);
  border-radius: 11px;
  background: #fff;
  font: inherit;
}
.auth-panel-body input:focus-visible {
  outline: 2px solid var(--accent, #a74434);
  outline-offset: 1px;
}
.auth-panel-check {
  flex-direction: row !important;
  align-items: center;
  gap: 8px !important;
}
.auth-panel-check input {
  width: auto;
}
.auth-panel-body button[type="submit"] {
  margin-top: 4px;
  padding: 13px 18px;
  border: 0;
  border-radius: 12px;
  background: var(--red, #a74434);
  color: #fff;
  font-weight: 750;
  cursor: pointer;
}
.auth-panel-body button[type="submit"]:disabled {
  opacity: 0.6;
  cursor: default;
}
/* Sign-in-with-Google/Microsoft buttons (auth/_sso.html). Deliberately not
   styled like the primary submit: the password form stays the primary path,
   and a second solid red button beside it would read as two equal choices. */
.sso-block {
  display: grid;
  gap: 10px;
  margin-top: 18px;
}
.sso-divider {
  display: grid;
  grid-template-columns: 1fr max-content 1fr;
  align-items: center;
  gap: 12px;
  color: var(--muted, #8a7d70);
  font-size: 0.8rem;
}
.sso-divider::before,
.sso-divider::after {
  content: "";
  height: 1px;
  background: var(--line, #e3d9c9);
}
.sso-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 16px;
  border: 1px solid var(--line, #e3d9c9);
  border-radius: 12px;
  background: #fff;
  color: var(--ink, #2f2a24);
  font-weight: 650;
  font-size: 0.92rem;
  text-decoration: none;
}
.sso-button:hover {
  border-color: var(--muted, #8a7d70);
}
.sso-button:focus-visible {
  outline: 2px solid var(--accent, #a74434);
  outline-offset: 2px;
}
.sso-mark {
  flex: none;
  width: 18px;
  height: 18px;
}
.auth-panel-switch {
  margin-top: 18px;
  color: var(--muted, #8a7d70);
  font-size: 0.85rem;
}
.auth-panel-switch a {
  color: var(--accent, #a74434);
  font-weight: 700;
}
.reader-rating {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--line, #e3d9c9);
  color: var(--muted, #8a7d70);
  font-size: .82rem;
}
.reader-rating strong { color: var(--ink, #302720); }
.reader-rating form { display: flex; align-items: center; gap: 9px; margin-left: auto; }
.star-rating-label { min-width: 116px; font-size: .76rem; text-align: right; }
.star-rating-stars { display: inline-flex; gap: 1px; }
.star-rating-star { width: 28px; padding: 0; border: 0; background: linear-gradient(90deg, var(--star-fill, #d29b28) var(--star-fill-width, 0%), #e9dfd1 var(--star-fill-width, 0%)); background-clip: text; -webkit-background-clip: text; color: transparent; font-size: 1.65rem; line-height: 1; cursor: pointer; }
.star-rating-star:focus-visible { outline: 2px solid var(--accent, #a74434); outline-offset: 2px; border-radius: 4px; }
@media (max-width: 480px) {
  .auth-panel-drawer {
    width: 100vw;
    padding: 20px 18px;
  }
  .reader-rating { align-items: flex-start; }
  .reader-rating form { width: 100%; margin-left: 0; }
  .reader-rating form { width: 100%; margin-left: 0; justify-content: space-between; }
  .star-rating-label { text-align: left; }
  .book-summary { grid-template-columns: 1fr !important; gap: 18px; padding: 18px; }
  .book-summary-cover-wrap { width: min(180px, 55vw); margin: 0 auto; }
  .book-summary-copy h1 { font-size: clamp(1.55rem, 7vw, 2.1rem); line-height: 1.08; }
}

@media (max-width: 700px) {
  .top .wrap.nav {
    display: flex;
    flex-wrap: nowrap !important;
    min-height: 54px;
  }
  .nav .site-search {
    display: none !important;
  }
  .mobile-search-toggle {
    display: grid !important;
  }
  .nav .site-search.is-mobile-open {
    position: absolute;
    z-index: 120;
    inset: 0;
    display: flex !important;
    width: 100%;
    max-width: none;
    min-width: 0;
    height: 54px;
    gap: 0;
    padding: 5px 7px;
    margin: 0;
    border: 0;
    border-radius: 0;
    background: #fffaf3;
    box-shadow: 0 5px 16px rgba(55, 37, 24, 0.08);
  }
  .nav .site-search.is-mobile-open input {
    flex: 1 1 0;
    width: 0;
    height: 44px;
    padding: 0 14px;
    border: 1px solid #dfd2c5;
    border-right: 0;
    border-radius: 13px 0 0 13px;
    background: #fff;
    box-shadow: none !important;
    font-size: 16px;
    outline: none;
  }
  .nav .site-search.is-mobile-open .header-filters-button,
  .nav .site-search.is-mobile-open .site-search-submit,
  .nav .site-search.is-mobile-open .mobile-search-close {
    flex: 0 0 42px;
    width: 42px;
    min-width: 42px;
    height: 44px;
    padding: 0;
  }
  .nav .site-search.is-mobile-open .header-filters-button {
    border: 1px solid #dfd2c5;
    border-left: 1px solid #eadfd4;
    border-radius: 0;
    background: #fff;
    color: #69594c;
  }
  .nav .site-search.is-mobile-open .site-search-submit {
    margin: 0;
    border: 0;
    border-radius: 0 13px 13px 0;
    background: #ad4937;
    color: #fff;
  }
  .nav .site-search .mobile-search-close {
    display: none;
  }
  .nav .site-search.is-mobile-open .mobile-search-close {
    display: grid !important;
    place-items: center;
    flex-basis: 38px;
    width: 38px;
    min-width: 38px;
    margin-left: 6px;
    border: 1px solid #e3d7ca;
    border-radius: 11px;
    background: #f4ede5 !important;
    color: #594c43;
    font-size: 1.25rem;
    font-weight: 700;
  }
}

.offer-list-modern {
  border: 1px solid #eadfd4;
  border-radius: 16px;
  background: #fffdf9;
  box-shadow: 0 8px 24px rgba(67, 45, 28, 0.04);
}
.offer-row-modern {
  gap: 20px;
  padding: 16px 18px;
  transition: background-color 0.16s ease;
}
.offer-row-modern:hover {
  background: #fff8ef;
}
.offer-shop {
  gap: 7px;
}
.offer-shop-name strong {
  font-size: 0.92rem;
}
.offer-price-main {
  font-size: 1.28rem;
  letter-spacing: -0.02em;
}
.offer-programs-modern {
  gap: 6px;
}
.offer-programs-modern .badge {
  border: 1px solid rgba(61, 112, 72, 0.12);
}
.offer-actions {
  gap: 7px;
}
.offer-actions .store-link {
  min-height: 40px;
}
@media (min-width: 901px) {
  .offer-row-modern .offer-actions {
    min-width: 354px;
    justify-content: flex-end;
  }
}
/* The offer row had a second <=650px block here, written before availability
   became its own cell. It styled .stock-pill, which no offer row has rendered
   since, and placed cells with .offer-row-modern > div:nth-child(2) - a
   selector one specificity point above the class-based rules below, so it won
   arguments it was no longer qualified to have. Deleted rather than patched. */

/* ============================================================
   Offer row v2: availability is its own cell (.offer-avail = dot + text).
   Desktop: shop | price | programs | actions, with availability under the
   shop name. Mobile: shop|price on top, programmes full-width, then
   availability (bottom-left) beside the action buttons (bottom-right).
   Authoritative - appended last so it wins over earlier offer rules.
   ============================================================ */
.offer-avail {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.74rem;
  font-weight: 700;
  color: #4c8c55;
  white-space: nowrap;
}
.offer-avail .offer-avail-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #2e7a4d;
  flex: none;
}
.offer-avail.out { color: #a65b51; }
.offer-avail.out .offer-avail-dot { background: #b23b30; }
.offer-avail.avail-preorder .offer-avail-dot,
.offer-avail.avail-expected .offer-avail-dot { background: #c8871a; }
.offer-avail.avail-preorder, .offer-avail.avail-expected { color: #8a6d2f; }

/* Full shop titles - never truncate. */
.offer-shop .offer-shop-name strong {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}

/* Top of the shop title and the top of the price always line up (even when a
   long shop name like "MEGOGO BOOKS" wraps to two lines). */
.offer-row-modern > .offer-shop { align-self: start; }
.offer-row-modern > .offer-price-cell { align-self: start; }

/* Desktop (>=651px): one row per offer.
   Availability used to be placed in grid row 2, under the shop name, which
   bought a whole second row for a 17px chip: rows measured 123px tall to hold
   51px of content, and the rest was the empty half of that second row beside
   it. It gets its own column on the same line instead - there was horizontal
   room going spare, the programmes column alone was 432px and often empty. */
@media (min-width: 651px) {
  .offer-row-modern {
    /* Every column a row does not control the width of is a fixed track, so
       the same thing sits at the same x in every offer. They were content-
       sized before: "Немає в наявності" is 40px wider than "В наявності", and
       that one row's wider availability column pushed its price and badges
       left of everyone else's.
       The badge column takes the slack instead - it is the one whose content
       genuinely varies, and it is where extra room is useful rather than
       merely empty. */
    grid-template-columns:
      260px            /* shop         */
      150px            /* price        */
      150px            /* availability */
      minmax(0, 1fr)   /* programmes - absorbs the slack */
      auto;            /* actions      */
    align-items: center;
    gap: 10px 16px;
    padding: 12px 18px;
  }
  .offer-row-modern > .offer-shop { grid-column: 1; grid-row: 1; align-self: center; }
  .offer-row-modern > .offer-price-cell { grid-column: 2; grid-row: 1; align-self: center; }
  .offer-row-modern > .offer-avail {
    grid-column: 3;
    grid-row: 1;
    align-self: center;
    justify-self: start;
    margin-top: 0;
  }
  .offer-row-modern > .offer-programs-modern {
    grid-column: 4;
    grid-row: 1;
    align-self: center;
    justify-self: start;
  }
  .offer-row-modern > .offer-actions { grid-column: 5; grid-row: 1; align-self: center; }
}


/* Mobile (<=650px): one text column, one action block.
   Chosen from design/mobile-offer-row-variations.html (variation 9).

   Everything readable stacks down a single left column, so the row scans like
   a short paragraph instead of a four-quadrant grid; both actions become one
   52px-wide segmented control pinned to the right and centred against the
   whole row, so the buttons sit at the same x on every offer no matter how
   tall that offer's text ran.

   .offer-price-cell becomes display:contents so its three children - the
   price, the shop's promo codes, and the "перевірено N тому" line - can be
   placed individually. Otherwise the freshness note is trapped under the
   price, and the price line ends up carrying two different kinds of
   information at two different weights. */
@media (max-width: 650px) {
  .offer-row-modern {
    display: grid;
    /* col 1 sizes to the widest of the price and "Немає в наявності";
       col 2 takes the rest for the promo codes and the freshness note. */
    grid-template-columns: auto minmax(0, 1fr) 52px;
    /* Declared, not left implicit, so the action block's `grid-row: 1 / -1`
       has a last line to reach: -1 counts back through the EXPLICIT grid
       only, and against an implicit one it collapses to `1 / 1` - which
       forced a 78px control into the 21px shop row and made every card
       50px taller than it needed to be. */
    grid-template-rows: auto auto auto auto;
    column-gap: 10px;
    row-gap: 4px;
    padding: 11px 12px;
    align-items: center;
  }
  .offer-row-modern > .offer-shop {
    grid-column: 1 / 3;
    grid-row: 1;
    flex-direction: row;
    align-items: center;
    gap: 7px;
    min-width: 0;
  }
  .offer-row-modern > .offer-price-cell { display: contents; }
  /* Both of them: only one is ever visible (the promo/base pair, see
     .is-hiding-promo), and whichever it is belongs in the same cell. */
  .offer-row-modern .offer-price-main {
    grid-column: 1;
    grid-row: 2;
    font-size: 1.2rem;
  }
  .offer-row-modern .offer-promo-codes {
    grid-column: 2;
    grid-row: 2;
    justify-self: start;
    margin: 0;
  }
  .offer-row-modern > .offer-avail { grid-column: 1; grid-row: 3; justify-self: start; }
  .offer-row-modern .offer-updated {
    grid-column: 2;
    grid-row: 3;
    justify-self: start;
    margin: 0;
  }
  /* Nothing to show, nothing to reserve. The track is explicit, so hiding
     the badges alone would leave a 0-height row and its 4px gap behind -
     drop the track too. Three rows still reach the action block's `-1`. */
  .offer-row-modern > .offer-programs-modern:empty { display: none; }
  .offer-row-modern:has(> .offer-programs-modern:empty) {
    grid-template-rows: auto auto auto;
  }
  .offer-row-modern > .offer-programs-modern { grid-column: 1 / 3; grid-row: 4; }

  /* The segmented control. Cart on top, "перейти" below, one hairline
     between them, spanning every row of the card. */
  .offer-row-modern > .offer-actions {
    grid-column: 3;
    grid-row: 1 / -1;
    display: grid;
    grid-auto-rows: 38px;
    gap: 0;
    width: 52px;
    justify-self: end;
    align-self: center;
    overflow: hidden;
    border: 1px solid #e2d7c9;
    border-radius: 12px;
    background: #fffdf9;
  }
  /* An offer with no cart button (out of stock, or no price to add) is a
     single 44px target rather than a half-empty 76px block. */
  .offer-row-modern > .offer-actions:not(:has(form)) { grid-auto-rows: 44px; }
  .offer-row-modern > .offer-actions > form { display: grid; margin: 0 }
  .offer-row-modern .offer-actions .offer-cart-button,
  .offer-row-modern .offer-actions .edition-cart-button,
  .offer-row-modern .offer-actions .store-link {
    width: 100%;
    height: 100%;
    min-width: 0;
    min-height: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  .offer-row-modern .offer-actions .offer-cart-button,
  .offer-row-modern .offer-actions .edition-cart-button {
    border-bottom: 1px solid #e2d7c9;
    background: #e7f1e9;
    color: #176d4f;
  }
  .offer-row-modern .offer-actions .store-link {
    background: transparent;
    color: #413a35;
    font-size: 1.05rem;
  }
}

/* While scrolling, don't let cards react to the (stationary) cursor passing
   under them - the hover lift + shadow repaint every frame caused desktop-only
   scroll stutter. Re-enabled the moment scrolling stops. */
body.is-scrolling .unified-book-card {
  pointer-events: none;
}
body.is-scrolling .unified-book-card:hover {
  transform: none;
  box-shadow: 0 5px 13px rgba(52, 36, 21, 0.07);
}
