/*! ebooknetworking.net head bundle (tail) — built by tools/enw_css_bundle.php. Do not edit: edit the sources below, then rebuild. */

/*! assets/css/enw-contrast.css · adc26a65aa95 · 8092 B · legibility pass: must outrank every page sheet */
/*!
 * enw-contrast.css — legibility pass: light text on dark, no blurred text.
 *
 * Loaded LAST, site-wide (from h2.php, after enw-legacy.css and after any
 * page-scoped sheet). Three rules, each measured before it was written.
 *
 * WHY IT EXISTS
 *
 * The palettes define an "on-*" token for each fill: --enw-primary pairs with
 * --enw-on-primary, --enw-accent with --enw-on-accent, and so on. Those pairs
 * are contrast-correct — tools/enw_contrast.php guards them, and they pass.
 *
 * The defect is that many components paint TEXT with the wrong half of that
 * pair: a near-black ink (--enw-on-accent / --enw-on-primary = #10131A in most
 * palettes, and again in every dark theme) laid over a surface that is not the
 * one that token was tuned for — a --enw-header band, a hard-coded #000 social
 * button, or a mid-tone fill. Measured on the live pages:
 *
 *   .bd-social-btn--twitter   #10131A on #000000   → 1.0:1   (invisible)
 *   .btn-primary hero button  #10131A on the dark hero gradient → 4.32:1
 *   footer fine print         #FFFFFF at 72% alpha on #BE123C  → 3.79:1
 *   "View all" on a dark band #BE123C on #1D0707               → 3.08:1
 *
 * And .stat-num paints its numbers with `background-clip: text` and
 * `-webkit-text-fill-color: transparent` — gradient-clipped text, which is why
 * those figures read as soft-edged rather than crisp.
 *
 * WHAT IT DOES NOT DO: it never changes a pairing that is already correct, and
 * it never introduces a sub-4.5:1 combination. Where white text cannot clear
 * 4.5:1 on a mid-tone fill, the FILL is deepened (rule 2) rather than the text
 * lightened — a dark button with white text, which is the requested look.
 */

/* ── 1. Text on a dark surface is light, never the palette's dark ink ────── */

/* Bands painted with --enw-header (near-black in every palette). These used
   --enw-on-primary, which is #10131A in dark themes.

   `.pdf-hero` IS NOT IN THIS GROUP, and that is the whole point of this note.
   enw-legacy.css §4.1 flattens the five legacy page heads — `.page-header`,
   `.hero`, `.pdf-hero`, `.page-hero`, `.mini-hero` — onto the PAGE BACKGROUND
   (`background: var(--enw-bg)`) and gives their text `var(--enw-text)`. So the
   hero is not a dark band any more: its surface follows the page, and the ink
   that follows the page is the right ink for it.

   Listing it here painted `--enw-on-header` — #FFFFFF in every light palette —
   onto #F4F6FA. Measured on the live home page: "Search Free" 1.08:1 and
   "Instantly search 82,000+ free PDF documents" 1.07:1, both invisible. The rule
   was correct when the hero still had its own dark gradient; the bridge removed
   that gradient and this sheet was never told. Where a band genuinely is still a
   dark fill — `.feature-banner`'s red gradient, the section heads below — the
   on-header ink stays. */
.page-title,
.feature-banner h2,
.feature-banner h2 em,
.books-section-heading h2,
.pdf-section-heading h2,
.cross-cta h3,
.bd-related-header h2,
.bd-float-arrow-title,
.bd-cover-overlay {
  color: var(--enw-on-header, #ffffff);
}

/* Secondary lines over the same bands: --enw-text-muted is a dark grey in the
   light palette and all but disappeared on the dark band.

   `.pdf-hero p` is excluded for the reason above — and it caught both the
   subtitle and `.pdf-hero-hint`, which is a <p> in that band. They take the
   muted page ink §4.1 gives them. */
.page-subtitle,
.feature-banner p,
.footer-desc,
.footer-col a,
.footer-col h4,
.footer-links a,
.footer-links-heading,
.bd-footer-links a,
.footer-contact,
.bd-footer-contact,
.footer-contact strong,
.bd-footer-contact strong {
  color: color-mix(in oklab, var(--enw-on-header, #ffffff) 84%, transparent);
}

/* The footer's fine print was #FFFFFF at 72% alpha — 3.79:1 on a #BE123C band. */
.footer-bottom,
.bd-footer-bottom,
.footer-bottom strong,
.bd-footer-bottom strong {
  color: var(--enw-on-header, #ffffff);
}

/* Social buttons carry hard-coded dark brands (#000, #1877F2, #0A66C2) but took
   their colour from --enw-on-primary, which is near-black in a dark theme. */
.bd-social-btn,
.bd-social-btn--twitter,
.bd-social-btn--fb,
.bd-social-btn--li,
.footer-social a {
  color: #ffffff;
}

/* ── 2. Coloured action surfaces: white label, and deep enough to carry it ─ */

/* --enw-accent is a mid-tone (e.g. #16A394), where white is only 3.1:1. The
   label goes white and the fill is darkened toward black until white clears
   WCAG AA (measured 6.8-7.5:1 across the nine palettes). */
.book-card-btn,
.book-btn,
.btn-primary,
.btn-try,
.contact-form button,
.nav-mobile-search button,
.pdf-search-form button,
.mini-search button,
.cross-cta-form button,
.enw-drawer__count {
  /* !important because the hero button is `a.btn-primary.enw-magnetic` and a
     more specific companion rule re-set its colour; the label must stay light. */
  color: #ffffff !important;
  background-color: color-mix(in oklab, var(--enw-accent, #16a394) 55%, #000000);
}

/* Same treatment for the danger-backed actions. */
.pdf-open-btn,
.book-card-new-badge,
.bd-book-card-btn {
  color: #ffffff;
  background-color: color-mix(in oklab, var(--enw-danger, #e0463e) 55%, #000000);
}

/* The rank badge is a gradient of two mid-tones; make it one deep fill so the
   white label is guaranteed. */
.rank-badge {
  color: #ffffff;
  background: color-mix(in oklab, var(--enw-accent, #d4a017) 52%, #000000);
}

/* A section's "view all" link inherits the band behind it. On a dark band its
   rose ink was 3.08:1, so in a dark theme it takes the band's own light ink. */
/* !important because these links are otherwise beaten by a more specific rule,
   measured: "View all →" #1F52C4 on #0E1116 (2.5:1) and the breadcrumb "Home"
   3.55:1 in the dark theme. Only dark states are targeted, so light is untouched. */
[data-enw-theme='dark'] .section-hd a,
[data-enw-theme='dark'] .bd-breadcrumb a,
[data-enw-theme='dark'] .breadcrumb a {
  color: var(--enw-on-header, #ffffff) !important;
}

@media (prefers-color-scheme: dark) {
  html:not([data-enw-theme='light']) .section-hd a,
  html:not([data-enw-theme='light']) .bd-breadcrumb a,
  html:not([data-enw-theme='light']) .breadcrumb a {
    color: var(--enw-on-header, #ffffff) !important;
  }
}

/* The "search more" CTA band paints a gradient of --enw-accent → --enw-accent-ink
   and puts --enw-text on it. That is right when the accent is a light gold, but
   the live palette's accent is a deep red, where the dark ink measures 2.27:1.
   It takes the same treatment as the buttons: white on a deepened accent fill,
   which holds in every palette. */
.search-section {
  background: color-mix(in oklab, var(--enw-accent, #d4a017) 52%, #000000);
}

.search-section h2,
.search-section p,
.search-section a {
  color: #ffffff;
}

/* A ghost button is transparent, so it reads on whatever band it sits in. In a
   dark theme that band is dark while the promo page's text token stayed dark
   (#2E1A1A on #321111 — 1.04:1, effectively invisible). */
[data-enw-theme='dark'] .enw-btn--ghost {
  color: var(--enw-on-header, #ffffff);
}

@media (prefers-color-scheme: dark) {
  html:not([data-enw-theme='light']) .enw-btn--ghost {
    color: var(--enw-on-header, #ffffff);
  }
}

/* ── 3. No blurred text: no shadows, and no gradient-clipped fills ───────── */

/* A text-shadow is what makes glyph edges look soft; there are none in the
   design system, and this keeps it that way. */
*,
*::before,
*::after {
  text-shadow: none;
}

/* Gradient text is painted with a transparent fill and `background-clip: text`.
   The fill goes back to the element's own ink, which is both crisp and themed. */
.stat-num,
.stat-item:nth-child(2) .stat-num,
.stat-item:nth-child(3) .stat-num,
.stat-item:nth-child(4) .stat-num,
.stat-item:nth-child(5) .stat-num,
.stat-num.blue {
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  -webkit-text-fill-color: currentColor;
  color: var(--enw-accent-ink, #117a6f);
}

/*! assets/css/enw-consent.css · 88f8606a0619 · 3318 B · the cookie banner, on every page that includes h2.php */
/*
 * enw-consent.css — the cookie banner.
 *
 * Self-contained on purpose. It reads the design system's tokens where they
 * exist (so the banner follows the reader's palette) but every one carries a
 * fallback, because this stylesheet also has to render correctly on the legacy
 * pages that never load enw.css — and a banner styled by nothing is an unstyled
 * div pinned over the page.
 *
 * The one rule that must never be dropped is `.enw-consent[hidden]`: the banner
 * is hidden with the HTML attribute, and a `display` declared below would win
 * over the attribute's own `display:none` without it.
 */

.enw-consent {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 2147483000; /* above the mobile tab bar and every modal the site ships */
  padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
  background: var(--enw-surface, #fff);
  color: var(--enw-text, #14161a);
  border-top: 1px solid var(--enw-border, rgba(0, 0, 0, 0.12));
  box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.12);
  font: 400 0.9375rem/1.5 Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

.enw-consent[hidden] {
  display: none;
}

.enw-consent__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1rem;
  max-width: 72rem;
  margin: 0 auto;
}

.enw-consent__text {
  flex: 1 1 22rem;
  margin: 0;
  min-width: 0;
}

.enw-consent__text a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.enw-consent__actions {
  display: flex;
  flex-shrink: 0;
  gap: 0.5rem;
  margin-left: auto;
}

.enw-consent__btn {
  appearance: none;
  border: 1px solid var(--enw-border, rgba(0, 0, 0, 0.18));
  border-radius: 0.5rem;
  padding: 0.5rem 1rem;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  background: transparent;
  color: inherit;
  white-space: nowrap;
}

.enw-consent__btn:focus-visible {
  outline: 2px solid var(--enw-accent, #2563eb);
  outline-offset: 2px;
}

.enw-consent__btn--primary {
  background: var(--enw-accent, #2563eb);
  border-color: var(--enw-accent, #2563eb);
  color: var(--enw-on-accent, #fff);
}

.enw-consent__btn--ghost:hover {
  background: var(--enw-surface-2, rgba(0, 0, 0, 0.04));
}

.enw-consent__btn--primary:hover {
  filter: brightness(1.06);
}

/*
 * The footer's "Cookie settings" control. It opens the banner the page already
 * holds, so it is a real <button> for the keyboard and the screen reader, styled
 * to read as an inline link. Lives in this sheet because this sheet is the one
 * the banner always brings with it.
 */
.enw-consent-open-link {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.enw-consent-open-link:focus-visible {
  outline: 2px solid var(--enw-accent, #2563eb);
  outline-offset: 2px;
}

@media (max-width: 34rem) {
  .enw-consent__actions {
    width: 100%;
    margin-left: 0;
  }

  .enw-consent__btn {
    flex: 1 1 0;
    text-align: center;
  }
}

@media (prefers-color-scheme: dark) {
  .enw-consent {
    background: var(--enw-surface, #14161a);
    color: var(--enw-text, #f2f3f5);
    border-top-color: var(--enw-border, rgba(255, 255, 255, 0.16));
    box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.5);
  }
}

/*! assets/css/enw-layout.css · 2fb62dd91935 · 5619 B · desktop width and vertical rhythm, printed last of all */
/* ===========================================================================
   enw-layout.css — desktop width and vertical rhythm.

   Why this file exists.

   Measured on a 1920px-wide desktop, the design system capped the page at
   1440px and the hero at 1200px. That leaves 236px of empty background on each
   side of the content and 360px each side of the hero, while .dual-hero,
   .stats-strip and .feature-banner were already full-bleed — so the page did
   not have one width, it had three. The site reads correctly at 150% zoom
   because that shrinks the CSS viewport to ~1280px, which is almost exactly
   the 1440px cap: the content then fills the window. At 100% the same content
   floats in the middle of a wide screen.

   The second measurement: two adjacent `.section` blocks left 64px of bottom
   padding + 40px of collapsed margin + 64px of top padding between their
   content — 168px of empty space, repeated down a homepage of eleven sections.
   At 150% zoom that reads as generous; at 100% it reads as broken.

   So: one width for every capped container, and a vertical rhythm that is
   roughly half the old one. Both are scoped to `min-width: 1100px`, so tablets,
   phones and the mobile tab bar are untouched — this is a desktop correction,
   not a global restyle.

   The `min(100% - 48px, …)` form keeps a 24px gutter per side on a narrower
   desktop and stops growing at 1800px, so an ultra-wide monitor does not
   produce 300-character lines.
   =========================================================================== */

@media (min-width: 1100px) {
  /* THE TOKEN FIRST, because the token is where most of the width lives.

     `--enw-container: 1440px` is declared in enw.css and consumed by
     `.enw-container`, `.container`, `.main-container`, `.section-inner` and
     `.wrap` across three sheets. Overriding the token here widens all of them
     at once, and — the reason it is worth doing rather than listing classes
     again — it widens containers in sheets this file has never read. The
     earlier version of this file listed classes and missed two page families
     entirely: the `/ebooks/<slug>.html` results pages, which cap at 960px, and
     the `.wrap` two-column layout, which caps at 1100px. Both were reported
     from the live site as "still not full page".

     `--enw-container-narrow` (760px) is deliberately NOT overridden: it is the
     measure for prose — `.enw-container--narrow` and `.hero-sub` — and a 1800px
     line of body text is unreadable. */
  :root {
    --enw-container: min(100% - 48px, 1800px);
  }

  /* One width, listed explicitly as well as via the token. Everything here is
     a page-level or band-level wrapper; the ones that do not read the token
     carry a literal cap in the legacy sheet (960px and 1100px were the two
     narrowest), and they are the ones that produced the reported pages. */
  .section-inner,
  .enw-container,
  .container,
  .main-container,
  .main-wrap,
  .wrap,
  .page-header-inner,
  .breadcrumb-inner,
  .results-strip-inner,
  .main-nav,
  .footer-inner,
  .enw-banner,
  .bd-container,
  .bd-footer-inner {
    max-width: min(100% - 48px, 1800px);
    max-inline-size: min(100% - 48px, 1800px);
  }

  /* Vertical rhythm. 36px top and bottom, with the old 32/40px margins removed
     entirely: margins between adjacent sections collapse to the larger of the
     two anyway, so they were only ever adding space on the outside edges.
     Gap between two sections goes from 168px to 72px. */
  .section,
  .section.alt {
    padding-block: 36px;
    margin-block: 0;
  }

  /* The hero was built for a 1200px band, where a 1.15fr / .85fr split put the
     cover near the right edge. At 1800px that half-and-half split becomes a
     726px column holding a 150px cover, which centres the cover in a void and
     leaves ~324px of empty red to the right of it. An `auto` second column
     lets the cover sit against the right padding instead, and the text column
     takes the rest.

     The selector is copied from enw.css rather than written as
     `.enw-banner__slide`, because the source rule carries a :not() and so is
     one class more specific — a plain class here would lose the cascade even
     though this file loads later. Same specificity + later load = it wins, and
     no !important is needed. */
  .enw-banner__slide:not(.enw-banner__slide--notext) {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  /* The book page's buy row is two buttons side by side — a primary and a
     "Used" alternative. In a 1200px container the primary is ~570px, which is
     a button. In the 1800px container below it grew to 1167px, which is a
     banner: it dominates a page whose point is the book, not the button. The
     row is capped instead of the container, so the page stays wide while the
     two buttons keep the weight they were designed with. */
  .bd-buy-btns {
    max-width: 720px;
  }

  /* The feature banner is a band of its own, not a section: it keeps a little
     more air than a section but loses the 48px it had. */
  .feature-banner {
    padding-block: 32px;
  }

  /* Footer. 80px of margin plus 64px of padding was the largest gap on the
     page — a full screen of scrolling on a laptop to reach one line of text. */
  footer {
    margin-top: 40px;
    padding-top: 48px;
  }

  /* Section headings sat 16px above their grid; on the wider column that reads
     as detached, so the heading keeps a little more air than the old value
     rather than less. */
  .section-hd {
    margin-bottom: 20px;
  }
}
