/* ==========================================================================
   Osevaro mockups: SHOP / CATEGORY page only.
   Built on ds/osevaro.css (never edited). Everything here is page-local.
   Rules kept: text never on paint or photos, one shell width, washes only
   in the kit's stacks, nothing under 13px, motion only under html.motion-ok.
   App fix round (10 Oct): no pet behind any card (the corgi stands in front
   of "Good to know"); Filter and Sort only above 12 products (APP-SPEC 8).
   Fix round (10 Oct): chips, filter pills, select, radio, tick, fit line,
   hover-pet shadow and narrow-tag rules now come from the design system, so
   their page copies are gone. The photo hero, the category tiles and the
   filter / sort bar are gone too: the products start on the first screen.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Page state: category (html[data-cat]) and view (html[data-view])
   set by pages/shop.js before first paint. CSS does the hiding.
   -------------------------------------------------------------------------- */
html:not([data-cat="all"]) [data-when-cat="all"],
html:not([data-cat="beds"]) [data-when-cat="beds"],
html:not([data-cat="hideaways"]) [data-when-cat="hideaways"],
html:not([data-cat="carriers"]) [data-when-cat="carriers"],
html[data-cat="all"] [data-unless-cat="all"],
html:not([data-view="empty"]) [data-when-view="empty"],
html[data-view="empty"] [data-when-view="results"] { display: none !important; }

/* Space between the page head and the product grid. App fix round: no pet
   peeks from behind a card any more (the corgi standing in front of "Good to
   know" is the page's pet), so this is just a gap now. */
:root { --shop-grid-top: clamp(28px, 2.8vw, 40px); }

/* --------------------------------------------------------------------------
   Breadcrumb: a bigger tap target, same look (DS request filed).
   32px tall on desktop, 44px on phones; the negative margins keep the
   visible spacing exactly as the design system draws it.
   -------------------------------------------------------------------------- */
.crumbs a {
  display: inline-flex; align-items: center;
  min-height: 32px; margin-block: -5px;
  padding-inline: 4px; margin-inline: -4px;
}
@media (max-width: 899.98px) {
  .crumbs a { min-height: 44px; margin-block: -11px; padding-inline: 6px; margin-inline: -6px; }
}

/* --------------------------------------------------------------------------
   1. Compact header: eyebrow, H1, one line, one row of category chips.
   Calm, 1180px+: the chips sit at the right end of the title row.
   Rich, 900px+: the page's one nest takes the right end instead.
   -------------------------------------------------------------------------- */
.shop-head { padding-top: clamp(14px, 1.8vw, 24px); padding-bottom: 0; }
.shop-head__row {
  display: grid; grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "copy" "chips";
  gap: 18px 48px;
  margin-top: clamp(14px, 1.6vw, 22px);
}
.shop-head__copy { grid-area: copy; display: flex; flex-direction: column; align-items: flex-start; gap: 12px; min-width: 0; }
.shop-chips { grid-area: chips; align-self: end; }
.shop-title { max-width: 22ch; }
.shop-nest { grid-area: nest; display: none; }

@media (min-width: 1180px) {
  html:not([data-wash="rich"]) .shop-head__row {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "copy chips";
    align-items: end;
  }
  html:not([data-wash="rich"]) .shop-chips { justify-content: flex-end; padding-bottom: 2px; }
}
@media (min-width: 900px) {
  html[data-wash="rich"] .shop-head__row {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "copy nest" "chips nest";
    align-items: end;
  }
  html[data-wash="rich"] .shop-nest {
    display: block; --nest-w: clamp(190px, 16vw, 250px);
    width: var(--nest-w);   /* an auto grid track gives a % width nothing to resolve against */
    align-self: end; margin-bottom: -6px;
  }
}
@media (max-width: 599.98px) {
  .shop-head__copy { gap: 10px; }
  .shop-head__row { gap: 14px; }
  /* Phones: one row of chips you can swipe, running out to the screen edge
     so the last one visibly continues; it never moves on its own. */
  .shop-chips {
    flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
    margin-inline: calc(-1 * var(--gutter)); padding: 4px var(--gutter);
    margin-block: -4px; scroll-padding-inline: var(--gutter);
  }
  .shop-chips::-webkit-scrollbar { display: none; }
  .shop-chips > .chip { flex: none; }
}

/* --------------------------------------------------------------------------
   2. Products: search line (search results only), grid, "More arriving soon"
   -------------------------------------------------------------------------- */
.shop-results { padding-bottom: clamp(96px, 8vw, 112px); }   /* room for the corgi on the card below */
.shop-grid { margin-top: var(--shop-grid-top); }
html[data-view="empty"] .shop-results > .sec-head { margin-bottom: 0; }

.shop-q { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin-top: clamp(18px, 2vw, 24px); }
.shop-q[hidden] { display: none; }
.shop-q__text { font-size: 16px; color: var(--ink-soft); }
.shop-q__text strong { color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }
.shop-q__clear { min-height: 44px; }   /* the whole pill, × included, is a 44px target */

/* Phones (2 columns): an odd count opens with one wide card, so rows stay full */
@media (max-width: 699.98px) {
  .shop-grid > .shop-item.is-wide { grid-column: 1 / -1; }
  .shop-grid > .shop-item.is-wide .pcard__media { aspect-ratio: 3 / 2; }
  .shop-grid > .shop-item.is-wide .pcard__media img { object-position: 50% 58%; }
  .shop-grid > .shop-item.is-wide .pcard__body { padding-inline: 8px; }
  .shop-grid > .shop-item.is-wide .pcard__title { font-size: 18px; }
  .shop-grid > .shop-item.is-wide .pcard__price { font-size: 22px; }
}

/* More arriving soon: a plain card. It fills the rest of the last row, or
   takes a row of its own (.is-row, set by shop.js). No pet behind it. */
.arrive-cell { min-width: 0; }
@media (max-width: 1179.98px) {
  .arrive-cell:not(.js-laid) { grid-column: 1 / -1; }
}
.arrive {
  position: relative; flex: 1;
  display: flex; flex-direction: column;
  container-type: inline-size;
  padding: 10px 10px 16px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card);
}
.arrive__inner { flex: 1; display: flex; flex-direction: column; gap: 14px; }
.arrive__art { aspect-ratio: 4 / 3; }
.arrive__body { flex: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; padding: 0 6px; }
.arrive__title {
  font-family: var(--font-display); font-weight: 600; font-variation-settings: 'SOFT' 50;
  font-size: 22px; line-height: 1.2; letter-spacing: -.01em; text-wrap: balance;
}
.arrive__text { font-size: 15px; line-height: 1.5; color: var(--ink-soft); max-width: var(--measure); }
.arrive__btn { margin-top: auto; white-space: normal; text-wrap: balance; max-width: 100%; }
@container (max-width: 559.98px) {
  .arrive-cell.is-row .arrive__art { aspect-ratio: 16 / 9; }
}
@container (min-width: 560px) {
  .arrive__inner { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: clamp(20px, 4cqi, 40px); align-items: center; }
  .arrive__art { aspect-ratio: 4 / 3; max-height: 300px; width: 100%; }
  .arrive__body { justify-content: center; padding: 10px 14px 6px 0; gap: 10px; }
  .arrive__title { font-size: 28px; }
  .arrive__text { font-size: 16px; }
  .arrive__btn { margin-top: 6px; }
}

/* --------------------------------------------------------------------------
   Empty search result (review state): real photo beside the words
   -------------------------------------------------------------------------- */
.nores-sec { padding-top: clamp(14px, 2vw, 28px) !important; padding-bottom: clamp(48px, 5.6vw, 80px); }
.nores {
  display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 6fr);
  gap: clamp(28px, 5vw, 84px); align-items: center;
  margin-top: clamp(14px, 2vw, 28px);
}
.nores__photo { max-width: 520px; }
.nores__photo .framed__photo { aspect-ratio: 1; object-position: 50% 42%; }
.nores__copy { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; min-width: 0; }
.nores__title { max-width: 20ch; overflow-wrap: anywhere; }
.nores__q { white-space: nowrap; }
.nores__joke { font-family: var(--font-display); font-variation-settings: 'SOFT' 50; font-weight: 500; font-style: italic; color: var(--ink); font-size: clamp(18px, .5vw + 14px, 21px); }
.nores__text { max-width: var(--measure); color: var(--ink-soft); }
.nores__search { display: flex; flex-direction: column; gap: 6px; width: 100%; max-width: 520px; margin-top: 4px; }
.nores__row { display: flex; gap: 8px; }
.nores__field { position: relative; flex: 1; min-width: 0; }
.nores__field .ic { position: absolute; left: 16px; top: 50%; margin-top: -11px; color: var(--ink-soft); pointer-events: none; }
.nores__field .input { padding-left: 46px; }
.nores__field .input::-webkit-search-cancel-button { -webkit-appearance: none; }
.nores__ask { max-width: var(--measure); }
@media (max-width: 899.98px) {
  .nores { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  .nores__photo { max-width: none; }
  .nores__photo .framed__photo { aspect-ratio: 4 / 3; object-position: 50% 38%; }
}
@media (max-width: 420px) {
  .nores__row { flex-direction: column; }
}

/* --------------------------------------------------------------------------
   3. Good to know (true facts; unconfirmed ones carry an owner note)
   -------------------------------------------------------------------------- */
/* Round 2 (owner): the corgi stands ON the card's top edge, in front of it (paws
   4px onto the edge, contact shadow, opaque front file in light mode), so the
   section keeps room above the card for all of it. */
:root { --know-pet-w: clamp(96px, 8vw, 116px); }
.shop-know { padding-bottom: 0; }
.section.shop-know { padding-top: max(0px, calc(var(--know-pet-w) * .994 * .971 + 12px - var(--section))); }
.know {
  padding: clamp(36px, 3vw, 40px) clamp(22px, 3vw, 40px) clamp(22px, 3vw, 40px);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card);
}
.know__list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px clamp(24px, 3vw, 48px); list-style: none; }
.know__item { display: flex; gap: 16px; align-items: flex-start; }
.know__item .h3 { font-size: 18px; }
.know__text { margin-top: 4px; font-size: 15px; line-height: 1.55; color: var(--ink-soft); max-width: 40ch; }
@media (max-width: 899.98px) {
  .know__list { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .know .wash-icon--md { --wash-size: 60px; }
}

/* ==========================================================================
   THE APP (round 2, APP-SPEC 10.3). Phones (under 768px) and the installed
   app: html[data-shell="app"], set by ds/app.js before the first paint.
   Everything below is scoped to the app shell, so desktop and the 768-899px
   site layout stay exactly as approved. ds/app.css draws the app bar, the
   docked tabs, the sheets, the sticky chip rail, the compact cards and the
   end cap; this part only arranges the shop screen with them.
   ========================================================================== */

/* App-only pieces never show on the website */
html:not([data-shell="app"]) [data-app-only] { display: none !important; }

/* Filter sheet groups (same as the components sheet; DS request filed) */
.filterset { display: grid; gap: 12px; min-width: 0; margin: 0; padding: 0; border: 0; }
.filterset__legend { margin-bottom: 12px; padding: 0; color: var(--ink-soft); }
.filters__foot { display: flex; align-items: center; gap: 10px; }
.filters__foot .btn--primary { flex: 1; }

/* Sort sheet: three rows, a tick on the current one; a tap sorts and closes */
.shop-sortrow {
  grid-template-columns: minmax(0, 1fr) 22px; width: 100%;
  border: 0; background: none; font: inherit; text-align: left; cursor: pointer;
}
.shop-sortrow .crow__tick { visibility: hidden; }
.shop-sortrow[aria-pressed="true"] .crow__tick { visibility: visible; }
.shop-sortrow[aria-pressed="true"] .crow__name { font-weight: 750; }

/* ---- 1. The website's page head steps aside: the app bar carries the title.
   The H1 stays for screen readers (the page keeps exactly one). */
html[data-shell="app"] .section.shop-head { padding: 0; }
html[data-shell="app"] .shop-head :is(.crumbs, .eyebrow, .shop-lead, .shop-chips, .shop-nest) { display: none; }
html[data-shell="app"] .shop-head__row { display: block; margin: 0; }
html[data-shell="app"] .shop-title {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* App bar: Back | "All products" (opens Categories) | Search, Filter.
   Centred while there is room; on narrow phones the side that only holds the
   back arrow gives its spare width to the title instead of cutting it short. */
html[data-shell="app"] .appbar__row { grid-template-columns: minmax(44px, 1fr) minmax(0, auto) minmax(92px, 1fr); }
/* Up to 12 products the end side holds Search alone (no Filter), so it needs only 44px */
html[data-shell="app"]:not(.shop-tools-on) .appbar__row { grid-template-columns: minmax(44px, 1fr) minmax(0, auto) minmax(44px, 1fr); }
@media (max-width: 374.98px) {
  html[data-shell="app"] .appbar__row { gap: 4px; }
  html[data-shell="app"] .appbar__titlebtn { padding-inline: 6px 4px; }
}
/* While searching the title is plain words, "Results for “bed”" (no chevron, no
   sheet): the field under the bar is where the search changes */
.shop-qtitle {
  grid-column: 2; min-width: 0; margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center;
  font-family: var(--font-body); font-size: 17px; font-weight: 650; line-height: 1.25; color: var(--ink);
}

/* ---- 2. Under the app bar: the chips (browsing) or the search you made.
   Both stay put as you scroll; once stuck they join the bar (card colour, one
   hairline under the pair instead of one under each). */
html[data-shell="app"] .shop-rail {
  margin-inline: 0;                                  /* a direct child of main: already edge to edge */
  padding-block: 6px 10px;
}
html[data-shell="app"] .shop-qbar {
  position: sticky; top: calc(var(--appbar-h) + var(--safe-t)); z-index: 40;
  padding: 4px max(var(--gutter), var(--safe-x)) 12px; background: var(--paper);
}
html[data-shell="app"] :is(.shop-rail, .shop-qbar).is-stuck { background: var(--card); box-shadow: 0 1px 0 var(--line); }
html[data-shell="app"].shop-bar-stuck .appbar.is-lifted { border-bottom-color: transparent; }
html.motion-ok[data-shell="app"] :is(.shop-rail, .shop-qbar) { transition: background-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease); }
html[data-shell="app"] .shop-qbar__in { position: relative; width: var(--shell); max-width: 100%; margin-inline: auto; }
html[data-shell="app"] .shop-qbar .qbtn { padding-right: 50px; }
.shop-qbar__clear { position: absolute; top: 2px; right: 2px; }
html[data-shell="app"][data-view="empty"] .shop-qbar__clear { display: none; }   /* nothing to clear back to: the chips below do that */
html[data-shell="app"][data-view="empty"] .shop-rail,
html[data-shell="app"].shop-searching .shop-rail { display: none; }

/* ---- 3. Count, sort, filters in use, the closed-ordering note.
   APP-SPEC 8: the Filter button and Sort only show above 12 products
   (html.shop-tools-on, set by shop.js); until then the chips are enough. */
html:not(.shop-tools-on) :is(.shop-filterbtn, .shop-tools__sort) { display: none !important; }
html:not(.shop-tools-on) .shop-tools { min-height: 0; margin: 4px 0 12px; }   /* just the count line: no 44px row to hold */
html[data-shell="app"] .shop-results { padding-top: 6px; padding-bottom: 0; }
html[data-shell="app"] .shop-q { display: none; }
.shop-tools { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 44px; margin-bottom: 10px; }
.shop-tools__count { min-width: 0; font-size: 15px; line-height: 1.35; color: var(--ink-soft); }
.shop-tools__count strong { color: var(--ink); font-weight: 700; font-variant-numeric: lining-nums tabular-nums; }
.shop-tools__sort { flex: none; gap: 4px; margin-right: -10px; padding-inline: 10px; }
.shop-tools__sort .ic { --ic-size: 18px; color: var(--ink-soft); }
.shop-pills { --cluster-gap: 8px; margin: -2px 0 14px; padding: 0; list-style: none; }
.shop-pills .fpill { min-height: 44px; }
.shop-note { margin-bottom: 16px; }
html[data-shell="app"][data-view="empty"] .shop-results > .sec-head { margin-bottom: 18px; }

/* ---- 4. The grid: two columns of compact cards (ds/app.css), no wide first
   card; "More arriving soon" fills the last slot, or takes a row of its own */
html[data-shell="app"] .shop-grid { margin-top: 0; }
html[data-shell="app"] .shop-grid > .shop-item.is-wide { grid-column: auto; }
html[data-shell="app"] .shop-grid > .shop-item .pcard__media { aspect-ratio: 1; }
html[data-shell="app"] .shop-grid > .shop-item .pcard__media img { object-position: 50% 50%; }
html[data-shell="app"] .shop-grid > .shop-item .pcard__body { padding-inline: 4px; }
html[data-shell="app"] .shop-grid > .shop-item .pcard__title { font-size: 15px; }
html[data-shell="app"] .shop-grid > .shop-item .pcard__price { font-size: 18px; }
html[data-shell="app"] .shop-skel { margin-top: 0; }

.shop-none { grid-column: 1 / -1; }
.shop-none__card {
  display: grid; justify-items: start; gap: 8px;
  padding: 20px; border: 1px solid var(--line); border-radius: 20px; background: var(--card);
}
.shop-none__text { font-size: 15px; line-height: 1.5; color: var(--ink-soft); max-width: 36ch; }
.shop-none .btn { margin-top: 6px; }

/* More arriving soon, one slot wide: the art, the title and the button */
html[data-shell="app"] .arrive-cell.is-compact,
html[data-shell="app"] .arrive-cell.is-row { margin-top: 0; }
html[data-shell="app"] .arrive { padding: 6px 6px 12px; border-radius: 20px; }
html[data-shell="app"] .arrive__art { border-radius: 15px; }
html[data-shell="app"] .arrive-cell.is-compact .arrive__inner { gap: 10px; }
html[data-shell="app"] .arrive-cell.is-compact .arrive__art { aspect-ratio: 1; }
html[data-shell="app"] .arrive-cell.is-compact .arrive__body { gap: 10px; padding: 0 4px; }
html[data-shell="app"] .arrive-cell.is-compact .arrive__title { font-size: 17px; line-height: 1.25; }
html[data-shell="app"] .arrive-cell.is-compact .arrive__text,
html[data-shell="app"] .arrive-cell.is-compact .arrive__btn { display: none; }
.arrive__link { display: none; }
html[data-shell="app"] .arrive-cell.is-compact .arrive__link {
  display: block; margin-top: auto;
  font-size: 15px; font-weight: 650; line-height: 1.35; color: var(--ink);
  text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: .2em;
}
html[data-shell="app"] .arrive-cell.is-compact .arrive__link .ic { display: none; }   /* the words fit on one line on most phones */
html[data-shell="app"] .arrive-cell.is-compact .arrive__link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
html[data-shell="app"] .arrive-cell.is-compact .arrive__link:focus-visible { outline: none; }
html[data-shell="app"] .arrive-cell.is-compact .arrive:has(.arrive__link:focus-visible) { outline: 3px solid var(--focus); outline-offset: 2px; }
html.motion-ok[data-shell="app"] .arrive-cell.is-compact .arrive:active { transform: scale(.97); transition: transform var(--t-press) var(--ease); }
/* a row of its own (an even number of products): art beside the words */
html[data-shell="app"] .arrive-cell.is-row { margin-top: 0; }
html[data-shell="app"] .arrive-cell.is-row .arrive__inner { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 14px; align-items: center; }
html[data-shell="app"] .arrive-cell.is-row .arrive__art { aspect-ratio: 1; }
html[data-shell="app"] .arrive-cell.is-row .arrive__body { padding: 4px 6px 0 0; gap: 8px; }
html[data-shell="app"] .arrive-cell.is-row .arrive__title { font-size: 20px; }
html[data-shell="app"] .arrive-cell.is-row .arrive__btn { margin-top: 4px; }
html[data-shell="app"] .arrive-cell.is-row .arrive__btn .ic { display: none; }   /* keeps "Suggest something" on one line beside the art */

/* No results (?view=empty): the search you made sits under the app bar
   (tap it to search again), so the inline form and the crumbs step aside */
html[data-shell="app"] .nores-sec { padding-top: 8px !important; padding-bottom: 40px; }
html[data-shell="app"] .nores-sec > .crumbs,
html[data-shell="app"] .nores__search { display: none; }
html[data-shell="app"] .nores { margin-top: 0; gap: 18px; }
html[data-shell="app"] .nores__photo .framed__photo { aspect-ratio: 16 / 10; border-radius: 20px; }
html[data-shell="app"] .nores__title { font-size: 26px; }

/* ---- 5. Good to know: one grouped card, "Delivery and returns" first, and
   the corgi with the ball standing ON its top edge, in front of it (paws 4px
   onto the edge, contact shadow under them, opaque front file in light mode).
   The heading sits on the left of the room kept above the card. */
html[data-shell="app"] { --know-pet-w: 104px; }
html[data-shell="app"] .section.shop-know { padding-top: calc(var(--know-pet-w) * .994 * .971 + 18px); }
html[data-shell="app"] .know { padding: 2px 16px; border-radius: 20px; }
html[data-shell="app"] .know .pet--perch { --pet-inset: 18px; }
html[data-shell="app"] .know__title.sr-only {
  position: absolute !important; left: 2px; bottom: calc(100% + 14px); width: auto; height: auto; margin: 0;
  overflow: visible; clip: auto; white-space: nowrap;
  font-family: var(--font-display); font-weight: 600; font-variation-settings: 'SOFT' 50;
  font-size: 22px; line-height: 1.2; letter-spacing: -.01em; color: var(--ink);
}
html[data-shell="app"] .know__more { display: none; }
html[data-shell="app"] .know__list { gap: 0; }
html[data-shell="app"] .know__item { gap: 14px; padding: 16px 0; }
html[data-shell="app"] .know__item:nth-child(3) { order: -1; }                   /* Delivery and returns first */
html[data-shell="app"] .know__item:not(:nth-child(2)) { border-bottom: 1px solid var(--line); }
html[data-shell="app"] .know .wash-icon--md { --wash-size: 48px; }
html[data-shell="app"] .know__item .h3 { font-size: 17px; }
html[data-shell="app"] .know__text { font-size: 15px; }
html[data-shell="app"][data-load="skeleton"] .shop-tools__count { visibility: hidden; }   /* the count is not known yet */

/* Website at 768-899px with the install card showing: keyboard focus scrolls
   clear of the card as well as the tab bar (WCAG 2.4.11). A page copy until
   ds/osevaro.css adds var(--install-h) to its own rule (DS request filed). */
@media (max-width: 899.98px) {
  html:not([data-shell="app"]) { scroll-padding-bottom: calc(var(--tabbar-h) + 24px + var(--safe-b) + var(--install-h, 0px)); }
}
