/* TB2 · The storefront's bottom tab bar (owner, 29 Oct 2026; brief TB2, prototype frozen as
   baselines/tb2-storefront-tab-bar-approved.2026-10-29-r2).

   Five tabs below 834 px: Home · Shop · Search · Cart · Orders. From 834 the bar is hidden and
   the header keeps its navigation, search and cart. The bar is in the server markup on every
   page that carries it, and ONE media query decides whether it is drawn — no measuring of
   innerWidth, so there is no flash, no layout shift and nothing for hydration to disagree with.

   ── THE LIFT (brief §4). These rules are the staff bar's, declaration for declaration:
   `.st-app--nav .st-nav` in staff.css. They cannot be shared yet because the staff refresh
   (feat/staff-ui-refresh) is not in main and the `.st-nav` there is still the older row — a
   plain flex line with a top-border marker and no label under the icon. When it lands, the
   three rules below marked LIFT take `, .st-app--nav .st-nav` (and `.st-tab` its item), and
   this file serves both surfaces. Nothing else needs to move, and no staff markup changes.
   One number is open on that day: the staff bar is 60 px tall where this one is 56 (the
   brief's figure). It goes to the owner with the lift, not quietly. */

:root {
  /* The bar's own box, stated in CSS rather than measured in script: 56 px of tab and its 1 px
     top border, and NOT the device's safe area — the inset is added once by each reader, for
     the reason given where this is set below. Zero unless a page carries a bar, so a page
     without one pads by nothing. The readers are the toast in store.css and store-listing.css,
     which already lifted by this variable before this bar existed; nothing else reads it. */
  --sc-tab-min: 56px; /* the tap target's floor, off the space scale on purpose — see .sc-tab */
  --sc-bar-h: 0px;
}
/* KEYED TO THE BAR, NOT TO THE WIDTH. The product page and checkout are narrow too, and they
   have no bar: keying this on the width alone made the product page reserve 57 px of nothing
   at 390, and would have lifted a toast over empty space. The height is declared on the body
   that actually carries a bar, so everything inside — the padding here and the toast — inherits
   a real number on those pages and zero on the others. */
@media (max-width: 833px) {
  body:has(.sc-tabbar) {
    /* WHAT THIS NUMBER MEANS IS SET BY ITS READERS, not by this file. The toast already lifts
       by it, in store.css and store-listing.css: `bottom: calc(var(--sc-bar-h) + 16px +
       env(safe-area-inset-bottom))`. Both of those are pinned to frozen baselines by
       scripts/css-check.mjs and cannot be changed, and they add the device inset themselves —
       so this variable is the bar's own box WITHOUT the inset, and whoever needs to clear the
       whole bar adds env() once, as the padding below does. Defining it the other way would
       have put the toast one inset too high on any phone with a home indicator, where nothing
       on this machine would ever have shown it. ONE SAFE AREA, COUNTED ONCE — in each reader. */
    --sc-bar-h: calc(var(--sc-tab-min) + 1px);
    padding-bottom: calc(var(--sc-bar-h) + env(safe-area-inset-bottom, 0px));
  }
}

/* LIFT ① the bar itself */
.sc-tabbar {
  position: fixed;
  inset: auto 0 0 0;
  /* Under the sheets (60) and the toast (70), over the page. The header is sticky at the top
     with its own 30 and never meets this. */
  z-index: 25;
  display: flex;
  background: var(--ui-bg);
  border-top: 1px solid var(--ui-border);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
/* FROM 834 the bar is hidden. On the prototype the script simply did not insert it; in the app
   it is in the markup on every page that carries it, and this is the single rule that decides.
   Checkout is not excluded here: it has no bar to hide, because drawsBarOn() in
   shell/tab-bar-model.ts does not render one on its paths. */
@media (min-width: 834px) {
  .sc-tabbar {
    display: none;
  }
}

/* LIFT ② the tab */
.sc-tab {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--ui-space-1);
  /* LAYOUT, NOT RHYTHM: the tap target. 56 px is not a step on the space scale and should not
     be — it is the floor a thumb needs, measured against 44. Named once, with its reason. */
  min-height: var(--sc-tab-min);
  padding: var(--ui-space-2) 2px 6px;
  position: relative;
  border: 0;
  background: transparent;
  color: var(--ui-text);
  font-family: inherit;
  font-size: var(--ui-text-xs);
  line-height: 1.1;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
.sc-tab__label {
  /* The label is the accessible name and is never hidden; at 320 px the five of them still sit
     on one line each. */
  white-space: nowrap;
}
/* THE BAR IS NOT SUBJECT TO A PAGE'S HEADER RULES. home.css ordered its phone header with
   `[data-open="sc-search"]` and `[data-cart-label]` — written for the two header buttons, but
   matching anything on the page, and the bar's Search and Cart carry exactly those attributes.
   Unordered, they jumped to the end of the bar, and this is what holds the order. Scoping those
   selectors to the header in home.css was planned for this PR and is NOT done: home.css is
   pinned by scripts/css-check.mjs to the frozen S1 baseline, rule for rule with comments
   stripped, so tightening them there would fail the check until that approved freeze is
   re-cut. It stays a follow-up, and nothing depends on it: this rule carries one weight more
   than the page's and a shared component should not rely on no page ever writing such a rule
   again. */
.sc-tabbar .sc-tab[data-open],
.sc-tabbar .sc-tab[data-cart-label] {
  order: 0;
}

/* LIFT ③ the current tab, by shape and not by colour alone: a pill, a heavier icon stroke, and
   the label in the accent at the strong weight. `aria-current` carries the same fact to a
   screen reader, and none of the three moves anything, so the row does not shift as you walk
   along it.

   THE FILL IS MEASURED, NOT PICKED. `--ui-accent-soft`, the staff bar's pill, measures 1.07:1
   against this bar's ground — a pill nobody can see. 18% of the accent mixed into the
   background gives 1.40:1, past the 1.3 floor with room for rounding, while the accent label
   on top of it still reads at 8.1:1. Palette tokens only: no new colour enters the storefront. */
.sc-tab[aria-current='page'] {
  background: color-mix(in srgb, var(--ui-accent) 18%, var(--ui-bg));
  color: var(--ui-accent);
}
.sc-tab[aria-current='page'] .sc-icon {
  stroke-width: 2;
}
.sc-tab[aria-current='page'] .sc-tab__label {
  font-weight: var(--ui-weight-strong);
}
.sc-tab:hover {
  color: var(--ui-accent);
}
.sc-tab:focus-visible {
  outline: var(--ui-ring-width) solid var(--ui-ring);
  outline-offset: -3px;
}
/* The count is the header's own `.sc-count` — same element, same attributes, painted by the
   same shell client — placed against the icon rather than a 44 px button. */
.sc-tab .sc-count {
  top: var(--ui-space-1);
  right: calc(50% - 20px);
}

/* THE PHONE HEADER, where the bar is drawn: Menu · logo · WhatsApp. Search and Cart are in the
   bar at these widths — moved, not dropped — so the header's own two step aside for the
   enquiry mark that had no place on a phone before. From 834 the header is untouched.
   The bar is in the markup on these pages, so `body:has(.sc-tabbar)` is what distinguishes a
   page that carries it from the product page and checkout, which do not. */
@media (max-width: 833px) {
  body:has(.sc-tabbar) .sc-header__left .sc-iconbtn:not(.sc-header__menubtn),
  body:has(.sc-tabbar) .sc-header__right .sc-iconbtn:not(.sc-wa) {
    display: none;
  }
}
/* THE MARK BELONGS TO THE BAR, and the Header is shared with the pages that have none — the
   product page renders the same header, and so does checkout. Hiding the mark only from 834 up
   put a fifth control into the product page's phone header, which is the very thing r2 fixed in
   the prototype. It is drawn where a bar is drawn, and nowhere else. */
.sc-wa {
  display: none;
}
@media (max-width: 833px) {
  body:has(.sc-tabbar) .sc-wa {
    /* NAMED, NOT REVERTED. `display: revert` in an author sheet rolls back to the browser's
       default for an <a> — `inline` — which also discards store.css's own
       `.sc-iconbtn { display: inline-grid }`. The mark would still have shown, and its box
       would have collapsed to the glyph: a tap target under 44 px that looks right in a
       screenshot. This restates the icon button's own display, which is what it has to be. */
    display: inline-grid;
  }
}
/* On the home page the phone header is its own approved design — the logo at the left, the
   controls at the right — so the enquiry mark takes the place Cart held there rather than the
   brief's literal Menu · logo · WhatsApp, which would re-arrange an approved screen. The three
   controls still move. Approved by the owner with the prototype, 29 Oct. */
@media (max-width: 959px) {
  .hm-page .sc-wa {
    order: 2;
  }
}
/* THE ONE COLOUR THAT IS NOT FROM THE PALETTE, and the standard's §2 exception for it: a
   third-party brand mark keeps its brand colour, scoped to the mark alone. The storefront had
   no such token — the footer names WhatsApp in words, it never draws the mark. It is not
   invented here: it is the value the staff app settled on, one step darker than the brand's own
   #25d366, which measures 2.63 against the rose ground and 2.75 against the cream, both under
   the 3:1 a graphic needs. */
:root {
  --sc-whatsapp: #178a44;
}
.sc-wa .sc-icon {
  color: var(--sc-whatsapp);
}
