/* Avionics Support Ltd - base styles, built against the official Visual Identity
   Guidelines reconciled 17 Sept (see Detailed-Build-Requirements.md section 10).
   This is a functional skeleton, not final design - Week 2 mock-up/demo is where the
   actual look gets signed off with Lee.

   18 Sept: added dashboard theming for the two admin views (section 15.3/15.4), per
   Tony's brand direction -
     - /admin/orders (avionics_staff) stays on the Avionics theme below (default on
       <body>), full Avionics branding, small Pinnacle credit in the footer.
     - /admin/ops (pinnacle_ops) gets a `pinnacle-theme` class on <body> which
       overrides to Pinnacle's own guidelines (PTG variant - gold #C8963A / black /
       gunmetal - confirmed as the right sub-brand vs. Pinnacle AI's electric blue,
       since this is delivery/consultancy work not an AI product), with the Avionics
       logo shown and labelled in a data-source banner rather than as the page brand.
     - Pinnacle mark used is public/images/pinnacle-mark.svg - a simple placeholder
       built from the guidelines' text description (nested gold/silver chevrons, no
       glow). The real ptg-logo-trans.png wasn't supplied, only the guidelines doc, so
       swap this file for the real asset whenever Tony can send it - nothing else
       needs to change. */

/* Fonts are hosted by the store itself (SIL Open Font License; see public/fonts/*-OFL.txt).
   No requests go to Google, and the Content-Security-Policy stays strict. */
@font-face { font-family: 'Open Sans'; font-style: normal; font-weight: 300; font-display: swap; src: url('fonts/OpenSans-Light.woff') format('woff'); }
@font-face { font-family: 'Open Sans'; font-style: normal; font-weight: 400; font-display: swap; src: url('fonts/OpenSans-Regular.woff') format('woff'); }
@font-face { font-family: 'Open Sans'; font-style: normal; font-weight: 700; font-display: swap; src: url('fonts/OpenSans-Bold.woff') format('woff'); }
@font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 400; font-display: swap; src: url('fonts/Montserrat-Regular.woff') format('woff'); }
@font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 600; font-display: swap; src: url('fonts/Montserrat-SemiBold.woff') format('woff'); }
@font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 700; font-display: swap; src: url('fonts/Montserrat-Bold.woff') format('woff'); }
@font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 800; font-display: swap; src: url('fonts/Montserrat-ExtraBold.woff') format('woff'); }

:root {
  /* Primary palette - guidelines are explicit these are drawn from exclusively */
  --avionics-red: #eb140f;
  --avionics-black: #000000;
  --avionics-white: #ffffff;

  /* Secondary palette - sparing use only: diagrams/infographics, not primary UI chrome */
  --avionics-mink: #5d5d68;
  --avionics-purple: #942c6d;
  --avionics-saffron: #edac41;

  /* Pinnacle (PTG) palette - used only where .pinnacle-theme is in scope, and for the
     small Pinnacle credit shown on Avionics-branded pages. Source: Pinnacle Brand
     Guidelines, 18 Sept. */
  --pinnacle-gold: #C8963A;
  --pinnacle-gold-light: #E8B85A;
  --pinnacle-black: #000000;
  --pinnacle-gunmetal: #2E2E2E;
  --pinnacle-body: #2D3748;
  --pinnacle-muted: #718096;
  --pinnacle-border: #E2E8F0;
  --pinnacle-light: #F7F9FC;
  --pinnacle-white: #ffffff;
}

* { box-sizing: border-box; }

body {
  font-family: 'Open Sans', sans-serif;
  font-weight: 400;
  color: var(--avionics-black);
  background: var(--avionics-white);
  margin: 0;
}

.site-header {
  /* Full-colour logo on white is the primary, on-brand treatment (guidelines,
     reconciled 17 Sept) - no need to force a dark background here. */
  padding: 16px 24px;
  border-bottom: 1px solid #eee;
}

h1 { font-weight: 700; }

main { max-width: 960px; margin: 0 auto; padding: 24px; }

button, .cta {
  background: var(--avionics-red);
  color: var(--avionics-white);
  border: none;
  padding: 10px 20px;
  font-family: inherit;
  font-weight: 700;
  cursor: pointer;
}

button:disabled { background: var(--avionics-mink); cursor: not-allowed; }

.results-list { list-style: none; padding: 0; }
.results-list li { padding: 12px 0; border-bottom: 1px solid #eee; display: flex; justify-content: space-between; }

.part-details { display: grid; grid-template-columns: auto 1fr; gap: 4px 16px; }

/* Section 15 - basket, checkout, and the two admin dashboards. */

a.cta { display: inline-block; text-decoration: none; margin: 8px 8px 8px 0; }
.cta-secondary { background: var(--avionics-mink); }
.link-button { background: none; border: none; color: var(--avionics-red); font-weight: 700; padding: 0; cursor: pointer; text-decoration: underline; }

.data-table { width: 100%; border-collapse: collapse; margin: 16px 0; }
.data-table th, .data-table td { text-align: left; padding: 8px 12px; border-bottom: 1px solid #eee; }
.data-table thead th { border-bottom: 2px solid var(--avionics-black); }

.subtotal { font-size: 1.1em; text-align: right; }

.checkout-form fieldset { border: 1px solid #eee; margin-bottom: 16px; padding: 12px 16px; }
.checkout-form label { display: block; margin: 8px 0; }
.checkout-form input, .checkout-form select { display: block; width: 100%; max-width: 360px; padding: 6px; margin-top: 2px; }
/* 2 Oct - postcode format-error message (routes/checkout.js server-side check +
   checkout.ejs's matching client-side one). */
.checkout-form .field-error { color: var(--sf-red, #c0392b); font-size: 12.5px; margin: 2px 0 8px; max-width: 360px; }

.dev-simulate { border: 2px dashed var(--avionics-saffron); padding: 16px; margin-top: 24px; }

.admin-header { display: flex; justify-content: space-between; align-items: center; }
.admin-login { max-width: 320px; margin: 60px auto; text-align: left; }
.admin-login label { display: block; margin: 12px 0; }
.admin-login input { display: block; width: 100%; padding: 8px; margin-top: 2px; }
.error { color: var(--avionics-red); font-weight: 700; }

.funnel-table th { width: 60%; }
.funnel-table .headline { font-weight: 700; }

.hint { font-weight: 400; color: var(--avionics-mink); font-size: 0.75em; }

.status-filter { margin: 12px 0; }
.status-filter a { margin-right: 16px; text-decoration: none; color: var(--avionics-black); }
.status-filter a.active { font-weight: 700; color: var(--avionics-red); text-decoration: underline; }

.order-card { border: 1px solid #eee; padding: 16px; margin-bottom: 16px; }
.order-card > header { display: flex; gap: 12px; align-items: center; margin-bottom: 8px; }
.order-date { color: var(--avionics-mink); font-size: 0.9em; }

.status-badge { padding: 2px 10px; border-radius: 10px; font-size: 0.8em; font-weight: 700; text-transform: uppercase; color: var(--avionics-white); white-space: nowrap; }
.status-open { background: var(--avionics-mink); }
.status-packed_ready { background: var(--avionics-saffron); color: var(--avionics-black); }
.status-shipped { background: #2e8b3d; }

.status-form { display: flex; gap: 6px; align-items: center; margin-top: 6px; }
.status-form select { padding: 4px; font-size: 0.85em; }
.status-form button { padding: 4px 10px; font-size: 0.85em; }

/* --- Dashboard branding (18 Sept) --------------------------------------------- */

/* Shared header layout for both dashboards - logo + title on the left, user/logout
   on the right. Each dashboard's colours come from either the default Avionics
   theme or .pinnacle-theme below. */
.dash-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 24px;
}
.dash-header .brand {
  display: flex;
  align-items: center;
  gap: 14px;
}
.dash-header .brand-logo { height: 40px; width: auto; display: block; }
.dash-header .brand-title { display: flex; flex-direction: column; line-height: 1.15; }
.dash-header .brand-title .dashboard-name { font-size: 0.78em; font-weight: 400; opacity: 0.8; }
.dash-header .link-button { font-size: 0.9em; }

/* Avionics theme (default - /admin/orders) - the existing site-header rules already
   give a white background with a light bottom border, which matches the guidelines'
   "full-colour logo on white" primary treatment, so the header itself is left as-is;
   this just sizes the logo and title within it. */
.dash-header .brand-title .dashboard-name { color: var(--avionics-mink); }

/* Small Pinnacle "delivered by" credit, shown in the footer of the Avionics-branded
   staff dashboard. This is the standard convention for a co-branded delivery tool -
   client brand dominant, delivery partner credited small and unobtrusively, same idea
   as a "Powered by ..." badge. Sizing (56px height, 85% opacity) is per the Pinnacle
   guidelines' own footer spec. */
.partner-credit {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 24px 32px;
  max-width: 960px;
  margin: 0 auto;
  opacity: 0.85;
}
.partner-credit img { height: 56px; width: auto; } /* size per guidelines' own footer spec */
.partner-credit-centred { justify-content: center; margin: 40px auto 24px; } /* login page (18 Sept) - no other footer content to anchor left against */
.partner-credit span {
  font-family: 'Montserrat', sans-serif;
  font-size: 0.75em;
  color: var(--avionics-mink);
  letter-spacing: 0.02em;
}

/* Pinnacle theme (/admin/ops) - body.pinnacle-theme flips the page over to Pinnacle's
   own PTG guidelines: black/gunmetal header, gold accents, Montserrat type, and the
   signature gold gradient stripe under the header. The Avionics logo still appears,
   but inside a clearly labelled "whose data is this" banner rather than as the page
   brand - see admin-ops.ejs. */
body.pinnacle-theme {
  font-family: 'Montserrat', sans-serif;
  color: var(--pinnacle-body);
  background: var(--pinnacle-light);
}
/* 18 Sept: the real ptg-logo-trans.png Tony sent has dark grey/black wordmark text
   (by design, per the guidelines' "ptg-logo-black.png ... for briefing paper headers"
   note - this is the light-background variant, not the dark one), so the header stays
   on white/light rather than Pinnacle black - same "full-colour logo on a light
   background" convention already used for Avionics' own header. The gold stripe below
   still carries the brand signature; swap this to the black-background logo variant
   and flip these two rules back to var(--pinnacle-black) if Tony would rather have
   the dark header. */
body.pinnacle-theme .dash-header {
  background: var(--pinnacle-white);
  color: var(--pinnacle-body);
  border-bottom: 1px solid var(--pinnacle-border);
}
body.pinnacle-theme .dash-header .brand-logo { height: 64px; }
body.pinnacle-theme .dash-header .brand-title .dashboard-name { color: var(--pinnacle-gold); opacity: 1; font-weight: 600; }
body.pinnacle-theme .dash-header .link-button { color: var(--pinnacle-gold); }
body.pinnacle-theme .gold-stripe {
  height: 3px;
  background: linear-gradient(90deg, var(--pinnacle-black), var(--pinnacle-gold) 30%, var(--pinnacle-gold-light) 50%, var(--pinnacle-gold) 70%, var(--pinnacle-black));
}
body.pinnacle-theme h1, body.pinnacle-theme h2 { font-weight: 700; color: var(--pinnacle-black); }
body.pinnacle-theme .data-table thead th { border-bottom: 2px solid var(--pinnacle-black); }
body.pinnacle-theme .data-table th, body.pinnacle-theme .data-table td { border-bottom: 1px solid var(--pinnacle-border); }
body.pinnacle-theme .funnel-table .headline { color: var(--pinnacle-gold); }
body.pinnacle-theme .hint { color: var(--pinnacle-muted); }

/* Data-source banner on the ops dashboard - explicitly labels whose data is being
   shown, per Tony's instruction ("appropriate labelling for what the data is"),
   since this is Pinnacle's own tool and may show other clients' data in future. */
.data-source-banner {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--pinnacle-white);
  border: 1px solid var(--pinnacle-border);
  border-left: 4px solid var(--avionics-red);
  padding: 12px 18px;
  margin: 20px 0 28px;
}
.data-source-banner img { height: 30px; width: auto; }
.data-source-banner .label { font-size: 0.85em; color: var(--pinnacle-muted); }
.data-source-banner .label strong { color: var(--pinnacle-body); font-weight: 700; }

/* Second nav row in each dashboard header - ops dashboard's own tabs (funnel/
   failures vs. health), and, 18 Sept, the cross-dashboard link shown to a login that
   holds both roles (see lib/auth.js). Avionics colours by default since this now
   also appears on the Avionics-themed orders dashboard; overridden to Pinnacle
   colours within .pinnacle-theme below. */
.ops-nav { display: flex; gap: 18px; }
.ops-nav a { color: var(--avionics-black); text-decoration: none; font-size: 0.9em; font-weight: 600; padding-bottom: 2px; }
.ops-nav a.active, .ops-nav a:hover { color: var(--avionics-red); border-bottom: 2px solid var(--avionics-red); }
body.pinnacle-theme .ops-nav a { color: var(--pinnacle-body); }
body.pinnacle-theme .ops-nav a.active, body.pinnacle-theme .ops-nav a:hover { color: var(--pinnacle-gold); border-bottom: 2px solid var(--pinnacle-gold); }

/* --- KPI stat bar (18 Sept feedback, Avionics order dashboard) ------------------
   18 Sept round 3 fix - the 6 stat tiles and the period-picker form used to be flex
   siblings in one wrapping row, so the wide "Total value" tile (last in the DOM)
   would drop onto its own line before the picker did, reading as detached from "the
   rest of the stats" (Tony's feedback). Now the 6 tiles live in their own grid that
   stays together as a block, with the period picker as a separate flex sibling next
   to (not inside) that grid. */
.stat-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: flex-start;
  margin: 16px 0 28px;
}
.stat-grid {
  flex: 1 1 640px;
  display: grid;
  grid-template-columns: repeat(6, minmax(110px, 1fr));
  gap: 12px;
}
@media (max-width: 900px) { .stat-grid { grid-template-columns: repeat(3, minmax(110px, 1fr)); } }
@media (max-width: 520px) { .stat-grid { grid-template-columns: repeat(2, minmax(110px, 1fr)); } }
.stat-tile {
  border: 1px solid #eee;
  border-top: 3px solid var(--avionics-red);
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.stat-label { font-size: 0.72em; text-transform: uppercase; letter-spacing: 0.04em; color: var(--avionics-mink); }
.stat-value { font-size: 1.6em; font-weight: 700; }
.period-picker { flex: 0 0 160px; display: flex; align-items: center; justify-content: center; }
.period-picker label { font-size: 0.8em; color: var(--avionics-mink); display: flex; flex-direction: column; gap: 4px; }
.period-picker select { padding: 6px; }

/* Tabularised order detail, reworked 18 Sept round 3 per Tony's column-order
   feedback: Item/Description/Qty are now always-visible columns (not a collapsible
   "Items" summary) since they're the thing pick/pack staff need first, and each cell
   stacks one line per item for a multi-item order rather than hiding them behind a
   click. */
.orders-table td { vertical-align: top; }
.orders-table th:first-child, .orders-table td:first-child { width: 24px; }
.item-lines div { padding: 1px 0; }
.item-lines div + div { border-top: 1px dashed #eee; margin-top: 3px; padding-top: 4px; }

/* Status-filter tabs vs. the bulk-action toolbar underneath look similar (both
   involve the same three status words) so 18 Sept round 3 adds an explicit label to
   each and a light background on the toolbar to read as a distinct "do something"
   action bar rather than another filter. */
.status-filter-intro { margin: 0 0 4px; }
.bulk-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 10px 0;
  padding: 8px 12px;
  font-size: 0.9em;
  background: #faf8f6;
  border: 1px solid #eee;
}
.bulk-toolbar-label { font-weight: 600; }
.bulk-toolbar select { padding: 4px; }

.quantum-form { margin: 0; }
.quantum-badge { border: 1px solid var(--avionics-border, #ddd); padding: 4px 10px; font-size: 0.8em; font-weight: 700; cursor: pointer; background: var(--avionics-white); }
.quantum-badge.quantum-pending { color: var(--avionics-mink); }
.quantum-badge.quantum-added { color: #2e8b3d; border-color: #2e8b3d; background: #eaf6ec; }

/* --- Health-check tab (18 Sept) -------------------------------------------------- */
.health-table td { vertical-align: top; }
.health-badge { display: inline-block; padding: 2px 10px; border-radius: 10px; font-size: 0.75em; font-weight: 700; text-transform: uppercase; margin-right: 4px; }
.health-ok { background: #eaf6ec; color: #2e8b3d; }
.health-fail { background: #fbe7e6; color: var(--avionics-red); }
.health-pending { background: var(--pinnacle-light); color: var(--pinnacle-muted); border: 1px solid var(--pinnacle-border); }
.raw-payload { background: var(--pinnacle-light); border: 1px solid var(--pinnacle-border); padding: 8px; font-size: 0.8em; max-width: 480px; white-space: pre-wrap; word-break: break-word; }
.check-suggestions { padding-left: 20px; }
.check-suggestions li { margin-bottom: 6px; }

/* --- Certification tag + checkout totals (29 Sept, ported from the mock-up) ------ */
/* Minimal styling only - full storefront design-system port (sticky header,
   categories sidebar, parts table) is a separate piece of work, tracked separately. */
.cert-tag {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  font-size: 0.75em;
  font-weight: 600;
  border: 1px solid var(--avionics-border, #ddd);
  background: var(--pinnacle-light, #faf8f6);
  color: var(--pinnacle-muted, #555);
  border-radius: 3px;
}
.order-totals { display: grid; grid-template-columns: auto auto; column-gap: 16px; row-gap: 4px; max-width: 320px; margin: 12px 0; }
.order-totals dt { text-align: left; }
.order-totals dd { text-align: right; margin: 0; }

/* ============================================================================
   Storefront look-and-feel, ported 29 Sept 2026 from the 24/25 Sept mock-up
   (mockups/avionics-storefront-mockup.html) for visual parity ahead of the real
   postcode/Judopay integration work - see Build-Progress-Log.md.

   Scoped under body.storefront so it doesn't affect the admin dashboards, which
   keep their own .dash-header-based theme above. Storefront views: home, part,
   category, search, cart, checkout, checkout-confirmation, not-found, rfq.

   Deliberately NOT ported: the mock-up's client-side slide-in drawer (basket/RFQ
   open as real pages here, not a JS drawer - this app is server-rendered per
   Detailed-Build-Requirements.md section 4's SEO requirement), client-side table
   sorting/pagination (server-side already, section 6), and the auto-scrolling
   promo-banner carousel (no live promo/discount data yet - task 8, not this pass).
   Colour variables reuse the existing --avionics- and --pinnacle- tokens above,
   consistent with "guidelines are explicit [the primary palette] is drawn from
   exclusively" (see the :root comment at the top of this file) - the mock-up's own
   --red/--ink/--paper etc. names are mapped onto those rather than introducing a
   second, parallel colour system.
   ============================================================================ */

body.storefront {
  --sf-border: #e3dad7;
  --sf-surface: #f7f3f2;
  --sf-surface-2: #efe9e7;
  --sf-muted: #8c807c;
  --sf-ink: var(--avionics-black);
  --sf-ink-soft: #423a37;
  --sf-red: var(--avionics-red);
  --sf-red-dark: #c01009;
  --sf-ok: #1e7a44;
  --sf-ok-bg: #e7f5ec;
  --sf-mink: var(--avionics-mink);
  --sf-mink-bg: #eeeef1;
  background: var(--sf-surface);
}
body.storefront main { max-width: none; padding: 0; margin: 0; }

/* --- Header ------------------------------------------------------------------ */
body.storefront .site-header {
  display: flex; align-items: center; gap: 22px; padding: 14px 28px;
  background: var(--avionics-white); border-bottom: 1px solid var(--sf-border); flex-wrap: wrap;
  position: sticky; top: 0; z-index: 5;
}
body.storefront .site-header .logo img { height: 40px; width: auto; display: block; }
body.storefront .site-nav { display: flex; gap: 20px; font-weight: 700; font-size: 13.5px; letter-spacing: 0.01em; color: var(--sf-ink-soft); flex: 1; align-items: center; }
body.storefront .site-nav a { text-decoration: none; color: var(--sf-ink-soft); }
body.storefront .site-nav a:hover { color: var(--sf-red); }
body.storefront .site-nav a.home-link { display: flex; align-items: center; gap: 5px; color: var(--sf-ink); }
body.storefront .site-nav a.home-link svg { width: 15px; height: 15px; }
body.storefront .header-actions { display: flex; align-items: center; gap: 10px; font-size: 13px; font-weight: 700; flex-wrap: wrap; }
body.storefront .header-contact { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 4px; margin-right: 6px; padding-right: 14px; border-right: 1px solid var(--sf-border); }
body.storefront .header-contact-item { display: flex; align-items: center; gap: 5px; text-decoration: none; color: var(--sf-ink-soft); font-size: 12.5px; font-weight: 700; white-space: nowrap; }
body.storefront .header-contact-item:hover { color: var(--sf-red); }
body.storefront .header-contact svg { width: 14px; height: 14px; flex-shrink: 0; }
body.storefront .account-login { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.15; margin-right: 4px; color: var(--sf-muted); }
body.storefront .account-login .t { font-size: 12.5px; font-weight: 700; color: var(--sf-ink-soft); }
body.storefront .account-login .s { font-size: 10px; font-weight: 700; color: var(--sf-muted); text-transform: uppercase; letter-spacing: 0.04em; }
body.storefront .basket-btn { display: flex; align-items: center; gap: 7px; background: var(--sf-surface); border: 1px solid var(--sf-border); border-radius: 999px; padding: 7px 13px 7px 11px; color: var(--sf-ink); text-decoration: none; transition: border-color 0.12s ease; }
body.storefront .basket-btn.basket-variant:hover { border-color: var(--sf-red); }
body.storefront .basket-btn.quote-variant:hover { border-color: var(--sf-mink); }
body.storefront .basket-btn .icn { width: 17px; height: 17px; flex-shrink: 0; color: var(--sf-ink-soft); }
body.storefront .basket-btn .lbl { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.15; }
body.storefront .basket-btn .lbl .t { font-size: 12.5px; font-weight: 700; color: var(--sf-ink); }
body.storefront .basket-btn .lbl .s { font-size: 10px; color: var(--sf-muted); font-weight: 600; }

/* --- Hero / title bar ---------------------------------------------------------- */
body.storefront .title-bar { background: var(--avionics-white); border-bottom: 1px solid var(--sf-border); padding: 26px 28px 22px; }
body.storefront .title-bar .inner { max-width: 1200px; margin: 0 auto; }
body.storefront .title-bar h1 { font-size: 25px; font-family: 'Montserrat', sans-serif; }
body.storefront .title-bar p { color: var(--sf-ink-soft); margin: 8px 0 0; font-size: 13.5px; max-width: none; }
body.storefront .title-bar p .phone { color: var(--sf-red); font-weight: 700; }
body.storefront .title-bar .eyebrow { color: var(--sf-red); font-size: 13px; font-weight: 800; margin-bottom: 6px; display: block; }

/* --- Search card ---------------------------------------------------------- */
body.storefront .search-wrap { max-width: 1200px; margin: 26px auto 24px; padding: 0 28px; }
body.storefront .search-card { background: var(--avionics-white); border: 1px solid var(--sf-border); border-radius: 10px; box-shadow: 0 8px 24px rgba(20,14,12,0.10); padding: 16px; }
body.storefront .search-card form { display: flex; gap: 10px; flex-wrap: wrap; }
body.storefront .search-card input[type="text"] { flex: 1; min-width: 200px; border: 1px solid var(--sf-border); background: var(--avionics-white); color: var(--sf-ink); border-radius: 7px; padding: 11px 13px; font-size: 14px; font-family: inherit; }
body.storefront .search-card input:focus { outline: 2px solid var(--sf-red); outline-offset: 1px; }
body.storefront .search-card button[type="submit"] { background: var(--sf-red); color: #fff; border: none; border-radius: 7px; padding: 0 22px; font-weight: 800; font-size: 13px; letter-spacing: 0.03em; cursor: pointer; }
body.storefront .search-card button[type="submit"]:hover { background: var(--sf-red-dark); }

/* --- Promo/consumables banners --------------------------------------------- */
/* Visual chrome only - no live promo/discount data yet (task 8: promo banners +
   discount_percent), so this shows a clearly-labelled "coming soon" placeholder
   rather than fabricated items. Swap the placeholder for real scrolling cards once
   Lee sends banner content and the discount data model is built. */
body.storefront .scroll-banner { position: relative; border-top: 1px solid var(--sf-border); border-bottom: 1px solid var(--sf-border); padding: 22px 28px 16px; margin-bottom: 24px; }
body.storefront .scroll-banner.promo { background: var(--sf-ink); }
body.storefront .scroll-banner.consumables { background: var(--sf-surface); }
body.storefront .banner-label { position: absolute; top: 0; left: 14px; transform: translateY(-50%); font-size: 15px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.08em; padding: 7px 14px; border-radius: 999px; box-shadow: 0 2px 6px rgba(0,0,0,0.2); background: var(--sf-red); color: #fff; }
body.storefront .banner-placeholder { max-width: 1200px; margin: 0 auto; font-size: 12.5px; }
body.storefront .scroll-banner.promo .banner-placeholder { color: #c9c2ba; }
body.storefront .scroll-banner.consumables .banner-placeholder { color: var(--sf-ink-soft); }

/* --- Homepage expand/collapse (30 Sept, ported from the mock-up's #layoutWrap
   pattern - see the comment above #homeLayout in home.ejs). #homeLayout is the
   height-animated wrapper (max-height 0 by default, set to a measured px value by
   site.js's expandHome()/collapseHome() - max-height can't transition to/from
   "auto", which is why a wrapper measures and sets a concrete number rather than
   relying on a CSS-only approach); .layout inside it is what actually fades/slides
   via opacity+transform once the wrapper has somewhere to reveal it into. Runs only
   via JS-added classes (.open), never a bare `hidden` attribute - the trigger's
   default state is "wrapper has no inline max-height yet", which is already 0 per
   the base rule below, so nothing needs hiding on first paint. --- */
body.storefront #homeLayout { overflow: hidden; max-height: 0; transition: max-height 0.6s ease-in-out; }
body.storefront .expand-search-trigger { display: block; width: 100%; text-align: center; background: none; border: none; border-top: 1px solid var(--sf-border); margin-top: 12px; padding: 11px 6px 2px; font-size: 12.5px; font-weight: 700; color: var(--sf-red); cursor: pointer; font-family: inherit; }
body.storefront .expand-search-trigger:hover { background: none; color: var(--sf-red-dark); text-decoration: underline; }
body.storefront .expand-search-trigger[hidden] { display: none; }
body.storefront .collapse-search-trigger { display: block; width: 100%; text-align: center; background: none; border: none; padding: 10px 6px; font-size: 12.5px; font-weight: 700; color: var(--sf-muted); cursor: pointer; font-family: inherit; }
body.storefront .collapse-search-trigger:hover { background: none; color: var(--sf-ink-soft); text-decoration: underline; }
body.storefront .collapse-search-trigger[hidden] { display: none; }
body.storefront a.collapse-search-trigger { text-decoration: none; box-sizing: border-box; }
body.storefront a.collapse-search-trigger:hover { text-decoration: underline; }

/* --- Layout: categories sidebar + results table ---------------------------- */
/* 2 Oct fix - the fade-in-on-expand rule below used to be the unscoped
   "body.storefront .layout { opacity: 0; ... }", which is exactly the same
   unconditional-property-override bug class that hit the drawers and the
   homepage expand/collapse earlier in this project: it applied to EVERY
   .layout element, not just the one inside #homeLayout that this animation
   was written for. home.ejs's .layout sits inside #homeLayout and gets its
   opacity flipped to 1 once #homeLayout.open is added (site.js's
   expandHome()) - but category.ejs and search.ejs both use a bare
   <div class="layout"> with no #homeLayout ancestor at all, so that opacity:0
   was permanent on those pages with nothing to ever set it back to 1 -
   category/search pages rendered with real content in the DOM, just
   invisible (Tony: "clicking any of the categories, I get a completely blank
   page"). Scoped to "#homeLayout .layout" so it only ever applies to the
   homepage's animated listing - category.ejs/search.ejs's .layout is no
   longer touched by this rule at all and is visible by default, as it should
   always have been. */
body.storefront .layout { max-width: 1200px; margin: 0 auto; padding: 22px 28px 60px; display: flex; gap: 26px; align-items: flex-start; }
body.storefront #homeLayout .layout { opacity: 0; transform: translateY(-22px); transition: opacity 0.6s ease-in-out, transform 0.6s ease-in-out; }
body.storefront #homeLayout.open .layout { opacity: 1; transform: translateY(0); transition-delay: 0.1s; }
@media (prefers-reduced-motion: reduce) { body.storefront #homeLayout, body.storefront #homeLayout .layout, body.storefront #homeLayout.open .layout { transition: none; } }
body.storefront aside.categories { width: 226px; flex-shrink: 0; position: sticky; top: 84px; }
body.storefront aside.categories h2 { font-size: 15px; color: var(--sf-ink); font-weight: 800; margin-bottom: 18px; }
body.storefront .cat-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
body.storefront .cat-list a { display: block; text-align: left; border-radius: 7px; padding: 9px 10px; font-size: 13px; font-weight: 700; color: var(--sf-ink); text-decoration: none; }
body.storefront .cat-list a:hover { background: var(--sf-surface); }
body.storefront .cat-list li.active a { background: var(--sf-red); color: #fff; }
body.storefront .scale-note { font-size: 11px; color: var(--sf-muted); margin: 10px 2px 0; line-height: 1.5; }
body.storefront .trust-box { margin-top: 18px; border: 1px solid var(--sf-border); border-radius: 9px; padding: 14px; background: var(--sf-surface); }
body.storefront .trust-box h3 { font-size: 11.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--sf-muted); font-weight: 800; margin-bottom: 9px; }
body.storefront .trust-box ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; font-size: 12.5px; color: var(--sf-ink-soft); }
body.storefront .trust-box li { display: flex; gap: 7px; align-items: flex-start; }
body.storefront .trust-box li::before { content: "✓"; color: var(--sf-ok); font-weight: 800; flex-shrink: 0; }

body.storefront main.results { flex: 1; min-width: 0; background: var(--avionics-white); border: 1px solid var(--sf-border); border-radius: 10px; padding: 18px; }
body.storefront .results-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 14px; gap: 12px; flex-wrap: wrap; }
body.storefront .results-head h2 { font-size: 15px; }
body.storefront .results-head .sub { font-size: 12.5px; color: var(--sf-muted); }

body.storefront .cert-tag { border-color: var(--sf-border); background: var(--sf-surface); color: var(--sf-ink-soft); }
body.storefront .stock-pill { display: inline-flex; align-items: center; gap: 5px; background: var(--sf-ok-bg); color: var(--sf-ok); border-radius: 999px; padding: 3px 10px 3px 8px; font-size: 11.5px; font-weight: 700; }
body.storefront .stock-pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--sf-ok); }
body.storefront .stock-pill.low { background: #fcf1de; color: #b4790a; }
body.storefront .stock-pill.low::before { background: #b4790a; }

body.storefront .pager-wrap { display: flex; align-items: center; justify-content: space-between; margin-top: 16px; flex-wrap: wrap; gap: 10px; }
body.storefront .pager-note { font-size: 11.5px; color: var(--sf-muted); }
body.storefront .btn-page { background: var(--avionics-white); border: 1.5px solid var(--sf-border); color: var(--sf-ink); border-radius: 7px; padding: 8px 16px; font-size: 12.5px; font-weight: 700; text-decoration: none; display: inline-block; }
body.storefront .btn-page:hover { border-color: var(--sf-ink-soft); }
body.storefront .price-note { font-size: 12px; color: var(--sf-muted); margin-top: 10px; }

/* 2 Oct fix - the parts table itself (category.ejs/search.ejs's <table class="parts">)
   never had its core styling ported from the mock-up at all - only the pieces inside
   it (stock-pill, cert-tag, price-note) were. With no border/padding/header-background
   on the th/td cells, a single header row with nothing below it to establish column
   widths rendered as a cramped, borderless run of text (Tony: "the table headers look
   odd"). Ported verbatim from the mock-up's table.parts rules. */
body.storefront .table-scroll { overflow-x: auto; border: 1px solid var(--sf-border); border-radius: 10px; }
/* 22 Oct: results list shows about 10 rows (20 per page) and scrolls inside its own box,
   so the banners below stay in place. Header row stays visible while scrolling. */
body.storefront .results-box { max-height: 470px; overflow-y: auto; }
body.storefront .results-box table.parts thead th { position: sticky; top: 0; z-index: 1; }
body.storefront table.parts { width: 100%; border-collapse: collapse; min-width: 820px; background: var(--avionics-white); }
body.storefront table.parts th { text-align: left; font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--sf-muted); font-weight: 800; background: var(--sf-surface); padding: 10px 12px; border-bottom: 1px solid var(--sf-border); white-space: nowrap; }
body.storefront table.parts td { padding: 11px 12px; border-bottom: 1px solid var(--sf-border); vertical-align: middle; font-size: 13px; text-align: left; }
body.storefront table.parts tbody tr:last-child td { border-bottom: none; }
body.storefront .pn-link { font-weight: 700; color: var(--sf-red); text-decoration: none; }
body.storefront .pn-link:hover { text-decoration: underline; }
body.storefront .desc-cell { color: var(--sf-ink); }
body.storefront .uom { font-size: 11.5px; color: var(--sf-muted); font-weight: 600; }
body.storefront .price { font-weight: 700; color: var(--sf-ink); }
body.storefront .price.rfq { font-weight: 700; color: var(--sf-mink); font-style: italic; font-size: 12px; }

/* 2 Oct fix - bulk search's CSV file upload, ported from the mock-up (which only
   had the upload control as a UI shell - "would be parsed the same way as the
   pasted list above", never actually read the file - public/js/site.js now really
   parses it, see wireCsvUpload()). Tony: "looks like we never built the ability to
   load in a file as we had before" - it existed to look at, but never worked. */
body.storefront .bulk-divider { display: flex; align-items: center; gap: 10px; color: var(--sf-muted); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; margin: 12px 0; }
body.storefront .bulk-divider::before, body.storefront .bulk-divider::after { content: ""; flex: 1; height: 1px; background: var(--sf-border); }
body.storefront .csv-upload { border: 1.5px dashed var(--sf-border); border-radius: 8px; padding: 16px; text-align: center; background: var(--avionics-white); width: 100%; }
body.storefront .csv-upload label { font-weight: 700; font-size: 13px; color: var(--sf-ink); cursor: pointer; }
body.storefront .csv-upload input[type="file"] { display: block; margin: 8px auto 0; font-size: 12.5px; }
body.storefront .csv-status { font-size: 12px; color: var(--sf-ok); font-weight: 700; margin-top: 8px; }
body.storefront .bulk-error { font-size: 12px; color: var(--sf-red); font-weight: 700; margin-top: 8px; }
/* The generic ".search-body .search-row form" rule is a single-line flex row (fine
   for the one-input single/wildcard forms) - bulk needs its contents stacked
   instead (textarea, divider, upload box, buttons, error), so its form overrides
   that to a column. */
body.storefront #bulkSearchForm.bulk-form { flex-direction: column; align-items: stretch; }
body.storefront .bulk-actions-row { display: flex; align-items: center; gap: 14px; margin-top: 10px; }

/* --- Footer trust strip ------------------------------------------------------ */
body.storefront footer.trust-strip { background: var(--sf-surface); border-top: 1px solid var(--sf-border); padding: 20px 28px; }
body.storefront .strip-inner { max-width: 1200px; margin: 0 auto; display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
body.storefront .strip-item { font-size: 12px; color: var(--sf-ink-soft); }
body.storefront .strip-item strong { display: block; color: var(--sf-ink); font-size: 12.5px; margin-bottom: 1px; }
@media (max-width: 720px) { body.storefront .strip-inner { grid-template-columns: 1fr 1fr; } body.storefront .layout { flex-direction: column; } body.storefront aside.categories { width: 100%; position: static; } }

/* --- Part page, cart, checkout - dressed with the same card/surface language --- */
body.storefront .page-card { max-width: 1200px; margin: 24px auto; padding: 0 28px; }
body.storefront .page-card > .card-inner { background: var(--avionics-white); border: 1px solid var(--sf-border); border-radius: 10px; padding: 24px; }
body.storefront .part-details { display: grid; grid-template-columns: auto 1fr; gap: 8px 16px; margin: 16px 0; }
body.storefront .part-details dt { color: var(--sf-muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700; }
body.storefront .part-details dd { margin: 0; font-weight: 600; }
body.storefront button, body.storefront .cta { background: var(--sf-red); border-radius: 7px; }
body.storefront button:hover, body.storefront .cta:hover { background: var(--sf-red-dark); }

/* --- Search tabs (Single Part / Bulk Search / Wildcard), 30 Sept, ported from the
   mock-up. Real forms, tab-switching chrome only - see home.ejs comment above the
   markup for why this does not affect the section 4 SEO requirement. Flat/joined
   tab-strip look (rounded top corners sitting flush against the card, active tab
   "lifted" onto the surface below it), matching the mock-up rather than the
   separate pill-buttons this looked like in the first pass. */
body.storefront .search-tabs { display: flex; align-items: center; gap: 2px; padding: 6px 6px 0; }
body.storefront .search-tabs button { border: none; background: transparent; color: var(--sf-muted); font-weight: 700; font-size: 12.5px; letter-spacing: 0.02em; padding: 9px 14px 10px; border-radius: 7px 7px 0 0; cursor: pointer; font-family: inherit; }
body.storefront .search-tabs button:hover { color: var(--sf-ink-soft); }
body.storefront .search-tabs button.active { color: var(--sf-ink); background: var(--sf-surface); }
body.storefront .search-body .search-row textarea { flex: 1; min-width: 200px; border: 1px solid var(--sf-border); background: var(--avionics-white); color: var(--sf-ink); border-radius: 7px; padding: 11px 13px; font-size: 14px; font-family: inherit; resize: vertical; }
body.storefront .search-body .search-row { display: flex; }
body.storefront .search-body .search-row[hidden] { display: none; }
body.storefront .search-body .search-row form { display: flex; gap: 10px; flex-wrap: wrap; width: 100%; align-items: flex-start; }

/* 2 Oct fix - "Clear all searches" + per-input "x" clear buttons, ported from the
   mock-up (.btnClearAllSearches / .input-clear-wrap / .clear-x), missing from the
   initial port entirely (Tony: "no way to clear search"). Sits right-aligned in the
   tab strip, matching the mock-up's inline style there. */
body.storefront .btn-clear-all { margin-left: auto; background: none; border: none; color: var(--sf-muted); font-weight: 700; font-size: 11.5px; text-decoration: underline; cursor: pointer; padding: 9px 10px; align-self: center; font-family: inherit; }
body.storefront .btn-clear-all:hover { color: var(--sf-ink-soft); background: none; }

body.storefront .input-clear-wrap { flex: 1; min-width: 200px; position: relative; display: flex; }
body.storefront .input-clear-wrap input[type="text"] { flex: 1; padding-right: 34px; }
body.storefront .clear-x { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); background: var(--sf-surface-2); border: none; border-radius: 50%; width: 22px; height: 22px; color: var(--sf-muted); cursor: pointer; font-size: 11px; line-height: 1; display: none; align-items: center; justify-content: center; }
body.storefront .clear-x.show { display: flex; }
body.storefront .clear-x:hover { background: var(--sf-border); color: var(--sf-ink-soft); }
/* The bulk textarea has no wrapping element to anchor an absolutely-positioned "x"
   to (it already fills the row), so its clear button sits inline next to "Search
   list" instead - same mock-up pattern (.clear-x's own position:static override). */
body.storefront .clear-x-inline { position: static; transform: none; margin-top: 2px; }

body.storefront .search-note { font-size: 12.5px; color: var(--sf-muted); margin: 10px 0 2px; }
body.storefront .cant-find-note { font-size: 12.5px; color: var(--sf-muted); margin: 4px 0 0; }
body.storefront .cant-find-note button { background: none; border: none; color: var(--sf-red); font-weight: 700; text-decoration: underline; cursor: pointer; padding: 0; font-family: inherit; font-size: inherit; }
body.storefront .cant-find-note button:hover { color: var(--sf-red-dark); background: none; }

/* --- Basket/RFQ header badges, 30 Sept. --- */
body.storefront .drawer-count { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 999px; background: var(--sf-red); color: #fff; font-size: 10px; font-weight: 800; line-height: 16px; }

/* --- Basket/RFQ slide-in drawers, 30 Sept, ported from the mock-up's dual-list
   pattern (section 5.2/14 item 15). Content filled by public/js/site.js. --- */
/* Always in the DOM (not `hidden`) - visibility is driven entirely by the .open
   class below, via opacity (overlay) and a translateX slide (drawer), matching the
   mock-up's #backdrop/#drawer pattern. This was a real bug in the first pass: the
   .drawer rule used to also set `display: flex` unconditionally, which - same class
   of mistake as the CSS-comment bug from 29 Sept - silently overrides the browser's
   own `[hidden] { display: none }` rule (an author stylesheet always wins over the
   user-agent one), so the drawer was actually visible at all times regardless of
   the `hidden` attribute in the markup. pointer-events is turned off while closed
   so the (invisible, off-screen) drawer can't be tabbed into or intercept clicks. */
body.storefront .drawer-overlay { position: fixed; inset: 0; background: rgba(20,14,12,0.45); z-index: 40; opacity: 0; pointer-events: none; transition: opacity 0.18s ease; }
body.storefront .drawer-overlay.open { opacity: 1; pointer-events: auto; }
body.storefront .drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(400px, 100vw); background: var(--avionics-white); box-shadow: -8px 0 24px rgba(20,14,12,0.18); z-index: 41; display: flex; flex-direction: column; transform: translateX(100%); pointer-events: none; transition: transform 0.18s ease; }
body.storefront .drawer.open { transform: translateX(0); pointer-events: auto; }
/* A closed drawer sits just off-screen; its shadow used to leak a faint strip onto the right edge. */
body.storefront .drawer:not(.open) { box-shadow: none; }
@media (prefers-reduced-motion: reduce) { body.storefront .drawer-overlay, body.storefront .drawer { transition: none; } }
body.storefront .drawer-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px; border-bottom: 1px solid var(--sf-border); }
body.storefront .drawer-head h2 { font-size: 16px; margin: 0; }
body.storefront .drawer-close { background: none; border: none; font-size: 22px; line-height: 1; color: var(--sf-muted); cursor: pointer; padding: 4px; }
body.storefront .drawer-close:hover { color: var(--sf-ink); }
body.storefront .drawer-body { flex: 1; overflow-y: auto; padding: 16px 20px; }
body.storefront .drawer-foot { padding: 16px 20px; border-top: 1px solid var(--sf-border); }
body.storefront .drawer-subtotal { font-size: 13.5px; color: var(--sf-ink-soft); margin: 0 0 12px; }
body.storefront .drawer-foot .cta, body.storefront .drawer-body .cta { display: block; text-align: center; text-decoration: none; color: #fff; padding: 11px; font-weight: 800; font-size: 13px; }
body.storefront .drawer-item { display: flex; justify-content: space-between; gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--sf-border); }
body.storefront .drawer-item:last-child { border-bottom: none; }
body.storefront .drawer-item-main { min-width: 0; }
body.storefront .drawer-item-main .drawer-item-pn { font-weight: 700; font-size: 13px; color: var(--sf-ink); display: block; }
body.storefront .drawer-item-main .drawer-item-desc { font-size: 12px; color: var(--sf-muted); display: block; margin-top: 2px; }
body.storefront .drawer-item-side { flex-shrink: 0; text-align: right; font-size: 12.5px; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
body.storefront .drawer-remove { background: none; border: none; color: var(--sf-red); font-weight: 700; font-size: 11.5px; cursor: pointer; padding: 0; text-decoration: underline; }
body.storefront .drawer-empty { color: var(--sf-muted); font-size: 13px; text-align: center; padding: 30px 0; }
body.storefront .rfq-submit-form { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--sf-border); display: flex; flex-direction: column; gap: 10px; }
body.storefront .rfq-submit-form label { font-size: 11.5px; font-weight: 700; color: var(--sf-muted); text-transform: uppercase; letter-spacing: 0.03em; display: flex; flex-direction: column; gap: 4px; }
body.storefront .rfq-submit-form input, body.storefront .rfq-submit-form textarea { font-family: inherit; font-size: 13.5px; font-weight: 400; text-transform: none; letter-spacing: normal; color: var(--sf-ink); border: 1px solid var(--sf-border); border-radius: 7px; padding: 9px 11px; }
body.storefront .rfq-note-lead { font-size: 12.5px; color: var(--sf-ink-soft); margin: 0 0 4px; }
body.storefront .rfq-submit-status { font-size: 12.5px; font-weight: 700; margin: 4px 0 0; }
body.storefront .rfq-submit-status.ok { color: var(--sf-ok); }
body.storefront .rfq-submit-status.err { color: var(--sf-red); }
@media (max-width: 480px) { body.storefront .drawer { width: 100vw; } }
body.storefront .checkout-form fieldset, body.storefront .data-table { border-color: var(--sf-border); }

/* Promotional code box (basket + checkout). Explicit colours so the Remove button is
   always legible (the generic .link-button style was rendering as a blank red block). */
.promo-form { margin: 12px 0; }
.promo-form button.promo-remove {
  background: transparent; border: 1px solid #b3261e; color: #b3261e;
  font-weight: 700; padding: 3px 10px; border-radius: 4px; cursor: pointer; text-decoration: none;
}
.promo-form button.promo-remove:hover { background: #b3261e; color: #fff; }
.promo-msg { margin: 8px 0; padding: 8px 12px; border-radius: 4px; font-weight: 700; }
.promo-msg-ok  { background: #e8f5e9; color: #1b5e20; border: 1px solid #a5d6a7; }
.promo-msg-err { background: #fdecea; color: #b3261e; border: 1px solid #f5b5af; }

/* Checkout slider + panel (12 Oct) */
body.storefront .drawer-checkout { width: min(480px, 100vw); }
#checkout-panel .results-list { list-style: none; padding: 0; margin: 0 0 8px; font-size: 13px; }
#checkout-panel .results-list li { display: flex; justify-content: space-between; gap: 10px; padding: 4px 0; border-bottom: 1px solid #eee; }
#checkout-panel .order-totals { display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; margin: 10px 0; font-size: 13.5px; }
#checkout-panel .order-totals dt, #checkout-panel .order-totals dd { margin: 0; }
#checkout-panel .order-totals dd { text-align: right; }
#checkout-panel .checkout-form input, #checkout-panel .checkout-form select { max-width: none; box-sizing: border-box; }
#checkout-panel .checkout-form fieldset { min-width: 0; }
#checkout-panel .co-check { display: flex; gap: 8px; align-items: flex-start; font-weight: 600; }
#checkout-panel .co-check input { width: auto; margin-top: 3px; }
#checkout-panel .co-actions { position: sticky; bottom: 0; background: #fff; padding: 12px 0 4px; border-top: 1px solid #eee; display: flex; flex-direction: column; gap: 10px; align-items: stretch; }
#checkout-panel .co-pay { background: var(--sf-red, #c0392b); color: #fff; border: none; border-radius: 6px; padding: 12px; font-weight: 800; font-size: 14px; cursor: pointer; }
#checkout-panel .co-pay[disabled] { opacity: 0.6; cursor: wait; }
#checkout-panel .co-back { text-align: center; font-weight: 700; }
#checkout-panel .promo-form { margin: 10px 0; }
.co-exit { font-weight: 700; margin: 0 0 8px; }

/* Root cause of the "solid red button with no text" bug: `body.storefront button` (red
   background) out-ranks the plain `.link-button` rule, so link-style buttons (e.g. Remove
   in the basket table) rendered red-on-red. This out-ranks it, for every link-style button
   on storefront pages. */
body.storefront .link-button,
body.storefront .link-button:hover {
  background: none; color: var(--sf-red); padding: 0; border: none; border-radius: 0;
  font-weight: 700; text-decoration: underline; cursor: pointer;
}
body.storefront .link-button:hover { color: var(--sf-red-dark); }

/* 13 Oct - stock feed: alternates, multiple stock lines, unavailable basket lines */
.alt-heading { margin: 1.5rem 0 .5rem; font-size: 1.05rem; }
.stock-line { border-top: 1px solid #d9dde3; padding: .75rem 0 .25rem; }
.stock-line:first-of-type { border-top: 0; }
.stock-line-title { font-size: 1rem; margin: 0 0 .25rem; color: #4a5568; }
.drawer-item-warn, .line-warn { display: block; color: #b42318; font-weight: 600; font-size: .85rem; }
tr.line-unavailable td { background: #fdf2f2; }


/* --- Part page (14 Oct feedback): header band, details left / buy panel right ------- */
body.storefront .part-hero { background: linear-gradient(135deg, #2e2e2e 0%, #000 100%); color: #fff; border-bottom: 4px solid var(--sf-red); }
body.storefront .part-hero .inner { max-width: 1200px; margin: 0 auto; padding: 22px 28px 26px; }
body.storefront .part-hero .eyebrow { display: block; font-size: 11.5px; letter-spacing: 0.12em; text-transform: uppercase; color: #c9c4c2; margin-top: 14px; font-weight: 700; }
body.storefront .part-hero h1 { margin: 4px 0 6px; font-size: 34px; letter-spacing: 0.01em; color: #fff; word-break: break-word; }
body.storefront .part-hero .description { margin: 0; font-size: 16px; color: #e8e4e2; max-width: 900px; }
body.storefront .back-to-search { color: #e8e4e2; font-size: 13px; font-weight: 700; text-decoration: none; }
body.storefront .back-to-search:hover { color: #fff; text-decoration: underline; }
body.storefront .stock-line { border-top: 1px solid var(--sf-border); padding: 18px 0; }
body.storefront .stock-line:first-of-type { border-top: 0; padding-top: 4px; }
body.storefront .stock-line-grid { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 28px; align-items: start; }
body.storefront .stock-line-grid .part-details { margin: 0; align-content: start; }
body.storefront .part-details dd.haz-yes { color: var(--sf-red); font-weight: 600; }
body.storefront .buy-panel { background: var(--sf-surface); border: 1px solid var(--sf-border); border-radius: 10px; padding: 18px; }
body.storefront .buy-price { margin-bottom: 14px; }
body.storefront .buy-price-amount { display: block; font-size: 30px; font-weight: 800; color: var(--sf-ink); line-height: 1.1; }
body.storefront .buy-price-rfq { font-size: 20px; color: var(--sf-mink); }
body.storefront .buy-price-unit { font-size: 12.5px; color: var(--sf-muted); }
body.storefront .buy-form { display: flex; gap: 10px; align-items: stretch; }
body.storefront .buy-qty { display: flex; flex-direction: column; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--sf-muted); gap: 3px; }
body.storefront .buy-qty input { width: 72px; padding: 9px 8px; font-size: 16px; font-weight: 700; border: 1.5px solid var(--sf-border); border-radius: 7px; background: #fff; }
body.storefront .buy-btn { flex: 1; font-size: 16px; padding: 12px 16px; border-radius: 8px; align-self: flex-end; }
body.storefront .view-list-btn { display: block; margin-top: 12px; text-align: center; padding: 10px 14px; border: 1.5px solid var(--sf-ink); border-radius: 8px; color: var(--sf-ink); font-weight: 700; font-size: 14px; text-decoration: none; background: #fff; }
body.storefront .view-list-btn:hover { background: var(--sf-ink); color: #fff; }
body.storefront .part-footer-nav { border-top: 1px solid var(--sf-border); padding-top: 18px; margin-top: 6px; }
body.storefront .back-to-search-btn { display: inline-block; padding: 10px 18px; border: 1.5px solid var(--sf-border); border-radius: 8px; background: #fff; color: var(--sf-ink); font-weight: 700; font-size: 13.5px; text-decoration: none; }
body.storefront .back-to-search-btn:hover { border-color: var(--sf-ink-soft); background: var(--sf-surface); }
@media (max-width: 760px) {
  body.storefront .stock-line-grid { grid-template-columns: 1fr; }
  body.storefront .part-hero h1 { font-size: 26px; }
  body.storefront .part-hero .inner { padding: 18px 16px 20px; }
}

/* --- Live banner cards (Hot Deals / Consumables) ---------------------------- */
body.storefront .banner-track { display: flex; gap: 14px; overflow-x: auto; padding: 8px 2px 10px; scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch; }
body.storefront .banner-card { position: relative; flex: 0 0 240px; scroll-snap-align: start; background: #fff; color: var(--sf-ink); border: 1px solid var(--sf-border); border-radius: 10px; padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 6px; }
body.storefront .banner-card h3 { margin: 0; font-size: 14.5px; line-height: 1.25; }
body.storefront .banner-card h3 a { color: inherit; text-decoration: none; }
body.storefront .banner-card h3 a:hover { text-decoration: underline; }
body.storefront .banner-img { height: 120px; border-radius: 7px; overflow: hidden; background: var(--sf-surface); display: flex; align-items: center; justify-content: center; }
body.storefront .banner-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
body.storefront .banner-img-none { background: var(--sf-surface-2); }
body.storefront .banner-img img.banner-logo { width: auto; height: auto; max-width: 70%; max-height: 60%; object-fit: contain; opacity: 0.9; }
body.storefront .banner-card h3.banner-pn { font-size: 15.5px; letter-spacing: 0.01em; }
body.storefront .banner-title { margin: 0; font-size: 13px; line-height: 1.3; color: var(--sf-ink-soft); }
body.storefront .deal-badge { display: inline-block; background: var(--sf-red); color: #fff; font-weight: 800; font-size: 12px; padding: 3px 8px; border-radius: 999px; }
body.storefront .banner-card .deal-badge { position: absolute; top: 16px; right: 18px; }
body.storefront .banner-desc { margin: 0; font-size: 12.5px; color: var(--sf-ink-soft); }
body.storefront .banner-meta { margin: 0; font-size: 11.5px; color: var(--sf-muted); }
body.storefront .banner-price { margin: 0; font-size: 15px; }
body.storefront .was-price { color: var(--sf-muted); text-decoration: line-through; font-size: 12.5px; }
body.storefront .now-price { font-weight: 800; }
body.storefront .banner-excl { font-size: 11px; color: var(--sf-muted); }
body.storefront .banner-actions { display: flex; gap: 8px; align-items: center; justify-content: space-between; margin-top: auto; }
body.storefront .banner-view { font-size: 12.5px; font-weight: 700; color: var(--sf-red); text-decoration: none; }
body.storefront .banner-add { margin: 0 0 0 auto; }
body.storefront .banner-add button { background: var(--sf-red); color: #fff; border: 0; border-radius: 6px; padding: 6px 10px; font-weight: 700; font-size: 12px; cursor: pointer; }
body.storefront .preview-note { background: #fff4d6; border: 1px solid #e6c765; padding: 10px 14px; border-radius: 8px; margin: 12px 0; font-size: 13px; }
body.storefront .stock-line-highlight { outline: 3px solid var(--sf-red); outline-offset: 4px; border-radius: 6px; }

/* --- Banner admin ----------------------------------------------------------- */
#bannerAdmin { max-width: 980px; margin: 0 auto; padding: 18px; }
#bannerAdmin .banner-admin-section { margin: 28px 0; }
#bannerAdmin .banner-item { border: 1px solid #d9d2cf; border-radius: 8px; padding: 14px; margin: 12px 0; background: #fff; }
#bannerAdmin .banner-item-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
#bannerAdmin .banner-fields { display: grid; gap: 10px; }
#bannerAdmin .banner-fields label { display: grid; gap: 4px; font-size: 13px; font-weight: 600; }
#bannerAdmin .banner-fields input[type="text"], #bannerAdmin .banner-fields select { padding: 8px 10px; border: 1px solid #bdb5b1; border-radius: 6px; font: inherit; }
#bannerAdmin .banner-picture { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; font-size: 13px; }
#bannerAdmin .banner-thumb { width: 120px; height: 68px; object-fit: cover; border-radius: 6px; border: 1px solid #d9d2cf; }
#bannerAdmin .banner-thumb-none { display: inline-flex; align-items: center; justify-content: center; background: #efe9e7; color: #8c807c; font-size: 11px; }
#bannerAdmin .banner-line-picker { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
#bannerAdmin .banner-warn { color: #a3170f; font-weight: 600; margin: 6px 0; }
#bannerAdmin .banner-ok { color: #1e7a44; font-weight: 600; }
#bannerAdmin .banner-linecheck { font-size: 12.5px; color: #423a37; background: #f7f3f2; padding: 8px 10px; border-radius: 6px; }
#bannerAdmin .banner-item-tools, #bannerAdmin .banner-section-tools { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
#bannerAdmin .inline-form { display: inline; margin: 0; }
#bannerAdmin .banner-save, #bannerAdmin .banner-publish { background: #e2130b; color: #fff; border: 0; border-radius: 6px; padding: 9px 16px; font-weight: 700; cursor: pointer; margin-top: 10px; }
#bannerAdmin .banner-delete { color: #a3170f; }

/* --- Users admin ------------------------------------------------------------ */
#userAdmin { max-width: 980px; margin: 0 auto; padding: 18px; }
#userAdmin .user-form { display: grid; gap: 10px; margin: 10px 0; }
#userAdmin .user-form > label { display: grid; gap: 4px; font-size: 13px; font-weight: 600; }
#userAdmin .user-form input[type="text"] { padding: 8px 10px; border: 1px solid #bdb5b1; border-radius: 6px; font: inherit; }
#userAdmin .perm-grid { border: 1px solid #d9d2cf; border-radius: 8px; padding: 10px 14px; display: grid; gap: 8px; }
#userAdmin .perm-item { display: flex; gap: 10px; align-items: flex-start; font-size: 13px; }
#userAdmin .user-card { border: 1px solid #d9d2cf; border-radius: 8px; padding: 10px 14px; margin: 10px 0; background: #fff; }
#userAdmin .user-card summary { cursor: pointer; display: flex; gap: 14px; align-items: baseline; flex-wrap: wrap; }
#userAdmin .user-sub { color: #6b605c; font-size: 12.5px; }
#userAdmin .inline-form { display: inline; margin: 0; }
#userAdmin .banner-save { background: #e2130b; color: #fff; border: 0; border-radius: 6px; padding: 9px 16px; font-weight: 700; cursor: pointer; justify-self: start; }
#userAdmin .banner-warn { color: #a3170f; font-weight: 600; }
#userAdmin .banner-delete { color: #a3170f; }
#userAdmin .banner-item-tools { display: flex; gap: 8px; flex-wrap: wrap; }
.admin-tabs { flex-wrap: wrap; }
.login-help { margin-top: 14px; font-size: 13px; }

/* --- Banner ticker (cards glide and loop; see public/js/banner-ticker.js) ---------- */
body.storefront .banner-track.ticker { overflow: hidden; scroll-snap-type: none; padding: 8px 0 10px; }
body.storefront .banner-belt { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-flex: none; flex: none; -webkit-flex-wrap: nowrap; flex-wrap: nowrap; width: max-content; min-width: max-content; }
body.storefront .banner-belt.css-anim { -webkit-animation: belt-scroll var(--belt-dur, 30s) linear infinite; animation: belt-scroll var(--belt-dur, 30s) linear infinite; }
body.storefront .belt-set { display: -webkit-flex; display: flex; -webkit-flex: none; flex: none; -webkit-flex-wrap: nowrap; flex-wrap: nowrap; gap: 14px; padding-right: 14px; }
body.storefront .belt-set > .banner-card { -webkit-flex-shrink: 0; flex-shrink: 0; }
body.storefront .banner-track.ticker:hover .banner-belt.css-anim, body.storefront .banner-track.ticker:focus-within .banner-belt.css-anim { -webkit-animation-play-state: paused; animation-play-state: paused; }
@-webkit-keyframes belt-scroll { from { -webkit-transform: translateX(0); transform: translateX(0); } to { -webkit-transform: translateX(calc(-1 * var(--belt-shift, 0px))); transform: translateX(calc(-1 * var(--belt-shift, 0px))); } }
@keyframes belt-scroll { from { transform: translateX(0); } to { transform: translateX(calc(-1 * var(--belt-shift, 0px))); } }
@media (prefers-reduced-motion: reduce) { body.storefront .banner-belt.css-anim { animation: none; } }

/* Whole banner card is clickable: the title link stretches over the card; the View link and
   Add to basket sit above it so they keep working on their own. */
body.storefront .banner-card h3 a::after { content: ''; position: absolute; inset: 0; border-radius: 10px; }
body.storefront .banner-card .banner-actions { position: relative; z-index: 2; }
body.storefront .banner-card:hover { border-color: var(--sf-red); box-shadow: 0 2px 10px rgba(0,0,0,.12); }
body.storefront .banner-card h3 a:focus-visible::after { outline: 2px solid var(--sf-red); outline-offset: 2px; }
body.storefront .stock-line { display: flow-root; }
body.storefront .part-banner-img { float: right; width: 190px; margin: 0 0 12px 18px; }
body.storefront .part-banner-img img { width: 100%; max-height: 140px; object-fit: cover; border-radius: 8px; display: block; border: 1px solid var(--sf-border); }
@media (max-width: 640px) { body.storefront .part-banner-img { float: none; width: 100%; max-width: 260px; margin: 0 0 12px; } }

body.storefront .preview-bar { background: #fff4d6; border-bottom: 1px solid #e6c765; padding: 9px 20px; font-size: 13px; display: flex; gap: 16px; align-items: center; justify-content: space-between; flex-wrap: wrap; position: sticky; top: 0; z-index: 50; }
body.storefront .preview-bar a { font-weight: 700; color: var(--sf-red); white-space: nowrap; }

/* Legal pages and footer links (26 Oct) */
.legal-links { text-align: center; padding: 14px 16px 24px; font-size: 0.9rem; }
.legal-links a { color: inherit; }
.site-bottom { position: relative; }
.powered-by { position: absolute; right: 24px; bottom: 24px; display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: 0.73rem; line-height: 1; opacity: 0.85; }  /* one size below the company line (0.8rem) */
.powered-by img { height: 44px; width: auto; display: block; }
.powered-by span { white-space: nowrap; }
/* 29 Oct: on wide screens the long company line ran underneath the badge. Reserve the badge's width on
   both sides (so the text stays centred) and the line wraps before it reaches the badge. */
@media (min-width: 1151px) {
  .legal-links { padding-left: 280px; padding-right: 280px; }
}
@media (max-width: 1150px) {
  .powered-by { position: static; justify-content: center; padding: 0 16px 20px; }
}
.legal-links .company-line { margin: 8px 0 0; font-size: 0.8rem; opacity: 0.75; }
.legal-page h2 { margin-top: 1.4em; }
.legal-page { max-width: 760px; }
.legal-draft { background: #fff4d6; border: 1px solid #e0b84a; padding: 8px 12px; border-radius: 4px; }
.co-terms { margin: 14px 0; }
/* 30 Oct: the terms sentence is ONE flex item (a span), so it reads as normal text instead of being spread across the row.
   Dark grey (not the pale helper-text grey) so a consent line stays easy to read; links in Avionics red. */
/* 30 Oct: banner discount shown under a part line (checkout, basket, confirmation). */
.line-deal { display: block; margin-top: 3px; font-size: 12px; font-weight: 400; color: #5c534f; }
.line-deal .deal-badge { display: inline-block; background: var(--avionics-red); color: #fff; font-weight: 800; font-size: 11px; padding: 2px 7px; border-radius: 999px; }
.line-deal .was-price, .data-table .was-price { color: #8c807c; text-decoration: line-through; font-size: 12px; }
.data-table .deal-badge { display: inline-block; background: var(--avionics-red); color: #fff; font-weight: 800; font-size: 11px; padding: 2px 7px; border-radius: 999px; }
.co-check-text { font-weight: 400; font-size: 13.5px; line-height: 1.5; color: #5c534f; }
.co-check-text a { color: var(--avionics-red); text-decoration: underline; font-size: inherit; font-weight: 400; }
.co-check-text a:hover { color: #c01009; }

/* 30 Oct: links with no colour of their own were browser blue (purple once visited). They now use Avionics red
   (RGB 235 20 15). :where() keeps this at the lowest specificity, so buttons, menus, banners and every
   link that already has its own colour are unaffected. */
:where(body.storefront) a { color: var(--avionics-red); }
:where(body.storefront) a:where(:hover) { color: #c01009; }

.under-one-note { color: #8a5a00; font-size: 0.9rem; }


/* ============================================================================
   Responsive pass (28 Oct): narrow windows and phones.
   - Header: slim; the menu moves behind a Menu button; contact details move into the menu.
   - Search results come first; the categories fold out; the Trusted Supply box follows the results.
   - Banners fit the screen; on phones they are swiped, one at a time, instead of gliding.
   Desktop (wide) layout is unchanged: the Menu button and the in-menu contact links are hidden there.
   ============================================================================ */
body.storefront .menu-toggle { display: none; align-items: center; gap: 6px; background: var(--sf-surface); border: 1px solid var(--sf-border); border-radius: 999px; padding: 7px 12px; font: inherit; font-weight: 700; font-size: 13px; color: var(--sf-ink); cursor: pointer; }
body.storefront .menu-toggle svg { width: 18px; height: 18px; }
body.storefront .site-nav a.store-link { background: var(--sf-red); color: #fff; border-radius: 999px; padding: 6px 15px; }
body.storefront .site-nav a.store-link:hover { background: var(--sf-red-dark); color: #fff; }
body.storefront .nav-contact { display: none; }
body.storefront .cat-toggle { background: none; border: 0; padding: 0; font: inherit; font-weight: 800; font-size: 15px; color: var(--sf-ink); text-align: left; cursor: default; pointer-events: none; display: flex; align-items: center; gap: 8px; }
body.storefront .cat-chevron { display: none; }

@media (max-width: 1250px) { body.storefront .account-login { display: none; } }

@media (max-width: 1100px) {
  body.storefront .site-header { gap: 12px; padding: 10px 16px; flex-wrap: nowrap; transition: transform 0.2s ease; }
  body.storefront .site-header.header-hidden { transform: translateY(-100%); }
  body.storefront .site-header .logo { order: 1; margin-right: auto; }
  body.storefront .header-actions { order: 2; flex-wrap: nowrap; }
  body.storefront .menu-toggle { display: flex; order: 3; }
  body.storefront .header-contact { display: none; }
  body.storefront .site-nav { order: 4; display: none; position: absolute; top: 100%; left: 0; right: 0; flex-direction: column; align-items: stretch; gap: 0; background: var(--avionics-white); border-bottom: 1px solid var(--sf-border); box-shadow: 0 10px 20px rgba(20,14,12,0.12); padding: 4px 0 8px; font-size: 15px; }
  body.storefront .site-header.nav-open .site-nav { display: flex; }
  body.storefront .site-nav a { padding: 13px 20px; border-top: 1px solid var(--sf-border); }
  body.storefront .site-nav a:first-child { border-top: 0; }
  body.storefront .site-nav a.store-link { margin: 8px 16px 4px; text-align: center; border-top: 0; }
  body.storefront .nav-contact { display: flex; flex-direction: column; border-top: 1px solid var(--sf-border); margin-top: 4px; }
  body.storefront .nav-contact a { color: var(--sf-red); font-size: 14px; border-top: 0; padding: 10px 20px; }
}

@media (max-width: 860px) {
  body.storefront .layout { flex-direction: column; padding: 14px 14px 36px; gap: 14px; }
  body.storefront .layout > main.results { order: 1; width: 100%; min-width: 0; }
  body.storefront aside.categories { order: 2; width: 100%; position: static; }
  body.storefront .cat-toggle { width: 100%; justify-content: space-between; pointer-events: auto; cursor: pointer; background: var(--avionics-white); border: 1px solid var(--sf-border); border-radius: 9px; padding: 12px 14px; }
  body.storefront aside.categories h2 { margin-bottom: 8px; }
  body.storefront .cat-chevron { display: inline-block; width: 8px; height: 8px; border-right: 2px solid var(--sf-ink-soft); border-bottom: 2px solid var(--sf-ink-soft); transform: rotate(45deg); transition: transform 0.15s ease; }
  body.storefront aside.categories.cat-open .cat-chevron { transform: rotate(-135deg); }
  body.storefront aside.categories .cat-list { display: none; }
  body.storefront aside.categories.cat-open .cat-list { display: flex; }
  body.storefront .trust-box { margin-top: 10px; }
  body.storefront .title-bar { padding: 16px 16px 14px; }
  body.storefront .title-bar h1 { font-size: 21px; }
  body.storefront .title-bar p { font-size: 13px; }
  body.storefront .title-bar .eyebrow { font-size: 12px; margin-bottom: 4px; }
  /* Once the visitor is looking at results, the introduction gives way to the results themselves
     (it stays on the home page). */
  body.storefront.results-page .title-bar .hero-copy, body.storefront.results-page .title-bar .eyebrow,
  body:has(#homeLayout.open) .title-bar .hero-copy, body:has(#homeLayout.open) .title-bar .eyebrow { display: none; }
  body.storefront.results-page .title-bar, body:has(#homeLayout.open) .title-bar { padding: 10px 16px; }
  body.storefront.results-page .title-bar h1, body:has(#homeLayout.open) .title-bar h1 { font-size: 18px; }
  body.storefront .search-wrap { margin: 14px auto 14px; padding: 0 12px; }
  body.storefront .search-card { padding: 12px; }
  body.storefront .search-tabs { flex-wrap: wrap; gap: 4px; }
  body.storefront .scroll-banner { padding: 18px 12px 10px; margin-bottom: 14px; }
  body.storefront .banner-card { flex-basis: min(260px, 78vw); }
  body.storefront .banner-img { height: 96px; }
  body.storefront .banner-track { scroll-snap-type: x mandatory; }
}

@media (max-width: 600px) {
  body.storefront .site-header { padding: 8px 12px; gap: 8px; }
  body.storefront .site-header .logo img { height: 30px; }
  body.storefront .header-actions { gap: 6px; }
  body.storefront .basket-btn { padding: 6px 10px 6px 9px; gap: 5px; }
  body.storefront .basket-btn .lbl .s { display: none; }
  body.storefront .basket-btn .icn { width: 16px; height: 16px; }
  body.storefront .menu-toggle { padding: 7px 10px; }
  body.storefront .menu-toggle span { display: none; }
  body.storefront .search-card form { flex-direction: column; }
  body.storefront .search-card input[type="text"] { min-width: 0; width: 100%; box-sizing: border-box; }
  body.storefront .search-card button[type="submit"] { padding: 11px 22px; width: 100%; }
  body.storefront .banner-card { flex-basis: 86vw; }
  body.storefront .banner-track { gap: 10px; }
}
@media (max-width: 600px) {
  body.storefront .search-card .input-clear-wrap { width: 100%; flex: 0 0 auto; min-width: 0; box-sizing: border-box; }
}
/* The generic storefront button turns red on hover; these two controls keep their own look. */
body.storefront button.menu-toggle:hover, body.storefront button.menu-toggle:active, body.storefront button.menu-toggle:focus { background: var(--sf-surface-2, #ece6e2); color: var(--sf-ink); }
body.storefront button.cat-toggle:hover, body.storefront button.cat-toggle:active, body.storefront button.cat-toggle:focus { background: var(--avionics-white); color: var(--sf-ink); }
@media (min-width: 861px) { body.storefront button.cat-toggle:hover, body.storefront button.cat-toggle:active, body.storefront button.cat-toggle:focus { background: none; } }

/* Payment confirmation wait (30 Oct) */
.confirm-wait-active { text-align: center; }
.confirm-wait [hidden] { display: none; }
.confirm-spinner { animation: confirm-spin 1.6s linear infinite; margin-bottom: 12px; }
@keyframes confirm-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .confirm-spinner { animation: none; } }

/* Basket quantity editing (store31) */
body.storefront .qty-form { display: flex; align-items: center; gap: 8px; margin: 0; }
body.storefront .qty-input, body.storefront .drawer-qty { width: 64px; padding: 6px 6px; font-size: 16px; font-weight: 700; border: 1.5px solid var(--sf-border); border-radius: 6px; background: #fff; }
body.storefront .drawer-qty { width: 56px; padding: 3px 4px; font-size: 14px; }

/* Part page: the banner picture sits beside the part number in the header band (store35) */
body.storefront .part-hero .inner { display: flow-root; }
body.storefront .part-hero-img { float: right; width: 190px; margin: 14px 0 0 18px; }
body.storefront .part-hero-img img { width: 100%; max-height: 140px; object-fit: cover; border-radius: 8px; display: block; border: 1px solid rgba(255,255,255,.25); background: #fff; }
@media (max-width: 640px) { body.storefront .part-hero-img { width: 120px; margin: 10px 0 0 12px; } }

/* Phones: make it obvious the banner rows can be swiped (store42) */
body.storefront .scroll-banner.promo { --cue-bg: var(--sf-ink); }
body.storefront .scroll-banner.consumables { --cue-bg: var(--sf-surface); }
body.storefront .scroll-cue { display: none; }
@media (max-width: 600px) {
  body.storefront .banner-card { flex-basis: 80vw; }
  body.storefront .scroll-cue { display: flex; position: absolute; width: 46px; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: opacity .2s; z-index: 3; }
  body.storefront .scroll-cue-right { right: 0; background: linear-gradient(to left, var(--cue-bg, #fff) 25%, transparent); }
  body.storefront .scroll-cue-left { left: 0; background: linear-gradient(to right, var(--cue-bg, #fff) 25%, transparent); }
  body.storefront .scroll-cue.cue-on { opacity: 1; }
  body.storefront .scroll-cue button { pointer-events: none; width: 30px; height: 30px; border-radius: 50%; border: 0; padding: 0 0 3px; background: #fff; color: var(--sf-red); font-size: 24px; line-height: 1; font-weight: 700; box-shadow: 0 1px 6px rgba(0,0,0,.35); }
  body.storefront .scroll-cue.cue-on button { pointer-events: auto; }
}
