/*
 * BDeBooks additions on top of bde-v3.css (the handoff's stylesheet, byte for byte).
 * Only what the handoff has no rule for, or where one of our rules must win. Each block
 * says why. Values reuse the handoff's tokens.
 */

/* Bengali is set in the f3 interface stack (Hind Siliguri for Bengali letters), and its conjuncts
   need more line height than Latin. */
html.bn body { font-family: var(--f2-ui, 'Hind Siliguri', ui-sans-serif, system-ui, sans-serif); }
html.bn .book-title, html.bn .h1, html.bn .h2, html.bn .h3, html.bn h1, html.bn h2, html.bn h3 { line-height: 1.35; letter-spacing: 0; }
html.bn .book-title { padding-bottom: 1px; }
/* r5-9 (23, 24): a Bengali card title measured 20px of glyphs in an 18px line, so vowel signs
   below the line could be cut, and the 11px author line was hard to read. */
html.bn .book-title { line-height: 1.6; padding-bottom: 0; }
html.bn .book-author { font-size: 12px; line-height: 1.5; }

/* The footer's column titles are h2 (a real outline), drawn as the handoff's h4. */
.site-footer .footer-heading { margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .9px; text-transform: uppercase; color: #fff; }
.footer-langs { padding-bottom: 26px; }
.site-footer .footer-langs ul { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: row; flex-wrap: wrap; gap: 10px 22px; }
.footer-langs span { margin-left: 4px; font-size: 11px; color: #8196B6; }

/* A cover the library does not hold, or one that failed to load: a drawn mark on the
   cover's own ground, never a broken image and never the title typed into a box. */
.cover-mark { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: #EEF2F8; color: #9FB0C9; }
.cover-mark[hidden] { display: none; }
.cover-mark svg { width: 36%; height: auto; }

/* The whole card is not a second link; its cover repeats the title's link, hidden from
   the keyboard and screen readers, so the card still opens on a tap anywhere on the art. */


/* Section heads used across the pages. */
.section { margin-top: 34px; }
.section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.section-head p { margin: 6px 0 0; font-size: 12.5px; color: var(--muted); }
.section-link { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; font-size: 12.5px; font-weight: 600; white-space: nowrap; }

/* Subject tiles under the hero (handoff home, "category tiles"). */
.cat-tiles { margin-top: 22px; display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 12px; }
.cat-tile { display: flex; flex-direction: column; align-items: center; gap: 7px; padding: 16px 8px 14px; border-radius: 13px; border: 1px solid var(--border); background: #fff; color: var(--sub); font-size: 12px; font-weight: 600; text-align: center; min-width: 0; }
.cat-tile:hover { border-color: #CFE0FA; color: var(--ink); }
.cat-tile__name { max-width: 100%; overflow-wrap: anywhere; line-height: 1.3; }
.cat-tile__n { font-size: 10.5px; font-weight: 600; color: var(--muted); }
.cat-tile__icon { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; color: var(--blue); }
.cat-tile__icon[data-hue="teal"] { color: #0E8A7A; } .cat-tile__icon[data-hue="magenta"] { color: #C23A7E; }
.cat-tile__icon[data-hue="gold"] { color: #B37700; } .cat-tile__icon[data-hue="green"] { color: #2F8A3C; }
.cat-tile__icon[data-hue="plum"] { color: #7B45C9; } .cat-tile__icon[data-hue="red"] { color: #D0405A; }
.cat-tile__icon[data-hue="ember"] { color: #D0621E; } .cat-tile__icon[data-hue="navy"] { color: #1466D6; }
.cat-tile__icon[data-hue="more"] { color: var(--sub); }

/* Live numbers strip (handoff "stats"). */
.stats-grid { margin-top: 26px; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-radius: 14px; background: #FBFCFE; }
.stats-grid > div { display: flex; align-items: center; gap: 12px; padding: 16px 20px; border-right: 1px solid var(--line); min-width: 0; }
.stats-grid > div:last-child { border-right: 0; }
.stats-grid .stat-icon { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 9px; display: flex; align-items: center; justify-content: center; }
.stats-grid .stat-n { font-size: 19px; font-weight: 800; letter-spacing: -.6px; }
.stats-grid .stat-l { margin-top: 2px; font-size: 11px; color: var(--muted); }
@media (max-width: 980px) { .stats-grid > div:nth-child(2) { border-right: 0; } .stats-grid > div:nth-child(-n+2) { border-bottom: 1px solid var(--line); } }

/* The two soft panels between the first shelf and the rest (handoff design, Home Page). */
.promos { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 14px; }
.promo { position: relative; overflow: hidden; min-height: 186px; padding: 26px 28px; border-radius: 16px; }
.promo h2 { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -.4px; max-width: 300px; }
.promo p { margin: 10px 0 0; max-width: 300px; font-size: 12px; line-height: 1.6; color: var(--body); }
.promo .btn { margin-top: 16px; position: relative; z-index: 1; }
.promo img { position: absolute; right: 0; bottom: 0; height: 100%; width: auto; max-width: 58%; object-fit: cover; object-position: left center; pointer-events: none; }
.promo--listen { background: linear-gradient(115deg, #E6F7F7 0%, #EAF5FB 100%); }
.promo--discover { background: linear-gradient(115deg, #F4EFFB 0%, #F8F2FB 100%); }
.btn-dark { background: #0F2444; border-color: #0F2444; color: #fff; }
.btn-dark:hover { background: #1A3560; color: #fff; }
@media (max-width: 760px) { .promos { grid-template-columns: minmax(0, 1fr); } .promo img { opacity: .35; } }

/* Author chips (handoff "Top Authors"). */
.people { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.person { display: flex; align-items: center; gap: 10px; min-height: 56px; padding: 10px; border-radius: 10px; background: var(--soft); color: var(--ink); }
.person:hover { background: #F1F6FD; color: var(--ink); }
.person .avatar { width: 36px; height: 36px; font-size: 12px; background: #fff; border: 1px solid var(--field); flex: 0 0 auto; }
.person b { display: block; font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.person span.muted { font-size: 10.5px; }

/* Link chips for the ways to browse. */
.link-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.link-chips a { min-height: 34px; color: var(--ink); }
.link-chips a .muted { margin-left: 8px; font-size: 10.5px; }

/* Audiobook cards (handoff "Popular Audiobooks"): the cover with a play mark. */
.audio-card { display: flex; flex-direction: column; min-width: 0; color: var(--ink); }
.audio-card .cover { border-radius: 10px; }
.audio-card .play-mark { position: absolute; right: 8px; bottom: 8px; width: 30px; height: 30px; border-radius: 50%; background: var(--audio); display: flex; align-items: center; justify-content: center; box-shadow: 0 6px 14px rgba(123, 69, 201, .35); }
.audio-card .t { margin-top: 9px; font-size: 12.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.audio-card .a { margin-top: 3px; font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.audio-card .d { margin-top: 5px; display: flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; color: var(--audio); }

/* The ad slot keeps its own box so the page never jumps when it fills. */
.ad-slot { margin: 30px auto 0; }

/* Phone: the tab bar's targets are at least 44px, and the header's search icon hides
   behind the tab bar's own Search. */
@media (max-width: 560px) {
  .tabbar a { min-height: 44px; }
  .stats-grid > div { padding: 14px; }
  .promo { padding: 22px 20px; }
}

/* Advertising slot (partials/ad). Its own box, labelled, never inside a download or read
   section, and its height reserved so the page does not jump when it fills. */
.ad { margin-top: 30px; border-radius: 14px; background: var(--soft); border: 1px solid var(--line); padding: 14px 18px; }
.ad__label { display: block; font-size: 10px; font-weight: 700; letter-spacing: .8px; color: var(--muted); }
.ad__slot { margin-top: 8px; min-height: 90px; display: flex; align-items: center; justify-content: center; }
.ad__slot--box { min-height: 250px; }
@media print { .tabbar, .ad, .site-header .nav, .site-footer, .mobile-menu { display: none; } }

/* Visually hidden, still read by screen readers. */
.u-sr { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* The hero's plain facts (handoff trust row), each with a check mark. */
.hero-facts { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px 18px; }
.hero-facts li { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 500; color: var(--sub); }
.hero-facts li::before { content: ""; width: 13px; height: 13px; flex: 0 0 auto; border-radius: 50%; border: 1.6px solid #0E8A5F;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230E8A5F' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 12 4 4 8-8'/%3E%3C/svg%3E") center / 9px no-repeat; }

/* The single-column children may shrink below their content (the handoff's r2 sets the
   track to minmax(0, 1fr); a child with a wide image still needs min-width: 0). */
@media (max-width: 980px) {
  .two-col > *, .book-hero > * { min-width: 0; }
}

/* The promo panels: words above the art, the art kept to the right. */
.promo > :not(img) { position: relative; z-index: 1; }
.promo img { max-width: 46%; }

/* Phone home, as designs/Mobile Home draws it: heading, search, tiles, then the books.
   The art, the longer lede, the facts row and the numbers strip wait for a wider screen. */
@media (max-width: 560px) {
  .hero-art, .hero-lede, .hero-facts, .home-stats { display: none !important; }
  .hero-title { font-size: 30px !important; letter-spacing: -1px !important; }
  .cat-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
  .grid-books .tags { display: none; }
}

/* Header search: the magnifier is its submit button. */
.searchbox-go { display: flex; align-items: center; justify-content: center; width: 22px; height: 22px; margin-left: -4px; padding: 0; border: 0; background: transparent; cursor: pointer; border-radius: 6px; }
/* Menu search: the field and its button on one row, both 44px tall. */
.menu-search { display: flex; gap: 8px; }
.menu-search .input { height: 44px; }
.menu-search .btn-icon { width: 44px; height: 44px; flex: 0 0 auto; }

/* One link per card: the title's, stretched over the whole card, with the actions above it. */
.book-card { position: relative; }
.book-card .book-card__link::after { content: ""; position: absolute; inset: 0; border-radius: 12px; }
.book-card .book-card__link:focus-visible { outline: none; }
.book-card .book-card__link:focus-visible::after { outline: 2px solid var(--blue); outline-offset: 2px; }
.book-card .book-actions { position: relative; z-index: 1; }
.book-card:hover { border-color: #D4E3F7; }

/* Shared states (designs/44 Interaction States): one look for every form and notice. */
.input.is-invalid, .textarea.is-invalid, .input[aria-invalid="true"], .textarea[aria-invalid="true"] { border-color: #E78A9A; background: #FFF8F9; }
.field-label { display: block; margin-bottom: 6px; font-size: 11.5px; font-weight: 700; color: var(--sub); }
.notice { padding: 14px 16px; border-radius: 12px; border: 1px solid transparent; font-size: 13px; line-height: 1.55; }
.notice-success { background: #E8F8F1; border-color: #CBEFDF; color: #0B6E4B; }
.notice-error { background: #FDECEE; border-color: #F7D3D9; color: #B02A42; }
.notice-info { background: #F1F6FD; border-color: #D6E6FB; color: #1A4E9A; }
.skeleton { background: #EEF2F7; border-radius: 8px; }
@media (prefers-reduced-motion: no-preference) {
  .skeleton { background: linear-gradient(90deg, #EEF2F7 0%, #F6F8FB 50%, #EEF2F7 100%); background-size: 200% 100%; animation: bde-skeleton 1.4s ease-in-out infinite; }
  @keyframes bde-skeleton { from { background-position: 100% 0; } to { background-position: -100% 0; } }
}

/* The footer has as many link columns as the page has (the root has two, a catalogue four),
   so the grid follows that count on wide screens instead of leaving empty columns. */
@media (min-width: 981px) {
  .site-footer .cols { grid-template-columns: minmax(0, 1.5fr) repeat(var(--foot-cols, 4), minmax(0, 1fr)); }
}

/* Bengali headings: the handoff's negative tracking (set inline on the hero) pinches the
   conjuncts together, so /bn/ keeps normal tracking on every heading. */
html.bn .hero-title, html.bn .h1, html.bn .h2, html.bn .h3, html.bn h1, html.bn h2, html.bn h3 { letter-spacing: 0 !important; }

/* Tap targets (WCAG 2.5.8, owner 44px rule on phones): the logo link is as tall as the
   header row, and a card's icon button never shrinks below its own width at 320px. */
.site-header .brand { min-height: 44px; }
.book-actions .btn-icon { flex: 0 0 auto; min-width: 30px; }

/* The brand is the current BDeBooks logo image (owner 2026-09-29, config/branding.php), not
   the handoff's icon plus text. Its width and height attributes give the box its ratio before
   the file arrives, so nothing moves; the handoff's img[width][height]{height:auto} (0,2,1)
   would make it 800px tall, hence the attribute selectors here. It never shrinks in the
   header row, and the link keeps the 44px tap height above. */
.brand img.brand__logo[width][height] { display: block; height: 28px; width: auto; max-width: none; flex: 0 0 auto; }
.site-header .brand, .menu-brand { flex: 0 0 auto; }
@media (max-width: 560px) {
  .brand img.brand__logo[width][height] { height: 24px; }
}
/* Owner rule: primary phone controls are at least 44 by 44 (the handoff draws 36). */
@media (max-width: 560px) {
  .book-actions .btn { height: 44px; }
  .book-actions .btn-primary { min-width: 0; padding: 0 8px; overflow: hidden; text-overflow: ellipsis; }
  .book-actions .btn-icon { width: 44px !important; min-width: 44px; }
}

/* The handoff r2 adds img[width][height]{height:auto} (0,2,1), which outranks its own
   .cover img{height:100%} (0,1,1): a cover with a recorded size would stop filling its
   2:3 box. Covers fill their box whatever attributes they carry. */
.cover img, .cover img[width][height] { width: 100%; height: 100%; object-fit: cover; }
.promo img[width][height] { height: 100%; width: auto; }

/* ===================================================== audit 2026-09-24 (foundation) */

/* A fallback with Inter's metrics, so the page does not jump when Inter arrives (book page
   CLS 0.29 measured: a breadcrumb that wrapped in Arial fitted on one line in Inter). */
@font-face { font-family: 'Inter Fallback'; src: local('Arial'); size-adjust: 107.06%; ascent-override: 90.49%; descent-override: 22.56%; line-gap-override: 0%; }
html, body { font-family: var(--f2-ui, 'Inter Fallback', ui-sans-serif, system-ui, sans-serif); }
html.bn body { font-family: var(--f2-ui, 'Hind Siliguri', ui-sans-serif, system-ui, sans-serif); }

/* Form fields: a boundary a reader can see (WCAG 1.4.11, 3:1; the handoff's #DCE5F2 is 1.27:1)
   and a focus ring, not only a 1px colour change. */
.input, .textarea, .select, .root-searchbar, .hero-search, .header-searchbox, .error-search input { border-color: #7D8FAD !important; }
.input:focus-visible, .textarea:focus-visible, .select:focus-visible { border-color: var(--blue) !important; box-shadow: 0 0 0 3px var(--blue-50); }
.hero-search:focus-within, .root-searchbar:focus-within { border-color: var(--blue) !important; box-shadow: 0 0 0 3px var(--blue-50); }

/* Contrast (AA 4.5:1): PDF tag text (4.47 -> 5.17), avatar initials, list counts, pager dots. */
.tag-pdf { color: #B8304A; }
.avatar { color: #0B55C2; }
.pill .ls-tabs__n { color: var(--muted); }
.pill.active .ls-tabs__n, .pill[aria-current] .ls-tabs__n { color: #fff; }
.ls-pager .disabled, .pagination .disabled { color: var(--muted); }

/* A card's format tags wrap rather than cut the last one off ("AUD"). */
.book-card .tags { flex-wrap: wrap; row-gap: 4px; }

/* Links inside running text are underlined, not told apart by colour alone (WCAG 1.4.1). */
label a, .prose a, p a:not(.btn) { text-decoration: underline; text-underline-offset: 2px; }

/* Phones: a focused control is never hidden under the tab bar (WCAG 2.4.11), the page keeps
   the tab bar's space only where there is a tab bar, and small links become 44px targets. */
@media (max-width: 560px) {
  html { scroll-padding-bottom: 78px; }
  body:not(:has(.tabbar)) { padding-bottom: 0; }
  .site-footer a { display: inline-flex; align-items: center; min-height: 44px; }
  .site-footer .cols ul { gap: 0; }
  .site-footer .brand { min-height: 44px; }
  .section-link { min-height: 44px; }
  .chip { min-height: 44px; }
  :is(.ls-crumbs, .bk-crumbs, .crumbs, .breadcrumb, nav[aria-label="Breadcrumb"]) a { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }
}
/* Publish page step numbers: #0F68E6 on #EAF2FF was 4.49:1. */
body .publish-steps .n { color: #0B55C2; }
/* The hero art sits in a <picture> so phones skip it; the image stays the grid item. */
.hero-art-pic { display: block; min-width: 0; justify-self: end; width: 100%; max-width: 480px; }
.hero-art-pic .hero-art { justify-self: auto; }
@media (max-width: 980px) { .hero-art-pic { justify-self: start; } }
@media (max-width: 560px) { .hero-art-pic { display: none; } }

/* r5-8 (phone footer): the eight policy links ran down one narrow column and made the footer
   about two screens tall. On a phone that column spans the footer and lists its links in two
   columns; every link keeps its 44px tap height. */
@media (max-width: 980px) {
  .site-footer .cols > div:last-child { grid-column: 1 / -1; }
  .site-footer .cols > div:last-child ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; }
}

/* r5 C6 (phones): small links and keys that were still 24 to 36px tall get an invisible
   44 by 44 hit area (RULES 7), so nothing moves or grows on screen. */
@media (max-width: 560px) {
  :is(.pagination a, .ls-pager a, .catalog-pagination a, .dir-page .az__key, .dir-page .dir-chip, .bk-legal a, .bk-more, .listen-back, .ls-searchbox__clear, .ls-filter__option) { position: relative; }
  :is(.pagination a, .ls-pager a, .catalog-pagination a, .dir-page .az__key, .dir-page .dir-chip, .bk-legal a, .bk-more, .listen-back, .ls-searchbox__clear, .ls-filter__option)::after { content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, 44px); height: max(100%, 44px); transform: translate(-50%, -50%); }
}

/* r5 C7 (Bengali): Anek Bangla draws smaller than Inter at the same size, so the smallest
   interface text was hard to read on /bn/. One step up; the author line is r5-9 above. */
html.bn .hero-facts li { font-size: 12.5px; }
html.bn .audio-card .a, html.bn .stats-grid .stat-l { font-size: 12px; }
html.bn .cat-tile__n { font-size: 11.5px; }
html.bn .section-head p { font-size: 13.5px; }

/* ===================================================== craft pass (2026-09-24)
   bdebooks/design/CRAFT-DIRECTION-2026-09-24.md. Shared foundation only; page-level changes
   live with their pages. */
:root { --serif: 'BDe Serif', 'BDe Serif Fallback', Georgia, 'Times New Roman', serif; }
/* Bengali headings take the f3 heading stack (Outfit, then Hind Siliguri for the Bengali letters),
   as every f3 heading on /bn/ does; Anek Bangla (156 KB) is no longer drawn (UI/UX review F2). */
:where(.serif, .book-title, .bk-title, .h1, .h2, h1, h2, h3):lang(bn) { font-family: var(--f2-display, 'Hind Siliguri', ui-sans-serif, system-ui, sans-serif); letter-spacing: 0; }
/* Format labels are neutral text; only audio keeps its purple (rule 6). */
.tag-pdf, .tag-epub, .tag-mobi, .tag-txt { background: #EEF2F8; color: var(--sub); }
