/* The palette lives in brand.css, which is loaded first and is the only
   stylesheet that differs between the affiliate sites. Do not add a literal
   colour below: add a token there and use it. */


*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 400 17px/1.68 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; }
a { color: var(--brand); text-decoration-color: color-mix(in srgb, var(--brand) 35%, transparent); text-underline-offset: 2px; }
a:hover { text-decoration-color: currentColor; }

h1, h2, h3, h4 { line-height: 1.18; letter-spacing: -.018em; margin: 0 0 .5em; font-weight: 750; }
h1 { font-size: clamp(2rem, 1.5rem + 2.2vw, 3rem); }
h2 { font-size: clamp(1.5rem, 1.25rem + 1.1vw, 2.05rem); margin-top: 2.2em; }
h3 { font-size: 1.35rem; margin-top: 1.8em; }
h4 { font-size: 1.1rem; }
p, ul, ol { margin: 0 0 1.15em; }

.wrap { width: min(100% - 2.5rem, var(--wrap)); margin-inline: auto; }

/* The reading column is 80% of the site width. The masthead and footer keep the
   full 1250px; everything inside <main> comes in to 1000px, so a heading, a
   table and a paragraph all end at the same place. */
main .wrap { width: min(100% - 2.5rem, var(--content)); }

/* Index pages go back out to the full width (Dean, 2026-09-05). A reading column
   is narrow because a long line of prose is hard to follow; a grid of products
   has no such problem and gains a column at every breakpoint from the room. */
.page--category main .wrap { width: min(100% - 2.5rem, var(--wrap)); }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip { position: absolute; left: -9999px; top: 0; background: var(--surface); padding: .75rem 1rem; z-index: 100; }
.skip:focus { left: 0; }
:focus-visible { outline: 3px solid var(--cta); outline-offset: 2px; border-radius: 3px; }

/* ---------------------------------------------------------------- masthead */
.masthead { background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 50; }
.masthead__inner { display: flex; align-items: center; gap: 1rem; min-height: 4.9rem; }
.brand { display: flex; align-items: center; gap: .6rem; text-decoration: none; }
/* Height drives the size and the width follows the art, so a site whose mark or
   wordmark is a different shape needs no CSS change, only its own files. */
.brand__mark { display: block; flex: none; height: 2.5rem; width: auto; }
.brand__wordmark { display: block; height: 2.625rem; width: auto; }

/* The nav collapses to a button at 60rem, but the lockup only runs out of room
   on a phone: at full size the brand, the button and the gutters come to 420px,
   which overflows a 375px screen. */
@media (max-width: 30rem) {
  .brand { gap: .5rem; }
  .brand__mark { height: 1.875rem; }
  .brand__wordmark { height: 1.75rem; }
}

/* On a phone the masthead is sticky and 4.9rem of a 667px screen is a lot to
   spend on a logo the reader has already seen. Once they scroll, the lockup
   halves and the bar closes up; it comes back at the top. Driven by a class that
   site.js toggles, so with scripting off the header simply stays full size,
   which is the same bargain the rest of the site makes.
   
   Transitioned on height rather than transform: the images set their own width
   from their height, so the row reflows instead of the art being squashed. */
@media (max-width: 60rem) {
  .masthead__inner { transition: min-height .18s ease; }
  .brand__mark, .brand__wordmark { transition: height .18s ease; }
  .masthead.is-scrolled .masthead__inner { min-height: 3.1rem; }
  .masthead.is-scrolled .brand__mark { height: 1.25rem; }
  .masthead.is-scrolled .brand__wordmark { height: 1.3rem; }
}
@media (max-width: 30rem) {
  .masthead.is-scrolled .brand__mark { height: 1rem; }
  .masthead.is-scrolled .brand__wordmark { height: .95rem; }
}
@media (prefers-reduced-motion: reduce) {
  .masthead__inner, .brand__mark, .brand__wordmark { transition: none; }
}

/* The list and the search box sit on one row. Without this the nav is a block,
   the search wraps under the links and the masthead grows a second storey. */
.nav { margin-left: auto; display: flex; align-items: center; gap: 1rem; }
.nav__list { display: flex; gap: .1rem; list-style: none; margin: 0; padding: 0; }
.nav__item { position: relative; }
.nav__item > a { display: block; padding: .6rem .8rem; border-radius: var(--radius-sm); text-decoration: none; color: var(--ink-soft); font-size: .96rem; font-weight: 600; }
.nav__item > a:hover { background: var(--bg); color: var(--brand); }
.nav__item > a[aria-current] { color: var(--brand); background: var(--brand-soft); }
.nav__sub { position: absolute; left: 0; top: 100%; min-width: 13rem; margin: 0; padding: .4rem; list-style: none; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); display: none; }
.nav__item--has-children:hover .nav__sub, .nav__item--has-children:focus-within .nav__sub { display: block; }
.nav__sub a { display: block; padding: .5rem .7rem; border-radius: 7px; text-decoration: none; color: var(--ink-soft); font-size: .93rem; font-weight: 500; }
.nav__sub a:hover { background: var(--bg); color: var(--brand); }
.navtoggle__btn { display: none; }

@media (max-width: 60rem) {
  .navtoggle__btn { display: flex; flex-direction: column; gap: 4px; margin-left: auto; padding: .6rem; cursor: pointer; border-radius: var(--radius-sm); }
  .navtoggle__btn span { width: 22px; height: 2px; background: var(--ink); border-radius: 2px; }
  .nav { display: none; position: absolute; inset: 100% 0 auto 0; background: var(--surface); border-bottom: 1px solid var(--line); padding: .5rem 1.25rem 1.25rem; box-shadow: var(--shadow-lg); }
  /* Stacked in the drawer: links first, then the search across the full width. */
  .navtoggle:checked ~ .nav { display: flex; flex-direction: column; align-items: stretch; gap: 0; }
  .nav__list { flex-direction: column; gap: 0; }
  .nav__sub { position: static; display: block; border: 0; box-shadow: none; padding: 0 0 .3rem 1rem; }
}

/* ---------------------------------------------------------------- article */
.article { max-width: none; }
.article__meta { color: var(--ink-faint); font-size: .92rem; margin: -.2em 0 1.6rem; }
.lede { font-size: 1.19rem; line-height: 1.6; color: var(--ink-soft); }
.crumbs { font-size: .87rem; color: var(--ink-faint); margin: 1.25rem 0 .6rem; }
.crumbs a { color: var(--ink-faint); text-decoration: none; }
.crumbs a:hover { color: var(--brand); text-decoration: underline; }
.crumbs span { margin: 0 .4rem; }

.article figure { margin: 2rem 0; }
.article figcaption { font-size: .87rem; color: var(--ink-faint); text-align: center; margin-top: .5rem; }
.article img { border-radius: var(--radius-sm); }
.article h2 a, .article h3 a { text-decoration: none; }

.disclosure {
  font-size: .89rem; color: var(--ink-soft); background: var(--brand-soft);
  border: 1px solid color-mix(in srgb, var(--brand) 16%, transparent);
  padding: .7rem 1rem; border-radius: var(--radius-sm); margin: 0 0 2rem;
}

/* ---------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .1rem; padding: .85rem 1.5rem; border-radius: var(--radius-sm); font-weight: 700;
  font-size: 1rem; text-decoration: none; line-height: 1.25; border: 1px solid transparent;
  transition: background-color .14s ease, transform .06s ease, box-shadow .14s ease;
}
.btn:active { transform: translateY(1px); }
.btn--buy { background: var(--cta); color: #fff; box-shadow: 0 1px 2px rgba(196,84,15,.25), 0 4px 14px rgba(196,84,15,.22); }
.btn--buy:hover { background: var(--cta-dark); color: #fff; }
.btn--block { display: flex; width: 100%; }
.btn--sm { padding: .55rem 1rem; font-size: .9rem; white-space: nowrap; }
.btn__sub { font-size: .72rem; font-weight: 500; opacity: .9; }
.btn--sm .btn__sub { display: none; }
.btn--ghost { background: var(--surface); border-color: var(--line); color: var(--ink); }
.btn--ghost:hover { border-color: var(--brand); color: var(--brand); }

/* ---------------------------------------------------------------- stars */
.stars { display: inline-flex; gap: 1px; vertical-align: -1px; }
.stars svg { width: 15px; height: 15px; fill: var(--star); }
.stars svg.is-empty { fill: var(--star-empty); }
.ratings { display: grid; gap: .3rem; margin: 0; }
.ratings div { display: flex; align-items: center; gap: .5rem; font-size: .9rem; }
.ratings dt { color: var(--ink-soft); min-width: 6.6rem; font-weight: 600; }
.ratings dd { margin: 0; display: flex; align-items: center; }

/* ---------------------------------------------------------------- top picks */
.toppicks { margin: 0 0 3rem; }
.toppicks__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 1.25rem; }
.pick {
  position: relative; display: flex; flex-direction: column; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow);
}
.pick--editors { border-color: var(--cta); box-shadow: var(--shadow-lg); }
.pick__ribbon {
  position: absolute; top: 0; left: 0; background: var(--cta); color: #fff;
  font-size: .68rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
  padding: .35rem .7rem; border-bottom-right-radius: var(--radius-sm); z-index: 1;
}
.pick__media { display: grid; place-items: center; padding: 2rem 1.25rem 1rem; background: var(--surface); min-height: 13rem; }
.pick__media img { max-height: 11rem; width: auto; object-fit: contain; mix-blend-mode: multiply; }
.pick__award {
  text-align: center; font-size: .82rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--brand); padding: 0 1rem .85rem;
  border-bottom: 1px solid var(--line-soft);
}
.pick__body { padding: 1.1rem 1.25rem; flex: 1; display: flex; flex-direction: column; }
.pick__name { margin: 0 0 .45rem; font-size: 1.12rem; line-height: 1.3; }
.pick__name a { color: var(--ink); text-decoration: none; }
.pick__name a:hover { color: var(--brand); }
.pick__blurb { margin: 0 0 1rem; font-size: .95rem; color: var(--ink-soft); }
.pick__ratings { margin: auto 0 1.1rem; padding-top: .9rem; border-top: 1px solid var(--line-soft); }
.pick__cta { margin: 0; }

/* ---------------------------------------------------------------- contents */
.toc { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.25rem 1.5rem; margin: 0 0 2.5rem; }
.toc__h { margin: 0 0 .75rem; font-size: .78rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-faint); }
.toc__list { list-style: none; margin: 0; padding: 0; columns: 2; column-gap: 2.5rem; }
.toc__list li { break-inside: avoid; margin: 0 0 .42rem; font-size: .95rem; }
.toc__list a { color: var(--ink-soft); text-decoration: none; }
.toc__list a:hover { color: var(--brand); text-decoration: underline; }
.toc__list .toc__rank { color: var(--ink-faint); font-variant-numeric: tabular-nums; margin-right: .35rem; font-weight: 700; }
@media (max-width: 40rem) { .toc__list { columns: 1; } }

/* ---------------------------------------------------------------- verdict */
.verdict {
  display: flex; gap: 1.5rem; align-items: center; flex-wrap: wrap;
  background: var(--surface); border: 2px solid var(--cta); border-radius: var(--radius);
  padding: 1.4rem 1.5rem; margin: 0 0 2.5rem; box-shadow: var(--shadow);
}
.verdict__img { flex: none; width: 120px; height: 120px; object-fit: contain; mix-blend-mode: multiply; }
.verdict__text { flex: 1 1 18rem; }
.verdict__h { margin: 0 0 .3rem; font-size: .74rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--cta); }
.verdict__name { margin: 0 0 .35rem; font-size: 1.4rem; font-weight: 750; line-height: 1.2; }
.verdict__why { margin: 0 0 1rem; color: var(--ink-soft); }

/* ---------------------------------------------------------------- product card */
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.75rem; margin: 0 0 1.75rem; box-shadow: var(--shadow); scroll-margin-top: 5.5rem;
}
.card__head { display: grid; grid-template-columns: 15rem 1fr; gap: 2rem; align-items: start; }
.card__rank {
  display: inline-block; font-size: .72rem; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: #fff; background: var(--brand);
  padding: .25rem .6rem; border-radius: 999px; margin-bottom: .6rem;
}
.card__award { display: inline-block; margin-left: .4rem; background: var(--cta); }
.card__media { display: grid; place-items: start center; }
.card__media img { max-height: 15rem; width: auto; object-fit: contain; mix-blend-mode: multiply; }
.card__ratings { margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid var(--line-soft); width: 100%; }
.card__name { margin: 0 0 .6rem; font-size: 1.45rem; }
.card__prose { color: var(--ink); }
.card__prose p, .card__prose ul, .card__prose ol { max-width: none; }
.card__prose > p:first-child { margin-top: 0; }
.card__prose ul { padding-left: 1.15rem; }
.card__prose li { margin-bottom: .4rem; }
.card__prose h3, .card__prose h4 { font-size: 1.05rem; margin-top: 1.4em; }

.proscons { display: grid; grid-template-columns: 1fr 1fr; gap: 0; margin-top: 1.5rem; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.proscons__col { padding: 1rem 1.15rem; }
.proscons__col + .proscons__col { border-left: 1px solid var(--line); }
.proscons h4 { margin: 0 0 .6rem; font-size: .76rem; text-transform: uppercase; letter-spacing: .08em; }
.proscons--pro h4 { color: var(--good); }
.proscons--con h4 { color: var(--bad); }
.proscons ul { margin: 0; padding: 0; list-style: none; font-size: .95rem; }
.proscons li { position: relative; padding-left: 1.5rem; margin-bottom: .45rem; }
.proscons li::before { position: absolute; left: 0; top: -1px; font-weight: 700; }
.proscons--pro li::before { content: "✓"; color: var(--good); }
.proscons--con li::before { content: "✕"; color: var(--bad); }
.card__cta { margin: 1.5rem 0 0; }

@media (max-width: 52rem) {
  .card { padding: 1.25rem; }
  .card__head { grid-template-columns: 1fr; gap: 1.25rem; }
  .card__media img { max-height: 12rem; }
  .proscons { grid-template-columns: 1fr; }
  .proscons__col + .proscons__col { border-left: 0; border-top: 1px solid var(--line); }
}

/* ---------------------------------------------------------------- comparison table */
/* position: relative is load bearing. An absolutely positioned descendant is
   clipped by an overflow container only when that container is its containing
   block. Every comparison table header holds <span class="visually-hidden">Buy</span>,
   which is position: absolute with no left, so it sits at its static position
   inside the scrolled table and escapes the clip: 579px of document in a 375px
   viewport on the first site to hit it, 543 on the second. Readers never
   scrolled sideways, but every full page mobile screenshot came out that wide.
   tools/check_mobile_overflow.mjs holds the line. (2026-09-12. This file is
   copied byte for byte between sites, so it names none of them.) */
.table-wrap { position: relative; overflow-x: auto; margin: 0 0 2.5rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow); }
.compare { width: 100%; border-collapse: collapse; font-size: .97rem; }
.compare th, .compare td { padding: .95rem 1.1rem; text-align: left; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
.compare thead th { font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-faint); background: var(--surface-2); font-weight: 800; }
.compare tbody tr:last-child th, .compare tbody tr:last-child td { border-bottom: 0; }
.compare tbody tr:hover { background: var(--surface-2); }
.compare tbody th { font-weight: 650; }
.compare tbody th a { color: var(--ink); text-decoration: none; }
.compare tbody th a:hover { color: var(--brand); text-decoration: underline; }
/* Column widths. A width on a cell in an auto-layout table is a preference,
   not an instruction: the surplus from a table narrower than its container gets
   shared out anyway, and the photo column was taking 339px of a 998px table
   while the model names it pushed aside wrapped onto two lines. Giving the
   model column width:100% makes it absorb all of the slack instead, which is
   the column that actually wants it. The others are classed rather than counted
   with nth-child because "Best for" only renders when a guide has awards. */
.compare__img { width: 68px; }
.compare__img img { width: 56px; height: 56px; object-fit: contain; mix-blend-mode: multiply; display: block; }
.compare__model { width: 100%; }
.compare__award, .compare__pro { min-width: 9rem; }
.compare__buy { width: 1%; white-space: nowrap; text-align: right; }

/* ---------------------------------------------------------------- ads */
.ad { margin: 2.5rem 0; text-align: center; min-height: 100px; }
.ad__label { display: block; font-size: .68rem; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-faint); margin-bottom: .35rem; }
/* Only drawn on localhost, where a placement has no unit id yet, so the frames
   can be judged before the units exist. */
.ad__placeholder {
  display: grid; place-items: center; min-height: 100px; border: 1px dashed var(--line);
  border-radius: var(--radius-sm); color: var(--ink-faint); font-size: .78rem;
}
.ad--rail .ad__placeholder { min-height: 600px; }
/* A strip, so the space it reserves looks like the ad that will fill it. */
.ad--strip .ad__placeholder { min-height: 90px; }
.ad__placeholder strong { display: block; font-weight: 650; color: var(--ink-soft); }
.ad__placeholder span { display: block; font-size: .72rem; }
/* An In-article unit takes the page's own type and sits in the flow, so it gets
   no frame of its own. */
.ad--inarticle { margin: 2rem 0; }

/* The side rails.
   Fixed in the margin beside the page's own container, and shown only where
   that margin is actually wide enough, so they can never overlap the content:
   the reading column is 1000px and the index wrap is 1250px, which need
   1000 + 2x(160 + 24) = 1368px and 1250 + 2x(160 + 24) = 1618px of viewport.
   Below that they do not exist at all, which is most visits: 69% of this
   site's traffic is a phone. */
/* Written as "every page, except the wide ones until there is room", NOT as a
   list of page types that may have rails.
   
   It was a list until 2026-09-07, naming recipe, article, category and home. The
   markup is emitted for every type in ADSENSE_PAGE_TYPES, so review and roundup
   emitted two rails each and the CSS never revealed them: 223 pages, every review
   and every guide, carrying invisible ad units. They are the money pages, and an
   <ins> inside a display:none parent is also an <ins> Google will not fill, so
   they earned nothing and reported unfilled rather than looking broken.
   
   Inverted, a page type added to ADSENSE_PAGE_TYPES gets working rails without
   anybody remembering to come here. */
.adrail { display: none; }

/* The reading column is 1000px, so the rails need 1000 + 2x(160 + 24) = 1368px
   of viewport. Below that they do not exist at all, which is most visits: 69% of
   this site's traffic is a phone. */
@media (min-width: 87rem) {
  .adrail {
    display: block; position: fixed; top: 6.5rem; width: 160px; z-index: 10;
  }
  .adrail--l { left: calc(50% - 500px - 1.5rem - 160px); }
  .adrail--r { left: calc(50% + 500px + 1.5rem); }

  /* The index pages go out to 1250px and need 1618px before their rails fit.
     Hidden here so they cannot overlap the grid, and turned back on below. */
  .page--category .adrail, .page--home .adrail { display: none; }
}

@media (min-width: 102rem) {
  .page--category .adrail, .page--home .adrail { display: block; }
  .page--category .adrail--l, .page--home .adrail--l { left: calc(50% - 625px - 1.5rem - 160px); }
  .page--category .adrail--r, .page--home .adrail--r { left: calc(50% + 625px + 1.5rem); }
}
.adrail .ad { margin: 0; }

/* ---------------------------------------------------------------- faq */
.article details.faq { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .9rem 1.15rem; margin: 0 0 .6rem; background: var(--surface); }
.article details.faq summary { cursor: pointer; font-weight: 650; }
.article details.faq[open] summary { margin-bottom: .6rem; }

/* ---------------------------------------------------------------- hubs, tiles */
.hub__head { margin: 1.5rem 0 2rem; }
.feature {
  display: flex; gap: 1.75rem; align-items: center; text-decoration: none; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.5rem; margin: 0 0 2.5rem; box-shadow: var(--shadow); transition: box-shadow .15s ease;
}
.feature:hover { box-shadow: var(--shadow-lg); }
.feature img { flex: none; width: 120px; height: 120px; object-fit: contain; mix-blend-mode: multiply; }
.feature__kicker { margin: 0 0 .25rem; font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .1em; color: var(--cta); }
.feature__title { margin: 0 0 .3rem; font-size: 1.5rem; font-weight: 750; letter-spacing: -.02em; }
.feature__meta { margin: 0; font-size: .93rem; color: var(--ink-faint); }
.feature:hover .feature__title { color: var(--brand); }

/* The top pick, first in the results column.
   
   It was sticky for a few hours on 2026-09-07 and that was wrong: pinned to the
   top of a scrolling list it sat ON TOP of the cards it is meant to introduce,
   hiding the first result at every scroll position. Dean called it, having asked
   for the sticky in the first place; seeing it beat reasoning about it.
   
   It keeps its own dark ground, so it still reads as an answer rather than one
   more card in a column of white ones, and being first is enough. */
.feature--pinned {
  margin-bottom: 1.5rem;
  background: linear-gradient(135deg, var(--pin-1) 0%, var(--pin-2) 55%, var(--pin-3) 100%);
  border-color: var(--pin-line); color: var(--pin-ink);
  box-shadow: 0 2px 6px rgba(27,24,21,.16), 0 16px 44px rgba(27,24,21,.22);
  padding: 1.25rem 1.5rem;
}
.feature--pinned .feature__kicker { color: var(--pin-kick); }
.feature--pinned .feature__title { color: #fff; font-size: 1.35rem; }
.feature--pinned .feature__meta  { color: var(--pin-soft); }
.feature--pinned:hover .feature__title { color: var(--pin-hover); }
/* The photograph is cut out on white, so multiply would paint it black here. */
.feature--pinned img {
  width: 92px; height: 92px; mix-blend-mode: normal;
  background: #fff; border-radius: 10px; padding: .35rem;
}
.feature__go {
  margin-left: auto; flex: none; align-self: center;
  font-size: .85rem; font-weight: 700; letter-spacing: .01em;
  background: var(--cta); color: #fff; padding: .6rem 1.1rem; border-radius: 999px;
  box-shadow: 0 1px 2px rgba(196,84,15,.3);
}
.feature--pinned:hover .feature__go { background: var(--cta-dark); }
/* Only the pinned one has the pill; the plain card keeps its old shape. */
.feature:not(.feature--pinned) .feature__go { display: none; }

/* On a phone the column is the whole screen, so a sticky card would cover the
   list it is meant to introduce. */
@media (max-width: 60rem) {
  .feature--pinned img { width: 72px; height: 72px; }
  .feature__go { display: none; }
}

/* Order is not a facet: no counts, so no room reserved for them. */
.facet--sort li a { gap: 0; }

.cards { list-style: none; margin: 0 0 2.5rem; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr)); gap: 1.5rem; }
/* The tile frame. Source images are every shape from 1:1 to 2.4:1, so the frame
   fixes the size and the image fits inside it; without this the grid is ragged. */
.tile a { display: flex; flex-direction: column; height: 100%; text-decoration: none; color: var(--ink); }
.tile__shot {
  display: grid; place-items: center; aspect-ratio: 3 / 2; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--line); overflow: hidden;
  transition: box-shadow .15s ease, border-color .15s ease;
}
.tile__shot img { width: 100%; height: 100%; display: block; }
.tile a:hover .tile__shot { box-shadow: var(--shadow); border-color: var(--brand); }
.tile__shot--none { font-size: 2rem; }

/* Photography (recipes, articles) fills the frame. */
.cards--photo .tile__shot { aspect-ratio: 3 / 2; }
.cards--photo .tile__shot img { object-fit: cover; }

/* Product shots are cut-outs on white: they sit inside the frame, never cropped. */
.cards--product .tile__shot { aspect-ratio: 4 / 3; }
.cards--product .tile__shot img { object-fit: contain; padding: 1rem; mix-blend-mode: multiply; }

.tile__title {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  margin-top: .7rem; font-weight: 650; font-size: 1rem; line-height: 1.35; letter-spacing: -.01em;
}
.tile a:hover .tile__title { color: var(--brand); }
.tile__excerpt {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  margin-top: .3rem; font-size: .89rem; line-height: 1.45; color: var(--ink-soft);
}
/* A guide card ends this line with how many cookers it compares, and two of the
   thirty have a pick name long enough to fill both lines on its own, which
   clipped the count out of sight. The third line is for those two; the rest
   never reach it, and a row's cards match height anyway. */
.cards--guides .tile__excerpt { -webkit-line-clamp: 3; }
.tile__meta {
  display: block; font-size: .82rem; color: var(--ink-faint);
  margin-top: auto; padding-top: .55rem;
}
/* Each fact stays whole. Without this a card three or four across broke the
   author across lines at the hyphen, so "Ji-hyun" read as "Ji-" then "hyun". */
.tile__bit { white-space: nowrap; }
.tile__dot { margin: 0 .4rem; }

.pager { display: flex; align-items: center; justify-content: center; gap: 1.25rem; margin: 2.5rem 0; font-size: .95rem; }
.pager a { color: var(--brand); font-weight: 650; text-decoration: none; padding: .55rem 1rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.pager a:hover { border-color: var(--brand); }
.pager__at { color: var(--ink-faint); }

/* ---------------------------------------------------------------- home */
.hero { padding: 3.5rem 0 2.5rem; max-width: 40rem; }
.hero h1 { margin-bottom: .35rem; }
.hero .lede { margin-bottom: 1.5rem; }
.section__head { display: flex; align-items: baseline; gap: 1rem; margin: 3rem 0 1.25rem; }
.section__head h2 { margin: 0; }
.section__more { margin-left: auto; font-size: .93rem; font-weight: 650; text-decoration: none; }

.linklist { list-style: none; margin: 0 0 2.5rem; padding: 0; }
.linklist li { display: flex; justify-content: space-between; gap: 1.5rem; padding: .85rem 0; border-bottom: 1px solid var(--line); }
.linklist a { color: var(--ink); text-decoration: none; font-weight: 600; }
.linklist a:hover { color: var(--brand); text-decoration: underline; }
.linklist time { color: var(--ink-faint); font-size: .88rem; white-space: nowrap; }

/* ---------------------------------------------------------------- related */
.related { margin-top: 3.5rem; padding-top: 2rem; border-top: 1px solid var(--line); }
.related__list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 1.25rem; }
.related__item a { display: flex; gap: .9rem; align-items: center; text-decoration: none; color: var(--ink); font-size: .95rem; font-weight: 600; }
.related__item img { border-radius: var(--radius-sm); object-fit: cover; flex: none; width: 76px; height: 58px; border: 1px solid var(--line); }
.related__item a:hover span { color: var(--brand); text-decoration: underline; }

/* ---------------------------------------------------------------- authors */
.authors { display: grid; gap: 2rem; margin: 1.75rem 0 3rem; }
.author { display: flex; gap: 1.5rem; align-items: flex-start; }
.author .author__photo { flex: none; width: 116px; height: 116px; border-radius: 50%; object-fit: cover; background: var(--surface); border: 1px solid var(--line); }
.author .author__photo--none { display: grid; place-items: center; font-size: 2.5rem; font-weight: 800; color: var(--brand); background: var(--brand-soft); }
.author__name { margin: 0 0 .1rem; font-size: 1.2rem; }
.author__role { margin: 0 0 .7rem; font-size: .75rem; text-transform: uppercase; letter-spacing: .09em; color: var(--ink-faint); font-weight: 800; }
.author__text p { margin: 0 0 .65rem; }
.author__text p:last-child { margin-bottom: 0; }
@media (max-width: 34rem) { .author { flex-direction: column; gap: .9rem; } .author .author__photo { width: 92px; height: 92px; } }

/* ---------------------------------------------------------------- contact */
/* The contact form sits in a card, so it reads as the thing the page is for
   rather than three boxes trailing off the bottom of the copy. */
.contactform {
  max-width: 40rem; margin-top: 1.75rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.6rem;
  box-shadow: 0 1px 2px rgba(27,24,21,.04), 0 8px 24px rgba(27,24,21,.05);
}
.contactform .field { margin: 0 0 1.15rem; }
.contactform label { display: block; font-weight: 650; font-size: .92rem; margin-bottom: .4rem; }
.contactform input[type=text], .contactform input[type=email], .contactform textarea {
  width: 100%; padding: .8rem .9rem; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--ink); font: inherit;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.contactform input::placeholder, .contactform textarea::placeholder { color: var(--ink-faint); }
/* A visible focus ring in the brand colour: which box you are in should never be
   a guess, and the browser default is a thin outline on a light background. */
.contactform input:focus, .contactform textarea:focus {
  outline: none; background: var(--surface);
  border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft);
}
.contactform textarea { resize: vertical; min-height: 9rem; }

/* Name and email share a row once there is space for both. min-width:0 or a long
   placeholder pushes the grid wider than its container. */
.contactform__row { display: grid; gap: 0 1rem; }
.contactform__row > .field { min-width: 0; }
@media (min-width: 34rem) { .contactform__row { grid-template-columns: 1fr 1fr; } }

.contactform__send { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin: 1.5rem 0 0; }
.contactform__note { font-size: .87rem; color: var(--ink-soft); }
@media (max-width: 30rem) {
  .contactform { padding: 1.15rem; }
  .contactform__send .btn { width: 100%; justify-content: center; }
}
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.formerrors { background: var(--bad-bg); border: 1px solid var(--bad); color: var(--bad-ink); padding: .85rem 1.1rem; border-radius: var(--radius-sm); margin-bottom: 1.25rem; }
.formerrors ul { margin: .4rem 0 0; padding-left: 1.2rem; }
.contactform .hint { font-size: .82rem; color: var(--ink-faint); margin: 1rem 0 0; }
.hint { font-size: .87rem; color: var(--ink-faint); }

/* ---------------------------------------------------------------- footer */
.footer { margin-top: 5rem; padding: 3rem 0 2.5rem; background: var(--surface); border-top: 1px solid var(--line); font-size: .95rem; }
.footer__cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 2rem; }
.footer__heading { font-size: .74rem; text-transform: uppercase; letter-spacing: .09em; color: var(--ink-faint); margin: 0 0 .75rem; font-weight: 800; }
.footer__col ul { list-style: none; margin: 0; padding: 0; }
.footer__col li { margin-bottom: .45rem; }
.footer__col a { color: var(--ink-soft); text-decoration: none; }
.footer__col a:hover { color: var(--brand); text-decoration: underline; }
.footer__disclosure { margin: 2.5rem 0 .6rem; padding-top: 1.5rem; border-top: 1px solid var(--line); color: var(--ink-faint); font-size: .89rem; }
.footer__legal { margin: 0; color: var(--ink-faint); font-size: .85rem; }

/* ---------------------------------------------------------------- buy box */
.buybox {
  position: relative; display: flex; gap: 1.75rem; align-items: center; flex-wrap: wrap;
  background: linear-gradient(180deg, #fff, var(--surface-2));
  border: 2px solid var(--cta); border-radius: var(--radius);
  padding: 1.6rem 1.75rem; margin: 0 0 2.5rem; box-shadow: var(--shadow-lg);
}
.buybox__ribbon {
  position: absolute; top: -.75rem; left: 1.5rem; margin: 0; background: var(--cta); color: #fff;
  font-size: .68rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
  padding: .3rem .75rem; border-radius: 999px;
}
.buybox__media { flex: none; }
.buybox__media img { width: 160px; height: 160px; object-fit: contain; mix-blend-mode: multiply; }
.buybox__body { flex: 1 1 20rem; }
.buybox__label { margin: 0 0 .15rem; font-size: .7rem; font-weight: 800; letter-spacing: .11em; text-transform: uppercase; color: var(--cta); }
.buybox__name { margin: 0 0 .5rem; font-size: 1.45rem; font-weight: 750; line-height: 1.2; letter-spacing: -.02em; }
.buybox__note { margin: 0 0 1rem; color: var(--ink-soft); max-width: 46ch; }
.buybox__ratings { margin: 0 0 1.15rem; }
.buybox__small { margin: .7rem 0 0; font-size: .8rem; color: var(--ink-faint); }
.btn--lg { padding: 1rem 2rem; font-size: 1.05rem; }

/* A repeated CTA at the end of a long article, where the reader has finished
   deciding. The old site's only link was somewhere in the middle of the prose. */
.cta-band {
  display: flex; gap: 1.25rem; align-items: center; justify-content: space-between; flex-wrap: wrap;
  background: var(--brand-soft); border: 1px solid color-mix(in srgb, var(--brand) 20%, transparent);
  border-radius: var(--radius); padding: 1.35rem 1.6rem; margin: 2.5rem 0;
}
.cta-band__text { margin: 0; font-weight: 650; font-size: 1.05rem; }
.cta-band__sub { margin: .2rem 0 0; font-size: .9rem; color: var(--ink-soft); font-weight: 400; }

/* ---------------------------------------------------------------- trust strip */
.trust {
  display: flex; flex-wrap: wrap; gap: .5rem 2rem; list-style: none; margin: 0 0 2.5rem; padding: 0;
  font-size: .93rem; color: var(--ink-soft);
}
.trust li { position: relative; padding-left: 1.5rem; }
.trust li::before {
  content: "✓"; position: absolute; left: 0; top: -1px; color: var(--good); font-weight: 800;
}
.trust strong { color: var(--ink); font-weight: 700; }

/* ---------------------------------------------------------------- zoom + lightbox */
.zoom {
  display: block; padding: 0; border: 1px solid var(--line); background: var(--surface);
  border-radius: var(--radius-sm); cursor: zoom-in; width: 100%; position: relative; overflow: hidden;
}
.zoom img { display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: contain; padding: .75rem; mix-blend-mode: multiply; }
.zoom__hint {
  display: block; font-size: .72rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-faint); padding: .4rem; border-top: 1px solid var(--line-soft); background: var(--surface-2);
}
.zoom:hover { border-color: var(--brand); }
.zoom:hover .zoom__hint { color: var(--brand); }

.lightbox { border: 0; padding: 0; background: transparent; max-width: 92vw; max-height: 92vh; overflow: visible; }
.lightbox::backdrop { background: var(--scrim); }
.lightbox img { display: block; max-width: 92vw; max-height: 88vh; border-radius: var(--radius); background: #fff; }
.lightbox__close {
  position: absolute; top: -.9rem; right: -.9rem; width: 2.4rem; height: 2.4rem; border-radius: 50%;
  border: 0; background: #fff; color: var(--ink); font-size: 1.5rem; line-height: 1; cursor: pointer;
  box-shadow: var(--shadow-lg);
}

/* ---------------------------------------------------------------- card CTA, centred */
.card__cta { margin: 1.75rem 0 0; text-align: center; }
.card__cta .btn { min-width: 20rem; }
@media (max-width: 34rem) { .card__cta .btn { min-width: 0; width: 100%; } }

/* ---------------------------------------------------------------- pros and cons */
.proscons { background: var(--surface-2); }
.proscons__col { padding: 1.15rem 1.35rem; }
.proscons h4 {
  margin: 0 0 .75rem; font-size: .74rem; text-transform: uppercase; letter-spacing: .09em;
  display: flex; align-items: center; gap: .45rem;
}
.proscons h4::before {
  display: grid; place-items: center; width: 1.35rem; height: 1.35rem; border-radius: 50%;
  font-size: .8rem; color: #fff;
}
.proscons--pro h4::before { content: "✓"; background: var(--good); }
.proscons--con h4::before { content: "✕"; background: var(--bad); }
.proscons li { padding-left: 1.6rem; margin-bottom: .55rem; line-height: 1.5; }
.proscons li:last-child { margin-bottom: 0; }
.proscons--pro li::before { content: "✓"; color: var(--good); }
.proscons--con li::before { content: "✕"; color: var(--bad); }

/* ---------------------------------------------------------------- FAQ */
.article details.faq {
  border: 1px solid var(--line); border-left: 3px solid var(--brand); border-radius: var(--radius-sm);
  padding: 0; margin: 0 0 .75rem; background: var(--surface); max-width: none; overflow: hidden;
}
.article details.faq summary {
  cursor: pointer; font-weight: 700; padding: .95rem 1.25rem; list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.article details.faq summary::-webkit-details-marker { display: none; }
.article details.faq summary::after { content: "+"; font-size: 1.4rem; color: var(--brand); font-weight: 400; line-height: 1; }
.article details.faq[open] summary::after { content: "\2212"; }
.article details.faq[open] summary { border-bottom: 1px solid var(--line-soft); }
.article details.faq > div { padding: 1rem 1.25rem 1.15rem; }
.article details.faq > div > p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- author box */
.authorbox {
  display: flex; gap: 1.35rem; align-items: flex-start; margin: 3rem 0 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.5rem 1.75rem;
}
.authorbox__photo { flex: none; width: 84px; height: 84px; border-radius: 50%; object-fit: cover; border: 1px solid var(--line); }
.authorbox__label { margin: 0 0 .1rem; font-size: .7rem; font-weight: 800; letter-spacing: .11em; text-transform: uppercase; color: var(--ink-faint); }
.authorbox__name { margin: 0 0 .5rem; font-size: 1.15rem; font-weight: 750; display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.authorbox__role { font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-faint); }
.authorbox__bio { margin: 0 0 .6rem; color: var(--ink-soft); font-size: .96rem; }
.authorbox__more { margin: 0; font-size: .93rem; font-weight: 650; }
@media (max-width: 34rem) { .authorbox { flex-direction: column; gap: 1rem; padding: 1.25rem; } }
.compare__dash { color: var(--ink-faint); }

/* ---------------------------------------------------------------- conclusion */
/* The closing section of a round-up. It is the last thing a reader sees before
   the verdict, and it was three paragraphs of undifferentiated body copy. */
.article h2#verdict { margin-top: 2.5rem; }
.conclusion {
  background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--brand);
  border-radius: var(--radius); padding: 1.5rem 1.75rem; margin: 2.5rem 0;
}
.conclusion > :first-child { margin-top: 0; }
.conclusion > :last-child { margin-bottom: 0; }
.conclusion h2, .conclusion h3 { margin-top: 0; font-size: 1.35rem; }

/* The article title needs room to breathe under a sticky masthead. */
.article > h1:first-child, .wrap > h1:first-child { margin-top: 2.5rem; }
.crumbs + h1 { margin-top: 1rem; }

/* A table thumbnail is a zoom target too, without the card's frame and hint. */
.zoom--thumb { width: 56px; border: 0; background: transparent; border-radius: 6px; }
.zoom--thumb img { padding: 0; aspect-ratio: 1; }
.zoom--thumb .zoom__hint { display: none; }
.zoom--thumb:hover { outline: 2px solid var(--brand); outline-offset: 2px; }

/* An inline content image that opens the lightbox. It must not gain the card's
   frame, hint bar or full-width block behaviour. */
.zoom--inline { display: inline-block; width: auto; border: 0; background: transparent; padding: 0; border-radius: var(--radius-sm); }
.zoom--inline img { padding: 0; aspect-ratio: auto; width: auto; max-width: 100%; }

/* .zoom img is the product-card treatment: a cut-out photographed on white,
   multiplied so the white box disappears into the page. That is right for a
   review's product shots and wrong for a photograph, which it tints against the
   off-white background, so it is switched off only where the body is editorial. */
.page--recipe .zoom--inline img,
.page--article .zoom--inline img { mix-blend-mode: normal; object-fit: fill; }
.zoom--inline .zoom__hint { display: none; }
.zoom--inline:hover { outline: 2px solid var(--brand); outline-offset: 3px; }
/* Centring an inline photograph means centring its wrapper, not relying on the
   figure's text-align. The lightbox wrapper is a <button>, and a button shrink
   wraps to its content even at display:block, so it sat hard against the left
   edge of a 1000px column with text-align:center having no inline box to act
   on: a 624px photo ended up 188px off centre. */
.article figure .zoom--inline { display: block; width: fit-content; margin-inline: auto; }

/* ---------------------------------------------------------------- article media
   Product photographs come out of the export at up to 1200px and were filling
   the whole 1250px column, so a single picture of a rice cooker was taller than
   the screen. Capped and centred. */
.article figure { margin: 2rem auto; text-align: center; }
.article figure img { max-height: 26rem; width: auto; max-width: 100%; margin-inline: auto; }
.article figure a { display: inline-block; }
.article > p > img, .article .zoom--inline img { max-height: 26rem; width: auto; }
.article > p > img, .article > img { display: block; margin-inline: auto; }
.article figcaption { font-size: .86rem; color: var(--ink-faint); margin-top: .6rem; }
.article figcaption a { color: var(--ink-faint); }

/* ---------------------------------------------------------------- spec table
   The specification block imports as a bare two-column table: a wall of rows
   with no padding, no rules and no visual break from the prose. */
.article .table-wrap { box-shadow: none; }
/* These are for the tables that come out of the old WordPress bodies, which are
   two-column label/value affairs. They must not reach .compare, which is a
   component with its own complete styling and lives inside .article too. They
   were reaching it: `.article table td:first-child { width: 34% }` outranks
   `.compare__img { width: 68px }` on specificity and blew the photo column out
   to 197px, and the same block was also forcing top alignment, zebra striping
   and a bold grey first column onto it. */
.article table:not(.compare) { width: 100%; border-collapse: collapse; font-size: .96rem; }
.article table:not(.compare) td, .article table:not(.compare) th { padding: .8rem 1.1rem; border-bottom: 1px solid var(--line-soft); text-align: left; vertical-align: top; }
.article table:not(.compare) tr:last-child td, .article table:not(.compare) tr:last-child th { border-bottom: 0; }
.article table:not(.compare) tr:nth-child(odd) td { background: var(--surface-2); }
.article table:not(.compare) td:first-child { width: 34%; color: var(--ink-soft); font-weight: 650; }
.article table:not(.compare) td:first-child strong { font-weight: 650; }
.article table:not(.compare) thead th { font-size: .74rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-faint); background: var(--surface-2); }
@media (max-width: 34rem) { .article table:not(.compare) td:first-child { width: 45%; } }

/* ---------------------------------------------------------------- quotes */
.article blockquote {
  margin: 2rem 0; padding: 1.35rem 1.6rem 1.35rem 3.4rem; position: relative;
  background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--brand);
  border-radius: var(--radius); font-size: 1.05rem; line-height: 1.6; color: var(--ink);
}
.article blockquote::before {
  content: "\201C"; position: absolute; left: 1rem; top: .35rem;
  font-size: 3.2rem; line-height: 1; color: var(--brand); opacity: .35; font-family: Georgia, serif;
}
.article blockquote p { margin: 0 0 .6rem; max-width: none; }
.article blockquote p:last-child { margin-bottom: 0; }
.article blockquote cite, .article blockquote em:last-child {
  display: block; margin-top: .75rem; font-size: .88rem; font-style: normal;
  color: var(--ink-faint); font-weight: 650;
}

/* ---------------------------------------------------------------- rules
   A bare <hr> defaults to border-style: inset, which browsers draw as a groove:
   a light line above a dark one, so it reads as two lines rather than one. It
   was never styled here, so every separator in the imported prose looked
   doubled. One line, quiet, with room around it. */
hr { height: 0; border: 0; border-top: 1px solid var(--line); margin: 2.5rem 0; }
.article hr:last-child { display: none; }

/* The review's closing paragraphs, sitting under "Should you buy it?" and above
   the button. Not boxed: the buy box directly beneath it already is, and two
   nested frames read as an error. */
.verdict-prose { margin: 0 0 1.5rem; }
.verdict-prose > :first-child { margin-top: 0; }
.verdict-prose > :last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- product index
   A retailer-shaped category page for the reviews: facets down the side, rows
   that compare at a glance. No price column, because Amazon prices have to come
   from their API and we have none: the button fetches the real one. */
.pindex { display: grid; grid-template-columns: 15rem 1fr; gap: 2rem; align-items: start; margin: 1.5rem 0 3rem; }
/* A grid item's min-width is auto, so a column refuses to shrink below the
   min-content of what is inside it. On a 320px phone that pushed the results
   column to 313px inside a 280px slot and gave the homepage a horizontal
   scrollbar. Letting the columns shrink is the fix; nothing else changes. */
.pindex > *, .prod > * { min-width: 0; }
@media (max-width: 56rem) { .pindex { grid-template-columns: 1fr; } }

.pindex__filters { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.25rem; position: sticky; top: 5.5rem; }
@media (max-width: 56rem) { .pindex__filters { position: static; } }
.pindex__filterhead { display: flex; align-items: baseline; gap: 1rem; margin-bottom: 1rem; }
.pindex__filterhead h2 { margin: 0; font-size: .8rem; text-transform: uppercase; letter-spacing: .09em; color: var(--ink-faint); }
.pindex__clear { margin-left: auto; font-size: .85rem; font-weight: 650; }

.pills { list-style: none; margin: 0 0 1.25rem; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; }
.pills a { display: inline-flex; align-items: center; gap: .4rem; background: var(--brand-soft); border: 1px solid color-mix(in srgb, var(--brand) 25%, transparent); color: var(--brand); border-radius: 999px; padding: .25rem .65rem; font-size: .82rem; font-weight: 650; text-decoration: none; }
.pills a:hover { background: var(--brand); color: #fff; }

.facet + .facet { margin-top: 1.35rem; padding-top: 1.25rem; border-top: 1px solid var(--line-soft); }
.facet h3 { margin: 0 0 .5rem; font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-faint); }
.facet ul { list-style: none; margin: 0; padding: 0; max-height: 15rem; overflow-y: auto; }
.facet li a { display: flex; align-items: center; gap: .5rem; padding: .3rem .45rem; border-radius: 7px; text-decoration: none; color: var(--ink-soft); font-size: .92rem; }
.facet li a:hover { background: var(--bg); color: var(--brand); }
.facet li.is-on a { background: var(--brand); color: #fff; font-weight: 650; }
.facet__n { margin-left: auto; font-size: .78rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.facet li.is-on .facet__n { color: rgba(255,255,255,.8); }

.pindex__bar { display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.pindex__count { margin: 0; color: var(--ink-soft); }
.sorts { list-style: none; margin: 0 0 0 auto; padding: 0; display: flex; gap: .25rem; flex-wrap: wrap; font-size: .88rem; }
.sorts a { display: block; padding: .35rem .7rem; border-radius: 999px; text-decoration: none; color: var(--ink-soft); }
.sorts a:hover { background: var(--surface); color: var(--brand); }
.sorts li.is-on a { background: var(--ink); color: #fff; font-weight: 650; }
.pindex__none { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 2rem; text-align: center; }

.prods { list-style: none; margin: 0; padding: 0; display: grid; gap: 1rem; }
.prod { display: grid; grid-template-columns: 9rem 1fr 11rem; gap: 1.5rem; align-items: center;
        background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.15rem; transition: box-shadow .15s ease; }
.prod:hover { box-shadow: var(--shadow); }
.prod__shot { display: grid; place-items: center; }
.prod__shot img { width: 100%; height: 8rem; object-fit: contain; mix-blend-mode: multiply; }
.prod__name { margin: 0 0 .35rem; font-size: 1.08rem; line-height: 1.3; }
.prod__name a { color: var(--ink); text-decoration: none; }
.prod__name a:hover { color: var(--brand); }
.prod__score { display: flex; align-items: center; gap: .45rem; margin: 0 0 .55rem; font-size: .88rem; color: var(--ink-soft); font-weight: 650; }
.prod__specs { display: flex; flex-wrap: wrap; gap: .3rem 1.25rem; margin: 0 0 .5rem; font-size: .86rem; }
.prod__specs div { display: flex; gap: .35rem; }
.prod__specs dt { color: var(--ink-faint); }
.prod__specs dd { margin: 0; font-weight: 650; }
.prod__blurb { margin: 0; font-size: .89rem; color: var(--ink-faint); }
.prod__act { display: grid; gap: .5rem; }
.prod__act .btn { width: 100%; }

@media (max-width: 46rem) {
  .prod { grid-template-columns: 6rem 1fr; }
  .prod__shot img { height: 5.5rem; }
  .prod__act { grid-column: 1 / -1; grid-template-columns: 1fr 1fr; }
}

/* ---------------------------------------------------------------- search */
/* In the masthead, after the nav. Collapses to a full-width row inside the
   drawer on a phone, where the nav is a checkbox-driven panel. */
.navsearch { display: flex; align-items: center; gap: .3rem; margin-left: 1.25rem; }
.navsearch input {
  width: 9.5rem; padding: .42rem .7rem; font: inherit; font-size: .9rem;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface-2); color: var(--ink);
  transition: width .18s ease, border-color .15s, box-shadow .15s;
}
.navsearch input::placeholder { color: var(--ink-faint); }
.navsearch input:focus {
  outline: none; width: 13rem; background: var(--surface);
  border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft);
}
.navsearch button {
  display: grid; place-items: center; width: 2rem; height: 2rem; flex: none;
  border: 0; border-radius: 50%; background: none; color: var(--ink-soft); cursor: pointer;
}
.navsearch button:hover { color: var(--brand); background: var(--brand-soft); }

.searchpage { display: flex; gap: .6rem; margin-top: 1rem; max-width: 34rem; }
.searchpage input {
  flex: 1; padding: .8rem 1rem; font: inherit;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink);
}
.searchpage input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.searchhint { color: var(--ink-soft); max-width: 40rem; }

.results { list-style: none; margin: 1.25rem 0 3rem; padding: 0; display: grid; gap: .75rem; }
.result {
  display: flex; align-items: center; gap: 1.15rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1rem 1.25rem;
}
.result__shot { flex: none; width: 90px; height: 90px; object-fit: contain; mix-blend-mode: multiply; }
.result__body { min-width: 0; flex: 1; }
.result__kind { margin: 0 0 .2rem; font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .09em; color: var(--ink-faint); }
.result__title { margin: 0 0 .3rem; font-size: 1.08rem; line-height: 1.35; }
.result__title a { text-decoration: none; color: var(--ink); }
.result__title a:hover { color: var(--brand); }
.result__blurb { margin: 0; font-size: .92rem; color: var(--ink-soft); }
.result__score { margin: 0; flex: none; text-align: center; font-weight: 700; font-size: .9rem; }
.result mark { background: var(--mark); color: inherit; padding: 0 .1em; border-radius: 2px; }

@media (max-width: 60rem) {
  .navsearch { margin: .75rem 0 0; width: 100%; }
  .navsearch input, .navsearch input:focus { width: 100%; }
  .result { align-items: flex-start; }
  .result__shot { width: 64px; height: 64px; }
  .result__score { display: none; }
}
