/* A backgroundless bar across the top 80px holding three floating pieces (Patryk, 2026-10-18): the
   logo at the left, the three categories in a tray in the middle, the menu button in a tray of its own
   at the right, with Mouse finder, All mice, Articles and About under it. One layout at every width:
   the text links went into the menu so the bar never runs out of room as pages are added. scene.js
   keeps every shell below this band (its topInset). */
.category-nav {
  position: fixed; z-index: 30; inset: 0 0 auto 0;
  height: 80px; padding: 0 20px;     /* the menu's tray 20px from the right, as from the top */
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  pointer-events: none;                 /* the empty strip stays click-through; only the pieces catch */
}
.category-nav > * { pointer-events: auto; }/* 6px past the bar's 20px, so the 28px logo stands as far from the left as from the top (26px). */
.category-nav .brand { justify-self: start; margin-left: 6px; display: grid; place-items: center; color: var(--ink); }
.category-nav .brand-mark { width: 28px; height: 28px; display: block; }

/* The two trays are Storefolio's switch in its light theme (storefolio.co, .nav-links and
   .nav-indicator, read 2026-10-18): grey and half clear, no shadow of their own, the chosen mark a
   white pill raised by one small shadow, the others at 55% of the ink. 32px marks, 3px padding and a
   1px border make each tray 40px tall. The categories are ovals (circles were tried and dropped);
   the menu button, alone in its tray, is round. */
.category-nav .cats, .category-nav .nav-side {
  position: relative; display: flex; align-items: center; gap: 2px; padding: 3px;
  border: 1px solid transparent; border-radius: 999px;
  background: oklch(.9 0 0 / .8);
  -webkit-backdrop-filter: blur(4px) saturate(1.6); backdrop-filter: blur(4px) saturate(1.6);
}
.category-nav .nav-side { justify-self: end; }
.category-nav .cats a, .category-nav .nav-burger {
  position: relative; display: grid; place-items: center; height: 32px; border-radius: 999px;
  color: oklch(.24 0 0 / .55); text-decoration: none;
  transition: background .2s, color .2s, box-shadow .2s;
}
.category-nav .cats a { width: 44px; }
.category-nav .nav-burger { width: 32px; }
.category-nav .cats a:hover, .category-nav .nav-burger:hover { color: oklch(.24 0 0); }
/* The raised white: the menu button wears it always (Patryk, 2026-10-18: it is alone in its tray),
   the categories through one pill that slides under the chosen mark, as Storefolio's does
   (.nav-indicator: 0.35s on cubic-bezier(.22, 1, .36, 1)). Each category is a page of its own, so the
   pill is placed by CSS from which link is current, and the move from one page's place to the next
   is the view transition's (below): the pill has a name of its own and the browser carries it
   across. A page with no category of its own (Articles, About) has no pill. */
.category-nav .nav-burger, .category-nav .nav-indicator {
  background: var(--surface); box-shadow: var(--shadow-raised);
}
.category-nav .nav-burger, .category-nav .cats a[aria-current="page"] { color: oklch(.2 0 0); }
.category-nav .nav-indicator {
  position: absolute; top: 3px; left: 3px; width: 44px; height: 32px; border-radius: 999px;
  pointer-events: none; opacity: 0; view-transition-name: nav-indicator;
}
.category-nav .cats:has(> a[aria-current="page"]) .nav-indicator { opacity: 1; }
.category-nav .cats:has(> a:nth-of-type(2)[aria-current="page"]) .nav-indicator { transform: translateX(46px); }
.category-nav .cats:has(> a:nth-of-type(3)[aria-current="page"]) .nav-indicator { transform: translateX(92px); }
.category-nav .cats:has(> a:nth-of-type(4)[aria-current="page"]) .nav-indicator { transform: translateX(138px); }
/* The marks are named too, so they paint over the pill while it moves and their colour cross-fades. */
.category-nav .cats a:nth-of-type(1) { view-transition-name: nav-cat-1; }
.category-nav .cats a:nth-of-type(2) { view-transition-name: nav-cat-2; }
.category-nav .cats a:nth-of-type(3) { view-transition-name: nav-cat-3; }
.category-nav .cats a:nth-of-type(4) { view-transition-name: nav-cat-4; }
/* The marks as they always were: 23px, their own 1.7 stroke. */
.category-nav .cats svg { width: 23px; height: 23px; }
.category-nav .cat-label { display: none; }
.category-nav .nav-burger svg { width: 18px; height: 18px; stroke-width: 2.2; }

/* The menu (Patryk, 2026-11-01, after ElevenLabs' account menu): a white card lifted off the page by
   a hairline ring and a stack of soft shadows that grow wider and fainter, so it reads as standing
   well above the page rather than drawn on it. The entries are a mark in the text's ink and one
   line; the entry you point at and the page you are on take the grey the list rows use, across the
   card's whole width as the rows of the result list do (the consistency pass of 2026-11-02). The country
   closes it under a hairline as one more such entry (Patryk, 2026-11-01: a card of its own, on a
   grey band or not, looked set apart from the rest). */
.category-nav .nav-menu {
  position: absolute; top: calc(100% + 8px); right: 0; width: 224px; max-width: calc(100vw - 20px); padding: 6px 0;
  display: flex; flex-direction: column;
  border-radius: 14px; background: var(--surface);
  box-shadow: var(--shadow-pop);
  overflow: hidden;   /* a row's hover grey keeps to the rounded corners (it squared off past them, 2026-11-02) */
  transform-origin: top right; transition: opacity .16s, transform .2s cubic-bezier(.22, 1, .36, 1), visibility .2s;
}
.category-nav .nav-menu[hidden] { display: flex; opacity: 0; visibility: hidden; transform: scale(.96) translateY(-4px); pointer-events: none; }
.category-nav .nav-menu a {
  display: flex; align-items: center; gap: 10px; padding: 8px 16px;
  font-size: 14px; line-height: 20px; color: var(--ink); text-decoration: none; transition: background .12s;
}
.category-nav .nav-menu a svg { flex: 0 0 auto; width: 18px; height: 18px; }
.category-nav .nav-menu a:hover, .category-nav .nav-menu a[aria-current="page"] { background: var(--tile); }
.category-nav .nav-menu a:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.category-nav .nav-menu hr { margin: 6px 0; border: 0; border-top: 1px solid var(--line); }
/* The country (js/nav.js): a row like the others, its flag where they have their mark, the country's
   name, and a chevron at the right where the trigger elsewhere says Change, since it opens a choice
   rather than a page. The label over the name is for the trigger over a product's price table. */
.category-nav .nav-country[hidden], .category-nav .nav-menu hr:has(+ .nav-country[hidden]) { display: none; }
.category-nav .nav-country .country-trigger { width: 100%; padding: 8px 16px; gap: 10px; transition: background .12s; }
.category-nav .nav-country .country-trigger:hover { background: var(--tile); }
.category-nav .nav-country .country-trigger:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.category-nav .nav-country .country-flag { width: 18px; justify-content: center; }
.category-nav .nav-country .country-flag :is(svg, img) { width: 18px; height: 13.5px; }
.category-nav .nav-country .country-label { display: none; }
.category-nav .nav-country .country-name { font-size: 14px; font-weight: 400; line-height: 20px; }
.category-nav .nav-country .country-change {
  width: 16px; height: 16px; font-size: 0; color: var(--muted);
  background: currentColor; -webkit-mask: var(--chevron) center / 16px no-repeat; mask: var(--chevron) center / 16px no-repeat;
}
.category-nav .nav-country .country-trigger:hover .country-change { color: var(--ink); text-decoration: none; }
.category-nav { --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 6 6 6-6 6'/%3E%3C/svg%3E"); }
/* The pages of words, About and the 404, hold the bar to the 1240px content as a catalog does
   (catalog.css, .catalog-page): only a finder's bar runs to the window's edges (Patryk, 2026-11-02). */
.affiliates-page .category-nav, .not-found-page .category-nav { padding-inline: max(20px, calc((100% - 1240px) / 2 + 24px)); }
@media (max-width: 700px) { .affiliates-page .category-nav, .not-found-page .category-nav { padding-inline: 10px; } }
/* The button that opens the dialog, here and over a product page's price table (product.css). */
.country-trigger {
  display: flex; align-items: center; gap: 11px; border: 0; background: none; cursor: pointer;
  font: inherit; color: var(--ink); text-align: left;
}
.country-trigger-text { flex: 1; display: flex; flex-direction: column; line-height: 1.25; }
.country-label { font-size: 12px; color: var(--muted); }
.country-name { font-size: 14.5px; font-weight: 600; }
.country-change { font-size: 13px; font-weight: 500; color: var(--muted); }
.country-trigger:hover .country-change { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
/* A flag (js/nav.js, flagOf), in the menu, over a product page's price table and in the dialog. */
.country-flag { flex: 0 0 auto; display: inline-flex; }
/* flag-icons' 4:3 pictures, with a corner and a faint ring so a white flag keeps its edge on white. */
.country-flag :is(svg, img) { display: block; width: 24px; height: 18px; border-radius: 3px; object-fit: cover; box-shadow: 0 0 0 1px oklch(0 0 0 / .1); }
.country-flag svg.flag-globe { box-shadow: none; color: var(--ink); }
.country-flag-code { display: inline-block; min-width: 24px; padding: 1px 4px; border-radius: 3px; background: var(--tile-hover); font-size: 11px; font-weight: 700; text-align: center; }

/* The dialog the button opens (Patryk, 2026-10-29: the select was small and fiddly; 2026-11-02: the
   tiles three to a row ran past its foot). One row per region: its name at the left in the muted
   grey, its countries as small pills that wrap; the first is "Worldwide", International with the
   visitor's own country when no region lists it (no search field since 2026-11-02, Patryk). All of it fits a computer's
   screen without scrolling; a phone takes it as a sheet from the bottom, the region's name over its
   pills, and scrolls. The pill you are on is the ink, as a picked filter is in the catalog. */
.country-dialog {
  width: min(680px, calc(100vw - 32px)); max-height: min(760px, calc(100vh - 48px)); padding: 0;
  border: 0; border-radius: 18px; background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-modal);
  overflow: hidden; flex-direction: column;
}
.country-dialog[open] { display: flex; animation: country-in .2s var(--ease-out); }
.country-dialog::backdrop { background: var(--scrim); }
@keyframes country-in { from { opacity: 0; transform: translateY(8px) scale(.98); } }
.country-head { display: flex; align-items: center; justify-content: space-between; padding: 20px 20px 0 24px; }
.country-head h2 { margin: 0; font-size: 19px; font-weight: 600; letter-spacing: -.01em; }
.country-close { display: grid; place-items: center; width: 32px; height: 32px; border: 0; border-radius: 999px; background: var(--tile); color: var(--muted); cursor: pointer; transition: background .15s, color .15s; }
.country-close:hover { background: var(--tile-hover); color: var(--ink); }
.country-close svg { width: 16px; height: 16px; }
.country-close:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.country-lede { margin: 2px 24px 14px; font-size: 14px; color: var(--muted); }
.country-groups { overflow-y: auto; padding: 4px 24px 22px; overscroll-behavior: contain; }
.country-group { display: grid; grid-template-columns: 148px minmax(0, 1fr); align-items: start; column-gap: 12px; padding: 5px 0; }
.country-group h3 { margin: 0; padding-top: 8px; font-size: 13px; font-weight: 500; line-height: 18px; color: var(--muted); }
.country-grid { display: flex; flex-wrap: wrap; gap: 6px; }
.country-tile {
  display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 13px 0 9px;
  border: 0; border-radius: 999px; background: var(--tile); cursor: pointer;
  font: inherit; font-size: 13.5px; font-weight: 500; color: var(--ink); white-space: nowrap;
  transition: background .12s, color .12s;
}
.country-tile:hover { background: var(--tile-hover); }
.country-tile:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.country-tile .country-flag :is(svg, img) { width: 20px; height: 15px; border-radius: 3px; }
.country-tile .country-flag svg.flag-globe { width: 20px; height: 14px; }
.country-tile[aria-current], .country-tile[aria-current]:hover { background: var(--ink); color: var(--raised); }
.country-tile[aria-current] .country-flag svg.flag-globe { color: var(--raised); }
.country-tile-text { display: flex; align-items: baseline; gap: 6px; }
@media (max-width: 700px) {
  .country-name { font-size: 15.5px; }
  /* A sheet from the screen's foot, 90% of the screen tall (80% until Patryk, 2026-11-04: "a bit
     bigger on the phone"), with pills a finger hits easily: 36px, as tall as a filter row. */
  .country-dialog {
    width: 100%; max-width: none; height: 90vh; height: 90dvh; max-height: none; margin: auto 0 0; border-radius: 14px 14px 0 0;
  }
  .country-dialog[open] { animation-name: country-up; }
  @keyframes country-up { from { transform: translateY(40px); opacity: 0; } }
  .country-head { padding: 16px 14px 0 16px; }
  .country-lede { margin: 2px 16px 10px; font-size: 13.5px; }
  .country-groups { flex: 1; padding: 2px 16px calc(16px + env(safe-area-inset-bottom)); }
  .country-group { grid-template-columns: minmax(0, 1fr); padding: 5px 0; }
  .country-group { padding: 7px 0; }
  .country-group h3 { padding: 0 0 6px; font-size: 13px; }
  .country-grid { gap: 6px; }
  .country-tile { height: 36px; padding: 0 13px 0 10px; gap: 8px; font-size: 14px; }
}
@media (prefers-reduced-motion: reduce) {
  .country-dialog[open] { animation: none; }
}

/* The bar's one shape on every page (scripts/lib/nav.cjs, Patryk 2026-10-28): the logo, the switch in
   the middle, and at the right end the search, the floor's pill (Mouse finder, or Browse all on a finder) and the
   menu. The search is a button beside the menu at every width; it opens the field over the page,
   which blurs under it (.search-layer, js/site-search.js, Patryk 2026-11-01). */
.category-nav .nav-end { grid-column: 3; justify-self: end; display: flex; align-items: center; gap: 8px; }
/* The search's button wears the menu button's look (Patryk, 2026-11-01): a white 32px circle with
   its small shadow, in a ring of the trays' grey drawn by a second shadow, 40px across in all. */
.category-nav .nav-search-btn {
  display: grid; place-items: center; width: 32px; height: 32px; margin: 4px; padding: 0; border: 0; border-radius: 999px;
  background: var(--surface); color: var(--ink); cursor: pointer;
  box-shadow: var(--shadow-raised), 0 0 0 4px oklch(.9 0 0 / .8);
}
.category-nav .nav-search-btn svg { width: 18px; height: 18px; stroke-width: 2.2; }
/* The menu and search buttons answer the pointer as the floor's pill does (2026-11-02: the burger's
   hover only lightened its icon, the search had none). */
.category-nav .nav-burger, .category-nav .nav-search-btn { transition: background .15s, color .15s, box-shadow .2s; }
.category-nav .nav-burger:hover, .category-nav .nav-search-btn:hover { background: var(--tile); color: var(--ink); }
/* The floor's pill (scripts/lib/nav.cjs). In the library and on a page of no floor it is "Mouse
   finder": the dark pill as tall as the trays, the one dark thing in the bar, so the finder is found
   at once from every page. Words only, no icon. */
.category-nav .nav-finder {
  display: inline-flex; align-items: center; height: 40px; padding: 0 20px; border-radius: 999px;
  background: var(--ink); color: var(--raised); font-size: 14px; font-weight: 600; text-decoration: none; white-space: nowrap;
  transition: background .15s, transform .16s cubic-bezier(.22, 1, .36, 1);
}
.category-nav .nav-finder:hover { background: var(--ink-deep); }
.category-nav .nav-finder:active { transform: scale(.97); }
.category-nav .nav-finder:focus-visible { outline: 2px solid var(--muted); outline-offset: 2px; }
/* On a finder the same place holds Browse all, in the same dark pill (Patryk, 2026-11-02: the quiet
   grey one read as disabled), so the bar's right end is one shape on every page. */
.category-nav .nav-browse {
  display: inline-flex; align-items: center; height: 40px; padding: 0 20px; border-radius: 999px;
  background: var(--ink); color: var(--raised); font-size: 14px; font-weight: 600; text-decoration: none; white-space: nowrap;
  transition: background .15s, transform .16s cubic-bezier(.22, 1, .36, 1);
}
.category-nav .nav-browse:hover { background: var(--ink-deep); }
.category-nav .nav-browse:active { transform: scale(.97); }
.category-nav .nav-browse:focus-visible { outline: 2px solid var(--muted); outline-offset: 2px; }

/* Where the page stands in the library, over its title (the audit of 2026-11-01): a product page's
   "All mice / Logitech", the comparison's "All mice". Each is a link back into the catalog, the
   brand to the catalog narrowed to it; the slash between them is a separator, not an arrow. Muted,
   in the brand line's type, so it reads as context and not as a heading. */
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px; margin: 0 0 4px; font-size: 14px; font-weight: 500; line-height: 20px; color: var(--muted); }
.crumbs a { color: inherit; text-decoration: none; }
.crumbs a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.crumbs a:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; border-radius: 3px; }
.crumbs span[aria-hidden] { color: oklch(0 0 0 / .25); }
/* The way back on the compare page: the arrow before the words. */
.crumbs .crumb-back { display: inline-flex; align-items: center; gap: 6px; }
.crumbs .crumb-back svg { flex: 0 0 auto; width: 16px; height: 16px; }

/* The layer: the whole page, bar included, blurred and washed under one white card at the top, the
   field across its head and the list under a hairline (Patryk, 2026-11-01, after a command palette's).
   Before anything is typed the list holds the best-known products (js/site-search.js); each row is
   the product's picture in a 40px grey tile, its name and its spec line under it, the chosen
   row on the grey the list rows use. The field leaves the bar for the
   layer, because the bar is a stacking context of its own and nothing inside it can rise over its
   logo and switch. Without script the field stays in the bar, hidden, and the button does nothing. */
.category-nav .nav-search { display: none; }
.search-layer {
  display: none; position: fixed; inset: 0; z-index: 60; padding: 36px 16px 16px; overflow-y: auto; overscroll-behavior: contain;
  background: oklch(.96 0 0 / .45); -webkit-backdrop-filter: blur(6px) saturate(1.1); backdrop-filter: blur(6px) saturate(1.1);
}
.search-layer.is-open { display: block; animation: search-in .18s cubic-bezier(.22, 1, .36, 1); }
@keyframes search-in { from { opacity: 0; } }
html:has(.search-layer.is-open) { overflow: hidden; }
.nav-search {
  position: relative; width: min(720px, 100%); margin: 0 auto; border-radius: 18px; background: var(--surface); overflow: hidden;
  box-shadow: var(--shadow-pop);
}
/* The field's head lines its glass up with the rows' tiles below it (16px in from the card's edge),
   and the type is a step smaller than a page's body: a palette is read at a glance. */
.nav-search label { display: flex; align-items: center; gap: 12px; height: 54px; padding: 0 16px 0 18px; cursor: text; }
.nav-search label > svg { flex: 0 0 auto; width: 18px; height: 18px; color: var(--ink); }
.nav-search input { flex: 1; min-width: 0; border: 0; background: none; outline: none; font: inherit; font-size: 15px; color: var(--ink); }
/* 16px on a phone, so it does not zoom into the field when it takes the cursor. */
@media (max-width: 700px) { .nav-search input { font-size: 16px; } }
.nav-search input::placeholder { color: var(--muted); }
.nav-search input::-webkit-search-cancel-button { display: none; }
/* The cross that shuts the search (js/site-search.js). */
.nav-search-x {
  flex: 0 0 auto; display: grid; place-items: center; width: 32px; height: 32px; margin-right: -6px; padding: 0; border: 0;
  border-radius: 999px; background: none; color: var(--muted); cursor: pointer; transition: background .15s, color .15s;
}
.nav-search-x:hover { background: var(--tile); color: var(--ink); }
.nav-search-x svg { width: 18px; height: 18px; }
/* Eight rows (56px each, 2px apart), the list's padding and its 1px hairline fit with no scrollbar
   (eight is what the empty field shows); a ninth row scrolls; a thin bar in the
   hairline's grey, not the system's wide one. */
.nav-results {
  max-height: min(calc(100vh - 160px), 479px); overflow-y: auto; padding: 8px 0; border-top: 1px solid var(--line);
  scrollbar-width: thin; scrollbar-color: oklch(0 0 0 / .16) transparent;
}
.nav-results::-webkit-scrollbar { width: 10px; }
.nav-results::-webkit-scrollbar-track { background: transparent; }
.nav-results::-webkit-scrollbar-thumb { border: 3px solid transparent; border-radius: 999px; background: oklch(0 0 0 / .16) padding-box; }
.nav-results::-webkit-scrollbar-thumb:hover { background-color: oklch(0 0 0 / .3); }
.nav-results[hidden] { display: none; }
/* The chosen row's grey runs the card's whole width, as the rows of the result list and the menu do
   (Patryk, 2026-11-02); the tile keeps the field's 16px from the card's edge. */
.nav-results a { display: flex; align-items: center; gap: 14px; padding: 8px 16px; color: var(--ink); text-decoration: none; transition: background .12s; }
.nav-results a + a { margin-top: 2px; }
.nav-results a.is-on { background: var(--tile); }
.sr-ico {
  flex: 0 0 auto; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 9px; overflow: hidden;
  background: var(--tile); transition: background .15s;
}
.nav-results a.is-on .sr-ico { background: var(--tile-hover); }
.sr-ico img { width: 100%; height: 100%; padding: 3px; object-fit: contain; mix-blend-mode: multiply; }
.sr-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; line-height: 1.2; }
.sr-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; font-weight: 600; }
.sr-d { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12.5px; color: var(--muted); }
.sr-none { margin: 0; padding: 14px 16px; font-size: 14px; color: var(--muted); }
/* How many match, at the foot of the list, under the last row drawn. */
.sr-count { margin: 0; padding: 10px 16px 4px; font-size: 12px; color: var(--muted); }
/* Until the index has come: a wheel at the field's right, and grey rows in the shape of the real ones. */
.sr-spin { display: none; flex: 0 0 auto; width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--line); border-top-color: var(--muted); animation: sr-spin .7s linear infinite; }
.nav-search.is-loading .sr-spin { display: block; }
@keyframes sr-spin { to { transform: rotate(360deg); } }
.sr-skel { display: flex; align-items: center; gap: 14px; padding: 8px 16px; }
.sr-skel + .sr-skel { margin-top: 2px; }
.sr-skel > span:first-child { flex: 0 0 40px; height: 40px; border-radius: 9px; }
.sr-skel > span:last-child { flex: 1; display: flex; flex-direction: column; gap: 7px; }
.sr-skel i { display: block; height: 10px; width: 45%; border-radius: 5px; }
.sr-skel i + i { width: 70%; }
.sr-skel > span:first-child, .sr-skel i { background: var(--tile); animation: sr-pulse 1.2s ease-in-out infinite; }
@keyframes sr-pulse { 50% { opacity: .5; } }
@media (prefers-reduced-motion: reduce) { .sr-spin { animation-duration: 2s; } .sr-skel > span:first-child, .sr-skel i { animation: none; } }

/* A phone: the floor's pill goes, as the menu's first entries are Finder and Browse catalog, and a
   catalog has the finder's pill over its list (catalog.css, .c-finder). */
@media (max-width: 700px) {
  .category-nav .nav-finder, .category-nav .nav-browse { display: none; }
  .search-layer { padding: 10px 12px 12px; }
  /* Four 40px marks instead of 44px, so the switch keeps a gap from the search's button on a
     375px screen; the raised pill moves by the narrower step. */
  .category-nav .cats a, .category-nav .nav-indicator { width: 40px; }
  /* Centred in the room between the logo and the buttons, not on the screen, which would put it
     against the search's button. */
  .category-nav { grid-template-columns: auto 1fr auto; column-gap: 8px; }
  .category-nav .cats { justify-self: center; }
  .category-nav .cats:has(> a:nth-of-type(2)[aria-current="page"]) .nav-indicator { transform: translateX(42px); }
  .category-nav .cats:has(> a:nth-of-type(3)[aria-current="page"]) .nav-indicator { transform: translateX(84px); }
  .category-nav .cats:has(> a:nth-of-type(4)[aria-current="page"]) .nav-indicator { transform: translateX(126px); }
}
@media (max-width: 700px) {
  .category-nav { height: 60px; padding: 0 10px; }
  .category-nav .brand { margin-left: 8px; }
  .category-nav .brand-mark { width: 24px; height: 24px; }
  .category-nav .nav-menu a { padding: 11px 16px; font-size: 15.5px; }
  .category-nav .nav-menu a svg { width: 19px; height: 19px; }
  .category-nav .nav-country .country-trigger { padding: 11px 16px; }
  .category-nav .nav-country .country-name { font-size: 15.5px; }
  .category-nav .nav-country .country-flag { width: 19px; }
  .category-nav .nav-country .country-flag :is(svg, img) { width: 19px; height: 14.25px; }
}
/* The search's row in the menu (js/nav.js), a phone's only: a field-like button at the menu's head. */
.nav-menu-search { display: none; }
/* A phone (Patryk, 2026-11-02): the switch in the middle of the screen, the search inside the menu,
   and the menu a full-width sheet under the bar rather than a little card at its corner. */
@media (max-width: 700px) {
  .category-nav { grid-template-columns: 1fr auto 1fr; }
  .category-nav .nav-search-btn { display: none; }
  /* A blur makes its tray the containing block of anything fixed inside it, so the sheet would be the
     38px tray's width; the menu's tray goes without (it is alone and small, the blur unseen). */
  .category-nav .nav-side { -webkit-backdrop-filter: none; backdrop-filter: none; }
  /* The menu is the whole screen under the bar (Patryk, 2026-11-02), the switch gone from the bar
     while it is open and the button a cross. */
  .category-nav .nav-menu {
    position: fixed; top: 60px; left: 0; right: 0; bottom: 0; width: auto; max-width: none;
    max-height: none; overflow-y: auto; overscroll-behavior: contain; padding: 8px 0 calc(16px + env(safe-area-inset-bottom));
    border-radius: 0; box-shadow: none; transform-origin: top center;
  }
  .menu-open .category-nav { background: var(--surface); }
  .menu-open .category-nav .cats { visibility: hidden; }
  .menu-open, .menu-open body { overflow: hidden; }
  /* The compare tray stands over the page at the screen's foot, where the menu has the country. */
  .menu-open .cmp-tray { display: none; }
  /* The bar goes up while the page is read down (js/nav.js). */
  .category-nav { transition: transform .28s cubic-bezier(.22, 1, .36, 1); }
  .nav-tucked .category-nav { transform: translateY(-100%); }
  .category-nav .nav-menu[hidden] { transform: translateY(-8px); }
  /* Larger rows, type and marks on the whole-screen menu (Patryk, 2026-11-02). */
  .category-nav .nav-menu a { gap: 14px; padding: 14px 22px; font-size: 18px; line-height: 24px; }
  .category-nav .nav-menu a svg { width: 22px; height: 22px; }
  /* The country pinned to the menu's foot, a field with a hairline ring and no fill, its name and a
     chevron (Patryk, 2026-11-02); the rule over it goes, the field is edge enough. */
  .category-nav .nav-menu hr:has(+ .nav-country) { display: none; }
  .category-nav .nav-country { margin: auto 16px 0; padding-top: 16px; }
  .category-nav .nav-country .country-trigger {
    height: 52px; padding: 0 14px; gap: 12px; border: 1px solid var(--line); border-radius: 12px; background: none;
  }
  .category-nav .nav-country .country-trigger:hover { background: none; }
  .category-nav .nav-country .country-name { font-size: 16px; }
  .category-nav .nav-country .country-flag { width: 24px; }
  .category-nav .nav-country .country-flag :is(svg, img) { width: 24px; height: 18px; border-radius: 3px; }
  .category-nav .nav-country .country-change { width: 18px; height: 18px; transform: rotate(90deg); }
  .nav-menu-search {
    display: flex; align-items: center; gap: 10px; margin: 4px 16px 10px; height: 46px; padding: 0 14px;
    border: 0; border-radius: 12px; background: var(--tile); color: var(--muted); font: inherit; font-size: 16px; text-align: left; cursor: pointer;
  }
  .nav-menu-search svg { flex: 0 0 auto; width: 18px; height: 18px; }
}
@media (prefers-reduced-motion: reduce) {
  .category-nav .nav-menu, .category-nav .cats a, .category-nav .nav-burger, .category-nav .nav-finder, .category-nav .nav-browse { transition: none; }
  .search-layer.is-open { animation: none; }
}

/* Moving between Mice, Keyboards, Mousepads and About used to be a hard cut: four separate pages,
   each blank until its own scene drew. A cross-document view transition fades one page into the
   next instead. Every page loads this file, so all four opt in here; a browser without support
   (Firefox) keeps the plain cut. The bar has its own name so it stays where it is while the page
   under it changes: only its icons cross-fade, which is the active one turning black. The old page
   holds still underneath while the new one fades in over it: had both faded at once, the empty
   canvas would show through halfway, a flash of the bare background. Reduced motion keeps the cut. */
@view-transition { navigation: auto; }
.category-nav { view-transition-name: category-nav; }
/* The logo and the menu move on their own, so between a finder (the window's edges) and a catalog or
   a product page (the content's edges, catalog.css) they slide to their place instead of jumping. */
.category-nav .brand { view-transition-name: nav-brand; }
.category-nav .nav-side { view-transition-name: nav-side; }
::view-transition-group(nav-brand), ::view-transition-group(nav-side) { animation-duration: .35s; animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
::view-transition-old(root) { animation: none; }
::view-transition-new(root) { animation: 260ms cubic-bezier(.2, 0, 0, 1) both page-in; }
::view-transition-group(nav-indicator) { animation-duration: .35s; animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
::view-transition-group(nav-cat-1), ::view-transition-group(nav-cat-2), ::view-transition-group(nav-cat-3), ::view-transition-group(nav-cat-4) { animation-duration: .35s; }
@keyframes page-in { from { opacity: 0; transform: translateY(8px); } }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* The search's rows sit in a scrolling list, which would clip a ring outside them. */
.nav-results a:focus-visible { outline-offset: -2px; }
