/* Site-specific tweaks on top of Pico. Fonts and spacing: Pico variables; the theme
   colors below are ours. */
/* Pico scales the base font up to 125% on wide screens; keep it at 100%. */
:root {
  --pico-font-size: 100%;
}
/* The theme is pinned light in base.html. This selector matches the specificity of
   Pico's own light block (`:root:not([data-theme=dark])`) and wins on load order. */
:root[data-theme="light"] {
  --pico-color: #111418; /* near-black; Pico ships a gray #373c44 */
  /* One ink for every heading. Pico ramps h1-h6 from #2d3138 to #646b79, which next
     to near-black body text reads as faded rather than as hierarchy. */
  --pico-h1-color: var(--pico-color);
  --pico-h2-color: var(--pico-color);
  --pico-h3-color: var(--pico-color);
  --pico-h4-color: var(--pico-color);
  --pico-h5-color: var(--pico-color);
  --pico-h6-color: var(--pico-color);
  --pico-muted-color: #565959; /* 7:1 on white */
  --card-border: #cfd5e2; /* 1.9:1 on white: a visible edge, not a line to read */
}
/* Links read as text: a catalog of blue underlined links reads as a document, not a
   shop. They take the blue and an underline on hover and on keyboard focus.
   Pico styles links through :where() and :is(), which set custom properties at zero
   specificity. These rules set color and text-decoration directly, so they also replace
   Pico's hover and aria-current treatment; both are restored below. */
a:not([role="button"]) {
  color: inherit;
  text-decoration: none;
}
/* :active too: a tap is the only one of these a phone can do. The blue is
   --pico-primary, not --pico-primary-hover, which is 2.4:1 against the body text and so
   reads as "slightly less black" rather than as a color. */
a:not([role="button"]):hover,
a:not([role="button"]):focus-visible,
a:not([role="button"]):active,
nav button.linklike:hover,
nav button.linklike:focus-visible,
nav button.linklike:active {
  color: var(--pico-primary);
  text-decoration: underline;
}
/* A card's title sets its own heading color, so the rule above does not reach it. */
.products article a:hover h3,
.products article a:focus-visible h3,
.products article a:active h3 {
  color: var(--pico-primary);
}
/* Running text is the exception: inside a sentence nothing but the blue and the
   underline says a link is a link, and a phone has no hover. */
.prose a:not([role="button"]) {
  color: var(--pico-primary);
  text-decoration: underline;
}
/* Ties with the hover rule above on specificity, so it needs its own hover state. */
.prose a:not([role="button"]):hover,
.prose a:not([role="button"]):focus-visible,
.prose a:not([role="button"]):active {
  color: var(--pico-primary-hover);
}
/* Which category the catalogue is showing. Weight, not color, so it still reads next to
   a hovered sibling. */
a[aria-current]:not([aria-current="false"]) {
  font-weight: bold;
}
body > header nav {
  border-bottom: 1px solid var(--pico-muted-border-color);
  margin-bottom: var(--pico-block-spacing-vertical);
}
/* More items than fit a phone. Let them wrap as whole labels rather than squeeze each
   one onto two lines and push the last off the edge. */
body > header nav,
body > header nav ul {
  flex-wrap: wrap;
}
body > header nav li {
  white-space: nowrap;
}
form.lang {
  display: inline-flex;
  gap: 0.4rem;
  align-items: center;
  margin: 0;
}
/* Logging out and switching language have to be POSTs, so they are buttons; in the
   header they read as the links beside them. width: auto beats Pico's
   `button[type=submit] { width: 100% }`; the padding is left to Pico's own `nav li
   button` rule, which matches what `nav li a` gets, so the hit box does too. */
nav button.linklike {
  width: auto;
  margin: 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
nav form.lang {
  font-size: 0.8rem;
}
nav form.lang span {
  font-weight: bold;
}
/* The second row: the shop's own sections, under the account links. The two rows sit
   against each other, so the first one drops the padding below its links. Pico puts that
   padding on the li, not on the nav. */
nav.utilities > ul > li {
  padding-bottom: 0;
}
nav.menubar {
  border-bottom: 1px solid var(--pico-muted-border-color);
}
/* How many things are in the cart, beside the word rather than over it: a badge on a
   text link has nothing to sit on. The brackets are drawn rather than written: they are
   punctuation, so nothing should select or copy them with the number. */
nav.utilities .cart-count {
  font-weight: bold;
}
nav.utilities .cart-count::before {
  content: "(";
}
nav.utilities .cart-count::after {
  content: ")";
}
/* The legal links, quiet at the bottom of every page. */
body > footer {
  border-top: 1px solid var(--pico-muted-border-color);
  margin-top: var(--pico-block-spacing-vertical);
  font-size: 0.9rem;
}
body > footer p {
  margin-bottom: 0.25rem;
}
body > footer nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.5rem;
  margin: 0 0 0.25rem;
  padding: 0;
  list-style: none;
}
/* Decoration, drawn rather than written into the markup. The empty alt text keeps a
   screen reader from announcing it between every link; generated content is read out
   otherwise. A browser without alt-text support drops the declaration and shows no
   separator, which is the right way to lose it.
   The list's gap only falls on the dot's left, hence the margin on its right. */
body > footer nav li + li::before {
  content: "·" / "";
  margin-right: 0.5rem;
  color: var(--pico-muted-color);
}
/* The classless build has no dropdown either, and it styles details as an accordion,
   which in a nav is an indented block that pushes the row apart. Undone here.
   A panel closes on a second click on its summary; js/menu.js adds what <details> will
   not do for itself, closing it on a click elsewhere, on Escape, and when the focus
   leaves it. */
nav details.dropdown {
  position: relative;
  margin: 0;
}
nav details.dropdown > summary {
  color: inherit;
  padding: var(--pico-nav-link-spacing-vertical) var(--pico-nav-link-spacing-horizontal);
}
/* Pico draws an accordion chevron here. A menu bar needs no arrow. */
nav details.dropdown > summary::after {
  display: none;
}
/* Pico colors an open accordion's summary through
   `details[open]>summary:not([role]):not(:focus)`, which is (0,3,2); this has to outrank
   it, hence the :not([role]). */
nav details.dropdown[open] > summary:not([role]) {
  margin-bottom: 0;
  color: inherit;
}
nav details.dropdown > summary:hover,
nav details.dropdown > summary:focus-visible {
  color: var(--pico-primary);
}
nav details.dropdown > ul {
  /* Pico's nav ul is a flex row, which the panel would otherwise inherit. Out of flow
     is also what lets js/menu.js close a menu on pointerdown: the page below does not
     move between the press and the click, so a tap lands on what it was aimed at. */
  display: block;
  position: absolute;
  z-index: 1;
  min-width: 12rem;
  margin: 0;
  padding: 0.25rem 0;
  list-style: none;
  background: var(--pico-card-background-color);
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
  box-shadow: 0 2px 6px rgb(0 0 0 / 12%);
}
nav details.dropdown > ul li {
  display: block;
  margin: 0;
  padding: 0;
}
nav details.dropdown > ul a {
  display: block;
  padding: 0.4rem 0.8rem;
}
/* The classless Pico build has no .grid: one column, side by side from 768px. */
.grid {
  display: grid;
  gap: var(--pico-spacing);
}
@media (min-width: 768px) {
  .grid {
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
  }
}
/* Wraps because Pico already makes nav lists flex. margin-block, not the shorthand:
   Pico gives the first nav list a negative left margin that cancels the padding below,
   and zeroing it would pull the column out of line with the heading. */
.catalog .filters ul {
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  margin-block: 0 var(--pico-spacing);
}
/* Pico pads nav items by 1rem vertically, which swamps the row gap above. */
.catalog .filters li {
  padding-block: 0;
  overflow-wrap: break-word; /* one long category name must not push into the grid */
}
/* The filter beside the grid on a wide screen, a wrapped row above it on a narrow one.
   Flex rather than a grid column, so a catalogue with no categories to filter by still
   gives the products the whole width. The wrap and gap above are for the narrow case;
   here the list becomes a column. */
@media (min-width: 768px) {
  .catalog {
    display: flex;
    gap: var(--pico-spacing);
  }
  /* Fixed rather than sized by its contents, which would move the grid from page to
     page as the longest category name changed. */
  .catalog .filters {
    flex: 0 0 13rem;
  }
  .catalog .results {
    flex: 1;
    min-width: 0; /* a flex child refuses to shrink below its content without this */
  }
  .catalog .filters ul {
    display: block;
  }
  /* Pico makes nav items inline-block; in a column they are rows. */
  .catalog .filters li {
    display: block;
    margin-block-end: 0.5rem;
  }
}
.products {
  display: grid;
  gap: var(--pico-spacing);
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
}
/* Pico draws a card's inner separators with this token too, so setting it here keeps the
   line above the footer in step with the outer edge. */
.products article {
  position: relative;
  margin: 0;
  --pico-card-border-color: var(--card-border);
  border: var(--pico-border-width) solid var(--pico-card-border-color);
  transition: border-color var(--pico-transition);
}
/* The blue the rest of the shop uses on hover, one step from the resting border rather
   than the leap to near-black that --pico-muted-color would be. */
.products article:hover,
.products article:focus-within {
  --pico-card-border-color: var(--pico-primary);
}
.products article > footer strong {
  font-size: 1.1rem;
}
.products article > footer small {
  display: block;
  color: var(--pico-muted-color);
}
/* The anchor wraps only the image and the title; this stretches the target over the whole
   card, which is what the hover suggests, and leaves the title as its accessible name.
   The text underneath cannot be selected, and anything interactive added to a card later
   needs position: relative to come back above it. */
.products article > a::after {
  content: "";
  position: absolute;
  inset: 0;
}
.products article img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}
.products article h3 {
  font-size: 1.1rem;
  margin-top: 0.5rem;
}
article.product img {
  width: 100%;
}
article.product .price {
  font-size: 1.5rem;
}
